11/**
22 * ObjectUI - Query AST Builder
33 * Phase 3.3: QuerySchema AST implementation
4+ * ObjectStack Spec v0.7.1: Window functions support
45 */
56
67import type {
@@ -15,6 +16,9 @@ import type {
1516 LimitNode ,
1617 OffsetNode ,
1718 AggregateNode ,
19+ WindowNode ,
20+ WindowFunction ,
21+ WindowFrame ,
1822 FieldNode ,
1923 LiteralNode ,
2024 OperatorNode ,
@@ -64,7 +68,7 @@ export class QueryASTBuilder {
6468 }
6569
6670 private buildSelect ( query : QuerySchema ) : SelectNode {
67- const fields : ( FieldNode | AggregateNode ) [ ] = [ ] ;
71+ const fields : ( FieldNode | AggregateNode | WindowNode ) [ ] = [ ] ;
6872
6973 if ( query . fields && query . fields . length > 0 ) {
7074 fields . push ( ...query . fields . map ( field => this . buildField ( field ) ) ) ;
@@ -77,6 +81,9 @@ export class QueryASTBuilder {
7781 fields . push ( ...query . aggregations . map ( agg => this . buildAggregation ( agg ) ) ) ;
7882 }
7983
84+ // Add window functions if they exist (future extension point)
85+ // query.windows?.forEach(win => fields.push(this.buildWindow(win)));
86+
8087 return {
8188 type : 'select' ,
8289 fields,
@@ -279,6 +286,55 @@ export class QueryASTBuilder {
279286 } ;
280287 }
281288
289+ /**
290+ * Build window function node (ObjectStack Spec v0.7.1)
291+ */
292+ private buildWindow ( config : {
293+ function : WindowFunction ;
294+ field ?: string ;
295+ alias : string ;
296+ partitionBy ?: string [ ] ;
297+ orderBy ?: Array < { field : string ; direction : 'asc' | 'desc' } > ;
298+ frame ?: WindowFrame ;
299+ offset ?: number ;
300+ defaultValue ?: any ;
301+ } ) : WindowNode {
302+ const node : WindowNode = {
303+ type : 'window' ,
304+ function : config . function ,
305+ alias : config . alias ,
306+ } ;
307+
308+ if ( config . field ) {
309+ node . field = this . buildField ( config . field ) ;
310+ }
311+
312+ if ( config . partitionBy && config . partitionBy . length > 0 ) {
313+ node . partitionBy = config . partitionBy . map ( field => this . buildField ( field ) ) ;
314+ }
315+
316+ if ( config . orderBy && config . orderBy . length > 0 ) {
317+ node . orderBy = config . orderBy . map ( sort => ( {
318+ field : this . buildField ( sort . field ) ,
319+ direction : sort . direction ,
320+ } ) ) ;
321+ }
322+
323+ if ( config . frame ) {
324+ node . frame = config . frame ;
325+ }
326+
327+ if ( config . offset !== undefined ) {
328+ node . offset = config . offset ;
329+ }
330+
331+ if ( config . defaultValue !== undefined ) {
332+ node . defaultValue = this . buildLiteral ( config . defaultValue ) ;
333+ }
334+
335+ return node ;
336+ }
337+
282338 optimize ( ast : QueryAST ) : QueryAST {
283339 return ast ;
284340 }
0 commit comments