squirreling 0.7.9 → 0.7.10
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 +1 -0
- package/package.json +5 -5
- package/src/backend/dataSource.js +1 -1
- package/src/execute/expression.js +7 -0
- package/src/index.d.ts +14 -1
- package/src/parse/joins.js +3 -9
- package/src/validation.js +2 -1
- package/src/validationErrors.js +2 -0
package/README.md
CHANGED
|
@@ -104,4 +104,5 @@ Squirreling mostly follows the SQL standard. The following features are supporte
|
|
|
104
104
|
- Date: `CURRENT_DATE`, `CURRENT_TIME`, `CURRENT_TIMESTAMP`, `INTERVAL`
|
|
105
105
|
- Json: `JSON_VALUE`, `JSON_QUERY`, `JSON_OBJECT`
|
|
106
106
|
- Regex: `REGEXP_SUBSTR`, `REGEXP_REPLACE`
|
|
107
|
+
- Conditional: `COALESCE`, `NULLIF`
|
|
107
108
|
- User-defined functions (UDFs)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "squirreling",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.10",
|
|
4
4
|
"description": "Squirreling SQL Engine",
|
|
5
5
|
"author": "Hyperparam",
|
|
6
6
|
"homepage": "https://hyperparam.app",
|
|
@@ -37,11 +37,11 @@
|
|
|
37
37
|
"test": "vitest run"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
|
-
"@types/node": "25.0
|
|
41
|
-
"@vitest/coverage-v8": "4.0.
|
|
40
|
+
"@types/node": "25.2.0",
|
|
41
|
+
"@vitest/coverage-v8": "4.0.18",
|
|
42
42
|
"eslint": "9.39.2",
|
|
43
|
-
"eslint-plugin-jsdoc": "62.
|
|
43
|
+
"eslint-plugin-jsdoc": "62.5.0",
|
|
44
44
|
"typescript": "5.9.3",
|
|
45
|
-
"vitest": "4.0.
|
|
45
|
+
"vitest": "4.0.18"
|
|
46
46
|
}
|
|
47
47
|
}
|
|
@@ -268,6 +268,13 @@ export async function evaluateExpr({ node, row, tables, functions, rowIndex, row
|
|
|
268
268
|
return null
|
|
269
269
|
}
|
|
270
270
|
|
|
271
|
+
if (funcName === 'NULLIF') {
|
|
272
|
+
// NULLIF(a, b) returns null if a = b, otherwise returns a
|
|
273
|
+
const val1 = await evaluateExpr({ node: node.args[0], row, tables, functions, rowIndex, rows })
|
|
274
|
+
const val2 = await evaluateExpr({ node: node.args[1], row, tables, functions, rowIndex, rows })
|
|
275
|
+
return val1 == val2 ? null : val1
|
|
276
|
+
}
|
|
277
|
+
|
|
271
278
|
if (funcName === 'CURRENT_DATE') {
|
|
272
279
|
return new Date().toISOString().split('T')[0]
|
|
273
280
|
}
|
package/src/index.d.ts
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
import type { AsyncDataSource, AsyncRow, ExecuteSqlOptions, ParseSqlOptions, SelectStatement, SqlPrimitive, Token } from './types.js'
|
|
2
|
-
export type {
|
|
2
|
+
export type {
|
|
3
|
+
AsyncCells,
|
|
4
|
+
AsyncDataSource,
|
|
5
|
+
AsyncRow,
|
|
6
|
+
ExecuteSqlOptions,
|
|
7
|
+
ExprNode,
|
|
8
|
+
ParseSqlOptions,
|
|
9
|
+
QueryHints,
|
|
10
|
+
ScanOptions,
|
|
11
|
+
SelectStatement,
|
|
12
|
+
SqlPrimitive,
|
|
13
|
+
Token,
|
|
14
|
+
UserDefinedFunction,
|
|
15
|
+
} from './types.js'
|
|
3
16
|
|
|
4
17
|
/**
|
|
5
18
|
* Executes a SQL SELECT query against an array of data rows
|
package/src/parse/joins.js
CHANGED
|
@@ -24,21 +24,15 @@ export function parseJoins(state) {
|
|
|
24
24
|
joinType = 'INNER'
|
|
25
25
|
} else if (tok.value === 'LEFT') {
|
|
26
26
|
consume(state)
|
|
27
|
-
|
|
28
|
-
// LEFT OUTER JOIN
|
|
29
|
-
}
|
|
27
|
+
match(state, 'keyword', 'OUTER') // LEFT OUTER JOIN
|
|
30
28
|
joinType = 'LEFT'
|
|
31
29
|
} else if (tok.value === 'RIGHT') {
|
|
32
30
|
consume(state)
|
|
33
|
-
|
|
34
|
-
// RIGHT OUTER JOIN
|
|
35
|
-
}
|
|
31
|
+
match(state, 'keyword', 'OUTER') // RIGHT OUTER JOIN
|
|
36
32
|
joinType = 'RIGHT'
|
|
37
33
|
} else if (tok.value === 'FULL') {
|
|
38
34
|
consume(state)
|
|
39
|
-
|
|
40
|
-
// FULL OUTER JOIN
|
|
41
|
-
}
|
|
35
|
+
match(state, 'keyword', 'OUTER') // FULL OUTER JOIN
|
|
42
36
|
joinType = 'FULL'
|
|
43
37
|
} else if (tok.value === 'POSITIONAL') {
|
|
44
38
|
consume(state)
|
package/src/validation.js
CHANGED
|
@@ -117,6 +117,7 @@ export const FUNCTION_ARG_COUNTS = {
|
|
|
117
117
|
|
|
118
118
|
// Conditional functions
|
|
119
119
|
COALESCE: { min: 1 },
|
|
120
|
+
NULLIF: { min: 2, max: 2 },
|
|
120
121
|
|
|
121
122
|
// Aggregate functions
|
|
122
123
|
COUNT: { min: 1, max: 1 },
|
|
@@ -194,7 +195,7 @@ export function isKnownFunction(funcName, functions) {
|
|
|
194
195
|
if ([
|
|
195
196
|
'CURRENT_DATE', 'CURRENT_TIME', 'CURRENT_TIMESTAMP',
|
|
196
197
|
'JSON_VALUE', 'JSON_QUERY', 'JSON_OBJECT',
|
|
197
|
-
'COALESCE', 'CAST',
|
|
198
|
+
'COALESCE', 'NULLIF', 'CAST',
|
|
198
199
|
].includes(funcName)) {
|
|
199
200
|
return true
|
|
200
201
|
}
|