@itwin/ecsql-common 4.2.0-dev.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,2384 @@
1
+ import { asInstanceOf, isInstanceOf } from "@itwin/core-bentley";
2
+ /**
3
+ * Id returned by native code
4
+ * @internal
5
+ */
6
+ var NativeExpIds;
7
+ (function (NativeExpIds) {
8
+ NativeExpIds["AllOrAny"] = "AllOrAnyExp";
9
+ NativeExpIds["Assignment"] = "AssignmentExp";
10
+ NativeExpIds["BetweenRangeValue"] = "BetweenRangeValueExp";
11
+ NativeExpIds["BinaryBoolean"] = "BinaryBooleanExp";
12
+ NativeExpIds["BinaryValue"] = "BinaryValueExp";
13
+ NativeExpIds["BooleanFactor"] = "BooleanFactorExp";
14
+ NativeExpIds["Cast"] = "CastExp";
15
+ NativeExpIds["ClassName"] = "ClassNameExp";
16
+ NativeExpIds["CommonTable"] = "CommonTableExp";
17
+ NativeExpIds["CommonTableBlock"] = "CommonTableBlockExp";
18
+ NativeExpIds["CommonTableBlockName"] = "CommonTableBlockNameExp";
19
+ NativeExpIds["CrossJoin"] = "CrossJoinExp";
20
+ NativeExpIds["DeleteStatement"] = "DeleteStatementExp";
21
+ NativeExpIds["DerivedProperty"] = "DerivedPropertyExp";
22
+ NativeExpIds["FunctionCall"] = "FunctionCallExp";
23
+ NativeExpIds["IIF"] = "IIFExp";
24
+ NativeExpIds["InsertStatement"] = "InsertStatementExp";
25
+ NativeExpIds["LikeRhsValue"] = "LikeRhsValueExp";
26
+ NativeExpIds["LimitOffset"] = "LimitOffsetExp";
27
+ NativeExpIds["LiteralValue"] = "LiteralValueExp";
28
+ NativeExpIds["MemberFunctionCall"] = "MemberFunctionCallExp";
29
+ NativeExpIds["NaturalJoin"] = "NaturalJoinExp";
30
+ NativeExpIds["Options"] = "OptionsExp";
31
+ NativeExpIds["OrderBySpec"] = "OrderBySpecExp";
32
+ NativeExpIds["Parameter"] = "ParameterExp";
33
+ NativeExpIds["PropertyName"] = "PropertyNameExp";
34
+ NativeExpIds["QualifiedJoin"] = "QualifiedJoinExp";
35
+ NativeExpIds["RowConstructor"] = "RowConstructor";
36
+ NativeExpIds["SearchCaseValue"] = "SearchCaseValueExp";
37
+ NativeExpIds["SelectStatement"] = "SelectStatementExp";
38
+ NativeExpIds["SingleSelectStatement"] = "SingleSelectStatementExp";
39
+ NativeExpIds["Subquery"] = "SubqueryExp";
40
+ NativeExpIds["SubqueryRef"] = "SubqueryRefExp";
41
+ NativeExpIds["SubqueryTest"] = "SubqueryTestExp";
42
+ NativeExpIds["TableValuedFunction"] = "TableValuedFunctionExp";
43
+ NativeExpIds["UnaryValue"] = "UnaryValueExp";
44
+ NativeExpIds["UpdateStatement"] = "UpdateStatementExp";
45
+ NativeExpIds["UsingRelationshipJoinExp"] = "UsingRelationshipJoinExp";
46
+ })(NativeExpIds || (NativeExpIds = {}));
47
+ /**
48
+ * Type of literal value.
49
+ * @alpha
50
+ */
51
+ export var LiteralValueType;
52
+ (function (LiteralValueType) {
53
+ LiteralValueType["Null"] = "NULL";
54
+ LiteralValueType["String"] = "STRING";
55
+ LiteralValueType["Date"] = "DATE";
56
+ LiteralValueType["Time"] = "TIME";
57
+ LiteralValueType["Timestamp"] = "TIMESTAMP";
58
+ LiteralValueType["Raw"] = "RAW";
59
+ })(LiteralValueType || (LiteralValueType = {}));
60
+ /**
61
+ * Qualified JOIN type @see [[QualifiedJoinExpr]]
62
+ * @alpha
63
+ */
64
+ export var JoinType;
65
+ (function (JoinType) {
66
+ JoinType["LeftOuter"] = "LEFT OUTER JOIN";
67
+ JoinType["RightOuter"] = "RIGHT OUTER JOIN";
68
+ JoinType["FullOuter"] = "FULL OUTER JOIN";
69
+ JoinType["Inner"] = "INNER JOIN";
70
+ })(JoinType || (JoinType = {}));
71
+ /**
72
+ * ECSql expr type supported @see [[Expr]]
73
+ * @alpha
74
+ */
75
+ export var ExprType;
76
+ (function (ExprType) {
77
+ ExprType["Literal"] = "Literal";
78
+ ExprType["Unary"] = "Unary";
79
+ ExprType["Parameter"] = "Parameter";
80
+ ExprType["Cast"] = "Cast";
81
+ ExprType["BinaryValue"] = "BinaryValue";
82
+ ExprType["SearchCase"] = "SearchCase";
83
+ ExprType["IIF"] = "IIF";
84
+ ExprType["FuncCall"] = "FuncCall";
85
+ ExprType["PropertyName"] = "PropertyName";
86
+ ExprType["Subquery"] = "Subquery";
87
+ ExprType["Between"] = "Between";
88
+ // Match = "Match",
89
+ ExprType["Like"] = "Like";
90
+ ExprType["In"] = "In";
91
+ ExprType["Not"] = "Not";
92
+ ExprType["IsOfType"] = "IsOfType";
93
+ ExprType["IsNull"] = "IsNull";
94
+ ExprType["BinaryBoolean"] = "BinaryBoolean";
95
+ ExprType["SubqueryTest"] = "SubqueryTest";
96
+ ExprType["UsingRelationshipJoin"] = "UsingRelationshipJoin";
97
+ ExprType["QualifiedJoin"] = "QualifiedJoin";
98
+ ExprType["SubqueryRef"] = "SubqueryRef";
99
+ ExprType["CteBlockRef"] = "CteBlockRef";
100
+ ExprType["ClassName"] = "ClassName";
101
+ ExprType["TableValuedFunc"] = "TableValuedFunc";
102
+ ExprType["DerivedProperty"] = "DerivedProperty";
103
+ ExprType["SetClause"] = "SetClause";
104
+ ExprType["Select"] = "Select";
105
+ ExprType["ECSqlOptionsClause"] = "ECSqlOptions";
106
+ ExprType["CteBlock"] = "CteBlock";
107
+ ExprType["MemberFuncCall"] = "MemberFuncCall";
108
+ ExprType["Cte"] = "Cte";
109
+ ExprType["UpdateStatement"] = "UpdateStatement";
110
+ ExprType["InsertStatement"] = "InsertStatement";
111
+ ExprType["DeleteStatement"] = "DeleteStatement";
112
+ ExprType["SelectStatement"] = "SelectStatement";
113
+ ExprType["SelectionClause"] = "SelectionClause";
114
+ ExprType["WhereClause"] = "WhereClause";
115
+ ExprType["GroupByClause"] = "GroupByClause";
116
+ ExprType["HavingClause"] = "HavingCluase";
117
+ ExprType["FromClause"] = "FromClause";
118
+ ExprType["OrderByClause"] = "OrderByClause";
119
+ ExprType["OrderBySpec"] = "OrderBySpec";
120
+ ExprType["LimitClause"] = "LimitClause";
121
+ ExprType["Assignment"] = "Assignment";
122
+ })(ExprType || (ExprType = {}));
123
+ /**
124
+ * Allow to create statement expression tree from a ecsql
125
+ * @alpha
126
+ */
127
+ export class ExprFactory {
128
+ constructor(provider) {
129
+ this.provider = provider;
130
+ }
131
+ async parseStatement(ecsql) {
132
+ return StatementExpr.deserialize(this.provider.parseECSql(ecsql));
133
+ }
134
+ }
135
+ /**
136
+ * Base class for all ECSql expressions.
137
+ * @alpha
138
+ */
139
+ export class Expr {
140
+ constructor(expType) {
141
+ this.expType = expType;
142
+ }
143
+ /**
144
+ * Find instances of expressions matching the type in sub tree.
145
+ * @param type a subclass of Expr
146
+ * @returns
147
+ */
148
+ findInstancesOf(type) {
149
+ const listOfT = [];
150
+ this.traverse((expr) => {
151
+ const inst = expr.asInstanceOf(type);
152
+ if (inst)
153
+ listOfT.push(inst);
154
+ });
155
+ return listOfT;
156
+ }
157
+ /**
158
+ * Allow to traverse the expression tree depth first
159
+ * @param callback this will be called for each expression traverse from first to last.
160
+ */
161
+ traverse(callback) {
162
+ const list = [this];
163
+ let parent;
164
+ while (list.length > 0) {
165
+ const current = list.pop();
166
+ if (current) {
167
+ const rc = callback(current, parent);
168
+ if (typeof rc === "boolean") {
169
+ if (!rc)
170
+ return;
171
+ }
172
+ parent = current;
173
+ list.push(...current.children.reverse());
174
+ }
175
+ }
176
+ }
177
+ /**
178
+ * Test if class instance is of certain type
179
+ * @param type A class that extends from Expr
180
+ * @returns true if instances matches the type else return false.
181
+ */
182
+ isInstanceOf(type) { return isInstanceOf(this, type); }
183
+ asInstanceOf(type) { return asInstanceOf(this, type); }
184
+ /**
185
+ * Convert expression tree to ECSQL.
186
+ * @param args args to ecsql writer.
187
+ * @returns ECSQL string
188
+ */
189
+ toECSql(args) {
190
+ if (args) {
191
+ const customWriter = new ECSqlWriter(args);
192
+ this.writeTo(customWriter);
193
+ return customWriter.toString();
194
+ }
195
+ const defaultWriter = new ECSqlWriter();
196
+ this.writeTo(defaultWriter);
197
+ return defaultWriter.toString();
198
+ }
199
+ }
200
+ /**
201
+ * Base class for all ECSQL Statements. Here are list of subclasses @see [[CteExpr]], @see [[SelectStatement]], @see [[InsertStatement]], @see [UpdateStatement]] and @see [[DeleteStatement]]
202
+ * @alpha
203
+ */
204
+ export class StatementExpr extends Expr {
205
+ static deserialize(node) {
206
+ if (node.id === NativeExpIds.CommonTable)
207
+ return CteExpr.deserialize(node);
208
+ if (node.id === NativeExpIds.InsertStatement)
209
+ return InsertStatementExpr.deserialize(node);
210
+ if (node.id === NativeExpIds.UpdateStatement)
211
+ return UpdateStatementExpr.deserialize(node);
212
+ if (node.id === NativeExpIds.DeleteStatement)
213
+ return DeleteStatementExpr.deserialize(node);
214
+ if (node.id === NativeExpIds.SelectStatement)
215
+ return SelectStatementExpr.deserialize(node);
216
+ throw new Error(`unknow node.id = ${node.id}`);
217
+ }
218
+ }
219
+ /**
220
+ * Base class for all computed expression like Value and Boolean.
221
+ * @alpha
222
+ */
223
+ export class ComputedExpr extends Expr {
224
+ static deserialize(node) {
225
+ if (BooleanExpr.deserializableIds.includes(node.id)) {
226
+ return BooleanExpr.deserialize(node);
227
+ }
228
+ if (ValueExpr.deserializableIds.includes(node.id)) {
229
+ return ValueExpr.deserialize(node);
230
+ }
231
+ throw new Error(`unknow node.id = ${node.id}`);
232
+ }
233
+ }
234
+ /**
235
+ * Base class for a boolean expressions. It has following subclasses
236
+ * @see [[BooleanExpr]]
237
+ * @see [[ubqueryTestExpr]]
238
+ * @see [[BetweenExpr]]
239
+ * @see [[LikeExpr]]
240
+ * @see [[InExpr]]
241
+ * @see [[IsNullExpr]]
242
+ * @see [[IsOfTypeExpr]]
243
+ * @see [[NotExpr]]
244
+ * @see [[BinaryBooleanExpr]]
245
+ * @alpha
246
+ */
247
+ class BooleanExpr extends ComputedExpr {
248
+ static deserialize(node) {
249
+ if (node.id === NativeExpIds.BinaryBoolean) {
250
+ const op = node.op;
251
+ // if (MatchExpr.parseOp(op)[0]) {
252
+ // return MatchExpr.deserialize(node);
253
+ // }
254
+ if (BetweenExpr.parseOp(op)[0]) {
255
+ return BetweenExpr.deserialize(node);
256
+ }
257
+ if (LikeExpr.parseOp(op)[0]) {
258
+ return LikeExpr.deserialize(node);
259
+ }
260
+ if (InExpr.parseOp(op)[0]) {
261
+ return InExpr.deserialize(node);
262
+ }
263
+ if (IsNullExpr.parseOp(node)[0]) {
264
+ return IsNullExpr.deserialize(node);
265
+ }
266
+ if (IsOfTypeExpr.parseOp(node)[0]) {
267
+ return IsOfTypeExpr.deserialize(node);
268
+ }
269
+ return BinaryBooleanExpr.deserialize(node);
270
+ }
271
+ if (node.id === NativeExpIds.BooleanFactor) {
272
+ return NotExpr.deserialize(node);
273
+ }
274
+ if (node.id === NativeExpIds.SubqueryTest) {
275
+ return SubqueryTestExpr.deserialize(node);
276
+ }
277
+ if (node.id === NativeExpIds.BooleanFactor) {
278
+ return NotExpr.deserialize(node);
279
+ }
280
+ throw new Error(`Unknown type of native value exp ${node.id}`);
281
+ }
282
+ }
283
+ BooleanExpr.deserializableIds = [NativeExpIds.BinaryBoolean, NativeExpIds.BooleanFactor, NativeExpIds.SubqueryTest, NativeExpIds.AllOrAny, NativeExpIds.BooleanFactor];
284
+ export { BooleanExpr };
285
+ /**
286
+ * Base class for all value expressions. Following is list of subclasses.
287
+ * @see [[SubqueryExpr]]
288
+ * @see [[ValueExpr]]
289
+ * @see [[UnaryValueExpr]]
290
+ * @see [[FuncCallExpr]]
291
+ * @see [[CastExpr]]
292
+ * @see [[BinaryValueExpr]]
293
+ * @see [[SearchCaseExpr]]
294
+ * @see [[IIFExpr]]
295
+ * @see [[LiteralExpr]]
296
+ * @see [[PropertyNameExpr]]
297
+ * @alpha
298
+ */
299
+ class ValueExpr extends ComputedExpr {
300
+ static deserialize(node) {
301
+ if (node.id === NativeExpIds.UnaryValue) {
302
+ return UnaryValueExpr.deserialize(node);
303
+ }
304
+ if (node.id === NativeExpIds.PropertyName) {
305
+ return PropertyNameExpr.deserialize(node);
306
+ }
307
+ if (node.id === NativeExpIds.Parameter) {
308
+ return ParameterExpr.deserialize(node);
309
+ }
310
+ if (node.id === NativeExpIds.FunctionCall) {
311
+ return FuncCallExpr.deserialize(node);
312
+ }
313
+ if (node.id === NativeExpIds.Cast) {
314
+ return CastExpr.deserialize(node);
315
+ }
316
+ if (node.id === NativeExpIds.Subquery) {
317
+ return SubqueryExpr.deserialize(node);
318
+ }
319
+ if (node.id === NativeExpIds.BinaryValue) {
320
+ return BinaryValueExpr.deserialize(node);
321
+ }
322
+ if (node.id === NativeExpIds.SearchCaseValue) {
323
+ return SearchCaseExpr.deserialize(node);
324
+ }
325
+ if (node.id === NativeExpIds.IIF) {
326
+ return IIFExpr.deserialize(node);
327
+ }
328
+ if (node.id === NativeExpIds.LiteralValue) {
329
+ return LiteralExpr.deserialize(node);
330
+ }
331
+ throw new Error(`Unknown type of native value exp ${node.id}`);
332
+ }
333
+ }
334
+ ValueExpr.deserializableIds = [
335
+ NativeExpIds.LiteralValue,
336
+ NativeExpIds.Parameter,
337
+ NativeExpIds.FunctionCall,
338
+ NativeExpIds.Cast,
339
+ NativeExpIds.BinaryValue,
340
+ NativeExpIds.SearchCaseValue,
341
+ NativeExpIds.IIF,
342
+ NativeExpIds.UnaryValue,
343
+ NativeExpIds.PropertyName,
344
+ NativeExpIds.Subquery,
345
+ ];
346
+ export { ValueExpr };
347
+ /**
348
+ * Base class for expressions that can be used in FROM clause of a SELECT. Following list of this subclasses.
349
+ * @see [[ClassRefExpr]]
350
+ * @see [[ClassNameExpr]]
351
+ * @see [[SubqueryRefExpr]]
352
+ * @see [[UsingRelationshipJoinExpr]]
353
+ * @see [[QualifiedJoinExpr]]
354
+ * @see [[CteBlockRefExpr]]
355
+ * @see [[TableValuedFuncExpr]]
356
+ * @alpha
357
+ */
358
+ class ClassRefExpr extends Expr {
359
+ static deserialize(node) {
360
+ if (node.id === NativeExpIds.ClassName) {
361
+ return ClassNameExpr.deserialize(node);
362
+ }
363
+ if (node.id === NativeExpIds.SubqueryRef) {
364
+ return SubqueryRefExpr.deserialize(node);
365
+ }
366
+ if (node.id === NativeExpIds.UsingRelationshipJoinExp) {
367
+ return UsingRelationshipJoinExpr.deserialize(node);
368
+ }
369
+ if (node.id === NativeExpIds.QualifiedJoin) {
370
+ return QualifiedJoinExpr.deserialize(node);
371
+ }
372
+ if (node.id === NativeExpIds.CommonTableBlockName) {
373
+ return CteBlockRefExpr.deserialize(node);
374
+ }
375
+ if (node.id === NativeExpIds.TableValuedFunction) {
376
+ return TableValuedFuncExpr.deserialize(node);
377
+ }
378
+ throw new Error(`Unknown type of native value exp ${node.id}`);
379
+ }
380
+ }
381
+ ClassRefExpr.deserializableIds = [
382
+ NativeExpIds.ClassName,
383
+ NativeExpIds.SubqueryRef,
384
+ NativeExpIds.UsingRelationshipJoinExp,
385
+ NativeExpIds.QualifiedJoin,
386
+ NativeExpIds.CommonTableBlockName,
387
+ ];
388
+ export { ClassRefExpr };
389
+ /**
390
+ * Write expression tree to string
391
+ * @alpha
392
+ */
393
+ export class ECSqlWriter {
394
+ constructor(options = {
395
+ multiline: false,
396
+ spaceAfterComma: true,
397
+ spaceAroundBinOp: true,
398
+ eol: "\r\n",
399
+ keywordCasing: "UPPER",
400
+ indent: { size: 3, char: " " },
401
+ }) {
402
+ this.options = options;
403
+ this._tokens = [];
404
+ this._currentIndent = 0;
405
+ this._isNewLine = false;
406
+ }
407
+ indent() {
408
+ this._currentIndent++;
409
+ }
410
+ unindent() {
411
+ if (this._currentIndent > 0)
412
+ this._currentIndent--;
413
+ }
414
+ appendBinaryOp(val) {
415
+ if (this.options.spaceAroundBinOp)
416
+ return this.append(` ${val} `);
417
+ return this.append(val);
418
+ }
419
+ appendKeyword(val) {
420
+ if (this.options.keywordCasing === "UPPER")
421
+ return this.append(val);
422
+ return this.append(val.toLowerCase());
423
+ }
424
+ appendComma() {
425
+ this.append(",");
426
+ if (this.options.spaceAfterComma)
427
+ this.appendSpace();
428
+ }
429
+ appendQuoted(val) {
430
+ return this.append(`[${val}]`);
431
+ }
432
+ append(val) {
433
+ if (this._isNewLine) {
434
+ if (this._currentIndent > 0 && this.options.indent.size > 0 && this.options.indent.char.length === 1) {
435
+ this._tokens.push("".padEnd(this._currentIndent * this.options.indent.size, this.options.indent.char));
436
+ }
437
+ this._isNewLine = false;
438
+ }
439
+ this._tokens.push(val);
440
+ return this;
441
+ }
442
+ appendStringLiteral(val) {
443
+ return this.append(`'${val}'`);
444
+ }
445
+ appendLineOrSpace() {
446
+ if (this.options.multiline)
447
+ return this.appendLine();
448
+ return this.appendSpace();
449
+ }
450
+ appendSpace() {
451
+ return this.append(" ");
452
+ }
453
+ appendLine() {
454
+ if (this.options.multiline) {
455
+ this._isNewLine = true;
456
+ if (this._tokens.length > 0) {
457
+ this._tokens[this._tokens.length - 1] = this._tokens[this._tokens.length - 1].trimEnd();
458
+ }
459
+ this._tokens.push(this.options.eol);
460
+ }
461
+ return this;
462
+ }
463
+ clear() {
464
+ this._tokens = [];
465
+ return this;
466
+ }
467
+ squash() {
468
+ if (this._tokens.length > 1) {
469
+ this._tokens = [this.toString()];
470
+ }
471
+ return this;
472
+ }
473
+ toString() {
474
+ return this._tokens.join("");
475
+ }
476
+ appendExp(exp) {
477
+ exp.writeTo(this);
478
+ return this;
479
+ }
480
+ }
481
+ /**
482
+ * Use to describe selection clause terms in a SELECT statements @see [[SelectionClauseExpr]] @see [[SelectExpr]]
483
+ * @alpha
484
+ */
485
+ class DerivedPropertyExpr extends Expr {
486
+ constructor(computedExpr, alias) {
487
+ super(DerivedPropertyExpr.type);
488
+ this.computedExpr = computedExpr;
489
+ this.alias = alias;
490
+ }
491
+ get children() {
492
+ return [this.computedExpr];
493
+ }
494
+ static deserialize(node) {
495
+ if (node.id !== NativeExpIds.DerivedProperty) {
496
+ throw new Error(`Parse node is 'node.id !== NativeExpIds.DerivedProperty'. ${JSON.stringify(node)}`);
497
+ }
498
+ return new DerivedPropertyExpr(ComputedExpr.deserialize(node.exp), node.alias ? node.alias : undefined);
499
+ }
500
+ writeTo(writer) {
501
+ writer.appendExp(this.computedExpr);
502
+ if (this.alias) {
503
+ writer.appendSpace();
504
+ writer.appendQuoted(this.alias);
505
+ }
506
+ }
507
+ }
508
+ DerivedPropertyExpr.type = ExprType.DerivedProperty;
509
+ export { DerivedPropertyExpr };
510
+ /**
511
+ * Describes a ECSQL delete statement.
512
+ * @alpha
513
+ */
514
+ class DeleteStatementExpr extends StatementExpr {
515
+ constructor(className, where, options) {
516
+ super(DeleteStatementExpr.type);
517
+ this.className = className;
518
+ this.where = where;
519
+ this.options = options;
520
+ }
521
+ get children() {
522
+ const exprs = [this.className];
523
+ if (this.where)
524
+ exprs.push(this.where);
525
+ if (this.options)
526
+ exprs.push(this.options);
527
+ return exprs;
528
+ }
529
+ static deserialize(node) {
530
+ if (node.id !== NativeExpIds.DeleteStatement) {
531
+ throw new Error(`Parse node is 'node.id !== NativeExpIds.DeleteStatement'. ${JSON.stringify(node)}`);
532
+ }
533
+ const className = ClassNameExpr.deserialize(node.class);
534
+ const where = node.where ? WhereClauseExp.deserialize(node.where) : undefined;
535
+ const options = node.options ? ECSqlOptionsClauseExpr.deserialize(node.options) : undefined;
536
+ return new DeleteStatementExpr(className, where, options);
537
+ }
538
+ writeTo(writer) {
539
+ writer.appendKeyword("DELETE");
540
+ writer.appendSpace();
541
+ writer.appendKeyword("FROM");
542
+ writer.appendSpace();
543
+ writer.appendExp(this.className);
544
+ if (this.where) {
545
+ writer.appendSpace();
546
+ writer.appendExp(this.where);
547
+ }
548
+ if (this.options) {
549
+ writer.appendSpace();
550
+ writer.appendExp(this.options);
551
+ }
552
+ }
553
+ }
554
+ DeleteStatementExpr.type = ExprType.DeleteStatement;
555
+ export { DeleteStatementExpr };
556
+ /**
557
+ * Describe a ECSQL Insert statement.
558
+ * @alpha
559
+ */
560
+ class InsertStatementExpr extends StatementExpr {
561
+ constructor(className, values, propertyNames) {
562
+ super(InsertStatementExpr.type);
563
+ this.className = className;
564
+ this.values = values;
565
+ this.propertyNames = propertyNames;
566
+ }
567
+ get children() {
568
+ const exprs = [this.className];
569
+ exprs.push(...this.values);
570
+ if (this.propertyNames)
571
+ exprs.push(...this.propertyNames);
572
+ return exprs;
573
+ }
574
+ static deserialize(node) {
575
+ if (node.id !== NativeExpIds.InsertStatement) {
576
+ throw new Error(`Parse node is 'node.id !== NativeExpIds.InsertStatement'. ${JSON.stringify(node)}`);
577
+ }
578
+ const className = ClassNameExpr.deserialize(node.class);
579
+ if (className.polymorphicInfo) {
580
+ // Patch as INSERT are always ONLY but parser have issue accepting ONLY.
581
+ if (className.polymorphicInfo.allOrAny === "ONLY") {
582
+ className.polymorphicInfo = undefined;
583
+ }
584
+ }
585
+ const values = Array.from(node.values.map((v) => ValueExpr.deserialize(v)));
586
+ const properties = node.properties ? Array.from(node.properties.map((v) => PropertyNameExpr.deserialize(v))) : undefined;
587
+ return new InsertStatementExpr(className, values, properties);
588
+ }
589
+ writeTo(writer) {
590
+ writer.appendKeyword("INSERT");
591
+ writer.appendSpace();
592
+ writer.appendKeyword("INTO");
593
+ writer.appendSpace();
594
+ writer.appendExp(this.className);
595
+ writer.appendSpace();
596
+ if (this.propertyNames) {
597
+ writer.append("(");
598
+ this.propertyNames.forEach((v, i) => {
599
+ if (i > 0) {
600
+ writer.appendComma();
601
+ }
602
+ writer.appendExp(v);
603
+ });
604
+ writer.append(")");
605
+ }
606
+ writer.appendSpace();
607
+ writer.appendKeyword("VALUES");
608
+ writer.append("(");
609
+ this.values.forEach((v, i) => {
610
+ if (i > 0) {
611
+ writer.appendComma();
612
+ }
613
+ writer.appendExp(v);
614
+ });
615
+ writer.append(")");
616
+ }
617
+ }
618
+ InsertStatementExpr.type = ExprType.InsertStatement;
619
+ export { InsertStatementExpr };
620
+ /**
621
+ * Describes a JOIN clause e.g. <classNameExpr> JOIN <classNameExpr> ON <joinspec>
622
+ * @alpha
623
+ */
624
+ class QualifiedJoinExpr extends ClassRefExpr {
625
+ constructor(joinType, from, to, spec) {
626
+ super(QualifiedJoinExpr.type);
627
+ this.joinType = joinType;
628
+ this.from = from;
629
+ this.to = to;
630
+ this.spec = spec;
631
+ }
632
+ get children() {
633
+ const exprs = [this.from, this.to];
634
+ if (this.spec instanceof BooleanExpr)
635
+ exprs.push(this.spec);
636
+ return exprs;
637
+ }
638
+ static deserialize(node) {
639
+ if (node.id !== NativeExpIds.QualifiedJoin) {
640
+ throw new Error(`Parse node is 'node.id !== NativeExpIds.QualifiedJoin'. ${JSON.stringify(node)}`);
641
+ }
642
+ const type = node.type;
643
+ const from = ClassRefExpr.deserialize(node.from);
644
+ const to = ClassRefExpr.deserialize(node.to);
645
+ let spec;
646
+ if (Array.isArray(node.spec))
647
+ spec = node.spec;
648
+ else
649
+ spec = BooleanExpr.deserialize(node.spec);
650
+ return new QualifiedJoinExpr(type, from, to, spec);
651
+ }
652
+ writeTo(writer) {
653
+ writer.appendExp(this.from);
654
+ writer.appendSpace();
655
+ if (this.joinType === JoinType.LeftOuter) {
656
+ writer.appendKeyword("LEFT").appendSpace();
657
+ writer.appendKeyword("OUTER").appendSpace();
658
+ writer.appendKeyword("JOIN").appendSpace();
659
+ }
660
+ else if (this.joinType === JoinType.RightOuter) {
661
+ writer.appendKeyword("RIGHT").appendSpace();
662
+ writer.appendKeyword("OUTER").appendSpace();
663
+ writer.appendKeyword("JOIN").appendSpace();
664
+ }
665
+ else if (this.joinType === JoinType.FullOuter) {
666
+ writer.appendKeyword("FULL").appendSpace();
667
+ writer.appendKeyword("OUTER").appendSpace();
668
+ writer.appendKeyword("JOIN").appendSpace();
669
+ }
670
+ else if (this.joinType === JoinType.Inner) {
671
+ writer.appendKeyword("INNER").appendSpace();
672
+ writer.appendKeyword("JOIN").appendSpace();
673
+ }
674
+ else {
675
+ throw new Error(`not supported join type ${this.joinType}`);
676
+ }
677
+ writer.appendExp(this.to);
678
+ if (this.spec) {
679
+ writer.appendSpace();
680
+ if (this.spec instanceof BooleanExpr) {
681
+ writer.appendKeyword("ON");
682
+ writer.appendSpace();
683
+ writer.appendExp(this.spec);
684
+ }
685
+ else if (this.spec instanceof Array) {
686
+ writer.appendKeyword("USING");
687
+ this.spec.forEach((v, i) => {
688
+ if (i > 0) {
689
+ writer.appendComma();
690
+ writer.append(v);
691
+ }
692
+ });
693
+ }
694
+ else {
695
+ throw new Error("unknow join spec");
696
+ }
697
+ }
698
+ }
699
+ }
700
+ QualifiedJoinExpr.type = ExprType.QualifiedJoin;
701
+ export { QualifiedJoinExpr };
702
+ /**
703
+ * Describe a JOIN USING clause.
704
+ * @alpha
705
+ */
706
+ class UsingRelationshipJoinExpr extends ClassRefExpr {
707
+ constructor(fromClassName, toClassName, toRelClassName, direction) {
708
+ super(UsingRelationshipJoinExpr.type);
709
+ this.fromClassName = fromClassName;
710
+ this.toClassName = toClassName;
711
+ this.toRelClassName = toRelClassName;
712
+ this.direction = direction;
713
+ }
714
+ get children() {
715
+ return [this.fromClassName, this.toClassName, this.toRelClassName];
716
+ }
717
+ static deserialize(node) {
718
+ if (node.id !== NativeExpIds.UsingRelationshipJoinExp) {
719
+ throw new Error(`Parse node is 'node.id !== NativeExpIds.UsingRelationshipJoinExp'. ${JSON.stringify(node)}`);
720
+ }
721
+ const from = ClassRefExpr.deserialize(node.from);
722
+ const to = ClassNameExpr.deserialize(node.to);
723
+ const usingRel = ClassNameExpr.deserialize(node.using);
724
+ const direction = node.direction ? node.direction : undefined;
725
+ return new UsingRelationshipJoinExpr(from, to, usingRel, direction);
726
+ }
727
+ writeTo(writer) {
728
+ writer.appendExp(this.fromClassName);
729
+ writer.appendSpace();
730
+ writer.appendKeyword("JOIN");
731
+ writer.appendSpace();
732
+ writer.appendExp(this.toClassName);
733
+ writer.appendSpace();
734
+ writer.appendKeyword("USING");
735
+ writer.appendSpace();
736
+ writer.appendExp(this.toRelClassName);
737
+ if (this.direction) {
738
+ writer.appendSpace();
739
+ writer.appendKeyword(this.direction);
740
+ }
741
+ }
742
+ }
743
+ UsingRelationshipJoinExpr.type = ExprType.UsingRelationshipJoin;
744
+ export { UsingRelationshipJoinExpr };
745
+ /**
746
+ * Describe subquery result test e.g. EXISTS(<subquery>)
747
+ * @alpha
748
+ */
749
+ class SubqueryTestExpr extends BooleanExpr {
750
+ constructor(op, query) {
751
+ super(SubqueryTestExpr.type);
752
+ this.op = op;
753
+ this.query = query;
754
+ }
755
+ get children() {
756
+ return [this.query];
757
+ }
758
+ static deserialize(node) {
759
+ if (node.id !== NativeExpIds.SubqueryTest) {
760
+ throw new Error(`Parse node is 'node.id !== NativeExpIds.SubqueryTest'. ${JSON.stringify(node)}`);
761
+ }
762
+ const query = SubqueryExpr.deserialize(node.query);
763
+ const op = node.op;
764
+ return new SubqueryTestExpr(op, query);
765
+ }
766
+ writeTo(writer) {
767
+ writer.appendKeyword(this.op);
768
+ writer.appendExp(this.query);
769
+ }
770
+ }
771
+ SubqueryTestExpr.type = ExprType.SubqueryTest;
772
+ export { SubqueryTestExpr };
773
+ /**
774
+ * Describe a subquery when used in FROM clause.
775
+ * @alpha
776
+ */
777
+ class SubqueryRefExpr extends ClassRefExpr {
778
+ constructor(query, polymorphicInfo, alias) {
779
+ super(SubqueryRefExpr.type);
780
+ this.query = query;
781
+ this.polymorphicInfo = polymorphicInfo;
782
+ this.alias = alias;
783
+ }
784
+ get children() {
785
+ return [this.query];
786
+ }
787
+ static deserialize(node) {
788
+ if (node.id !== NativeExpIds.SubqueryRef) {
789
+ throw new Error(`Parse node is 'node.id !== NativeExpIds.SubqueryRef'. ${JSON.stringify(node)}`);
790
+ }
791
+ const query = SubqueryExpr.deserialize(node.query);
792
+ const polymorphicInfo = node.polymorphicInfo ? node.polymorphicInfo : undefined;
793
+ const alias = node.alias ? node.alias : undefined;
794
+ return new SubqueryRefExpr(query, polymorphicInfo, alias);
795
+ }
796
+ writeTo(writer) {
797
+ if (this.polymorphicInfo) {
798
+ if (this.polymorphicInfo.disqualify) {
799
+ writer.append(this.polymorphicInfo.disqualify);
800
+ }
801
+ writer.appendKeyword(this.polymorphicInfo.allOrAny);
802
+ writer.appendSpace();
803
+ }
804
+ writer.appendExp(this.query);
805
+ if (this.alias) {
806
+ writer.appendSpace();
807
+ writer.appendQuoted(this.alias);
808
+ }
809
+ }
810
+ }
811
+ SubqueryRefExpr.type = ExprType.SubqueryRef;
812
+ export { SubqueryRefExpr };
813
+ /**
814
+ * Describe a optionally compound SELECT statement.
815
+ * @alpha
816
+ */
817
+ class SelectStatementExpr extends StatementExpr {
818
+ constructor(singleSelect, nextSelect) {
819
+ super(SelectStatementExpr.type);
820
+ this.singleSelect = singleSelect;
821
+ this.nextSelect = nextSelect;
822
+ }
823
+ get children() {
824
+ const exprs = [this.singleSelect];
825
+ if (this.nextSelect)
826
+ exprs.push(this.nextSelect.select);
827
+ return exprs;
828
+ }
829
+ static deserialize(node) {
830
+ if (node.id !== NativeExpIds.SelectStatement) {
831
+ throw new Error(`Parse node is 'node.id !== NativeExpIds.SelectStatement'. ${JSON.stringify(node)}`);
832
+ }
833
+ const singleSelect = SelectExpr.deserialize(node.select);
834
+ let nextSelect;
835
+ if (node.nextBlock) {
836
+ nextSelect = {
837
+ op: node.nextBlock.combineOp,
838
+ select: SelectStatementExpr.deserialize(node.nextBlock.select),
839
+ };
840
+ }
841
+ return new SelectStatementExpr(singleSelect, nextSelect);
842
+ }
843
+ writeTo(writer) {
844
+ writer.appendExp(this.singleSelect);
845
+ if (this.nextSelect) {
846
+ writer.appendSpace();
847
+ if (this.nextSelect.op === "UNION ALL") {
848
+ writer.appendKeyword("UNION");
849
+ writer.appendSpace();
850
+ writer.appendKeyword("ALL");
851
+ }
852
+ else {
853
+ writer.append(this.nextSelect.op);
854
+ }
855
+ writer.appendSpace();
856
+ writer.appendExp(this.nextSelect.select);
857
+ }
858
+ }
859
+ }
860
+ SelectStatementExpr.type = ExprType.SelectStatement;
861
+ export { SelectStatementExpr };
862
+ /**
863
+ * Describe selection in a SELECT query
864
+ * @alpha
865
+ */
866
+ class SelectionClauseExpr extends Expr {
867
+ constructor(derivedPropertyList) {
868
+ super(SelectionClauseExpr.type);
869
+ this.derivedPropertyList = derivedPropertyList;
870
+ }
871
+ get children() {
872
+ return [...this.derivedPropertyList];
873
+ }
874
+ static deserialize(node) {
875
+ if (!Array.isArray(node)) {
876
+ throw new Error(`Expect node to be array of NativeECSqlParseNode[] ${JSON.stringify(node)}`);
877
+ }
878
+ return new SelectionClauseExpr(Array.from(node.map((v) => DerivedPropertyExpr.deserialize(v))));
879
+ }
880
+ writeTo(writer) {
881
+ this.derivedPropertyList.forEach((v, i) => {
882
+ if (i > 0) {
883
+ writer.appendComma();
884
+ }
885
+ writer.appendExp(v);
886
+ });
887
+ }
888
+ }
889
+ SelectionClauseExpr.type = ExprType.SelectionClause;
890
+ export { SelectionClauseExpr };
891
+ /**
892
+ * Describe a GROUP BY clause in a SELECT statement.
893
+ * @alpha
894
+ */
895
+ class GroupByClauseExpr extends Expr {
896
+ constructor(exprList) {
897
+ super(GroupByClauseExpr.type);
898
+ this.exprList = exprList;
899
+ }
900
+ get children() {
901
+ return [...this.exprList];
902
+ }
903
+ static deserialize(node) {
904
+ if (!Array.isArray(node)) {
905
+ throw new Error(`Expect node to be array of NativeECSqlParseNode[] ${JSON.stringify(node)}`);
906
+ }
907
+ return new GroupByClauseExpr(Array.from(node.map((v) => ValueExpr.deserialize(v))));
908
+ }
909
+ writeTo(writer) {
910
+ writer.appendKeyword("GROUP");
911
+ writer.appendSpace();
912
+ writer.appendKeyword("BY");
913
+ writer.appendSpace();
914
+ this.exprList.forEach((v, i) => {
915
+ if (i > 0) {
916
+ writer.appendComma();
917
+ }
918
+ writer.appendExp(v);
919
+ });
920
+ }
921
+ }
922
+ GroupByClauseExpr.type = ExprType.GroupByClause;
923
+ export { GroupByClauseExpr };
924
+ /**
925
+ * Describe a HAVING clause in a SELECT statement.
926
+ * @alpha
927
+ */
928
+ class HavingClauseExpr extends Expr {
929
+ constructor(filterExpr) {
930
+ super(HavingClauseExpr.type);
931
+ this.filterExpr = filterExpr;
932
+ }
933
+ get children() {
934
+ return [this.filterExpr];
935
+ }
936
+ static deserialize(node) {
937
+ if (typeof node !== "object") {
938
+ throw new Error(`Expect node to be array of NativeECSqlParseNode ${JSON.stringify(node)}`);
939
+ }
940
+ return new HavingClauseExpr(BooleanExpr.deserialize(node));
941
+ }
942
+ writeTo(writer) {
943
+ writer.appendKeyword("HAVING");
944
+ writer.appendSpace();
945
+ writer.appendExp(this.filterExpr);
946
+ }
947
+ }
948
+ HavingClauseExpr.type = ExprType.HavingClause;
949
+ export { HavingClauseExpr };
950
+ /**
951
+ * Describe a FROM clause in a SELECT statement.
952
+ * @alpha
953
+ */
954
+ class FromClauseExpr extends Expr {
955
+ constructor(classRefs) {
956
+ super(FromClauseExpr.type);
957
+ this.classRefs = classRefs;
958
+ }
959
+ get children() {
960
+ return [...this.classRefs];
961
+ }
962
+ static deserialize(node) {
963
+ if (!Array.isArray(node)) {
964
+ throw new Error(`Expect node to be array of NativeECSqlParseNode[] ${JSON.stringify(node)}`);
965
+ }
966
+ return new FromClauseExpr(Array.from(node.map((v) => ClassRefExpr.deserialize(v))));
967
+ }
968
+ writeTo(writer) {
969
+ writer.appendKeyword("FROM");
970
+ writer.appendSpace();
971
+ this.classRefs.forEach((v, i) => {
972
+ if (i > 0) {
973
+ writer.appendComma();
974
+ }
975
+ writer.appendExp(v);
976
+ });
977
+ }
978
+ }
979
+ FromClauseExpr.type = ExprType.FromClause;
980
+ export { FromClauseExpr };
981
+ /**
982
+ * Describe a WHERE clause in a SELECT, UPDATE and DELETE statement.
983
+ * @alpha
984
+ */
985
+ class WhereClauseExp extends Expr {
986
+ constructor(filterExpr) {
987
+ super(WhereClauseExp.type);
988
+ this.filterExpr = filterExpr;
989
+ }
990
+ get children() {
991
+ return [this.filterExpr];
992
+ }
993
+ static deserialize(node) {
994
+ if (typeof node !== "object") {
995
+ throw new Error(`Expect node to be array of NativeECSqlParseNode ${JSON.stringify(node)}`);
996
+ }
997
+ return new WhereClauseExp(BooleanExpr.deserialize(node));
998
+ }
999
+ writeTo(writer) {
1000
+ writer.appendKeyword("WHERE");
1001
+ writer.appendSpace();
1002
+ writer.appendExp(this.filterExpr);
1003
+ }
1004
+ }
1005
+ WhereClauseExp.type = ExprType.WhereClause;
1006
+ export { WhereClauseExp };
1007
+ /**
1008
+ * Describe a single sorted term in a ORDER BY clause of a SELECT statement.
1009
+ * @alpha
1010
+ */
1011
+ class OrderBySpecExpr extends Expr {
1012
+ constructor(term, sortDirection, nulls) {
1013
+ super(OrderBySpecExpr.type);
1014
+ this.term = term;
1015
+ this.sortDirection = sortDirection;
1016
+ this.nulls = nulls;
1017
+ }
1018
+ get children() {
1019
+ return [this.term];
1020
+ }
1021
+ static deserialize(node) {
1022
+ if (typeof node !== "object") {
1023
+ throw new Error(`Expect node to be array of NativeECSqlParseNode ${JSON.stringify(node)}`);
1024
+ }
1025
+ return new OrderBySpecExpr(ValueExpr.deserialize(node.exp), node.direction ? node.direction : undefined);
1026
+ }
1027
+ writeTo(writer) {
1028
+ writer.appendExp(this.term);
1029
+ if (this.sortDirection) {
1030
+ writer.appendSpace();
1031
+ writer.appendKeyword(this.sortDirection);
1032
+ }
1033
+ if (this.nulls) {
1034
+ writer.appendSpace();
1035
+ writer.appendKeyword("NULLS");
1036
+ writer.appendSpace();
1037
+ writer.appendKeyword(this.nulls);
1038
+ }
1039
+ }
1040
+ }
1041
+ OrderBySpecExpr.type = ExprType.OrderBySpec;
1042
+ export { OrderBySpecExpr };
1043
+ /**
1044
+ * Describe a ORDER BY clause in a SELECT statement.
1045
+ * @alpha
1046
+ */
1047
+ class OrderByClauseExpr extends Expr {
1048
+ constructor(terms) {
1049
+ super(OrderByClauseExpr.type);
1050
+ this.terms = terms;
1051
+ }
1052
+ get children() {
1053
+ return [...this.terms.map((v) => v.term)];
1054
+ }
1055
+ static deserialize(node) {
1056
+ if (!Array.isArray(node)) {
1057
+ throw new Error(`Expect node to be array of NativeECSqlParseNode[] ${JSON.stringify(node)}`);
1058
+ }
1059
+ return new OrderByClauseExpr(Array.from(node.map((v) => OrderBySpecExpr.deserialize(v))));
1060
+ }
1061
+ writeTo(writer) {
1062
+ writer.appendKeyword("ORDER");
1063
+ writer.appendSpace();
1064
+ writer.appendKeyword("BY");
1065
+ writer.appendSpace();
1066
+ this.terms.forEach((v, i) => {
1067
+ if (i > 0) {
1068
+ writer.appendComma();
1069
+ }
1070
+ writer.appendExp(v);
1071
+ });
1072
+ }
1073
+ }
1074
+ OrderByClauseExpr.type = ExprType.OrderByClause;
1075
+ export { OrderByClauseExpr };
1076
+ /**
1077
+ * Describe a LIMIT clause in a SELECT statement.
1078
+ * @alpha
1079
+ */
1080
+ class LimitClauseExpr extends Expr {
1081
+ constructor(limit, offset) {
1082
+ super(LimitClauseExpr.type);
1083
+ this.limit = limit;
1084
+ this.offset = offset;
1085
+ }
1086
+ get children() {
1087
+ const exprs = [this.limit];
1088
+ if (this.offset)
1089
+ exprs.push(this.offset);
1090
+ return exprs;
1091
+ }
1092
+ static deserialize(node) {
1093
+ if (typeof node !== "object") {
1094
+ throw new Error(`Expect node to be array of NativeECSqlParseNode ${JSON.stringify(node)}`);
1095
+ }
1096
+ return new LimitClauseExpr(ValueExpr.deserialize(node.exp), node.offset ? ValueExpr.deserialize(node.offset) : undefined);
1097
+ }
1098
+ writeTo(writer) {
1099
+ writer.appendKeyword("LIMIT");
1100
+ writer.appendSpace();
1101
+ writer.appendExp(this.limit);
1102
+ if (this.offset) {
1103
+ writer.appendSpace();
1104
+ writer.appendKeyword("OFFSET");
1105
+ writer.appendSpace();
1106
+ writer.appendExp(this.offset);
1107
+ }
1108
+ }
1109
+ }
1110
+ LimitClauseExpr.type = ExprType.LimitClause;
1111
+ export { LimitClauseExpr };
1112
+ /**
1113
+ * Describe a single select statement.
1114
+ * @alpha
1115
+ */
1116
+ class SelectExpr extends Expr {
1117
+ constructor(selection, rowQuantifier, from, where, groupBy, having, orderBy, limit, options) {
1118
+ super(SelectExpr.type);
1119
+ this.selection = selection;
1120
+ this.rowQuantifier = rowQuantifier;
1121
+ this.from = from;
1122
+ this.where = where;
1123
+ this.groupBy = groupBy;
1124
+ this.having = having;
1125
+ this.orderBy = orderBy;
1126
+ this.limit = limit;
1127
+ this.options = options;
1128
+ }
1129
+ get children() {
1130
+ const exprs = [this.selection];
1131
+ if (this.from)
1132
+ exprs.push(this.from);
1133
+ if (this.where)
1134
+ exprs.push(this.where);
1135
+ if (this.groupBy)
1136
+ exprs.push(this.groupBy);
1137
+ if (this.having)
1138
+ exprs.push(this.having);
1139
+ if (this.orderBy)
1140
+ exprs.push(this.orderBy);
1141
+ if (this.limit)
1142
+ exprs.push(this.limit);
1143
+ if (this.options)
1144
+ exprs.push(this.options);
1145
+ return exprs;
1146
+ }
1147
+ static deserialize(node) {
1148
+ if (node.id !== NativeExpIds.SingleSelectStatement && node.id !== NativeExpIds.RowConstructor) {
1149
+ throw new Error(`Parse node is 'node.id !== NativeExpIds.SingleSelectStatement/RowConstructor'. ${JSON.stringify(node)}`);
1150
+ }
1151
+ if (node.id === NativeExpIds.RowConstructor) {
1152
+ const values = SelectionClauseExpr.deserialize(node.values);
1153
+ return new SelectExpr(values);
1154
+ }
1155
+ const selection = SelectionClauseExpr.deserialize(node.selection);
1156
+ const from = node.from ? FromClauseExpr.deserialize(node.from) : undefined;
1157
+ const where = node.where ? WhereClauseExp.deserialize(node.where) : undefined;
1158
+ const groupBy = node.groupBy ? GroupByClauseExpr.deserialize(node.groupBy) : undefined;
1159
+ const having = node.having ? HavingClauseExpr.deserialize(node.having) : undefined;
1160
+ const orderBy = node.orderBy ? OrderByClauseExpr.deserialize(node.orderBy) : undefined;
1161
+ const options = node.options ? ECSqlOptionsClauseExpr.deserialize(node.options) : undefined;
1162
+ const limitSpec = node.limit ? LimitClauseExpr.deserialize(node.limit) : undefined;
1163
+ const rowQuantifier = node.selectionType ? node.selectionType : undefined;
1164
+ return new SelectExpr(selection, rowQuantifier, from, where, groupBy, having, orderBy, limitSpec, options);
1165
+ }
1166
+ writeTo(writer) {
1167
+ writer.appendKeyword("SELECT");
1168
+ writer.appendSpace();
1169
+ if (this.rowQuantifier) {
1170
+ writer.appendKeyword(this.rowQuantifier);
1171
+ writer.appendSpace();
1172
+ }
1173
+ writer.appendExp(this.selection);
1174
+ if (this.from) {
1175
+ writer.appendSpace();
1176
+ writer.appendExp(this.from);
1177
+ }
1178
+ if (this.where) {
1179
+ writer.appendSpace();
1180
+ writer.appendExp(this.where);
1181
+ }
1182
+ if (this.groupBy) {
1183
+ writer.appendSpace();
1184
+ writer.appendExp(this.groupBy);
1185
+ }
1186
+ if (this.having) {
1187
+ writer.appendSpace();
1188
+ writer.appendExp(this.having);
1189
+ }
1190
+ if (this.orderBy) {
1191
+ writer.appendSpace();
1192
+ writer.appendExp(this.orderBy);
1193
+ }
1194
+ if (this.limit) {
1195
+ writer.appendSpace();
1196
+ writer.appendExp(this.limit);
1197
+ }
1198
+ if (this.options) {
1199
+ writer.appendSpace();
1200
+ writer.appendExp(this.options);
1201
+ }
1202
+ }
1203
+ }
1204
+ SelectExpr.type = ExprType.Select;
1205
+ export { SelectExpr };
1206
+ /**
1207
+ * Describe a subquery when used as value. This kind of query expect to return one column and one one value.
1208
+ * @alpha
1209
+ */
1210
+ class SubqueryExpr extends ValueExpr {
1211
+ constructor(query) {
1212
+ super(SubqueryExpr.type);
1213
+ this.query = query;
1214
+ }
1215
+ get children() {
1216
+ return [this.query];
1217
+ }
1218
+ static deserialize(node) {
1219
+ if (node.id !== NativeExpIds.Subquery) {
1220
+ throw new Error(`Parse node is 'node.id !== NativeExpIds.Subquery'. ${JSON.stringify(node)}`);
1221
+ }
1222
+ return new SubqueryExpr(SelectStatementExpr.deserialize(node.query));
1223
+ }
1224
+ writeTo(writer) {
1225
+ writer.append("(");
1226
+ writer.appendExp(this.query);
1227
+ writer.append(")");
1228
+ }
1229
+ }
1230
+ SubqueryExpr.type = ExprType.Subquery;
1231
+ export { SubqueryExpr };
1232
+ /**
1233
+ * Describe a binary boolean expression in ECSQL.
1234
+ * @alpha
1235
+ */
1236
+ class BinaryBooleanExpr extends BooleanExpr {
1237
+ constructor(op, lhsExpr, rhsExpr, not) {
1238
+ super(BinaryBooleanExpr.type);
1239
+ this.op = op;
1240
+ this.lhsExpr = lhsExpr;
1241
+ this.rhsExpr = rhsExpr;
1242
+ this.not = not;
1243
+ }
1244
+ get children() {
1245
+ return [this.lhsExpr, this.rhsExpr];
1246
+ }
1247
+ static deserialize(node) {
1248
+ if (node.id !== NativeExpIds.BinaryBoolean) {
1249
+ throw new Error(`Parse node is 'node.id !== NativeExpIds.BinaryBoolean'. ${JSON.stringify(node)}`);
1250
+ }
1251
+ const op = node.op;
1252
+ return new BinaryBooleanExpr(op, ComputedExpr.deserialize(node.lhs), ComputedExpr.deserialize(node.rhs));
1253
+ }
1254
+ writeTo(writer) {
1255
+ writer.append("(");
1256
+ writer.appendExp(this.lhsExpr);
1257
+ writer.appendBinaryOp(this.op);
1258
+ writer.appendExp(this.rhsExpr);
1259
+ writer.append(")");
1260
+ }
1261
+ }
1262
+ BinaryBooleanExpr.type = ExprType.BinaryBoolean;
1263
+ export { BinaryBooleanExpr };
1264
+ /**
1265
+ * Describe a <expr> IS NULL boolean expression
1266
+ * @alpha
1267
+ */
1268
+ class IsNullExpr extends BooleanExpr {
1269
+ constructor(operandExpr, not) {
1270
+ super(IsNullExpr.type);
1271
+ this.operandExpr = operandExpr;
1272
+ this.not = not;
1273
+ }
1274
+ get children() {
1275
+ return [this.operandExpr];
1276
+ }
1277
+ static parseOp(node) {
1278
+ const op = node.op;
1279
+ const isLiteral = node.rhs.op === NativeExpIds.LiteralValue;
1280
+ if (!isLiteral) {
1281
+ return [false, false];
1282
+ }
1283
+ const isNull = LiteralExpr.deserialize(node.rhs).rawValue === "NULL";
1284
+ return [op.startsWith("IS"), isNull];
1285
+ }
1286
+ static deserialize(node) {
1287
+ if (node.id !== NativeExpIds.BinaryBoolean) {
1288
+ throw new Error(`Parse node is 'node.id !== NativeExpIds.BinaryBoolean'. ${JSON.stringify(node)}`);
1289
+ }
1290
+ const [isNullExp, isNull] = this.parseOp(node);
1291
+ if (!isNullExp) {
1292
+ throw new Error(`Parse node has 'node.op !== IS NULL'. ${JSON.stringify(node)}`);
1293
+ }
1294
+ const exp = ValueExpr.deserialize(node.lhs);
1295
+ return new IsNullExpr(exp, isNull ? "NOT" : undefined);
1296
+ }
1297
+ writeTo(writer) {
1298
+ writer.appendExp(this.operandExpr);
1299
+ writer.appendSpace();
1300
+ writer.appendKeyword("IS");
1301
+ writer.appendSpace();
1302
+ if (this.not) {
1303
+ writer.appendKeyword("NOT");
1304
+ writer.appendSpace();
1305
+ }
1306
+ writer.appendKeyword("NULL");
1307
+ }
1308
+ }
1309
+ IsNullExpr.type = ExprType.IsNull;
1310
+ export { IsNullExpr };
1311
+ /**
1312
+ * Describe a <expr> IS (type1[, type2]) in ECSQL.
1313
+ * @alpha
1314
+ */
1315
+ class IsOfTypeExpr extends BooleanExpr {
1316
+ constructor(lhsExpr, typeNames, not) {
1317
+ super(IsOfTypeExpr.type);
1318
+ this.lhsExpr = lhsExpr;
1319
+ this.typeNames = typeNames;
1320
+ this.not = not;
1321
+ }
1322
+ get children() {
1323
+ return [this.lhsExpr, ...this.typeNames];
1324
+ }
1325
+ static parseOp(node) {
1326
+ const op = node.op;
1327
+ return [op.startsWith("IS") && Array.isArray(node.rhs), op.endsWith("NOT")];
1328
+ }
1329
+ static deserialize(node) {
1330
+ if (node.id !== NativeExpIds.BinaryBoolean) {
1331
+ throw new Error(`Parse node is 'node.id !== NativeExpIds.BinaryBoolean'. ${JSON.stringify(node)}`);
1332
+ }
1333
+ const [isTypeOf, isNull] = this.parseOp(node);
1334
+ if (!isTypeOf) {
1335
+ throw new Error(`Parse node has 'node.op !== IS (type....)'. ${JSON.stringify(node)}`);
1336
+ }
1337
+ const exp = ValueExpr.deserialize(node.lhs);
1338
+ const classNames = Array.from(node.rhs.map((v) => ClassNameExpr.deserialize(v)));
1339
+ return new IsOfTypeExpr(exp, classNames, isNull ? "NOT" : undefined);
1340
+ }
1341
+ writeTo(writer) {
1342
+ writer.appendExp(this.lhsExpr);
1343
+ writer.appendSpace();
1344
+ writer.appendKeyword("IS");
1345
+ writer.appendSpace();
1346
+ if (this.not) {
1347
+ writer.appendKeyword("NOT");
1348
+ writer.appendSpace();
1349
+ }
1350
+ writer.append("(");
1351
+ this.typeNames.forEach((v, i) => {
1352
+ if (i > 0) {
1353
+ writer.appendComma();
1354
+ }
1355
+ writer.appendExp(v);
1356
+ });
1357
+ writer.append(")");
1358
+ }
1359
+ }
1360
+ IsOfTypeExpr.type = ExprType.IsOfType;
1361
+ export { IsOfTypeExpr };
1362
+ /**
1363
+ * Describe a NOT <expr> boolean expression
1364
+ * @alpha
1365
+ */
1366
+ class NotExpr extends BooleanExpr {
1367
+ constructor(operandExpr) {
1368
+ super(NotExpr.type);
1369
+ this.operandExpr = operandExpr;
1370
+ }
1371
+ get children() {
1372
+ return [this.operandExpr];
1373
+ }
1374
+ static deserialize(node) {
1375
+ if (node.id !== NativeExpIds.BooleanFactor) {
1376
+ throw new Error(`Parse node is 'node.id !== NativeExpIds.BooleanFactor'. ${JSON.stringify(node)}`);
1377
+ }
1378
+ const exp = ComputedExpr.deserialize(node.exp);
1379
+ return new NotExpr(exp);
1380
+ }
1381
+ writeTo(writer) {
1382
+ writer.append("(");
1383
+ writer.appendKeyword("NOT");
1384
+ writer.appendSpace();
1385
+ writer.appendExp(this.operandExpr);
1386
+ writer.append(")");
1387
+ }
1388
+ }
1389
+ NotExpr.type = ExprType.Not;
1390
+ export { NotExpr };
1391
+ /**
1392
+ * Describe a <expr> IN subquery|(val1[,val2...]) boolean expression
1393
+ * @alpha
1394
+ */
1395
+ class InExpr extends BooleanExpr {
1396
+ constructor(lhsExpr, rhsExpr, not) {
1397
+ super(InExpr.type);
1398
+ this.lhsExpr = lhsExpr;
1399
+ this.rhsExpr = rhsExpr;
1400
+ this.not = not;
1401
+ }
1402
+ get children() {
1403
+ const exprs = [this.lhsExpr];
1404
+ if (this.rhsExpr instanceof SubqueryExpr)
1405
+ exprs.push(this.rhsExpr);
1406
+ else {
1407
+ exprs.push(...this.rhsExpr);
1408
+ }
1409
+ return exprs;
1410
+ }
1411
+ static parseOp(op) {
1412
+ return [op.endsWith("IN"), op.startsWith("NOT ")];
1413
+ }
1414
+ static deserialize(node) {
1415
+ if (node.id !== NativeExpIds.BinaryBoolean) {
1416
+ throw new Error(`Parse node is 'node.id !== NativeExpIds.BinaryBoolean'. ${JSON.stringify(node)}`);
1417
+ }
1418
+ const [isIn, isNull] = this.parseOp(node.op);
1419
+ if (!isIn) {
1420
+ throw new Error(`Parse node has 'node.op !== IN'. ${JSON.stringify(node)}`);
1421
+ }
1422
+ const lhs = ValueExpr.deserialize(node.lhs);
1423
+ if (Array.isArray(node.rhs))
1424
+ return new InExpr(lhs, Array.from(node.rhs.map((v) => ValueExpr.deserialize(v))), isNull ? "NOT" : undefined);
1425
+ else if (node.rhs.id === NativeExpIds.Subquery)
1426
+ return new InExpr(lhs, SubqueryExpr.deserialize(node.rhs), isNull ? "NOT" : undefined);
1427
+ else
1428
+ throw new Error(`unknown IN rhs ${node.rhs.id}`);
1429
+ }
1430
+ writeTo(writer) {
1431
+ writer.appendExp(this.lhsExpr);
1432
+ writer.appendSpace();
1433
+ if (this.not) {
1434
+ writer.appendKeyword("NOT");
1435
+ writer.appendSpace();
1436
+ }
1437
+ writer.appendKeyword("IN");
1438
+ writer.appendSpace();
1439
+ if (this.rhsExpr instanceof SubqueryExpr) {
1440
+ writer.appendExp(this.rhsExpr);
1441
+ }
1442
+ else if (Array.isArray(this.rhsExpr)) {
1443
+ writer.append("(");
1444
+ this.rhsExpr.forEach((v, i) => {
1445
+ if (i > 0) {
1446
+ writer.appendComma();
1447
+ }
1448
+ writer.appendExp(v);
1449
+ });
1450
+ writer.append(")");
1451
+ }
1452
+ else {
1453
+ throw new Error("unknown expression on rhs of IN expr.");
1454
+ }
1455
+ }
1456
+ }
1457
+ InExpr.type = ExprType.In;
1458
+ export { InExpr };
1459
+ /**
1460
+ * Describe a <expr> LIKE <expr> [ESCAPE <expr>] boolean expression
1461
+ * @alpha
1462
+ */
1463
+ class LikeExpr extends BooleanExpr {
1464
+ constructor(lhsExpr, patternExpr, escapeExpr, not) {
1465
+ super(LikeExpr.type);
1466
+ this.lhsExpr = lhsExpr;
1467
+ this.patternExpr = patternExpr;
1468
+ this.escapeExpr = escapeExpr;
1469
+ this.not = not;
1470
+ }
1471
+ get children() {
1472
+ const exprs = [this.lhsExpr, this.patternExpr];
1473
+ if (this.escapeExpr)
1474
+ exprs.push(this.escapeExpr);
1475
+ return exprs;
1476
+ }
1477
+ static parseOp(op) {
1478
+ return [op.endsWith("LIKE"), op.startsWith("NOT ")];
1479
+ }
1480
+ static deserialize(node) {
1481
+ if (node.id !== NativeExpIds.BinaryBoolean) {
1482
+ throw new Error(`Parse node is 'node.id !== NativeExpIds.BinaryBoolean'. ${JSON.stringify(node)}`);
1483
+ }
1484
+ const [isLike, isNull] = this.parseOp(node.op);
1485
+ if (!isLike) {
1486
+ throw new Error(`Parse node has 'node.op !== LIKE'. ${JSON.stringify(node)}`);
1487
+ }
1488
+ const lhs = ValueExpr.deserialize(node.lhs);
1489
+ const pattren = ValueExpr.deserialize(node.rhs.pattren);
1490
+ const escape = node.rhs.escape ? ValueExpr.deserialize(node.rhs.escape) : undefined;
1491
+ return new LikeExpr(lhs, pattren, escape, isNull ? "NOT" : undefined);
1492
+ }
1493
+ writeTo(writer) {
1494
+ writer.appendExp(this.lhsExpr);
1495
+ writer.appendSpace();
1496
+ if (this.not) {
1497
+ writer.appendKeyword("NOT");
1498
+ writer.appendSpace();
1499
+ }
1500
+ writer.appendKeyword("LIKE");
1501
+ writer.appendSpace();
1502
+ writer.appendExp(this.patternExpr);
1503
+ if (this.escapeExpr) {
1504
+ writer.appendSpace();
1505
+ writer.appendKeyword("ESCAPE");
1506
+ writer.appendSpace();
1507
+ writer.appendExp(this.escapeExpr);
1508
+ }
1509
+ }
1510
+ }
1511
+ LikeExpr.type = ExprType.Like;
1512
+ export { LikeExpr };
1513
+ /**
1514
+ * Describe a <expr> BETWEEN <expr> AND <expr> boolean expression
1515
+ * @alpha
1516
+ */
1517
+ class BetweenExpr extends BooleanExpr {
1518
+ constructor(lhsExpr, lowerBoundExpr, upperBoundExpr, not) {
1519
+ super(BetweenExpr.type);
1520
+ this.lhsExpr = lhsExpr;
1521
+ this.lowerBoundExpr = lowerBoundExpr;
1522
+ this.upperBoundExpr = upperBoundExpr;
1523
+ this.not = not;
1524
+ }
1525
+ get children() {
1526
+ return [this.lhsExpr, this.lowerBoundExpr, this.upperBoundExpr];
1527
+ }
1528
+ static parseOp(op) {
1529
+ return [op.endsWith(" BETWEEN"), op.startsWith("NOT ")];
1530
+ }
1531
+ static deserialize(node) {
1532
+ if (node.id !== NativeExpIds.BinaryBoolean) {
1533
+ throw new Error(`Parse node is 'node.id !== NativeExpIds.BinaryBoolean'. ${JSON.stringify(node)}`);
1534
+ }
1535
+ const [isBetween, isNull] = this.parseOp(node.op);
1536
+ if (!isBetween) {
1537
+ throw new Error(`Parse node has 'node.op !== BETWEEN'. ${JSON.stringify(node)}`);
1538
+ }
1539
+ const rhs = node.rhs;
1540
+ return new BetweenExpr(ValueExpr.deserialize(node.lhs), ValueExpr.deserialize(rhs.lbound), ValueExpr.deserialize(rhs.ubound), isNull ? "NOT" : undefined);
1541
+ }
1542
+ writeTo(writer) {
1543
+ writer.appendExp(this.lhsExpr);
1544
+ writer.appendSpace();
1545
+ if (this.not) {
1546
+ writer.appendKeyword("NOT");
1547
+ writer.appendSpace();
1548
+ }
1549
+ writer.appendKeyword("BETWEEN");
1550
+ writer.appendSpace();
1551
+ writer.appendExp(this.lowerBoundExpr);
1552
+ writer.appendSpace();
1553
+ writer.appendKeyword("AND");
1554
+ writer.appendSpace();
1555
+ writer.appendExp(this.upperBoundExpr);
1556
+ }
1557
+ }
1558
+ BetweenExpr.type = ExprType.Between;
1559
+ export { BetweenExpr };
1560
+ /**
1561
+ * Describe a common table expression base query statement
1562
+ * @alpha
1563
+ */
1564
+ class CteExpr extends StatementExpr {
1565
+ constructor(cteBlocks, query, recursive) {
1566
+ super(CteExpr.type);
1567
+ this.cteBlocks = cteBlocks;
1568
+ this.query = query;
1569
+ this.recursive = recursive;
1570
+ }
1571
+ get children() {
1572
+ return [...this.cteBlocks, this.query];
1573
+ }
1574
+ static deserialize(node) {
1575
+ if (node.id !== NativeExpIds.CommonTable) {
1576
+ throw new Error(`Parse node is 'node.id !== NativeExpIds.CommonTable'. ${JSON.stringify(node)}`);
1577
+ }
1578
+ const blocks = Array.from(node.blocks.map((v) => CteBlockExpr.deserialize(v)));
1579
+ return new CteExpr(blocks, SelectStatementExpr.deserialize(node.select), node.recursive === true ? "RECURSIVE" : undefined);
1580
+ }
1581
+ writeTo(writer) {
1582
+ writer.appendKeyword("WITH");
1583
+ writer.appendSpace();
1584
+ if (this.recursive) {
1585
+ writer.appendKeyword(this.recursive);
1586
+ writer.appendSpace();
1587
+ }
1588
+ this.cteBlocks.forEach((v, i) => {
1589
+ if (i > 0) {
1590
+ writer.appendComma();
1591
+ }
1592
+ writer.appendExp(v);
1593
+ });
1594
+ writer.appendSpace();
1595
+ writer.appendExp(this.query);
1596
+ }
1597
+ }
1598
+ CteExpr.type = ExprType.Cte;
1599
+ export { CteExpr };
1600
+ /**
1601
+ * Describe a single block of CTE that can be reference in FROM clause of a SELECT
1602
+ * @alpha
1603
+ */
1604
+ class CteBlockExpr extends Expr {
1605
+ constructor(name, query, props) {
1606
+ super(CteBlockExpr.type);
1607
+ this.name = name;
1608
+ this.query = query;
1609
+ this.props = props;
1610
+ }
1611
+ get children() {
1612
+ return [this.query];
1613
+ }
1614
+ static deserialize(node) {
1615
+ if (node.id !== NativeExpIds.CommonTableBlock) {
1616
+ throw new Error(`Parse node is 'node.id !== NativeExpIds.CommonTableBlock'. ${JSON.stringify(node)}`);
1617
+ }
1618
+ return new CteBlockExpr(node.name, SelectStatementExpr.deserialize(node.asQuery), node.args);
1619
+ }
1620
+ writeTo(writer) {
1621
+ writer.appendQuoted(this.name);
1622
+ writer.append("(");
1623
+ this.props.forEach((v, i) => {
1624
+ if (i > 0) {
1625
+ writer.appendComma();
1626
+ }
1627
+ writer.appendQuoted(v);
1628
+ });
1629
+ writer.append(")");
1630
+ writer.appendSpace();
1631
+ writer.appendKeyword("AS");
1632
+ writer.appendSpace();
1633
+ writer.append("(");
1634
+ writer.appendLine();
1635
+ writer.indent();
1636
+ writer.appendExp(this.query);
1637
+ writer.unindent();
1638
+ writer.appendLine();
1639
+ writer.append(")");
1640
+ }
1641
+ }
1642
+ CteBlockExpr.type = ExprType.CteBlock;
1643
+ export { CteBlockExpr };
1644
+ /**
1645
+ * Describe a name reference to a CTE block.
1646
+ * @alpha
1647
+ */
1648
+ class CteBlockRefExpr extends ClassRefExpr {
1649
+ constructor(name, alias) {
1650
+ super(CteBlockRefExpr.type);
1651
+ this.name = name;
1652
+ this.alias = alias;
1653
+ }
1654
+ get children() {
1655
+ return [];
1656
+ }
1657
+ static deserialize(node) {
1658
+ if (node.id !== NativeExpIds.CommonTableBlockName) {
1659
+ throw new Error(`Parse node is 'node.id !== NativeExpIds.CommonTableBlockName'. ${JSON.stringify(node)}`);
1660
+ }
1661
+ return new CteBlockRefExpr(node.name, node.alias ? node.alias : undefined);
1662
+ }
1663
+ writeTo(writer) {
1664
+ writer.appendQuoted(this.name);
1665
+ if (this.alias) {
1666
+ writer.appendQuoted(this.alias);
1667
+ }
1668
+ }
1669
+ }
1670
+ CteBlockRefExpr.type = ExprType.CteBlockRef;
1671
+ export { CteBlockRefExpr };
1672
+ /**
1673
+ * Describe a table value function expression in ECSQL that appear in FROM clause of query.
1674
+ * @alpha
1675
+ */
1676
+ class TableValuedFuncExpr extends ClassRefExpr {
1677
+ constructor(schemaName, memberFunc, alias) {
1678
+ super(TableValuedFuncExpr.type);
1679
+ this.schemaName = schemaName;
1680
+ this.memberFunc = memberFunc;
1681
+ this.alias = alias;
1682
+ }
1683
+ get children() {
1684
+ return [this.memberFunc];
1685
+ }
1686
+ static deserialize(node) {
1687
+ if (node.id !== NativeExpIds.TableValuedFunction) {
1688
+ throw new Error(`Parse node is 'node.id !== NativeExpIds.TableValuedFunction'. ${JSON.stringify(node)}`);
1689
+ }
1690
+ return new TableValuedFuncExpr(node.schema, MemberFuncCallExpr.deserialize(node.func), node.alias);
1691
+ }
1692
+ writeTo(writer) {
1693
+ writer.appendQuoted(this.schemaName);
1694
+ writer.append(".");
1695
+ writer.appendExp(this.memberFunc);
1696
+ if (this.alias) {
1697
+ writer.appendSpace();
1698
+ writer.appendQuoted(this.alias);
1699
+ }
1700
+ }
1701
+ }
1702
+ TableValuedFuncExpr.type = ExprType.TableValuedFunc;
1703
+ export { TableValuedFuncExpr };
1704
+ /**
1705
+ * Describe a class name reference in ECSQL that appear in FROM clause of a SELECT.
1706
+ * @alpha
1707
+ */
1708
+ class ClassNameExpr extends ClassRefExpr {
1709
+ constructor(schemaNameOrAlias, className, tablespace, alias, polymorphicInfo, memberFunc) {
1710
+ super(ClassNameExpr.type);
1711
+ this.schemaNameOrAlias = schemaNameOrAlias;
1712
+ this.className = className;
1713
+ this.tablespace = tablespace;
1714
+ this.alias = alias;
1715
+ this.polymorphicInfo = polymorphicInfo;
1716
+ this.memberFunc = memberFunc;
1717
+ }
1718
+ get children() {
1719
+ return [];
1720
+ }
1721
+ static deserialize(node) {
1722
+ if (node.id !== NativeExpIds.ClassName) {
1723
+ throw new Error(`Parse node is 'node.id !== NativeExpIds.ClassName'. ${JSON.stringify(node)}`);
1724
+ }
1725
+ const className = node.className;
1726
+ const tablespace = node.tableSpace ? node.tableSpace : undefined;
1727
+ const schemaName = node.schemaName;
1728
+ const alias = node.alias ? node.alias : undefined;
1729
+ const polymorphicInfo = node.polymorphicInfo ? { disqualify: node.polymorphicInfo.disqualify, allOrAny: node.polymorphicInfo.scope } : undefined;
1730
+ const memberFunc = node.func ? MemberFuncCallExpr.deserialize(node.func) : undefined;
1731
+ return new ClassNameExpr(schemaName, className, tablespace, alias, polymorphicInfo, memberFunc);
1732
+ }
1733
+ writeTo(writer) {
1734
+ if (this.polymorphicInfo) {
1735
+ if (this.polymorphicInfo.disqualify) {
1736
+ writer.append(this.polymorphicInfo.disqualify);
1737
+ }
1738
+ writer.appendKeyword(this.polymorphicInfo.allOrAny);
1739
+ writer.appendSpace();
1740
+ }
1741
+ if (this.tablespace) {
1742
+ writer.append("[").append(this.tablespace).append("]");
1743
+ writer.append(".");
1744
+ }
1745
+ writer.append("[").append(this.schemaNameOrAlias).append("]");
1746
+ writer.append(".");
1747
+ writer.append("[").append(this.className).append("]");
1748
+ if (this.memberFunc) {
1749
+ writer.append(".");
1750
+ writer.appendExp(this.memberFunc);
1751
+ }
1752
+ if (this.alias) {
1753
+ writer.appendSpace();
1754
+ writer.appendQuoted(this.alias);
1755
+ }
1756
+ }
1757
+ static fromECSql(ecsql) {
1758
+ const regex = /\s*((\+)?\s*(ALL|ONLY)\s+)?(\[?(\w+)\]?[\.:])?\[?(\w+)\]?[\.:]\[?(\w+)\]?(\s+(AS)?(\s+(\w+)))?/i;
1759
+ const match = ecsql.match(regex);
1760
+ if (!match) {
1761
+ throw new Error("ECSQL className must follow syntax: [+][ALL|ONLY] [tablespace.][.|:][schemaOrAlias]][.|:][className] [AS] [alias");
1762
+ }
1763
+ const plus = match.at(2);
1764
+ const allOrOnlyStr = match.at(3);
1765
+ const tablespace = match.at(5);
1766
+ const schemaOrAlias = match.at(6);
1767
+ const className = match.at(7);
1768
+ const alias = match.at(11);
1769
+ if (!schemaOrAlias || !className)
1770
+ throw new Error("ECSQL className must follow syntax: [+][ALL|ONLY] [tablespace.][.|:][schemaOrAlias]][.|:][className] [AS] [alias");
1771
+ let polyInfo;
1772
+ if (allOrOnlyStr) {
1773
+ const allOrAny = allOrOnlyStr.toUpperCase();
1774
+ polyInfo = { disqualify: plus, allOrAny };
1775
+ }
1776
+ return new ClassNameExpr(schemaOrAlias, className, tablespace, alias, polyInfo);
1777
+ }
1778
+ }
1779
+ ClassNameExpr.type = ExprType.ClassName;
1780
+ export { ClassNameExpr };
1781
+ /**
1782
+ * Describe a UPDATE statement in ECSQL.
1783
+ * @alpha
1784
+ */
1785
+ class UpdateStatementExpr extends StatementExpr {
1786
+ constructor(className, assignement, where, options) {
1787
+ super(UpdateStatementExpr.type);
1788
+ this.className = className;
1789
+ this.assignement = assignement;
1790
+ this.where = where;
1791
+ this.options = options;
1792
+ }
1793
+ get children() {
1794
+ const exprs = [this.className, this.assignement];
1795
+ if (this.where)
1796
+ exprs.push(this.where);
1797
+ if (this.options)
1798
+ exprs.push(this.options);
1799
+ return exprs;
1800
+ }
1801
+ static deserialize(node) {
1802
+ if (node.id !== NativeExpIds.UpdateStatement) {
1803
+ throw new Error(`Parse node is 'node.id !== NativeExpIds.UpdateStatement'. ${JSON.stringify(node)}`);
1804
+ }
1805
+ const className = ClassNameExpr.deserialize(node.className);
1806
+ const assignment = SetClauseExpr.deserialize(node.assignment);
1807
+ const where = node.where ? WhereClauseExp.deserialize(node.where) : undefined;
1808
+ const options = node.options ? ECSqlOptionsClauseExpr.deserialize(node.options) : undefined;
1809
+ return new UpdateStatementExpr(className, assignment, where, options);
1810
+ }
1811
+ writeTo(writer) {
1812
+ writer.appendKeyword("UPDATE");
1813
+ writer.appendSpace();
1814
+ writer.appendExp(this.className);
1815
+ writer.appendSpace();
1816
+ writer.appendExp(this.assignement);
1817
+ if (this.where) {
1818
+ writer.appendSpace();
1819
+ writer.appendExp(this.where);
1820
+ }
1821
+ if (this.options) {
1822
+ writer.appendSpace();
1823
+ writer.appendExp(this.options);
1824
+ }
1825
+ }
1826
+ }
1827
+ UpdateStatementExpr.type = ExprType.UpdateStatement;
1828
+ export { UpdateStatementExpr };
1829
+ /**
1830
+ * Describe ECSQL option clause.
1831
+ * @alpha
1832
+ */
1833
+ class ECSqlOptionsClauseExpr extends Expr {
1834
+ constructor(options) {
1835
+ super(ECSqlOptionsClauseExpr.type);
1836
+ this.options = options;
1837
+ }
1838
+ get children() {
1839
+ return [];
1840
+ }
1841
+ static deserialize(node) {
1842
+ if (node.id !== NativeExpIds.Options) {
1843
+ throw new Error(`Parse node is 'node.id !== NativeExpIds.Options'. ${JSON.stringify(node)}`);
1844
+ }
1845
+ return new ECSqlOptionsClauseExpr(node.options);
1846
+ }
1847
+ writeTo(writer) {
1848
+ writer.appendKeyword("ECSQLOPTIONS");
1849
+ writer.appendSpace();
1850
+ this.options.forEach((v, i) => {
1851
+ if (i > 0) {
1852
+ writer.appendSpace();
1853
+ }
1854
+ writer.append(v.name);
1855
+ if (v.value) {
1856
+ writer.appendBinaryOp("=");
1857
+ writer.append(v.value);
1858
+ }
1859
+ });
1860
+ }
1861
+ }
1862
+ ECSqlOptionsClauseExpr.type = ExprType.ECSqlOptionsClause;
1863
+ export { ECSqlOptionsClauseExpr };
1864
+ /**
1865
+ * A single property value assignment for update clause
1866
+ * @alpha
1867
+ */
1868
+ class AssignmentExpr extends Expr {
1869
+ constructor(propertyName, valueExpr) {
1870
+ super(SetClauseExpr.type);
1871
+ this.propertyName = propertyName;
1872
+ this.valueExpr = valueExpr;
1873
+ }
1874
+ get children() {
1875
+ return [this.propertyName, this.valueExpr];
1876
+ }
1877
+ static deserialize(node) {
1878
+ if (node.id !== NativeExpIds.Assignment) {
1879
+ throw new Error(`Parse node is 'node.id !== NativeExpIds.Assignment'. ${JSON.stringify(node)}`);
1880
+ }
1881
+ return new AssignmentExpr(PropertyNameExpr.deserialize(node.propertyName), ValueExpr.deserialize(node.value));
1882
+ }
1883
+ writeTo(writer) {
1884
+ writer.appendExp(this.propertyName);
1885
+ writer.appendBinaryOp("=");
1886
+ writer.appendExp(this.valueExpr);
1887
+ }
1888
+ }
1889
+ AssignmentExpr.type = ExprType.Assignment;
1890
+ export { AssignmentExpr };
1891
+ /**
1892
+ * Describe a set clause in a UPDATE statement
1893
+ * @alpha
1894
+ */
1895
+ class SetClauseExpr extends Expr {
1896
+ constructor(assignments) {
1897
+ super(SetClauseExpr.type);
1898
+ this.assignments = assignments;
1899
+ }
1900
+ get children() {
1901
+ return [...this.assignments];
1902
+ }
1903
+ static deserialize(node) {
1904
+ if (!Array.isArray(node)) {
1905
+ throw new Error(`AssignmentClause expect array of NativeECSqlParseNode. ${JSON.stringify(node)}`);
1906
+ }
1907
+ const setClause = node;
1908
+ const assignments = [];
1909
+ setClause.forEach((v) => {
1910
+ assignments.push(AssignmentExpr.deserialize(v));
1911
+ });
1912
+ return new SetClauseExpr(assignments);
1913
+ }
1914
+ writeTo(writer) {
1915
+ writer.appendKeyword("SET");
1916
+ writer.appendSpace();
1917
+ this.assignments.forEach((v, i) => {
1918
+ if (i > 0) {
1919
+ writer.appendComma();
1920
+ }
1921
+ writer.appendExp(v);
1922
+ });
1923
+ }
1924
+ }
1925
+ SetClauseExpr.type = ExprType.SetClause;
1926
+ export { SetClauseExpr };
1927
+ /**
1928
+ * Describe a strong typed IIF function in ECSQL
1929
+ * @alpha
1930
+ */
1931
+ class IIFExpr extends ValueExpr {
1932
+ constructor(whenExpr, thenExpr, elseExpr) {
1933
+ super(IIFExpr.type);
1934
+ this.whenExpr = whenExpr;
1935
+ this.thenExpr = thenExpr;
1936
+ this.elseExpr = elseExpr;
1937
+ }
1938
+ get children() {
1939
+ return [this.whenExpr, this.thenExpr, this.elseExpr];
1940
+ }
1941
+ static deserialize(node) {
1942
+ if (node.id !== NativeExpIds.IIF) {
1943
+ throw new Error(`Parse node is 'node.id !== NativeExpIds.IIF'. ${JSON.stringify(node)}`);
1944
+ }
1945
+ return new IIFExpr(BooleanExpr.deserialize(node.when), ValueExpr.deserialize(node.then), ValueExpr.deserialize(node.else));
1946
+ }
1947
+ writeTo(writer) {
1948
+ writer.appendKeyword("IIF");
1949
+ writer.append("(");
1950
+ writer.appendExp(this.whenExpr);
1951
+ writer.appendComma();
1952
+ writer.appendExp(this.thenExpr);
1953
+ writer.appendComma();
1954
+ writer.appendExp(this.elseExpr);
1955
+ writer.append(")");
1956
+ }
1957
+ }
1958
+ IIFExpr.type = ExprType.IIF;
1959
+ export { IIFExpr };
1960
+ /**
1961
+ * Describe a CASE-WHEN-THEN expression in ECSQL
1962
+ * @alpha
1963
+ */
1964
+ class SearchCaseExpr extends ValueExpr {
1965
+ constructor(whenThenList, elseExpr) {
1966
+ super(SearchCaseExpr.type);
1967
+ this.whenThenList = whenThenList;
1968
+ this.elseExpr = elseExpr;
1969
+ }
1970
+ get children() {
1971
+ const exprs = [];
1972
+ this.whenThenList.forEach((v) => {
1973
+ exprs.push(v.whenExpr, v.thenExpr);
1974
+ });
1975
+ if (this.elseExpr)
1976
+ exprs.push(this.elseExpr);
1977
+ return exprs;
1978
+ }
1979
+ static deserialize(node) {
1980
+ if (node.id !== NativeExpIds.SearchCaseValue) {
1981
+ throw new Error(`Parse node is 'node.id !== NativeExpIds.SearchCaseValue'. ${JSON.stringify(node)}`);
1982
+ }
1983
+ const whenThenList = [];
1984
+ for (const whenThenProps of node.whenThenList) {
1985
+ whenThenList.push({
1986
+ whenExpr: BooleanExpr.deserialize(whenThenProps.when),
1987
+ thenExpr: ValueExpr.deserialize(whenThenProps.then),
1988
+ });
1989
+ }
1990
+ const elseExp = node.elseExp ? ValueExpr.deserialize(node.elseExp) : undefined;
1991
+ return new SearchCaseExpr(whenThenList, elseExp);
1992
+ }
1993
+ writeTo(writer) {
1994
+ writer.appendKeyword("CASE");
1995
+ this.whenThenList.forEach((v) => {
1996
+ writer.appendSpace();
1997
+ writer.appendKeyword("WHEN");
1998
+ writer.appendSpace();
1999
+ writer.appendExp(v.whenExpr);
2000
+ writer.appendSpace();
2001
+ writer.appendKeyword("THEN");
2002
+ writer.appendSpace();
2003
+ writer.appendExp(v.thenExpr);
2004
+ });
2005
+ if (this.elseExpr) {
2006
+ writer.appendSpace();
2007
+ writer.appendKeyword("ELSE");
2008
+ writer.appendSpace();
2009
+ writer.appendExp(this.elseExpr);
2010
+ }
2011
+ writer.appendSpace();
2012
+ writer.appendKeyword("END");
2013
+ }
2014
+ }
2015
+ SearchCaseExpr.type = ExprType.SearchCase;
2016
+ export { SearchCaseExpr };
2017
+ /**
2018
+ * Describe a binary value expression
2019
+ * @alpha
2020
+ */
2021
+ class BinaryValueExpr extends ValueExpr {
2022
+ constructor(op, lhsExpr, rhsExpr) {
2023
+ super(BinaryValueExpr.type);
2024
+ this.op = op;
2025
+ this.lhsExpr = lhsExpr;
2026
+ this.rhsExpr = rhsExpr;
2027
+ }
2028
+ get children() {
2029
+ return [this.lhsExpr, this.rhsExpr];
2030
+ }
2031
+ static deserialize(node) {
2032
+ if (node.id !== NativeExpIds.BinaryValue && node.id !== NativeExpIds.BinaryBoolean) {
2033
+ throw new Error(`Parse node is 'node.id !== NativeExpIds.BinaryValue' . ${JSON.stringify(node)}`);
2034
+ }
2035
+ return new BinaryValueExpr(node.op, ValueExpr.deserialize(node.lhs), ValueExpr.deserialize(node.rhs));
2036
+ }
2037
+ writeTo(writer) {
2038
+ writer.append("(");
2039
+ writer.appendExp(this.lhsExpr);
2040
+ writer.appendBinaryOp(this.op);
2041
+ writer.appendExp(this.rhsExpr);
2042
+ writer.append(")");
2043
+ }
2044
+ }
2045
+ BinaryValueExpr.type = ExprType.BinaryValue;
2046
+ export { BinaryValueExpr };
2047
+ /**
2048
+ * Cast a expression into a target time e.g. CAST(<expr> AS STRING)
2049
+ * @alpha
2050
+ */
2051
+ class CastExpr extends ValueExpr {
2052
+ constructor(valueExpr, targetType) {
2053
+ super(CastExpr.type);
2054
+ this.valueExpr = valueExpr;
2055
+ this.targetType = targetType;
2056
+ }
2057
+ get children() {
2058
+ return [this.valueExpr];
2059
+ }
2060
+ static deserialize(node) {
2061
+ if (node.id !== NativeExpIds.Cast) {
2062
+ throw new Error(`Parse node is 'node.id !== NativeExpIds.CastExp'. ${JSON.stringify(node)}`);
2063
+ }
2064
+ return new CastExpr(ValueExpr.deserialize(node.exp), node.as);
2065
+ }
2066
+ writeTo(writer) {
2067
+ writer.appendKeyword("CAST");
2068
+ writer.append("(");
2069
+ writer.appendExp(this.valueExpr);
2070
+ writer.appendSpace();
2071
+ writer.appendKeyword("AS");
2072
+ writer.appendSpace();
2073
+ writer.append(this.targetType);
2074
+ writer.append(")");
2075
+ }
2076
+ }
2077
+ CastExpr.type = ExprType.Cast;
2078
+ export { CastExpr };
2079
+ /**
2080
+ * Represent a member function called w.r.t a ClassNameExpr
2081
+ * @alpha
2082
+ */
2083
+ class MemberFuncCallExpr extends Expr {
2084
+ constructor(functionName, args) {
2085
+ super(MemberFuncCallExpr.type);
2086
+ this.functionName = functionName;
2087
+ this.args = args;
2088
+ }
2089
+ get children() {
2090
+ return [...this.args];
2091
+ }
2092
+ static deserialize(node) {
2093
+ if (node.id !== NativeExpIds.MemberFunctionCall) {
2094
+ throw new Error(`Parse node is 'node.id !== NativeExpIds.MemberFunctionCall'. ${JSON.stringify(node)}`);
2095
+ }
2096
+ const args = Array.from(node.args.map((v) => ValueExpr.deserialize(v)));
2097
+ return new MemberFuncCallExpr(node.name, args);
2098
+ }
2099
+ writeTo(writer) {
2100
+ writer.appendQuoted(this.functionName);
2101
+ writer.append("(");
2102
+ this.args.forEach((v, i) => {
2103
+ if (i > 0) {
2104
+ writer.appendComma();
2105
+ }
2106
+ writer.appendExp(v);
2107
+ });
2108
+ writer.append(")");
2109
+ }
2110
+ }
2111
+ MemberFuncCallExpr.type = ExprType.MemberFuncCall;
2112
+ export { MemberFuncCallExpr };
2113
+ /**
2114
+ * Represent a function call in ecsql
2115
+ * @alpha
2116
+ */
2117
+ class FuncCallExpr extends ValueExpr {
2118
+ constructor(functionName, args, allOrDistinct) {
2119
+ super(FuncCallExpr.type);
2120
+ this.functionName = functionName;
2121
+ this.args = args;
2122
+ this.allOrDistinct = allOrDistinct;
2123
+ }
2124
+ get children() {
2125
+ return [...this.args];
2126
+ }
2127
+ static deserialize(node) {
2128
+ if (node.id !== NativeExpIds.FunctionCall) {
2129
+ throw new Error(`Parse node is 'node.id !== NativeExpIds.FunctionCall'. ${JSON.stringify(node)}`);
2130
+ }
2131
+ const args = Array.from(node.args.map((v) => ValueExpr.deserialize(v)));
2132
+ const rowQuantifier = node.quantifier ? node.quantifier : undefined;
2133
+ return new FuncCallExpr(node.name, args, rowQuantifier);
2134
+ }
2135
+ writeTo(writer) {
2136
+ writer.append(this.functionName);
2137
+ writer.append("(");
2138
+ if (this.allOrDistinct) {
2139
+ writer.appendKeyword(this.allOrDistinct);
2140
+ writer.appendSpace();
2141
+ }
2142
+ this.args.forEach((v, i) => {
2143
+ if (i > 0) {
2144
+ writer.appendComma();
2145
+ }
2146
+ writer.appendExp(v);
2147
+ });
2148
+ writer.append(")");
2149
+ }
2150
+ static makeAbs(arg) {
2151
+ return new FuncCallExpr("ABS", [arg]);
2152
+ }
2153
+ static makeLower(arg) {
2154
+ return new FuncCallExpr("LOWER", [arg]);
2155
+ }
2156
+ static makeUpper(arg) {
2157
+ return new FuncCallExpr("UPPER", [arg]);
2158
+ }
2159
+ static makeLTrim(arg0, arg1) {
2160
+ return new FuncCallExpr("LTRIM", arg1 ? [arg0, arg1] : [arg0]);
2161
+ }
2162
+ static makeRTrim(arg0, arg1) {
2163
+ return new FuncCallExpr("RTRIM", arg1 ? [arg0, arg1] : [arg0]);
2164
+ }
2165
+ static makeLHex(arg) {
2166
+ return new FuncCallExpr("HEX", [arg]);
2167
+ }
2168
+ static makeLIfNull(arg0, arg1) {
2169
+ return new FuncCallExpr("IFNULL", [arg0, arg1]);
2170
+ }
2171
+ static makeInstr(arg0, arg1) {
2172
+ return new FuncCallExpr("INSTR", [arg0, arg1]);
2173
+ }
2174
+ static makeLength(arg0) {
2175
+ return new FuncCallExpr("LENGTH", [arg0]);
2176
+ }
2177
+ static makeLike(arg0, arg1, arg2) {
2178
+ return new FuncCallExpr("LIKE", arg2 ? [arg0, arg1, arg2] : [arg0, arg1]);
2179
+ }
2180
+ static makeLikelihood(arg0, arg1) {
2181
+ return new FuncCallExpr("LIKELIHOOD", [arg0, arg1]);
2182
+ }
2183
+ static makeMax(arg, ...optionalArgs) {
2184
+ return new FuncCallExpr("MAX", [arg, ...optionalArgs]);
2185
+ }
2186
+ static makeMin(arg, ...optionalArgs) {
2187
+ return new FuncCallExpr("MIN", [arg, ...optionalArgs]);
2188
+ }
2189
+ static makePrintf(arg, ...optionalArgs) {
2190
+ return new FuncCallExpr("PRINTF", [arg, ...optionalArgs]);
2191
+ }
2192
+ static makeRandom() {
2193
+ return new FuncCallExpr("RANDOM", []);
2194
+ }
2195
+ static makeQuote(arg) {
2196
+ return new FuncCallExpr("QUOTE", [arg]);
2197
+ }
2198
+ static makeRandomBlob(arg) {
2199
+ return new FuncCallExpr("RANDOMBLOB", [arg]);
2200
+ }
2201
+ static makeReplace(arg0, arg1, arg2) {
2202
+ return new FuncCallExpr("REPLACE", [arg0, arg1, arg2]);
2203
+ }
2204
+ static makeRound(arg0, arg1) {
2205
+ return new FuncCallExpr("ROUND", arg1 ? [arg0, arg1] : [arg0]);
2206
+ }
2207
+ static makeSign(arg0) {
2208
+ return new FuncCallExpr("SIGN", [arg0]);
2209
+ }
2210
+ static makeUnhex(arg0) {
2211
+ return new FuncCallExpr("UNHEX", [arg0]);
2212
+ }
2213
+ static makeSoundex(arg0) {
2214
+ return new FuncCallExpr("SOUNDEX", [arg0]);
2215
+ }
2216
+ static makeTrim(arg0, arg1) {
2217
+ return new FuncCallExpr("TRIM", arg1 ? [arg0, arg1] : [arg0]);
2218
+ }
2219
+ static makeTypeOf(arg0) {
2220
+ return new FuncCallExpr("TYPEOF", [arg0]);
2221
+ }
2222
+ static makeZeroBlob(arg0) {
2223
+ return new FuncCallExpr("ZEROBLOB", [arg0]);
2224
+ }
2225
+ static makeUnlikely(arg0) {
2226
+ return new FuncCallExpr("UNLIKELY", [arg0]);
2227
+ }
2228
+ static makeSubstring(arg0, arg1, arg2) {
2229
+ return new FuncCallExpr("SUBSTR", [arg0, arg1, arg2]);
2230
+ }
2231
+ static makeStrToGuid(arg0) {
2232
+ return new FuncCallExpr("STRTOGUID", [arg0]);
2233
+ }
2234
+ static makeGuidToStr(arg0) {
2235
+ return new FuncCallExpr("GUIDTOSTR", [arg0]);
2236
+ }
2237
+ static makeIdToHex(arg0) {
2238
+ return new FuncCallExpr("IDTOHEX", [arg0]);
2239
+ }
2240
+ static makeHexToId(arg0) {
2241
+ return new FuncCallExpr("HEXTOID", [arg0]);
2242
+ }
2243
+ static makeEcClassName(arg0, fmt = "s:c") {
2244
+ return new FuncCallExpr("EC_CLASSNAME", [arg0, new LiteralExpr(LiteralValueType.String, fmt)]);
2245
+ }
2246
+ static makeEcClassId(arg0) {
2247
+ return new FuncCallExpr("EC_CLASSId", [arg0]);
2248
+ }
2249
+ static makeInstanceOf(arg0, arg1) {
2250
+ return new FuncCallExpr("EC_INSTANCEOF", [arg0, arg1]);
2251
+ }
2252
+ }
2253
+ FuncCallExpr.type = ExprType.FuncCall;
2254
+ export { FuncCallExpr };
2255
+ /**
2256
+ * Represent positional or named parameter
2257
+ * @alpha
2258
+ */
2259
+ class ParameterExpr extends ValueExpr {
2260
+ constructor(name) {
2261
+ super(ParameterExpr.type);
2262
+ this.name = name;
2263
+ }
2264
+ get children() {
2265
+ return [];
2266
+ }
2267
+ static deserialize(node) {
2268
+ if (node.id !== NativeExpIds.Parameter) {
2269
+ throw new Error(`Parse node is 'node.id !== NativeExpIds.Parameter'. ${JSON.stringify(node)}`);
2270
+ }
2271
+ return new ParameterExpr(node.name);
2272
+ }
2273
+ writeTo(writer) {
2274
+ if (this.name && this.name !== "")
2275
+ writer.append(`:${this.name}`);
2276
+ else
2277
+ writer.append(`?`);
2278
+ }
2279
+ }
2280
+ ParameterExpr.type = ExprType.Parameter;
2281
+ export { ParameterExpr };
2282
+ /**
2283
+ * Unary value with operator e.g. [+|-|~]<number>
2284
+ * @alpha
2285
+ */
2286
+ class UnaryValueExpr extends ValueExpr {
2287
+ constructor(op, valueExpr) {
2288
+ super(UnaryValueExpr.type);
2289
+ this.op = op;
2290
+ this.valueExpr = valueExpr;
2291
+ }
2292
+ get children() {
2293
+ return [this.valueExpr];
2294
+ }
2295
+ static deserialize(node) {
2296
+ if (node.id !== NativeExpIds.UnaryValue && node.id !== NativeExpIds.BooleanFactor) {
2297
+ throw new Error(`Parse node is 'node.id !== NativeExpIds.UnaryValue && node.id !== NativeExpIds.BooleanFactor'. ${JSON.stringify(node)}`);
2298
+ }
2299
+ if (node.op !== "+" && node.op !== "-" && node.op !== "~") {
2300
+ throw new Error(`Unrecognized operator in .node.op'. Must me on of UnaryOp. ${JSON.stringify(node)}`);
2301
+ }
2302
+ return new UnaryValueExpr(node.op, ValueExpr.deserialize(node.exp));
2303
+ }
2304
+ writeTo(writer) {
2305
+ writer.append(this.op);
2306
+ writer.appendExp(this.valueExpr);
2307
+ }
2308
+ }
2309
+ UnaryValueExpr.type = ExprType.Unary;
2310
+ export { UnaryValueExpr };
2311
+ /**
2312
+ * Represent constant literal like string, data, time, timestamp, number or null
2313
+ * @alpha
2314
+ */
2315
+ class LiteralExpr extends ValueExpr {
2316
+ constructor(valueType, rawValue) {
2317
+ super(LiteralExpr.type);
2318
+ this.valueType = valueType;
2319
+ this.rawValue = rawValue;
2320
+ }
2321
+ get children() {
2322
+ return [];
2323
+ }
2324
+ static deserialize(node) {
2325
+ if (node.id !== NativeExpIds.LiteralValue) {
2326
+ throw new Error(`Parse node is 'node.id !== NativeExpIds.LiteralValue'. ${JSON.stringify(node)}`);
2327
+ }
2328
+ return new LiteralExpr(node.kind, node.value);
2329
+ }
2330
+ writeTo(writer) {
2331
+ if (this.valueType === LiteralValueType.String)
2332
+ writer.appendStringLiteral(this.rawValue);
2333
+ else if (this.valueType === LiteralValueType.Date)
2334
+ writer.appendKeyword("DATE").appendSpace().appendStringLiteral(this.rawValue);
2335
+ else if (this.valueType === LiteralValueType.Time)
2336
+ writer.appendKeyword("TIME").appendSpace().appendStringLiteral(this.rawValue);
2337
+ else if (this.valueType === LiteralValueType.Timestamp)
2338
+ writer.appendKeyword("TIMESTAMP").appendSpace().appendStringLiteral(this.rawValue);
2339
+ else if (this.valueType === LiteralValueType.Null)
2340
+ writer.appendKeyword("NULL");
2341
+ else
2342
+ writer.append(this.rawValue);
2343
+ }
2344
+ static makeRaw(val) { return new LiteralExpr(LiteralValueType.Raw, val); }
2345
+ static makeString(val) { return new LiteralExpr(LiteralValueType.String, val); }
2346
+ static makeNumber(val) { return new LiteralExpr(LiteralValueType.Raw, val.toString()); }
2347
+ static makeDate(val) { return new LiteralExpr(LiteralValueType.Date, val.toDateString()); }
2348
+ static makeTime(val) { return new LiteralExpr(LiteralValueType.String, val.toTimeString()); }
2349
+ static makeTimestamp(val) { return new LiteralExpr(LiteralValueType.String, val.toTimeString()); }
2350
+ static makeNull() { return new LiteralExpr(LiteralValueType.Null, ""); }
2351
+ }
2352
+ LiteralExpr.type = ExprType.Literal;
2353
+ export { LiteralExpr };
2354
+ /**
2355
+ * Represent property name identifier
2356
+ * @alpha
2357
+ */
2358
+ class PropertyNameExpr extends ValueExpr {
2359
+ constructor(propertyPath) {
2360
+ super(PropertyNameExpr.type);
2361
+ this.propertyPath = propertyPath;
2362
+ }
2363
+ get children() {
2364
+ return [];
2365
+ }
2366
+ static deserialize(node) {
2367
+ if (node.id !== NativeExpIds.PropertyName) {
2368
+ throw new Error(`Parse node is 'node.id !== NativeExpIds.PropertyNameExp'. ${JSON.stringify(node)}`);
2369
+ }
2370
+ return new PropertyNameExpr(node.path);
2371
+ }
2372
+ writeTo(writer) {
2373
+ // donot quote $
2374
+ const str = this.propertyPath.split("->");
2375
+ if (str.length === 2) {
2376
+ writer.append(str[0].split(".").map((v) => v.startsWith("[") || v === "$" ? v : `[${v}]`).join("."));
2377
+ writer.append("->");
2378
+ }
2379
+ writer.append(str[str.length - 1].split(".").map((v) => v.startsWith("[") || v === "$" ? v : `[${v}]`).join("."));
2380
+ }
2381
+ }
2382
+ PropertyNameExpr.type = ExprType.PropertyName;
2383
+ export { PropertyNameExpr };
2384
+ //# sourceMappingURL=ECSqlAst.js.map