mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-09-06 16:17:01 +00:00
column name case insensitive, better auto column names
This commit is contained in:
+31
-12
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user