js.documents 14.4.56 → 14.4.57
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.
- package/dist/codecs/read.cjs +2 -2
- package/dist/codecs/read.js +1 -1
- package/dist/composition-plan-CfvhXeOC.cjs +627 -0
- package/dist/composition-plan-DU9nPPN7.d.cts +102 -0
- package/dist/composition-plan-f0zaExUW.js +508 -0
- package/dist/composition-plan-l6QPO4FX.d.ts +102 -0
- package/dist/convert/composition-plan.cjs +7 -0
- package/dist/convert/composition-plan.d.cts +2 -0
- package/dist/convert/composition-plan.d.ts +2 -0
- package/dist/convert/composition-plan.js +2 -0
- package/dist/convert/composition-to-pdf.cjs +12 -12
- package/dist/convert/composition-to-pdf.d.cts +1 -1
- package/dist/convert/composition-to-pdf.d.ts +1 -1
- package/dist/convert/composition-to-pdf.js +2 -2
- package/dist/convert/composition.cjs +16 -511
- package/dist/convert/composition.d.cts +2 -85
- package/dist/convert/composition.d.ts +2 -85
- package/dist/convert/composition.js +2 -502
- package/dist/convert/convert.cjs +2 -2
- package/dist/convert/convert.js +1 -1
- package/dist/convert/from-package.cjs +3 -3
- package/dist/convert/from-package.js +2 -2
- package/dist/convert/from-pdf.cjs +18 -18
- package/dist/convert/from-pdf.js +2 -2
- package/dist/convert/local.cjs +3 -3
- package/dist/convert/local.js +1 -1
- package/dist/edit/odp/slide.cjs +4 -4
- package/dist/edit/odp/slide.d.cts +1 -1
- package/dist/edit/odp/slide.d.ts +1 -1
- package/dist/edit/odp/slide.js +1 -1
- package/dist/edit/odt/content.d.cts +1 -1
- package/dist/edit/odt/content.d.ts +1 -1
- package/dist/edit/odt/editor.cjs +4 -4
- package/dist/edit/odt/editor.d.cts +1 -1
- package/dist/edit/odt/editor.d.ts +1 -1
- package/dist/edit/odt/editor.js +1 -1
- package/dist/edit/odt/table-grid.cjs +23 -0
- package/dist/edit/odt/table-grid.d.cts +54 -0
- package/dist/edit/odt/table-grid.d.ts +54 -0
- package/dist/edit/odt/table-grid.js +2 -0
- package/dist/edit/odt/table.cjs +12 -653
- package/dist/edit/odt/table.d.cts +2 -2
- package/dist/edit/odt/table.d.ts +2 -2
- package/dist/edit/odt/table.js +2 -647
- package/dist/{evaluate-BbOsgdmN.d.cts → evaluate-BSEUxiUK.d.cts} +3 -1
- package/dist/evaluate-CEzsBx3w.cjs +564 -0
- package/dist/{evaluate-C7fmk69X.d.ts → evaluate-D8fG2ZeB.d.ts} +3 -1
- package/dist/evaluate-IK-3aMv5.js +445 -0
- package/dist/evaluate-columns-CyqKHkIW.d.cts +41 -0
- package/dist/evaluate-columns-cOo8fOfT.d.ts +41 -0
- package/dist/index.cjs +24 -24
- package/dist/index.d.cts +6 -5
- package/dist/index.d.ts +6 -5
- package/dist/index.js +8 -8
- package/dist/latex/lint.cjs +2 -2
- package/dist/latex/lint.js +1 -1
- package/dist/latex/lower-fold.cjs +6 -0
- package/dist/latex/lower-fold.d.cts +17 -0
- package/dist/latex/lower-fold.d.ts +17 -0
- package/dist/latex/lower-fold.js +2 -0
- package/dist/latex/lower.cjs +11 -617
- package/dist/latex/lower.d.cts +18 -1
- package/dist/latex/lower.d.ts +18 -1
- package/dist/latex/lower.js +2 -616
- package/dist/latex/symbols.d.cts +1 -15
- package/dist/latex/symbols.d.ts +1 -15
- package/dist/latex/temml.d.cts +1 -24
- package/dist/latex/temml.d.ts +1 -24
- package/dist/layout/engine.cjs +2 -2
- package/dist/layout/engine.js +1 -1
- package/dist/layout/reconstruct-lines.cjs +315 -0
- package/dist/layout/reconstruct-lines.d.cts +2 -0
- package/dist/layout/reconstruct-lines.d.ts +2 -0
- package/dist/layout/reconstruct-lines.js +297 -0
- package/dist/layout/reconstruct-presentations-prod.cjs +9 -0
- package/dist/layout/reconstruct-presentations-prod.d.cts +26 -0
- package/dist/layout/reconstruct-presentations-prod.d.ts +26 -0
- package/dist/layout/reconstruct-presentations-prod.js +2 -0
- package/dist/layout/reconstruct-tables.cjs +5 -0
- package/dist/layout/reconstruct-tables.d.cts +22 -0
- package/dist/layout/reconstruct-tables.d.ts +22 -0
- package/dist/layout/reconstruct-tables.js +2 -0
- package/dist/layout/reconstruct.cjs +11 -1545
- package/dist/layout/reconstruct.d.cts +2 -14
- package/dist/layout/reconstruct.d.ts +2 -14
- package/dist/layout/reconstruct.js +2 -1542
- package/dist/layout/shared.cjs +2 -2
- package/dist/layout/shared.js +1 -1
- package/dist/layout/sheets-render.cjs +19 -0
- package/dist/layout/sheets-render.d.cts +41 -0
- package/dist/layout/sheets-render.d.ts +41 -0
- package/dist/layout/sheets-render.js +2 -0
- package/dist/layout/sheets.cjs +10 -544
- package/dist/layout/sheets.d.cts +13 -2
- package/dist/layout/sheets.d.ts +13 -2
- package/dist/layout/sheets.js +2 -543
- package/dist/layout/slides.cjs +2 -2
- package/dist/layout/slides.js +1 -1
- package/dist/layout-DIJzJk4x.js +526 -0
- package/dist/layout-iuiyl_Fk.cjs +621 -0
- package/dist/layout-types-oSbHvZid.d.cts +13 -0
- package/dist/layout-types-oSbHvZid.d.ts +13 -0
- package/dist/lower-DCs3rWI7.js +618 -0
- package/dist/lower-DzOb13w4.cjs +701 -0
- package/dist/markdown/math.cjs +2 -2
- package/dist/markdown/math.js +1 -1
- package/dist/mathml/layout-stretch.cjs +16 -0
- package/dist/mathml/layout-stretch.d.cts +24 -0
- package/dist/mathml/layout-stretch.d.ts +24 -0
- package/dist/mathml/layout-stretch.js +2 -0
- package/dist/mathml/layout-types.d.cts +1 -12
- package/dist/mathml/layout-types.d.ts +1 -12
- package/dist/mathml/layout.cjs +3 -525
- package/dist/mathml/layout.d.cts +2 -2
- package/dist/mathml/layout.d.ts +2 -2
- package/dist/mathml/layout.js +1 -523
- package/dist/odb/formula/evaluate.d.cts +1 -1
- package/dist/odb/formula/evaluate.d.ts +1 -1
- package/dist/odb/report/render.d.cts +1 -1
- package/dist/odb/report/render.d.ts +1 -1
- package/dist/odb/report/source.cjs +2 -2
- package/dist/odb/report/source.d.cts +1 -1
- package/dist/odb/report/source.d.ts +1 -1
- package/dist/odb/report/source.js +1 -1
- package/dist/odb/sql/evaluate-columns.cjs +122 -0
- package/dist/odb/sql/evaluate-columns.d.cts +2 -0
- package/dist/odb/sql/evaluate-columns.d.ts +2 -0
- package/dist/odb/sql/evaluate-columns.js +114 -0
- package/dist/odb/sql/evaluate-predicates.cjs +16 -0
- package/dist/odb/sql/evaluate-predicates.d.cts +23 -0
- package/dist/odb/sql/evaluate-predicates.d.ts +23 -0
- package/dist/odb/sql/evaluate-predicates.js +2 -0
- package/dist/odb/sql/evaluate.cjs +7 -556
- package/dist/odb/sql/evaluate.d.cts +2 -2
- package/dist/odb/sql/evaluate.d.ts +2 -2
- package/dist/odb/sql/evaluate.js +2 -552
- package/dist/read-BSH--XB4.js +682 -0
- package/dist/read-CahCZMwG.cjs +759 -0
- package/dist/reconstruct-BKOCAedo.d.ts +29 -0
- package/dist/reconstruct-D4TEteZ6.d.cts +29 -0
- package/dist/reconstruct-lines-B7t66ICm.d.cts +33 -0
- package/dist/reconstruct-lines-B7t66ICm.d.ts +33 -0
- package/dist/reconstruct-presentations-prod-B5fkPiRZ.js +1256 -0
- package/dist/reconstruct-presentations-prod-X315aBmI.cjs +1375 -0
- package/dist/sheets-BQCpNXsE.cjs +700 -0
- package/dist/sheets-DWDvGN-g.js +545 -0
- package/dist/svg/read-geometry.cjs +10 -0
- package/dist/svg/read-geometry.d.cts +24 -0
- package/dist/svg/read-geometry.d.ts +24 -0
- package/dist/svg/read-geometry.js +2 -0
- package/dist/svg/read.cjs +6 -680
- package/dist/svg/read.d.cts +17 -2
- package/dist/svg/read.d.ts +17 -2
- package/dist/svg/read.js +2 -679
- package/dist/symbols-BlzXfLEe.d.cts +16 -0
- package/dist/symbols-CKm2r4D0.d.ts +16 -0
- package/dist/table-B5gSMY7w.js +649 -0
- package/dist/{table-DrE6jEWv.d.cts → table-BK_Ao-Y6.d.cts} +9 -1
- package/dist/{table-B5htMG3g.d.ts → table-CxY85YUj.d.ts} +9 -1
- package/dist/table-DqUIOSPV.cjs +840 -0
- package/dist/temml-1-I9N9DD.d.cts +25 -0
- package/dist/temml-1-I9N9DD.d.ts +25 -0
- package/package.json +1 -1
|
@@ -0,0 +1,445 @@
|
|
|
1
|
+
import { CELL_NULL, aggregateCellValues, cellComparisonKey, compareCellValues } from "./odb/values.js";
|
|
2
|
+
import { HsqldbSqlEvaluationError } from "./odb/sql/errors.js";
|
|
3
|
+
import { ColumnResolver, columnAt, resolveColumnIndex, resolveTable, valueAtIndex } from "./odb/sql/evaluate-columns.js";
|
|
4
|
+
//#region src/odb/sql/evaluate-predicates.ts
|
|
5
|
+
function sqlFailure(sql) {
|
|
6
|
+
return (message) => new HsqldbSqlEvaluationError(message, sql);
|
|
7
|
+
}
|
|
8
|
+
function compareValues(left, right, sql) {
|
|
9
|
+
return compareCellValues(left, right, sqlFailure(sql));
|
|
10
|
+
}
|
|
11
|
+
function truthOfComparison(ordering, operator) {
|
|
12
|
+
switch (operator) {
|
|
13
|
+
case "=": return ordering === 0 ? "true" : "false";
|
|
14
|
+
case "<>": return ordering === 0 ? "false" : "true";
|
|
15
|
+
case "<": return ordering < 0 ? "true" : "false";
|
|
16
|
+
case ">": return ordering > 0 ? "true" : "false";
|
|
17
|
+
case "<=": return ordering <= 0 ? "true" : "false";
|
|
18
|
+
case ">=": return ordering >= 0 ? "true" : "false";
|
|
19
|
+
}
|
|
20
|
+
return assertNeverOperator(operator);
|
|
21
|
+
}
|
|
22
|
+
function notTruth(truth) {
|
|
23
|
+
if (truth === "true") return "false";
|
|
24
|
+
return truth === "false" ? "true" : "unknown";
|
|
25
|
+
}
|
|
26
|
+
function andTruth(left, right) {
|
|
27
|
+
if (left === "false" || right === "false") return "false";
|
|
28
|
+
return left === "true" && right === "true" ? "true" : "unknown";
|
|
29
|
+
}
|
|
30
|
+
function orTruth(left, right) {
|
|
31
|
+
if (left === "true" || right === "true") return "true";
|
|
32
|
+
return left === "false" && right === "false" ? "false" : "unknown";
|
|
33
|
+
}
|
|
34
|
+
function literalToValue(literal) {
|
|
35
|
+
switch (literal.kind) {
|
|
36
|
+
case "number": return {
|
|
37
|
+
kind: "number",
|
|
38
|
+
value: literal.value
|
|
39
|
+
};
|
|
40
|
+
case "string": return {
|
|
41
|
+
kind: "string",
|
|
42
|
+
value: literal.value
|
|
43
|
+
};
|
|
44
|
+
case "boolean": return {
|
|
45
|
+
kind: "boolean",
|
|
46
|
+
value: literal.value
|
|
47
|
+
};
|
|
48
|
+
case "null": return CELL_NULL;
|
|
49
|
+
}
|
|
50
|
+
return assertNeverLiteralKind(literal);
|
|
51
|
+
}
|
|
52
|
+
function likePatternToRegExp(pattern) {
|
|
53
|
+
let source = "^";
|
|
54
|
+
for (const character of pattern) if (character === "%") source += "[\\s\\S]*";
|
|
55
|
+
else if (character === "_") source += "[\\s\\S]";
|
|
56
|
+
else source += character.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
57
|
+
return new RegExp(`${source}$`);
|
|
58
|
+
}
|
|
59
|
+
function operandValue(operand, row, resolver) {
|
|
60
|
+
return operand.kind === "literal" ? literalToValue(operand.literal) : resolver.valueOf(operand.column, row);
|
|
61
|
+
}
|
|
62
|
+
function evaluateLike(value, pattern, sql) {
|
|
63
|
+
const key = cellComparisonKey(value);
|
|
64
|
+
if (key === void 0) return "unknown";
|
|
65
|
+
if (key.valueClass !== "text") throw new HsqldbSqlEvaluationError(`LIKE requires a text value, but its left operand is a ${key.valueClass} value`, sql);
|
|
66
|
+
return likePatternToRegExp(pattern).test(key.text) ? "true" : "false";
|
|
67
|
+
}
|
|
68
|
+
function evaluateIn(value, values, sql) {
|
|
69
|
+
if (value.kind === "empty") return "unknown";
|
|
70
|
+
let sawNull = false;
|
|
71
|
+
for (const literal of values) {
|
|
72
|
+
const candidate = literalToValue(literal);
|
|
73
|
+
if (candidate.kind === "empty") {
|
|
74
|
+
sawNull = true;
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
if (compareValues(value, candidate, sql) === 0) return "true";
|
|
78
|
+
}
|
|
79
|
+
return sawNull ? "unknown" : "false";
|
|
80
|
+
}
|
|
81
|
+
function evaluatePredicate(predicate, row, resolver, tables, sql) {
|
|
82
|
+
switch (predicate.kind) {
|
|
83
|
+
case "comparison": {
|
|
84
|
+
const left = operandValue(predicate.left, row, resolver);
|
|
85
|
+
const right = operandValue(predicate.right, row, resolver);
|
|
86
|
+
if (left.kind === "empty" || right.kind === "empty") return "unknown";
|
|
87
|
+
return truthOfComparison(compareValues(left, right, sql), predicate.operator);
|
|
88
|
+
}
|
|
89
|
+
case "isNull": {
|
|
90
|
+
const isNull = operandValue(predicate.operand, row, resolver).kind === "empty";
|
|
91
|
+
return (predicate.negated ? !isNull : isNull) ? "true" : "false";
|
|
92
|
+
}
|
|
93
|
+
case "like": {
|
|
94
|
+
const truth = evaluateLike(operandValue(predicate.operand, row, resolver), predicate.pattern, sql);
|
|
95
|
+
return predicate.negated ? notTruth(truth) : truth;
|
|
96
|
+
}
|
|
97
|
+
case "in": {
|
|
98
|
+
const truth = evaluateIn(operandValue(predicate.operand, row, resolver), predicate.values, sql);
|
|
99
|
+
return predicate.negated ? notTruth(truth) : truth;
|
|
100
|
+
}
|
|
101
|
+
case "inSubquery": {
|
|
102
|
+
const truth = evaluateInSubquery(operandValue(predicate.operand, row, resolver), predicate.query, tables, resolver, row, sql);
|
|
103
|
+
return predicate.negated ? notTruth(truth) : truth;
|
|
104
|
+
}
|
|
105
|
+
case "between": {
|
|
106
|
+
const value = operandValue(predicate.operand, row, resolver);
|
|
107
|
+
const lower = operandValue(predicate.lower, row, resolver);
|
|
108
|
+
const upper = operandValue(predicate.upper, row, resolver);
|
|
109
|
+
if (value.kind === "empty" || lower.kind === "empty" || upper.kind === "empty") return "unknown";
|
|
110
|
+
const truth = andTruth(truthOfComparison(compareValues(value, lower, sql), ">="), truthOfComparison(compareValues(value, upper, sql), "<="));
|
|
111
|
+
return predicate.negated ? notTruth(truth) : truth;
|
|
112
|
+
}
|
|
113
|
+
case "exists": return evaluateExists(predicate.query, tables, resolver, row);
|
|
114
|
+
case "not": return notTruth(evaluatePredicate(predicate.predicate, row, resolver, tables, sql));
|
|
115
|
+
case "and": return andTruth(evaluatePredicate(predicate.left, row, resolver, tables, sql), evaluatePredicate(predicate.right, row, resolver, tables, sql));
|
|
116
|
+
case "or": return orTruth(evaluatePredicate(predicate.left, row, resolver, tables, sql), evaluatePredicate(predicate.right, row, resolver, tables, sql));
|
|
117
|
+
}
|
|
118
|
+
return assertNeverPredicateKind(predicate);
|
|
119
|
+
}
|
|
120
|
+
function evaluateInSubquery(value, query, tables, outerResolver, outerRow, sql) {
|
|
121
|
+
if (value.kind === "empty") return "unknown";
|
|
122
|
+
const result = evaluateSelectInScope(query, tables, {
|
|
123
|
+
resolver: outerResolver,
|
|
124
|
+
row: outerRow
|
|
125
|
+
});
|
|
126
|
+
if (result.columns.length !== 1) throw new HsqldbSqlEvaluationError(`IN (SELECT ...) requires the subquery to produce exactly one column, but it produced ${String(result.columns.length)} (${result.columns.length === 0 ? "none" : result.columns.join(", ")})`, sql);
|
|
127
|
+
let sawNull = false;
|
|
128
|
+
for (const candidateRow of result.rows) {
|
|
129
|
+
const candidate = candidateRow[0];
|
|
130
|
+
if (candidate === void 0) throw new HsqldbSqlEvaluationError("malformed subquery row: it declares one column but carries none", sql);
|
|
131
|
+
if (candidate.kind === "empty") {
|
|
132
|
+
sawNull = true;
|
|
133
|
+
continue;
|
|
134
|
+
}
|
|
135
|
+
if (compareValues(value, candidate, sql) === 0) return "true";
|
|
136
|
+
}
|
|
137
|
+
return sawNull ? "unknown" : "false";
|
|
138
|
+
}
|
|
139
|
+
function evaluateExists(query, tables, outerResolver, outerRow) {
|
|
140
|
+
return evaluateSelectInScope(query, tables, {
|
|
141
|
+
resolver: outerResolver,
|
|
142
|
+
row: outerRow
|
|
143
|
+
}).rows.length > 0 ? "true" : "false";
|
|
144
|
+
}
|
|
145
|
+
//#endregion
|
|
146
|
+
//#region src/odb/sql/evaluate.ts
|
|
147
|
+
function aggregateOverValues(aggregate, values, sql) {
|
|
148
|
+
return aggregateCellValues(aggregate, values, sqlFailure(sql));
|
|
149
|
+
}
|
|
150
|
+
function compareForSort(left, right, sql) {
|
|
151
|
+
const leftNull = left.kind === "empty";
|
|
152
|
+
const rightNull = right.kind === "empty";
|
|
153
|
+
if (leftNull || rightNull) {
|
|
154
|
+
if (leftNull && rightNull) return 0;
|
|
155
|
+
return leftNull ? 1 : -1;
|
|
156
|
+
}
|
|
157
|
+
return compareValues(left, right, sql);
|
|
158
|
+
}
|
|
159
|
+
function sortRows(rows, directions, sql) {
|
|
160
|
+
return [...rows].sort((left, right) => {
|
|
161
|
+
for (const [index, direction] of directions.entries()) {
|
|
162
|
+
const leftKey = left.sortKeys[index];
|
|
163
|
+
const rightKey = right.sortKeys[index];
|
|
164
|
+
if (leftKey === void 0 || rightKey === void 0) throw new HsqldbSqlEvaluationError("an ORDER BY term has no sort key on this row", sql);
|
|
165
|
+
const ordering = compareForSort(leftKey, rightKey, sql);
|
|
166
|
+
if (ordering !== 0) return direction === "asc" ? ordering : -ordering;
|
|
167
|
+
}
|
|
168
|
+
return 0;
|
|
169
|
+
}).map((row) => row.output);
|
|
170
|
+
}
|
|
171
|
+
function groupKeyOf(values) {
|
|
172
|
+
return values.map((value) => {
|
|
173
|
+
switch (value.kind) {
|
|
174
|
+
case "empty": return "null";
|
|
175
|
+
case "boolean": return `boolean:${String(value.value)}`;
|
|
176
|
+
case "number":
|
|
177
|
+
case "percentage":
|
|
178
|
+
case "currency": return `numeric:${String(value.value)}`;
|
|
179
|
+
case "date":
|
|
180
|
+
case "time":
|
|
181
|
+
case "dateTime":
|
|
182
|
+
case "string":
|
|
183
|
+
case "error": return `text:${value.value}`;
|
|
184
|
+
}
|
|
185
|
+
return assertNeverValueKind(value);
|
|
186
|
+
}).join("\0");
|
|
187
|
+
}
|
|
188
|
+
function planSelectList(statement, resolver) {
|
|
189
|
+
const plan = [];
|
|
190
|
+
for (const item of statement.items) switch (item.kind) {
|
|
191
|
+
case "star":
|
|
192
|
+
for (let index = 0; index < resolver.columnCount; index += 1) plan.push({
|
|
193
|
+
kind: "column",
|
|
194
|
+
index,
|
|
195
|
+
text: resolver.nameAt(index)
|
|
196
|
+
});
|
|
197
|
+
break;
|
|
198
|
+
case "column":
|
|
199
|
+
plan.push({
|
|
200
|
+
kind: "column",
|
|
201
|
+
index: resolver.indexOf(item.column),
|
|
202
|
+
text: item.column.text
|
|
203
|
+
});
|
|
204
|
+
break;
|
|
205
|
+
case "aggregate": plan.push({
|
|
206
|
+
kind: "aggregate",
|
|
207
|
+
aggregate: item.aggregate,
|
|
208
|
+
argumentIndex: item.argument.kind === "star" ? void 0 : resolver.indexOf(item.argument.column),
|
|
209
|
+
outputName: item.outputName
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
return plan;
|
|
213
|
+
}
|
|
214
|
+
function planColumnNames(plan, resolver) {
|
|
215
|
+
return plan.map((item) => item.kind === "column" ? resolver.nameAt(item.index) : item.outputName);
|
|
216
|
+
}
|
|
217
|
+
function evaluateUngrouped(statement, plan, matching, resolver) {
|
|
218
|
+
const projection = plan.map((item) => {
|
|
219
|
+
if (item.kind !== "column") throw new HsqldbSqlEvaluationError(`${item.outputName} is an aggregate, so every other select-list item must be grouped`, statement.sql);
|
|
220
|
+
return item.index;
|
|
221
|
+
});
|
|
222
|
+
const orderIndices = statement.orderBy.map((term) => resolver.indexOf(term.column));
|
|
223
|
+
const sortable = matching.map((row) => ({
|
|
224
|
+
output: projection.map((index) => resolver.valueAt(index, row)),
|
|
225
|
+
sortKeys: orderIndices.map((index) => resolver.valueAt(index, row))
|
|
226
|
+
}));
|
|
227
|
+
return {
|
|
228
|
+
columns: planColumnNames(plan, resolver),
|
|
229
|
+
rows: sortRows(sortable, statement.orderBy.map((term) => term.direction), statement.sql)
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
function partitionIntoGroups(rows, groupIndices, resolver) {
|
|
233
|
+
const groups = /* @__PURE__ */ new Map();
|
|
234
|
+
for (const row of rows) {
|
|
235
|
+
const keyValues = groupIndices.map((index) => resolver.valueAt(index, row));
|
|
236
|
+
const key = groupKeyOf(keyValues);
|
|
237
|
+
const existing = groups.get(key);
|
|
238
|
+
if (existing === void 0) groups.set(key, {
|
|
239
|
+
keyValues,
|
|
240
|
+
rows: [row]
|
|
241
|
+
});
|
|
242
|
+
else existing.rows.push(row);
|
|
243
|
+
}
|
|
244
|
+
return [...groups.values()];
|
|
245
|
+
}
|
|
246
|
+
function evaluateGrouped(statement, plan, matching, resolver) {
|
|
247
|
+
const groupIndices = statement.groupBy.map((ref) => resolver.indexOf(ref));
|
|
248
|
+
for (const item of plan) if (item.kind === "column" && !groupIndices.includes(item.index)) throw new HsqldbSqlEvaluationError(`column "${item.text}" is neither grouped nor aggregated—add it to GROUP BY or wrap it in an aggregate`, statement.sql);
|
|
249
|
+
const groups = groupIndices.length === 0 ? [{
|
|
250
|
+
keyValues: [],
|
|
251
|
+
rows: [...matching]
|
|
252
|
+
}] : partitionIntoGroups(matching, groupIndices, resolver);
|
|
253
|
+
const orderPositions = statement.orderBy.map((term) => {
|
|
254
|
+
const position = groupIndices.indexOf(resolver.indexOf(term.column));
|
|
255
|
+
if (position < 0) throw new HsqldbSqlEvaluationError(`ORDER BY column "${term.column.text}" is not a GROUP BY column—a grouped result has no single value for it`, statement.sql);
|
|
256
|
+
return position;
|
|
257
|
+
});
|
|
258
|
+
const sortable = groups.map((group) => ({
|
|
259
|
+
output: plan.map((item) => {
|
|
260
|
+
if (item.kind === "aggregate") {
|
|
261
|
+
const argumentIndex = item.argumentIndex;
|
|
262
|
+
if (argumentIndex === void 0) return {
|
|
263
|
+
kind: "number",
|
|
264
|
+
value: group.rows.length
|
|
265
|
+
};
|
|
266
|
+
return aggregateOverValues(item.aggregate, group.rows.map((row) => resolver.valueAt(argumentIndex, row)), statement.sql);
|
|
267
|
+
}
|
|
268
|
+
const keyValue = group.keyValues[groupIndices.indexOf(item.index)];
|
|
269
|
+
if (keyValue === void 0) throw new HsqldbSqlEvaluationError(`grouped column "${item.text}" has no value on this group`, statement.sql);
|
|
270
|
+
return keyValue;
|
|
271
|
+
}),
|
|
272
|
+
sortKeys: orderPositions.map((position) => {
|
|
273
|
+
const keyValue = group.keyValues[position];
|
|
274
|
+
if (keyValue === void 0) throw new HsqldbSqlEvaluationError("an ORDER BY term resolved to a GROUP BY column with no value on this group", statement.sql);
|
|
275
|
+
return keyValue;
|
|
276
|
+
})
|
|
277
|
+
}));
|
|
278
|
+
return {
|
|
279
|
+
columns: planColumnNames(plan, resolver),
|
|
280
|
+
rows: sortRows(sortable, statement.orderBy.map((term) => term.direction), statement.sql)
|
|
281
|
+
};
|
|
282
|
+
}
|
|
283
|
+
function tableColumns(qualifier, table) {
|
|
284
|
+
return table.columns.map((column) => ({
|
|
285
|
+
qualifiers: [qualifier],
|
|
286
|
+
columnName: column.name
|
|
287
|
+
}));
|
|
288
|
+
}
|
|
289
|
+
function nullRow(count) {
|
|
290
|
+
return new Array(count).fill(CELL_NULL);
|
|
291
|
+
}
|
|
292
|
+
function computeNaturalSharedPairs(leftColumns, rightColumns, sql) {
|
|
293
|
+
const rightIndexByName = /* @__PURE__ */ new Map();
|
|
294
|
+
const ambiguousRightNames = /* @__PURE__ */ new Set();
|
|
295
|
+
rightColumns.forEach((column, index) => {
|
|
296
|
+
if (rightIndexByName.has(column.columnName)) ambiguousRightNames.add(column.columnName);
|
|
297
|
+
else rightIndexByName.set(column.columnName, index);
|
|
298
|
+
});
|
|
299
|
+
const pairs = [];
|
|
300
|
+
const seenNames = /* @__PURE__ */ new Set();
|
|
301
|
+
leftColumns.forEach((leftColumn, leftIndex) => {
|
|
302
|
+
const rightIndex = rightIndexByName.get(leftColumn.columnName);
|
|
303
|
+
if (rightIndex === void 0) return;
|
|
304
|
+
if (ambiguousRightNames.has(leftColumn.columnName) || seenNames.has(leftColumn.columnName)) throw new HsqldbSqlEvaluationError(`NATURAL JOIN cannot determine a unique match for column "${leftColumn.columnName}"—more than one column shares that name on one side of the join`, sql);
|
|
305
|
+
seenNames.add(leftColumn.columnName);
|
|
306
|
+
pairs.push({
|
|
307
|
+
leftIndex,
|
|
308
|
+
rightIndex,
|
|
309
|
+
columnName: leftColumn.columnName
|
|
310
|
+
});
|
|
311
|
+
});
|
|
312
|
+
return pairs;
|
|
313
|
+
}
|
|
314
|
+
function evaluateSharedColumnMatch(combined, pairs, leftColumnCount, sql) {
|
|
315
|
+
return pairs.every((pair) => {
|
|
316
|
+
const left = valueAtIndex(combined, pair.leftIndex, sql);
|
|
317
|
+
const right = valueAtIndex(combined, leftColumnCount + pair.rightIndex, sql);
|
|
318
|
+
return left.kind !== "empty" && right.kind !== "empty" && compareValues(left, right, sql) === 0;
|
|
319
|
+
});
|
|
320
|
+
}
|
|
321
|
+
function mergeSharedColumns(rawColumns, rows, sharedPairs, leftColumnCount, sql) {
|
|
322
|
+
const sharedLeftIndices = new Set(sharedPairs.map((pair) => pair.leftIndex));
|
|
323
|
+
const sharedRightIndices = new Set(sharedPairs.map((pair) => leftColumnCount + pair.rightIndex));
|
|
324
|
+
const remainingIndices = rawColumns.map((_column, index) => index).filter((index) => !sharedLeftIndices.has(index) && !sharedRightIndices.has(index));
|
|
325
|
+
return {
|
|
326
|
+
columns: [...sharedPairs.map((pair) => {
|
|
327
|
+
const leftColumn = columnAt(rawColumns, pair.leftIndex, sql);
|
|
328
|
+
const rightColumn = columnAt(rawColumns, leftColumnCount + pair.rightIndex, sql);
|
|
329
|
+
return {
|
|
330
|
+
qualifiers: [.../* @__PURE__ */ new Set([...leftColumn.qualifiers, ...rightColumn.qualifiers])],
|
|
331
|
+
columnName: leftColumn.columnName
|
|
332
|
+
};
|
|
333
|
+
}), ...remainingIndices.map((index) => columnAt(rawColumns, index, sql))],
|
|
334
|
+
rows: rows.map((row) => {
|
|
335
|
+
const mergedValues = sharedPairs.map((pair) => {
|
|
336
|
+
const leftValue = valueAtIndex(row, pair.leftIndex, sql);
|
|
337
|
+
const rightValue = valueAtIndex(row, leftColumnCount + pair.rightIndex, sql);
|
|
338
|
+
return leftValue.kind !== "empty" ? leftValue : rightValue;
|
|
339
|
+
});
|
|
340
|
+
const remainingValues = remainingIndices.map((index) => valueAtIndex(row, index, sql));
|
|
341
|
+
return [...mergedValues, ...remainingValues];
|
|
342
|
+
})
|
|
343
|
+
};
|
|
344
|
+
}
|
|
345
|
+
function applyJoinClause(left, join, tables, sql, outer) {
|
|
346
|
+
const rightTable = resolveTable(tables, join.table, sql);
|
|
347
|
+
const rightColumns = tableColumns(join.alias !== void 0 ? join.alias.name : rightTable.tableName, rightTable);
|
|
348
|
+
const leftColumnCount = left.columns.length;
|
|
349
|
+
const rawColumns = [...left.columns, ...rightColumns];
|
|
350
|
+
let onPredicate;
|
|
351
|
+
let sharedPairs = [];
|
|
352
|
+
if (join.condition.kind === "on") onPredicate = join.condition.predicate;
|
|
353
|
+
else if (join.condition.kind === "using") {
|
|
354
|
+
const allLeftIndices = left.columns.map((_column, index) => index);
|
|
355
|
+
const allRightIndices = rightColumns.map((_column, index) => index);
|
|
356
|
+
sharedPairs = join.condition.columns.map((ref) => {
|
|
357
|
+
const leftIndex = resolveColumnIndex(left.columns, allLeftIndices, ref, sql);
|
|
358
|
+
return {
|
|
359
|
+
leftIndex,
|
|
360
|
+
rightIndex: resolveColumnIndex(rightColumns, allRightIndices, ref, sql),
|
|
361
|
+
columnName: columnAt(left.columns, leftIndex, sql).columnName
|
|
362
|
+
};
|
|
363
|
+
});
|
|
364
|
+
} else if (join.condition.kind === "natural") {
|
|
365
|
+
sharedPairs = computeNaturalSharedPairs(left.columns, rightColumns, sql);
|
|
366
|
+
if (sharedPairs.length === 0) throw new HsqldbSqlEvaluationError("NATURAL JOIN found no columns shared between the joined tables", sql);
|
|
367
|
+
}
|
|
368
|
+
const rawResolver = new ColumnResolver(rawColumns, sql, outer);
|
|
369
|
+
const matchedLeft = /* @__PURE__ */ new Set();
|
|
370
|
+
const matchedRight = /* @__PURE__ */ new Set();
|
|
371
|
+
const paired = [];
|
|
372
|
+
left.rows.forEach((leftRow, leftIndex) => {
|
|
373
|
+
rightTable.rows.forEach((rightRow, rightIndex) => {
|
|
374
|
+
const combined = [...leftRow, ...rightRow];
|
|
375
|
+
if (onPredicate !== void 0 ? evaluatePredicate(onPredicate, combined, rawResolver, tables, sql) === "true" : sharedPairs.length > 0 ? evaluateSharedColumnMatch(combined, sharedPairs, leftColumnCount, sql) : true) {
|
|
376
|
+
paired.push(combined);
|
|
377
|
+
matchedLeft.add(leftIndex);
|
|
378
|
+
matchedRight.add(rightIndex);
|
|
379
|
+
}
|
|
380
|
+
});
|
|
381
|
+
});
|
|
382
|
+
if (join.joinKind === "left" || join.joinKind === "full") left.rows.forEach((leftRow, leftIndex) => {
|
|
383
|
+
if (!matchedLeft.has(leftIndex)) paired.push([...leftRow, ...nullRow(rightColumns.length)]);
|
|
384
|
+
});
|
|
385
|
+
if (join.joinKind === "right" || join.joinKind === "full") rightTable.rows.forEach((rightRow, rightIndex) => {
|
|
386
|
+
if (!matchedRight.has(rightIndex)) paired.push([...nullRow(leftColumnCount), ...rightRow]);
|
|
387
|
+
});
|
|
388
|
+
if (join.condition.kind === "using" || join.condition.kind === "natural") return mergeSharedColumns(rawColumns, paired, sharedPairs, leftColumnCount, sql);
|
|
389
|
+
return {
|
|
390
|
+
columns: rawColumns,
|
|
391
|
+
rows: paired
|
|
392
|
+
};
|
|
393
|
+
}
|
|
394
|
+
function resolveFromSource(source, tables, sql) {
|
|
395
|
+
if (source.kind === "table") {
|
|
396
|
+
const table = resolveTable(tables, source.table, sql);
|
|
397
|
+
return {
|
|
398
|
+
columns: tableColumns(source.alias !== void 0 ? source.alias.name : table.tableName, table),
|
|
399
|
+
rows: table.rows
|
|
400
|
+
};
|
|
401
|
+
}
|
|
402
|
+
const result = evaluateSelectInScope(source.query, tables, void 0);
|
|
403
|
+
return {
|
|
404
|
+
columns: result.columns.map((name) => ({
|
|
405
|
+
qualifiers: [source.alias.name],
|
|
406
|
+
columnName: name
|
|
407
|
+
})),
|
|
408
|
+
rows: result.rows
|
|
409
|
+
};
|
|
410
|
+
}
|
|
411
|
+
function joinTables(from, tables, sql, outer) {
|
|
412
|
+
let result = resolveFromSource(from.source, tables, sql);
|
|
413
|
+
for (const join of from.joins) result = applyJoinClause(result, join, tables, sql, outer);
|
|
414
|
+
return result;
|
|
415
|
+
}
|
|
416
|
+
function evaluateSelect(statement, tables) {
|
|
417
|
+
return evaluateSelectInScope(statement, tables, void 0);
|
|
418
|
+
}
|
|
419
|
+
function evaluateSelectInScope(statement, tables, outer) {
|
|
420
|
+
const { columns, rows } = joinTables(statement.from, tables, statement.sql, outer);
|
|
421
|
+
const resolver = new ColumnResolver(columns, statement.sql, outer);
|
|
422
|
+
const plan = planSelectList(statement, resolver);
|
|
423
|
+
const where = statement.where;
|
|
424
|
+
const matching = where === void 0 ? rows : rows.filter((row) => evaluatePredicate(where, row, resolver, tables, statement.sql) === "true");
|
|
425
|
+
const hasAggregate = plan.some((item) => item.kind === "aggregate");
|
|
426
|
+
if (statement.groupBy.length > 0 || hasAggregate) {
|
|
427
|
+
if (statement.groupBy.length > 0 && statement.items.some((item) => item.kind === "star")) throw new HsqldbSqlEvaluationError("SELECT * is not valid with GROUP BY—name the grouped columns and the aggregates explicitly", statement.sql);
|
|
428
|
+
return evaluateGrouped(statement, plan, matching, resolver);
|
|
429
|
+
}
|
|
430
|
+
return evaluateUngrouped(statement, plan, matching, resolver);
|
|
431
|
+
}
|
|
432
|
+
function assertNeverOperator(value) {
|
|
433
|
+
throw new Error(`documents.js: unhandled operator ${JSON.stringify(value)}`);
|
|
434
|
+
}
|
|
435
|
+
function assertNeverLiteralKind(value) {
|
|
436
|
+
throw new Error(`documents.js: unhandled literal ${JSON.stringify(value)}`);
|
|
437
|
+
}
|
|
438
|
+
function assertNeverPredicateKind(value) {
|
|
439
|
+
throw new Error(`documents.js: unhandled predicate ${JSON.stringify(value)}`);
|
|
440
|
+
}
|
|
441
|
+
function assertNeverValueKind(value) {
|
|
442
|
+
throw new Error(`documents.js: unhandled value ${JSON.stringify(value)}`);
|
|
443
|
+
}
|
|
444
|
+
//#endregion
|
|
445
|
+
export { operandValue as _, evaluateSelect as a, truthOfComparison as b, compareValues as c, evaluateInSubquery as d, evaluateLike as f, notTruth as g, literalToValue as h, assertNeverValueKind as i, evaluateExists as l, likePatternToRegExp as m, assertNeverOperator as n, evaluateSelectInScope as o, evaluatePredicate as p, assertNeverPredicateKind as r, andTruth as s, assertNeverLiteralKind as t, evaluateIn as u, orTruth as v, sqlFailure as y };
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { r as HsqldbTable } from "./script-pkZ2Kor4.cjs";
|
|
2
|
+
import { r as SqlColumnRef, u as SqlNameRef } from "./parser-BTA1wXPd.cjs";
|
|
3
|
+
import { ContentCellValue } from "document-schema.js";
|
|
4
|
+
//#region src/odb/sql/evaluate-columns.d.ts
|
|
5
|
+
declare function tryResolveName(candidates: readonly string[], ref: SqlNameRef, what: string, sql: string): string | undefined;
|
|
6
|
+
declare function resolveName(candidates: readonly string[], ref: SqlNameRef, what: string, sql: string): string;
|
|
7
|
+
declare function resolveTable(tables: readonly HsqldbTable[], ref: SqlNameRef, sql: string): HsqldbTable;
|
|
8
|
+
interface ResolvedColumn {
|
|
9
|
+
readonly qualifiers: readonly string[];
|
|
10
|
+
readonly columnName: string;
|
|
11
|
+
}
|
|
12
|
+
interface SharedColumnPair {
|
|
13
|
+
readonly leftIndex: number;
|
|
14
|
+
readonly rightIndex: number;
|
|
15
|
+
readonly columnName: string;
|
|
16
|
+
}
|
|
17
|
+
declare function columnAt(columns: readonly ResolvedColumn[], index: number, sql: string): ResolvedColumn;
|
|
18
|
+
declare function valueAtIndex(row: readonly ContentCellValue[], index: number, sql: string): ContentCellValue;
|
|
19
|
+
declare function tryResolveColumnIndex(columns: readonly ResolvedColumn[], candidateIndices: readonly number[], ref: SqlNameRef, sql: string): number | undefined;
|
|
20
|
+
declare function resolveColumnIndex(columns: readonly ResolvedColumn[], candidateIndices: readonly number[], ref: SqlNameRef, sql: string): number;
|
|
21
|
+
interface OuterScope {
|
|
22
|
+
readonly resolver: ColumnResolver;
|
|
23
|
+
readonly row: readonly ContentCellValue[];
|
|
24
|
+
}
|
|
25
|
+
declare class ColumnResolver {
|
|
26
|
+
private readonly sql;
|
|
27
|
+
private readonly outer?;
|
|
28
|
+
private readonly cache;
|
|
29
|
+
private readonly columns;
|
|
30
|
+
private readonly qualifierNames;
|
|
31
|
+
constructor(columns: readonly ResolvedColumn[], sql: string, outer?: OuterScope | undefined);
|
|
32
|
+
get columnCount(): number;
|
|
33
|
+
nameAt(index: number): string;
|
|
34
|
+
indexOf(ref: SqlColumnRef): number;
|
|
35
|
+
private tryLocalIndexOf;
|
|
36
|
+
private candidateIndicesFor;
|
|
37
|
+
valueAt(index: number, row: readonly ContentCellValue[]): ContentCellValue;
|
|
38
|
+
valueOf(ref: SqlColumnRef, row: readonly ContentCellValue[]): ContentCellValue;
|
|
39
|
+
}
|
|
40
|
+
//#endregion
|
|
41
|
+
export { columnAt as a, resolveTable as c, valueAtIndex as d, SharedColumnPair as i, tryResolveColumnIndex as l, OuterScope as n, resolveColumnIndex as o, ResolvedColumn as r, resolveName as s, ColumnResolver as t, tryResolveName as u };
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { r as HsqldbTable } from "./script-pkZ2Kor4.js";
|
|
2
|
+
import { r as SqlColumnRef, u as SqlNameRef } from "./parser-CoIi0l9I.js";
|
|
3
|
+
import { ContentCellValue } from "document-schema.js";
|
|
4
|
+
//#region src/odb/sql/evaluate-columns.d.ts
|
|
5
|
+
declare function tryResolveName(candidates: readonly string[], ref: SqlNameRef, what: string, sql: string): string | undefined;
|
|
6
|
+
declare function resolveName(candidates: readonly string[], ref: SqlNameRef, what: string, sql: string): string;
|
|
7
|
+
declare function resolveTable(tables: readonly HsqldbTable[], ref: SqlNameRef, sql: string): HsqldbTable;
|
|
8
|
+
interface ResolvedColumn {
|
|
9
|
+
readonly qualifiers: readonly string[];
|
|
10
|
+
readonly columnName: string;
|
|
11
|
+
}
|
|
12
|
+
interface SharedColumnPair {
|
|
13
|
+
readonly leftIndex: number;
|
|
14
|
+
readonly rightIndex: number;
|
|
15
|
+
readonly columnName: string;
|
|
16
|
+
}
|
|
17
|
+
declare function columnAt(columns: readonly ResolvedColumn[], index: number, sql: string): ResolvedColumn;
|
|
18
|
+
declare function valueAtIndex(row: readonly ContentCellValue[], index: number, sql: string): ContentCellValue;
|
|
19
|
+
declare function tryResolveColumnIndex(columns: readonly ResolvedColumn[], candidateIndices: readonly number[], ref: SqlNameRef, sql: string): number | undefined;
|
|
20
|
+
declare function resolveColumnIndex(columns: readonly ResolvedColumn[], candidateIndices: readonly number[], ref: SqlNameRef, sql: string): number;
|
|
21
|
+
interface OuterScope {
|
|
22
|
+
readonly resolver: ColumnResolver;
|
|
23
|
+
readonly row: readonly ContentCellValue[];
|
|
24
|
+
}
|
|
25
|
+
declare class ColumnResolver {
|
|
26
|
+
private readonly sql;
|
|
27
|
+
private readonly outer?;
|
|
28
|
+
private readonly cache;
|
|
29
|
+
private readonly columns;
|
|
30
|
+
private readonly qualifierNames;
|
|
31
|
+
constructor(columns: readonly ResolvedColumn[], sql: string, outer?: OuterScope | undefined);
|
|
32
|
+
get columnCount(): number;
|
|
33
|
+
nameAt(index: number): string;
|
|
34
|
+
indexOf(ref: SqlColumnRef): number;
|
|
35
|
+
private tryLocalIndexOf;
|
|
36
|
+
private candidateIndicesFor;
|
|
37
|
+
valueAt(index: number, row: readonly ContentCellValue[]): ContentCellValue;
|
|
38
|
+
valueOf(ref: SqlColumnRef, row: readonly ContentCellValue[]): ContentCellValue;
|
|
39
|
+
}
|
|
40
|
+
//#endregion
|
|
41
|
+
export { columnAt as a, resolveTable as c, valueAtIndex as d, SharedColumnPair as i, tryResolveColumnIndex as l, OuterScope as n, resolveColumnIndex as o, ResolvedColumn as r, resolveName as s, ColumnResolver as t, tryResolveName as u };
|