@@ -206,6 +206,9 @@ func (b *Builder) buildScalar(inScope *scope, e ast.Expr) (ex sql.Expression) {
206206 case * ast.GroupConcatExpr :
207207 // TODO this is an aggregation
208208 return b .buildGroupConcat (inScope , v )
209+ case * ast.OrderedInjectedExpr :
210+ // TODO this is an aggregation in practice but is handled differently
211+ return b .buildOrderedInjectedExpr (inScope , v )
209212 case * ast.ParenExpr :
210213 return b .buildScalar (inScope , v .Expr )
211214 case * ast.AndExpr :
@@ -272,23 +275,7 @@ func (b *Builder) buildScalar(inScope *scope, e ast.Expr) (ex sql.Expression) {
272275 }
273276 return ret
274277 case ast.InjectedExpr :
275- if err := b .cat .AuthorizationHandler ().HandleAuth (b .ctx , b .authQueryState , v .Auth ); err != nil && b .authEnabled {
276- b .handleErr (err )
277- }
278- resolvedChildren := make ([]any , len (v .Children ))
279- for i , child := range v .Children {
280- resolvedChildren [i ] = b .buildScalar (inScope , child )
281- }
282- expr , err := v .Expression .WithResolvedChildren (resolvedChildren )
283- if err != nil {
284- b .handleErr (err )
285- return nil
286- }
287- if sqlExpr , ok := expr .(sql.Expression ); ok {
288- return sqlExpr
289- }
290- b .handleErr (fmt .Errorf ("Injected expression does not resolve to a valid expression" ))
291- return nil
278+ return b .buildInjectedExpr (inScope , v )
292279 case * ast.RangeCond :
293280 val := b .buildScalar (inScope , v .Left )
294281 lower := b .buildScalar (inScope , v .From )
@@ -422,6 +409,39 @@ func (b *Builder) buildScalar(inScope *scope, e ast.Expr) (ex sql.Expression) {
422409 return nil
423410}
424411
412+ func (b * Builder ) buildInjectedExpr (inScope * scope , v ast.InjectedExpr ) sql.Expression {
413+ if err := b .cat .AuthorizationHandler ().HandleAuth (b .ctx , b .authQueryState , v .Auth ); err != nil && b .authEnabled {
414+ b .handleErr (err )
415+ }
416+
417+ var resolvedChildren []any
418+ if len (v .Children ) > 0 {
419+ resolvedChildren = make ([]any , len (v .Children ))
420+ for i , child := range v .Children {
421+ resolvedChildren [i ] = b .buildScalar (inScope , child )
422+ }
423+ } else {
424+ resolvedChildren = make ([]any , len (v .SelectExprChildren ))
425+ for i , child := range v .SelectExprChildren {
426+ resolvedChildren [i ] = b .selectExprToExpression (inScope , child )
427+ }
428+ }
429+ return b .buildInjectedExpressionFromResolvedChildren (v , resolvedChildren )
430+ }
431+
432+ func (b * Builder ) buildInjectedExpressionFromResolvedChildren (v ast.InjectedExpr , resolvedChildren []any ) sql.Expression {
433+ expr , err := v .Expression .WithResolvedChildren (resolvedChildren )
434+ if err != nil {
435+ b .handleErr (err )
436+ return nil
437+ }
438+ if sqlExpr , ok := expr .(sql.Expression ); ok {
439+ return sqlExpr
440+ }
441+ b .handleErr (fmt .Errorf ("injected expression should resolve to sql.Expression, got %T" , expr ))
442+ return nil
443+ }
444+
425445func (b * Builder ) getOrigTblName (node sql.Node , alias string ) string {
426446 if node == nil {
427447 return ""
@@ -930,7 +950,7 @@ func (b *Builder) ConvertVal(v *ast.SQLVal) sql.Expression {
930950 return b .convertInt (string (v .Val ), 10 )
931951 }
932952 case ast .HexNum :
933- //TODO: binary collation?
953+ // TODO: binary collation?
934954 v := strings .ToLower (string (v .Val ))
935955 if strings .HasPrefix (v , "0x" ) {
936956 v = v [2 :]
@@ -949,7 +969,7 @@ func (b *Builder) ConvertVal(v *ast.SQLVal) sql.Expression {
949969 }
950970 return expression .NewLiteral (val , types .LongBlob )
951971 case ast .HexVal :
952- //TODO: binary collation?
972+ // TODO: binary collation?
953973 val , err := v .HexDecode ()
954974 if err != nil {
955975 b .handleErr (err )
@@ -994,7 +1014,7 @@ func (b *Builder) ConvertVal(v *ast.SQLVal) sql.Expression {
9941014// filter, since we only need to load the tables once. All steps after this
9951015// one can assume that the expression has been fully resolved and is valid.
9961016func (b * Builder ) buildMatchAgainst (inScope * scope , v * ast.MatchExpr ) * expression.MatchAgainst {
997- //TODO: implement proper scope support and remove this check
1017+ // TODO: implement proper scope support and remove this check
9981018 if (inScope .groupBy != nil && inScope .groupBy .hasAggs ()) || inScope .windowFuncs != nil {
9991019 b .handleErr (fmt .Errorf ("aggregate and window functions are not yet supported alongside MATCH expressions" ))
10001020 }
0 commit comments