sqlmath 0.0.5 → 2022.4.28
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/.npmignore +1 -0
- package/CHANGELOG.md +29 -0
- package/README.md +3 -3
- package/_binary_sqlmath_napi8_darwin_x64.node +0 -0
- package/_binary_sqlmath_napi8_linux_x64.node +0 -0
- package/_binary_sqlmath_napi8_win32_x64.node +0 -0
- package/_binary_sqlmath_shell_darwin_x64 +0 -0
- package/_binary_sqlmath_shell_linux_x64 +0 -0
- package/_binary_sqlmath_shell_win32_x64.exe +0 -0
- package/jslint.mjs +451 -321
- package/package.json +5 -5
- package/sqlmath.mjs +193 -107
- package/sqlmath_custom.mjs +4 -0
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"email": "kaizhu256@gmail.com",
|
|
4
4
|
"name": "kai zhu"
|
|
5
5
|
},
|
|
6
|
-
"counter":
|
|
6
|
+
"counter": 10,
|
|
7
7
|
"cpu": [
|
|
8
8
|
"x64"
|
|
9
9
|
],
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"engines": {
|
|
12
12
|
"node": ">=14"
|
|
13
13
|
},
|
|
14
|
-
"fileCount":
|
|
14
|
+
"fileCount": 28,
|
|
15
15
|
"homepage": "https://github.com/sqlmath/sqlmath",
|
|
16
16
|
"keywords": [
|
|
17
17
|
"data-science",
|
|
@@ -32,10 +32,10 @@
|
|
|
32
32
|
"url": "https://github.com/sqlmath/sqlmath"
|
|
33
33
|
},
|
|
34
34
|
"scripts": {
|
|
35
|
-
"build": "sh jslint_ci.sh
|
|
36
|
-
"test": "sh jslint_ci.sh
|
|
35
|
+
"build": "sh jslint_ci.sh shCiBuildNodejs",
|
|
36
|
+
"test": "sh jslint_ci.sh shCiTestNodejs",
|
|
37
37
|
"test2": "sh jslint_ci.sh shCiBase",
|
|
38
38
|
"test_win32": "node -e \"require('child_process').spawn('C:\\\\Program Files\\\\Git\\\\bin\\\\bash.exe',['-c','npm run test' + ' ' + process.argv.slice(1).join(' ')],{stdio:['ignore',1,2]});\""
|
|
39
39
|
},
|
|
40
|
-
"version": "
|
|
40
|
+
"version": "2022.4.28"
|
|
41
41
|
}
|
package/sqlmath.mjs
CHANGED
|
@@ -8,7 +8,8 @@ let {
|
|
|
8
8
|
assertJsonEqual,
|
|
9
9
|
assertOrThrow,
|
|
10
10
|
debugInline,
|
|
11
|
-
noop
|
|
11
|
+
noop,
|
|
12
|
+
objectDeepCopyWithKeysSorted
|
|
12
13
|
} = jslint;
|
|
13
14
|
let local = Object.assign({}, jslint);
|
|
14
15
|
|
|
@@ -17,7 +18,7 @@ function assertNumericalEqual(aa, bb, message) {
|
|
|
17
18
|
// This function will assert aa - bb <= Number.EPSILON
|
|
18
19
|
|
|
19
20
|
assertOrThrow(aa, "value cannot be 0 or falsy");
|
|
20
|
-
if (!(Math.abs(aa - bb) <= Number.EPSILON)) {
|
|
21
|
+
if (!(Math.abs((aa - bb) / Math.max(aa, bb)) <= 256 * Number.EPSILON)) {
|
|
21
22
|
throw new Error(
|
|
22
23
|
JSON.stringify(aa) + " != " + JSON.stringify(bb) + (
|
|
23
24
|
message
|
|
@@ -58,10 +59,10 @@ file sqlmath.js
|
|
|
58
59
|
let SQLITE_OPEN_URI = 0x00000040; /* Ok for sqlite3_open_v2() */
|
|
59
60
|
let SQLITE_OPEN_WAL = 0x00080000; /* VFS only */
|
|
60
61
|
let addon;
|
|
61
|
-
let
|
|
62
|
+
let consoleError = console.error;
|
|
63
|
+
let dbDict = new WeakMap(); // private map of sqlite-database-connections
|
|
62
64
|
let requireCjs = createRequire(import.meta.url);
|
|
63
65
|
let testList;
|
|
64
|
-
// private map of sqlite-database-connections
|
|
65
66
|
|
|
66
67
|
function cCall(func, argList) {
|
|
67
68
|
// this function will serialize <argList> to a c <baton>,
|
|
@@ -168,8 +169,12 @@ file sqlmath.js
|
|
|
168
169
|
bindList = [],
|
|
169
170
|
db,
|
|
170
171
|
responseType,
|
|
171
|
-
|
|
172
|
-
|
|
172
|
+
sql,
|
|
173
|
+
tmpColList,
|
|
174
|
+
tmpColListPriority,
|
|
175
|
+
tmpCsv,
|
|
176
|
+
tmpRowList,
|
|
177
|
+
tmpTableName
|
|
173
178
|
}) {
|
|
174
179
|
// this function will exec <sql> in <db> and return <result>
|
|
175
180
|
let bindByKey = !Array.isArray(bindList);
|
|
@@ -180,10 +185,14 @@ file sqlmath.js
|
|
|
180
185
|
);
|
|
181
186
|
let result;
|
|
182
187
|
let serialize = jsToSqlSerializer();
|
|
183
|
-
if (
|
|
188
|
+
if (tmpCsv || tmpRowList) {
|
|
184
189
|
await dbTableInsertAsync({
|
|
190
|
+
colList: tmpColList,
|
|
191
|
+
colListPriority: tmpColListPriority,
|
|
192
|
+
csv: tmpCsv,
|
|
185
193
|
db,
|
|
186
|
-
rowList
|
|
194
|
+
rowList: tmpRowList,
|
|
195
|
+
tableName: tmpTableName
|
|
187
196
|
});
|
|
188
197
|
}
|
|
189
198
|
Object.entries(bindList).forEach(function ([
|
|
@@ -202,8 +211,6 @@ file sqlmath.js
|
|
|
202
211
|
(
|
|
203
212
|
responseType === "lastBlob"
|
|
204
213
|
? 1
|
|
205
|
-
: responseType === "lastMatrixDouble"
|
|
206
|
-
? 2
|
|
207
214
|
: 0
|
|
208
215
|
)
|
|
209
216
|
].concat(serialize.bufSharedList));
|
|
@@ -212,8 +219,6 @@ file sqlmath.js
|
|
|
212
219
|
case "arraybuffer":
|
|
213
220
|
case "lastBlob":
|
|
214
221
|
return result;
|
|
215
|
-
case "lastMatrixDouble":
|
|
216
|
-
return new Float64Array(result);
|
|
217
222
|
case "list":
|
|
218
223
|
return JSON.parse(new TextDecoder().decode(result));
|
|
219
224
|
default:
|
|
@@ -231,6 +236,25 @@ file sqlmath.js
|
|
|
231
236
|
}
|
|
232
237
|
}
|
|
233
238
|
|
|
239
|
+
async function dbExecWithRetryAsync(option) {
|
|
240
|
+
// this function will exec <sql> in <db> and return <result> with <retryLimit>
|
|
241
|
+
let retry = option.retryLimit || 1;
|
|
242
|
+
while (true) {
|
|
243
|
+
try {
|
|
244
|
+
return await dbExecAsync(option);
|
|
245
|
+
} catch (err) {
|
|
246
|
+
assertOrThrow(retry > 0, err);
|
|
247
|
+
consoleError(err);
|
|
248
|
+
consoleError(
|
|
249
|
+
"dbExecWithRetryAsync - retry failed sql-query with "
|
|
250
|
+
+ retry
|
|
251
|
+
+ " remaining retry"
|
|
252
|
+
);
|
|
253
|
+
retry -= 1;
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
234
258
|
function dbGetLastBlobAsync({
|
|
235
259
|
bindList = [],
|
|
236
260
|
db,
|
|
@@ -246,21 +270,6 @@ file sqlmath.js
|
|
|
246
270
|
});
|
|
247
271
|
}
|
|
248
272
|
|
|
249
|
-
function dbGetLastMatrixDouble({
|
|
250
|
-
bindList = [],
|
|
251
|
-
db,
|
|
252
|
-
sql
|
|
253
|
-
}) {
|
|
254
|
-
// this function will exec <sql> in <db> and return last SELECT-statement
|
|
255
|
-
// from execution as row x col matrix of doubles
|
|
256
|
-
return dbExecAsync({
|
|
257
|
-
bindList,
|
|
258
|
-
db,
|
|
259
|
-
responseType: "lastMatrixDouble",
|
|
260
|
-
sql
|
|
261
|
-
});
|
|
262
|
-
}
|
|
263
|
-
|
|
264
273
|
async function dbMemoryLoadAsync({
|
|
265
274
|
db,
|
|
266
275
|
filename
|
|
@@ -306,9 +315,12 @@ file sqlmath.js
|
|
|
306
315
|
), async function () {
|
|
307
316
|
let finalizer;
|
|
308
317
|
let ptr = await cCall("__dbOpenAsync", [
|
|
309
|
-
String(filename),
|
|
318
|
+
String(filename),
|
|
319
|
+
undefined,
|
|
320
|
+
flags ?? (
|
|
310
321
|
SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE | SQLITE_OPEN_URI
|
|
311
|
-
),
|
|
322
|
+
),
|
|
323
|
+
undefined
|
|
312
324
|
]);
|
|
313
325
|
ptr = ptr[0][0];
|
|
314
326
|
finalizer = new BigInt64Array(addon.__dbFinalizerCreate());
|
|
@@ -330,13 +342,14 @@ file sqlmath.js
|
|
|
330
342
|
csv,
|
|
331
343
|
db,
|
|
332
344
|
rowList,
|
|
333
|
-
tableName
|
|
345
|
+
tableName
|
|
334
346
|
}) {
|
|
335
347
|
// this function will create-or-replace temp <tablename> with <rowList>
|
|
336
348
|
let serialize = jsToSqlSerializer();
|
|
337
349
|
let sqlCreateTable;
|
|
338
350
|
let sqlInsertRow;
|
|
339
351
|
// normalize and validate tableName
|
|
352
|
+
tableName = tableName || "__tmp1";
|
|
340
353
|
tableName = "temp." + JSON.stringify(tableName.replace((
|
|
341
354
|
/^temp\./
|
|
342
355
|
), ""));
|
|
@@ -429,9 +442,6 @@ file sqlmath.js
|
|
|
429
442
|
}
|
|
430
443
|
function bufferSetBuffer(aa, bb, offset) {
|
|
431
444
|
// this function will set buffer <bb> to buffer <aa> at <offset>
|
|
432
|
-
if (typeof bb === "string") {
|
|
433
|
-
bb = new TextEncoder().encode(bb);
|
|
434
|
-
}
|
|
435
445
|
aa = new Uint8Array(aa.buffer, aa.byteOffset, aa.byteLength);
|
|
436
446
|
bb = new Uint8Array(bb.buffer, bb.byteOffset, bb.byteLength);
|
|
437
447
|
aa.set(bb, offset);
|
|
@@ -1013,50 +1023,6 @@ Definition of the CSV Format
|
|
|
1013
1023
|
dd
|
|
1014
1024
|
});
|
|
1015
1025
|
});
|
|
1016
|
-
// test dbGetLastMatrixDouble's bind handling-behavior
|
|
1017
|
-
[
|
|
1018
|
-
aa
|
|
1019
|
-
].forEach(async function (aa) {
|
|
1020
|
-
let cc = Number(
|
|
1021
|
-
typeof aa === "symbol"
|
|
1022
|
-
? 0
|
|
1023
|
-
: aa
|
|
1024
|
-
) || 0;
|
|
1025
|
-
let dd = await dbGetLastMatrixDouble({
|
|
1026
|
-
bindList: [
|
|
1027
|
-
aa
|
|
1028
|
-
],
|
|
1029
|
-
db,
|
|
1030
|
-
sql: "SELECT 1, 2, 3; SELECT 1, 2, ?"
|
|
1031
|
-
});
|
|
1032
|
-
switch (typeof(aa)) {
|
|
1033
|
-
case "bigint":
|
|
1034
|
-
aa = String(aa);
|
|
1035
|
-
break;
|
|
1036
|
-
case "object":
|
|
1037
|
-
if (typeof aa?.getUTCFullYear === "function") {
|
|
1038
|
-
cc = aa.getUTCFullYear();
|
|
1039
|
-
}
|
|
1040
|
-
break;
|
|
1041
|
-
}
|
|
1042
|
-
cc = new Float64Array([
|
|
1043
|
-
1, 3, 1, 2, cc
|
|
1044
|
-
]);
|
|
1045
|
-
// debugInline(ii, aa, bb, cc, dd);
|
|
1046
|
-
cc.forEach(function (val, jj) {
|
|
1047
|
-
assertJsonEqual(
|
|
1048
|
-
val,
|
|
1049
|
-
dd[jj],
|
|
1050
|
-
{
|
|
1051
|
-
ii,
|
|
1052
|
-
aa, //jslint-quiet
|
|
1053
|
-
bb,
|
|
1054
|
-
cc,
|
|
1055
|
-
dd
|
|
1056
|
-
}
|
|
1057
|
-
);
|
|
1058
|
-
});
|
|
1059
|
-
});
|
|
1060
1026
|
// test dbExecAsync's responseType handling-behavior
|
|
1061
1027
|
[
|
|
1062
1028
|
"arraybuffer",
|
|
@@ -1212,19 +1178,15 @@ Definition of the CSV Format
|
|
|
1212
1178
|
colListPriority,
|
|
1213
1179
|
rowList
|
|
1214
1180
|
}, jj) {
|
|
1215
|
-
let cc
|
|
1216
|
-
await dbTableInsertAsync({
|
|
1217
|
-
colList,
|
|
1218
|
-
colListPriority,
|
|
1219
|
-
db,
|
|
1220
|
-
rowList,
|
|
1221
|
-
tableName: "datatype_" + ii + "_" + jj
|
|
1222
|
-
});
|
|
1223
|
-
cc = noop(
|
|
1181
|
+
let cc = noop(
|
|
1224
1182
|
await dbExecAsync({
|
|
1225
1183
|
db,
|
|
1226
1184
|
responseType: "list",
|
|
1227
|
-
sql:
|
|
1185
|
+
sql: `SELECT * FROM datatype_${ii}_${jj}`,
|
|
1186
|
+
tmpColList: colList,
|
|
1187
|
+
tmpColListPriority: colListPriority,
|
|
1188
|
+
tmpRowList: rowList,
|
|
1189
|
+
tmpTableName: "datatype_" + ii + "_" + jj
|
|
1228
1190
|
})
|
|
1229
1191
|
)[0];
|
|
1230
1192
|
// debugInline(ii, jj, aa, bb, cc);
|
|
@@ -1282,12 +1244,14 @@ Definition of the CSV Format
|
|
|
1282
1244
|
sql: (`
|
|
1283
1245
|
CREATE TABLE testDbExecAsync1 AS
|
|
1284
1246
|
SELECT 101 AS c101, 102 AS c102
|
|
1247
|
+
--
|
|
1285
1248
|
UNION ALL
|
|
1286
1249
|
VALUES
|
|
1287
1250
|
(201, 202),
|
|
1288
1251
|
(301, NULL);
|
|
1289
1252
|
CREATE TABLE testDbExecAsync2 AS
|
|
1290
1253
|
SELECT 401 AS c401, 402 AS c402, 403 AS c403
|
|
1254
|
+
--
|
|
1291
1255
|
UNION ALL
|
|
1292
1256
|
VALUES
|
|
1293
1257
|
(501, 502.0123, 5030123456789),
|
|
@@ -1350,18 +1314,27 @@ SELECT * FROM testDbExecAsync2;
|
|
|
1350
1314
|
));
|
|
1351
1315
|
// test sqlmath-defined-func handling-behavior
|
|
1352
1316
|
[
|
|
1317
|
+
"COT(NULL)", null,
|
|
1353
1318
|
"COT('-1')", -0.642092615934331,
|
|
1354
1319
|
"COT('0')", null,
|
|
1355
1320
|
"COT('1')", 0.642092615934331,
|
|
1356
1321
|
"COT(-1)", -0.642092615934331,
|
|
1357
1322
|
"COT(0)", null,
|
|
1358
1323
|
"COT(1)", 0.642092615934331,
|
|
1324
|
+
"COTH(NULL)", null,
|
|
1359
1325
|
"COTH('-1')", -1.31303528549933,
|
|
1360
1326
|
"COTH('0')", null,
|
|
1361
1327
|
"COTH('1')", 1.31303528549933,
|
|
1362
1328
|
"COTH(-1)", -1.31303528549933,
|
|
1363
1329
|
"COTH(0)", null,
|
|
1364
1330
|
"COTH(1)", 1.31303528549933,
|
|
1331
|
+
"ROUNDORZERO(NULL, NULL)", 0,
|
|
1332
|
+
"ROUNDORZERO(NULL, 0)", 0,
|
|
1333
|
+
"ROUNDORZERO(NULL, 0.5)", 0,
|
|
1334
|
+
"ROUNDORZERO(0.5, NULL)", 1,
|
|
1335
|
+
"ROUNDORZERO(0.5, 0.5)", 1,
|
|
1336
|
+
"ROUNDORZERO(0.5, 1)", 0.5,
|
|
1337
|
+
"SIGN(NULL)", null,
|
|
1365
1338
|
"SIGN('-1')", -1,
|
|
1366
1339
|
"SIGN('0')", 0,
|
|
1367
1340
|
"SIGN('1')", 1,
|
|
@@ -1374,7 +1347,6 @@ SELECT * FROM testDbExecAsync2;
|
|
|
1374
1347
|
"SIGN(0xffffffffffffffff)", -1,
|
|
1375
1348
|
"SIGN(1)", 1,
|
|
1376
1349
|
"SIGN(1e999)", 1,
|
|
1377
|
-
"SIGN(NULL)", null,
|
|
1378
1350
|
// sentinel
|
|
1379
1351
|
"NULL", null
|
|
1380
1352
|
].forEach(async function (sql, ii, list) {
|
|
@@ -1388,15 +1360,26 @@ SELECT * FROM testDbExecAsync2;
|
|
|
1388
1360
|
await dbExecAsync({
|
|
1389
1361
|
db,
|
|
1390
1362
|
responseType: "dict",
|
|
1391
|
-
sql:
|
|
1363
|
+
sql: `SELECT ${sql} AS val`
|
|
1392
1364
|
})
|
|
1393
1365
|
)[0][0].val;
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1366
|
+
assertJsonEqual(bb, cc, {
|
|
1367
|
+
bb,
|
|
1368
|
+
cc,
|
|
1369
|
+
ii,
|
|
1370
|
+
sql
|
|
1371
|
+
});
|
|
1397
1372
|
});
|
|
1398
1373
|
}
|
|
1399
1374
|
|
|
1375
|
+
function testDbExecWithRetryAsync() {
|
|
1376
|
+
// this function will test dbExecWithRetryAsync's handling-behavior
|
|
1377
|
+
// test null-case handling-behavior
|
|
1378
|
+
assertErrorThrownAsync(function () {
|
|
1379
|
+
return dbExecWithRetryAsync({});
|
|
1380
|
+
}, "invalid or closed db");
|
|
1381
|
+
}
|
|
1382
|
+
|
|
1400
1383
|
async function testDbMemoryXxx() {
|
|
1401
1384
|
// this function will test dbMemoryXxx's handling-behavior
|
|
1402
1385
|
let data;
|
|
@@ -1480,11 +1463,15 @@ SELECT * FROM testDbExecAsync2;
|
|
|
1480
1463
|
].forEach(function ([
|
|
1481
1464
|
rowList, rgx
|
|
1482
1465
|
]) {
|
|
1483
|
-
assertErrorThrownAsync(
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1466
|
+
assertErrorThrownAsync(
|
|
1467
|
+
dbTableInsertAsync.bind(
|
|
1468
|
+
undefined,
|
|
1469
|
+
{
|
|
1470
|
+
rowList
|
|
1471
|
+
}
|
|
1472
|
+
),
|
|
1473
|
+
rgx
|
|
1474
|
+
);
|
|
1488
1475
|
});
|
|
1489
1476
|
// test csv handling-behavior
|
|
1490
1477
|
[
|
|
@@ -1526,17 +1513,13 @@ SELECT * FROM testDbExecAsync2;
|
|
|
1526
1513
|
].forEach(async function ([
|
|
1527
1514
|
aa, bb
|
|
1528
1515
|
], ii) {
|
|
1529
|
-
let cc
|
|
1530
|
-
await dbTableInsertAsync({
|
|
1531
|
-
csv: aa,
|
|
1532
|
-
db,
|
|
1533
|
-
tableName: "csv_" + ii
|
|
1534
|
-
});
|
|
1535
|
-
cc = noop(
|
|
1516
|
+
let cc = noop(
|
|
1536
1517
|
await dbExecAsync({
|
|
1537
1518
|
db,
|
|
1538
1519
|
responseType: "list",
|
|
1539
|
-
sql:
|
|
1520
|
+
sql: `SELECT * FROM temp.csv_${ii}`,
|
|
1521
|
+
tmpCsv: aa,
|
|
1522
|
+
tmpTableName: "csv_" + ii
|
|
1540
1523
|
})
|
|
1541
1524
|
)[0];
|
|
1542
1525
|
assertOrThrow(
|
|
@@ -1590,7 +1573,7 @@ SELECT * FROM testDbExecAsync2;
|
|
|
1590
1573
|
return;
|
|
1591
1574
|
}
|
|
1592
1575
|
ii *= 0.5;
|
|
1593
|
-
sql =
|
|
1576
|
+
sql = `SELECT throwerror(${sql})`;
|
|
1594
1577
|
assertErrorThrownAsync(function () {
|
|
1595
1578
|
return dbExecAsync({
|
|
1596
1579
|
db,
|
|
@@ -1653,6 +1636,101 @@ SELECT * FROM testDbExecAsync2;
|
|
|
1653
1636
|
});
|
|
1654
1637
|
}
|
|
1655
1638
|
|
|
1639
|
+
async function testSqlKthpercentile() {
|
|
1640
|
+
// this function will test sql-kthpercentile's handling-behavior
|
|
1641
|
+
let db = await dbOpenAsync({
|
|
1642
|
+
filename: ":memory:"
|
|
1643
|
+
});
|
|
1644
|
+
[
|
|
1645
|
+
[
|
|
1646
|
+
[], -99, 1
|
|
1647
|
+
], [
|
|
1648
|
+
[], 0, 1
|
|
1649
|
+
], [
|
|
1650
|
+
[], 0.125, 1
|
|
1651
|
+
], [
|
|
1652
|
+
[], 0.25, 2
|
|
1653
|
+
], [
|
|
1654
|
+
[], 0.375, 3
|
|
1655
|
+
], [
|
|
1656
|
+
[], 0.5, 4
|
|
1657
|
+
], [
|
|
1658
|
+
[], 0.625, 5
|
|
1659
|
+
], [
|
|
1660
|
+
[], 0.75, 6
|
|
1661
|
+
], [
|
|
1662
|
+
[], 0.875, 7
|
|
1663
|
+
], [
|
|
1664
|
+
[], 1, 8
|
|
1665
|
+
], [
|
|
1666
|
+
[], 99, 8
|
|
1667
|
+
], [
|
|
1668
|
+
[
|
|
1669
|
+
0.5
|
|
1670
|
+
], 0, 0.5
|
|
1671
|
+
], [
|
|
1672
|
+
[
|
|
1673
|
+
0.5
|
|
1674
|
+
], 0.125, 0.5
|
|
1675
|
+
], [
|
|
1676
|
+
[
|
|
1677
|
+
1.5
|
|
1678
|
+
], 0.25, 1.5
|
|
1679
|
+
], [
|
|
1680
|
+
[
|
|
1681
|
+
2.5
|
|
1682
|
+
], 0.375, 2.5
|
|
1683
|
+
], [
|
|
1684
|
+
[
|
|
1685
|
+
3.5
|
|
1686
|
+
], 0.5, 3.5
|
|
1687
|
+
], [
|
|
1688
|
+
[
|
|
1689
|
+
4.5
|
|
1690
|
+
], 0.625, 4.5
|
|
1691
|
+
], [
|
|
1692
|
+
[
|
|
1693
|
+
5.5
|
|
1694
|
+
], 0.75, 5.5
|
|
1695
|
+
], [
|
|
1696
|
+
[
|
|
1697
|
+
6.5
|
|
1698
|
+
], 0.875, 6.5
|
|
1699
|
+
], [
|
|
1700
|
+
[
|
|
1701
|
+
7.5
|
|
1702
|
+
], 1, 8
|
|
1703
|
+
]
|
|
1704
|
+
].forEach(async function ([
|
|
1705
|
+
data, kk, expected
|
|
1706
|
+
], ii) {
|
|
1707
|
+
let actual;
|
|
1708
|
+
data = data.concat([
|
|
1709
|
+
undefined, undefined, 8, 7, 6, 5, 4, 3, 2, 1, undefined
|
|
1710
|
+
]);
|
|
1711
|
+
actual = noop(
|
|
1712
|
+
await dbExecAsync({
|
|
1713
|
+
db,
|
|
1714
|
+
sql: (`
|
|
1715
|
+
SELECT kthpercentile(val, ${kk}) AS val FROM __tmp${ii};
|
|
1716
|
+
-- test null-case handling-behavior
|
|
1717
|
+
SELECT kthpercentile(val, ${kk}) AS val FROM __tmp${ii} WHERE 0;
|
|
1718
|
+
`),
|
|
1719
|
+
tmpRowList: data.map(function (val) {
|
|
1720
|
+
return {
|
|
1721
|
+
val
|
|
1722
|
+
};
|
|
1723
|
+
}),
|
|
1724
|
+
tmpTableName: `__tmp${ii}`
|
|
1725
|
+
})
|
|
1726
|
+
)[0][0].val;
|
|
1727
|
+
assertJsonEqual(actual, expected, {
|
|
1728
|
+
data,
|
|
1729
|
+
kk
|
|
1730
|
+
});
|
|
1731
|
+
});
|
|
1732
|
+
}
|
|
1733
|
+
|
|
1656
1734
|
addon = requireCjs(
|
|
1657
1735
|
"./_binary_sqlmath"
|
|
1658
1736
|
+ "_napi8"
|
|
@@ -1666,11 +1744,13 @@ SELECT * FROM testDbExecAsync2;
|
|
|
1666
1744
|
testDbBind,
|
|
1667
1745
|
testDbCloseAsync,
|
|
1668
1746
|
testDbExecAsync,
|
|
1747
|
+
testDbExecWithRetryAsync,
|
|
1669
1748
|
testDbMemoryXxx,
|
|
1670
1749
|
testDbOpenAsync,
|
|
1671
1750
|
testDbTableInsertAsync,
|
|
1672
1751
|
testSqlError,
|
|
1673
|
-
testSqlExt
|
|
1752
|
+
testSqlExt,
|
|
1753
|
+
testSqlKthpercentile
|
|
1674
1754
|
];
|
|
1675
1755
|
Object.assign(local, {
|
|
1676
1756
|
SQLITE_MAX_LENGTH2,
|
|
@@ -1699,15 +1779,21 @@ SELECT * FROM testDbExecAsync2;
|
|
|
1699
1779
|
assertNumericalEqual,
|
|
1700
1780
|
dbCloseAsync,
|
|
1701
1781
|
dbExecAsync,
|
|
1782
|
+
dbExecWithRetryAsync,
|
|
1702
1783
|
dbGetLastBlobAsync,
|
|
1703
1784
|
dbMemoryLoadAsync,
|
|
1704
1785
|
dbMemorySaveAsync,
|
|
1705
1786
|
dbOpenAsync,
|
|
1706
1787
|
dbTableInsertAsync,
|
|
1707
1788
|
debugInline,
|
|
1789
|
+
objectDeepCopyWithKeysSorted,
|
|
1708
1790
|
testAll,
|
|
1709
1791
|
testList
|
|
1710
1792
|
});
|
|
1793
|
+
if (process.env.npm_config_mode_test) {
|
|
1794
|
+
// mock consoleError
|
|
1795
|
+
consoleError = noop;
|
|
1796
|
+
}
|
|
1711
1797
|
}());
|
|
1712
1798
|
|
|
1713
1799
|
export default Object.freeze(local);
|