Skip to content

Commit 6e5e5e7

Browse files
committed
lateral join, unnest, parquet encoding config support
1 parent ba44065 commit 6e5e5e7

File tree

11 files changed

+1550
-14
lines changed

11 files changed

+1550
-14
lines changed

src/autocomplete/suggestion-builder.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,9 @@ function getAllColumns(schema: SchemaInfo): ColumnWithTable[] {
8080
* into compound suggestions (e.g., "Left" → "LEFT JOIN") instead of
8181
* suggesting bare "LEFT" which is incomplete on its own.
8282
*/
83+
// Keywords that are valid but rarely the primary intent — suggest at MediumLow.
84+
const MEDIUM_LOW_KEYWORDS = new Set(["Unnest"])
85+
8386
const JOIN_COMPOUND_MAP = new Map<string, string>([
8487
["Left", "LEFT JOIN"],
8588
["Inner", "INNER JOIN"],
@@ -170,12 +173,17 @@ export function buildSuggestions(
170173
// Functions are suggested separately in the functions loop below.
171174
const kind = SuggestionKind.Keyword
172175

176+
// Some keywords are valid but rarely typed directly — suggest them lower.
177+
const priority = MEDIUM_LOW_KEYWORDS.has(name)
178+
? SuggestionPriority.MediumLow
179+
: SuggestionPriority.Medium
180+
173181
suggestions.push({
174182
label: keyword,
175183
kind,
176184
insertText: keyword,
177185
filterText: keyword.toLowerCase(),
178-
priority: SuggestionPriority.Medium,
186+
priority,
179187
})
180188
}
181189

src/parser/ast.ts

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,18 @@ export interface MaterializedViewPeriod extends AstNode {
233233
sampleByInterval?: boolean
234234
}
235235

236+
export interface ParquetConfig extends AstNode {
237+
type: "parquetConfig"
238+
/** Encoding: PLAIN, RLE_DICTIONARY, DELTA_BINARY_PACKED, DELTA_LENGTH_BYTE_ARRAY, DEFAULT */
239+
encoding?: string
240+
/** Compression codec: UNCOMPRESSED, SNAPPY, GZIP, BROTLI, ZSTD, LZ4_RAW */
241+
compression?: string
242+
/** Compression level, e.g. 3 for ZSTD(3) */
243+
compressionLevel?: number
244+
/** Whether BLOOM_FILTER is enabled */
245+
bloomFilter?: boolean
246+
}
247+
236248
export interface ColumnDefinition extends AstNode {
237249
type: "columnDefinition"
238250
name: string
@@ -245,6 +257,8 @@ export interface ColumnDefinition extends AstNode {
245257
indexed?: boolean
246258
/** INDEX CAPACITY value */
247259
indexCapacity?: number
260+
/** PARQUET encoding/compression/bloom filter config */
261+
parquetConfig?: ParquetConfig
248262
}
249263

250264
export interface AlterTableStatement extends AstNode {
@@ -411,9 +425,12 @@ export interface AlterColumnAction {
411425
| "cache"
412426
| "nocache"
413427
| "symbolCapacity"
428+
| "setParquet"
414429
newType?: string
415430
capacity?: number
416431
cache?: boolean
432+
/** PARQUET config for SET PARQUET(...) */
433+
parquetConfig?: ParquetConfig
417434
}
418435

419436
export interface DropPartitionAction {
@@ -820,10 +837,38 @@ export interface TableFunctionCall extends AstNode {
820837
args: Expression[]
821838
}
822839

840+
export interface UnnestArg extends AstNode {
841+
type: "unnestArg"
842+
expression: Expression
843+
/** JSON UNNEST column definitions: COLUMNS(name TYPE, ...) */
844+
columns?: UnnestColumnDef[]
845+
}
846+
847+
export interface UnnestColumnDef extends AstNode {
848+
type: "unnestColumnDef"
849+
name: string
850+
dataType: string
851+
}
852+
853+
export interface UnnestSource extends AstNode {
854+
type: "unnest"
855+
args: UnnestArg[]
856+
withOrdinality?: boolean
857+
}
858+
823859
export interface TableRef extends AstNode {
824860
type: "tableRef"
825-
table: QualifiedName | SelectStatement | TableFunctionCall | ShowStatement
861+
table:
862+
| QualifiedName
863+
| SelectStatement
864+
| TableFunctionCall
865+
| ShowStatement
866+
| UnnestSource
867+
/** Whether this table ref was preceded by LATERAL in comma-separated FROM */
868+
lateral?: boolean
826869
alias?: string
870+
/** Column alias list for UNNEST sources, e.g. UNNEST(arr) u(val, ord) */
871+
columnAliases?: string[]
827872
joins?: JoinClause[]
828873
timestampDesignation?: string
829874
}
@@ -840,6 +885,8 @@ export interface JoinClause extends AstNode {
840885
| "window"
841886
| "horizon"
842887
outer?: boolean
888+
/** Whether LATERAL was specified after JOIN keyword */
889+
lateral?: boolean
843890
table: TableRef
844891
on?: Expression
845892
/** Tolerance interval for ASOF and LT joins (e.g., "1h", "30s") */

src/parser/cst-types.d.ts

Lines changed: 107 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -186,9 +186,61 @@ export interface FromClauseCstNode extends CstNode {
186186
}
187187

188188
export type FromClauseCstChildren = {
189-
tableRef: (TableRefCstNode)[];
189+
fromSource: (FromSourceCstNode)[];
190190
joinClause?: JoinClauseCstNode[];
191191
Comma?: IToken[];
192+
Lateral?: IToken[];
193+
};
194+
195+
export interface FromSourceCstNode extends CstNode {
196+
name: "fromSource";
197+
children: FromSourceCstChildren;
198+
}
199+
200+
export type FromSourceCstChildren = {
201+
unnestClause?: UnnestClauseCstNode[];
202+
tableRef?: TableRefCstNode[];
203+
};
204+
205+
export interface UnnestArgCstNode extends CstNode {
206+
name: "unnestArg";
207+
children: UnnestArgCstChildren;
208+
}
209+
210+
export type UnnestArgCstChildren = {
211+
expression: ExpressionCstNode[];
212+
Columns?: IToken[];
213+
LParen?: IToken[];
214+
unnestColumnDef?: (UnnestColumnDefCstNode)[];
215+
Comma?: IToken[];
216+
RParen?: IToken[];
217+
};
218+
219+
export interface UnnestColumnDefCstNode extends CstNode {
220+
name: "unnestColumnDef";
221+
children: UnnestColumnDefCstChildren;
222+
}
223+
224+
export type UnnestColumnDefCstChildren = {
225+
identifier: IdentifierCstNode[];
226+
dataType: DataTypeCstNode[];
227+
};
228+
229+
export interface UnnestClauseCstNode extends CstNode {
230+
name: "unnestClause";
231+
children: UnnestClauseCstChildren;
232+
}
233+
234+
export type UnnestClauseCstChildren = {
235+
Unnest: IToken[];
236+
LParen: (IToken)[];
237+
unnestArg: (UnnestArgCstNode)[];
238+
Comma?: (IToken)[];
239+
RParen: (IToken)[];
240+
With?: IToken[];
241+
Ordinality?: IToken[];
242+
As?: IToken[];
243+
identifier?: (IdentifierCstNode)[];
192244
};
193245

194246
export interface ImplicitSelectBodyCstNode extends CstNode {
@@ -368,6 +420,7 @@ export type StandardJoinCstChildren = {
368420
Inner?: IToken[];
369421
Cross?: IToken[];
370422
Join: IToken[];
423+
Lateral?: IToken[];
371424
tableRef: TableRefCstNode[];
372425
On?: IToken[];
373426
expression?: ExpressionCstNode[];
@@ -911,6 +964,50 @@ export type ColumnDefinitionCstChildren = {
911964
Cache?: IToken[];
912965
Nocache?: IToken[];
913966
Index?: IToken[];
967+
parquetConfig?: ParquetConfigCstNode[];
968+
};
969+
970+
export interface ParquetConfigCstNode extends CstNode {
971+
name: "parquetConfig";
972+
children: ParquetConfigCstChildren;
973+
}
974+
975+
export type ParquetConfigCstChildren = {
976+
Parquet: IToken[];
977+
LParen: (IToken)[];
978+
BloomFilter?: (IToken)[];
979+
parquetEncoding?: ParquetEncodingCstNode[];
980+
Comma?: (IToken)[];
981+
parquetCompression?: ParquetCompressionCstNode[];
982+
NumberLiteral?: IToken[];
983+
RParen: (IToken)[];
984+
};
985+
986+
export interface ParquetEncodingCstNode extends CstNode {
987+
name: "parquetEncoding";
988+
children: ParquetEncodingCstChildren;
989+
}
990+
991+
export type ParquetEncodingCstChildren = {
992+
Plain?: IToken[];
993+
RleDictionary?: IToken[];
994+
DeltaBinaryPacked?: IToken[];
995+
DeltaLengthByteArray?: IToken[];
996+
Default?: IToken[];
997+
};
998+
999+
export interface ParquetCompressionCstNode extends CstNode {
1000+
name: "parquetCompression";
1001+
children: ParquetCompressionCstChildren;
1002+
}
1003+
1004+
export type ParquetCompressionCstChildren = {
1005+
Uncompressed?: IToken[];
1006+
Snappy?: IToken[];
1007+
Gzip?: IToken[];
1008+
Brotli?: IToken[];
1009+
Zstd?: IToken[];
1010+
Lz4Raw?: IToken[];
9141011
};
9151012

9161013
export interface CastDefinitionCstNode extends CstNode {
@@ -1140,11 +1237,12 @@ export type AlterTableActionCstChildren = {
11401237
Nocache?: (IToken)[];
11411238
Index?: (IToken)[];
11421239
Symbol?: IToken[];
1240+
Set?: (IToken)[];
1241+
parquetConfig?: ParquetConfigCstNode[];
11431242
Attach?: IToken[];
11441243
Detach?: IToken[];
11451244
Squash?: IToken[];
11461245
Partitions?: IToken[];
1147-
Set?: IToken[];
11481246
Param?: IToken[];
11491247
tableParam?: (TableParamCstNode)[];
11501248
Ttl?: IToken[];
@@ -2453,6 +2551,10 @@ export interface ICstNodeVisitor<IN, OUT> extends ICstVisitor<IN, OUT> {
24532551
selectItem(children: SelectItemCstChildren, param?: IN): OUT;
24542552
qualifiedStar(children: QualifiedStarCstChildren, param?: IN): OUT;
24552553
fromClause(children: FromClauseCstChildren, param?: IN): OUT;
2554+
fromSource(children: FromSourceCstChildren, param?: IN): OUT;
2555+
unnestArg(children: UnnestArgCstChildren, param?: IN): OUT;
2556+
unnestColumnDef(children: UnnestColumnDefCstChildren, param?: IN): OUT;
2557+
unnestClause(children: UnnestClauseCstChildren, param?: IN): OUT;
24562558
implicitSelectBody(children: ImplicitSelectBodyCstChildren, param?: IN): OUT;
24572559
implicitSelectStatement(children: ImplicitSelectStatementCstChildren, param?: IN): OUT;
24582560
tableRef(children: TableRefCstChildren, param?: IN): OUT;
@@ -2498,6 +2600,9 @@ export interface ICstNodeVisitor<IN, OUT> extends ICstVisitor<IN, OUT> {
24982600
materializedViewPeriod(children: MaterializedViewPeriodCstChildren, param?: IN): OUT;
24992601
materializedViewPartition(children: MaterializedViewPartitionCstChildren, param?: IN): OUT;
25002602
columnDefinition(children: ColumnDefinitionCstChildren, param?: IN): OUT;
2603+
parquetConfig(children: ParquetConfigCstChildren, param?: IN): OUT;
2604+
parquetEncoding(children: ParquetEncodingCstChildren, param?: IN): OUT;
2605+
parquetCompression(children: ParquetCompressionCstChildren, param?: IN): OUT;
25012606
castDefinition(children: CastDefinitionCstChildren, param?: IN): OUT;
25022607
indexDefinition(children: IndexDefinitionCstChildren, param?: IN): OUT;
25032608
tableParamName(children: TableParamNameCstChildren, param?: IN): OUT;

src/parser/lexer.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import {
2727
Between,
2828
Binary,
2929
Boolean,
30+
BloomFilter,
3031
By,
3132
Bypass,
3233
Byte,
@@ -63,6 +64,8 @@ import {
6364
Dedup,
6465
Default,
6566
DefaultTransactionReadOnly,
67+
DeltaBinaryPacked,
68+
DeltaLengthByteArray,
6669
Deferred,
6770
Delay,
6871
Delete,
@@ -128,6 +131,7 @@ import {
128131
Keep,
129132
Key,
130133
Keys,
134+
Lateral,
131135
Latest,
132136
Left,
133137
Length,
@@ -172,6 +176,7 @@ import {
172176
Option,
173177
Or,
174178
Order,
179+
Ordinality,
175180
Others,
176181
Outer,
177182
Over,
@@ -188,6 +193,7 @@ import {
188193
Period,
189194
Permissions,
190195
Pivot,
196+
Plain,
191197
Prepare,
192198
Preceding,
193199
Prev,
@@ -209,6 +215,7 @@ import {
209215
Resume,
210216
Revoke,
211217
Right,
218+
RleDictionary,
212219
Row,
213220
RowGroupSize,
214221
Rows,
@@ -257,6 +264,7 @@ import {
257264
Unbounded,
258265
Union,
259266
Unlock,
267+
Unnest,
260268
Unpivot,
261269
Update,
262270
Upsert,
@@ -317,6 +325,7 @@ export {
317325
Between,
318326
Binary,
319327
Boolean,
328+
BloomFilter,
320329
By,
321330
Bypass,
322331
Byte,
@@ -353,6 +362,8 @@ export {
353362
Dedup,
354363
Default,
355364
DefaultTransactionReadOnly,
365+
DeltaBinaryPacked,
366+
DeltaLengthByteArray,
356367
Deferred,
357368
Delay,
358369
Delete,
@@ -418,6 +429,7 @@ export {
418429
Keep,
419430
Key,
420431
Keys,
432+
Lateral,
421433
Latest,
422434
Left,
423435
Length,
@@ -462,6 +474,7 @@ export {
462474
Option,
463475
Or,
464476
Order,
477+
Ordinality,
465478
Others,
466479
Outer,
467480
Over,
@@ -478,6 +491,7 @@ export {
478491
Period,
479492
Permissions,
480493
Pivot,
494+
Plain,
481495
Prepare,
482496
Preceding,
483497
Prev,
@@ -499,6 +513,7 @@ export {
499513
Resume,
500514
Revoke,
501515
Right,
516+
RleDictionary,
502517
Row,
503518
RowGroupSize,
504519
Rows,
@@ -547,6 +562,7 @@ export {
547562
Unbounded,
548563
Union,
549564
Unlock,
565+
Unnest,
550566
Unpivot,
551567
Update,
552568
Upsert,

0 commit comments

Comments
 (0)