Skip to content

Commit 1ccfa5f

Browse files
committed
support storage policy
1 parent 9aefa6e commit 1ccfa5f

10 files changed

Lines changed: 1537 additions & 48 deletions

File tree

src/parser/ast.ts

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@ export interface CreateTableStatement extends AstNode {
167167
value: number
168168
unit: "HOURS" | "DAYS" | "WEEKS" | "MONTHS" | "YEARS"
169169
}
170+
storagePolicy?: StoragePolicy
170171
withParams?: TableParam[]
171172
volume?: string
172173
ownedBy?: string
@@ -224,16 +225,38 @@ export interface CreateMaterializedViewStatement extends AstNode {
224225
period?: MaterializedViewPeriod
225226
query: SelectStatement
226227
asParens?: boolean
228+
indexes?: IndexDefinition[]
227229
timestamp?: QualifiedName
228230
partitionBy?: "YEAR" | "MONTH" | "WEEK" | "DAY" | "HOUR"
229231
ttl?: {
230232
value: number
231233
unit: "HOURS" | "DAYS" | "WEEKS" | "MONTHS" | "YEARS"
232234
}
235+
storagePolicy?: StoragePolicy
233236
volume?: string
234237
ownedBy?: string
235238
}
236239

240+
export interface StoragePolicy extends AstNode {
241+
type: "storagePolicy"
242+
toParquet?: {
243+
value: number
244+
unit: "HOURS" | "DAYS" | "WEEKS" | "MONTHS" | "YEARS"
245+
}
246+
dropNative?: {
247+
value: number
248+
unit: "HOURS" | "DAYS" | "WEEKS" | "MONTHS" | "YEARS"
249+
}
250+
dropLocal?: {
251+
value: number
252+
unit: "HOURS" | "DAYS" | "WEEKS" | "MONTHS" | "YEARS"
253+
}
254+
dropRemote?: {
255+
value: number
256+
unit: "HOURS" | "DAYS" | "WEEKS" | "MONTHS" | "YEARS"
257+
}
258+
}
259+
237260
export interface MaterializedViewRefresh extends AstNode {
238261
type: "materializedViewRefresh"
239262
mode?: "immediate" | "manual"
@@ -300,6 +323,10 @@ export type AlterMaterializedViewAction =
300323
| AlterMaterializedViewSetRefresh
301324
| AlterMaterializedViewResumeWal
302325
| AlterMaterializedViewSuspendWal
326+
| AlterMaterializedViewSetStoragePolicy
327+
| AlterMaterializedViewDropStoragePolicy
328+
| AlterMaterializedViewEnableStoragePolicy
329+
| AlterMaterializedViewDisableStoragePolicy
303330

304331
export interface AlterMaterializedViewAddIndex {
305332
actionType: "addIndex"
@@ -349,6 +376,23 @@ export interface AlterMaterializedViewSuspendWal {
349376
actionType: "suspendWal"
350377
}
351378

379+
export interface AlterMaterializedViewSetStoragePolicy {
380+
actionType: "setStoragePolicy"
381+
policy: StoragePolicy
382+
}
383+
384+
export interface AlterMaterializedViewDropStoragePolicy {
385+
actionType: "dropStoragePolicy"
386+
}
387+
388+
export interface AlterMaterializedViewEnableStoragePolicy {
389+
actionType: "enableStoragePolicy"
390+
}
391+
392+
export interface AlterMaterializedViewDisableStoragePolicy {
393+
actionType: "disableStoragePolicy"
394+
}
395+
352396
export interface AlterUserStatement extends AstNode {
353397
type: "alterUser"
354398
user: QualifiedName
@@ -415,6 +459,10 @@ export type AlterTableAction =
415459
| SuspendWalAction
416460
| ResumeWalAction
417461
| ConvertPartitionAction
462+
| SetStoragePolicyAction
463+
| DropStoragePolicyAction
464+
| EnableStoragePolicyAction
465+
| DisableStoragePolicyAction
418466

419467
export interface AddColumnAction {
420468
actionType: "addColumn"
@@ -485,6 +533,23 @@ export interface SetTtlAction {
485533
}
486534
}
487535

536+
export interface SetStoragePolicyAction {
537+
actionType: "setStoragePolicy"
538+
policy: StoragePolicy
539+
}
540+
541+
export interface DropStoragePolicyAction {
542+
actionType: "dropStoragePolicy"
543+
}
544+
545+
export interface EnableStoragePolicyAction {
546+
actionType: "enableStoragePolicy"
547+
}
548+
549+
export interface DisableStoragePolicyAction {
550+
actionType: "disableStoragePolicy"
551+
}
552+
488553
export interface DedupDisableAction {
489554
actionType: "dedupDisable"
490555
}

src/parser/cst-types.d.ts

Lines changed: 94 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -681,8 +681,7 @@ export interface DeclareAssignmentCstNode extends CstNode {
681681
export type DeclareAssignmentCstChildren = {
682682
Overridable?: IToken[];
683683
VariableReference: IToken[];
684-
ColonEquals?: IToken[];
685-
Equals?: IToken[];
684+
ColonEquals: IToken[];
686685
expression: ExpressionCstNode[];
687686
};
688687

@@ -765,6 +764,7 @@ export type CreateTableBodyCstChildren = {
765764
Week?: IToken[];
766765
Month?: IToken[];
767766
Year?: IToken[];
767+
optionalStoragePolicy: OptionalStoragePolicyCstNode[];
768768
Bypass?: IToken[];
769769
Wal?: (IToken)[];
770770
With?: IToken[];
@@ -884,9 +884,12 @@ export type CreateMaterializedViewBodyCstChildren = {
884884
LParen?: (IToken)[];
885885
selectStatement: SelectStatementCstNode[];
886886
RParen?: (IToken)[];
887+
Comma?: IToken[];
888+
indexDefinition?: IndexDefinitionCstNode[];
887889
Timestamp?: IToken[];
888890
columnRef?: ColumnRefCstNode[];
889891
materializedViewPartition?: MaterializedViewPartitionCstNode[];
892+
optionalStoragePolicy: OptionalStoragePolicyCstNode[];
890893
In?: IToken[];
891894
Volume?: IToken[];
892895
StringLiteral?: IToken[];
@@ -944,12 +947,18 @@ export type MaterializedViewPartitionCstChildren = {
944947
By: IToken[];
945948
partitionPeriod: PartitionPeriodCstNode[];
946949
Ttl?: IToken[];
950+
DurationLiteral?: IToken[];
947951
NumberLiteral?: IToken[];
948952
Hours?: IToken[];
949953
Days?: IToken[];
950954
Weeks?: IToken[];
951955
Months?: IToken[];
952956
Years?: IToken[];
957+
Hour?: IToken[];
958+
Day?: IToken[];
959+
Week?: IToken[];
960+
Month?: IToken[];
961+
Year?: IToken[];
953962
};
954963

955964
export interface ColumnDefinitionCstNode extends CstNode {
@@ -1011,6 +1020,73 @@ export type ParquetCompressionCstChildren = {
10111020
Lz4Raw?: IToken[];
10121021
};
10131022

1023+
export interface OptionalStoragePolicyCstNode extends CstNode {
1024+
name: "optionalStoragePolicy";
1025+
children: OptionalStoragePolicyCstChildren;
1026+
}
1027+
1028+
export type OptionalStoragePolicyCstChildren = {
1029+
storagePolicy?: StoragePolicyCstNode[];
1030+
};
1031+
1032+
export interface StoragePolicyCstNode extends CstNode {
1033+
name: "storagePolicy";
1034+
children: StoragePolicyCstChildren;
1035+
}
1036+
1037+
export type StoragePolicyCstChildren = {
1038+
Storage: IToken[];
1039+
Policy: IToken[];
1040+
LParen: IToken[];
1041+
storagePolicyClause?: (StoragePolicyClauseCstNode)[];
1042+
Comma?: IToken[];
1043+
RParen: IToken[];
1044+
};
1045+
1046+
export interface StoragePolicyClauseCstNode extends CstNode {
1047+
name: "storagePolicyClause";
1048+
children: StoragePolicyClauseCstChildren;
1049+
}
1050+
1051+
export type StoragePolicyClauseCstChildren = {
1052+
To?: IToken[];
1053+
Parquet?: IToken[];
1054+
storagePolicyTtl?: (StoragePolicyTtlCstNode)[];
1055+
Drop?: IToken[];
1056+
Native?: IToken[];
1057+
Local?: IToken[];
1058+
Remote?: IToken[];
1059+
};
1060+
1061+
export interface StoragePolicyTtlCstNode extends CstNode {
1062+
name: "storagePolicyTtl";
1063+
children: StoragePolicyTtlCstChildren;
1064+
}
1065+
1066+
export type StoragePolicyTtlCstChildren = {
1067+
DurationLiteral?: IToken[];
1068+
NumberLiteral?: IToken[];
1069+
storagePolicyTimeUnit?: StoragePolicyTimeUnitCstNode[];
1070+
};
1071+
1072+
export interface StoragePolicyTimeUnitCstNode extends CstNode {
1073+
name: "storagePolicyTimeUnit";
1074+
children: StoragePolicyTimeUnitCstChildren;
1075+
}
1076+
1077+
export type StoragePolicyTimeUnitCstChildren = {
1078+
Hours?: IToken[];
1079+
Days?: IToken[];
1080+
Weeks?: IToken[];
1081+
Months?: IToken[];
1082+
Years?: IToken[];
1083+
Hour?: IToken[];
1084+
Day?: IToken[];
1085+
Week?: IToken[];
1086+
Month?: IToken[];
1087+
Year?: IToken[];
1088+
};
1089+
10141090
export interface CastDefinitionCstNode extends CstNode {
10151091
name: "castDefinition";
10161092
children: CastDefinitionCstChildren;
@@ -1226,6 +1302,8 @@ export type AlterTableActionCstChildren = {
12261302
StringLiteral?: (IToken)[];
12271303
Where?: (IToken)[];
12281304
expression?: (ExpressionCstNode)[];
1305+
Storage?: (IToken)[];
1306+
Policy?: (IToken)[];
12291307
Rename?: IToken[];
12301308
To?: IToken[];
12311309
identifier?: (IdentifierCstNode)[];
@@ -1251,9 +1329,10 @@ export type AlterTableActionCstChildren = {
12511329
timeUnit?: TimeUnitCstNode[];
12521330
Bypass?: IToken[];
12531331
Wal?: (IToken)[];
1332+
storagePolicy?: StoragePolicyCstNode[];
12541333
Dedup?: IToken[];
1255-
Disable?: IToken[];
1256-
Enable?: IToken[];
1334+
Disable?: (IToken)[];
1335+
Enable?: (IToken)[];
12571336
Upsert?: IToken[];
12581337
Keys?: IToken[];
12591338
LParen?: IToken[];
@@ -1309,7 +1388,7 @@ export type AlterMaterializedViewActionCstChildren = {
13091388
Index?: (IToken)[];
13101389
Capacity?: (IToken)[];
13111390
NumberLiteral?: (IToken)[];
1312-
Drop?: IToken[];
1391+
Drop?: (IToken)[];
13131392
Symbol?: IToken[];
13141393
Set?: IToken[];
13151394
Ttl?: IToken[];
@@ -1319,12 +1398,17 @@ export type AlterMaterializedViewActionCstChildren = {
13191398
Limit?: IToken[];
13201399
materializedViewRefresh?: MaterializedViewRefreshCstNode[];
13211400
materializedViewPeriod?: MaterializedViewPeriodCstNode[];
1401+
storagePolicy?: StoragePolicyCstNode[];
13221402
Resume?: IToken[];
13231403
Wal?: (IToken)[];
13241404
From?: IToken[];
13251405
Transaction?: IToken[];
13261406
Txn?: IToken[];
13271407
Suspend?: IToken[];
1408+
Storage?: (IToken)[];
1409+
Policy?: (IToken)[];
1410+
Enable?: IToken[];
1411+
Disable?: IToken[];
13281412
};
13291413

13301414
export interface DropStatementCstNode extends CstNode {
@@ -2640,6 +2724,11 @@ export interface ICstNodeVisitor<IN, OUT> extends ICstVisitor<IN, OUT> {
26402724
parquetConfig(children: ParquetConfigCstChildren, param?: IN): OUT;
26412725
parquetEncoding(children: ParquetEncodingCstChildren, param?: IN): OUT;
26422726
parquetCompression(children: ParquetCompressionCstChildren, param?: IN): OUT;
2727+
optionalStoragePolicy(children: OptionalStoragePolicyCstChildren, param?: IN): OUT;
2728+
storagePolicy(children: StoragePolicyCstChildren, param?: IN): OUT;
2729+
storagePolicyClause(children: StoragePolicyClauseCstChildren, param?: IN): OUT;
2730+
storagePolicyTtl(children: StoragePolicyTtlCstChildren, param?: IN): OUT;
2731+
storagePolicyTimeUnit(children: StoragePolicyTimeUnitCstChildren, param?: IN): OUT;
26432732
castDefinition(children: CastDefinitionCstChildren, param?: IN): OUT;
26442733
indexDefinition(children: IndexDefinitionCstChildren, param?: IN): OUT;
26452734
tableParamName(children: TableParamNameCstChildren, param?: IN): OUT;

src/parser/lexer.ts

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,11 @@ import {
298298
Lz4Raw,
299299
Brotli,
300300
Lzo,
301+
Storage,
302+
Policy,
303+
Native,
304+
Local,
305+
Remote,
301306
} from "./tokens"
302307

303308
// Re-export all keyword tokens for parser and external use
@@ -596,6 +601,11 @@ export {
596601
Lz4Raw,
597602
Brotli,
598603
Lzo,
604+
Storage,
605+
Policy,
606+
Native,
607+
Local,
608+
Remote,
599609
}
600610

601611
// =============================================================================
@@ -727,12 +737,21 @@ export const DecimalLiteral = createToken({
727737
})
728738

729739
// QuestDB time units for SAMPLE BY (e.g., 1h, 5m, 30s, 1d, 1M, 1y, 100T, 1U, 1.5d)
730-
// Units: n=nanos, u/U=micros, T=millis, ms=millis, s=seconds, m=minutes, h/H=hours, d=days, w=weeks, M=months, y=years
731-
// Supports decimal values like 1.5d, 0.5h
732-
// Multi-char units (ms, us) must appear before single-char alternatives to avoid prefix match
740+
// and storage policy / TTL DDL (e.g., 2Y, 2W, 2D, 1M).
741+
// SAMPLE BY units: n=nanos, u/U=micros, T=millis, ms=millis, s=seconds,
742+
// m=minutes, h/H=hours, d=days, w=weeks, M=months, y=years.
743+
// Storage policy / TTL docs additionally use the uppercase canonical forms
744+
// H, D, W, M, Y for hour/day/week/month/year — QuestDB's TTL parser is
745+
// case-insensitive on the unit suffix (LowerCaseCharSequenceIntHashMap in
746+
// PartitionBy.ttlUnitToIndexMap), so we accept D/W/Y here too. Semantic
747+
// disambiguation (e.g. rejecting nanos in storage policy) is enforced by
748+
// per-context grammar rules.
749+
// Supports decimal values like 1.5d, 0.5h.
750+
// Multi-char units (ms, us) must appear before single-char alternatives to
751+
// avoid prefix match.
733752
export const DurationLiteral = createToken({
734753
name: "DurationLiteral",
735-
pattern: /\d[\d_]*(\.\d[\d_]*)?(ms|us|[smhdMyNnTUuHw])/,
754+
pattern: /\d[\d_]*(\.\d[\d_]*)?(ms|us|[smhdwyMDWYNnTUuH])/,
736755
})
737756

738757
// Numbers (negation is handled as unary minus in the parser, not in the lexer)

0 commit comments

Comments
 (0)