@quereus/quereus 0.6.0 → 0.6.2
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/src/common/type-inference.d.ts +9 -1
- package/dist/src/common/type-inference.d.ts.map +1 -1
- package/dist/src/common/type-inference.js +11 -3
- package/dist/src/common/type-inference.js.map +1 -1
- package/dist/src/core/database.d.ts +27 -1
- package/dist/src/core/database.d.ts.map +1 -1
- package/dist/src/core/database.js +39 -6
- package/dist/src/core/database.js.map +1 -1
- package/dist/src/core/param.d.ts +17 -1
- package/dist/src/core/param.d.ts.map +1 -1
- package/dist/src/core/param.js +23 -1
- package/dist/src/core/param.js.map +1 -1
- package/dist/src/core/statement.d.ts +10 -1
- package/dist/src/core/statement.d.ts.map +1 -1
- package/dist/src/core/statement.js +71 -5
- package/dist/src/core/statement.js.map +1 -1
- package/dist/src/func/builtins/datetime.js +9 -9
- package/dist/src/func/builtins/datetime.js.map +1 -1
- package/dist/src/func/builtins/json.js +11 -11
- package/dist/src/func/builtins/json.js.map +1 -1
- package/dist/src/func/builtins/string.js +2 -2
- package/dist/src/func/builtins/string.js.map +1 -1
- package/dist/src/planner/nodes/subquery.js +3 -3
- package/dist/src/planner/nodes/subquery.js.map +1 -1
- package/dist/src/planner/scopes/param.d.ts +2 -2
- package/dist/src/planner/scopes/param.d.ts.map +1 -1
- package/dist/src/planner/scopes/param.js +9 -9
- package/dist/src/planner/scopes/param.js.map +1 -1
- package/dist/src/runtime/emit/between.js +2 -2
- package/dist/src/runtime/emit/between.js.map +1 -1
- package/dist/src/runtime/emit/binary.d.ts.map +1 -1
- package/dist/src/runtime/emit/binary.js +26 -28
- package/dist/src/runtime/emit/binary.js.map +1 -1
- package/dist/src/runtime/emit/subquery.js +8 -8
- package/dist/src/runtime/emit/subquery.js.map +1 -1
- package/dist/src/runtime/emit/temporal-arithmetic.d.ts +1 -1
- package/dist/src/runtime/emit/temporal-arithmetic.js +7 -7
- package/dist/src/runtime/emit/temporal-arithmetic.js.map +1 -1
- package/dist/src/runtime/emit/unary.js +4 -4
- package/dist/src/runtime/emit/unary.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/logical-type.d.ts +5 -0
- package/dist/src/types/logical-type.d.ts.map +1 -1
- package/dist/src/types/logical-type.js +15 -0
- package/dist/src/types/logical-type.js.map +1 -1
- package/package.json +1 -1
- package/src/common/type-inference.ts +11 -3
- package/src/core/database.ts +41 -6
- package/src/core/param.ts +23 -1
- package/src/core/statement.ts +89 -5
- package/src/func/builtins/datetime.ts +9 -9
- package/src/func/builtins/json.ts +11 -11
- package/src/func/builtins/string.ts +2 -2
- package/src/planner/nodes/subquery.ts +3 -3
- package/src/planner/scopes/param.ts +9 -9
- package/src/runtime/emit/between.ts +2 -2
- package/src/runtime/emit/binary.ts +26 -28
- package/src/runtime/emit/subquery.ts +8 -8
- package/src/runtime/emit/temporal-arithmetic.ts +7 -7
- package/src/runtime/emit/unary.ts +4 -4
- package/src/types/index.ts +1 -1
- package/src/types/logical-type.ts +16 -0
|
@@ -152,7 +152,7 @@ export function emitComparisonOp(plan: BinaryOpNode, ctx: EmissionContext): Inst
|
|
|
152
152
|
|
|
153
153
|
// Apply type coercion before comparison
|
|
154
154
|
const [coercedV1, coercedV2] = coerceForComparison(v1, v2);
|
|
155
|
-
return compareSqlValuesFast(coercedV1, coercedV2, collationFunc) === 0
|
|
155
|
+
return compareSqlValuesFast(coercedV1, coercedV2, collationFunc) === 0;
|
|
156
156
|
};
|
|
157
157
|
break;
|
|
158
158
|
case '!=':
|
|
@@ -169,7 +169,7 @@ export function emitComparisonOp(plan: BinaryOpNode, ctx: EmissionContext): Inst
|
|
|
169
169
|
|
|
170
170
|
// Apply type coercion before comparison
|
|
171
171
|
const [coercedV1, coercedV2] = coerceForComparison(v1, v2);
|
|
172
|
-
return compareSqlValuesFast(coercedV1, coercedV2, collationFunc) !== 0
|
|
172
|
+
return compareSqlValuesFast(coercedV1, coercedV2, collationFunc) !== 0;
|
|
173
173
|
};
|
|
174
174
|
break;
|
|
175
175
|
case '<':
|
|
@@ -185,7 +185,7 @@ export function emitComparisonOp(plan: BinaryOpNode, ctx: EmissionContext): Inst
|
|
|
185
185
|
|
|
186
186
|
// Apply type coercion before comparison
|
|
187
187
|
const [coercedV1, coercedV2] = coerceForComparison(v1, v2);
|
|
188
|
-
return compareSqlValuesFast(coercedV1, coercedV2, collationFunc) < 0
|
|
188
|
+
return compareSqlValuesFast(coercedV1, coercedV2, collationFunc) < 0;
|
|
189
189
|
};
|
|
190
190
|
break;
|
|
191
191
|
case '<=':
|
|
@@ -201,7 +201,7 @@ export function emitComparisonOp(plan: BinaryOpNode, ctx: EmissionContext): Inst
|
|
|
201
201
|
|
|
202
202
|
// Apply type coercion before comparison
|
|
203
203
|
const [coercedV1, coercedV2] = coerceForComparison(v1, v2);
|
|
204
|
-
return compareSqlValuesFast(coercedV1, coercedV2, collationFunc) <= 0
|
|
204
|
+
return compareSqlValuesFast(coercedV1, coercedV2, collationFunc) <= 0;
|
|
205
205
|
};
|
|
206
206
|
break;
|
|
207
207
|
case '>':
|
|
@@ -219,9 +219,7 @@ export function emitComparisonOp(plan: BinaryOpNode, ctx: EmissionContext): Inst
|
|
|
219
219
|
|
|
220
220
|
// Apply type coercion before comparison
|
|
221
221
|
const [coercedV1, coercedV2] = coerceForComparison(v1, v2);
|
|
222
|
-
|
|
223
|
-
const finalResult = comparisonResult > 0 ? 1 : 0;
|
|
224
|
-
return finalResult;
|
|
222
|
+
return compareSqlValuesFast(coercedV1, coercedV2, collationFunc) > 0;
|
|
225
223
|
};
|
|
226
224
|
break;
|
|
227
225
|
case '>=':
|
|
@@ -237,7 +235,7 @@ export function emitComparisonOp(plan: BinaryOpNode, ctx: EmissionContext): Inst
|
|
|
237
235
|
|
|
238
236
|
// Apply type coercion before comparison
|
|
239
237
|
const [coercedV1, coercedV2] = coerceForComparison(v1, v2);
|
|
240
|
-
return compareSqlValuesFast(coercedV1, coercedV2, collationFunc) >= 0
|
|
238
|
+
return compareSqlValuesFast(coercedV1, coercedV2, collationFunc) >= 0;
|
|
241
239
|
};
|
|
242
240
|
break;
|
|
243
241
|
default:
|
|
@@ -283,38 +281,38 @@ export function emitLogicalOp(plan: BinaryOpNode, ctx: EmissionContext): Instruc
|
|
|
283
281
|
// SQL three-valued logic
|
|
284
282
|
switch (operator) {
|
|
285
283
|
case 'AND': {
|
|
286
|
-
// NULL AND x -> NULL if x is true or NULL, otherwise
|
|
287
|
-
//
|
|
288
|
-
//
|
|
284
|
+
// NULL AND x -> NULL if x is true or NULL, otherwise false
|
|
285
|
+
// false AND x -> false
|
|
286
|
+
// true AND x -> x
|
|
289
287
|
if (v1 === null) {
|
|
290
|
-
return (v2 === null || v2) ? null :
|
|
288
|
+
return (v2 === null || v2) ? null : false;
|
|
291
289
|
}
|
|
292
|
-
if (!v1) return
|
|
293
|
-
return v2 === null ? null : (v2 ?
|
|
290
|
+
if (!v1) return false;
|
|
291
|
+
return v2 === null ? null : (v2 ? true : false);
|
|
294
292
|
}
|
|
295
293
|
|
|
296
294
|
case 'OR': {
|
|
297
|
-
// NULL OR x -> NULL if x is false or NULL, otherwise
|
|
298
|
-
//
|
|
299
|
-
//
|
|
295
|
+
// NULL OR x -> NULL if x is false or NULL, otherwise true
|
|
296
|
+
// true OR x -> true
|
|
297
|
+
// false OR x -> x
|
|
300
298
|
if (v1 === null) {
|
|
301
|
-
return (v2 === null || !v2) ? null :
|
|
299
|
+
return (v2 === null || !v2) ? null : true;
|
|
302
300
|
}
|
|
303
|
-
if (v1) return
|
|
304
|
-
return v2 === null ? null : (v2 ?
|
|
301
|
+
if (v1) return true;
|
|
302
|
+
return v2 === null ? null : (v2 ? true : false);
|
|
305
303
|
}
|
|
306
304
|
|
|
307
305
|
case 'XOR': {
|
|
308
306
|
// NULL XOR x -> NULL
|
|
309
307
|
// x XOR NULL -> NULL
|
|
310
|
-
//
|
|
311
|
-
//
|
|
312
|
-
//
|
|
313
|
-
//
|
|
308
|
+
// false XOR false -> false
|
|
309
|
+
// false XOR true -> true
|
|
310
|
+
// true XOR false -> true
|
|
311
|
+
// true XOR true -> false
|
|
314
312
|
if (v1 === null || v2 === null) return null;
|
|
315
|
-
const b1 = v1
|
|
316
|
-
const b2 = v2
|
|
317
|
-
return b1 !== b2
|
|
313
|
+
const b1 = !!v1;
|
|
314
|
+
const b2 = !!v2;
|
|
315
|
+
return b1 !== b2;
|
|
318
316
|
}
|
|
319
317
|
|
|
320
318
|
default:
|
|
@@ -344,7 +342,7 @@ export function emitLikeOp(plan: BinaryOpNode, ctx: EmissionContext): Instructio
|
|
|
344
342
|
const textStr = String(text);
|
|
345
343
|
const patternStr = String(pattern);
|
|
346
344
|
|
|
347
|
-
return simpleLike(patternStr, textStr)
|
|
345
|
+
return simpleLike(patternStr, textStr);
|
|
348
346
|
}
|
|
349
347
|
|
|
350
348
|
const leftExpr = emitPlanNode(plan.left, ctx);
|
|
@@ -63,13 +63,13 @@ export function emitIn(plan: InNode, ctx: EmissionContext): Instruction {
|
|
|
63
63
|
}
|
|
64
64
|
// Check for match immediately - no need to materialize
|
|
65
65
|
if (compareSqlValuesFast(condition, rowValue, collation) === 0) {
|
|
66
|
-
return
|
|
66
|
+
return true; // Found a match
|
|
67
67
|
}
|
|
68
68
|
}
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
// No match found - if any value was NULL, result is NULL
|
|
72
|
-
return hasNull ? null :
|
|
72
|
+
return hasNull ? null : false;
|
|
73
73
|
}
|
|
74
74
|
|
|
75
75
|
const sourceInstruction = emitPlanNode(plan.source, ctx);
|
|
@@ -103,11 +103,11 @@ export function emitIn(plan: InNode, ctx: EmissionContext): Instruction {
|
|
|
103
103
|
// Check if condition exists in pre-built tree
|
|
104
104
|
const path = tree.find(condition);
|
|
105
105
|
if (path.on) {
|
|
106
|
-
return
|
|
106
|
+
return true; // Found a match
|
|
107
107
|
}
|
|
108
108
|
|
|
109
109
|
// No match found - if any value was NULL, result is NULL
|
|
110
|
-
return hasNull ? null :
|
|
110
|
+
return hasNull ? null : false;
|
|
111
111
|
}
|
|
112
112
|
|
|
113
113
|
const values = plan.values.map(val => (val as unknown as ConstantNode).getValue());
|
|
@@ -163,12 +163,12 @@ export function emitIn(plan: InNode, ctx: EmissionContext): Instruction {
|
|
|
163
163
|
continue;
|
|
164
164
|
}
|
|
165
165
|
if (compareSqlValuesFast(condition, value, collation) === 0) {
|
|
166
|
-
return
|
|
166
|
+
return true; // Found a match
|
|
167
167
|
}
|
|
168
168
|
}
|
|
169
169
|
|
|
170
170
|
// No match found - if any value was NULL, result is NULL
|
|
171
|
-
return hasNull ? null :
|
|
171
|
+
return hasNull ? null : false;
|
|
172
172
|
}
|
|
173
173
|
|
|
174
174
|
const conditionExpr = emitPlanNode(plan.condition, ctx);
|
|
@@ -188,9 +188,9 @@ export function emitIn(plan: InNode, ctx: EmissionContext): Instruction {
|
|
|
188
188
|
export function emitExists(plan: ExistsNode, ctx: EmissionContext): Instruction {
|
|
189
189
|
async function run(_rctx: RuntimeContext, input: AsyncIterable<Row>): Promise<SqlValue> {
|
|
190
190
|
for await (const _row of input) {
|
|
191
|
-
return
|
|
191
|
+
return true; // First row => TRUE
|
|
192
192
|
}
|
|
193
|
-
return
|
|
193
|
+
return false; // Empty => FALSE
|
|
194
194
|
}
|
|
195
195
|
|
|
196
196
|
const innerInstruction = emitPlanNode(plan.subquery, ctx);
|
|
@@ -268,7 +268,7 @@ export function emitTemporalArithmetic(plan: BinaryOpNode, ctx: EmissionContext)
|
|
|
268
268
|
* @param operator The comparison operator (=, !=, <, <=, >, >=)
|
|
269
269
|
* @param v1 First value
|
|
270
270
|
* @param v2 Second value
|
|
271
|
-
* @returns Comparison result (
|
|
271
|
+
* @returns Comparison result (boolean) if temporal comparison, undefined otherwise
|
|
272
272
|
*/
|
|
273
273
|
export function tryTemporalComparison(operator: string, v1: SqlValue, v2: SqlValue): SqlValue | undefined {
|
|
274
274
|
// Check if both values are timespans
|
|
@@ -284,18 +284,18 @@ export function tryTemporalComparison(operator: string, v1: SqlValue, v2: SqlVal
|
|
|
284
284
|
switch (operator) {
|
|
285
285
|
case '=':
|
|
286
286
|
case '==':
|
|
287
|
-
return cmp === 0
|
|
287
|
+
return cmp === 0;
|
|
288
288
|
case '!=':
|
|
289
289
|
case '<>':
|
|
290
|
-
return cmp !== 0
|
|
290
|
+
return cmp !== 0;
|
|
291
291
|
case '<':
|
|
292
|
-
return cmp < 0
|
|
292
|
+
return cmp < 0;
|
|
293
293
|
case '<=':
|
|
294
|
-
return cmp <= 0
|
|
294
|
+
return cmp <= 0;
|
|
295
295
|
case '>':
|
|
296
|
-
return cmp > 0
|
|
296
|
+
return cmp > 0;
|
|
297
297
|
case '>=':
|
|
298
|
-
return cmp >= 0
|
|
298
|
+
return cmp >= 0;
|
|
299
299
|
default:
|
|
300
300
|
return undefined;
|
|
301
301
|
}
|
|
@@ -19,23 +19,23 @@ export function emitUnaryOp(plan: UnaryOpNode, ctx: EmissionContext): Instructio
|
|
|
19
19
|
switch (operator) {
|
|
20
20
|
case 'NOT':
|
|
21
21
|
run = (ctx: RuntimeContext, operand: SqlValue) => {
|
|
22
|
-
// SQL NOT: NULL -> NULL,
|
|
22
|
+
// SQL NOT: NULL -> NULL, false -> true, true -> false
|
|
23
23
|
if (operand === null) return null;
|
|
24
|
-
return isTruthy(operand)
|
|
24
|
+
return !isTruthy(operand);
|
|
25
25
|
};
|
|
26
26
|
note = 'NOT';
|
|
27
27
|
break;
|
|
28
28
|
|
|
29
29
|
case 'IS NULL':
|
|
30
30
|
run = (ctx: RuntimeContext, operand: SqlValue) => {
|
|
31
|
-
return operand === null
|
|
31
|
+
return operand === null;
|
|
32
32
|
};
|
|
33
33
|
note = 'IS NULL';
|
|
34
34
|
break;
|
|
35
35
|
|
|
36
36
|
case 'IS NOT NULL':
|
|
37
37
|
run = (ctx: RuntimeContext, operand: SqlValue) => {
|
|
38
|
-
return operand !== null
|
|
38
|
+
return operand !== null;
|
|
39
39
|
};
|
|
40
40
|
note = 'IS NOT NULL';
|
|
41
41
|
break;
|
package/src/types/index.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// Core type system exports
|
|
2
|
-
export { PhysicalType, type LogicalType, getPhysicalType } from './logical-type.js';
|
|
2
|
+
export { PhysicalType, type LogicalType, getPhysicalType, physicalTypeName } from './logical-type.js';
|
|
3
3
|
|
|
4
4
|
// Built-in types
|
|
5
5
|
export { NULL_TYPE, INTEGER_TYPE, REAL_TYPE, TEXT_TYPE, BLOB_TYPE, BOOLEAN_TYPE, NUMERIC_TYPE, ANY_TYPE } from './builtin-types.js';
|
|
@@ -73,3 +73,19 @@ export function getPhysicalType(value: SqlValue): PhysicalType {
|
|
|
73
73
|
return PhysicalType.NULL;
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
+
/**
|
|
77
|
+
* Get a human-readable name for a physical type code.
|
|
78
|
+
* Useful for error messages and debugging.
|
|
79
|
+
*/
|
|
80
|
+
export function physicalTypeName(physicalType: PhysicalType): string {
|
|
81
|
+
switch (physicalType) {
|
|
82
|
+
case PhysicalType.NULL: return 'NULL';
|
|
83
|
+
case PhysicalType.INTEGER: return 'INTEGER';
|
|
84
|
+
case PhysicalType.REAL: return 'REAL';
|
|
85
|
+
case PhysicalType.TEXT: return 'TEXT';
|
|
86
|
+
case PhysicalType.BLOB: return 'BLOB';
|
|
87
|
+
case PhysicalType.BOOLEAN: return 'BOOLEAN';
|
|
88
|
+
default: return 'UNKNOWN';
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|