@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
|
@@ -197,7 +197,7 @@ export function buildInsertStmt(
|
|
|
197
197
|
name: contextVar.name,
|
|
198
198
|
type: {
|
|
199
199
|
typeClass: 'scalar' as const,
|
|
200
|
-
|
|
200
|
+
logicalType: contextVar.logicalType,
|
|
201
201
|
nullable: !contextVar.notNull,
|
|
202
202
|
isReadOnly: true
|
|
203
203
|
},
|
|
@@ -287,7 +287,7 @@ export function buildInsertStmt(
|
|
|
287
287
|
name: col.name,
|
|
288
288
|
type: {
|
|
289
289
|
typeClass: 'scalar' as const,
|
|
290
|
-
|
|
290
|
+
logicalType: col.logicalType,
|
|
291
291
|
nullable: true, // OLD values are always NULL for INSERT
|
|
292
292
|
isReadOnly: false
|
|
293
293
|
},
|
|
@@ -299,7 +299,7 @@ export function buildInsertStmt(
|
|
|
299
299
|
name: col.name,
|
|
300
300
|
type: {
|
|
301
301
|
typeClass: 'scalar' as const,
|
|
302
|
-
|
|
302
|
+
logicalType: col.logicalType,
|
|
303
303
|
nullable: !col.notNull,
|
|
304
304
|
isReadOnly: false
|
|
305
305
|
},
|
|
@@ -18,6 +18,7 @@ import { InternalRecursiveCTERefNode as _InternalRecursiveCTERefNode } from '../
|
|
|
18
18
|
import type { CTEScopeNode, CTEPlanNode } from '../nodes/cte-node.js';
|
|
19
19
|
import { JoinNode } from '../nodes/join-node.js';
|
|
20
20
|
import { ColumnReferenceNode } from '../nodes/reference.js';
|
|
21
|
+
import { TEXT_TYPE } from '../../types/builtin-types.js';
|
|
21
22
|
import { ValuesNode } from '../nodes/values-node.js';
|
|
22
23
|
import { createLogger } from '../../common/logger.js';
|
|
23
24
|
|
|
@@ -440,7 +441,7 @@ export function buildFrom(fromClause: AST.FromClause, parentContext: PlanningCon
|
|
|
440
441
|
columnNames.forEach((colName, i) => {
|
|
441
442
|
if (i < subqueryAttributes.length) {
|
|
442
443
|
const attr = subqueryAttributes[i];
|
|
443
|
-
const columnType = fromTable.getType().columns[i]?.type || { typeClass: 'scalar',
|
|
444
|
+
const columnType = fromTable.getType().columns[i]?.type || { typeClass: 'scalar', logicalType: TEXT_TYPE, nullable: true, isReadOnly: true };
|
|
444
445
|
subqueryScope.registerSymbol(colName.toLowerCase(), (exp, s) =>
|
|
445
446
|
new ColumnReferenceNode(s, exp as AST.ColumnExpr, columnType, attr.id, i));
|
|
446
447
|
}
|
|
@@ -479,7 +480,7 @@ export function buildFrom(fromClause: AST.FromClause, parentContext: PlanningCon
|
|
|
479
480
|
columnNames.forEach((colName, i) => {
|
|
480
481
|
if (i < mutatingAttributes.length) {
|
|
481
482
|
const attr = mutatingAttributes[i];
|
|
482
|
-
const columnType = fromTable.getType().columns[i]?.type || { typeClass: 'scalar',
|
|
483
|
+
const columnType = fromTable.getType().columns[i]?.type || { typeClass: 'scalar', logicalType: TEXT_TYPE, nullable: true, isReadOnly: false };
|
|
483
484
|
mutatingScope.registerSymbol(colName.toLowerCase(), (exp, s) =>
|
|
484
485
|
new ColumnReferenceNode(s, exp as AST.ColumnExpr, columnType, attr.id, i));
|
|
485
486
|
}
|
|
@@ -36,7 +36,7 @@ export function buildUpdateStmt(
|
|
|
36
36
|
name: contextVar.name,
|
|
37
37
|
type: {
|
|
38
38
|
typeClass: 'scalar' as const,
|
|
39
|
-
|
|
39
|
+
logicalType: contextVar.logicalType,
|
|
40
40
|
nullable: !contextVar.notNull,
|
|
41
41
|
isReadOnly: true
|
|
42
42
|
},
|
|
@@ -86,7 +86,7 @@ export function buildUpdateStmt(
|
|
|
86
86
|
name: col.name,
|
|
87
87
|
type: {
|
|
88
88
|
typeClass: 'scalar' as const,
|
|
89
|
-
|
|
89
|
+
logicalType: col.logicalType,
|
|
90
90
|
nullable: !col.notNull,
|
|
91
91
|
isReadOnly: false
|
|
92
92
|
},
|
|
@@ -98,7 +98,7 @@ export function buildUpdateStmt(
|
|
|
98
98
|
name: col.name,
|
|
99
99
|
type: {
|
|
100
100
|
typeClass: 'scalar' as const,
|
|
101
|
-
|
|
101
|
+
logicalType: col.logicalType,
|
|
102
102
|
nullable: !col.notNull,
|
|
103
103
|
isReadOnly: false
|
|
104
104
|
},
|
|
@@ -151,7 +151,7 @@ export function buildUpdateStmt(
|
|
|
151
151
|
exp as AST.ColumnExpr,
|
|
152
152
|
{
|
|
153
153
|
typeClass: 'scalar',
|
|
154
|
-
|
|
154
|
+
logicalType: tableColumn.logicalType,
|
|
155
155
|
nullable: !tableColumn.notNull,
|
|
156
156
|
isReadOnly: false
|
|
157
157
|
},
|
|
@@ -168,7 +168,7 @@ export function buildUpdateStmt(
|
|
|
168
168
|
exp as AST.ColumnExpr,
|
|
169
169
|
{
|
|
170
170
|
typeClass: 'scalar',
|
|
171
|
-
|
|
171
|
+
logicalType: tableColumn.logicalType,
|
|
172
172
|
nullable: !tableColumn.notNull,
|
|
173
173
|
isReadOnly: false
|
|
174
174
|
},
|
|
@@ -184,7 +184,7 @@ export function buildUpdateStmt(
|
|
|
184
184
|
exp as AST.ColumnExpr,
|
|
185
185
|
{
|
|
186
186
|
typeClass: 'scalar',
|
|
187
|
-
|
|
187
|
+
logicalType: tableColumn.logicalType,
|
|
188
188
|
nullable: !tableColumn.notNull,
|
|
189
189
|
isReadOnly: false
|
|
190
190
|
},
|
|
@@ -200,7 +200,7 @@ export function buildUpdateStmt(
|
|
|
200
200
|
exp as AST.ColumnExpr,
|
|
201
201
|
{
|
|
202
202
|
typeClass: 'scalar',
|
|
203
|
-
|
|
203
|
+
logicalType: tableColumn.logicalType,
|
|
204
204
|
nullable: !tableColumn.notNull,
|
|
205
205
|
isReadOnly: false
|
|
206
206
|
},
|
|
@@ -6,6 +6,7 @@ import type { FunctionSchema } from '../../schema/function.js';
|
|
|
6
6
|
import { isAggregateFunctionSchema } from '../../schema/function.js';
|
|
7
7
|
import type * as AST from '../../parser/ast.js';
|
|
8
8
|
import { formatExpressionList, formatScalarType } from '../../util/plan-formatter.js';
|
|
9
|
+
import { NULL_TYPE } from '../../types/builtin-types.js';
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
12
|
* Represents an aggregate function call within a SQL query.
|
|
@@ -13,6 +14,7 @@ import { formatExpressionList, formatScalarType } from '../../util/plan-formatte
|
|
|
13
14
|
*/
|
|
14
15
|
export class AggregateFunctionCallNode extends PlanNode implements ScalarPlanNode {
|
|
15
16
|
readonly nodeType = PlanNodeType.ScalarFunctionCall; // Using same type as scalar functions
|
|
17
|
+
private readonly _inferredType?: ScalarType;
|
|
16
18
|
|
|
17
19
|
constructor(
|
|
18
20
|
scope: Scope,
|
|
@@ -22,12 +24,19 @@ export class AggregateFunctionCallNode extends PlanNode implements ScalarPlanNod
|
|
|
22
24
|
public readonly args: ReadonlyArray<ScalarPlanNode>,
|
|
23
25
|
public readonly isDistinct: boolean = false,
|
|
24
26
|
public readonly orderBy?: ReadonlyArray<{ expression: ScalarPlanNode; direction: 'asc' | 'desc' }>,
|
|
25
|
-
public readonly filter?: ScalarPlanNode
|
|
27
|
+
public readonly filter?: ScalarPlanNode,
|
|
28
|
+
inferredType?: ScalarType
|
|
26
29
|
) {
|
|
27
30
|
super(scope);
|
|
31
|
+
this._inferredType = inferredType;
|
|
28
32
|
}
|
|
29
33
|
|
|
30
34
|
getType(): ScalarType {
|
|
35
|
+
// Use inferred type if available
|
|
36
|
+
if (this._inferredType) {
|
|
37
|
+
return this._inferredType;
|
|
38
|
+
}
|
|
39
|
+
|
|
31
40
|
// Get the return type from the function schema
|
|
32
41
|
if (isAggregateFunctionSchema(this.functionSchema)) {
|
|
33
42
|
return this.functionSchema.returnType;
|
|
@@ -36,7 +45,7 @@ export class AggregateFunctionCallNode extends PlanNode implements ScalarPlanNod
|
|
|
36
45
|
// Fallback for non-aggregate functions (shouldn't happen)
|
|
37
46
|
return {
|
|
38
47
|
typeClass: 'scalar',
|
|
39
|
-
|
|
48
|
+
logicalType: NULL_TYPE,
|
|
40
49
|
nullable: true, // Aggregates can return NULL
|
|
41
50
|
isReadOnly: true
|
|
42
51
|
};
|
|
@@ -109,7 +118,8 @@ export class AggregateFunctionCallNode extends PlanNode implements ScalarPlanNod
|
|
|
109
118
|
newArgs,
|
|
110
119
|
this.isDistinct,
|
|
111
120
|
newOrderBy,
|
|
112
|
-
newFilter
|
|
121
|
+
newFilter,
|
|
122
|
+
this._inferredType
|
|
113
123
|
);
|
|
114
124
|
}
|
|
115
125
|
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { PlanNode, type UnaryRelationalNode, type RelationalPlanNode, type Attribute, type TableDescriptor, isRelationalNode } from './plan-node.js';
|
|
2
2
|
import type { RelationType, ScalarType } 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 { Cached } from '../../util/cached.js';
|
|
7
6
|
import type { CTECapable } from '../framework/characteristics.js';
|
|
7
|
+
import { TEXT_TYPE } from '../../types/builtin-types.js';
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* Narrow contract that any node must satisfy to be placed in the CTE lookup map
|
|
@@ -74,7 +74,7 @@ export class CTENode extends PlanNode implements CTEPlanNode, CTEScopeNode, CTEC
|
|
|
74
74
|
}
|
|
75
75
|
// Fallback: generic TEXT scalar if nothing else is available (should not normally happen)
|
|
76
76
|
if (!resolvedType) {
|
|
77
|
-
resolvedType = { typeClass: 'scalar',
|
|
77
|
+
resolvedType = { typeClass: 'scalar', logicalType: TEXT_TYPE, nullable: true, isReadOnly: false } satisfies ScalarType;
|
|
78
78
|
}
|
|
79
79
|
return {
|
|
80
80
|
id: srcAttr?.id ?? PlanNode.nextAttrId(),
|
|
@@ -3,7 +3,7 @@ import { PlanNodeType } from './plan-node-type.js';
|
|
|
3
3
|
import type { Scope } from '../scopes/scope.js';
|
|
4
4
|
import type * as AST from '../../parser/ast.js';
|
|
5
5
|
import { RelationType, type VoidType } from '../../common/datatype.js';
|
|
6
|
-
import {
|
|
6
|
+
import { TEXT_TYPE } from '../../types/builtin-types.js';
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* DECLARE SCHEMA statement plan node
|
|
@@ -66,7 +66,7 @@ export class DiffSchemaNode extends PlanNode implements RelationalPlanNode {
|
|
|
66
66
|
name: 'ddl',
|
|
67
67
|
type: {
|
|
68
68
|
typeClass: 'scalar',
|
|
69
|
-
|
|
69
|
+
logicalType: TEXT_TYPE,
|
|
70
70
|
nullable: false,
|
|
71
71
|
isReadOnly: true,
|
|
72
72
|
},
|
|
@@ -172,7 +172,7 @@ export class ExplainSchemaNode extends PlanNode implements RelationalPlanNode {
|
|
|
172
172
|
name: 'info',
|
|
173
173
|
type: {
|
|
174
174
|
typeClass: 'scalar',
|
|
175
|
-
|
|
175
|
+
logicalType: TEXT_TYPE,
|
|
176
176
|
nullable: false,
|
|
177
177
|
isReadOnly: true,
|
|
178
178
|
},
|
|
@@ -9,18 +9,22 @@ import { FunctionFlags } from '../../common/constants.js';
|
|
|
9
9
|
|
|
10
10
|
export class ScalarFunctionCallNode extends PlanNode implements NaryScalarNode {
|
|
11
11
|
override readonly nodeType = PlanNodeType.ScalarFunctionCall;
|
|
12
|
+
private readonly _inferredType?: ScalarType;
|
|
12
13
|
|
|
13
14
|
constructor(
|
|
14
15
|
scope: Scope,
|
|
15
16
|
public readonly expression: AST.FunctionExpr,
|
|
16
17
|
public readonly functionSchema: FunctionSchema,
|
|
17
|
-
public readonly operands: ScalarPlanNode[]
|
|
18
|
+
public readonly operands: ScalarPlanNode[],
|
|
19
|
+
inferredType?: ScalarType
|
|
18
20
|
) {
|
|
19
21
|
super(scope);
|
|
22
|
+
this._inferredType = inferredType;
|
|
20
23
|
}
|
|
21
24
|
|
|
22
25
|
getType(): ScalarType {
|
|
23
|
-
|
|
26
|
+
// Use inferred type if available, otherwise use schema's return type
|
|
27
|
+
return this._inferredType ?? (this.functionSchema.returnType as ScalarType);
|
|
24
28
|
}
|
|
25
29
|
|
|
26
30
|
getChildren(): readonly ScalarPlanNode[] {
|
|
@@ -54,7 +58,8 @@ export class ScalarFunctionCallNode extends PlanNode implements NaryScalarNode {
|
|
|
54
58
|
this.scope,
|
|
55
59
|
this.expression,
|
|
56
60
|
this.functionSchema,
|
|
57
|
-
newChildren as ScalarPlanNode[]
|
|
61
|
+
newChildren as ScalarPlanNode[],
|
|
62
|
+
this._inferredType
|
|
58
63
|
);
|
|
59
64
|
}
|
|
60
65
|
|
|
@@ -50,7 +50,7 @@ export class InsertNode extends PlanNode implements RelationalPlanNode {
|
|
|
50
50
|
name: col.name,
|
|
51
51
|
type: {
|
|
52
52
|
typeClass: 'scalar',
|
|
53
|
-
|
|
53
|
+
logicalType: col.logicalType,
|
|
54
54
|
nullable: isOld ? true : !col.notNull, // OLD values can be null, NEW follows column constraints
|
|
55
55
|
isReadOnly: false
|
|
56
56
|
},
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { SqlValue } from '../../common/types.js';
|
|
2
2
|
import * as AST from '../../parser/ast.js';
|
|
3
3
|
import { Attribute, type RelationalPlanNode } from './plan-node.js';
|
|
4
4
|
import { PlanNodeType } from './plan-node-type.js';
|
|
@@ -6,6 +6,7 @@ import { expressionToString } from '../../util/ast-stringify.js';
|
|
|
6
6
|
import { PlanNode } from './plan-node.js';
|
|
7
7
|
import { RelationType } from '../../common/datatype.js';
|
|
8
8
|
import { Scope } from '../scopes/scope.js';
|
|
9
|
+
import { TEXT_TYPE } from '../../types/builtin-types.js';
|
|
9
10
|
|
|
10
11
|
export class PragmaPlanNode extends PlanNode implements RelationalPlanNode {
|
|
11
12
|
override readonly nodeType = PlanNodeType.Pragma;
|
|
@@ -29,7 +30,7 @@ export class PragmaPlanNode extends PlanNode implements RelationalPlanNode {
|
|
|
29
30
|
name: "name",
|
|
30
31
|
type: {
|
|
31
32
|
typeClass: 'scalar',
|
|
32
|
-
|
|
33
|
+
logicalType: TEXT_TYPE,
|
|
33
34
|
nullable: false,
|
|
34
35
|
isReadOnly: true,
|
|
35
36
|
},
|
|
@@ -39,7 +40,7 @@ export class PragmaPlanNode extends PlanNode implements RelationalPlanNode {
|
|
|
39
40
|
name: "value",
|
|
40
41
|
type: {
|
|
41
42
|
typeClass: 'scalar',
|
|
42
|
-
|
|
43
|
+
logicalType: TEXT_TYPE,
|
|
43
44
|
nullable: false,
|
|
44
45
|
},
|
|
45
46
|
generated: true,
|
|
@@ -38,7 +38,7 @@ export class TableReferenceNode extends PlanNode implements ZeroAryRelationalNod
|
|
|
38
38
|
name: column.name,
|
|
39
39
|
type: {
|
|
40
40
|
typeClass: 'scalar' as const,
|
|
41
|
-
|
|
41
|
+
logicalType: column.logicalType,
|
|
42
42
|
nullable: !column.notNull,
|
|
43
43
|
isReadOnly: false,
|
|
44
44
|
collationName: column.collation
|
|
@@ -8,6 +8,8 @@ import { Cached } from "../../util/cached.js";
|
|
|
8
8
|
import { formatExpression, formatScalarType } from "../../util/plan-formatter.js";
|
|
9
9
|
import { quereusError } from '../../common/errors.js';
|
|
10
10
|
import { StatusCode } from '../../common/types.js';
|
|
11
|
+
import { NULL_TYPE, INTEGER_TYPE, REAL_TYPE, TEXT_TYPE, BLOB_TYPE, BOOLEAN_TYPE } from "../../types/builtin-types.js";
|
|
12
|
+
import { typeRegistry } from "../../types/registry.js";
|
|
11
13
|
|
|
12
14
|
export class UnaryOpNode extends PlanNode implements UnaryScalarNode {
|
|
13
15
|
readonly nodeType = PlanNodeType.UnaryOp;
|
|
@@ -25,36 +27,31 @@ export class UnaryOpNode extends PlanNode implements UnaryScalarNode {
|
|
|
25
27
|
generateType = (): ScalarType => {
|
|
26
28
|
const operandType = this.operand.getType();
|
|
27
29
|
|
|
28
|
-
let
|
|
29
|
-
let affinity: SqlDataType = operandType.affinity;
|
|
30
|
+
let logicalType = operandType.logicalType;
|
|
30
31
|
let nullable = operandType.nullable;
|
|
31
32
|
|
|
32
33
|
switch (this.expression.operator) {
|
|
33
34
|
case 'NOT':
|
|
34
35
|
case 'IS NULL':
|
|
35
36
|
case 'IS NOT NULL':
|
|
36
|
-
|
|
37
|
-
affinity = SqlDataType.INTEGER;
|
|
37
|
+
logicalType = BOOLEAN_TYPE;
|
|
38
38
|
nullable = false; // Boolean results are never null
|
|
39
39
|
break;
|
|
40
40
|
case '-':
|
|
41
41
|
case '+':
|
|
42
|
-
// Numeric unary operators preserve type
|
|
43
|
-
datatype = operandType.datatype;
|
|
42
|
+
// Numeric unary operators preserve type
|
|
44
43
|
break;
|
|
45
44
|
case '~':
|
|
46
45
|
// Bitwise NOT - results in integer
|
|
47
|
-
|
|
48
|
-
affinity = SqlDataType.INTEGER;
|
|
46
|
+
logicalType = INTEGER_TYPE;
|
|
49
47
|
break;
|
|
50
48
|
}
|
|
51
49
|
|
|
52
50
|
return {
|
|
53
51
|
typeClass: 'scalar',
|
|
54
|
-
|
|
52
|
+
logicalType,
|
|
55
53
|
nullable,
|
|
56
54
|
isReadOnly: operandType.isReadOnly,
|
|
57
|
-
datatype,
|
|
58
55
|
collationName: operandType.collationName,
|
|
59
56
|
};
|
|
60
57
|
}
|
|
@@ -130,17 +127,11 @@ export class BinaryOpNode extends PlanNode implements BinaryScalarNode {
|
|
|
130
127
|
const leftType = this.left.getType();
|
|
131
128
|
const rightType = this.right.getType();
|
|
132
129
|
|
|
133
|
-
|
|
130
|
+
let logicalType = leftType.logicalType;
|
|
134
131
|
|
|
135
|
-
let datatype: SqlDataType | undefined;
|
|
136
132
|
switch (this.expression.operator) {
|
|
137
133
|
case 'OR':
|
|
138
134
|
case 'AND':
|
|
139
|
-
case '+':
|
|
140
|
-
case '-':
|
|
141
|
-
case '*':
|
|
142
|
-
case '/':
|
|
143
|
-
case '%':
|
|
144
135
|
case '=':
|
|
145
136
|
case '!=':
|
|
146
137
|
case '<':
|
|
@@ -150,10 +141,33 @@ export class BinaryOpNode extends PlanNode implements BinaryScalarNode {
|
|
|
150
141
|
case 'IS':
|
|
151
142
|
case 'IS NOT':
|
|
152
143
|
case 'IN':
|
|
153
|
-
|
|
144
|
+
// Comparison and logical operators return boolean
|
|
145
|
+
logicalType = BOOLEAN_TYPE;
|
|
146
|
+
break;
|
|
147
|
+
case '+':
|
|
148
|
+
case '-':
|
|
149
|
+
case '*':
|
|
150
|
+
case '/':
|
|
151
|
+
case '%':
|
|
152
|
+
// Arithmetic operators - implement numeric type promotion
|
|
153
|
+
// Rules: INTEGER + INTEGER -> INTEGER, INTEGER + REAL -> REAL, REAL + REAL -> REAL
|
|
154
|
+
if (leftType.logicalType.isNumeric && rightType.logicalType.isNumeric) {
|
|
155
|
+
// Both operands are numeric
|
|
156
|
+
if (leftType.logicalType.name === 'REAL' || rightType.logicalType.name === 'REAL') {
|
|
157
|
+
// If either is REAL, result is REAL
|
|
158
|
+
logicalType = REAL_TYPE;
|
|
159
|
+
} else {
|
|
160
|
+
// Both are INTEGER, result is INTEGER
|
|
161
|
+
logicalType = INTEGER_TYPE;
|
|
162
|
+
}
|
|
163
|
+
} else {
|
|
164
|
+
// Non-numeric operands - use left operand type (fallback)
|
|
165
|
+
logicalType = leftType.logicalType;
|
|
166
|
+
}
|
|
154
167
|
break;
|
|
155
168
|
case '||':
|
|
156
|
-
|
|
169
|
+
// String concatenation
|
|
170
|
+
logicalType = TEXT_TYPE;
|
|
157
171
|
break;
|
|
158
172
|
};
|
|
159
173
|
|
|
@@ -162,10 +176,9 @@ export class BinaryOpNode extends PlanNode implements BinaryScalarNode {
|
|
|
162
176
|
|
|
163
177
|
return {
|
|
164
178
|
typeClass: 'scalar',
|
|
165
|
-
|
|
179
|
+
logicalType,
|
|
166
180
|
nullable: leftType.nullable || rightType.nullable,
|
|
167
181
|
isReadOnly: leftType.isReadOnly || rightType.isReadOnly,
|
|
168
|
-
datatype,
|
|
169
182
|
collationName,
|
|
170
183
|
};
|
|
171
184
|
}
|
|
@@ -252,55 +265,49 @@ export class LiteralNode extends PlanNode implements ZeroAryScalarNode, Constant
|
|
|
252
265
|
if (value === null) {
|
|
253
266
|
return {
|
|
254
267
|
typeClass: 'scalar',
|
|
255
|
-
|
|
268
|
+
logicalType: NULL_TYPE,
|
|
256
269
|
nullable: true,
|
|
257
270
|
isReadOnly: true,
|
|
258
|
-
datatype: SqlDataType.NULL,
|
|
259
271
|
};
|
|
260
272
|
}
|
|
261
273
|
if (typeof value === 'number') {
|
|
262
274
|
return {
|
|
263
275
|
typeClass: 'scalar',
|
|
264
|
-
|
|
276
|
+
logicalType: REAL_TYPE,
|
|
265
277
|
nullable: false,
|
|
266
278
|
isReadOnly: true,
|
|
267
|
-
datatype: SqlDataType.REAL,
|
|
268
279
|
};
|
|
269
280
|
}
|
|
270
281
|
if (typeof value === 'bigint') {
|
|
271
282
|
return {
|
|
272
283
|
typeClass: 'scalar',
|
|
273
|
-
|
|
284
|
+
logicalType: INTEGER_TYPE,
|
|
274
285
|
nullable: false,
|
|
275
286
|
isReadOnly: true,
|
|
276
|
-
datatype: SqlDataType.INTEGER,
|
|
277
287
|
};
|
|
278
288
|
}
|
|
279
289
|
if (typeof value === 'string') {
|
|
280
290
|
return {
|
|
281
291
|
typeClass: 'scalar',
|
|
282
|
-
|
|
292
|
+
logicalType: TEXT_TYPE,
|
|
283
293
|
nullable: false,
|
|
284
294
|
isReadOnly: true,
|
|
285
|
-
datatype: SqlDataType.TEXT,
|
|
286
295
|
};
|
|
287
296
|
}
|
|
288
297
|
if (typeof value === 'boolean') {
|
|
289
298
|
return {
|
|
290
299
|
typeClass: 'scalar',
|
|
291
|
-
|
|
300
|
+
logicalType: BOOLEAN_TYPE,
|
|
292
301
|
nullable: false,
|
|
293
302
|
isReadOnly: true,
|
|
294
|
-
datatype: SqlDataType.INTEGER,
|
|
295
303
|
};
|
|
296
304
|
}
|
|
297
305
|
if (value instanceof Uint8Array) {
|
|
298
306
|
return {
|
|
299
307
|
typeClass: 'scalar',
|
|
300
|
-
|
|
308
|
+
logicalType: BLOB_TYPE,
|
|
301
309
|
nullable: false,
|
|
302
310
|
isReadOnly: true,
|
|
303
|
-
datatype: SqlDataType.BLOB,
|
|
304
311
|
};
|
|
305
312
|
}
|
|
306
313
|
quereusError(`Unknown literal type ${typeof value}`, StatusCode.INTERNAL);
|
|
@@ -377,16 +384,15 @@ export class CaseExprNode extends PlanNode implements NaryScalarNode {
|
|
|
377
384
|
// No THEN clauses and no ELSE - should not happen in valid SQL
|
|
378
385
|
return {
|
|
379
386
|
typeClass: 'scalar',
|
|
380
|
-
|
|
387
|
+
logicalType: NULL_TYPE,
|
|
381
388
|
nullable: true,
|
|
382
389
|
isReadOnly: true,
|
|
383
|
-
datatype: SqlDataType.NULL,
|
|
384
390
|
};
|
|
385
391
|
}
|
|
386
392
|
|
|
387
393
|
// Use the first result expression as the base type
|
|
388
394
|
const firstType = resultExpressions[0].getType();
|
|
389
|
-
let
|
|
395
|
+
let logicalType = firstType.logicalType;
|
|
390
396
|
let nullable = firstType.nullable;
|
|
391
397
|
let isReadOnly = firstType.isReadOnly;
|
|
392
398
|
let collationName = firstType.collationName;
|
|
@@ -411,9 +417,9 @@ export class CaseExprNode extends PlanNode implements NaryScalarNode {
|
|
|
411
417
|
}
|
|
412
418
|
|
|
413
419
|
// TODO: Implement proper type coercion rules for SQL
|
|
414
|
-
// For now, if types differ, default to TEXT
|
|
415
|
-
if (exprType.
|
|
416
|
-
|
|
420
|
+
// For now, if types differ, default to TEXT
|
|
421
|
+
if (exprType.logicalType !== logicalType) {
|
|
422
|
+
logicalType = TEXT_TYPE;
|
|
417
423
|
}
|
|
418
424
|
}
|
|
419
425
|
|
|
@@ -424,11 +430,10 @@ export class CaseExprNode extends PlanNode implements NaryScalarNode {
|
|
|
424
430
|
|
|
425
431
|
return {
|
|
426
432
|
typeClass: 'scalar',
|
|
427
|
-
|
|
433
|
+
logicalType,
|
|
428
434
|
nullable,
|
|
429
435
|
isReadOnly,
|
|
430
436
|
collationName,
|
|
431
|
-
// Don't set datatype since it can vary based on runtime conditions
|
|
432
437
|
};
|
|
433
438
|
}
|
|
434
439
|
|
|
@@ -558,69 +563,17 @@ export class CastNode extends PlanNode implements UnaryScalarNode {
|
|
|
558
563
|
|
|
559
564
|
generateType = (): ScalarType => {
|
|
560
565
|
const operandType = this.operand.getType();
|
|
561
|
-
const targetType = this.expression.targetType
|
|
562
|
-
|
|
563
|
-
//
|
|
564
|
-
|
|
565
|
-
let affinity: SqlDataType;
|
|
566
|
-
|
|
567
|
-
switch (targetType) {
|
|
568
|
-
case 'INTEGER':
|
|
569
|
-
case 'INT':
|
|
570
|
-
case 'TINYINT':
|
|
571
|
-
case 'SMALLINT':
|
|
572
|
-
case 'MEDIUMINT':
|
|
573
|
-
case 'BIGINT':
|
|
574
|
-
case 'UNSIGNED BIG INT':
|
|
575
|
-
case 'INT2':
|
|
576
|
-
case 'INT8':
|
|
577
|
-
datatype = SqlDataType.INTEGER;
|
|
578
|
-
affinity = SqlDataType.INTEGER;
|
|
579
|
-
break;
|
|
580
|
-
case 'REAL':
|
|
581
|
-
case 'DOUBLE':
|
|
582
|
-
case 'DOUBLE PRECISION':
|
|
583
|
-
case 'FLOAT':
|
|
584
|
-
datatype = SqlDataType.REAL;
|
|
585
|
-
affinity = SqlDataType.REAL;
|
|
586
|
-
break;
|
|
587
|
-
case 'TEXT':
|
|
588
|
-
case 'CHARACTER':
|
|
589
|
-
case 'VARCHAR':
|
|
590
|
-
case 'VARYING CHARACTER':
|
|
591
|
-
case 'NCHAR':
|
|
592
|
-
case 'NATIVE CHARACTER':
|
|
593
|
-
case 'NVARCHAR':
|
|
594
|
-
case 'CLOB':
|
|
595
|
-
datatype = SqlDataType.TEXT;
|
|
596
|
-
affinity = SqlDataType.TEXT;
|
|
597
|
-
break;
|
|
598
|
-
case 'BLOB':
|
|
599
|
-
datatype = SqlDataType.BLOB;
|
|
600
|
-
affinity = SqlDataType.BLOB;
|
|
601
|
-
break;
|
|
602
|
-
case 'NUMERIC':
|
|
603
|
-
case 'DECIMAL':
|
|
604
|
-
case 'BOOLEAN':
|
|
605
|
-
case 'DATE':
|
|
606
|
-
case 'DATETIME':
|
|
607
|
-
datatype = SqlDataType.NUMERIC;
|
|
608
|
-
affinity = SqlDataType.NUMERIC;
|
|
609
|
-
break;
|
|
610
|
-
default:
|
|
611
|
-
// For unknown types, default to BLOB affinity
|
|
612
|
-
datatype = SqlDataType.BLOB;
|
|
613
|
-
affinity = SqlDataType.BLOB;
|
|
614
|
-
break;
|
|
615
|
-
}
|
|
566
|
+
const targetType = this.expression.targetType;
|
|
567
|
+
|
|
568
|
+
// Look up the logical type from the type registry
|
|
569
|
+
const logicalType = typeRegistry.getTypeOrDefault(targetType);
|
|
616
570
|
|
|
617
571
|
return {
|
|
618
572
|
typeClass: 'scalar',
|
|
619
|
-
|
|
573
|
+
logicalType,
|
|
620
574
|
nullable: operandType.nullable, // CAST preserves nullability
|
|
621
575
|
isReadOnly: operandType.isReadOnly,
|
|
622
|
-
|
|
623
|
-
collationName: affinity === SqlDataType.TEXT ? operandType.collationName : undefined,
|
|
576
|
+
collationName: logicalType.isTextual ? operandType.collationName : undefined,
|
|
624
577
|
};
|
|
625
578
|
}
|
|
626
579
|
|
|
@@ -756,13 +709,12 @@ export class BetweenNode extends PlanNode implements TernaryScalarNode {
|
|
|
756
709
|
}
|
|
757
710
|
|
|
758
711
|
getType(): ScalarType {
|
|
759
|
-
// BETWEEN always returns
|
|
712
|
+
// BETWEEN always returns BOOLEAN
|
|
760
713
|
return {
|
|
761
714
|
typeClass: 'scalar',
|
|
762
|
-
|
|
715
|
+
logicalType: BOOLEAN_TYPE,
|
|
763
716
|
nullable: false,
|
|
764
717
|
isReadOnly: true,
|
|
765
|
-
datatype: SqlDataType.INTEGER,
|
|
766
718
|
};
|
|
767
719
|
}
|
|
768
720
|
|
|
@@ -3,7 +3,7 @@ import { isRelationalNode, PlanNode, type Attribute, type RelationalPlanNode, ty
|
|
|
3
3
|
import type { RelationType } from '../../common/datatype.js';
|
|
4
4
|
import type { Scope } from '../scopes/scope.js';
|
|
5
5
|
import { Cached } from '../../util/cached.js';
|
|
6
|
-
import {
|
|
6
|
+
import { INTEGER_TYPE } from '../../types/builtin-types.js';
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Represents a sequencing operation that adds a row number column to convert bags to sets.
|
|
@@ -31,7 +31,7 @@ export class SequencingNode extends PlanNode implements UnaryRelationalNode {
|
|
|
31
31
|
name: this.sequenceColumnName,
|
|
32
32
|
type: {
|
|
33
33
|
typeClass: 'scalar' as const,
|
|
34
|
-
|
|
34
|
+
logicalType: INTEGER_TYPE,
|
|
35
35
|
nullable: false,
|
|
36
36
|
isReadOnly: true
|
|
37
37
|
},
|
|
@@ -2,7 +2,7 @@ import { PlanNodeType } from './plan-node-type.js';
|
|
|
2
2
|
import { PlanNode, type RelationalPlanNode } from './plan-node.js';
|
|
3
3
|
import type { ScalarType } from '../../common/datatype.js';
|
|
4
4
|
import type { Scope } from '../scopes/scope.js';
|
|
5
|
-
import {
|
|
5
|
+
import { INTEGER_TYPE } from '../../types/builtin-types.js';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* A sink node that consumes an async iterable for side effects.
|
|
@@ -25,7 +25,7 @@ export class SinkNode extends PlanNode {
|
|
|
25
25
|
return {
|
|
26
26
|
typeClass: 'scalar',
|
|
27
27
|
isReadOnly: true,
|
|
28
|
-
|
|
28
|
+
logicalType: INTEGER_TYPE,
|
|
29
29
|
nullable: false
|
|
30
30
|
};
|
|
31
31
|
}
|