lakeql 0.2.0 → 0.5.1
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/bin.js +470 -169
- package/dist/{chunk-32PE6IK4.js → chunk-AUL4DYT4.js} +1076 -99
- package/dist/{chunk-3WUY56UD.js → chunk-TR4JNJ47.js} +1274 -172
- package/dist/cloudflare.d.ts +1 -1
- package/dist/cloudflare.js +2 -2
- package/dist/index.d.ts +18 -2
- package/dist/index.js +2 -2
- package/dist/node.d.ts +1 -1
- package/dist/node.js +3 -3
- package/package.json +6 -6
|
@@ -9207,6 +9207,48 @@ function compareSortValues(left, right, term) {
|
|
|
9207
9207
|
}
|
|
9208
9208
|
|
|
9209
9209
|
// ../core/dist/query-json.js
|
|
9210
|
+
var COMPARE_OPS = ["eq", "ne", "lt", "lte", "gt", "gte"];
|
|
9211
|
+
var ARITHMETIC_OPS = ["add", "sub", "mul", "div", "mod"];
|
|
9212
|
+
var AGGREGATE_OPS = [
|
|
9213
|
+
"count",
|
|
9214
|
+
"sum",
|
|
9215
|
+
"avg",
|
|
9216
|
+
"var_samp",
|
|
9217
|
+
"var_pop",
|
|
9218
|
+
"stddev_samp",
|
|
9219
|
+
"stddev_pop",
|
|
9220
|
+
"median",
|
|
9221
|
+
"quantile",
|
|
9222
|
+
"min",
|
|
9223
|
+
"max",
|
|
9224
|
+
"count_distinct",
|
|
9225
|
+
"approx_count_distinct",
|
|
9226
|
+
"mode",
|
|
9227
|
+
"first",
|
|
9228
|
+
"last"
|
|
9229
|
+
];
|
|
9230
|
+
var WINDOW_FN_NAMES = [
|
|
9231
|
+
"row_number",
|
|
9232
|
+
"rank",
|
|
9233
|
+
"dense_rank",
|
|
9234
|
+
"percent_rank",
|
|
9235
|
+
"cume_dist",
|
|
9236
|
+
"ntile",
|
|
9237
|
+
"lag",
|
|
9238
|
+
"lead",
|
|
9239
|
+
"first_value",
|
|
9240
|
+
"last_value",
|
|
9241
|
+
"nth_value"
|
|
9242
|
+
];
|
|
9243
|
+
var WINDOW_FRAME_MODES = ["rows", "range", "groups"];
|
|
9244
|
+
var WINDOW_FRAME_EXCLUDES = ["no-others", "current-row", "group", "ties"];
|
|
9245
|
+
var WINDOW_FRAME_BOUND_KINDS = [
|
|
9246
|
+
"unbounded-preceding",
|
|
9247
|
+
"preceding",
|
|
9248
|
+
"current-row",
|
|
9249
|
+
"following",
|
|
9250
|
+
"unbounded-following"
|
|
9251
|
+
];
|
|
9210
9252
|
function parseJsonQuery(input) {
|
|
9211
9253
|
if (!isRecord(input))
|
|
9212
9254
|
throwParse("JSON query must be an object");
|
|
@@ -9223,6 +9265,10 @@ function parseJsonQuery(input) {
|
|
|
9223
9265
|
}
|
|
9224
9266
|
if (input.where !== void 0)
|
|
9225
9267
|
init.where = parseJsonExpr(input.where);
|
|
9268
|
+
if (input.windows !== void 0)
|
|
9269
|
+
init.windows = parseJsonWindows(input.windows);
|
|
9270
|
+
if (input.qualify !== void 0)
|
|
9271
|
+
init.qualify = parseJsonExpr(input.qualify);
|
|
9226
9272
|
if (input.distinct !== void 0) {
|
|
9227
9273
|
if (typeof input.distinct !== "boolean")
|
|
9228
9274
|
throwParse("JSON query distinct must be a boolean");
|
|
@@ -9262,6 +9308,8 @@ function parseJsonOrderByTerm(input) {
|
|
|
9262
9308
|
function parseJsonExpr(input) {
|
|
9263
9309
|
if (!isRecord(input))
|
|
9264
9310
|
throwParse("JSON expression must be an object");
|
|
9311
|
+
if (typeof input.kind === "string")
|
|
9312
|
+
return parseJsonExprAst(input);
|
|
9265
9313
|
const entries = Object.entries(input);
|
|
9266
9314
|
if (entries.length !== 1)
|
|
9267
9315
|
throwParse("JSON expression must have exactly one operator");
|
|
@@ -9314,6 +9362,213 @@ function parseJsonExpr(input) {
|
|
|
9314
9362
|
throwParse(`Unsupported JSON expression operator ${op}`);
|
|
9315
9363
|
}
|
|
9316
9364
|
}
|
|
9365
|
+
function parseJsonExprAst(input) {
|
|
9366
|
+
switch (input.kind) {
|
|
9367
|
+
case "literal":
|
|
9368
|
+
return { kind: "literal", value: requireScalar(input.value, "literal") };
|
|
9369
|
+
case "column":
|
|
9370
|
+
if (typeof input.name !== "string")
|
|
9371
|
+
throwParse("column expression name must be a string");
|
|
9372
|
+
return { kind: "column", name: input.name };
|
|
9373
|
+
case "compare": {
|
|
9374
|
+
if (!isCompareOp(input.op))
|
|
9375
|
+
throwParse("compare expression op must be eq, ne, lt, lte, gt, or gte");
|
|
9376
|
+
return {
|
|
9377
|
+
kind: "compare",
|
|
9378
|
+
op: input.op,
|
|
9379
|
+
left: parseJsonExpr(input.left),
|
|
9380
|
+
right: parseJsonExpr(input.right)
|
|
9381
|
+
};
|
|
9382
|
+
}
|
|
9383
|
+
case "in": {
|
|
9384
|
+
if (typeof input.negated !== "boolean")
|
|
9385
|
+
throwParse("in expression negated must be a boolean");
|
|
9386
|
+
if (!Array.isArray(input.values))
|
|
9387
|
+
throwParse("in expression values must be an array");
|
|
9388
|
+
return {
|
|
9389
|
+
kind: "in",
|
|
9390
|
+
negated: input.negated,
|
|
9391
|
+
target: parseJsonExpr(input.target),
|
|
9392
|
+
values: input.values.map(parseJsonExpr)
|
|
9393
|
+
};
|
|
9394
|
+
}
|
|
9395
|
+
case "between":
|
|
9396
|
+
return {
|
|
9397
|
+
kind: "between",
|
|
9398
|
+
target: parseJsonExpr(input.target),
|
|
9399
|
+
low: parseJsonExpr(input.low),
|
|
9400
|
+
high: parseJsonExpr(input.high)
|
|
9401
|
+
};
|
|
9402
|
+
case "null-check":
|
|
9403
|
+
if (typeof input.negated !== "boolean") {
|
|
9404
|
+
throwParse("null-check expression negated must be a boolean");
|
|
9405
|
+
}
|
|
9406
|
+
return { kind: "null-check", negated: input.negated, target: parseJsonExpr(input.target) };
|
|
9407
|
+
case "logical": {
|
|
9408
|
+
if (input.op !== "and" && input.op !== "or") {
|
|
9409
|
+
throwParse("logical expression op must be and or or");
|
|
9410
|
+
}
|
|
9411
|
+
if (!Array.isArray(input.operands))
|
|
9412
|
+
throwParse("logical expression operands must be an array");
|
|
9413
|
+
if (input.operands.length < 2) {
|
|
9414
|
+
throwParse("logical expression operands must include at least two expressions");
|
|
9415
|
+
}
|
|
9416
|
+
return { kind: "logical", op: input.op, operands: input.operands.map(parseJsonExpr) };
|
|
9417
|
+
}
|
|
9418
|
+
case "not":
|
|
9419
|
+
return { kind: "not", operand: parseJsonExpr(input.operand) };
|
|
9420
|
+
case "like":
|
|
9421
|
+
if (typeof input.caseInsensitive !== "boolean") {
|
|
9422
|
+
throwParse("like expression caseInsensitive must be a boolean");
|
|
9423
|
+
}
|
|
9424
|
+
if (typeof input.pattern !== "string")
|
|
9425
|
+
throwParse("like expression pattern must be a string");
|
|
9426
|
+
return {
|
|
9427
|
+
kind: "like",
|
|
9428
|
+
caseInsensitive: input.caseInsensitive,
|
|
9429
|
+
target: parseJsonExpr(input.target),
|
|
9430
|
+
pattern: input.pattern
|
|
9431
|
+
};
|
|
9432
|
+
case "call":
|
|
9433
|
+
if (typeof input.fn !== "string")
|
|
9434
|
+
throwParse("call expression fn must be a string");
|
|
9435
|
+
if (!Array.isArray(input.args))
|
|
9436
|
+
throwParse("call expression args must be an array");
|
|
9437
|
+
return { kind: "call", fn: input.fn, args: input.args.map(parseJsonExpr) };
|
|
9438
|
+
case "arithmetic":
|
|
9439
|
+
if (!isArithmeticOp(input.op))
|
|
9440
|
+
throwParse("arithmetic expression op is invalid");
|
|
9441
|
+
return {
|
|
9442
|
+
kind: "arithmetic",
|
|
9443
|
+
op: input.op,
|
|
9444
|
+
left: parseJsonExpr(input.left),
|
|
9445
|
+
right: parseJsonExpr(input.right)
|
|
9446
|
+
};
|
|
9447
|
+
case "case": {
|
|
9448
|
+
if (!Array.isArray(input.whens))
|
|
9449
|
+
throwParse("case expression whens must be an array");
|
|
9450
|
+
return {
|
|
9451
|
+
kind: "case",
|
|
9452
|
+
whens: input.whens.map((when) => {
|
|
9453
|
+
if (!isRecord(when))
|
|
9454
|
+
throwParse("case expression whens must be objects");
|
|
9455
|
+
return { when: parseJsonExpr(when.when), value: parseJsonExpr(when.value) };
|
|
9456
|
+
}),
|
|
9457
|
+
...input.else === void 0 ? {} : { else: parseJsonExpr(input.else) }
|
|
9458
|
+
};
|
|
9459
|
+
}
|
|
9460
|
+
default:
|
|
9461
|
+
throwParse(`Unsupported JSON expression kind ${String(input.kind)}`);
|
|
9462
|
+
}
|
|
9463
|
+
}
|
|
9464
|
+
function parseJsonWindows(input) {
|
|
9465
|
+
if (!isRecord(input))
|
|
9466
|
+
throwParse("JSON query windows must be an object");
|
|
9467
|
+
const windows = {};
|
|
9468
|
+
for (const [alias, value2] of Object.entries(input)) {
|
|
9469
|
+
if (alias.length === 0 || isPrototypeMutationKey2(alias)) {
|
|
9470
|
+
throwParse("JSON query window aliases must be valid object keys");
|
|
9471
|
+
}
|
|
9472
|
+
windows[alias] = parseJsonWindowExpr(value2);
|
|
9473
|
+
}
|
|
9474
|
+
return windows;
|
|
9475
|
+
}
|
|
9476
|
+
function parseJsonWindowExpr(input) {
|
|
9477
|
+
if (!isRecord(input))
|
|
9478
|
+
throwParse("JSON window expression must be an object");
|
|
9479
|
+
const over = input.over;
|
|
9480
|
+
if (!isRecord(over))
|
|
9481
|
+
throwParse("JSON window expression over must be an object");
|
|
9482
|
+
if (!Array.isArray(input.args))
|
|
9483
|
+
throwParse("JSON window expression args must be an array");
|
|
9484
|
+
const expr = {
|
|
9485
|
+
fn: parseJsonWindowFn(input.fn),
|
|
9486
|
+
args: input.args.map(parseJsonExpr),
|
|
9487
|
+
over: {
|
|
9488
|
+
partitionBy: parseExprArray(over.partitionBy, "JSON window partitionBy"),
|
|
9489
|
+
orderBy: parseJsonWindowOrderBy(over.orderBy),
|
|
9490
|
+
...over.frame === void 0 ? {} : { frame: parseJsonWindowFrame(over.frame) }
|
|
9491
|
+
}
|
|
9492
|
+
};
|
|
9493
|
+
if (input.filter !== void 0)
|
|
9494
|
+
expr.filter = parseJsonExpr(input.filter);
|
|
9495
|
+
if (input.ignoreNulls !== void 0) {
|
|
9496
|
+
if (typeof input.ignoreNulls !== "boolean") {
|
|
9497
|
+
throwParse("JSON window expression ignoreNulls must be a boolean");
|
|
9498
|
+
}
|
|
9499
|
+
expr.ignoreNulls = input.ignoreNulls;
|
|
9500
|
+
}
|
|
9501
|
+
if (input.distinct !== void 0) {
|
|
9502
|
+
if (typeof input.distinct !== "boolean") {
|
|
9503
|
+
throwParse("JSON window expression distinct must be a boolean");
|
|
9504
|
+
}
|
|
9505
|
+
expr.distinct = input.distinct;
|
|
9506
|
+
}
|
|
9507
|
+
return expr;
|
|
9508
|
+
}
|
|
9509
|
+
function parseJsonWindowFn(input) {
|
|
9510
|
+
if (isWindowFnName(input))
|
|
9511
|
+
return input;
|
|
9512
|
+
if (isRecord(input) && isAggregateOp(input.aggregate))
|
|
9513
|
+
return { aggregate: input.aggregate };
|
|
9514
|
+
throwParse("JSON window function is invalid");
|
|
9515
|
+
}
|
|
9516
|
+
function parseJsonWindowOrderBy(input) {
|
|
9517
|
+
if (input === void 0)
|
|
9518
|
+
return [];
|
|
9519
|
+
if (!Array.isArray(input))
|
|
9520
|
+
throwParse("JSON window orderBy must be an array");
|
|
9521
|
+
return input.map((term) => {
|
|
9522
|
+
if (!isRecord(term))
|
|
9523
|
+
throwParse("JSON window orderBy terms must be objects");
|
|
9524
|
+
const out = { expr: parseJsonExpr(term.expr) };
|
|
9525
|
+
if (term.direction !== void 0) {
|
|
9526
|
+
if (term.direction !== "asc" && term.direction !== "desc") {
|
|
9527
|
+
throwParse("JSON window orderBy direction must be asc or desc");
|
|
9528
|
+
}
|
|
9529
|
+
out.direction = term.direction;
|
|
9530
|
+
}
|
|
9531
|
+
if (term.nulls !== void 0) {
|
|
9532
|
+
if (term.nulls !== "first" && term.nulls !== "last") {
|
|
9533
|
+
throwParse("JSON window orderBy nulls must be first or last");
|
|
9534
|
+
}
|
|
9535
|
+
out.nulls = term.nulls;
|
|
9536
|
+
}
|
|
9537
|
+
return out;
|
|
9538
|
+
});
|
|
9539
|
+
}
|
|
9540
|
+
function parseJsonWindowFrame(input) {
|
|
9541
|
+
if (!isRecord(input))
|
|
9542
|
+
throwParse("JSON window frame must be an object");
|
|
9543
|
+
if (!isOneOf(WINDOW_FRAME_MODES, input.mode)) {
|
|
9544
|
+
throwParse("JSON window frame mode must be rows, range, or groups");
|
|
9545
|
+
}
|
|
9546
|
+
if (!isOneOf(WINDOW_FRAME_EXCLUDES, input.exclude))
|
|
9547
|
+
throwParse("JSON window frame exclude is invalid");
|
|
9548
|
+
return {
|
|
9549
|
+
mode: input.mode,
|
|
9550
|
+
start: parseJsonWindowFrameBound(input.start),
|
|
9551
|
+
end: parseJsonWindowFrameBound(input.end),
|
|
9552
|
+
exclude: input.exclude
|
|
9553
|
+
};
|
|
9554
|
+
}
|
|
9555
|
+
function parseJsonWindowFrameBound(input) {
|
|
9556
|
+
if (!isRecord(input))
|
|
9557
|
+
throwParse("JSON window frame bound must be an object");
|
|
9558
|
+
if (!isOneOf(WINDOW_FRAME_BOUND_KINDS, input.kind))
|
|
9559
|
+
throwParse("JSON window frame bound kind is invalid");
|
|
9560
|
+
return {
|
|
9561
|
+
kind: input.kind,
|
|
9562
|
+
...input.offset === void 0 ? {} : { offset: parseJsonExpr(input.offset) }
|
|
9563
|
+
};
|
|
9564
|
+
}
|
|
9565
|
+
function parseExprArray(input, field) {
|
|
9566
|
+
if (input === void 0)
|
|
9567
|
+
return [];
|
|
9568
|
+
if (!Array.isArray(input))
|
|
9569
|
+
throwParse(`${field} must be an array`);
|
|
9570
|
+
return input.map(parseJsonExpr);
|
|
9571
|
+
}
|
|
9317
9572
|
function tuple2(value2, op, cb) {
|
|
9318
9573
|
const tuple = requireTuple(value2, op, 2);
|
|
9319
9574
|
return cb(requireColumn(tuple[0], op), requireScalar(tuple[1], op));
|
|
@@ -9351,6 +9606,24 @@ function requireScalar(value2, op) {
|
|
|
9351
9606
|
}
|
|
9352
9607
|
throwParse(`${op} value must be a scalar`);
|
|
9353
9608
|
}
|
|
9609
|
+
function isCompareOp(value2) {
|
|
9610
|
+
return isOneOf(COMPARE_OPS, value2);
|
|
9611
|
+
}
|
|
9612
|
+
function isArithmeticOp(value2) {
|
|
9613
|
+
return isOneOf(ARITHMETIC_OPS, value2);
|
|
9614
|
+
}
|
|
9615
|
+
function isAggregateOp(value2) {
|
|
9616
|
+
return isOneOf(AGGREGATE_OPS, value2);
|
|
9617
|
+
}
|
|
9618
|
+
function isWindowFnName(value2) {
|
|
9619
|
+
return isOneOf(WINDOW_FN_NAMES, value2);
|
|
9620
|
+
}
|
|
9621
|
+
function isPrototypeMutationKey2(value2) {
|
|
9622
|
+
return value2 === "__proto__" || value2 === "prototype" || value2 === "constructor";
|
|
9623
|
+
}
|
|
9624
|
+
function isOneOf(values, value2) {
|
|
9625
|
+
return typeof value2 === "string" && values.includes(value2);
|
|
9626
|
+
}
|
|
9354
9627
|
function parseNonNegativeInt(value2, field) {
|
|
9355
9628
|
if (typeof value2 !== "number" || !Number.isInteger(value2) || value2 < 0) {
|
|
9356
9629
|
throwParse(`${field} must be a non-negative integer`);
|
|
@@ -12744,7 +13017,7 @@ var QueryResult = class {
|
|
|
12744
13017
|
if (config.scanner.scanColumns === void 0)
|
|
12745
13018
|
return void 0;
|
|
12746
13019
|
const state = createVectorGroupByState(groupColumns, spec);
|
|
12747
|
-
for await (const batch of this.columnBatches(aggregateReadColumns(groupColumns, spec, config.where), startedAt, columnarBatchSize(config.batchSize))) {
|
|
13020
|
+
for await (const batch of this.columnBatches(aggregateReadColumns(groupColumns, spec, config.where, config.projections), startedAt, columnarBatchSize(config.batchSize))) {
|
|
12748
13021
|
const selection = predicateSelection(batch, config.where);
|
|
12749
13022
|
this.stats.rowsMatched += updateVectorGroupByState(state, batch, selection, {
|
|
12750
13023
|
budget: config.budget,
|
|
@@ -12892,9 +13165,10 @@ var QueryResult = class {
|
|
|
12892
13165
|
]);
|
|
12893
13166
|
const groups = await aggregateGroupsFromState(groupColumns, spec, options);
|
|
12894
13167
|
const startedAt = this.config.now();
|
|
12895
|
-
const readColumns = aggregateReadColumns(groupColumns, spec, this.config.where);
|
|
13168
|
+
const readColumns = aggregateReadColumns(groupColumns, spec, this.config.where, this.config.projections);
|
|
12896
13169
|
for await (const row of this.matchedRows(startedAt, readColumns)) {
|
|
12897
|
-
const
|
|
13170
|
+
const aggregateRow = this.config.projections === void 0 ? row : project(row, ["*"], this.config.projections);
|
|
13171
|
+
const keyValues = groupColumns.map((column) => valueForColumn(aggregateRow, column));
|
|
12898
13172
|
const key = stableStringify(keyValues);
|
|
12899
13173
|
let group = groups.get(key);
|
|
12900
13174
|
if (!group) {
|
|
@@ -12904,7 +13178,7 @@ var QueryResult = class {
|
|
|
12904
13178
|
group = createAggregateGroup(groupColumns, keyValues, spec);
|
|
12905
13179
|
groups.set(key, group);
|
|
12906
13180
|
}
|
|
12907
|
-
group.add(
|
|
13181
|
+
group.add(aggregateRow);
|
|
12908
13182
|
enforceBufferedRowsBudget(this.config.budget, estimateAggregateBufferedRows(groups));
|
|
12909
13183
|
enforceOperatorMemoryBudget(this.config.budget, estimateAggregateOperatorMemoryBytes(groupColumns, spec, groups));
|
|
12910
13184
|
}
|
|
@@ -14480,10 +14754,15 @@ async function* rowsAsBatches(rows, batchSize) {
|
|
|
14480
14754
|
yield rows.slice(index, index + batchSize);
|
|
14481
14755
|
}
|
|
14482
14756
|
}
|
|
14483
|
-
function aggregateReadColumns(groupColumns, spec, where) {
|
|
14757
|
+
function aggregateReadColumns(groupColumns, spec, where, projections) {
|
|
14484
14758
|
const columns = /* @__PURE__ */ new Set();
|
|
14485
|
-
for (const column of groupColumns)
|
|
14486
|
-
|
|
14759
|
+
for (const column of groupColumns) {
|
|
14760
|
+
const projection = projections?.[column];
|
|
14761
|
+
if (projection === void 0)
|
|
14762
|
+
columns.add(column);
|
|
14763
|
+
else
|
|
14764
|
+
collectExprColumns(projection, columns);
|
|
14765
|
+
}
|
|
14487
14766
|
for (const aggregate of Object.values(spec)) {
|
|
14488
14767
|
if (aggregate.column !== void 0)
|
|
14489
14768
|
columns.add(aggregate.column);
|
|
@@ -14955,6 +15234,20 @@ async function lookupJoin(left, lookup, options) {
|
|
|
14955
15234
|
}
|
|
14956
15235
|
return out;
|
|
14957
15236
|
}
|
|
15237
|
+
async function crossJoin(left, right, options) {
|
|
15238
|
+
validateCrossJoinOptions(options);
|
|
15239
|
+
const rightRows = await collectRightRows(right, options.maxRightRows);
|
|
15240
|
+
const out = [];
|
|
15241
|
+
for await (const leftRow of left) {
|
|
15242
|
+
for (const rightRow of rightRows) {
|
|
15243
|
+
if (out.length >= options.maxOutputRows) {
|
|
15244
|
+
enforceMaxOutputRows(out.length + 1, options.maxOutputRows);
|
|
15245
|
+
}
|
|
15246
|
+
out.push(mergeCrossRows(leftRow, rightRow, options.rightPrefix));
|
|
15247
|
+
}
|
|
15248
|
+
}
|
|
15249
|
+
return out;
|
|
15250
|
+
}
|
|
14958
15251
|
async function collectRightRows(rows, maxRightRows) {
|
|
14959
15252
|
const out = [];
|
|
14960
15253
|
for await (const row of rows) {
|
|
@@ -14965,6 +15258,14 @@ async function collectRightRows(rows, maxRightRows) {
|
|
|
14965
15258
|
}
|
|
14966
15259
|
return out;
|
|
14967
15260
|
}
|
|
15261
|
+
function validateCrossJoinOptions(options) {
|
|
15262
|
+
if (!Number.isInteger(options.maxRightRows) || options.maxRightRows < 1) {
|
|
15263
|
+
throw new LakeqlError("LAKEQL_TYPE_ERROR", "Cross join maxRightRows must be a positive integer");
|
|
15264
|
+
}
|
|
15265
|
+
if (!Number.isInteger(options.maxOutputRows) || options.maxOutputRows < 1) {
|
|
15266
|
+
throw new LakeqlError("LAKEQL_TYPE_ERROR", "Cross join maxOutputRows must be a positive integer");
|
|
15267
|
+
}
|
|
15268
|
+
}
|
|
14968
15269
|
function validateJoinOptions(options, strategy) {
|
|
14969
15270
|
const leftKeys = normalizeJoinKeys(options.leftKey, "leftKey", strategy);
|
|
14970
15271
|
const rightKeys = normalizeJoinKeys(options.rightKey, "rightKey", strategy);
|
|
@@ -15028,11 +15329,24 @@ function mergeRows(left, right, options) {
|
|
|
15028
15329
|
}
|
|
15029
15330
|
return out;
|
|
15030
15331
|
}
|
|
15332
|
+
function mergeCrossRows(left, right, rightPrefix = "right.") {
|
|
15333
|
+
const out = { ...left };
|
|
15334
|
+
for (const [key, value2] of Object.entries(right)) {
|
|
15335
|
+
const outKey = key in out ? `${rightPrefix}${key}` : key;
|
|
15336
|
+
out[outKey] = value2;
|
|
15337
|
+
}
|
|
15338
|
+
return out;
|
|
15339
|
+
}
|
|
15031
15340
|
function enforceMaxRightRows(strategy, actual, limit) {
|
|
15032
15341
|
if (actual <= limit)
|
|
15033
15342
|
return;
|
|
15034
15343
|
throw new LakeqlError("LAKEQL_BUDGET_EXCEEDED", `${strategy} join exceeded maxRightRows (${actual} > ${limit})`, { metric: "maxRightRows", limit, actual });
|
|
15035
15344
|
}
|
|
15345
|
+
function enforceMaxOutputRows(actual, limit) {
|
|
15346
|
+
if (actual <= limit)
|
|
15347
|
+
return;
|
|
15348
|
+
throw new LakeqlError("LAKEQL_BUDGET_EXCEEDED", `Cross join exceeded maxOutputRows (${actual} > ${limit})`, { metric: "maxOutputRows", limit, actual });
|
|
15349
|
+
}
|
|
15036
15350
|
|
|
15037
15351
|
// ../core/dist/memory-store.js
|
|
15038
15352
|
async function collect(body) {
|
|
@@ -19757,6 +20071,7 @@ function parseSql(sql, options = {}) {
|
|
|
19757
20071
|
if (sql.length > MAX_SQL_LENGTH) {
|
|
19758
20072
|
throwParse2(`SQL input length exceeds ${MAX_SQL_LENGTH}`);
|
|
19759
20073
|
}
|
|
20074
|
+
rejectRecursiveCte(sql);
|
|
19760
20075
|
const windowPrepass = extractWindowFrames(sql);
|
|
19761
20076
|
const prepass = extractTopLevelQualify(windowPrepass.sql);
|
|
19762
20077
|
let statements;
|
|
@@ -19781,6 +20096,18 @@ function parseSql(sql, options = {}) {
|
|
|
19781
20096
|
throwUnsupported("Only SELECT statements are supported");
|
|
19782
20097
|
return selectStatementToAst(statement, context, context.qualifySql);
|
|
19783
20098
|
}
|
|
20099
|
+
function rejectRecursiveCte(sql) {
|
|
20100
|
+
const withIndex = findTopLevelKeyword(sql, "with", 0);
|
|
20101
|
+
if (withIndex === -1)
|
|
20102
|
+
return;
|
|
20103
|
+
const recursiveIndex = findTopLevelKeyword(sql, "recursive", withIndex + "with".length);
|
|
20104
|
+
if (recursiveIndex === -1)
|
|
20105
|
+
return;
|
|
20106
|
+
const between2 = sql.slice(withIndex + "with".length, recursiveIndex);
|
|
20107
|
+
if (between2.trim().length > 0)
|
|
20108
|
+
return;
|
|
20109
|
+
throwUnsupported("Recursive CTEs are not supported");
|
|
20110
|
+
}
|
|
19784
20111
|
function parseSqlStatement(sql, options = {}) {
|
|
19785
20112
|
const describe = parseDescribeStatement(sql);
|
|
19786
20113
|
if (describe !== void 0)
|
|
@@ -19811,28 +20138,27 @@ function withStatementToAst(statement, context) {
|
|
|
19811
20138
|
const binding = asNode(bindings[0], "CTE binding");
|
|
19812
20139
|
const name = nameNodeToString(binding.alias);
|
|
19813
20140
|
const inner = asNode(binding.statement, "CTE statement");
|
|
19814
|
-
if (inner.type !== "select")
|
|
20141
|
+
if (inner.type !== "select" && inner.type !== "with") {
|
|
19815
20142
|
throwUnsupported("Only SELECT CTEs are supported");
|
|
19816
|
-
|
|
19817
|
-
|
|
20143
|
+
}
|
|
20144
|
+
const cteQuery = inner.type === "with" ? withStatementToAst(inner, context) : selectStatementToAst(inner, context);
|
|
19818
20145
|
const outer = asNode(statement.in, "CTE outer query");
|
|
19819
20146
|
if (outer.type !== "select")
|
|
19820
20147
|
throwUnsupported("Only SELECT after WITH is supported");
|
|
19821
20148
|
const ast = selectStatementToAst(outer, context, context.qualifySql);
|
|
20149
|
+
if (ast.cte !== void 0)
|
|
20150
|
+
throwUnsupported("WITH queries cannot also use derived tables");
|
|
19822
20151
|
ast.cte = { name, query: cteQuery };
|
|
19823
20152
|
return ast;
|
|
19824
20153
|
}
|
|
19825
|
-
function validateCteQuery(ast) {
|
|
19826
|
-
if (ast.join !== void 0 || ast.subqueryJoin !== void 0 || ast.scalarSubqueries !== void 0 || ast.cte !== void 0) {
|
|
19827
|
-
throwUnsupported("Nested CTE joins and subqueries are not supported");
|
|
19828
|
-
}
|
|
19829
|
-
}
|
|
19830
20154
|
function selectStatementToAst(statement, context = newSqlParseContext(), qualifySql) {
|
|
19831
20155
|
const previousWindows = context.windows;
|
|
19832
20156
|
const previousNextWindowId = context.nextWindowId;
|
|
20157
|
+
const previousNextHavingAggregateId = context.nextHavingAggregateId;
|
|
19833
20158
|
const previousQualifySql = context.qualifySql;
|
|
19834
20159
|
context.windows = {};
|
|
19835
20160
|
context.nextWindowId = 0;
|
|
20161
|
+
context.nextHavingAggregateId = 0;
|
|
19836
20162
|
if (qualifySql === void 0)
|
|
19837
20163
|
delete context.qualifySql;
|
|
19838
20164
|
else
|
|
@@ -19840,6 +20166,7 @@ function selectStatementToAst(statement, context = newSqlParseContext(), qualify
|
|
|
19840
20166
|
const ast = selectStatementToAstInScope(statement, context);
|
|
19841
20167
|
context.windows = previousWindows;
|
|
19842
20168
|
context.nextWindowId = previousNextWindowId;
|
|
20169
|
+
context.nextHavingAggregateId = previousNextHavingAggregateId;
|
|
19843
20170
|
if (previousQualifySql === void 0)
|
|
19844
20171
|
delete context.qualifySql;
|
|
19845
20172
|
else
|
|
@@ -19850,16 +20177,28 @@ function selectStatementToAstInScope(statement, context) {
|
|
|
19850
20177
|
rejectPresent(statement, "with", "CTEs are not supported");
|
|
19851
20178
|
rejectPresent(statement, "windows", "Window functions are not supported");
|
|
19852
20179
|
const from = optionalArray(statement.from);
|
|
19853
|
-
if (from.length
|
|
19854
|
-
throwUnsupported("SELECT must have
|
|
20180
|
+
if (from.length < 1) {
|
|
20181
|
+
throwUnsupported("SELECT must have a FROM table");
|
|
19855
20182
|
}
|
|
19856
|
-
const leftSource = sourceTable(from[0]);
|
|
20183
|
+
const leftSource = sourceTable(from[0], context);
|
|
19857
20184
|
const ast = { source: leftSource.source };
|
|
20185
|
+
if (leftSource.cte !== void 0)
|
|
20186
|
+
ast.cte = leftSource.cte;
|
|
19858
20187
|
const scope = new SqlScope(leftSource);
|
|
19859
|
-
|
|
19860
|
-
|
|
19861
|
-
|
|
19862
|
-
|
|
20188
|
+
const joinedSources = [leftSource];
|
|
20189
|
+
const joins = [];
|
|
20190
|
+
for (const source of from.slice(1)) {
|
|
20191
|
+
const { join, right } = joinToAst(source, joinedSources);
|
|
20192
|
+
joins.push(join);
|
|
20193
|
+
joinedSources.push(right);
|
|
20194
|
+
scope.add(right);
|
|
20195
|
+
}
|
|
20196
|
+
if (joins.length > 0) {
|
|
20197
|
+
const firstJoin = joins[0];
|
|
20198
|
+
if (firstJoin === void 0)
|
|
20199
|
+
throwUnsupported("JOIN chain must contain at least one join");
|
|
20200
|
+
ast.join = firstJoin;
|
|
20201
|
+
ast.joins = joins;
|
|
19863
20202
|
}
|
|
19864
20203
|
if (statement.distinct !== void 0) {
|
|
19865
20204
|
if (statement.distinct !== "distinct") {
|
|
@@ -19874,6 +20213,7 @@ function selectStatementToAstInScope(statement, context) {
|
|
|
19874
20213
|
const projections = {};
|
|
19875
20214
|
const aggregates = {};
|
|
19876
20215
|
const outputAliases = /* @__PURE__ */ new Set();
|
|
20216
|
+
const hiddenAggregates = /* @__PURE__ */ new Set();
|
|
19877
20217
|
for (const column of columns) {
|
|
19878
20218
|
const item = asNode(column, "select item");
|
|
19879
20219
|
const expr = asNode(item.expr, "select expression");
|
|
@@ -19924,17 +20264,25 @@ function selectStatementToAstInScope(statement, context) {
|
|
|
19924
20264
|
const where = whereToAst(asNode(statement.where, "WHERE"), scope, context);
|
|
19925
20265
|
if (where.where !== void 0)
|
|
19926
20266
|
ast.where = where.where;
|
|
19927
|
-
if (where.
|
|
19928
|
-
ast.
|
|
20267
|
+
if (where.subqueryJoins !== void 0) {
|
|
20268
|
+
ast.subqueryJoins = where.subqueryJoins;
|
|
20269
|
+
const firstSubqueryJoin = where.subqueryJoins[0];
|
|
20270
|
+
if (firstSubqueryJoin !== void 0)
|
|
20271
|
+
ast.subqueryJoin = firstSubqueryJoin;
|
|
20272
|
+
}
|
|
19929
20273
|
}
|
|
19930
20274
|
if (statement.groupBy !== void 0) {
|
|
19931
20275
|
ast.groupBy = optionalArray(statement.groupBy).map((expr) => scope.refName(asNode(expr, "GROUP BY expression")));
|
|
19932
20276
|
}
|
|
19933
20277
|
if (statement.having !== void 0) {
|
|
19934
|
-
ast.having =
|
|
20278
|
+
ast.having = havingToExpr(asNode(statement.having, "HAVING"), scope, context, aggregates, hiddenAggregates, outputAliases);
|
|
20279
|
+
if (Object.keys(aggregates).length > 0)
|
|
20280
|
+
ast.aggregates = aggregates;
|
|
20281
|
+
if (hiddenAggregates.size > 0)
|
|
20282
|
+
ast.hiddenAggregates = [...hiddenAggregates];
|
|
19935
20283
|
}
|
|
19936
20284
|
if (context.qualifySql !== void 0) {
|
|
19937
|
-
ast.qualify = qualifyToExpr(context.qualifySql, scope, context);
|
|
20285
|
+
ast.qualify = expandProjectionAliasesInExpr(qualifyToExpr(context.qualifySql, scope, context), projections, context.windows);
|
|
19938
20286
|
}
|
|
19939
20287
|
if (Object.keys(context.windows).length > 0)
|
|
19940
20288
|
ast.windows = context.windows;
|
|
@@ -19952,6 +20300,9 @@ function selectStatementToAstInScope(statement, context) {
|
|
|
19952
20300
|
if (Object.keys(context.scalarSubqueries).length > 0) {
|
|
19953
20301
|
ast.scalarSubqueries = context.scalarSubqueries;
|
|
19954
20302
|
}
|
|
20303
|
+
if (Object.keys(context.correlatedScalarSubqueries).length > 0) {
|
|
20304
|
+
ast.correlatedScalarSubqueries = context.correlatedScalarSubqueries;
|
|
20305
|
+
}
|
|
19955
20306
|
return ast;
|
|
19956
20307
|
}
|
|
19957
20308
|
function qualifyToExpr(sql, scope, context) {
|
|
@@ -19967,12 +20318,106 @@ function qualifyToExpr(sql, scope, context) {
|
|
|
19967
20318
|
const where = asNode(statement.where, "QUALIFY predicate");
|
|
19968
20319
|
return exprToLakeql(where, scope, context);
|
|
19969
20320
|
}
|
|
20321
|
+
function expandProjectionAliasesInExpr(expr, projections, windows) {
|
|
20322
|
+
switch (expr.kind) {
|
|
20323
|
+
case "column":
|
|
20324
|
+
return expr.name in windows ? expr : projections[expr.name] ?? expr;
|
|
20325
|
+
case "compare":
|
|
20326
|
+
return {
|
|
20327
|
+
...expr,
|
|
20328
|
+
left: expandProjectionAliasesInExpr(expr.left, projections, windows),
|
|
20329
|
+
right: expandProjectionAliasesInExpr(expr.right, projections, windows)
|
|
20330
|
+
};
|
|
20331
|
+
case "between":
|
|
20332
|
+
return {
|
|
20333
|
+
...expr,
|
|
20334
|
+
target: expandProjectionAliasesInExpr(expr.target, projections, windows),
|
|
20335
|
+
low: expandProjectionAliasesInExpr(expr.low, projections, windows),
|
|
20336
|
+
high: expandProjectionAliasesInExpr(expr.high, projections, windows)
|
|
20337
|
+
};
|
|
20338
|
+
case "in":
|
|
20339
|
+
return {
|
|
20340
|
+
...expr,
|
|
20341
|
+
target: expandProjectionAliasesInExpr(expr.target, projections, windows),
|
|
20342
|
+
values: expr.values.map((value2) => expandProjectionAliasesInExpr(value2, projections, windows))
|
|
20343
|
+
};
|
|
20344
|
+
case "null-check":
|
|
20345
|
+
return { ...expr, target: expandProjectionAliasesInExpr(expr.target, projections, windows) };
|
|
20346
|
+
case "logical":
|
|
20347
|
+
return {
|
|
20348
|
+
...expr,
|
|
20349
|
+
operands: expr.operands.map((operand) => expandProjectionAliasesInExpr(operand, projections, windows))
|
|
20350
|
+
};
|
|
20351
|
+
case "not":
|
|
20352
|
+
return {
|
|
20353
|
+
...expr,
|
|
20354
|
+
operand: expandProjectionAliasesInExpr(expr.operand, projections, windows)
|
|
20355
|
+
};
|
|
20356
|
+
case "like":
|
|
20357
|
+
return { ...expr, target: expandProjectionAliasesInExpr(expr.target, projections, windows) };
|
|
20358
|
+
case "call":
|
|
20359
|
+
return {
|
|
20360
|
+
...expr,
|
|
20361
|
+
args: expr.args.map((arg) => expandProjectionAliasesInExpr(arg, projections, windows))
|
|
20362
|
+
};
|
|
20363
|
+
case "arithmetic":
|
|
20364
|
+
return {
|
|
20365
|
+
...expr,
|
|
20366
|
+
left: expandProjectionAliasesInExpr(expr.left, projections, windows),
|
|
20367
|
+
right: expandProjectionAliasesInExpr(expr.right, projections, windows)
|
|
20368
|
+
};
|
|
20369
|
+
case "case":
|
|
20370
|
+
return {
|
|
20371
|
+
...expr,
|
|
20372
|
+
whens: expr.whens.map((branch) => ({
|
|
20373
|
+
when: expandProjectionAliasesInExpr(branch.when, projections, windows),
|
|
20374
|
+
value: expandProjectionAliasesInExpr(branch.value, projections, windows)
|
|
20375
|
+
})),
|
|
20376
|
+
...expr.else === void 0 ? {} : { else: expandProjectionAliasesInExpr(expr.else, projections, windows) }
|
|
20377
|
+
};
|
|
20378
|
+
case "literal":
|
|
20379
|
+
return expr;
|
|
20380
|
+
}
|
|
20381
|
+
}
|
|
20382
|
+
function havingToExpr(expr, scope, context, aggregates, hiddenAggregates, outputAliases) {
|
|
20383
|
+
const previous = context.havingAggregates;
|
|
20384
|
+
context.havingAggregates = { aggregates, hiddenAggregates, outputAliases };
|
|
20385
|
+
try {
|
|
20386
|
+
return exprToLakeql(expr, scope, context);
|
|
20387
|
+
} finally {
|
|
20388
|
+
if (previous === void 0)
|
|
20389
|
+
delete context.havingAggregates;
|
|
20390
|
+
else
|
|
20391
|
+
context.havingAggregates = previous;
|
|
20392
|
+
}
|
|
20393
|
+
}
|
|
20394
|
+
function registerHavingAggregate(expr, scope, context) {
|
|
20395
|
+
const havingAggregates = context.havingAggregates;
|
|
20396
|
+
if (havingAggregates === void 0)
|
|
20397
|
+
throwUnsupported("HAVING aggregate context is missing");
|
|
20398
|
+
const spec = aggregateCallToSpec(expr, scope, context);
|
|
20399
|
+
for (const [alias2, aggregate] of Object.entries(havingAggregates.aggregates)) {
|
|
20400
|
+
if (JSON.stringify(aggregate) === JSON.stringify(spec))
|
|
20401
|
+
return alias2;
|
|
20402
|
+
}
|
|
20403
|
+
let alias = `__lakeql_having_${context.nextHavingAggregateId}`;
|
|
20404
|
+
context.nextHavingAggregateId += 1;
|
|
20405
|
+
while (havingAggregates.outputAliases.has(alias) || havingAggregates.aggregates[alias] !== void 0) {
|
|
20406
|
+
alias = `__lakeql_having_${context.nextHavingAggregateId}`;
|
|
20407
|
+
context.nextHavingAggregateId += 1;
|
|
20408
|
+
}
|
|
20409
|
+
havingAggregates.aggregates[alias] = spec;
|
|
20410
|
+
havingAggregates.hiddenAggregates.add(alias);
|
|
20411
|
+
return alias;
|
|
20412
|
+
}
|
|
19970
20413
|
function newSqlParseContext(options = {}) {
|
|
19971
20414
|
return {
|
|
19972
20415
|
scalarSubqueries: {},
|
|
20416
|
+
correlatedScalarSubqueries: {},
|
|
19973
20417
|
nextScalarSubqueryId: 0,
|
|
19974
20418
|
windows: {},
|
|
19975
20419
|
nextWindowId: 0,
|
|
20420
|
+
nextHavingAggregateId: 0,
|
|
19976
20421
|
windowFrames: [],
|
|
19977
20422
|
nextWindowFrameId: 0,
|
|
19978
20423
|
...options.parameters === void 0 ? {} : { parameters: options.parameters }
|
|
@@ -20000,13 +20445,19 @@ function exprToLakeql(expr, scope = SqlScope.empty(), context = newSqlParseConte
|
|
|
20000
20445
|
case "case":
|
|
20001
20446
|
return caseToExpr(expr, scope, context);
|
|
20002
20447
|
case "select":
|
|
20003
|
-
return scalarSubqueryToExpr(expr, context);
|
|
20448
|
+
return scalarSubqueryToExpr(expr, scope, context);
|
|
20004
20449
|
case "cast":
|
|
20005
20450
|
return castToExpr(expr, scope, context);
|
|
20006
20451
|
case "call":
|
|
20452
|
+
if (context.havingAggregates !== void 0 && isAggregateCall(expr)) {
|
|
20453
|
+
return { kind: "column", name: registerHavingAggregate(expr, scope, context) };
|
|
20454
|
+
}
|
|
20007
20455
|
if ("over" in expr && expr.over !== void 0) {
|
|
20008
20456
|
return { kind: "column", name: registerSyntheticWindow(expr, scope, context) };
|
|
20009
20457
|
}
|
|
20458
|
+
if (functionName(expr.function) === "exists") {
|
|
20459
|
+
return existsSubqueryToExpr(expr, context);
|
|
20460
|
+
}
|
|
20010
20461
|
return {
|
|
20011
20462
|
kind: "call",
|
|
20012
20463
|
fn: functionName(expr.function),
|
|
@@ -20070,17 +20521,15 @@ function binaryToExpr(expr, scope = SqlScope.empty(), context = newSqlParseConte
|
|
|
20070
20521
|
}
|
|
20071
20522
|
function whereToAst(expr, scope, context) {
|
|
20072
20523
|
const predicates = flattenWhereConjuncts(expr);
|
|
20073
|
-
|
|
20524
|
+
const subqueryJoins = [];
|
|
20074
20525
|
const residual = [];
|
|
20075
20526
|
for (const predicate of predicates) {
|
|
20076
|
-
const extracted = maybeSubqueryJoin(predicate, scope);
|
|
20527
|
+
const extracted = maybeSubqueryJoin(predicate, scope, context);
|
|
20077
20528
|
if (extracted === void 0) {
|
|
20078
20529
|
residual.push(predicate);
|
|
20079
20530
|
continue;
|
|
20080
20531
|
}
|
|
20081
|
-
|
|
20082
|
-
throwUnsupported("Only one IN subquery is supported");
|
|
20083
|
-
subqueryJoin = extracted;
|
|
20532
|
+
subqueryJoins.push(extracted);
|
|
20084
20533
|
}
|
|
20085
20534
|
const out = {};
|
|
20086
20535
|
if (residual.length === 1)
|
|
@@ -20092,35 +20541,159 @@ function whereToAst(expr, scope, context) {
|
|
|
20092
20541
|
operands: residual.map((predicate) => exprToLakeql(predicate, scope, context))
|
|
20093
20542
|
};
|
|
20094
20543
|
}
|
|
20095
|
-
if (
|
|
20096
|
-
out.
|
|
20544
|
+
if (subqueryJoins.length > 0)
|
|
20545
|
+
out.subqueryJoins = subqueryJoins;
|
|
20097
20546
|
return out;
|
|
20098
20547
|
}
|
|
20099
|
-
function maybeSubqueryJoin(expr, scope) {
|
|
20100
|
-
if (expr.type
|
|
20548
|
+
function maybeSubqueryJoin(expr, scope, context) {
|
|
20549
|
+
if (expr.type === "binary") {
|
|
20550
|
+
const scalarAggregateJoin = scalarAggregatePredicateSubqueryJoinToAst(expr, scope, context);
|
|
20551
|
+
if (scalarAggregateJoin !== void 0)
|
|
20552
|
+
return scalarAggregateJoin;
|
|
20553
|
+
const op = String(expr.op).toUpperCase();
|
|
20554
|
+
if (op !== "IN" && op !== "NOT IN")
|
|
20555
|
+
return void 0;
|
|
20556
|
+
const right = asNode(expr.right, "IN right side");
|
|
20557
|
+
if (right.type !== "select")
|
|
20558
|
+
return void 0;
|
|
20559
|
+
return subqueryJoinToAst(asNode(expr.left, "IN left side"), right, scope, op === "NOT IN", context);
|
|
20560
|
+
}
|
|
20561
|
+
const exists = existsCallFromPredicate(expr);
|
|
20562
|
+
if (exists === void 0)
|
|
20101
20563
|
return void 0;
|
|
20564
|
+
return existsSubqueryJoinToAst(exists.call, scope, exists.negated, context);
|
|
20565
|
+
}
|
|
20566
|
+
function scalarAggregatePredicateSubqueryJoinToAst(expr, outerScope, context) {
|
|
20102
20567
|
const op = String(expr.op).toUpperCase();
|
|
20103
|
-
if (
|
|
20568
|
+
if (!["=", "!=", "<>", "<", "<=", ">", ">="].includes(op))
|
|
20569
|
+
return void 0;
|
|
20570
|
+
const left = asNode(expr.left, "scalar aggregate predicate left side");
|
|
20571
|
+
const right = asNode(expr.right, "scalar aggregate predicate right side");
|
|
20572
|
+
const scalarSide = left.type === "select" && right.type !== "select" ? { subquery: left, other: right, subqueryOnLeft: true } : right.type === "select" && left.type !== "select" ? { subquery: right, other: left, subqueryOnLeft: false } : void 0;
|
|
20573
|
+
if (scalarSide === void 0)
|
|
20574
|
+
return void 0;
|
|
20575
|
+
const scalar = scalarAggregateSubqueryToAst(scalarSide.subquery, outerScope, context);
|
|
20576
|
+
if (scalar === void 0)
|
|
20577
|
+
return void 0;
|
|
20578
|
+
const subqueryScope = new SqlScope({
|
|
20579
|
+
source: scalar.source,
|
|
20580
|
+
alias: scalar.alias ?? scalar.source
|
|
20581
|
+
});
|
|
20582
|
+
const aggregate = scalar.aggregates[scalar.column];
|
|
20583
|
+
if (aggregate === void 0)
|
|
20584
|
+
throwUnsupported("Correlated scalar aggregate is missing output");
|
|
20585
|
+
const alias = scalar.alias;
|
|
20586
|
+
const out = {
|
|
20587
|
+
source: scalar.source,
|
|
20588
|
+
type: "semi",
|
|
20589
|
+
leftKey: scalar.leftKey,
|
|
20590
|
+
rightKey: scalar.rightKey,
|
|
20591
|
+
groupBy: scalar.groupBy,
|
|
20592
|
+
aggregates: scalar.aggregates,
|
|
20593
|
+
...scalar.hiddenAggregates === void 0 ? {} : { hiddenAggregates: scalar.hiddenAggregates },
|
|
20594
|
+
...scalar.having === void 0 ? {} : { having: scalar.having },
|
|
20595
|
+
...scalar.leftAlias === void 0 ? {} : { leftAlias: scalar.leftAlias },
|
|
20596
|
+
...alias === void 0 ? {} : { alias },
|
|
20597
|
+
...scalar.where === void 0 ? {} : { where: scalar.where }
|
|
20598
|
+
};
|
|
20599
|
+
const aggregateExpr = {
|
|
20600
|
+
kind: "column",
|
|
20601
|
+
name: alias === void 0 ? scalar.column : `${alias}.${scalar.column}`
|
|
20602
|
+
};
|
|
20603
|
+
const other = exprToLakeql(scalarSide.other, combinedScope(outerScope, subqueryScope), context);
|
|
20604
|
+
out.predicate = {
|
|
20605
|
+
kind: "compare",
|
|
20606
|
+
op: compareOp(op),
|
|
20607
|
+
left: scalarSide.subqueryOnLeft ? aggregateExpr : other,
|
|
20608
|
+
right: scalarSide.subqueryOnLeft ? other : aggregateExpr
|
|
20609
|
+
};
|
|
20610
|
+
return out;
|
|
20611
|
+
}
|
|
20612
|
+
function scalarAggregateSubqueryToAst(subquery, outerScope, context) {
|
|
20613
|
+
const from = optionalArray(subquery.from);
|
|
20614
|
+
if (from.length !== 1)
|
|
20615
|
+
return void 0;
|
|
20616
|
+
const source = sourceTable(from[0]);
|
|
20617
|
+
const subqueryScope = new SqlScope(source);
|
|
20618
|
+
const aggregate = scalarAggregateSelectItem(subquery, subqueryScope, context);
|
|
20619
|
+
if (aggregate === void 0)
|
|
20620
|
+
return void 0;
|
|
20621
|
+
rejectPresent(subquery, "orderBy", "ORDER BY in correlated scalar aggregate subqueries is not supported");
|
|
20622
|
+
rejectPresent(subquery, "limit", "LIMIT in correlated scalar aggregate subqueries is not supported");
|
|
20623
|
+
const out = {
|
|
20624
|
+
source: source.source,
|
|
20625
|
+
leftKey: [],
|
|
20626
|
+
rightKey: [],
|
|
20627
|
+
groupBy: [],
|
|
20628
|
+
aggregates: { [aggregate.alias]: aggregate.spec },
|
|
20629
|
+
column: aggregate.alias
|
|
20630
|
+
};
|
|
20631
|
+
applyCorrelatedSubqueryWhere(out, subquery, outerScope, subqueryScope, context);
|
|
20632
|
+
if (out.leftKey.length === 0) {
|
|
20633
|
+
if (predicateReferencesOuterScope(subquery, outerScope)) {
|
|
20634
|
+
throwUnsupported("Correlated scalar aggregate subqueries require equality correlation keys");
|
|
20635
|
+
}
|
|
20104
20636
|
return void 0;
|
|
20105
|
-
|
|
20106
|
-
if (
|
|
20637
|
+
}
|
|
20638
|
+
if (out.predicate !== void 0) {
|
|
20639
|
+
throwUnsupported("Correlated scalar aggregate subqueries with non-equality predicates are not supported");
|
|
20640
|
+
}
|
|
20641
|
+
if (subquery.groupBy !== void 0) {
|
|
20642
|
+
out.groupBy = optionalArray(subquery.groupBy).map((expr) => subqueryScope.refName(asNode(expr, "scalar aggregate subquery GROUP BY expression")));
|
|
20643
|
+
const rightKeys = new Set(out.rightKey);
|
|
20644
|
+
if (out.groupBy.some((column) => !rightKeys.has(column))) {
|
|
20645
|
+
throwUnsupported("Correlated scalar aggregate subqueries can only group by equality correlation keys");
|
|
20646
|
+
}
|
|
20647
|
+
}
|
|
20648
|
+
out.groupBy = appendUnique(out.groupBy ?? [], out.rightKey);
|
|
20649
|
+
if (subquery.having !== void 0) {
|
|
20650
|
+
const aggregates = out.aggregates ?? {};
|
|
20651
|
+
const hiddenAggregates = /* @__PURE__ */ new Set();
|
|
20652
|
+
const outputAliases = /* @__PURE__ */ new Set([...out.groupBy, aggregate.alias]);
|
|
20653
|
+
out.having = havingToExpr(asNode(subquery.having, "scalar aggregate subquery HAVING"), subqueryScope, context, aggregates, hiddenAggregates, outputAliases);
|
|
20654
|
+
if (Object.keys(aggregates).length > 0)
|
|
20655
|
+
out.aggregates = aggregates;
|
|
20656
|
+
if (hiddenAggregates.size > 0)
|
|
20657
|
+
out.hiddenAggregates = [...hiddenAggregates];
|
|
20658
|
+
}
|
|
20659
|
+
const leftAlias = outerScope.primaryAlias();
|
|
20660
|
+
if (leftAlias !== void 0)
|
|
20661
|
+
out.leftAlias = leftAlias;
|
|
20662
|
+
const alias = subqueryScope.primaryAlias();
|
|
20663
|
+
if (alias !== void 0)
|
|
20664
|
+
out.alias = alias;
|
|
20665
|
+
return out;
|
|
20666
|
+
}
|
|
20667
|
+
function scalarAggregateSelectItem(subquery, scope, context) {
|
|
20668
|
+
const columns = optionalArray(subquery.columns);
|
|
20669
|
+
if (columns.length !== 1) {
|
|
20670
|
+
throwUnsupported("Scalar aggregate subqueries must return exactly one column");
|
|
20671
|
+
}
|
|
20672
|
+
const item = asNode(columns[0], "scalar aggregate subquery select item");
|
|
20673
|
+
const expr = asNode(item.expr, "scalar aggregate subquery select expression");
|
|
20674
|
+
if (expr.type !== "call" || !isAggregateCall(expr))
|
|
20107
20675
|
return void 0;
|
|
20108
|
-
return
|
|
20676
|
+
return {
|
|
20677
|
+
alias: aliasName(item.alias) ?? functionName(expr.function),
|
|
20678
|
+
spec: aggregateCallToSpec(expr, scope, context)
|
|
20679
|
+
};
|
|
20109
20680
|
}
|
|
20110
|
-
function subqueryJoinToAst(left, subquery, outerScope, negated) {
|
|
20111
|
-
rejectPresent(subquery, "groupBy", "Grouped IN subqueries are not supported");
|
|
20112
|
-
rejectPresent(subquery, "having", "HAVING in IN subqueries is not supported");
|
|
20113
|
-
rejectPresent(subquery, "orderBy", "ORDER BY in IN subqueries is not supported");
|
|
20114
|
-
rejectPresent(subquery, "limit", "LIMIT in IN subqueries is not supported");
|
|
20681
|
+
function subqueryJoinToAst(left, subquery, outerScope, negated, context) {
|
|
20115
20682
|
const from = optionalArray(subquery.from);
|
|
20116
20683
|
if (from.length !== 1)
|
|
20117
20684
|
throwUnsupported("IN subqueries must select from one table");
|
|
20118
20685
|
const source = sourceTable(from[0]);
|
|
20119
20686
|
const subqueryScope = new SqlScope(source);
|
|
20687
|
+
const aggregates = {};
|
|
20688
|
+
const hiddenAggregates = /* @__PURE__ */ new Set();
|
|
20689
|
+
const outputAliases = /* @__PURE__ */ new Set();
|
|
20120
20690
|
const leftKey = subqueryLeftKeys(left, outerScope);
|
|
20691
|
+
const directLeftKeyCount = leftKey.length;
|
|
20121
20692
|
const rightKey = optionalArray(subquery.columns).map((column) => {
|
|
20122
20693
|
const item = asNode(column, "IN subquery select item");
|
|
20123
|
-
|
|
20694
|
+
const key = subqueryScope.refName(asNode(item.expr, "IN subquery key"));
|
|
20695
|
+
ensureUniqueOutputAlias(aliasName(item.alias) ?? key, outputAliases);
|
|
20696
|
+
return key;
|
|
20124
20697
|
});
|
|
20125
20698
|
if (leftKey.length !== rightKey.length || leftKey.length === 0) {
|
|
20126
20699
|
throwUnsupported("IN subquery key counts must match");
|
|
@@ -20131,11 +20704,206 @@ function subqueryJoinToAst(left, subquery, outerScope, negated) {
|
|
|
20131
20704
|
leftKey,
|
|
20132
20705
|
rightKey
|
|
20133
20706
|
};
|
|
20134
|
-
|
|
20135
|
-
|
|
20707
|
+
applyCorrelatedSubqueryWhere(out, subquery, outerScope, subqueryScope, context);
|
|
20708
|
+
if ((subquery.groupBy !== void 0 || subquery.having !== void 0) && out.predicate !== void 0) {
|
|
20709
|
+
throwUnsupported("Correlated grouped IN subqueries with non-equality predicates are not supported");
|
|
20710
|
+
}
|
|
20711
|
+
if (subquery.groupBy !== void 0) {
|
|
20712
|
+
out.groupBy = optionalArray(subquery.groupBy).map((expr) => subqueryScope.refName(asNode(expr, "IN subquery GROUP BY expression")));
|
|
20713
|
+
}
|
|
20714
|
+
if (subquery.groupBy !== void 0 || subquery.having !== void 0) {
|
|
20715
|
+
out.groupBy = appendUnique(out.groupBy ?? [], out.rightKey.slice(directLeftKeyCount));
|
|
20716
|
+
}
|
|
20717
|
+
if (subquery.having !== void 0) {
|
|
20718
|
+
out.having = havingToExpr(asNode(subquery.having, "IN subquery HAVING"), subqueryScope, context, aggregates, hiddenAggregates, outputAliases);
|
|
20719
|
+
}
|
|
20720
|
+
if (Object.keys(aggregates).length > 0)
|
|
20721
|
+
out.aggregates = aggregates;
|
|
20722
|
+
if (hiddenAggregates.size > 0)
|
|
20723
|
+
out.hiddenAggregates = [...hiddenAggregates];
|
|
20724
|
+
if (subquery.orderBy !== void 0) {
|
|
20725
|
+
out.orderBy = optionalArray(subquery.orderBy).map((term) => orderByToTerm(term, subqueryScope));
|
|
20726
|
+
}
|
|
20727
|
+
const limit = subquery.limit;
|
|
20728
|
+
if (limit !== void 0) {
|
|
20729
|
+
const node = asNode(limit, "IN subquery LIMIT");
|
|
20730
|
+
if (node.limit !== void 0)
|
|
20731
|
+
out.limit = nonNegativeInteger(node.limit, "LIMIT", context);
|
|
20732
|
+
if (node.offset !== void 0)
|
|
20733
|
+
out.offset = nonNegativeInteger(node.offset, "OFFSET", context);
|
|
20734
|
+
}
|
|
20735
|
+
return out;
|
|
20736
|
+
}
|
|
20737
|
+
function existsCallFromPredicate(expr) {
|
|
20738
|
+
if (expr.type === "call" && functionName(expr.function) === "exists") {
|
|
20739
|
+
return { call: expr, negated: false };
|
|
20740
|
+
}
|
|
20741
|
+
if (expr.type !== "unary" || String(expr.op).toUpperCase() !== "NOT")
|
|
20742
|
+
return void 0;
|
|
20743
|
+
const operand = asNode(expr.operand, "NOT operand");
|
|
20744
|
+
if (operand.type !== "call" || functionName(operand.function) !== "exists")
|
|
20745
|
+
return void 0;
|
|
20746
|
+
return { call: operand, negated: true };
|
|
20747
|
+
}
|
|
20748
|
+
function existsSubqueryJoinToAst(expr, outerScope, negated, context) {
|
|
20749
|
+
const subquery = existsSubquery(expr);
|
|
20750
|
+
rejectPresent(subquery, "orderBy", "ORDER BY in EXISTS subqueries is not supported");
|
|
20751
|
+
rejectPresent(subquery, "limit", "LIMIT in EXISTS subqueries is not supported");
|
|
20752
|
+
const from = optionalArray(subquery.from);
|
|
20753
|
+
if (from.length !== 1)
|
|
20754
|
+
throwUnsupported("EXISTS subqueries must select from one table");
|
|
20755
|
+
const source = sourceTable(from[0]);
|
|
20756
|
+
const subqueryScope = new SqlScope(source);
|
|
20757
|
+
const aggregates = {};
|
|
20758
|
+
const hiddenAggregates = /* @__PURE__ */ new Set();
|
|
20759
|
+
const outputAliases = /* @__PURE__ */ new Set();
|
|
20760
|
+
const out = {
|
|
20761
|
+
source: source.source,
|
|
20762
|
+
type: negated ? "anti" : "semi",
|
|
20763
|
+
leftKey: [],
|
|
20764
|
+
rightKey: []
|
|
20765
|
+
};
|
|
20766
|
+
applyCorrelatedSubqueryWhere(out, subquery, outerScope, subqueryScope, context);
|
|
20767
|
+
if (subquery.groupBy !== void 0 || subquery.having !== void 0) {
|
|
20768
|
+
if (out.predicate !== void 0) {
|
|
20769
|
+
throwUnsupported("Correlated grouped EXISTS subqueries with non-equality predicates are not supported");
|
|
20770
|
+
}
|
|
20771
|
+
if (out.leftKey.length === 0)
|
|
20772
|
+
return void 0;
|
|
20773
|
+
if (subquery.groupBy !== void 0) {
|
|
20774
|
+
out.groupBy = optionalArray(subquery.groupBy).map((expr2) => subqueryScope.refName(asNode(expr2, "EXISTS subquery GROUP BY expression")));
|
|
20775
|
+
}
|
|
20776
|
+
out.groupBy = appendUnique(out.groupBy ?? [], out.rightKey);
|
|
20777
|
+
if (subquery.having !== void 0) {
|
|
20778
|
+
out.having = havingToExpr(asNode(subquery.having, "EXISTS subquery HAVING"), subqueryScope, context, aggregates, hiddenAggregates, outputAliases);
|
|
20779
|
+
}
|
|
20780
|
+
if (Object.keys(aggregates).length > 0)
|
|
20781
|
+
out.aggregates = aggregates;
|
|
20782
|
+
if (hiddenAggregates.size > 0)
|
|
20783
|
+
out.hiddenAggregates = [...hiddenAggregates];
|
|
20784
|
+
return out;
|
|
20785
|
+
}
|
|
20786
|
+
return out.leftKey.length === 0 && out.predicate === void 0 ? void 0 : out;
|
|
20787
|
+
}
|
|
20788
|
+
function appendUnique(values, additions) {
|
|
20789
|
+
const out = [...values];
|
|
20790
|
+
const seen = new Set(out);
|
|
20791
|
+
for (const value2 of additions) {
|
|
20792
|
+
if (seen.has(value2))
|
|
20793
|
+
continue;
|
|
20794
|
+
seen.add(value2);
|
|
20795
|
+
out.push(value2);
|
|
20136
20796
|
}
|
|
20137
20797
|
return out;
|
|
20138
20798
|
}
|
|
20799
|
+
function existsSubquery(expr) {
|
|
20800
|
+
const args = optionalArray(expr.args);
|
|
20801
|
+
if (args.length !== 1)
|
|
20802
|
+
throwUnsupported("EXISTS requires exactly one subquery");
|
|
20803
|
+
const subquery = asNode(args[0], "EXISTS subquery");
|
|
20804
|
+
if (subquery.type !== "select")
|
|
20805
|
+
throwUnsupported("EXISTS requires a SELECT subquery");
|
|
20806
|
+
return subquery;
|
|
20807
|
+
}
|
|
20808
|
+
function applyCorrelatedSubqueryWhere(out, subquery, outerScope, subqueryScope, context) {
|
|
20809
|
+
if (subquery.where === void 0)
|
|
20810
|
+
return;
|
|
20811
|
+
const residual = [];
|
|
20812
|
+
const correlated = [];
|
|
20813
|
+
for (const predicate of flattenWhereConjuncts(asNode(subquery.where, "subquery WHERE"))) {
|
|
20814
|
+
const pair = correlatedJoinKeyPair(predicate, outerScope, subqueryScope);
|
|
20815
|
+
if (pair === void 0) {
|
|
20816
|
+
if (predicateReferencesOuterScope(predicate, outerScope)) {
|
|
20817
|
+
correlated.push(predicate);
|
|
20818
|
+
continue;
|
|
20819
|
+
}
|
|
20820
|
+
residual.push(predicate);
|
|
20821
|
+
continue;
|
|
20822
|
+
}
|
|
20823
|
+
out.leftKey.push(pair.leftKey);
|
|
20824
|
+
out.rightKey.push(pair.rightKey);
|
|
20825
|
+
}
|
|
20826
|
+
if (correlated.length === 1) {
|
|
20827
|
+
const leftAlias = outerScope.primaryAlias();
|
|
20828
|
+
if (leftAlias !== void 0)
|
|
20829
|
+
out.leftAlias = leftAlias;
|
|
20830
|
+
const alias = subqueryScope.primaryAlias();
|
|
20831
|
+
if (alias !== void 0)
|
|
20832
|
+
out.alias = alias;
|
|
20833
|
+
out.predicate = exprToLakeql(correlated[0], combinedScope(outerScope, subqueryScope), context);
|
|
20834
|
+
} else if (correlated.length > 1) {
|
|
20835
|
+
const leftAlias = outerScope.primaryAlias();
|
|
20836
|
+
if (leftAlias !== void 0)
|
|
20837
|
+
out.leftAlias = leftAlias;
|
|
20838
|
+
const alias = subqueryScope.primaryAlias();
|
|
20839
|
+
if (alias !== void 0)
|
|
20840
|
+
out.alias = alias;
|
|
20841
|
+
out.predicate = {
|
|
20842
|
+
kind: "logical",
|
|
20843
|
+
op: "and",
|
|
20844
|
+
operands: correlated.map((predicate) => exprToLakeql(predicate, combinedScope(outerScope, subqueryScope), context))
|
|
20845
|
+
};
|
|
20846
|
+
}
|
|
20847
|
+
if (residual.length === 1) {
|
|
20848
|
+
out.where = exprToLakeql(residual[0], subqueryScope, context);
|
|
20849
|
+
} else if (residual.length > 1) {
|
|
20850
|
+
out.where = {
|
|
20851
|
+
kind: "logical",
|
|
20852
|
+
op: "and",
|
|
20853
|
+
operands: residual.map((predicate) => exprToLakeql(predicate, subqueryScope, context))
|
|
20854
|
+
};
|
|
20855
|
+
}
|
|
20856
|
+
}
|
|
20857
|
+
function combinedScope(left, right) {
|
|
20858
|
+
const scope = SqlScope.empty();
|
|
20859
|
+
for (const source of left.sources())
|
|
20860
|
+
scope.add(source);
|
|
20861
|
+
for (const source of right.sources())
|
|
20862
|
+
scope.add(source);
|
|
20863
|
+
return scope;
|
|
20864
|
+
}
|
|
20865
|
+
function predicateReferencesOuterScope(predicate, outerScope) {
|
|
20866
|
+
let found = false;
|
|
20867
|
+
visitPgRefs(predicate, (ref) => {
|
|
20868
|
+
if (outerScope.qualifiedRefName(ref) !== void 0)
|
|
20869
|
+
found = true;
|
|
20870
|
+
});
|
|
20871
|
+
return found;
|
|
20872
|
+
}
|
|
20873
|
+
function visitPgRefs(value2, visit) {
|
|
20874
|
+
if (!isRecord4(value2))
|
|
20875
|
+
return;
|
|
20876
|
+
if (value2.type === "ref")
|
|
20877
|
+
visit(value2);
|
|
20878
|
+
for (const child of Object.values(value2)) {
|
|
20879
|
+
if (Array.isArray(child)) {
|
|
20880
|
+
for (const item of child)
|
|
20881
|
+
visitPgRefs(item, visit);
|
|
20882
|
+
} else {
|
|
20883
|
+
visitPgRefs(child, visit);
|
|
20884
|
+
}
|
|
20885
|
+
}
|
|
20886
|
+
}
|
|
20887
|
+
function isRecord4(value2) {
|
|
20888
|
+
return typeof value2 === "object" && value2 !== null;
|
|
20889
|
+
}
|
|
20890
|
+
function correlatedJoinKeyPair(predicate, outerScope, subqueryScope) {
|
|
20891
|
+
if (predicate.type !== "binary" || String(predicate.op) !== "=")
|
|
20892
|
+
return void 0;
|
|
20893
|
+
const left = asNode(predicate.left, "correlated left key");
|
|
20894
|
+
const right = asNode(predicate.right, "correlated right key");
|
|
20895
|
+
const leftOuter = outerScope.qualifiedRefName(left);
|
|
20896
|
+
const leftSubquery = subqueryScope.qualifiedRefName(left);
|
|
20897
|
+
const rightOuter = outerScope.qualifiedRefName(right);
|
|
20898
|
+
const rightSubquery = subqueryScope.qualifiedRefName(right);
|
|
20899
|
+
if (leftOuter !== void 0 && rightSubquery !== void 0) {
|
|
20900
|
+
return { leftKey: leftOuter, rightKey: rightSubquery };
|
|
20901
|
+
}
|
|
20902
|
+
if (rightOuter !== void 0 && leftSubquery !== void 0) {
|
|
20903
|
+
return { leftKey: rightOuter, rightKey: leftSubquery };
|
|
20904
|
+
}
|
|
20905
|
+
return void 0;
|
|
20906
|
+
}
|
|
20139
20907
|
function subqueryLeftKeys(expr, scope) {
|
|
20140
20908
|
if (expr.type === "list") {
|
|
20141
20909
|
return optionalArray(expr.expressions).map((value2) => scope.refName(asNode(value2, "IN left key")));
|
|
@@ -20151,7 +20919,10 @@ function flattenWhereConjuncts(expr) {
|
|
|
20151
20919
|
}
|
|
20152
20920
|
return [expr];
|
|
20153
20921
|
}
|
|
20154
|
-
function scalarSubqueryToExpr(subquery, context) {
|
|
20922
|
+
function scalarSubqueryToExpr(subquery, outerScope, context) {
|
|
20923
|
+
const correlated = scalarAggregateSubqueryToAst(subquery, outerScope, context);
|
|
20924
|
+
if (correlated !== void 0)
|
|
20925
|
+
return registerCorrelatedScalarSubquery(correlated, context);
|
|
20155
20926
|
const query = selectStatementToAst(subquery, context);
|
|
20156
20927
|
const outputColumns = scalarSubqueryOutputColumns(query);
|
|
20157
20928
|
if (outputColumns.length !== 1) {
|
|
@@ -20160,9 +20931,72 @@ function scalarSubqueryToExpr(subquery, context) {
|
|
|
20160
20931
|
if (query.aggregates === void 0 && query.limit !== 1) {
|
|
20161
20932
|
throwUnsupported("Scalar subqueries must be aggregate queries or use LIMIT 1");
|
|
20162
20933
|
}
|
|
20934
|
+
return registerScalarSubquery(query, outputColumns[0], context);
|
|
20935
|
+
}
|
|
20936
|
+
function existsSubqueryToExpr(expr, context) {
|
|
20937
|
+
const subquery = existsSubquery(expr);
|
|
20938
|
+
rejectPresent(subquery, "orderBy", "ORDER BY in EXISTS subqueries is not supported");
|
|
20939
|
+
rejectPresent(subquery, "limit", "LIMIT in EXISTS subqueries is not supported");
|
|
20940
|
+
rejectPresent(subquery, "windows", "Window functions in EXISTS subqueries are not supported");
|
|
20941
|
+
const from = optionalArray(subquery.from);
|
|
20942
|
+
if (from.length !== 1)
|
|
20943
|
+
throwUnsupported("EXISTS subqueries must select from one table");
|
|
20944
|
+
const source = sourceTable(from[0]);
|
|
20945
|
+
if (subquery.groupBy !== void 0 || subquery.having !== void 0) {
|
|
20946
|
+
return registerExistsSubquery(groupedExistsSubqueryToAst(subquery, source, context), context);
|
|
20947
|
+
}
|
|
20948
|
+
const query = {
|
|
20949
|
+
source: source.source,
|
|
20950
|
+
aggregates: { __lakeql_exists_count: { op: "count" } }
|
|
20951
|
+
};
|
|
20952
|
+
if (subquery.where !== void 0) {
|
|
20953
|
+
query.where = exprToLakeql(asNode(subquery.where, "EXISTS subquery WHERE"), new SqlScope(source), context);
|
|
20954
|
+
}
|
|
20955
|
+
const count = registerScalarSubquery(query, "__lakeql_exists_count", context);
|
|
20956
|
+
return { kind: "compare", op: "gt", left: count, right: literal2(0) };
|
|
20957
|
+
}
|
|
20958
|
+
function groupedExistsSubqueryToAst(subquery, source, context) {
|
|
20959
|
+
const scope = new SqlScope(source);
|
|
20960
|
+
const query = { source: source.source };
|
|
20961
|
+
if (subquery.where !== void 0) {
|
|
20962
|
+
query.where = exprToLakeql(asNode(subquery.where, "EXISTS subquery WHERE"), scope, context);
|
|
20963
|
+
}
|
|
20964
|
+
if (subquery.groupBy !== void 0) {
|
|
20965
|
+
query.groupBy = optionalArray(subquery.groupBy).map((expr) => scope.refName(asNode(expr, "EXISTS subquery GROUP BY expression")));
|
|
20966
|
+
query.select = query.groupBy;
|
|
20967
|
+
}
|
|
20968
|
+
const aggregates = {};
|
|
20969
|
+
const hiddenAggregates = /* @__PURE__ */ new Set();
|
|
20970
|
+
const outputAliases = new Set(query.select ?? []);
|
|
20971
|
+
if (subquery.having !== void 0) {
|
|
20972
|
+
query.having = havingToExpr(asNode(subquery.having, "EXISTS subquery HAVING"), scope, context, aggregates, hiddenAggregates, outputAliases);
|
|
20973
|
+
}
|
|
20974
|
+
if (Object.keys(aggregates).length > 0)
|
|
20975
|
+
query.aggregates = aggregates;
|
|
20976
|
+
if (hiddenAggregates.size > 0)
|
|
20977
|
+
query.hiddenAggregates = [...hiddenAggregates];
|
|
20978
|
+
return query;
|
|
20979
|
+
}
|
|
20980
|
+
function registerScalarSubquery(query, column, context) {
|
|
20163
20981
|
const id = `scalar_${context.nextScalarSubqueryId}`;
|
|
20164
20982
|
context.nextScalarSubqueryId += 1;
|
|
20165
|
-
context.scalarSubqueries[id] = { query, column
|
|
20983
|
+
context.scalarSubqueries[id] = { query, column };
|
|
20984
|
+
return { kind: "call", fn: "__lakeql_scalar_subquery", args: [{ kind: "literal", value: id }] };
|
|
20985
|
+
}
|
|
20986
|
+
function registerCorrelatedScalarSubquery(query, context) {
|
|
20987
|
+
const id = `correlated_scalar_${context.nextScalarSubqueryId}`;
|
|
20988
|
+
context.nextScalarSubqueryId += 1;
|
|
20989
|
+
context.correlatedScalarSubqueries[id] = query;
|
|
20990
|
+
return {
|
|
20991
|
+
kind: "call",
|
|
20992
|
+
fn: "__lakeql_correlated_scalar_subquery",
|
|
20993
|
+
args: [{ kind: "literal", value: id }]
|
|
20994
|
+
};
|
|
20995
|
+
}
|
|
20996
|
+
function registerExistsSubquery(query, context) {
|
|
20997
|
+
const id = `scalar_${context.nextScalarSubqueryId}`;
|
|
20998
|
+
context.nextScalarSubqueryId += 1;
|
|
20999
|
+
context.scalarSubqueries[id] = { query, column: "__lakeql_exists", mode: "exists" };
|
|
20166
21000
|
return { kind: "call", fn: "__lakeql_scalar_subquery", args: [{ kind: "literal", value: id }] };
|
|
20167
21001
|
}
|
|
20168
21002
|
function scalarSubqueryOutputColumns(query) {
|
|
@@ -20187,13 +21021,12 @@ function unaryToExpr(expr, scope = SqlScope.empty(), context = newSqlParseContex
|
|
|
20187
21021
|
throwUnsupported(`Unsupported unary operator ${op}`);
|
|
20188
21022
|
}
|
|
20189
21023
|
function caseToExpr(expr, scope = SqlScope.empty(), context = newSqlParseContext()) {
|
|
20190
|
-
|
|
20191
|
-
throwUnsupported("Simple CASE expressions are not supported yet");
|
|
20192
|
-
}
|
|
21024
|
+
const caseValue = expr.value === null || expr.value === void 0 ? void 0 : exprToLakeql(asNode(expr.value, "CASE expression"), scope, context);
|
|
20193
21025
|
const whens = optionalArray(expr.whens).map((branch) => {
|
|
20194
21026
|
const node = asNode(branch, "CASE branch");
|
|
21027
|
+
const when = exprToLakeql(asNode(node.when, "CASE WHEN expression"), scope, context);
|
|
20195
21028
|
return {
|
|
20196
|
-
when:
|
|
21029
|
+
when: caseValue === void 0 ? when : { kind: "compare", op: "eq", left: caseValue, right: when },
|
|
20197
21030
|
value: exprToLakeql(asNode(node.value, "CASE THEN expression"), scope, context)
|
|
20198
21031
|
};
|
|
20199
21032
|
});
|
|
@@ -20201,8 +21034,71 @@ function caseToExpr(expr, scope = SqlScope.empty(), context = newSqlParseContext
|
|
|
20201
21034
|
if (expr.else !== void 0) {
|
|
20202
21035
|
out.else = exprToLakeql(asNode(expr.else, "CASE ELSE expression"), scope, context);
|
|
20203
21036
|
}
|
|
21037
|
+
validateCaseResultTypes(out);
|
|
20204
21038
|
return out;
|
|
20205
21039
|
}
|
|
21040
|
+
function validateCaseResultTypes(expr) {
|
|
21041
|
+
const resultTypes = caseResultTypes(expr);
|
|
21042
|
+
if (resultTypes.size <= 1)
|
|
21043
|
+
return;
|
|
21044
|
+
throwType("CASE result branches must have compatible literal types", {
|
|
21045
|
+
types: [...resultTypes].sort()
|
|
21046
|
+
});
|
|
21047
|
+
}
|
|
21048
|
+
function caseResultTypes(expr) {
|
|
21049
|
+
const types = /* @__PURE__ */ new Set();
|
|
21050
|
+
for (const branch of expr.whens) {
|
|
21051
|
+
const type = staticExprResultType(branch.value);
|
|
21052
|
+
if (type !== void 0)
|
|
21053
|
+
types.add(type);
|
|
21054
|
+
}
|
|
21055
|
+
if (expr.else !== void 0) {
|
|
21056
|
+
const type = staticExprResultType(expr.else);
|
|
21057
|
+
if (type !== void 0)
|
|
21058
|
+
types.add(type);
|
|
21059
|
+
}
|
|
21060
|
+
return types;
|
|
21061
|
+
}
|
|
21062
|
+
function staticExprResultType(expr) {
|
|
21063
|
+
switch (expr.kind) {
|
|
21064
|
+
case "literal":
|
|
21065
|
+
return staticScalarType(expr.value);
|
|
21066
|
+
case "compare":
|
|
21067
|
+
case "between":
|
|
21068
|
+
case "in":
|
|
21069
|
+
case "like":
|
|
21070
|
+
case "logical":
|
|
21071
|
+
case "not":
|
|
21072
|
+
case "null-check":
|
|
21073
|
+
return "boolean";
|
|
21074
|
+
case "arithmetic":
|
|
21075
|
+
return "number";
|
|
21076
|
+
case "case": {
|
|
21077
|
+
const resultTypes = caseResultTypes(expr);
|
|
21078
|
+
return resultTypes.size === 1 ? [...resultTypes][0] : void 0;
|
|
21079
|
+
}
|
|
21080
|
+
case "call":
|
|
21081
|
+
case "column":
|
|
21082
|
+
return void 0;
|
|
21083
|
+
}
|
|
21084
|
+
}
|
|
21085
|
+
function staticScalarType(value2) {
|
|
21086
|
+
if (value2 === null)
|
|
21087
|
+
return void 0;
|
|
21088
|
+
if (value2 instanceof Uint8Array)
|
|
21089
|
+
return "binary";
|
|
21090
|
+
if (isTimestampValue(value2))
|
|
21091
|
+
return "timestamp";
|
|
21092
|
+
if (isIntervalValue(value2))
|
|
21093
|
+
return "interval";
|
|
21094
|
+
if (typeof value2 === "boolean")
|
|
21095
|
+
return "boolean";
|
|
21096
|
+
if (typeof value2 === "bigint")
|
|
21097
|
+
return "bigint";
|
|
21098
|
+
if (typeof value2 === "number")
|
|
21099
|
+
return "number";
|
|
21100
|
+
return "string";
|
|
21101
|
+
}
|
|
20206
21102
|
function ternaryToExpr(expr, scope = SqlScope.empty(), context = newSqlParseContext()) {
|
|
20207
21103
|
const op = String(expr.op).toUpperCase();
|
|
20208
21104
|
if (op !== "BETWEEN" && op !== "NOT BETWEEN") {
|
|
@@ -20478,7 +21374,7 @@ function isAggregateCall(expr) {
|
|
|
20478
21374
|
return false;
|
|
20479
21375
|
return aggregateOpOrUndefined(functionName(expr.function)) !== void 0;
|
|
20480
21376
|
}
|
|
20481
|
-
function
|
|
21377
|
+
function isAggregateOp2(op) {
|
|
20482
21378
|
return [
|
|
20483
21379
|
"count",
|
|
20484
21380
|
"sum",
|
|
@@ -20529,31 +21425,66 @@ var SqlScope = class _SqlScope {
|
|
|
20529
21425
|
this.aliases.set(source.source, source);
|
|
20530
21426
|
this.aliases.set(source.alias, source);
|
|
20531
21427
|
}
|
|
21428
|
+
sources() {
|
|
21429
|
+
return [...new Set(this.aliases.values())];
|
|
21430
|
+
}
|
|
21431
|
+
primaryAlias() {
|
|
21432
|
+
return this.sources()[0]?.alias;
|
|
21433
|
+
}
|
|
20532
21434
|
refName(expr) {
|
|
21435
|
+
const name = this.resolveQualifiedRefName(expr, true);
|
|
21436
|
+
if (name !== void 0)
|
|
21437
|
+
return name;
|
|
21438
|
+
if (expr.type !== "ref" || typeof expr.name !== "string") {
|
|
21439
|
+
throwUnsupported("Only column references are supported here");
|
|
21440
|
+
}
|
|
21441
|
+
const qualifier = expr.table === void 0 ? "" : nameNodeToString(expr.table);
|
|
21442
|
+
throwUnsupported(`Unknown SQL table qualifier ${qualifier}`);
|
|
21443
|
+
}
|
|
21444
|
+
qualifiedRefName(expr) {
|
|
21445
|
+
if (expr.type !== "ref" || typeof expr.name !== "string")
|
|
21446
|
+
return void 0;
|
|
21447
|
+
return this.resolveQualifiedRefName(expr, false);
|
|
21448
|
+
}
|
|
21449
|
+
resolveQualifiedRefName(expr, allowUnqualified) {
|
|
20533
21450
|
if (expr.type !== "ref" || typeof expr.name !== "string") {
|
|
20534
21451
|
throwUnsupported("Only column references are supported here");
|
|
20535
21452
|
}
|
|
20536
21453
|
if (expr.table === void 0)
|
|
20537
|
-
return expr.name;
|
|
21454
|
+
return allowUnqualified ? expr.name : void 0;
|
|
20538
21455
|
const qualifier = nameNodeToString(expr.table);
|
|
20539
21456
|
const source = this.aliases.get(qualifier);
|
|
20540
21457
|
if (source === void 0)
|
|
20541
|
-
|
|
21458
|
+
return void 0;
|
|
20542
21459
|
if (this.aliases.size <= 2)
|
|
20543
21460
|
return expr.name;
|
|
20544
21461
|
return `${source.alias}.${expr.name}`;
|
|
20545
21462
|
}
|
|
20546
21463
|
};
|
|
20547
|
-
function sourceTable(value2) {
|
|
21464
|
+
function sourceTable(value2, context) {
|
|
20548
21465
|
const node = asNode(value2, "FROM item");
|
|
20549
21466
|
if (node.type === "call")
|
|
20550
21467
|
return readParquetSourceTable(node);
|
|
21468
|
+
if (node.type === "statement")
|
|
21469
|
+
return derivedSourceTable(node, context);
|
|
20551
21470
|
if (node.type !== "table")
|
|
20552
21471
|
throwUnsupported("Only table FROM sources are supported");
|
|
20553
21472
|
if (node.join !== void 0)
|
|
20554
21473
|
throwUnsupported("Unexpected JOIN position");
|
|
20555
21474
|
const source = nameNodeToString(node.name);
|
|
20556
|
-
return { source, alias: aliasName(node.name) ?? source };
|
|
21475
|
+
return { source, alias: aliasName(node.alias) ?? aliasName(node.name) ?? source };
|
|
21476
|
+
}
|
|
21477
|
+
function derivedSourceTable(node, context) {
|
|
21478
|
+
if (context === void 0)
|
|
21479
|
+
throwUnsupported("Derived tables are not supported here");
|
|
21480
|
+
const alias = aliasName(node.alias);
|
|
21481
|
+
if (alias === void 0)
|
|
21482
|
+
throwUnsupported("Derived tables require an alias");
|
|
21483
|
+
const statement = asNode(node.statement, "derived table SELECT");
|
|
21484
|
+
if (statement.type !== "select")
|
|
21485
|
+
throwUnsupported("Derived tables must be SELECT statements");
|
|
21486
|
+
const query = selectStatementToAst(statement, context);
|
|
21487
|
+
return { source: alias, alias, cte: { name: alias, query } };
|
|
20557
21488
|
}
|
|
20558
21489
|
function readParquetSourceTable(node) {
|
|
20559
21490
|
const functionName2 = nameNodeToString(node.function).toLowerCase();
|
|
@@ -20569,74 +21500,120 @@ function readParquetSourceTable(node) {
|
|
|
20569
21500
|
}
|
|
20570
21501
|
return { source: arg.value, alias: aliasName(node.alias) ?? arg.value };
|
|
20571
21502
|
}
|
|
20572
|
-
function joinToAst(value2,
|
|
21503
|
+
function joinToAst(value2, joinedSources) {
|
|
20573
21504
|
const node = asNode(value2, "JOIN source");
|
|
20574
21505
|
if (node.type !== "table" && node.type !== "call") {
|
|
20575
21506
|
throwUnsupported("Only table JOIN sources are supported");
|
|
20576
21507
|
}
|
|
20577
|
-
const join = asNode(node.join, "JOIN");
|
|
20578
|
-
const joinType = String(join.type).toUpperCase();
|
|
20579
|
-
if (
|
|
21508
|
+
const join = node.join === void 0 ? void 0 : asNode(node.join, "JOIN");
|
|
21509
|
+
const joinType = join === void 0 ? "" : String(join.type).toUpperCase();
|
|
21510
|
+
if (join === void 0 || joinType === "CROSS JOIN") {
|
|
21511
|
+
const right2 = sourceTable({ ...node, join: void 0 });
|
|
21512
|
+
const left2 = joinedSources[0];
|
|
21513
|
+
if (left2 === void 0)
|
|
21514
|
+
throwUnsupported("JOIN requires a left source");
|
|
21515
|
+
return {
|
|
21516
|
+
right: right2,
|
|
21517
|
+
join: {
|
|
21518
|
+
source: right2.source,
|
|
21519
|
+
leftAlias: left2.alias,
|
|
21520
|
+
alias: right2.alias,
|
|
21521
|
+
type: "cross",
|
|
21522
|
+
leftKey: [],
|
|
21523
|
+
rightKey: []
|
|
21524
|
+
}
|
|
21525
|
+
};
|
|
21526
|
+
}
|
|
21527
|
+
if (joinType !== "INNER JOIN" && joinType !== "LEFT JOIN" && joinType !== "RIGHT JOIN" && joinType !== "FULL JOIN") {
|
|
20580
21528
|
throwUnsupported(`Unsupported JOIN type ${joinType}`);
|
|
20581
21529
|
}
|
|
20582
21530
|
const right = sourceTable({ ...node, join: void 0 });
|
|
21531
|
+
const left = joinedSources[0];
|
|
21532
|
+
if (left === void 0)
|
|
21533
|
+
throwUnsupported("JOIN requires a left source");
|
|
20583
21534
|
if (join.using !== void 0) {
|
|
20584
21535
|
const using = optionalArray(join.using);
|
|
20585
21536
|
if (using.length === 0)
|
|
20586
21537
|
throwUnsupported("JOIN USING requires at least one column");
|
|
20587
|
-
const
|
|
21538
|
+
const keys2 = using.map(nameNodeToString);
|
|
20588
21539
|
return {
|
|
20589
|
-
|
|
20590
|
-
|
|
20591
|
-
|
|
20592
|
-
|
|
20593
|
-
|
|
20594
|
-
|
|
21540
|
+
right,
|
|
21541
|
+
join: {
|
|
21542
|
+
source: right.source,
|
|
21543
|
+
leftAlias: left.alias,
|
|
21544
|
+
alias: right.alias,
|
|
21545
|
+
type: sqlJoinType(joinType),
|
|
21546
|
+
leftKey: keys2.map((key) => `${left.alias}.${key}`),
|
|
21547
|
+
rightKey: keys2.map((key) => `${right.alias}.${key}`)
|
|
21548
|
+
}
|
|
20595
21549
|
};
|
|
20596
21550
|
}
|
|
20597
21551
|
const on = asNode(join.on, "JOIN ON");
|
|
20598
|
-
const
|
|
21552
|
+
const keys = joinKeysFromPredicate(on, joinedSources, right);
|
|
20599
21553
|
return {
|
|
20600
|
-
|
|
20601
|
-
|
|
20602
|
-
|
|
20603
|
-
|
|
20604
|
-
|
|
20605
|
-
|
|
21554
|
+
right,
|
|
21555
|
+
join: {
|
|
21556
|
+
source: right.source,
|
|
21557
|
+
leftAlias: left.alias,
|
|
21558
|
+
alias: right.alias,
|
|
21559
|
+
type: sqlJoinType(joinType),
|
|
21560
|
+
leftKey: keys?.leftKey ?? [],
|
|
21561
|
+
rightKey: keys?.rightKey ?? [],
|
|
21562
|
+
...keys === void 0 ? { predicate: exprToLakeql(on, joinScope(joinedSources, right)) } : {}
|
|
21563
|
+
}
|
|
20606
21564
|
};
|
|
20607
21565
|
}
|
|
20608
|
-
function
|
|
20609
|
-
if (
|
|
20610
|
-
|
|
20611
|
-
|
|
21566
|
+
function sqlJoinType(joinType) {
|
|
21567
|
+
if (joinType === "LEFT JOIN")
|
|
21568
|
+
return "left";
|
|
21569
|
+
if (joinType === "RIGHT JOIN")
|
|
21570
|
+
return "right";
|
|
21571
|
+
if (joinType === "FULL JOIN")
|
|
21572
|
+
return "full";
|
|
21573
|
+
return "inner";
|
|
21574
|
+
}
|
|
21575
|
+
function maybeQualifiedJoinKey(expr, joinedSources, right) {
|
|
21576
|
+
if (expr.type !== "ref" || typeof expr.name !== "string" || expr.table === void 0)
|
|
21577
|
+
return void 0;
|
|
20612
21578
|
const qualifier = nameNodeToString(expr.table);
|
|
20613
|
-
if (qualifier ===
|
|
20614
|
-
return `${
|
|
20615
|
-
|
|
20616
|
-
|
|
20617
|
-
|
|
21579
|
+
if (qualifier === right.alias || qualifier === right.source) {
|
|
21580
|
+
return { side: "right", key: `${right.alias}.${expr.name}` };
|
|
21581
|
+
}
|
|
21582
|
+
const left = joinedSources.find((source) => qualifier === source.alias || qualifier === source.source);
|
|
21583
|
+
if (left !== void 0)
|
|
21584
|
+
return { side: "left", key: `${left.alias}.${expr.name}` };
|
|
21585
|
+
return void 0;
|
|
20618
21586
|
}
|
|
20619
|
-
function joinKeysFromPredicate(expr,
|
|
21587
|
+
function joinKeysFromPredicate(expr, joinedSources, right) {
|
|
20620
21588
|
const conjuncts2 = flattenJoinConjuncts(expr);
|
|
20621
21589
|
const leftKey = [];
|
|
20622
21590
|
const rightKey = [];
|
|
20623
21591
|
for (const conjunct of conjuncts2) {
|
|
20624
|
-
if (String(conjunct.op) !== "=")
|
|
20625
|
-
|
|
20626
|
-
const first =
|
|
20627
|
-
const second =
|
|
20628
|
-
if (first
|
|
20629
|
-
|
|
20630
|
-
|
|
20631
|
-
|
|
20632
|
-
|
|
20633
|
-
|
|
21592
|
+
if (conjunct.type !== "binary" || String(conjunct.op) !== "=")
|
|
21593
|
+
return void 0;
|
|
21594
|
+
const first = maybeQualifiedJoinKey(asNode(conjunct.left, "JOIN left key"), joinedSources, right);
|
|
21595
|
+
const second = maybeQualifiedJoinKey(asNode(conjunct.right, "JOIN right key"), joinedSources, right);
|
|
21596
|
+
if (first === void 0 || second === void 0)
|
|
21597
|
+
return void 0;
|
|
21598
|
+
if (first.side === "left" && second.side === "right") {
|
|
21599
|
+
leftKey.push(first.key);
|
|
21600
|
+
rightKey.push(second.key);
|
|
21601
|
+
} else if (second.side === "left" && first.side === "right") {
|
|
21602
|
+
leftKey.push(second.key);
|
|
21603
|
+
rightKey.push(first.key);
|
|
20634
21604
|
} else {
|
|
20635
21605
|
throwUnsupported("JOIN ON must compare left table key to right table key");
|
|
20636
21606
|
}
|
|
20637
21607
|
}
|
|
20638
21608
|
return { leftKey, rightKey };
|
|
20639
21609
|
}
|
|
21610
|
+
function joinScope(joinedSources, right) {
|
|
21611
|
+
const scope = SqlScope.empty();
|
|
21612
|
+
for (const source of joinedSources)
|
|
21613
|
+
scope.add(source);
|
|
21614
|
+
scope.add(right);
|
|
21615
|
+
return scope;
|
|
21616
|
+
}
|
|
20640
21617
|
function flattenJoinConjuncts(expr) {
|
|
20641
21618
|
if (expr.type === "binary" && String(expr.op).toUpperCase() === "AND") {
|
|
20642
21619
|
return [
|
|
@@ -20734,7 +21711,7 @@ function aggregateOp(op) {
|
|
|
20734
21711
|
throwUnsupported(`Unsupported aggregate ${op}`);
|
|
20735
21712
|
}
|
|
20736
21713
|
function aggregateOpOrUndefined(op) {
|
|
20737
|
-
if (
|
|
21714
|
+
if (isAggregateOp2(op))
|
|
20738
21715
|
return op;
|
|
20739
21716
|
if (op === "var" || op === "variance")
|
|
20740
21717
|
return "var_samp";
|
|
@@ -20800,4 +21777,4 @@ function throwType(message, details) {
|
|
|
20800
21777
|
throw new LakeqlError("LAKEQL_TYPE_ERROR", message, details);
|
|
20801
21778
|
}
|
|
20802
21779
|
|
|
20803
|
-
export { AggregationBuilder, CacheApiCache, Lake, MemoryCache, MemoryObjectStore, MemorySpillAdapter, ParquetScanAdapter, QueryBuilder, QueryResult, ResumedQuery, SharedMemoryCache, add, aggregateParquetGroupTask, aggregateParquetGroupTasks, aggregateParquetGroupTasksBatch, aggregateParquetTask, aggregateParquetTasks, and, asyncBufferFromStore, batchExprValues, batchFromColumns, batchFromVectors, bboxMayIntersect, between, broadcastJoin, buildBBoxIndex, buildMinMaxIndex, cacheApiCache, cachedObjectStore, classifyPredicate, col, concatBatches, createParquetLake, createParquetTableAs, createVectorAggregateStates, createVectorGroupByState, deserializeAggregateOperatorState, deserializeSortOperatorState, deserializeTopKOperatorState, deserializeWindowOperatorState, div, enforceVectorGroupByBudget, eq, evaluateWindowWorkUnitPartials, fanInWorkUnits, finalizeVectorAggregateStates, finalizeVectorGroupByBatch, finalizeVectorGroupByRows, fn, gatherBatch, getOrCreateVectorGroup, gt, gte, ilike, isIn, isNotNull, isNull, jsonWorkUnitBoundary, like, lit, lookupJoin, lt, lte, materializeBatchRow, materializeBatchRows, materializeSelectedBatchRows, memoryCache, memorySpillAdapter, memoryStore, mergeVectorAggregateStateSnapshots, mergeVectorAggregateStates, mergeVectorGroupByStates, mod, mul, ne, not, notIn, or, parquetScanner, parseHivePartitions, parseJsonQuery, parseSql, parseSqlStatement, partitionWindowWorkUnitRows, partitionedParquetOutputEntries, planParquetTaskWorkUnits, planRowGroups, planRowGroupsFromMetadata, predicateSelection, pruneFilesWithIndex, readControlSignal, readIcebergParquetDeletes, readParquetColumnBatches, readParquetMetadata, readParquetObjectBatches, readParquetObjects, rejectUnsupportedParquetSchema, restoreVectorAggregateStates, restoreVectorGroupByState, rowGroupMayMatch, rowGroupMustMatch, scalarVectorValue, scanParquetTaskBatches, scanParquetTaskColumnBatches, selectedRowCount, selectedRowIndices, serializeAggregateOperatorState, serializeSortOperatorState, serializeTopKOperatorState, serializeWindowOperatorState, snapshotVectorAggregateStates, snapshotVectorGroupByState, sub, throwIfAborted, tryPredicateSelection, updateVectorAggregateStateValue, updateVectorAggregateStates, updateVectorGroupAggregateValue, updateVectorGroupByState, uriObjectStore, vectorAggregateBatch, vectorFromValues, vectorGroupByBatch, vectorLength, vectorOrderByBatch, vectorProjectBatch, vectorSortIndices, vectorTopKBatch, vectorTopKIndices, vectorValue, windowOperatorState, windowOperatorStateFromRuns, windowParquetTask, windowParquetTasks, windowPartitionBucket, windowRowsFromState, withObjectStoreReadControls, writeParquet, writePartitionedParquet, writePartitionedParquetTask };
|
|
21780
|
+
export { AggregationBuilder, CacheApiCache, Lake, MemoryCache, MemoryObjectStore, MemorySpillAdapter, ParquetScanAdapter, QueryBuilder, QueryResult, ResumedQuery, SharedMemoryCache, add, aggregateParquetGroupTask, aggregateParquetGroupTasks, aggregateParquetGroupTasksBatch, aggregateParquetTask, aggregateParquetTasks, and, asyncBufferFromStore, batchExprValues, batchFromColumns, batchFromVectors, bboxMayIntersect, between, broadcastJoin, buildBBoxIndex, buildMinMaxIndex, cacheApiCache, cachedObjectStore, classifyPredicate, col, concatBatches, createParquetLake, createParquetTableAs, createVectorAggregateStates, createVectorGroupByState, crossJoin, deserializeAggregateOperatorState, deserializeSortOperatorState, deserializeTopKOperatorState, deserializeWindowOperatorState, div, enforceVectorGroupByBudget, eq, evaluateWindowWorkUnitPartials, fanInWorkUnits, finalizeVectorAggregateStates, finalizeVectorGroupByBatch, finalizeVectorGroupByRows, fn, gatherBatch, getOrCreateVectorGroup, gt, gte, ilike, isIn, isNotNull, isNull, jsonWorkUnitBoundary, like, lit, lookupJoin, lt, lte, materializeBatchRow, materializeBatchRows, materializeSelectedBatchRows, memoryCache, memorySpillAdapter, memoryStore, mergeVectorAggregateStateSnapshots, mergeVectorAggregateStates, mergeVectorGroupByStates, mod, mul, ne, not, notIn, or, parquetScanner, parseHivePartitions, parseJsonQuery, parseSql, parseSqlStatement, partitionWindowWorkUnitRows, partitionedParquetOutputEntries, planParquetTaskWorkUnits, planRowGroups, planRowGroupsFromMetadata, predicateSelection, pruneFilesWithIndex, readControlSignal, readIcebergParquetDeletes, readParquetColumnBatches, readParquetMetadata, readParquetObjectBatches, readParquetObjects, rejectUnsupportedParquetSchema, restoreVectorAggregateStates, restoreVectorGroupByState, rowGroupMayMatch, rowGroupMustMatch, scalarVectorValue, scanParquetTaskBatches, scanParquetTaskColumnBatches, selectedRowCount, selectedRowIndices, serializeAggregateOperatorState, serializeSortOperatorState, serializeTopKOperatorState, serializeWindowOperatorState, snapshotVectorAggregateStates, snapshotVectorGroupByState, sub, throwIfAborted, tryPredicateSelection, updateVectorAggregateStateValue, updateVectorAggregateStates, updateVectorGroupAggregateValue, updateVectorGroupByState, uriObjectStore, vectorAggregateBatch, vectorFromValues, vectorGroupByBatch, vectorLength, vectorOrderByBatch, vectorProjectBatch, vectorSortIndices, vectorTopKBatch, vectorTopKIndices, vectorValue, windowOperatorState, windowOperatorStateFromRuns, windowParquetTask, windowParquetTasks, windowPartitionBucket, windowRowsFromState, withObjectStoreReadControls, writeParquet, writePartitionedParquet, writePartitionedParquetTask };
|