Browse Source

column name case insensitive, better auto column names

pull/7185/head
chrislu 1 month ago
parent
commit
8645f3a264
  1. 43
      weed/query/engine/engine.go

43
weed/query/engine/engine.go

@ -1022,15 +1022,8 @@ type AggregationResult struct {
func (e *SQLEngine) parseAggregationFunction(funcExpr *sqlparser.FuncExpr, aliasExpr *sqlparser.AliasedExpr) (*AggregationSpec, error) {
funcName := strings.ToUpper(funcExpr.Name.String())
// Get alias name if specified
alias := funcName // Default alias is the function name
if !aliasExpr.As.IsEmpty() {
alias = aliasExpr.As.String()
}
spec := &AggregationSpec{
Function: funcName,
Alias: alias,
}
// Parse function arguments
@ -1043,9 +1036,11 @@ func (e *SQLEngine) parseAggregationFunction(funcExpr *sqlparser.FuncExpr, alias
switch arg := funcExpr.Exprs[0].(type) {
case *sqlparser.StarExpr:
spec.Column = "*"
spec.Alias = "COUNT(*)"
case *sqlparser.AliasedExpr:
if colName, ok := arg.Expr.(*sqlparser.ColName); ok {
spec.Column = colName.Name.String()
spec.Alias = fmt.Sprintf("COUNT(%s)", spec.Column)
} else {
return nil, fmt.Errorf("COUNT argument must be a column name or *")
}
@ -1062,6 +1057,7 @@ func (e *SQLEngine) parseAggregationFunction(funcExpr *sqlparser.FuncExpr, alias
case *sqlparser.AliasedExpr:
if colName, ok := arg.Expr.(*sqlparser.ColName); ok {
spec.Column = colName.Name.String()
spec.Alias = fmt.Sprintf("%s(%s)", funcName, spec.Column)
} else {
return nil, fmt.Errorf("%s argument must be a column name", funcName)
}
@ -1073,6 +1069,11 @@ func (e *SQLEngine) parseAggregationFunction(funcExpr *sqlparser.FuncExpr, alias
return nil, fmt.Errorf("unsupported aggregation function: %s", funcName)
}
// Override with user-specified alias if provided
if !aliasExpr.As.IsEmpty() {
spec.Alias = aliasExpr.As.String()
}
return spec, nil
}
@ -1140,7 +1141,7 @@ func (e *SQLEngine) computeAggregations(results []HybridScanResult, aggregations
// COUNT(column) counts non-null values
count := int64(0)
for _, result := range results {
if value, exists := result.Values[spec.Column]; exists && value != nil {
if value := e.findColumnValue(result.Values, spec.Column); value != nil {
if !e.isNullValue(value) {
count++
}
@ -1152,7 +1153,7 @@ func (e *SQLEngine) computeAggregations(results []HybridScanResult, aggregations
case "SUM":
sum := float64(0)
for _, result := range results {
if value, exists := result.Values[spec.Column]; exists && value != nil {
if value := e.findColumnValue(result.Values, spec.Column); value != nil {
if numValue := e.convertToNumber(value); numValue != nil {
sum += *numValue
}
@ -1164,7 +1165,7 @@ func (e *SQLEngine) computeAggregations(results []HybridScanResult, aggregations
sum := float64(0)
count := int64(0)
for _, result := range results {
if value, exists := result.Values[spec.Column]; exists && value != nil {
if value := e.findColumnValue(result.Values, spec.Column); value != nil {
if numValue := e.convertToNumber(value); numValue != nil {
sum += *numValue
count++
@ -1179,7 +1180,7 @@ func (e *SQLEngine) computeAggregations(results []HybridScanResult, aggregations
case "MIN":
var min interface{}
for _, result := range results {
if value, exists := result.Values[spec.Column]; exists && value != nil {
if value := e.findColumnValue(result.Values, spec.Column); value != nil {
if min == nil || e.compareValues(value, min) < 0 {
min = e.extractRawValue(value)
}
@ -1190,7 +1191,7 @@ func (e *SQLEngine) computeAggregations(results []HybridScanResult, aggregations
case "MAX":
var max interface{}
for _, result := range results {
if value, exists := result.Values[spec.Column]; exists && value != nil {
if value := e.findColumnValue(result.Values, spec.Column); value != nil {
if max == nil || e.compareValues(value, max) > 0 {
max = e.extractRawValue(value)
}
@ -1335,6 +1336,24 @@ func (e *SQLEngine) convertRawValueToSQL(value interface{}) sqltypes.Value {
return sqltypes.NULL
}
// findColumnValue performs case-insensitive lookup of column values
func (e *SQLEngine) findColumnValue(values map[string]*schema_pb.Value, columnName string) *schema_pb.Value {
// First try exact match
if value, exists := values[columnName]; exists {
return value
}
// Then try case-insensitive match
lowerColumnName := strings.ToLower(columnName)
for key, value := range values {
if strings.ToLower(key) == lowerColumnName {
return value
}
}
return nil
}
// discoverAndRegisterTopic attempts to discover an existing topic and register it in the SQL catalog
func (e *SQLEngine) discoverAndRegisterTopic(ctx context.Context, database, tableName string) error {
// First, check if topic exists by trying to get its schema from the broker/filer

Loading…
Cancel
Save