@@ -216,6 +216,18 @@ func explainArrayAccess(sb *strings.Builder, n *ast.ArrayAccess, indent string,
216216 Node (sb , n .Index , depth + 2 )
217217}
218218
219+ func explainArrayAccessWithAlias (sb * strings.Builder , n * ast.ArrayAccess , alias string , indent string , depth int ) {
220+ // Array access is represented as Function arrayElement
221+ if alias != "" {
222+ fmt .Fprintf (sb , "%sFunction arrayElement (alias %s) (children %d)\n " , indent , alias , 1 )
223+ } else {
224+ fmt .Fprintf (sb , "%sFunction arrayElement (children %d)\n " , indent , 1 )
225+ }
226+ fmt .Fprintf (sb , "%s ExpressionList (children %d)\n " , indent , 2 )
227+ Node (sb , n .Array , depth + 2 )
228+ Node (sb , n .Index , depth + 2 )
229+ }
230+
219231func explainTupleAccess (sb * strings.Builder , n * ast.TupleAccess , indent string , depth int ) {
220232 // Tuple access is represented as Function tupleElement
221233 fmt .Fprintf (sb , "%sFunction tupleElement (children %d)\n " , indent , 1 )
@@ -224,6 +236,18 @@ func explainTupleAccess(sb *strings.Builder, n *ast.TupleAccess, indent string,
224236 Node (sb , n .Index , depth + 2 )
225237}
226238
239+ func explainTupleAccessWithAlias (sb * strings.Builder , n * ast.TupleAccess , alias string , indent string , depth int ) {
240+ // Tuple access is represented as Function tupleElement
241+ if alias != "" {
242+ fmt .Fprintf (sb , "%sFunction tupleElement (alias %s) (children %d)\n " , indent , alias , 1 )
243+ } else {
244+ fmt .Fprintf (sb , "%sFunction tupleElement (children %d)\n " , indent , 1 )
245+ }
246+ fmt .Fprintf (sb , "%s ExpressionList (children %d)\n " , indent , 2 )
247+ Node (sb , n .Tuple , depth + 2 )
248+ Node (sb , n .Index , depth + 2 )
249+ }
250+
227251func explainLikeExpr (sb * strings.Builder , n * ast.LikeExpr , indent string , depth int ) {
228252 // LIKE is represented as Function like
229253 fnName := "like"
@@ -356,6 +380,7 @@ func explainExtractExpr(sb *strings.Builder, n *ast.ExtractExpr, indent string,
356380func explainWindowSpec (sb * strings.Builder , n * ast.WindowSpec , indent string , depth int ) {
357381 // Window spec is represented as WindowDefinition
358382 // For simple cases like OVER (), just output WindowDefinition without children
383+ // Note: ClickHouse's EXPLAIN AST does not output frame info (ROWS BETWEEN etc)
359384 children := 0
360385 if n .Name != "" {
361386 children ++
@@ -366,9 +391,6 @@ func explainWindowSpec(sb *strings.Builder, n *ast.WindowSpec, indent string, de
366391 if len (n .OrderBy ) > 0 {
367392 children ++
368393 }
369- if n .Frame != nil {
370- children ++
371- }
372394 if children > 0 {
373395 fmt .Fprintf (sb , "%sWindowDefinition (children %d)\n " , indent , children )
374396 if n .Name != "" {
@@ -383,7 +405,7 @@ func explainWindowSpec(sb *strings.Builder, n *ast.WindowSpec, indent string, de
383405 if len (n .OrderBy ) > 0 {
384406 fmt .Fprintf (sb , "%s ExpressionList (children %d)\n " , indent , len (n .OrderBy ))
385407 for _ , o := range n .OrderBy {
386- Node (sb , o . Expression , depth + 2 )
408+ explainOrderByElement (sb , o , strings . Repeat ( " " , depth + 2 ) , depth + 2 )
387409 }
388410 }
389411 // Frame handling would go here if needed
0 commit comments