diff --git a/pkg/query-service/app/clickhouseReader/reader.go b/pkg/query-service/app/clickhouseReader/reader.go index 72fa61d7e8..16dc129195 100644 --- a/pkg/query-service/app/clickhouseReader/reader.go +++ b/pkg/query-service/app/clickhouseReader/reader.go @@ -3028,26 +3028,37 @@ func (r *ClickHouseReader) UpdateTraceField(ctx context.Context, field *model.Up return model.ForbiddenError(errors.New("removing a selected field is not allowed, please reach out to support.")) } + // name of the materialized column colname := utils.GetClickhouseColumnNameV2(field.Type, field.DataType, field.Name) + // dataType and chDataType of the materialized column + // dataType: string => string, bool => bool, int64, float64 => number + // chDataType: string => String, bool => Bool, int64 => Float64, => float64 => Float64 + chDataType := strings.ToUpper(string(field.DataType[0])) + field.DataType[1:] dataType := strings.ToLower(field.DataType) if dataType == "int64" || dataType == "float64" { dataType = "number" + chDataType = "Float64" } - // if dataType == "string" { - // dataType = "String" - // } - attrColName := fmt.Sprintf("%s_%s", field.Type, dataType) + + // typeName: tag => attributes, resource => resources + typeName := field.Type + if field.Type == string(v3.AttributeKeyTypeTag) { + typeName = constants.Attributes + } else if field.Type == string(v3.AttributeKeyTypeResource) { + typeName = constants.Resources + } + + attrColName := fmt.Sprintf("%s_%s", typeName, dataType) for _, table := range []string{r.traceLocalTableName, r.traceTableName} { q := "ALTER TABLE %s.%s ON CLUSTER %s ADD COLUMN IF NOT EXISTS `%s` %s DEFAULT %s['%s'] CODEC(ZSTD(1))" query := fmt.Sprintf(q, r.TraceDB, table, r.cluster, - colname, field.DataType, + colname, chDataType, attrColName, field.Name, ) - fmt.Println(query) err := r.db.Exec(ctx, query) if err != nil { return &model.ApiError{Err: err, Typ: model.ErrorInternal} diff --git a/pkg/query-service/app/http_handler.go b/pkg/query-service/app/http_handler.go index 0611e0f050..244f666da8 100644 --- a/pkg/query-service/app/http_handler.go +++ b/pkg/query-service/app/http_handler.go @@ -4918,7 +4918,7 @@ func (aH *APIHandler) updateTraceField(w http.ResponseWriter, r *http.Request) { return } - err := logs.ValidateUpdateFieldPayload(&field) + err := logs.ValidateUpdateFieldPayloadV2(&field) if err != nil { apiErr := &model.ApiError{Typ: model.ErrorBadData, Err: err} RespondError(w, apiErr, "Incorrect payload") diff --git a/pkg/query-service/app/logs/validator.go b/pkg/query-service/app/logs/validator.go index 69c60b7164..03432922dd 100644 --- a/pkg/query-service/app/logs/validator.go +++ b/pkg/query-service/app/logs/validator.go @@ -20,9 +20,40 @@ func ValidateUpdateFieldPayload(field *model.UpdateField) error { return fmt.Errorf("dataType cannot be empty") } + matched, err := regexp.MatchString(fmt.Sprintf("^(%s|%s|%s)$", constants.Static, constants.Attributes, constants.Resources), field.Type) + if err != nil { + return err + } + if !matched { + return fmt.Errorf("type %s not supported", field.Type) + } + + if field.IndexType != "" { + matched, err := regexp.MatchString(`^(minmax|set\([0-9]\)|bloom_filter\((0?.?[0-9]+|1)\)|tokenbf_v1\([0-9]+,[0-9]+,[0-9]+\)|ngrambf_v1\([0-9]+,[0-9]+,[0-9]+,[0-9]+\))$`, field.IndexType) + if err != nil { + return err + } + if !matched { + return fmt.Errorf("index type %s not supported", field.IndexType) + } + } + return nil +} + +func ValidateUpdateFieldPayloadV2(field *model.UpdateField) error { + if field.Name == "" { + return fmt.Errorf("name cannot be empty") + } + if field.Type == "" { + return fmt.Errorf("type cannot be empty") + } + if field.DataType == "" { + return fmt.Errorf("dataType cannot be empty") + } + // the logs api uses the old names i.e attributes and resources while traces use tag and attribute. // update log api to use tag and attribute. - matched, err := regexp.MatchString(fmt.Sprintf("^(%s|%s|%s|%s|%s)$", constants.Static, constants.Attributes, constants.Resources, v3.AttributeKeyTypeTag, v3.AttributeKeyTypeResource), field.Type) + matched, err := regexp.MatchString(fmt.Sprintf("^(%s|%s)$", v3.AttributeKeyTypeTag, v3.AttributeKeyTypeResource), field.Type) if err != nil { return err }