@quereus/quereus 0.5.1 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -1
- package/dist/src/common/datatype.d.ts +4 -5
- package/dist/src/common/datatype.d.ts.map +1 -1
- package/dist/src/common/datatype.js.map +1 -1
- package/dist/src/common/type-inference.d.ts +3 -6
- package/dist/src/common/type-inference.d.ts.map +1 -1
- package/dist/src/common/type-inference.js +17 -22
- package/dist/src/common/type-inference.js.map +1 -1
- package/dist/src/core/param.d.ts.map +1 -1
- package/dist/src/core/param.js +3 -18
- package/dist/src/core/param.js.map +1 -1
- package/dist/src/func/builtins/aggregate.d.ts.map +1 -1
- package/dist/src/func/builtins/aggregate.js +24 -2
- package/dist/src/func/builtins/aggregate.js.map +1 -1
- package/dist/src/func/builtins/builtin-window-functions.js +10 -10
- package/dist/src/func/builtins/builtin-window-functions.js.map +1 -1
- package/dist/src/func/builtins/conversion.d.ts +10 -0
- package/dist/src/func/builtins/conversion.d.ts.map +1 -1
- package/dist/src/func/builtins/conversion.js +20 -1
- package/dist/src/func/builtins/conversion.js.map +1 -1
- package/dist/src/func/builtins/explain.js +53 -53
- package/dist/src/func/builtins/explain.js.map +1 -1
- package/dist/src/func/builtins/generation.js +2 -2
- package/dist/src/func/builtins/generation.js.map +1 -1
- package/dist/src/func/builtins/index.d.ts.map +1 -1
- package/dist/src/func/builtins/index.js +16 -1
- package/dist/src/func/builtins/index.js.map +1 -1
- package/dist/src/func/builtins/json-tvf.js +17 -17
- package/dist/src/func/builtins/json-tvf.js.map +1 -1
- package/dist/src/func/builtins/scalar.d.ts.map +1 -1
- package/dist/src/func/builtins/scalar.js +202 -13
- package/dist/src/func/builtins/scalar.js.map +1 -1
- package/dist/src/func/builtins/schema.js +18 -18
- package/dist/src/func/builtins/schema.js.map +1 -1
- package/dist/src/func/builtins/string.d.ts.map +1 -1
- package/dist/src/func/builtins/string.js +56 -47
- package/dist/src/func/builtins/string.js.map +1 -1
- package/dist/src/func/builtins/timespan.d.ts +45 -0
- package/dist/src/func/builtins/timespan.d.ts.map +1 -0
- package/dist/src/func/builtins/timespan.js +147 -0
- package/dist/src/func/builtins/timespan.js.map +1 -0
- package/dist/src/func/registration.d.ts +26 -0
- package/dist/src/func/registration.d.ts.map +1 -1
- package/dist/src/func/registration.js +9 -5
- package/dist/src/func/registration.js.map +1 -1
- package/dist/src/index.d.ts +1 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +1 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/parser/parser.js +2 -2
- package/dist/src/parser/parser.js.map +1 -1
- package/dist/src/planner/building/constraint-builder.js +2 -2
- package/dist/src/planner/building/constraint-builder.js.map +1 -1
- package/dist/src/planner/building/delete.js +3 -3
- package/dist/src/planner/building/delete.js.map +1 -1
- package/dist/src/planner/building/function-call.d.ts.map +1 -1
- package/dist/src/planner/building/function-call.js +24 -4
- package/dist/src/planner/building/function-call.js.map +1 -1
- package/dist/src/planner/building/insert.js +3 -3
- package/dist/src/planner/building/insert.js.map +1 -1
- package/dist/src/planner/building/select.d.ts.map +1 -1
- package/dist/src/planner/building/select.js +3 -2
- package/dist/src/planner/building/select.js.map +1 -1
- package/dist/src/planner/building/update.js +7 -7
- package/dist/src/planner/building/update.js.map +1 -1
- package/dist/src/planner/nodes/aggregate-function.d.ts +2 -1
- package/dist/src/planner/nodes/aggregate-function.d.ts.map +1 -1
- package/dist/src/planner/nodes/aggregate-function.js +10 -3
- package/dist/src/planner/nodes/aggregate-function.js.map +1 -1
- package/dist/src/planner/nodes/cte-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/cte-node.js +2 -2
- package/dist/src/planner/nodes/cte-node.js.map +1 -1
- package/dist/src/planner/nodes/declarative-schema.js +3 -3
- package/dist/src/planner/nodes/declarative-schema.js.map +1 -1
- package/dist/src/planner/nodes/function.d.ts +2 -1
- package/dist/src/planner/nodes/function.d.ts.map +1 -1
- package/dist/src/planner/nodes/function.js +6 -3
- package/dist/src/planner/nodes/function.js.map +1 -1
- package/dist/src/planner/nodes/insert-node.js +1 -1
- package/dist/src/planner/nodes/insert-node.js.map +1 -1
- package/dist/src/planner/nodes/pragma.d.ts +1 -1
- package/dist/src/planner/nodes/pragma.d.ts.map +1 -1
- package/dist/src/planner/nodes/pragma.js +3 -3
- package/dist/src/planner/nodes/pragma.js.map +1 -1
- package/dist/src/planner/nodes/reference.js +1 -1
- package/dist/src/planner/nodes/reference.js.map +1 -1
- package/dist/src/planner/nodes/scalar.d.ts.map +1 -1
- package/dist/src/planner/nodes/scalar.js +55 -101
- package/dist/src/planner/nodes/scalar.js.map +1 -1
- package/dist/src/planner/nodes/sequencing-node.js +2 -2
- package/dist/src/planner/nodes/sequencing-node.js.map +1 -1
- package/dist/src/planner/nodes/sink-node.js +2 -2
- package/dist/src/planner/nodes/sink-node.js.map +1 -1
- package/dist/src/planner/nodes/subquery.d.ts.map +1 -1
- package/dist/src/planner/nodes/subquery.js +4 -7
- package/dist/src/planner/nodes/subquery.js.map +1 -1
- package/dist/src/planner/nodes/view-reference-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/view-reference-node.js +2 -2
- package/dist/src/planner/nodes/view-reference-node.js.map +1 -1
- package/dist/src/planner/nodes/window-function.js +3 -3
- package/dist/src/planner/nodes/window-function.js.map +1 -1
- package/dist/src/planner/rules/access/rule-select-access-path.js +1 -1
- package/dist/src/planner/rules/access/rule-select-access-path.js.map +1 -1
- package/dist/src/planner/rules/retrieve/rule-grow-retrieve.js +1 -1
- package/dist/src/planner/rules/retrieve/rule-grow-retrieve.js.map +1 -1
- package/dist/src/planner/scopes/global.js +3 -3
- package/dist/src/planner/scopes/global.js.map +1 -1
- package/dist/src/planner/scopes/param.d.ts.map +1 -1
- package/dist/src/planner/scopes/param.js +2 -2
- package/dist/src/planner/scopes/param.js.map +1 -1
- package/dist/src/planner/type-utils.d.ts +2 -12
- package/dist/src/planner/type-utils.d.ts.map +1 -1
- package/dist/src/planner/type-utils.js +6 -21
- package/dist/src/planner/type-utils.js.map +1 -1
- package/dist/src/runtime/emit/binary.d.ts.map +1 -1
- package/dist/src/runtime/emit/binary.js +40 -2
- package/dist/src/runtime/emit/binary.js.map +1 -1
- package/dist/src/runtime/emit/set-operation.d.ts.map +1 -1
- package/dist/src/runtime/emit/set-operation.js +33 -22
- package/dist/src/runtime/emit/set-operation.js.map +1 -1
- package/dist/src/runtime/emit/temporal-arithmetic.d.ts +33 -0
- package/dist/src/runtime/emit/temporal-arithmetic.d.ts.map +1 -0
- package/dist/src/runtime/emit/temporal-arithmetic.js +269 -0
- package/dist/src/runtime/emit/temporal-arithmetic.js.map +1 -0
- package/dist/src/runtime/emit/unary.d.ts.map +1 -1
- package/dist/src/runtime/emit/unary.js +12 -0
- package/dist/src/runtime/emit/unary.js.map +1 -1
- package/dist/src/schema/catalog.js +3 -3
- package/dist/src/schema/catalog.js.map +1 -1
- package/dist/src/schema/column.d.ts +0 -3
- package/dist/src/schema/column.d.ts.map +1 -1
- package/dist/src/schema/column.js +0 -2
- package/dist/src/schema/column.js.map +1 -1
- package/dist/src/schema/function.d.ts +29 -1
- package/dist/src/schema/function.d.ts.map +1 -1
- package/dist/src/schema/function.js.map +1 -1
- package/dist/src/schema/table.d.ts +3 -3
- package/dist/src/schema/table.d.ts.map +1 -1
- package/dist/src/schema/table.js +4 -6
- package/dist/src/schema/table.js.map +1 -1
- package/dist/src/types/index.d.ts +1 -1
- package/dist/src/types/index.d.ts.map +1 -1
- package/dist/src/types/index.js +1 -1
- package/dist/src/types/index.js.map +1 -1
- package/dist/src/types/registry.d.ts.map +1 -1
- package/dist/src/types/registry.js +5 -1
- package/dist/src/types/registry.js.map +1 -1
- package/dist/src/types/temporal-types.d.ts +5 -0
- package/dist/src/types/temporal-types.d.ts.map +1 -1
- package/dist/src/types/temporal-types.js +122 -0
- package/dist/src/types/temporal-types.js.map +1 -1
- package/dist/src/util/ast-stringify.js +1 -1
- package/dist/src/util/ast-stringify.js.map +1 -1
- package/dist/src/util/plan-formatter.d.ts.map +1 -1
- package/dist/src/util/plan-formatter.js +1 -5
- package/dist/src/util/plan-formatter.js.map +1 -1
- package/dist/src/util/row-descriptor.js +2 -2
- package/dist/src/util/row-descriptor.js.map +1 -1
- package/dist/src/vtab/best-access-plan.d.ts +4 -3
- package/dist/src/vtab/best-access-plan.d.ts.map +1 -1
- package/dist/src/vtab/best-access-plan.js.map +1 -1
- package/dist/src/vtab/memory/module.js +1 -1
- package/dist/src/vtab/memory/module.js.map +1 -1
- package/package.json +1 -1
- package/src/common/datatype.ts +4 -5
- package/src/common/type-inference.ts +13 -22
- package/src/core/param.ts +4 -11
- package/src/func/builtins/aggregate.ts +24 -2
- package/src/func/builtins/builtin-window-functions.ts +10 -10
- package/src/func/builtins/conversion.ts +26 -1
- package/src/func/builtins/explain.ts +53 -53
- package/src/func/builtins/generation.ts +2 -2
- package/src/func/builtins/index.ts +20 -1
- package/src/func/builtins/json-tvf.ts +17 -17
- package/src/func/builtins/scalar.ts +205 -14
- package/src/func/builtins/schema.ts +18 -18
- package/src/func/builtins/string.ts +91 -78
- package/src/func/builtins/timespan.ts +179 -0
- package/src/func/registration.ts +35 -5
- package/src/index.ts +2 -1
- package/src/parser/parser.ts +2 -2
- package/src/planner/building/constraint-builder.ts +2 -2
- package/src/planner/building/delete.ts +3 -3
- package/src/planner/building/function-call.ts +44 -3
- package/src/planner/building/insert.ts +3 -3
- package/src/planner/building/select.ts +3 -2
- package/src/planner/building/update.ts +7 -7
- package/src/planner/nodes/aggregate-function.ts +13 -3
- package/src/planner/nodes/cte-node.ts +2 -2
- package/src/planner/nodes/declarative-schema.ts +3 -3
- package/src/planner/nodes/function.ts +8 -3
- package/src/planner/nodes/insert-node.ts +1 -1
- package/src/planner/nodes/pragma.ts +4 -3
- package/src/planner/nodes/reference.ts +1 -1
- package/src/planner/nodes/scalar.ts +54 -102
- package/src/planner/nodes/sequencing-node.ts +2 -2
- package/src/planner/nodes/sink-node.ts +2 -2
- package/src/planner/nodes/subquery.ts +5 -7
- package/src/planner/nodes/view-reference-node.ts +2 -2
- package/src/planner/nodes/window-function.ts +3 -3
- package/src/planner/rules/access/rule-select-access-path.ts +1 -1
- package/src/planner/rules/retrieve/rule-grow-retrieve.ts +1 -1
- package/src/planner/scopes/global.ts +3 -3
- package/src/planner/scopes/param.ts +2 -2
- package/src/planner/type-utils.ts +6 -14
- package/src/runtime/emit/binary.ts +48 -2
- package/src/runtime/emit/set-operation.ts +52 -22
- package/src/runtime/emit/temporal-arithmetic.ts +302 -0
- package/src/runtime/emit/unary.ts +13 -0
- package/src/schema/catalog.ts +3 -3
- package/src/schema/column.ts +0 -3
- package/src/schema/function.ts +29 -1
- package/src/schema/table.ts +5 -7
- package/src/types/index.ts +1 -1
- package/src/types/registry.ts +5 -1
- package/src/types/temporal-types.ts +123 -0
- package/src/util/ast-stringify.ts +1 -1
- package/src/util/plan-formatter.ts +1 -4
- package/src/util/row-descriptor.ts +2 -2
- package/src/vtab/best-access-plan.ts +4 -3
- package/src/vtab/memory/module.ts +1 -1
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { PlanNode, type ScalarPlanNode } from "./plan-node.js";
|
|
2
2
|
import type { ScalarType } from "../../common/datatype.js";
|
|
3
3
|
import type { RelationalPlanNode } from "./plan-node.js";
|
|
4
|
-
import { type CompareFn
|
|
4
|
+
import { type CompareFn } from "../../common/types.js";
|
|
5
5
|
import { PlanNodeType } from "./plan-node-type.js";
|
|
6
6
|
import type { Scope } from "../scopes/scope.js";
|
|
7
7
|
import { compareSqlValues } from "../../util/comparison.js";
|
|
8
8
|
import type { Expression } from "../../parser/ast.js";
|
|
9
9
|
import { formatExpression, formatScalarType } from "../../util/plan-formatter.js";
|
|
10
10
|
import { quereusError } from "../../common/errors.js";
|
|
11
|
+
import { BLOB_TYPE, INTEGER_TYPE } from "../../types/builtin-types.js";
|
|
11
12
|
import { StatusCode } from "../../common/types.js";
|
|
12
13
|
|
|
13
14
|
export class ScalarSubqueryNode extends PlanNode implements ScalarPlanNode {
|
|
@@ -31,10 +32,9 @@ export class ScalarSubqueryNode extends PlanNode implements ScalarPlanNode {
|
|
|
31
32
|
// Fallback to nullable BLOB if we can't determine type
|
|
32
33
|
return {
|
|
33
34
|
typeClass: 'scalar',
|
|
34
|
-
|
|
35
|
+
logicalType: BLOB_TYPE,
|
|
35
36
|
nullable: true,
|
|
36
37
|
isReadOnly: true,
|
|
37
|
-
datatype: SqlDataType.BLOB,
|
|
38
38
|
};
|
|
39
39
|
}
|
|
40
40
|
|
|
@@ -103,10 +103,9 @@ export class InNode extends PlanNode implements ScalarPlanNode {
|
|
|
103
103
|
getType(): ScalarType {
|
|
104
104
|
return {
|
|
105
105
|
typeClass: 'scalar',
|
|
106
|
-
|
|
106
|
+
logicalType: INTEGER_TYPE,
|
|
107
107
|
nullable: false,
|
|
108
108
|
isReadOnly: true,
|
|
109
|
-
datatype: SqlDataType.INTEGER,
|
|
110
109
|
}
|
|
111
110
|
}
|
|
112
111
|
|
|
@@ -216,10 +215,9 @@ export class ExistsNode extends PlanNode implements ScalarPlanNode {
|
|
|
216
215
|
getType(): ScalarType {
|
|
217
216
|
return {
|
|
218
217
|
typeClass: 'scalar',
|
|
219
|
-
|
|
218
|
+
logicalType: INTEGER_TYPE,
|
|
220
219
|
nullable: false,
|
|
221
220
|
isReadOnly: true,
|
|
222
|
-
datatype: SqlDataType.INTEGER,
|
|
223
221
|
};
|
|
224
222
|
}
|
|
225
223
|
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { PlanNode, type ZeroAryRelationalNode, type Attribute } from './plan-node.js';
|
|
2
2
|
import type { RelationType } from '../../common/datatype.js';
|
|
3
|
-
import { SqlDataType } from '../../common/types.js';
|
|
4
3
|
import { PlanNodeType } from './plan-node-type.js';
|
|
5
4
|
import type { Scope } from '../scopes/scope.js';
|
|
6
5
|
import type { ViewSchema } from '../../schema/view.js';
|
|
7
6
|
import { Cached } from '../../util/cached.js';
|
|
7
|
+
import { TEXT_TYPE } from '../../types/builtin-types.js';
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* Plan node for referencing a view in a FROM clause.
|
|
@@ -36,7 +36,7 @@ export class ViewReferenceNode extends PlanNode implements ZeroAryRelationalNode
|
|
|
36
36
|
name: columnName,
|
|
37
37
|
type: {
|
|
38
38
|
typeClass: 'scalar' as const,
|
|
39
|
-
|
|
39
|
+
logicalType: TEXT_TYPE,
|
|
40
40
|
nullable: true,
|
|
41
41
|
isReadOnly: false
|
|
42
42
|
}, // Default type, should be inferred
|
|
@@ -4,8 +4,8 @@ import type { ScalarType } from '../../common/datatype.js';
|
|
|
4
4
|
import type { Scope } from '../scopes/scope.js';
|
|
5
5
|
import type { WindowFunctionExpr } from '../../parser/ast.js';
|
|
6
6
|
import { Cached } from '../../util/cached.js';
|
|
7
|
-
import { SqlDataType } from '../../common/types.js';
|
|
8
7
|
import { formatScalarType } from '../../util/plan-formatter.js';
|
|
8
|
+
import { INTEGER_TYPE, REAL_TYPE } from '../../types/builtin-types.js';
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* Represents a window function call in the query plan.
|
|
@@ -30,10 +30,10 @@ export class WindowFunctionCallNode extends PlanNode implements ZeroAryScalarNod
|
|
|
30
30
|
// Most window functions return numeric types
|
|
31
31
|
// row_number() specifically returns an integer
|
|
32
32
|
if (this.functionName === 'row_number') {
|
|
33
|
-
return { typeClass: 'scalar',
|
|
33
|
+
return { typeClass: 'scalar', logicalType: INTEGER_TYPE, nullable: false } satisfies ScalarType;
|
|
34
34
|
}
|
|
35
35
|
// Other window functions would have their own type inference
|
|
36
|
-
return { typeClass: 'scalar',
|
|
36
|
+
return { typeClass: 'scalar', logicalType: REAL_TYPE, nullable: false } satisfies ScalarType;
|
|
37
37
|
});
|
|
38
38
|
}
|
|
39
39
|
|
|
@@ -120,7 +120,7 @@ function createIndexBasedAccess(retrieveNode: RetrieveNode, context: OptContext)
|
|
|
120
120
|
columns: tableSchema.columns.map((col, index) => ({
|
|
121
121
|
index,
|
|
122
122
|
name: col.name,
|
|
123
|
-
type: col.
|
|
123
|
+
type: col.logicalType,
|
|
124
124
|
isPrimaryKey: col.primaryKey || false,
|
|
125
125
|
isUnique: col.primaryKey || false // For now, assume only PK columns are unique
|
|
126
126
|
} as ColumnMeta)),
|
|
@@ -231,7 +231,7 @@ function fallbackIndexSupports(
|
|
|
231
231
|
columns: tableSchema.columns.map((col, index) => ({
|
|
232
232
|
index,
|
|
233
233
|
name: col.name,
|
|
234
|
-
type: col.
|
|
234
|
+
type: col.logicalType,
|
|
235
235
|
isPrimaryKey: col.primaryKey || false,
|
|
236
236
|
isUnique: col.primaryKey || false
|
|
237
237
|
})),
|
|
@@ -5,8 +5,8 @@ import * as AST from "../../parser/ast.js";
|
|
|
5
5
|
import { FunctionReferenceNode, TableReferenceNode } from "../nodes/reference.js";
|
|
6
6
|
import { Ambiguous } from "./scope.js";
|
|
7
7
|
import type { ScalarType } from "../../common/datatype.js";
|
|
8
|
-
import { SqlDataType } from "../../common/types.js";
|
|
9
8
|
import { isScalarFunctionSchema } from "../../schema/function.js";
|
|
9
|
+
import { REAL_TYPE } from "../../types/builtin-types.js";
|
|
10
10
|
|
|
11
11
|
export class GlobalScope extends BaseScope {
|
|
12
12
|
constructor(public readonly manager: SchemaManager) {
|
|
@@ -25,7 +25,7 @@ export class GlobalScope extends BaseScope {
|
|
|
25
25
|
// Get the proper scalar type from the function schema
|
|
26
26
|
const scalarType: ScalarType = isScalarFunctionSchema(func)
|
|
27
27
|
? func.returnType
|
|
28
|
-
: { typeClass: 'scalar',
|
|
28
|
+
: { typeClass: 'scalar', logicalType: REAL_TYPE, nullable: true, isReadOnly: true };
|
|
29
29
|
|
|
30
30
|
return new FunctionReferenceNode(this, func, scalarType);
|
|
31
31
|
}
|
|
@@ -54,7 +54,7 @@ export class GlobalScope extends BaseScope {
|
|
|
54
54
|
// Get the proper scalar type from the function schema
|
|
55
55
|
const scalarType: ScalarType = isScalarFunctionSchema(func)
|
|
56
56
|
? func.returnType
|
|
57
|
-
: { typeClass: 'scalar',
|
|
57
|
+
: { typeClass: 'scalar', logicalType: REAL_TYPE, nullable: true, isReadOnly: true };
|
|
58
58
|
|
|
59
59
|
return new FunctionReferenceNode(this, func, scalarType);
|
|
60
60
|
}
|
|
@@ -3,13 +3,13 @@ import { ParameterReferenceNode } from '../nodes/reference.js'; // Corrected imp
|
|
|
3
3
|
import { BaseScope } from './base.js';
|
|
4
4
|
import { Ambiguous, type Scope } from './scope.js';
|
|
5
5
|
import type { ScalarType } from '../../common/datatype.js';
|
|
6
|
-
import { SqlDataType } from '../../common/types.js';
|
|
7
6
|
import type { PlanNode } from '../nodes/plan-node.js';
|
|
7
|
+
import { TEXT_TYPE } from '../../types/builtin-types.js';
|
|
8
8
|
|
|
9
9
|
// Default type for parameters when not otherwise specified.
|
|
10
10
|
const DEFAULT_PARAMETER_TYPE: ScalarType = {
|
|
11
11
|
typeClass: 'scalar',
|
|
12
|
-
|
|
12
|
+
logicalType: TEXT_TYPE,
|
|
13
13
|
nullable: true,
|
|
14
14
|
};
|
|
15
15
|
|
|
@@ -4,8 +4,7 @@ import type { RelationType, ColumnDef, ScalarType, ColRef } from '../common/data
|
|
|
4
4
|
import { SqlDataType, StatusCode, type DeepReadonly, type SqlValue } from '../common/types.js'; // Import SqlValue and ensure SqlDataType is not type-only
|
|
5
5
|
import type { AstNode } from '../parser/ast.js';
|
|
6
6
|
import { QuereusError } from '../common/errors.js';
|
|
7
|
-
|
|
8
|
-
// If tableSchema.columns are of type from '../schema/column.js', then their affinity is already SqlDataType.
|
|
7
|
+
import { inferLogicalTypeFromValue } from '../common/type-inference.js';
|
|
9
8
|
|
|
10
9
|
/**
|
|
11
10
|
* Converts a TableSchema (from src/schema/table.ts) to a RelationType (from src/common/datatype.ts).
|
|
@@ -17,7 +16,7 @@ export function relationTypeFromTableSchema(tableSchema: TableSchema): RelationT
|
|
|
17
16
|
name: col.name,
|
|
18
17
|
type: {
|
|
19
18
|
typeClass: 'scalar',
|
|
20
|
-
|
|
19
|
+
logicalType: col.logicalType,
|
|
21
20
|
collationName: col.collation,
|
|
22
21
|
nullable: !col.notNull,
|
|
23
22
|
isReadOnly: false,
|
|
@@ -53,18 +52,11 @@ export function relationTypeFromTableSchema(tableSchema: TableSchema): RelationT
|
|
|
53
52
|
* @returns A ScalarType representing the inferred type of the value.
|
|
54
53
|
*/
|
|
55
54
|
export function getParameterScalarType(value: SqlValue): ScalarType {
|
|
56
|
-
|
|
57
|
-
if (value === null) affinity = SqlDataType.NULL;
|
|
58
|
-
else if (typeof value === 'number') affinity = SqlDataType.REAL;
|
|
59
|
-
else if (typeof value === 'bigint') affinity = SqlDataType.INTEGER;
|
|
60
|
-
else if (typeof value === 'string') affinity = SqlDataType.TEXT;
|
|
61
|
-
else if (value instanceof Uint8Array) affinity = SqlDataType.BLOB;
|
|
62
|
-
else if (typeof value === 'boolean') affinity = SqlDataType.INTEGER; // Store booleans as INTEGER
|
|
63
|
-
else affinity = SqlDataType.BLOB; // Default for unknown types that might pass as SqlValue
|
|
55
|
+
const logicalType = inferLogicalTypeFromValue(value);
|
|
64
56
|
|
|
65
57
|
return {
|
|
66
58
|
typeClass: 'scalar',
|
|
67
|
-
|
|
59
|
+
logicalType,
|
|
68
60
|
nullable: true, // No guarantees about the value, so it's nullable
|
|
69
61
|
isReadOnly: true, // Parameters are read-only within the query execution context
|
|
70
62
|
};
|
|
@@ -80,12 +72,12 @@ export function checkRelationsAssignable(source: RelationType, target: RelationT
|
|
|
80
72
|
return checkColumnsAssignable(source.columns, target.columns, astNode);
|
|
81
73
|
}
|
|
82
74
|
|
|
83
|
-
export function columnSchemaToDef(colName: string, colDef: ColumnSchema):
|
|
75
|
+
export function columnSchemaToDef(colName: string, colDef: ColumnSchema): ColumnDef {
|
|
84
76
|
return {
|
|
85
77
|
name: colName,
|
|
86
78
|
type: {
|
|
87
79
|
typeClass: 'scalar',
|
|
88
|
-
|
|
80
|
+
logicalType: colDef.logicalType,
|
|
89
81
|
collationName: colDef.collation,
|
|
90
82
|
nullable: !colDef.notNull,
|
|
91
83
|
isReadOnly: false,
|
|
@@ -8,6 +8,7 @@ import { compareSqlValuesFast, resolveCollation } from "../../util/comparison.js
|
|
|
8
8
|
import { coerceForComparison, coerceToNumberForArithmetic } from "../../util/coercion.js";
|
|
9
9
|
import { simpleLike } from "../../util/patterns.js";
|
|
10
10
|
import type { EmissionContext } from "../emission-context.js";
|
|
11
|
+
import { tryTemporalArithmetic, tryTemporalComparison } from "./temporal-arithmetic.js";
|
|
11
12
|
|
|
12
13
|
export function emitBinaryOp(plan: BinaryOpNode, ctx: EmissionContext): Instruction {
|
|
13
14
|
// Normalize operator to uppercase for case-insensitive matching of keywords
|
|
@@ -73,6 +74,13 @@ export function emitNumericOp(plan: BinaryOpNode, ctx: EmissionContext): Instruc
|
|
|
73
74
|
}
|
|
74
75
|
|
|
75
76
|
function run(ctx: RuntimeContext, v1: SqlValue, v2: SqlValue): SqlValue {
|
|
77
|
+
// Try temporal arithmetic first
|
|
78
|
+
const temporalResult = tryTemporalArithmetic(plan.expression.operator, v1, v2);
|
|
79
|
+
if (temporalResult !== undefined) {
|
|
80
|
+
return temporalResult;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Fall back to numeric arithmetic
|
|
76
84
|
if (v1 !== null && v2 !== null) {
|
|
77
85
|
if (typeof v1 === 'bigint' || typeof v2 === 'bigint') {
|
|
78
86
|
try {
|
|
@@ -127,13 +135,21 @@ export function emitComparisonOp(plan: BinaryOpNode, ctx: EmissionContext): Inst
|
|
|
127
135
|
// Pre-resolve collation function for optimal performance
|
|
128
136
|
const collationFunc = resolveCollation(collationName);
|
|
129
137
|
|
|
130
|
-
|
|
138
|
+
const operator = plan.expression.operator;
|
|
139
|
+
|
|
140
|
+
switch (operator) {
|
|
131
141
|
case '=':
|
|
132
142
|
case '==':
|
|
133
143
|
run = (ctx: RuntimeContext, v1: SqlValue, v2: SqlValue): SqlValue => {
|
|
134
144
|
// SQL comparison: NULL = anything -> NULL
|
|
135
145
|
if (v1 === null || v2 === null) return null;
|
|
136
146
|
|
|
147
|
+
// Try temporal comparison first
|
|
148
|
+
const temporalResult = tryTemporalComparison(operator, v1, v2);
|
|
149
|
+
if (temporalResult !== undefined) {
|
|
150
|
+
return temporalResult;
|
|
151
|
+
}
|
|
152
|
+
|
|
137
153
|
// Apply type coercion before comparison
|
|
138
154
|
const [coercedV1, coercedV2] = coerceForComparison(v1, v2);
|
|
139
155
|
return compareSqlValuesFast(coercedV1, coercedV2, collationFunc) === 0 ? 1 : 0;
|
|
@@ -145,6 +161,12 @@ export function emitComparisonOp(plan: BinaryOpNode, ctx: EmissionContext): Inst
|
|
|
145
161
|
// SQL comparison: NULL != anything -> NULL
|
|
146
162
|
if (v1 === null || v2 === null) return null;
|
|
147
163
|
|
|
164
|
+
// Try temporal comparison first
|
|
165
|
+
const temporalResult = tryTemporalComparison(operator, v1, v2);
|
|
166
|
+
if (temporalResult !== undefined) {
|
|
167
|
+
return temporalResult;
|
|
168
|
+
}
|
|
169
|
+
|
|
148
170
|
// Apply type coercion before comparison
|
|
149
171
|
const [coercedV1, coercedV2] = coerceForComparison(v1, v2);
|
|
150
172
|
return compareSqlValuesFast(coercedV1, coercedV2, collationFunc) !== 0 ? 1 : 0;
|
|
@@ -155,6 +177,12 @@ export function emitComparisonOp(plan: BinaryOpNode, ctx: EmissionContext): Inst
|
|
|
155
177
|
// SQL comparison: NULL < anything -> NULL
|
|
156
178
|
if (v1 === null || v2 === null) return null;
|
|
157
179
|
|
|
180
|
+
// Try temporal comparison first
|
|
181
|
+
const temporalResult = tryTemporalComparison(operator, v1, v2);
|
|
182
|
+
if (temporalResult !== undefined) {
|
|
183
|
+
return temporalResult;
|
|
184
|
+
}
|
|
185
|
+
|
|
158
186
|
// Apply type coercion before comparison
|
|
159
187
|
const [coercedV1, coercedV2] = coerceForComparison(v1, v2);
|
|
160
188
|
return compareSqlValuesFast(coercedV1, coercedV2, collationFunc) < 0 ? 1 : 0;
|
|
@@ -165,6 +193,12 @@ export function emitComparisonOp(plan: BinaryOpNode, ctx: EmissionContext): Inst
|
|
|
165
193
|
// SQL comparison: NULL <= anything -> NULL
|
|
166
194
|
if (v1 === null || v2 === null) return null;
|
|
167
195
|
|
|
196
|
+
// Try temporal comparison first
|
|
197
|
+
const temporalResult = tryTemporalComparison(operator, v1, v2);
|
|
198
|
+
if (temporalResult !== undefined) {
|
|
199
|
+
return temporalResult;
|
|
200
|
+
}
|
|
201
|
+
|
|
168
202
|
// Apply type coercion before comparison
|
|
169
203
|
const [coercedV1, coercedV2] = coerceForComparison(v1, v2);
|
|
170
204
|
return compareSqlValuesFast(coercedV1, coercedV2, collationFunc) <= 0 ? 1 : 0;
|
|
@@ -177,6 +211,12 @@ export function emitComparisonOp(plan: BinaryOpNode, ctx: EmissionContext): Inst
|
|
|
177
211
|
return null;
|
|
178
212
|
}
|
|
179
213
|
|
|
214
|
+
// Try temporal comparison first
|
|
215
|
+
const temporalResult = tryTemporalComparison(operator, v1, v2);
|
|
216
|
+
if (temporalResult !== undefined) {
|
|
217
|
+
return temporalResult;
|
|
218
|
+
}
|
|
219
|
+
|
|
180
220
|
// Apply type coercion before comparison
|
|
181
221
|
const [coercedV1, coercedV2] = coerceForComparison(v1, v2);
|
|
182
222
|
const comparisonResult = compareSqlValuesFast(coercedV1, coercedV2, collationFunc);
|
|
@@ -189,13 +229,19 @@ export function emitComparisonOp(plan: BinaryOpNode, ctx: EmissionContext): Inst
|
|
|
189
229
|
// SQL comparison: NULL >= anything -> NULL
|
|
190
230
|
if (v1 === null || v2 === null) return null;
|
|
191
231
|
|
|
232
|
+
// Try temporal comparison first
|
|
233
|
+
const temporalResult = tryTemporalComparison(operator, v1, v2);
|
|
234
|
+
if (temporalResult !== undefined) {
|
|
235
|
+
return temporalResult;
|
|
236
|
+
}
|
|
237
|
+
|
|
192
238
|
// Apply type coercion before comparison
|
|
193
239
|
const [coercedV1, coercedV2] = coerceForComparison(v1, v2);
|
|
194
240
|
return compareSqlValuesFast(coercedV1, coercedV2, collationFunc) >= 0 ? 1 : 0;
|
|
195
241
|
};
|
|
196
242
|
break;
|
|
197
243
|
default:
|
|
198
|
-
throw new QuereusError(`Unsupported comparison operator: ${
|
|
244
|
+
throw new QuereusError(`Unsupported comparison operator: ${operator}`, StatusCode.UNSUPPORTED);
|
|
199
245
|
}
|
|
200
246
|
|
|
201
247
|
const leftExpr = emitPlanNode(plan.left, ctx);
|
|
@@ -3,6 +3,8 @@ import type { Instruction, RuntimeContext, InstructionRun } from '../types.js';
|
|
|
3
3
|
import type { EmissionContext } from '../emission-context.js';
|
|
4
4
|
import { emitPlanNode } from '../emitters.js';
|
|
5
5
|
import type { Row } from '../../common/types.js';
|
|
6
|
+
import { BTree } from 'inheritree';
|
|
7
|
+
import { compareRows } from '../../util/comparison.js';
|
|
6
8
|
|
|
7
9
|
export function emitSetOperation(plan: SetOperationNode, ctx: EmissionContext): Instruction {
|
|
8
10
|
const leftInst = emitPlanNode(plan.left, ctx);
|
|
@@ -30,58 +32,86 @@ export function emitSetOperation(plan: SetOperationNode, ctx: EmissionContext):
|
|
|
30
32
|
}
|
|
31
33
|
|
|
32
34
|
async function* runUnionDistinct(rctx: RuntimeContext, leftRows: AsyncIterable<Row>, rightRows: AsyncIterable<Row>): AsyncIterable<Row> {
|
|
33
|
-
|
|
34
|
-
const
|
|
35
|
+
// Use BTree for proper SQL value comparison instead of JSON.stringify
|
|
36
|
+
const distinctTree = new BTree<Row, Row>(
|
|
37
|
+
(row: Row) => row,
|
|
38
|
+
compareRows
|
|
39
|
+
);
|
|
40
|
+
|
|
35
41
|
for await (const row of leftRows) {
|
|
36
42
|
const outputRow = createOutputRow(row);
|
|
37
|
-
const
|
|
38
|
-
if (
|
|
39
|
-
|
|
43
|
+
const newPath = distinctTree.insert(outputRow);
|
|
44
|
+
if (newPath.on) {
|
|
45
|
+
// This is a new distinct row
|
|
40
46
|
yield outputRow; // Let SortNode handle row context
|
|
41
47
|
}
|
|
42
48
|
}
|
|
43
49
|
for await (const row of rightRows) {
|
|
44
50
|
const outputRow = createOutputRow(row);
|
|
45
|
-
const
|
|
46
|
-
if (
|
|
47
|
-
|
|
51
|
+
const newPath = distinctTree.insert(outputRow);
|
|
52
|
+
if (newPath.on) {
|
|
53
|
+
// This is a new distinct row
|
|
48
54
|
yield outputRow; // Let SortNode handle row context
|
|
49
55
|
}
|
|
50
56
|
}
|
|
51
57
|
}
|
|
52
58
|
|
|
53
59
|
async function* runIntersect(rctx: RuntimeContext, leftRows: AsyncIterable<Row>, rightRows: AsyncIterable<Row>): AsyncIterable<Row> {
|
|
54
|
-
|
|
55
|
-
const
|
|
56
|
-
|
|
60
|
+
// Use BTree for proper SQL value comparison
|
|
61
|
+
const leftTree = new BTree<Row, Row>(
|
|
62
|
+
(row: Row) => row,
|
|
63
|
+
compareRows
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
// Build left set
|
|
57
67
|
for await (const row of leftRows) {
|
|
58
68
|
const outputRow = createOutputRow(row);
|
|
59
|
-
|
|
60
|
-
leftRowsArray.push(outputRow);
|
|
69
|
+
leftTree.insert(outputRow);
|
|
61
70
|
}
|
|
71
|
+
|
|
72
|
+
// Check right rows against left set
|
|
73
|
+
const yielded = new BTree<Row, Row>(
|
|
74
|
+
(row: Row) => row,
|
|
75
|
+
compareRows
|
|
76
|
+
);
|
|
77
|
+
|
|
62
78
|
for await (const row of rightRows) {
|
|
63
79
|
const outputRow = createOutputRow(row);
|
|
64
|
-
const
|
|
65
|
-
if (
|
|
66
|
-
|
|
67
|
-
|
|
80
|
+
const leftPath = leftTree.find(outputRow);
|
|
81
|
+
if (leftPath.on) {
|
|
82
|
+
// This row exists in left set - yield the LEFT row to preserve left-side types
|
|
83
|
+
const leftRow = leftTree.get(outputRow)!;
|
|
84
|
+
const yieldedPath = yielded.insert(leftRow);
|
|
85
|
+
if (yieldedPath.on) {
|
|
86
|
+
// Haven't yielded this row yet (handles duplicates in right)
|
|
87
|
+
yield leftRow; // Let SortNode handle row context
|
|
88
|
+
}
|
|
68
89
|
}
|
|
69
90
|
}
|
|
70
91
|
}
|
|
71
92
|
|
|
72
93
|
async function* runExcept(rctx: RuntimeContext, leftRows: AsyncIterable<Row>, rightRows: AsyncIterable<Row>): AsyncIterable<Row> {
|
|
73
|
-
|
|
74
|
-
const
|
|
94
|
+
// Use BTree for proper SQL value comparison
|
|
95
|
+
const rightTree = new BTree<Row, Row>(
|
|
96
|
+
(row: Row) => row,
|
|
97
|
+
compareRows
|
|
98
|
+
);
|
|
75
99
|
const leftRowsArray: Row[] = [];
|
|
100
|
+
|
|
101
|
+
// Collect left rows
|
|
76
102
|
for await (const row of leftRows) {
|
|
77
103
|
leftRowsArray.push(createOutputRow(row));
|
|
78
104
|
}
|
|
105
|
+
|
|
106
|
+
// Build right set
|
|
79
107
|
for await (const row of rightRows) {
|
|
80
|
-
|
|
108
|
+
rightTree.insert(createOutputRow(row));
|
|
81
109
|
}
|
|
110
|
+
|
|
111
|
+
// Yield left rows that are not in right set
|
|
82
112
|
for (const outputRow of leftRowsArray) {
|
|
83
|
-
const
|
|
84
|
-
if (!
|
|
113
|
+
const rightPath = rightTree.find(outputRow);
|
|
114
|
+
if (!rightPath.on) {
|
|
85
115
|
yield outputRow; // Let SortNode handle row context
|
|
86
116
|
}
|
|
87
117
|
}
|