documents.js 1.63.0 → 1.64.0

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.
Files changed (177) hide show
  1. package/README.md +113 -20
  2. package/dist/convert/convert.cjs +3 -3
  3. package/dist/convert/convert.d.cts +5 -2
  4. package/dist/convert/convert.d.ts +4 -1
  5. package/dist/convert/convert.js +3 -3
  6. package/dist/edit/docx/content.d.cts +1 -1
  7. package/dist/edit/docx/content.d.ts +1 -1
  8. package/dist/edit/docx/paragraph.d.cts +3 -3
  9. package/dist/edit/docx/paragraph.d.ts +3 -3
  10. package/dist/edit/ods/address.cjs +42 -24
  11. package/dist/edit/ods/address.d.cts +12 -2
  12. package/dist/edit/ods/address.d.ts +12 -2
  13. package/dist/edit/ods/address.js +39 -25
  14. package/dist/edit/ods/column-row.cjs +68 -6
  15. package/dist/edit/ods/column-row.d.cts +5 -1
  16. package/dist/edit/ods/column-row.d.ts +5 -1
  17. package/dist/edit/ods/column-row.js +68 -10
  18. package/dist/edit/ods/content.cjs +10 -2
  19. package/dist/edit/ods/content.js +10 -2
  20. package/dist/edit/ods/floating.cjs +90 -0
  21. package/dist/edit/ods/floating.d.cts +7 -0
  22. package/dist/edit/ods/floating.d.ts +7 -0
  23. package/dist/edit/ods/floating.js +88 -0
  24. package/dist/edit/ods/print-settings.cjs +158 -2
  25. package/dist/edit/ods/print-settings.js +159 -3
  26. package/dist/edit/ods/sheet.cjs +13 -0
  27. package/dist/edit/ods/sheet.d.cts +5 -1
  28. package/dist/edit/ods/sheet.d.ts +5 -1
  29. package/dist/edit/ods/sheet.js +14 -1
  30. package/dist/edit/odt/content.cjs +8 -4
  31. package/dist/edit/odt/content.js +8 -4
  32. package/dist/edit/odt/editor.cjs +7 -0
  33. package/dist/edit/odt/editor.d.cts +3 -0
  34. package/dist/edit/odt/editor.d.ts +3 -0
  35. package/dist/edit/odt/editor.js +7 -0
  36. package/dist/edit/odt/formula.cjs +19 -0
  37. package/dist/edit/odt/formula.d.cts +8 -0
  38. package/dist/edit/odt/formula.d.ts +8 -0
  39. package/dist/edit/odt/formula.js +17 -0
  40. package/dist/evaluate-BU5N1Jk1.d.ts +11 -0
  41. package/dist/evaluate-BhMXY6DM.d.cts +11 -0
  42. package/dist/firebird/backup.d.cts +1 -1
  43. package/dist/firebird/backup.d.ts +1 -1
  44. package/dist/firebird/data.cjs +30 -16
  45. package/dist/firebird/data.d.cts +3 -2
  46. package/dist/firebird/data.d.ts +3 -2
  47. package/dist/firebird/data.js +30 -17
  48. package/dist/fonts/ooxml.d.cts +1 -1
  49. package/dist/fonts/registry.d.cts +1 -1
  50. package/dist/formula-CgydMiTt.d.ts +10 -0
  51. package/dist/formula-CiwPw8nY.d.cts +10 -0
  52. package/dist/hsqldb/binary-script.d.cts +1 -1
  53. package/dist/hsqldb/binary-script.d.ts +1 -1
  54. package/dist/hsqldb/cache.d.cts +1 -1
  55. package/dist/hsqldb/cache.d.ts +1 -1
  56. package/dist/hsqldb/rowformat.cjs +22 -13
  57. package/dist/hsqldb/rowformat.js +22 -13
  58. package/dist/hsqldb/script.d.cts +1 -18
  59. package/dist/hsqldb/script.d.ts +1 -18
  60. package/dist/index.cjs +56 -0
  61. package/dist/index.d.cts +22 -8
  62. package/dist/index.d.ts +21 -7
  63. package/dist/index.js +15 -2
  64. package/dist/layout/sheets.cjs +30 -24
  65. package/dist/layout/sheets.js +31 -25
  66. package/dist/layout/slides.cjs +6 -4
  67. package/dist/layout/slides.js +7 -5
  68. package/dist/lexer-DGPWx_f2.d.cts +42 -0
  69. package/dist/lexer-DGPWx_f2.d.ts +42 -0
  70. package/dist/mathml/layout.d.cts +1 -1
  71. package/dist/mathml/layout.d.ts +1 -1
  72. package/dist/mathml/variant.d.cts +1 -6
  73. package/dist/mathml/variant.d.ts +1 -6
  74. package/dist/odb/csv.d.cts +1 -1
  75. package/dist/odb/csv.d.ts +1 -1
  76. package/dist/odb/formula/definition.cjs +49 -0
  77. package/dist/odb/formula/definition.d.cts +8 -0
  78. package/dist/odb/formula/definition.d.ts +8 -0
  79. package/dist/odb/formula/definition.js +46 -0
  80. package/dist/odb/formula/errors.cjs +47 -0
  81. package/dist/odb/formula/errors.d.cts +21 -0
  82. package/dist/odb/formula/errors.d.ts +21 -0
  83. package/dist/odb/formula/errors.js +43 -0
  84. package/dist/odb/formula/evaluate.cjs +283 -0
  85. package/dist/odb/formula/evaluate.d.cts +43 -0
  86. package/dist/odb/formula/evaluate.d.ts +43 -0
  87. package/dist/odb/formula/evaluate.js +281 -0
  88. package/dist/odb/formula/parser.cjs +198 -0
  89. package/dist/odb/formula/parser.d.cts +29 -0
  90. package/dist/odb/formula/parser.d.ts +29 -0
  91. package/dist/odb/formula/parser.js +197 -0
  92. package/dist/odb/read.d.cts +1 -1
  93. package/dist/odb/read.d.ts +1 -1
  94. package/dist/odb/report/content.cjs +27 -0
  95. package/dist/odb/report/content.d.cts +14 -0
  96. package/dist/odb/report/content.d.ts +14 -0
  97. package/dist/odb/report/content.js +25 -0
  98. package/dist/odb/report/render.cjs +106 -0
  99. package/dist/odb/report/render.d.cts +7 -0
  100. package/dist/odb/report/render.d.ts +7 -0
  101. package/dist/odb/report/render.js +106 -0
  102. package/dist/odb/report/source.cjs +45 -0
  103. package/dist/odb/report/source.d.cts +14 -0
  104. package/dist/odb/report/source.d.ts +14 -0
  105. package/dist/odb/report/source.js +42 -0
  106. package/dist/odb/spreadsheet.d.cts +1 -1
  107. package/dist/odb/spreadsheet.d.ts +1 -1
  108. package/dist/odb/sql/errors.cjs +38 -0
  109. package/dist/odb/sql/errors.d.cts +17 -0
  110. package/dist/odb/sql/errors.d.ts +17 -0
  111. package/dist/odb/sql/errors.js +35 -0
  112. package/dist/odb/sql/evaluate.cjs +312 -0
  113. package/dist/odb/sql/evaluate.d.cts +2 -0
  114. package/dist/odb/sql/evaluate.d.ts +2 -0
  115. package/dist/odb/sql/evaluate.js +311 -0
  116. package/dist/odb/sql/lexer.cjs +282 -0
  117. package/dist/odb/sql/lexer.d.cts +2 -0
  118. package/dist/odb/sql/lexer.d.ts +2 -0
  119. package/dist/odb/sql/lexer.js +281 -0
  120. package/dist/odb/sql/parser.cjs +479 -0
  121. package/dist/odb/sql/parser.d.cts +2 -0
  122. package/dist/odb/sql/parser.d.ts +2 -0
  123. package/dist/odb/sql/parser.js +478 -0
  124. package/dist/odb/values.cjs +75 -0
  125. package/dist/odb/values.d.cts +2 -0
  126. package/dist/odb/values.d.ts +2 -0
  127. package/dist/odb/values.js +69 -0
  128. package/dist/odf/odt/read.cjs +43 -21
  129. package/dist/odf/odt/read.js +43 -21
  130. package/dist/odf-package/formula.cjs +59 -0
  131. package/dist/odf-package/formula.d.cts +11 -0
  132. package/dist/odf-package/formula.d.ts +11 -0
  133. package/dist/odf-package/formula.js +58 -0
  134. package/dist/odf-package/manifest.cjs +29 -0
  135. package/dist/odf-package/manifest.d.cts +5 -2
  136. package/dist/odf-package/manifest.d.ts +5 -2
  137. package/dist/odf-package/manifest.js +30 -2
  138. package/dist/odf-package/media.cjs +2 -1
  139. package/dist/odf-package/media.js +2 -2
  140. package/dist/omml/read.cjs +265 -0
  141. package/dist/omml/read.d.cts +12 -0
  142. package/dist/omml/read.d.ts +12 -0
  143. package/dist/omml/read.js +263 -0
  144. package/dist/omml/shared.cjs +67 -0
  145. package/dist/omml/shared.d.cts +2 -0
  146. package/dist/omml/shared.d.ts +2 -0
  147. package/dist/omml/shared.js +64 -0
  148. package/dist/omml/write.cjs +3 -51
  149. package/dist/omml/write.d.cts +2 -2
  150. package/dist/omml/write.d.ts +2 -2
  151. package/dist/omml/write.js +1 -49
  152. package/dist/ooxml/docx/extras.cjs +15 -0
  153. package/dist/ooxml/docx/extras.d.cts +12 -0
  154. package/dist/ooxml/docx/extras.d.ts +12 -0
  155. package/dist/ooxml/docx/extras.js +14 -0
  156. package/dist/ooxml/docx/formula.cjs +109 -0
  157. package/dist/ooxml/docx/formula.d.cts +2 -0
  158. package/dist/ooxml/docx/formula.d.ts +2 -0
  159. package/dist/ooxml/docx/formula.js +108 -0
  160. package/dist/ooxml/docx/read.cjs +10 -2
  161. package/dist/ooxml/docx/read.d.cts +6 -2
  162. package/dist/ooxml/docx/read.d.ts +6 -2
  163. package/dist/ooxml/docx/read.js +11 -3
  164. package/dist/parser-B9vC1T6T.d.cts +101 -0
  165. package/dist/parser-DQSgYJzQ.d.ts +101 -0
  166. package/dist/{registry-CtPhMD0f.d.cts → registry-lqJej0Jr.d.cts} +1 -1
  167. package/dist/script-DsGGIzGU.d.cts +19 -0
  168. package/dist/script-DsGGIzGU.d.ts +19 -0
  169. package/dist/shared-DLZ3IQUl.d.cts +15 -0
  170. package/dist/shared-DUOzjwcL.d.ts +15 -0
  171. package/dist/values-BetetbaH.d.cts +23 -0
  172. package/dist/values-BetetbaH.d.ts +23 -0
  173. package/dist/variant-BMrebjMw.d.cts +7 -0
  174. package/dist/variant-BMrebjMw.d.ts +7 -0
  175. package/dist/{write-DuyfnbL_.d.cts → write-BQ6SK8r8.d.cts} +2 -6
  176. package/dist/{write-Zqwx6pka.d.ts → write-THs7ipBq.d.ts} +2 -6
  177. package/package.json +1 -1
@@ -0,0 +1,478 @@
1
+ import { HsqldbSqlParseError, HsqldbSqlUnsupportedError } from "./errors.js";
2
+ import { tokenizeSql } from "./lexer.js";
3
+ //#region src/odb/sql/parser.ts
4
+ const AGGREGATE_FUNCTIONS = /* @__PURE__ */ new Set([
5
+ "COUNT",
6
+ "SUM",
7
+ "AVG",
8
+ "MIN",
9
+ "MAX"
10
+ ]);
11
+ function isAggregateFunction(keyword) {
12
+ return AGGREGATE_FUNCTIONS.has(keyword);
13
+ }
14
+ const OUT_OF_SCOPE_KEYWORDS = /* @__PURE__ */ new Map([
15
+ ["JOIN", "a JOIN"],
16
+ ["INNER", "a JOIN"],
17
+ ["OUTER", "a JOIN"],
18
+ ["LEFT", "a JOIN"],
19
+ ["RIGHT", "a JOIN"],
20
+ ["FULL", "a JOIN"],
21
+ ["CROSS", "a JOIN"],
22
+ ["NATURAL", "a JOIN"],
23
+ ["ON", "a JOIN"],
24
+ ["USING", "a JOIN"],
25
+ ["UNION", "UNION"],
26
+ ["INTERSECT", "INTERSECT"],
27
+ ["EXCEPT", "EXCEPT"],
28
+ ["MINUS", "EXCEPT (MINUS)"],
29
+ ["DISTINCT", "DISTINCT"],
30
+ ["ALL", "the ALL quantifier"],
31
+ ["HAVING", "HAVING"],
32
+ ["LIMIT", "a row-limit clause (LIMIT)"],
33
+ ["OFFSET", "a row-limit clause (OFFSET)"],
34
+ ["FETCH", "a row-limit clause (FETCH)"],
35
+ ["TOP", "a row-limit clause (TOP)"],
36
+ ["AS", "a column or table alias (AS)"],
37
+ ["CASE", "a CASE expression"],
38
+ ["WHEN", "a CASE expression"],
39
+ ["THEN", "a CASE expression"],
40
+ ["ELSE", "a CASE expression"],
41
+ ["END", "a CASE expression"],
42
+ ["EXISTS", "an EXISTS subquery"],
43
+ ["ANY", "a quantified subquery predicate (ANY)"],
44
+ ["SOME", "a quantified subquery predicate (SOME)"],
45
+ ["WITH", "a common table expression (WITH)"],
46
+ ["INTO", "a SELECT ... INTO clause"],
47
+ ["INSERT", "a non-SELECT statement (INSERT)"],
48
+ ["UPDATE", "a non-SELECT statement (UPDATE)"],
49
+ ["DELETE", "a non-SELECT statement (DELETE)"],
50
+ ["CREATE", "a non-SELECT statement (CREATE)"],
51
+ ["DROP", "a non-SELECT statement (DROP)"],
52
+ ["ALTER", "a non-SELECT statement (ALTER)"],
53
+ ["ESCAPE", "a LIKE ... ESCAPE clause"],
54
+ ["COLLATE", "a COLLATE clause"],
55
+ ["NULLS", "an ORDER BY NULLS FIRST/LAST clause"]
56
+ ]);
57
+ function describeToken(token) {
58
+ switch (token.kind) {
59
+ case "keyword": return `keyword "${token.keyword}"`;
60
+ case "identifier": return `identifier "${token.text}"`;
61
+ case "string": return `string literal ${token.text}`;
62
+ case "number": return `numeric literal ${token.text}`;
63
+ case "operator": return `operator "${token.operator}"`;
64
+ case "punctuation": return `"${token.punctuation}"`;
65
+ case "end": return "end of statement";
66
+ }
67
+ }
68
+ function rejectOutOfScopeConstructs(tokens, sql) {
69
+ tokens.forEach((token, index) => {
70
+ if (token.kind === "keyword") {
71
+ const construct = OUT_OF_SCOPE_KEYWORDS.get(token.keyword);
72
+ if (construct !== void 0) throw new HsqldbSqlUnsupportedError(construct, sql);
73
+ if (token.keyword === "SELECT" && index > 0) throw new HsqldbSqlUnsupportedError("a subquery", sql);
74
+ return;
75
+ }
76
+ if (token.kind === "identifier") {
77
+ const next = tokens[index + 1];
78
+ if (next?.kind === "punctuation" && next.punctuation === "(") throw new HsqldbSqlUnsupportedError(`a scalar function (${token.text})`, sql);
79
+ }
80
+ });
81
+ }
82
+ var SqlParser = class {
83
+ tokens;
84
+ sql;
85
+ index = 0;
86
+ constructor(sql) {
87
+ this.sql = sql;
88
+ this.tokens = tokenizeSql(sql);
89
+ rejectOutOfScopeConstructs(this.tokens, sql);
90
+ }
91
+ peek() {
92
+ const token = this.tokens[this.index];
93
+ if (token === void 0) throw new HsqldbSqlParseError("unexpected end of statement", this.sql, this.sql.length);
94
+ return token;
95
+ }
96
+ advance() {
97
+ const token = this.peek();
98
+ if (token.kind !== "end") this.index += 1;
99
+ return token;
100
+ }
101
+ fail(expected) {
102
+ const token = this.peek();
103
+ throw new HsqldbSqlParseError(`expected ${expected}, found ${describeToken(token)}`, this.sql, token.start);
104
+ }
105
+ atKeyword(keyword) {
106
+ const token = this.peek();
107
+ return token.kind === "keyword" && token.keyword === keyword;
108
+ }
109
+ atPunctuation(punctuation) {
110
+ const token = this.peek();
111
+ return token.kind === "punctuation" && token.punctuation === punctuation;
112
+ }
113
+ takeKeyword(keyword) {
114
+ if (!this.atKeyword(keyword)) this.fail(`keyword ${keyword}`);
115
+ this.advance();
116
+ }
117
+ takePunctuation(punctuation) {
118
+ if (!this.atPunctuation(punctuation)) this.fail(`"${punctuation}"`);
119
+ this.advance();
120
+ }
121
+ takeName(what) {
122
+ const token = this.peek();
123
+ if (token.kind !== "identifier") this.fail(what);
124
+ this.advance();
125
+ return {
126
+ name: token.name,
127
+ quoted: token.quoted
128
+ };
129
+ }
130
+ parseColumnRef() {
131
+ const start = this.peek().start;
132
+ const first = this.takeName("a column name");
133
+ if (this.atPunctuation(".")) {
134
+ this.advance();
135
+ return {
136
+ qualifier: first,
137
+ column: this.takeName("a column name after \".\""),
138
+ text: this.sql.slice(start, this.previousEnd())
139
+ };
140
+ }
141
+ return {
142
+ qualifier: void 0,
143
+ column: first,
144
+ text: this.sql.slice(start, this.previousEnd())
145
+ };
146
+ }
147
+ previousEnd() {
148
+ const previous = this.tokens[this.index - 1];
149
+ if (previous === void 0) throw new HsqldbSqlParseError("unexpected end of statement", this.sql, this.sql.length);
150
+ return previous.start + previous.text.length;
151
+ }
152
+ parseAggregate(aggregate) {
153
+ this.advance();
154
+ this.takePunctuation("(");
155
+ if (this.atPunctuation("*")) {
156
+ if (aggregate !== "COUNT") this.fail(`a column name -- ${aggregate}(*) is not valid SQL, only COUNT(*) is`);
157
+ this.advance();
158
+ this.takePunctuation(")");
159
+ return {
160
+ kind: "aggregate",
161
+ aggregate,
162
+ argument: { kind: "star" },
163
+ outputName: "COUNT(*)"
164
+ };
165
+ }
166
+ const column = this.parseColumnRef();
167
+ this.takePunctuation(")");
168
+ return {
169
+ kind: "aggregate",
170
+ aggregate,
171
+ argument: {
172
+ kind: "column",
173
+ column
174
+ },
175
+ outputName: `${aggregate}(${column.column.name})`
176
+ };
177
+ }
178
+ parseSelectItem() {
179
+ const token = this.peek();
180
+ if (token.kind === "keyword" && isAggregateFunction(token.keyword)) return this.parseAggregate(token.keyword);
181
+ return {
182
+ kind: "column",
183
+ column: this.parseColumnRef()
184
+ };
185
+ }
186
+ parseSelectList() {
187
+ if (this.atPunctuation("*")) {
188
+ this.advance();
189
+ if (this.atPunctuation(",")) throw new HsqldbSqlUnsupportedError("a select list mixing \"*\" with named columns", this.sql);
190
+ return [{ kind: "star" }];
191
+ }
192
+ const items = [this.parseSelectItem()];
193
+ while (this.atPunctuation(",")) {
194
+ this.advance();
195
+ if (this.atPunctuation("*")) throw new HsqldbSqlUnsupportedError("a select list mixing \"*\" with named columns", this.sql);
196
+ items.push(this.parseSelectItem());
197
+ }
198
+ return items;
199
+ }
200
+ parseLiteral() {
201
+ const token = this.peek();
202
+ if (token.kind === "punctuation" && token.punctuation === "-") {
203
+ this.advance();
204
+ const number = this.peek();
205
+ if (number.kind !== "number") throw new HsqldbSqlUnsupportedError("an arithmetic expression", this.sql);
206
+ this.advance();
207
+ return {
208
+ kind: "number",
209
+ value: -number.value
210
+ };
211
+ }
212
+ if (token.kind === "number") {
213
+ this.advance();
214
+ return {
215
+ kind: "number",
216
+ value: token.value
217
+ };
218
+ }
219
+ if (token.kind === "string") {
220
+ this.advance();
221
+ return {
222
+ kind: "string",
223
+ value: token.value
224
+ };
225
+ }
226
+ if (token.kind === "keyword" && (token.keyword === "TRUE" || token.keyword === "FALSE")) {
227
+ this.advance();
228
+ return {
229
+ kind: "boolean",
230
+ value: token.keyword === "TRUE"
231
+ };
232
+ }
233
+ if (token.kind === "keyword" && token.keyword === "NULL") {
234
+ this.advance();
235
+ return { kind: "null" };
236
+ }
237
+ this.fail("a literal value");
238
+ }
239
+ parseOperand() {
240
+ const token = this.peek();
241
+ if (token.kind === "identifier") return {
242
+ kind: "column",
243
+ column: this.parseColumnRef()
244
+ };
245
+ if (token.kind === "punctuation" && token.punctuation === "(") throw new HsqldbSqlUnsupportedError("a parenthesised value expression", this.sql);
246
+ return {
247
+ kind: "literal",
248
+ literal: this.parseLiteral()
249
+ };
250
+ }
251
+ parseInList(operand, negated) {
252
+ this.takePunctuation("(");
253
+ const values = [];
254
+ for (;;) {
255
+ if (this.peek().kind === "identifier") throw new HsqldbSqlUnsupportedError("a column reference inside an IN list", this.sql);
256
+ values.push(this.parseLiteral());
257
+ if (this.atPunctuation(",")) {
258
+ this.advance();
259
+ continue;
260
+ }
261
+ break;
262
+ }
263
+ this.takePunctuation(")");
264
+ return {
265
+ kind: "in",
266
+ operand,
267
+ values,
268
+ negated
269
+ };
270
+ }
271
+ parseLike(operand, negated) {
272
+ const token = this.peek();
273
+ if (token.kind !== "string") {
274
+ if (token.kind === "identifier") throw new HsqldbSqlUnsupportedError("a non-literal LIKE pattern", this.sql);
275
+ this.fail("a string literal LIKE pattern");
276
+ }
277
+ this.advance();
278
+ return {
279
+ kind: "like",
280
+ operand,
281
+ pattern: token.value,
282
+ negated
283
+ };
284
+ }
285
+ parseBetween(operand, negated) {
286
+ const lower = this.parseOperand();
287
+ this.takeKeyword("AND");
288
+ return {
289
+ kind: "between",
290
+ operand,
291
+ lower,
292
+ upper: this.parseOperand(),
293
+ negated
294
+ };
295
+ }
296
+ parseNegatedPostfix(operand) {
297
+ this.advance();
298
+ if (this.atKeyword("LIKE")) {
299
+ this.advance();
300
+ return this.parseLike(operand, true);
301
+ }
302
+ if (this.atKeyword("IN")) {
303
+ this.advance();
304
+ return this.parseInList(operand, true);
305
+ }
306
+ if (this.atKeyword("BETWEEN")) {
307
+ this.advance();
308
+ return this.parseBetween(operand, true);
309
+ }
310
+ this.fail("keyword LIKE, IN or BETWEEN after NOT");
311
+ }
312
+ parsePostfix(operand) {
313
+ const token = this.peek();
314
+ if (token.kind === "operator") {
315
+ this.advance();
316
+ return {
317
+ kind: "comparison",
318
+ operator: token.operator,
319
+ left: operand,
320
+ right: this.parseOperand()
321
+ };
322
+ }
323
+ if (token.kind === "punctuation" && (token.punctuation === "*" || token.punctuation === "-")) throw new HsqldbSqlUnsupportedError("an arithmetic expression", this.sql);
324
+ if (token.kind === "keyword") {
325
+ if (token.keyword === "IS") {
326
+ this.advance();
327
+ const negated = this.atKeyword("NOT");
328
+ if (negated) this.advance();
329
+ this.takeKeyword("NULL");
330
+ return {
331
+ kind: "isNull",
332
+ operand,
333
+ negated
334
+ };
335
+ }
336
+ if (token.keyword === "LIKE") {
337
+ this.advance();
338
+ return this.parseLike(operand, false);
339
+ }
340
+ if (token.keyword === "IN") {
341
+ this.advance();
342
+ return this.parseInList(operand, false);
343
+ }
344
+ if (token.keyword === "BETWEEN") {
345
+ this.advance();
346
+ return this.parseBetween(operand, false);
347
+ }
348
+ if (token.keyword === "NOT") return this.parseNegatedPostfix(operand);
349
+ }
350
+ this.fail("a comparison operator, or keyword IS, LIKE, IN or BETWEEN");
351
+ }
352
+ parsePrimary() {
353
+ if (this.atPunctuation("(")) {
354
+ this.advance();
355
+ const predicate = this.parsePredicate();
356
+ this.takePunctuation(")");
357
+ return predicate;
358
+ }
359
+ return this.parsePostfix(this.parseOperand());
360
+ }
361
+ parseNot() {
362
+ if (this.atKeyword("NOT")) {
363
+ this.advance();
364
+ return {
365
+ kind: "not",
366
+ predicate: this.parseNot()
367
+ };
368
+ }
369
+ return this.parsePrimary();
370
+ }
371
+ parseAnd() {
372
+ let predicate = this.parseNot();
373
+ while (this.atKeyword("AND")) {
374
+ this.advance();
375
+ predicate = {
376
+ kind: "and",
377
+ left: predicate,
378
+ right: this.parseNot()
379
+ };
380
+ }
381
+ return predicate;
382
+ }
383
+ parsePredicate() {
384
+ let predicate = this.parseAnd();
385
+ while (this.atKeyword("OR")) {
386
+ this.advance();
387
+ predicate = {
388
+ kind: "or",
389
+ left: predicate,
390
+ right: this.parseAnd()
391
+ };
392
+ }
393
+ return predicate;
394
+ }
395
+ parseGroupBy() {
396
+ this.takeKeyword("GROUP");
397
+ this.takeKeyword("BY");
398
+ const columns = [this.parseGroupByColumn()];
399
+ while (this.atPunctuation(",")) {
400
+ this.advance();
401
+ columns.push(this.parseGroupByColumn());
402
+ }
403
+ return columns;
404
+ }
405
+ parseGroupByColumn() {
406
+ const token = this.peek();
407
+ if (token.kind === "keyword" && isAggregateFunction(token.keyword)) this.fail("a column name -- an aggregate function is not valid in GROUP BY");
408
+ return this.parseColumnRef();
409
+ }
410
+ parseOrderBy() {
411
+ this.takeKeyword("ORDER");
412
+ this.takeKeyword("BY");
413
+ const terms = [this.parseOrderByTerm()];
414
+ while (this.atPunctuation(",")) {
415
+ this.advance();
416
+ terms.push(this.parseOrderByTerm());
417
+ }
418
+ return terms;
419
+ }
420
+ parseOrderByTerm() {
421
+ const token = this.peek();
422
+ if (token.kind === "keyword" && isAggregateFunction(token.keyword)) throw new HsqldbSqlUnsupportedError("an aggregate function in ORDER BY", this.sql);
423
+ if (token.kind === "number") throw new HsqldbSqlUnsupportedError("an ordinal column reference in ORDER BY (ORDER BY 1)", this.sql);
424
+ const column = this.parseColumnRef();
425
+ if (this.atKeyword("ASC")) {
426
+ this.advance();
427
+ return {
428
+ column,
429
+ direction: "asc"
430
+ };
431
+ }
432
+ if (this.atKeyword("DESC")) {
433
+ this.advance();
434
+ return {
435
+ column,
436
+ direction: "desc"
437
+ };
438
+ }
439
+ return {
440
+ column,
441
+ direction: "asc"
442
+ };
443
+ }
444
+ parseStatement() {
445
+ const first = this.peek();
446
+ if (!(first.kind === "keyword" && first.keyword === "SELECT")) this.fail("keyword SELECT");
447
+ this.advance();
448
+ const items = this.parseSelectList();
449
+ this.takeKeyword("FROM");
450
+ if (this.atPunctuation("(")) throw new HsqldbSqlUnsupportedError("a derived table in FROM", this.sql);
451
+ const from = this.takeName("a table name");
452
+ if (this.atPunctuation(".")) throw new HsqldbSqlUnsupportedError("a schema-qualified table name", this.sql);
453
+ if (this.atPunctuation(",")) throw new HsqldbSqlUnsupportedError("a JOIN", this.sql);
454
+ if (this.peek().kind === "identifier") throw new HsqldbSqlUnsupportedError("a table alias", this.sql);
455
+ let where;
456
+ if (this.atKeyword("WHERE")) {
457
+ this.advance();
458
+ where = this.parsePredicate();
459
+ }
460
+ const groupBy = this.atKeyword("GROUP") ? this.parseGroupBy() : [];
461
+ const orderBy = this.atKeyword("ORDER") ? this.parseOrderBy() : [];
462
+ if (this.atPunctuation(";")) this.advance();
463
+ if (this.peek().kind !== "end") this.fail("end of statement");
464
+ return {
465
+ sql: this.sql,
466
+ items,
467
+ from,
468
+ where,
469
+ groupBy,
470
+ orderBy
471
+ };
472
+ }
473
+ };
474
+ function parseSelect(sql) {
475
+ return new SqlParser(sql).parseStatement();
476
+ }
477
+ //#endregion
478
+ export { parseSelect };
@@ -0,0 +1,75 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ //#region src/odb/values.ts
3
+ const CELL_NULL = { kind: "empty" };
4
+ function cellComparisonKey(value) {
5
+ switch (value.kind) {
6
+ case "number":
7
+ case "percentage":
8
+ case "currency": return {
9
+ valueClass: "numeric",
10
+ numeric: value.value
11
+ };
12
+ case "boolean": return {
13
+ valueClass: "boolean",
14
+ boolean: value.value
15
+ };
16
+ case "date":
17
+ case "time":
18
+ case "dateTime":
19
+ case "string":
20
+ case "error": return {
21
+ valueClass: "text",
22
+ text: value.value
23
+ };
24
+ case "empty": return;
25
+ }
26
+ }
27
+ function compareCellKeys(left, right, fail) {
28
+ if (left.valueClass === "numeric" && right.valueClass === "numeric") return left.numeric === right.numeric ? 0 : left.numeric < right.numeric ? -1 : 1;
29
+ if (left.valueClass === "boolean" && right.valueClass === "boolean") return left.boolean === right.boolean ? 0 : left.boolean ? 1 : -1;
30
+ if (left.valueClass === "text" && right.valueClass === "text") return left.text === right.text ? 0 : left.text < right.text ? -1 : 1;
31
+ throw fail(`cannot compare a ${left.valueClass} value with a ${right.valueClass} value`);
32
+ }
33
+ function compareCellValues(left, right, fail) {
34
+ const leftKey = cellComparisonKey(left);
35
+ const rightKey = cellComparisonKey(right);
36
+ if (leftKey === void 0 || rightKey === void 0) throw fail("a NULL value reached a comparison that had already ruled NULL out");
37
+ return compareCellKeys(leftKey, rightKey, fail);
38
+ }
39
+ function cellValuesEqual(left, right) {
40
+ const leftKey = cellComparisonKey(left);
41
+ const rightKey = cellComparisonKey(right);
42
+ if (leftKey === void 0 || rightKey === void 0) return leftKey === rightKey;
43
+ if (leftKey.valueClass === "numeric" && rightKey.valueClass === "numeric") return leftKey.numeric === rightKey.numeric;
44
+ if (leftKey.valueClass === "boolean" && rightKey.valueClass === "boolean") return leftKey.boolean === rightKey.boolean;
45
+ return leftKey.valueClass === "text" && rightKey.valueClass === "text" && leftKey.text === rightKey.text;
46
+ }
47
+ function numericOf(value, aggregate, fail) {
48
+ const key = cellComparisonKey(value);
49
+ if (key?.valueClass !== "numeric") throw fail(`${aggregate} requires numeric values, but found a ${value.kind} value`);
50
+ return key.numeric;
51
+ }
52
+ function aggregateCellValues(aggregate, values, fail) {
53
+ const present = values.filter((value) => value.kind !== "empty");
54
+ if (aggregate === "COUNT") return {
55
+ kind: "number",
56
+ value: present.length
57
+ };
58
+ const first = present[0];
59
+ if (first === void 0) return CELL_NULL;
60
+ if (aggregate === "SUM" || aggregate === "AVG") {
61
+ const total = present.reduce((sum, value) => sum + numericOf(value, aggregate, fail), 0);
62
+ return {
63
+ kind: "number",
64
+ value: aggregate === "SUM" ? total : total / present.length
65
+ };
66
+ }
67
+ return present.reduce((best, value) => (aggregate === "MIN" ? compareCellValues(value, best, fail) < 0 : compareCellValues(value, best, fail) > 0) ? value : best, first);
68
+ }
69
+ //#endregion
70
+ exports.CELL_NULL = CELL_NULL;
71
+ exports.aggregateCellValues = aggregateCellValues;
72
+ exports.cellComparisonKey = cellComparisonKey;
73
+ exports.cellValuesEqual = cellValuesEqual;
74
+ exports.compareCellKeys = compareCellKeys;
75
+ exports.compareCellValues = compareCellValues;
@@ -0,0 +1,2 @@
1
+ import { a as CellValueFailure, c as cellValuesEqual, i as CellValueClass, l as compareCellKeys, n as CellAggregateFunction, o as aggregateCellValues, r as CellComparisonKey, s as cellComparisonKey, t as CELL_NULL, u as compareCellValues } from "../values-BetetbaH.cjs";
2
+ export { CELL_NULL, CellAggregateFunction, CellComparisonKey, CellValueClass, CellValueFailure, aggregateCellValues, cellComparisonKey, cellValuesEqual, compareCellKeys, compareCellValues };
@@ -0,0 +1,2 @@
1
+ import { a as CellValueFailure, c as cellValuesEqual, i as CellValueClass, l as compareCellKeys, n as CellAggregateFunction, o as aggregateCellValues, r as CellComparisonKey, s as cellComparisonKey, t as CELL_NULL, u as compareCellValues } from "../values-BetetbaH.js";
2
+ export { CELL_NULL, CellAggregateFunction, CellComparisonKey, CellValueClass, CellValueFailure, aggregateCellValues, cellComparisonKey, cellValuesEqual, compareCellKeys, compareCellValues };
@@ -0,0 +1,69 @@
1
+ //#region src/odb/values.ts
2
+ const CELL_NULL = { kind: "empty" };
3
+ function cellComparisonKey(value) {
4
+ switch (value.kind) {
5
+ case "number":
6
+ case "percentage":
7
+ case "currency": return {
8
+ valueClass: "numeric",
9
+ numeric: value.value
10
+ };
11
+ case "boolean": return {
12
+ valueClass: "boolean",
13
+ boolean: value.value
14
+ };
15
+ case "date":
16
+ case "time":
17
+ case "dateTime":
18
+ case "string":
19
+ case "error": return {
20
+ valueClass: "text",
21
+ text: value.value
22
+ };
23
+ case "empty": return;
24
+ }
25
+ }
26
+ function compareCellKeys(left, right, fail) {
27
+ if (left.valueClass === "numeric" && right.valueClass === "numeric") return left.numeric === right.numeric ? 0 : left.numeric < right.numeric ? -1 : 1;
28
+ if (left.valueClass === "boolean" && right.valueClass === "boolean") return left.boolean === right.boolean ? 0 : left.boolean ? 1 : -1;
29
+ if (left.valueClass === "text" && right.valueClass === "text") return left.text === right.text ? 0 : left.text < right.text ? -1 : 1;
30
+ throw fail(`cannot compare a ${left.valueClass} value with a ${right.valueClass} value`);
31
+ }
32
+ function compareCellValues(left, right, fail) {
33
+ const leftKey = cellComparisonKey(left);
34
+ const rightKey = cellComparisonKey(right);
35
+ if (leftKey === void 0 || rightKey === void 0) throw fail("a NULL value reached a comparison that had already ruled NULL out");
36
+ return compareCellKeys(leftKey, rightKey, fail);
37
+ }
38
+ function cellValuesEqual(left, right) {
39
+ const leftKey = cellComparisonKey(left);
40
+ const rightKey = cellComparisonKey(right);
41
+ if (leftKey === void 0 || rightKey === void 0) return leftKey === rightKey;
42
+ if (leftKey.valueClass === "numeric" && rightKey.valueClass === "numeric") return leftKey.numeric === rightKey.numeric;
43
+ if (leftKey.valueClass === "boolean" && rightKey.valueClass === "boolean") return leftKey.boolean === rightKey.boolean;
44
+ return leftKey.valueClass === "text" && rightKey.valueClass === "text" && leftKey.text === rightKey.text;
45
+ }
46
+ function numericOf(value, aggregate, fail) {
47
+ const key = cellComparisonKey(value);
48
+ if (key?.valueClass !== "numeric") throw fail(`${aggregate} requires numeric values, but found a ${value.kind} value`);
49
+ return key.numeric;
50
+ }
51
+ function aggregateCellValues(aggregate, values, fail) {
52
+ const present = values.filter((value) => value.kind !== "empty");
53
+ if (aggregate === "COUNT") return {
54
+ kind: "number",
55
+ value: present.length
56
+ };
57
+ const first = present[0];
58
+ if (first === void 0) return CELL_NULL;
59
+ if (aggregate === "SUM" || aggregate === "AVG") {
60
+ const total = present.reduce((sum, value) => sum + numericOf(value, aggregate, fail), 0);
61
+ return {
62
+ kind: "number",
63
+ value: aggregate === "SUM" ? total : total / present.length
64
+ };
65
+ }
66
+ return present.reduce((best, value) => (aggregate === "MIN" ? compareCellValues(value, best, fail) < 0 : compareCellValues(value, best, fail) > 0) ? value : best, first);
67
+ }
68
+ //#endregion
69
+ export { CELL_NULL, aggregateCellValues, cellComparisonKey, cellValuesEqual, compareCellKeys, compareCellValues };