sqlmath 2025.6.28 → 2025.9.30

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/test.mjs ADDED
@@ -0,0 +1,4176 @@
1
+ // MIT License
2
+ //
3
+ // Copyright (c) 2021 Kai Zhu
4
+ //
5
+ // Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ // of this software and associated documentation files (the "Software"), to deal
7
+ // in the Software without restriction, including without limitation the rights
8
+ // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ // copies of the Software, and to permit persons to whom the Software is
10
+ // furnished to do so, subject to the following conditions:
11
+ //
12
+ // The above copyright notice and this permission notice shall be included in
13
+ // all copies or substantial portions of the Software.
14
+ //
15
+ // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ // SOFTWARE.
22
+
23
+ /*
24
+ * example usage:
25
+ npm_config_mode_test_save2=1 npm test
26
+ */
27
+
28
+ /*jslint beta, node*/
29
+ import moduleChildProcess from "child_process";
30
+ import modulePath from "path";
31
+ import moduleUtil from "util";
32
+ import jslint from "./jslint.mjs";
33
+ import {
34
+ LGBM_PREDICT_NORMAL,
35
+ SQLMATH_EXE,
36
+ assertErrorThrownAsync,
37
+ assertJsonEqual,
38
+ assertNumericalEqual,
39
+ assertOrThrow,
40
+ childProcessSpawn2,
41
+ ciBuildExt,
42
+ dbCloseAsync,
43
+ dbExecAndReturnLastBlob,
44
+ dbExecAndReturnLastRow,
45
+ dbExecAndReturnLastTable,
46
+ dbExecAndReturnLastValue,
47
+ dbExecAsync,
48
+ dbExecProfile,
49
+ dbFileLoadAsync,
50
+ dbFileSaveAsync,
51
+ dbNoopAsync,
52
+ dbOpenAsync,
53
+ dbTableImportAsync,
54
+ debugInline,
55
+ fsCopyFileUnlessTest,
56
+ fsExistsUnlessTest,
57
+ fsReadFileUnlessTest,
58
+ fsWriteFileUnlessTest,
59
+ jsbatonGetInt64,
60
+ jsbatonGetString,
61
+ listOrEmptyList,
62
+ noop,
63
+ sqlmathWebworkerInit,
64
+ version,
65
+ waitAsync
66
+ } from "./sqlmath.mjs";
67
+ let {
68
+ jstestDescribe,
69
+ jstestIt
70
+ } = jslint;
71
+ let {
72
+ npm_config_mode_test_save
73
+ } = process.env;
74
+
75
+ dbExecProfile({
76
+ modeInit: true
77
+ });
78
+
79
+ jstestDescribe((
80
+ "test_apidoc"
81
+ ), function test_apidoc() {
82
+ jstestIt((
83
+ "test apidoc handling-behavior"
84
+ ), function () {
85
+ jslint.jslint_apidoc({
86
+ example_list: [
87
+ "README.md",
88
+ "test.mjs",
89
+ "sqlmath.mjs"
90
+ ],
91
+ github_repo: "https://github.com/sqlmath/sqlmath",
92
+ module_list: [
93
+ {
94
+ pathname: "./sqlmath.mjs"
95
+ }
96
+ ],
97
+ package_name: "sqlmath",
98
+ pathname: ".artifact/apidoc.html",
99
+ version
100
+ });
101
+ });
102
+ });
103
+
104
+ jstestDescribe((
105
+ "test_assertXxx"
106
+ ), function test_assertXxx() {
107
+ jstestIt((
108
+ "test assertXxx handling-behavior"
109
+ ), function () {
110
+ assertErrorThrownAsync(function () {
111
+ assertNumericalEqual(0, 0);
112
+ }, "value cannot be 0 or falsy");
113
+ assertErrorThrownAsync(function () {
114
+ assertNumericalEqual(1, 2);
115
+ }, "1 != 2");
116
+ assertErrorThrownAsync(function () {
117
+ assertNumericalEqual(1, 2, "aa");
118
+ }, "aa");
119
+ assertNumericalEqual(1, 1);
120
+ });
121
+ });
122
+
123
+ jstestDescribe((
124
+ "test_childProcessSpawn2"
125
+ ), function test_childProcessSpawn2() {
126
+ jstestIt((
127
+ "test childProcessSpawn2 handling-behavior"
128
+ ), async function () {
129
+ await Promise.all([
130
+ childProcessSpawn2(
131
+ "undefined",
132
+ [],
133
+ {modeCapture: "utf8", modeDebug: true, stdio: []}
134
+ ),
135
+ (async function () {
136
+ let result;
137
+ result = await moduleUtil.promisify(
138
+ moduleChildProcess.execFile
139
+ )(
140
+ (
141
+ process.cwd()
142
+ + modulePath.sep
143
+ + SQLMATH_EXE
144
+ ),
145
+ [
146
+ ":memory:",
147
+ (`
148
+ SELECT
149
+ CAST(
150
+ SQLAR_UNCOMPRESS(
151
+ SQLAR_COMPRESS(
152
+ CAST('abcd1234' AS BLOB)
153
+ ),
154
+ 8
155
+ )
156
+ AS 'TEXT'
157
+ ),
158
+ CAST(
159
+ GZIP_UNCOMPRESS(
160
+ GZIP_COMPRESS(
161
+ CAST('abcd1234' AS BLOB)
162
+ )
163
+ )
164
+ AS 'TEXT'
165
+ );
166
+ `)
167
+ ]
168
+ );
169
+ result = result.stdout.trim();
170
+ assertJsonEqual(result, "abcd1234|abcd1234");
171
+ }())
172
+ ]);
173
+ });
174
+ });
175
+
176
+ jstestDescribe((
177
+ "test_ciBuildExtXxx"
178
+ ), function test_ciBuildExtXxx() {
179
+ jstestIt((
180
+ "test ciBuildExt handling-behavior"
181
+ ), async function () {
182
+ await Promise.all([
183
+ ciBuildExt({process: {arch: "arm", env: {}, platform: "win32"}}),
184
+ ciBuildExt({process: {arch: "arm64", env: {}, platform: "win32"}}),
185
+ ciBuildExt({process: {arch: "ia32", env: {}, platform: "win32"}}),
186
+ ciBuildExt({process: {cwd: noop}}),
187
+ ciBuildExt({process: {env: {}, platform: "darwin"}}),
188
+ ciBuildExt({process: {env: {}, platform: "win32"}}),
189
+ ciBuildExt({process: {versions: {}}})
190
+ ]);
191
+ });
192
+ });
193
+
194
+ jstestDescribe((
195
+ "test_dbBind"
196
+ ), function test_dbBind() {
197
+ jstestIt((
198
+ "test db-bind handling-behavior"
199
+ ), async function test_dbBind() {
200
+ let db;
201
+ async function test_dbBind_exec(ii, valIn, valExpect) {
202
+ await Promise.all([
203
+ [
204
+ [
205
+ valExpect, valExpect, 0
206
+ ],
207
+ (
208
+ "SELECT 0;"
209
+ + " SELECT ? AS c1, ? AS c2, ? AS c3, ? AS c4"
210
+ + " UNION ALL SELECT ?1, ?2, ?3, ?4"
211
+ + " UNION ALL SELECT ?1, ?2, ?3, ?4"
212
+ )
213
+ ],
214
+ [
215
+ {
216
+ k1: valExpect,
217
+ k2: valExpect,
218
+ k3: 0
219
+ },
220
+ (
221
+ "SELECT 0;"
222
+ + " SELECT $k1 AS c1, $k2 AS c2, $k3 AS c3, $k4 AS c4"
223
+ + " UNION ALL SELECT :k1, :k2, :k3, :k4"
224
+ + " UNION ALL SELECT @k1, @k2, @k3, @k4"
225
+ )
226
+ ]
227
+ ].map(async function ([
228
+ bindList, sql
229
+ ]) {
230
+ let bufActual = await dbExecAsync({
231
+ bindList,
232
+ db,
233
+ responseType: "list",
234
+ sql
235
+ });
236
+ let bufExpect = [
237
+ [
238
+ ["0"],
239
+ [0]
240
+ ],
241
+ [
242
+ ["c1", "c2", "c3", "c4"],
243
+ [valExpect, valExpect, 0, undefined],
244
+ [valExpect, valExpect, 0, undefined],
245
+ [valExpect, valExpect, 0, undefined]
246
+ ]
247
+ ];
248
+ assertJsonEqual(bufActual, bufExpect, {
249
+ bufActual,
250
+ bufExpect,
251
+ ii,
252
+ valExpect,
253
+ valIn
254
+ });
255
+ }));
256
+ }
257
+ async function test_dbBind_lastBlob(ii, valIn, valExpect) {
258
+ let bufActual;
259
+ let bufExpect;
260
+ if (valExpect === Error) {
261
+ assertErrorThrownAsync(
262
+ dbExecAndReturnLastBlob.bind(undefined, {
263
+ bindList: [valIn],
264
+ db,
265
+ sql: "SELECT 1, 2, 3; SELECT 1, 2, ?"
266
+ }),
267
+ "inclusive-range|not JSON serializable"
268
+ );
269
+ return;
270
+ }
271
+ bufActual = new TextDecoder().decode(
272
+ await dbExecAndReturnLastBlob({
273
+ bindList: [valIn],
274
+ db,
275
+ sql: "SELECT 1, 2, 3; SELECT 1, 2, ?"
276
+ })
277
+ );
278
+ bufExpect = String(valExpect);
279
+ switch (typeof(valIn)) {
280
+ case "bigint":
281
+ valIn = Number(valIn);
282
+ break;
283
+ case "function":
284
+ case "symbol":
285
+ case "undefined":
286
+ bufExpect = "";
287
+ break;
288
+ case "number":
289
+ switch (valIn) {
290
+ case -2:
291
+ bufExpect = "-2.0";
292
+ break;
293
+ case -Infinity:
294
+ bufExpect = "-Inf";
295
+ break;
296
+ case 2:
297
+ bufExpect = "2.0";
298
+ break;
299
+ case Infinity:
300
+ bufExpect = "Inf";
301
+ break;
302
+ default:
303
+ if (Number.isNaN(valIn)) {
304
+ bufExpect = "";
305
+ }
306
+ }
307
+ break;
308
+ case "object":
309
+ if (valIn === null) {
310
+ bufExpect = "";
311
+ break;
312
+ }
313
+ if (
314
+ valIn?.constructor === ArrayBuffer
315
+ || ArrayBuffer.isView(valIn)
316
+ ) {
317
+ bufExpect = new TextDecoder().decode(valIn);
318
+ break;
319
+ }
320
+ break;
321
+ }
322
+ assertJsonEqual(bufActual, bufExpect, {
323
+ bufActual,
324
+ bufExpect,
325
+ ii,
326
+ valExpect,
327
+ valIn
328
+ });
329
+ }
330
+ async function test_dbBind_lastValue(ii, valIn, valExpect) {
331
+ let valActual;
332
+ if (valExpect === Error) {
333
+ assertErrorThrownAsync(
334
+ dbExecAndReturnLastValue.bind(undefined, {
335
+ bindList: [valIn],
336
+ db,
337
+ sql: "SELECT 1, 2, 3; SELECT 1, 2, ?"
338
+ }),
339
+ "inclusive-range|not JSON serializable"
340
+ );
341
+ return;
342
+ }
343
+ valActual = await dbExecAndReturnLastValue({
344
+ bindList: [valIn],
345
+ db,
346
+ sql: "SELECT 1, 2, 3; SELECT 1, 2, ?"
347
+ });
348
+ assertJsonEqual(valActual, valExpect, {
349
+ ii,
350
+ valActual,
351
+ valExpect,
352
+ valIn
353
+ });
354
+ }
355
+ async function test_dbBind_responseType(ii, valIn, valExpect) {
356
+ await Promise.all([
357
+ "arraybuffer",
358
+ "list",
359
+ "lastvalue",
360
+ undefined
361
+ ].map(async function (responseType) {
362
+ let valActual;
363
+ if (valExpect === Error) {
364
+ assertErrorThrownAsync(
365
+ dbExecAsync.bind(undefined, {
366
+ bindList: [valIn],
367
+ db,
368
+ responseType,
369
+ sql: "SELECT ? AS val"
370
+ }),
371
+ "inclusive-range|not JSON serializable"
372
+ );
373
+ return;
374
+ }
375
+ valActual = await dbExecAsync({
376
+ bindList: [valIn],
377
+ db,
378
+ responseType,
379
+ sql: "SELECT ? AS val"
380
+ });
381
+ switch (responseType) {
382
+ case "arraybuffer":
383
+ valActual = JSON.parse(
384
+ new TextDecoder().decode(valActual)
385
+ )[0][1][0];
386
+ break;
387
+ case "lastvalue":
388
+ break;
389
+ case "list":
390
+ valActual = valActual[0][1][0];
391
+ break;
392
+ default:
393
+ valActual = valActual[0][0].val;
394
+ }
395
+ assertJsonEqual(valActual, valExpect, {
396
+ ii,
397
+ responseType,
398
+ valActual,
399
+ valExpect,
400
+ valIn
401
+ });
402
+ }));
403
+ }
404
+ db = await dbOpenAsync({});
405
+ await Promise.all([
406
+ // 1. bigint
407
+ [-0n, -0],
408
+ [-0n, 0],
409
+ [-0x8000000000000000n, "-9223372036854775808"],
410
+ [-0x8000000000000001n, Error],
411
+ [-1n, -1],
412
+ [-2n, -2],
413
+ [0n, -0],
414
+ [0n, 0],
415
+ [0x7fffffffffffffffn, "9223372036854775807"],
416
+ [0x8000000000000000n, Error],
417
+ [1n, 1],
418
+ [2n, 2],
419
+ // 2. boolean
420
+ [false, 0],
421
+ [true, 1],
422
+ // 3. function
423
+ [noop, null],
424
+ // 4. number
425
+ [-0, -0],
426
+ [-0, 0],
427
+ [-0.5, -0.5],
428
+ [-1 / 0, null],
429
+ [-1e-999, 0],
430
+ [-1e999, null],
431
+ [-2, -2],
432
+ [-Infinity, null],
433
+ [-NaN, null],
434
+ [0, -0],
435
+ [0, 0],
436
+ [0.5, 0.5],
437
+ [1 / 0, null],
438
+ [1e-999, 0],
439
+ [1e999, null],
440
+ [2, 2],
441
+ [Infinity, null],
442
+ [NaN, null],
443
+ // 5. object
444
+ [[], "[]"],
445
+ [new ArrayBuffer(0), null],
446
+ [new ArrayBuffer(1), null],
447
+ [new Date(0), "1970-01-01T00:00:00.000Z"],
448
+ [new RegExp(), "{}"],
449
+ [new TextEncoder().encode(""), null],
450
+ [new TextEncoder().encode("\u0000"), null],
451
+ [new TextEncoder().encode("\u0000\u{1f600}\u0000"), null],
452
+ [new Uint8Array(0), null],
453
+ [new Uint8Array(1), null],
454
+ [null, null],
455
+ [{}, "{}"],
456
+ // 6. string
457
+ ["", ""],
458
+ ["'", "'"],
459
+ ["0", "0"],
460
+ ["1", "1"],
461
+ ["2", "2"],
462
+ ["\"", "\""],
463
+ ["\u0000", "\u0000"],
464
+ ["\u0000\u{1f600}\u0000", "\u0000\u{1f600}\u0000"],
465
+ ["a".repeat(9999), "a".repeat(9999)],
466
+ // 7. symbol
467
+ [Symbol(), null],
468
+ // 8. undefined
469
+ [undefined, null]
470
+ ].map(async function ([valIn, valExpect], ii) {
471
+ await Promise.all([
472
+ test_dbBind_exec(ii, valIn, valExpect),
473
+ test_dbBind_lastBlob(ii, valIn, valExpect),
474
+ test_dbBind_lastValue(ii, valIn, valExpect),
475
+ test_dbBind_responseType(ii, valIn, valExpect)
476
+ ]);
477
+ }));
478
+ });
479
+ });
480
+
481
+ jstestDescribe((
482
+ "test_dbNoopAsync"
483
+ ), function test_dbNoopAsync() {
484
+ jstestIt((
485
+ "test dbNoopAsync handling-behavior"
486
+ ), async function () {
487
+ // test datatype handling-behavior
488
+ await Promise.all([
489
+ // 1. bigint
490
+ [-0n, -0],
491
+ [-0n, 0],
492
+ [-0x8000000000000000n, -0x8000000000000000n],
493
+ [-0x8000000000000001n, Error],
494
+ [-1n, -1],
495
+ [-2n, -2],
496
+ [0n, -0],
497
+ [0n, 0],
498
+ [0x7fffffffffffffffn, 0x7fffffffffffffffn],
499
+ [0x8000000000000000n, Error],
500
+ [1n, 1],
501
+ [2n, 2],
502
+ // 2. boolean
503
+ [false, 0],
504
+ [true, 1],
505
+ // 3. function
506
+ [noop, Error],
507
+ // 4. number
508
+ [-0, -0],
509
+ [-0, 0],
510
+ [-0.5, Error],
511
+ [-1 / 0, Error],
512
+ [-1e-999, 0],
513
+ [-1e999, Error],
514
+ [-2, -2],
515
+ [-Infinity, Error],
516
+ [-NaN, Error],
517
+ [0, -0],
518
+ [0, 0],
519
+ [0.5, Error],
520
+ [1 / 0, Error],
521
+ [1e-999, 0],
522
+ [1e999, Error],
523
+ [2, 2],
524
+ [Infinity, Error],
525
+ [NaN, Error],
526
+ // 5. object
527
+ [[], Error],
528
+ [new ArrayBuffer(0), 0],
529
+ [new ArrayBuffer(1), 0],
530
+ [new Date(0), Error],
531
+ [new RegExp(), Error],
532
+ [new TextEncoder().encode(""), Error],
533
+ [new TextEncoder().encode("\u0000"), Error],
534
+ [new TextEncoder().encode("\u0000\u{1f600}\u0000"), Error],
535
+ [new Uint8Array(0), Error],
536
+ [new Uint8Array(1), Error],
537
+ [null, 0],
538
+ [{}, Error],
539
+ // 6. string
540
+ ["", ""],
541
+ ["'", "'"],
542
+ ["0", "0"],
543
+ ["1", "1"],
544
+ ["2", "2"],
545
+ ["\"", "\""],
546
+ ["\u0000", ""],
547
+ ["\u0000\u{1f600}\u0000", "\u0000\u{1f600}"],
548
+ ["a".repeat(9999), "a".repeat(9999)],
549
+ // 7. symbol
550
+ [Symbol(), Error],
551
+ // 8. undefined
552
+ [undefined, 0]
553
+ ].map(async function ([valIn, valExpect], ii) {
554
+ let baton;
555
+ let valActual;
556
+ if (valExpect === Error) {
557
+ assertErrorThrownAsync(function () {
558
+ return dbNoopAsync(undefined, valIn, undefined);
559
+ }, "invalid arg|integer");
560
+ return;
561
+ }
562
+ baton = await dbNoopAsync(undefined, valIn, undefined);
563
+ baton = baton[0];
564
+ valActual = (
565
+ typeof valIn === "string"
566
+ ? jsbatonGetString(baton, 1)
567
+ : String(jsbatonGetInt64(baton, 1))
568
+ );
569
+ valExpect = String(valExpect);
570
+ if (typeof valIn === "bigint") {
571
+ valIn = String(valIn);
572
+ }
573
+ assertJsonEqual(valActual, valExpect, {
574
+ ii,
575
+ valActual,
576
+ valExpect,
577
+ valIn
578
+ });
579
+ }));
580
+ });
581
+ });
582
+
583
+ jstestDescribe((
584
+ "test_dbXxxAsync"
585
+ ), function test_dbXxxAsync() {
586
+ jstestIt((
587
+ "test dbCloseAsync handling-behavior"
588
+ ), async function test_dbCloseAsync() {
589
+ let db = await dbOpenAsync({});
590
+ // test null-case handling-behavior
591
+ assertErrorThrownAsync(function () {
592
+ return dbCloseAsync({});
593
+ }, "cannot close db");
594
+ // test close handling-behavior
595
+ dbCloseAsync(db);
596
+ });
597
+ jstestIt((
598
+ "test dbExecAndReturnXxx handling-behavior"
599
+ ), async function test_dbExecAndReturnXxx() {
600
+ let db = await dbOpenAsync({});
601
+ // test dbExecAndReturnLastRow null-case handling-behavior
602
+ assertJsonEqual(
603
+ noop(
604
+ await dbExecAndReturnLastRow({
605
+ db,
606
+ sql: "SELECT 0 WHERE 0"
607
+ })
608
+ ),
609
+ {}
610
+ );
611
+ // test dbExecAndReturnLastTable null-case handling-behavior
612
+ assertJsonEqual(
613
+ noop(
614
+ await dbExecAndReturnLastTable({
615
+ db,
616
+ sql: "SELECT 0 WHERE 0"
617
+ })
618
+ ),
619
+ []
620
+ );
621
+ // test dbExecAndReturnLastBlob null-case handling-behavior
622
+ assertJsonEqual(
623
+ new TextDecoder().decode(
624
+ await dbExecAndReturnLastBlob({
625
+ db,
626
+ sql: "SELECT 0 WHERE 0"
627
+ })
628
+ ),
629
+ ""
630
+ );
631
+ // test dbExecAndReturnLastBlob string handling-behavior
632
+ assertJsonEqual(
633
+ new TextDecoder().decode(
634
+ await dbExecAndReturnLastBlob({
635
+ db,
636
+ sql: "SELECT 1, 2, 3"
637
+ })
638
+ ),
639
+ "3"
640
+ );
641
+ // test dbExecAndReturnLastValue null-case handling-behavior
642
+ assertJsonEqual(
643
+ noop(
644
+ await dbExecAndReturnLastValue({
645
+ db,
646
+ sql: "SELECT 0 WHERE 0"
647
+ })
648
+ ),
649
+ null
650
+ );
651
+ // test dbExecAndReturnLastValue json handling-behavior
652
+ assertJsonEqual(
653
+ noop(
654
+ await dbExecAndReturnLastValue({
655
+ db,
656
+ sql: "SELECT 1, 2, 3"
657
+ })
658
+ ),
659
+ 3
660
+ );
661
+ });
662
+ jstestIt((
663
+ "test dbExecAsync handling-behavior"
664
+ ), async function test_dbExecAsync() {
665
+ let db = await dbOpenAsync({});
666
+ // test modeNoop handling-behavior
667
+ dbExecAsync({
668
+ modeNoop: true
669
+ });
670
+ // test null-case handling-behavior
671
+ assertErrorThrownAsync(function () {
672
+ return dbExecAsync({
673
+ db,
674
+ sql: undefined
675
+ });
676
+ }, "syntax error");
677
+ // test race-condition handling-behavior
678
+ Array.from(new Array(4)).forEach(async function () {
679
+ let result;
680
+ try {
681
+ result = await dbExecAsync({
682
+ bindList: [
683
+ new TextEncoder().encode("foob"),
684
+ new TextEncoder().encode("fooba"),
685
+ new TextEncoder().encode("foobar")
686
+ ],
687
+ db,
688
+ responseType: "list",
689
+ sql: (`
690
+ CREATE TABLE testDbExecAsync1 AS
691
+ SELECT 101 AS c101, 102 AS c102
692
+ --
693
+ UNION ALL
694
+ VALUES
695
+ (201, 202),
696
+ (301, NULL);
697
+ CREATE TABLE testDbExecAsync2 AS
698
+ SELECT 401 AS c401, 402 AS c402, 403 AS c403
699
+ --
700
+ UNION ALL
701
+ VALUES
702
+ (501, 502.0123, 5030123456789),
703
+ (601, '602', '603_\"\x01\x08\x09\x0a\x0b\x0c\x0d\x0e'),
704
+ (?1, ?2, ?3),
705
+ (CAST(?1 AS TEXT), CAST(?2 AS TEXT), CAST(?3 AS TEXT)),
706
+ (
707
+ CAST(GZIP_UNCOMPRESS(GZIP_COMPRESS(?1)) AS TEXT),
708
+ CAST(GZIP_UNCOMPRESS(GZIP_COMPRESS(?2)) AS TEXT),
709
+ CAST(GZIP_UNCOMPRESS(GZIP_COMPRESS(?3)) AS TEXT)
710
+ );
711
+ SELECT * FROM testDbExecAsync1;
712
+ SELECT * FROM testDbExecAsync2;
713
+ `)
714
+ });
715
+ assertJsonEqual(
716
+ result,
717
+ [
718
+ [
719
+ ["c101", "c102"],
720
+ [101, 102],
721
+ [201, 202],
722
+ [301, null]
723
+ ],
724
+ [
725
+ ["c401", "c402", "c403"],
726
+ [401, 402, 403],
727
+ [501, 502.0123, 5030123456789],
728
+ [601, "602", "603_\"\u0001\b\t\n\u000b\f\r\u000e"],
729
+ [null, null, null],
730
+ ["foob", "fooba", "foobar"],
731
+ ["foob", "fooba", "foobar"]
732
+ ]
733
+ ]
734
+ );
735
+ } catch (err) {
736
+ assertOrThrow(
737
+ err.message.indexOf(
738
+ "table testDbExecAsync1 already exists"
739
+ ) >= 0,
740
+ err
741
+ );
742
+ }
743
+ });
744
+ // test close-while-busy handling-behavior
745
+ assertErrorThrownAsync(function () {
746
+ return dbCloseAsync(db);
747
+ }, "cannot close db");
748
+ });
749
+ jstestIt((
750
+ "test dbFileXxx handling-behavior"
751
+ ), async function test_dbFileXxx() {
752
+ let data;
753
+ let db = await dbOpenAsync({});
754
+ // test null-case handling-behavior
755
+ dbFileLoadAsync({
756
+ modeNoop: true
757
+ });
758
+ assertErrorThrownAsync(function () {
759
+ return dbFileSaveAsync({
760
+ db,
761
+ filename: 0
762
+ });
763
+ }, "invalid filename 0");
764
+ await dbExecAsync({
765
+ db,
766
+ sql: "CREATE TABLE t01 AS SELECT 1 AS c01"
767
+ });
768
+ await dbFileSaveAsync({
769
+ db,
770
+ filename: ".testDbFileXxx.sqlite"
771
+ });
772
+ db = await dbOpenAsync({});
773
+ await dbFileLoadAsync({
774
+ db,
775
+ filename: ".testDbFileXxx.sqlite"
776
+ });
777
+ data = await dbExecAsync({
778
+ db,
779
+ sql: "SELECT * FROM t01"
780
+ });
781
+ assertJsonEqual(data, [[{c01: 1}]]);
782
+ });
783
+ jstestIt((
784
+ "test dbOpenAsync handling-behavior"
785
+ ), async function test_dbOpenAsync() {
786
+ // test auto-finalization handling-behavior
787
+ await new Promise(function (resolve) {
788
+ dbOpenAsync({
789
+ afterFinalization: resolve
790
+ });
791
+ });
792
+ // test null-case handling-behavior
793
+ await dbOpenAsync({});
794
+ });
795
+ jstestIt((
796
+ "test dbTableXxx handling-behavior"
797
+ ), async function test_dbTableXxx() {
798
+ let db = await dbOpenAsync({});
799
+ await Promise.all([
800
+ dbTableImportAsync({
801
+ db,
802
+ mode: "csv",
803
+ tableName: "__csv0",
804
+ textData: ""
805
+ }),
806
+ dbTableImportAsync({
807
+ db,
808
+ mode: "csv",
809
+ tableName: "__csv1",
810
+ textData: String(`
811
+ duplicate_header,duplicate_header
812
+ "aaa","b""bb","ccc"
813
+ "aaa","b
814
+ bb","ccc"
815
+ zzz,yyy,xxx
816
+ `).trim()
817
+ }),
818
+ dbTableImportAsync({
819
+ db,
820
+ mode: "json",
821
+ tableName: "__json0",
822
+ textData: "null"
823
+ }),
824
+ dbTableImportAsync({
825
+ db,
826
+ mode: "json",
827
+ tableName: "__json1",
828
+ textData: JSON.stringify({
829
+ aa: {aa: 1, bb: 2},
830
+ bb: {aa: 3, bb: 4}
831
+ })
832
+ }),
833
+ dbTableImportAsync({
834
+ db,
835
+ mode: "tsv",
836
+ tableName: "__tsv1",
837
+ textData: "aa,bb\tcc,dd"
838
+ })
839
+ ]);
840
+ });
841
+ });
842
+
843
+ jstestDescribe((
844
+ "test_fsXxx"
845
+ ), function test_fsXxx() {
846
+ jstestIt((
847
+ "test fsXxx handling-behavior"
848
+ ), async function () {
849
+ await Promise.all([
850
+ fsCopyFileUnlessTest("", ""),
851
+ fsExistsUnlessTest(""),
852
+ fsReadFileUnlessTest("", ""),
853
+ fsWriteFileUnlessTest("", ""),
854
+ //
855
+ fsCopyFileUnlessTest(
856
+ "package.json",
857
+ ".tmp/test_fsCopyFileUnlessTest_force",
858
+ "force"
859
+ ),
860
+ fsExistsUnlessTest("", "force"),
861
+ fsExistsUnlessTest("package.json", "force"),
862
+ fsReadFileUnlessTest("package.json", "force"),
863
+ fsWriteFileUnlessTest(
864
+ ".tmp/test_fsWriteFileUnlessTest_force",
865
+ "",
866
+ "force"
867
+ )
868
+ ]);
869
+ });
870
+ });
871
+
872
+ jstestDescribe((
873
+ "test_lgbm"
874
+ ), function test_lgbm() {
875
+ jstestIt((
876
+ "test lgbm handling-behavior"
877
+ ), async function () {
878
+ let filePreb = "test_lgbm_preb.txt";
879
+ let fileTest = "test_lgbm_binary.test";
880
+ let fileTrain = "test_lgbm_binary.train";
881
+ let promiseList = [];
882
+ let sqlDataFile = (`
883
+ UPDATE __lgbm_state
884
+ SET
885
+ data_train_handle = (
886
+ SELECT
887
+ LGBM_DATASETCREATEFROMFILE(
888
+ '${fileTrain}', -- filename
889
+ 'max_bin=15', -- param_data
890
+ NULL -- reference
891
+ )
892
+ );
893
+ UPDATE __lgbm_state
894
+ SET
895
+ data_test_handle = (
896
+ SELECT
897
+ LGBM_DATASETCREATEFROMFILE(
898
+ '${fileTest}', -- filename
899
+ 'max_bin=15', -- param_data
900
+ data_train_handle -- reference
901
+ )
902
+ );
903
+ `);
904
+ let sqlDataTable = (`
905
+ UPDATE __lgbm_state
906
+ SET
907
+ data_train_handle = (
908
+ SELECT
909
+ LGBM_DATASETCREATEFROMTABLE(
910
+ 'max_bin=15', -- param_data
911
+ NULL, -- reference
912
+ --
913
+ _1, _2, _3, _4,
914
+ _5, _6, _7, _8,
915
+ _9, _10, _11, _12,
916
+ _13, _14, _15, _16,
917
+ _17, _18, _19, _20,
918
+ _21, _22, _23, _24,
919
+ _25, _26, _27, _28,
920
+ _29
921
+ )
922
+ FROM __lgbm_file_train
923
+ );
924
+ UPDATE __lgbm_state
925
+ SET
926
+ data_test_handle = (
927
+ SELECT
928
+ LGBM_DATASETCREATEFROMTABLE(
929
+ 'max_bin=15', -- param_data
930
+ data_train_handle, -- reference
931
+ --
932
+ _1, _2, _3, _4,
933
+ _5, _6, _7, _8,
934
+ _9, _10, _11, _12,
935
+ _13, _14, _15, _16,
936
+ _17, _18, _19, _20,
937
+ _21, _22, _23, _24,
938
+ _25, _26, _27, _28,
939
+ _29
940
+ )
941
+ FROM __lgbm_file_test
942
+ );
943
+ `);
944
+ let sqlIi = 0;
945
+ let sqlPredictFile = (`
946
+ SELECT
947
+ LGBM_PREDICTFORFILE(
948
+ model, -- model
949
+ ${LGBM_PREDICT_NORMAL}, -- predict_type
950
+ 0, -- start_iteration
951
+ 25, -- num_iteration
952
+ '', -- param_pred
953
+ --
954
+ '${fileTest}', -- data_filename
955
+ 0, -- data_has_header
956
+ 'fileActual' -- result_filename
957
+ )
958
+ FROM __lgbm_state;
959
+ SELECT
960
+ LGBM_PREDICTFORFILE(
961
+ model, -- model
962
+ ${LGBM_PREDICT_NORMAL}, -- predict_type
963
+ 10, -- start_iteration
964
+ 25, -- num_iteration
965
+ '', -- param_pred
966
+ --
967
+ '${fileTest}', -- data_filename
968
+ 0, -- data_has_header
969
+ 'fileActual' -- result_filename
970
+ )
971
+ FROM __lgbm_state;
972
+ `);
973
+ let sqlPredictTable = (`
974
+ DROP TABLE IF EXISTS __lgbm_table_preb;
975
+ CREATE TABLE __lgbm_table_preb AS
976
+ SELECT
977
+ DOUBLEARRAY_EXTRACT(__lgp, 0) AS prediction
978
+ FROM (
979
+ SELECT
980
+ LGBM_PREDICTFORTABLE(
981
+ (SELECT model FROM __lgbm_state), -- model
982
+ ${LGBM_PREDICT_NORMAL}, -- predict_type
983
+ 0, -- start_iteration
984
+ 25, -- num_iteration
985
+ '', -- param_pred
986
+ --
987
+ _2, _3, _4,
988
+ _5, _6, _7, _8,
989
+ _9, _10, _11, _12,
990
+ _13, _14, _15, _16,
991
+ _17, _18, _19, _20,
992
+ _21, _22, _23, _24,
993
+ _25, _26, _27, _28,
994
+ _29
995
+ ) OVER (
996
+ ORDER BY rowid ASC
997
+ ROWS BETWEEN 0 PRECEDING AND 0 FOLLOWING
998
+ ) AS __lgp
999
+ FROM __lgbm_file_test
1000
+ );
1001
+ DROP TABLE IF EXISTS __lgbm_table_preb;
1002
+ CREATE TABLE __lgbm_table_preb AS
1003
+ SELECT
1004
+ DOUBLEARRAY_EXTRACT(__lgp, 0) AS _1
1005
+ FROM (
1006
+ SELECT
1007
+ LGBM_PREDICTFORTABLE(
1008
+ (SELECT model FROM __lgbm_state), -- model
1009
+ ${LGBM_PREDICT_NORMAL}, -- predict_type
1010
+ 10, -- start_iteration
1011
+ 25, -- num_iteration
1012
+ '', -- param_pred
1013
+ --
1014
+ _2, _3, _4,
1015
+ _5, _6, _7, _8,
1016
+ _9, _10, _11, _12,
1017
+ _13, _14, _15, _16,
1018
+ _17, _18, _19, _20,
1019
+ _21, _22, _23, _24,
1020
+ _25, _26, _27, _28,
1021
+ _29
1022
+ ) OVER (
1023
+ ORDER BY rowid ASC
1024
+ ROWS BETWEEN 0 PRECEDING AND 0 FOLLOWING
1025
+ ) AS __lgp
1026
+ FROM __lgbm_file_test
1027
+ );
1028
+ `);
1029
+ let sqlTrainData = (`
1030
+ UPDATE __lgbm_state
1031
+ SET
1032
+ model = LGBM_TRAINFROMDATASET(
1033
+ -- param_train
1034
+ (
1035
+ 'objective=binary'
1036
+ || ' learning_rate=0.1' -- default=0.1
1037
+ || ' max_depth=-1' -- default=-1
1038
+ || ' metric=auc' -- default=""
1039
+ || ' min_data_in_leaf=20' -- default=20
1040
+ || ' num_class=1' -- default=1
1041
+ || ' num_leaves=31' -- default=31
1042
+ || ' verbosity=0' -- default=1
1043
+ ),
1044
+ 50, -- num_iteration
1045
+ 10, -- eval_step
1046
+ --
1047
+ data_train_handle, -- train_data
1048
+ data_test_handle -- test_data
1049
+ );
1050
+ `);
1051
+ let sqlTrainFile = (`
1052
+ UPDATE __lgbm_state
1053
+ SET
1054
+ model = LGBM_TRAINFROMFILE(
1055
+ -- param_train
1056
+ (
1057
+ 'objective=binary'
1058
+ || ' learning_rate=0.1' -- default=0.1
1059
+ || ' max_depth=-1' -- default=-1
1060
+ || ' metric=auc' -- default=""
1061
+ || ' min_data_in_leaf=20' -- default=20
1062
+ || ' num_class=1' -- default=1
1063
+ || ' num_leaves=31' -- default=31
1064
+ || ' verbosity=0' -- default=1
1065
+ ),
1066
+ 50, -- num_iteration
1067
+ 10, -- eval_step
1068
+ --
1069
+ '${fileTrain}', -- file_train
1070
+ 'max_bin=15', -- param_data
1071
+ '${fileTest}' -- file_test
1072
+ );
1073
+ `);
1074
+ let sqlTrainTable = (`
1075
+ UPDATE __lgbm_state
1076
+ SET
1077
+ model = (
1078
+ SELECT
1079
+ LGBM_TRAINFROMTABLE(
1080
+ -- param_train
1081
+ (
1082
+ 'objective=binary'
1083
+ || ' learning_rate=0.1' -- default=0.1
1084
+ || ' max_depth=-1' -- default=-1
1085
+ || ' metric=auc' -- default=""
1086
+ || ' min_data_in_leaf=20' -- default=20
1087
+ || ' num_class=1' -- default=1
1088
+ || ' num_leaves=31' -- default=31
1089
+ || ' verbosity=0' -- default=1
1090
+ ),
1091
+ 50, -- num_iteration
1092
+ 10, -- eval_step
1093
+ --
1094
+ 'max_bin=15', -- param_data
1095
+ NULL, -- reference
1096
+ --
1097
+ _1, _2, _3, _4,
1098
+ _5, _6, _7, _8,
1099
+ _9, _10, _11, _12,
1100
+ _13, _14, _15, _16,
1101
+ _17, _18, _19, _20,
1102
+ _21, _22, _23, _24,
1103
+ _25, _26, _27, _28,
1104
+ _29
1105
+ )
1106
+ FROM __lgbm_file_train
1107
+ );
1108
+ `);
1109
+ async function testLgbm(sqlDataXxx, sqlTrainXxx, sqlPredictXxx, sqlIi) {
1110
+ let db = await dbOpenAsync({});
1111
+ let fileActual = `.tmp/test_lgbm_preb_${sqlIi}.txt`;
1112
+ await Promise.all([
1113
+ dbTableImportAsync({
1114
+ db,
1115
+ filename: filePreb,
1116
+ headerMissing: true,
1117
+ mode: "tsv",
1118
+ tableName: "__lgbm_file_preb"
1119
+ }),
1120
+ dbTableImportAsync({
1121
+ db,
1122
+ filename: fileTest,
1123
+ headerMissing: true,
1124
+ mode: "tsv",
1125
+ tableName: "__lgbm_file_test"
1126
+ }),
1127
+ dbTableImportAsync({
1128
+ db,
1129
+ filename: fileTrain,
1130
+ headerMissing: true,
1131
+ mode: "tsv",
1132
+ tableName: "__lgbm_file_train"
1133
+ })
1134
+ ]);
1135
+ await dbExecAsync({
1136
+ db,
1137
+ sql: (`
1138
+ -- lgbm - init
1139
+ CREATE TABLE __lgbm_state(
1140
+ data_test_handle INTEGER,
1141
+ data_test_num_data REAL,
1142
+ data_test_num_feature REAL,
1143
+ --
1144
+ data_train_handle INTEGER,
1145
+ data_train_num_data REAL,
1146
+ data_train_num_feature REAL,
1147
+ --
1148
+ model BLOB
1149
+ );
1150
+ INSERT INTO __lgbm_state(rowid) SELECT 1;
1151
+
1152
+ -- lgbm - data
1153
+ ${sqlDataXxx};
1154
+ UPDATE __lgbm_state
1155
+ SET
1156
+ data_test_num_data = LGBM_DATASETGETNUMDATA(data_test_handle),
1157
+ data_test_num_feature = LGBM_DATASETGETNUMFEATURE(data_test_handle),
1158
+ data_train_num_data = LGBM_DATASETGETNUMDATA(data_train_handle),
1159
+ data_train_num_feature = LGBM_DATASETGETNUMFEATURE(data_train_handle);
1160
+
1161
+ -- lgbm - train
1162
+ ${sqlTrainXxx};
1163
+ `)
1164
+ });
1165
+ await dbExecAsync({
1166
+ db,
1167
+ sql: (`
1168
+ -- lgbm - predict
1169
+ ${sqlPredictXxx.replace(/fileActual/g, fileActual)};
1170
+
1171
+ -- lgbm - cleanup
1172
+ SELECT
1173
+ LGBM_DATASETFREE(data_test_handle),
1174
+ LGBM_DATASETFREE(data_train_handle)
1175
+ FROM __lgbm_state;
1176
+ `)
1177
+ });
1178
+ if (sqlPredictXxx === sqlPredictFile) {
1179
+ dbTableImportAsync({
1180
+ db,
1181
+ filename: fileActual,
1182
+ headerMissing: true,
1183
+ mode: "tsv",
1184
+ tableName: "__lgbm_table_preb"
1185
+ });
1186
+ }
1187
+ await dbFileSaveAsync({
1188
+ db,
1189
+ filename: `.tmp/test_lgbm_${sqlIi}.sqlite`
1190
+ });
1191
+ assertJsonEqual(
1192
+ noop(
1193
+ await dbExecAndReturnLastRow({
1194
+ db,
1195
+ sql: (`
1196
+ SELECT
1197
+ data_test_num_data,
1198
+ data_test_num_feature,
1199
+ data_train_num_data,
1200
+ data_train_num_feature
1201
+ FROM __lgbm_state;
1202
+ `)
1203
+ })
1204
+ ),
1205
+ {
1206
+ "data_test_num_data": 500,
1207
+ "data_test_num_feature": 28,
1208
+ "data_train_num_data": 7000,
1209
+ "data_train_num_feature": 28
1210
+ }
1211
+ );
1212
+ if (sqlPredictXxx === sqlPredictFile) {
1213
+ assertJsonEqual(
1214
+ await fsReadFileUnlessTest(fileActual, "force"),
1215
+ await fsReadFileUnlessTest(filePreb, "force")
1216
+ );
1217
+ }
1218
+ assertJsonEqual(
1219
+ noop(
1220
+ await dbExecAndReturnLastTable({
1221
+ db,
1222
+ sql: (`
1223
+ SELECT ROUND(_1, 8) AS _1 FROM __lgbm_table_preb;
1224
+ `)
1225
+ })
1226
+ ),
1227
+ noop(
1228
+ await dbExecAndReturnLastTable({
1229
+ db,
1230
+ sql: (`
1231
+ SELECT ROUND(_1, 8) AS _1 FROM __lgbm_file_preb;
1232
+ `)
1233
+ })
1234
+ )
1235
+ );
1236
+ }
1237
+ [
1238
+ sqlDataFile, sqlDataTable
1239
+ ].forEach(function (sqlDataXxx) {
1240
+ [
1241
+ sqlTrainData, sqlTrainFile, sqlTrainTable
1242
+ ].forEach(function (sqlTrainXxx) {
1243
+ [
1244
+ sqlPredictFile, sqlPredictTable
1245
+ ].forEach(function (sqlPredictXxx) {
1246
+ sqlIi += 1;
1247
+ promiseList.push(
1248
+ testLgbm(sqlDataXxx, sqlTrainXxx, sqlPredictXxx, sqlIi)
1249
+ );
1250
+ });
1251
+ });
1252
+ });
1253
+ await Promise.all(promiseList);
1254
+ });
1255
+ });
1256
+
1257
+ jstestDescribe((
1258
+ "test_misc"
1259
+ ), function test_misc() {
1260
+ jstestIt((
1261
+ "test misc handling-behavior"
1262
+ ), async function () {
1263
+ // test assertErrorThrownAsync error handling-behavior
1264
+ await assertErrorThrownAsync(function () {
1265
+ return assertErrorThrownAsync(noop);
1266
+ }, "No error thrown");
1267
+ // test assertJsonEqual error handling-behavior
1268
+ await assertErrorThrownAsync(function () {
1269
+ assertJsonEqual(1, 2);
1270
+ }, "!==");
1271
+ await assertErrorThrownAsync(function () {
1272
+ assertJsonEqual(1, 2, "undefined");
1273
+ }, "undefined");
1274
+ await assertErrorThrownAsync(function () {
1275
+ assertJsonEqual(1, 2, {});
1276
+ }, "");
1277
+ // test assertOrThrow error handling-behavior
1278
+ await assertErrorThrownAsync(function () {
1279
+ assertOrThrow(undefined, "undefined");
1280
+ }, "undefined");
1281
+ await assertErrorThrownAsync(function () {
1282
+ assertOrThrow(undefined, new Error());
1283
+ }, "");
1284
+ // test listOrEmptyList null-case handling-behavior
1285
+ assertJsonEqual(listOrEmptyList(), []);
1286
+ // test waitAsync null-case handling-behavior
1287
+ await waitAsync();
1288
+ });
1289
+ });
1290
+
1291
+ jstestDescribe((
1292
+ "test_sqlite"
1293
+ ), function test_sqlite() {
1294
+ jstestIt((
1295
+ "test sqlite-error handling-behavior"
1296
+ ), async function test_sqliteError() {
1297
+ let db = await dbOpenAsync({});
1298
+ assertJsonEqual(
1299
+ "not an error",
1300
+ noop(
1301
+ await dbExecAndReturnLastRow({
1302
+ db,
1303
+ sql: `SELECT throwerror(0) AS val`
1304
+ })
1305
+ ).val
1306
+ );
1307
+ await Promise.all([
1308
+ [1, "SQL logic error"],
1309
+ [2, "unknown error"],
1310
+ [3, "access permission denied"],
1311
+ [4, "query aborted"],
1312
+ [5, "database is locked"],
1313
+ [6, "database table is locked"],
1314
+ [7, "out of memory"],
1315
+ [8, "attempt to write a readonly database"],
1316
+ [9, "interrupted"],
1317
+ [10, "disk I/O error"],
1318
+ [11, "database disk image is malformed"],
1319
+ [12, "unknown operation"],
1320
+ [13, "database or disk is full"],
1321
+ [14, "unable to open database file"],
1322
+ [15, "locking protocol"],
1323
+ [16, "unknown error"],
1324
+ [17, "database schema has changed"],
1325
+ [18, "string or blob too big"],
1326
+ [19, "constraint failed"],
1327
+ [20, "datatype mismatch"],
1328
+ [21, "bad parameter or other API misuse"],
1329
+ [22, "unknown error"],
1330
+ [23, "authorization denied"],
1331
+ [24, "unknown error"],
1332
+ [25, "column index out of range"],
1333
+ [26, "file is not a database"],
1334
+ [27, "notification message"],
1335
+ [28, "warning message"],
1336
+ [100, "unknown error"],
1337
+ [101, "unknown error"]
1338
+ ].map(async function ([
1339
+ errno, errmsg
1340
+ ]) {
1341
+ await assertErrorThrownAsync(function () {
1342
+ return dbExecAsync({
1343
+ db,
1344
+ sql: `SELECT throwerror(${errno})`
1345
+ });
1346
+ }, errmsg);
1347
+ }));
1348
+ });
1349
+ jstestIt((
1350
+ "test sqlite-extension-doublearray_xxx handling-behavior"
1351
+ ), async function test_sqlite_extension_doublearray_xxx() {
1352
+ let db = await dbOpenAsync({});
1353
+ await Promise.all([
1354
+ [" [ , 1 ] ", "error"],
1355
+ [" [ , ] ", "error"],
1356
+ [" [ 1 , ] ", "error"],
1357
+ [" [ ] ", "[]"],
1358
+ [" [ null ] ", "[0.0]"],
1359
+ ["", "error"],
1360
+ ["1,2]", "error"],
1361
+ ["[,1]", "error"],
1362
+ ["[,]", "error"],
1363
+ ["[0]", "[0.0]"],
1364
+ ["[1,2", "error"],
1365
+ ["[1,2,a]", "[1.0,2.0,0.0]"],
1366
+ ["[1,]", "error"],
1367
+ ["[1,a,3]", "[1.0,0.0,3.0]"],
1368
+ ["[1]", "[1.0]"],
1369
+ ["[]", "[]"],
1370
+ ["[a,2,3]", "[0.0,2.0,3.0]"],
1371
+ [0, "error"],
1372
+ [1, "error"],
1373
+ [`[${"1".repeat(100)}]`, `[1.11111111111111e+99]`],
1374
+ [null, "error"],
1375
+ [undefined, "error"],
1376
+ [{}, "error"]
1377
+ ].map(async function ([valIn, valExpect], ii) {
1378
+ let valActual;
1379
+ try {
1380
+ valActual = noop(
1381
+ await dbExecAndReturnLastRow({
1382
+ bindList: {
1383
+ valIn
1384
+ },
1385
+ db,
1386
+ sql: (`
1387
+ SELECT DOUBLEARRAY_JSONTO(DOUBLEARRAY_JSONFROM($valIn)) AS result;
1388
+ `)
1389
+ })
1390
+ ).result;
1391
+ } catch (ignore) {
1392
+ assertOrThrow(valExpect === "error", JSON.stringify({
1393
+ ii,
1394
+ valActual,
1395
+ valExpect,
1396
+ valIn
1397
+ }, undefined, 4));
1398
+ return;
1399
+ }
1400
+ assertJsonEqual(valActual, valExpect, {
1401
+ ii,
1402
+ valActual,
1403
+ valExpect,
1404
+ valIn
1405
+ });
1406
+ }));
1407
+ });
1408
+ jstestIt((
1409
+ "test_sqlite_extension_idate_xxx handling-behavior"
1410
+ ), async function test_sqlite_extension_idate_xxx() {
1411
+ let db = await dbOpenAsync({});
1412
+ let promiseList = [];
1413
+ function idateArgNormalize(sqlFunc, arg, mode) {
1414
+ function idateArgYmdTruncate() {
1415
+ if (Number.isFinite(Number(arg))) {
1416
+ return Math.floor(arg / 1_00_00_00);
1417
+ }
1418
+ return arg.split(" ")[0];
1419
+ }
1420
+ switch (arg !== null && mode) {
1421
+ case "expect":
1422
+ if ((/(?:IDATEFROM|'IYMDH\w*?').*?_YMD$/).test(sqlFunc)) {
1423
+ return arg - (arg % 1_00_00_00);
1424
+ }
1425
+ if ((/'IY'/).test(sqlFunc)) {
1426
+ arg = idateArgYmdTruncate(arg);
1427
+ return arg - (arg % 1_00_00);
1428
+ }
1429
+ if ((/'IYM'/).test(sqlFunc)) {
1430
+ arg = idateArgYmdTruncate(arg);
1431
+ return arg - (arg % 1_00);
1432
+ }
1433
+ if ((/'IYMD'/).test(sqlFunc)) {
1434
+ arg = idateArgYmdTruncate(arg);
1435
+ return arg - (arg % 1);
1436
+ }
1437
+ if ((/'IYMDH'/).test(sqlFunc)) {
1438
+ return arg - (arg % 1_00_00);
1439
+ }
1440
+ if ((/'IYMDHM'/).test(sqlFunc)) {
1441
+ return arg - (arg % 1_00);
1442
+ }
1443
+ if (
1444
+ (/^IDATEYMDFROM|'ITEXTYMD'/).test(sqlFunc)
1445
+ || ((/_YMD$/).test(sqlFunc) && !(/IDATEFROM/).test(sqlFunc))
1446
+ ) {
1447
+ return idateArgYmdTruncate(arg);
1448
+ }
1449
+ break;
1450
+ case "input":
1451
+ if ((/_YMD$/).test(sqlFunc)) {
1452
+ return idateArgYmdTruncate(arg);
1453
+ }
1454
+ break;
1455
+ }
1456
+ return arg;
1457
+ }
1458
+ promiseList.push([
1459
+ "IDATEADD",
1460
+ //
1461
+ "IDATEFROM",
1462
+ // "IDATEFROMEPOCH",
1463
+ "IDATEYMDFROM",
1464
+ // "IDATEYMDFROMEPOCH",
1465
+ //
1466
+ "IDATETO('IDATE')",
1467
+ "IDATETO('IEPOCH')",
1468
+ "IDATETO('IJULIAN')",
1469
+ "IDATETO('ITEXT')",
1470
+ "IDATETO('ITEXTYMD')",
1471
+ "IDATETO('IY')",
1472
+ "IDATETO('IYM')",
1473
+ "IDATETO('IYMD')",
1474
+ "IDATETO('IYMDH')",
1475
+ "IDATETO('IYMDHM')",
1476
+ "IDATETO('IYMDHMS')",
1477
+ "IDATETOEPOCH"
1478
+ ].map(function (sqlFunc) {
1479
+ return [
1480
+ ["", null],
1481
+ ["+0", null],
1482
+ ["+1", null],
1483
+ ["-0", null],
1484
+ ["-1", null],
1485
+ ["-1000-01-01 00:00:00", null],
1486
+ ["-10000101000000", null],
1487
+ ["-9991231000000", null],
1488
+ ["-9999-12-31 23:59:59", null],
1489
+ ["-99991231235959", null],
1490
+ ["-99991231235960", null],
1491
+ ["0", null],
1492
+ ["0999-12-31 23:59:00", null],
1493
+ ["09991231235900", null],
1494
+ ["1000-01-01 00:00:00", null, -1],
1495
+ ["10000101000000", null, -1],
1496
+ ["999-12-31 23:59:00", null],
1497
+ ["999-12-31 23:59:59", null],
1498
+ ["9991231000000", null],
1499
+ ["9999-12-31 23:59:59", null, 1],
1500
+ ["9999-12-31 23:59:60", null],
1501
+ ["9999-12-32 23:59:59", null],
1502
+ ["99991231235959", null, 1],
1503
+ ["99991231235960", null],
1504
+ [-1, null],
1505
+ [-10000101000000, null],
1506
+ [-9991231000000, null],
1507
+ [-99991231235959, null],
1508
+ [-99991231235960, null],
1509
+ [0, null],
1510
+ [1, null],
1511
+ [10000101000000, null, -1],
1512
+ [9991231000000, null],
1513
+ [9991231235900, null],
1514
+ [99991231235959, null, 1],
1515
+ [99991231235960, null],
1516
+ [99991232235959, null],
1517
+ [null, null]
1518
+ ].map(function ([valIn, valExpect, modifier]) {
1519
+ return [sqlFunc, valIn, valExpect, modifier];
1520
+ });
1521
+ }).flat());
1522
+ promiseList.push([
1523
+ "IDATEFROM",
1524
+ "IDATEYMDFROM"
1525
+ ].map(function (sqlFunc) {
1526
+ return [
1527
+ [10000101000000, null],
1528
+ [99991231235959, null]
1529
+ ].map(function ([valIn, valExpect, modifier]) {
1530
+ return [sqlFunc, valIn, valExpect, modifier];
1531
+ });
1532
+ }).flat());
1533
+ promiseList.push([
1534
+ "IDATEADD",
1535
+ "IDATETO('IDATE')",
1536
+ "IDATETO('IEPOCH')",
1537
+ "IDATETO('IJULIAN')",
1538
+ "IDATETO('ITEXT')",
1539
+ "IDATETO('ITEXTYMD')",
1540
+ "IDATETO('IY')",
1541
+ "IDATETO('IYM')",
1542
+ "IDATETO('IYMD')",
1543
+ "IDATETO('IYMDH')",
1544
+ "IDATETO('IYMDHM')",
1545
+ "IDATETO('IYMDHMS')",
1546
+ "IDATETOEPOCH"
1547
+ ].map(function (sqlFunc) {
1548
+ return [
1549
+ ["1000-01-01 00:00:00", null],
1550
+ ["9999-12-31 23:59:59", null],
1551
+ [2086302.5, null],
1552
+ [5373483.5, null]
1553
+ ].map(function ([valIn, valExpect, modifier]) {
1554
+ return [sqlFunc, valIn, valExpect, modifier];
1555
+ });
1556
+ }).flat());
1557
+ promiseList.push([
1558
+ "IDATEADD",
1559
+ "IDATETO('IDATE')"
1560
+ ].map(function (sqlFunc) {
1561
+ return [
1562
+ ["10000101000000", 10000101000000],
1563
+ ["99991231235959", 99991231235959],
1564
+ [10000101000000, 10000101000000],
1565
+ [10000229000000, 10000301000000],
1566
+ [10000301000000, 10000301000000],
1567
+ [10040229000000, 10040229000000],
1568
+ [99960229235959, 99960229235959],
1569
+ [99970229235959, 99970301235959],
1570
+ [99970301235959, 99970301235959],
1571
+ [99991231235959, 99991231235959]
1572
+ ].map(function ([valIn, valExpect]) {
1573
+ return [sqlFunc, `${sqlFunc}_YMD`].map(function (sqlFunc) {
1574
+ return [
1575
+ sqlFunc,
1576
+ idateArgNormalize(sqlFunc, valIn, "input"),
1577
+ idateArgNormalize(sqlFunc, valExpect, "expect")
1578
+ ];
1579
+ });
1580
+ }).flat();
1581
+ }).flat());
1582
+ promiseList.push([
1583
+ "IDATEFROMEPOCH",
1584
+ "IDATEYMDFROMEPOCH"
1585
+ ].map(function (sqlFunc) {
1586
+ return [
1587
+ [10000101000000, "-30610224000"],
1588
+ [10000101000000, -30610224000],
1589
+ [10000301000000, -30605126400],
1590
+ [10040229000000, -30478982400],
1591
+ [99960229235959, 253281254399, 253281168000],
1592
+ [99970301235959, 253312876799, 253312790400],
1593
+ [99991231235959, "253402300799", "253402214400"],
1594
+ [99991231235959, 253402300799, 253402214400]
1595
+ ].map(function ([valExpect, valIn, valInYmd]) {
1596
+ return [
1597
+ sqlFunc,
1598
+ (
1599
+ (/^IDATEYMDFROM|_YMD$/).test(sqlFunc)
1600
+ ? valInYmd || valIn
1601
+ : valIn
1602
+ ),
1603
+ idateArgNormalize(sqlFunc, valExpect, "expect")
1604
+ ];
1605
+ });
1606
+ }).flat());
1607
+ promiseList.push([
1608
+ "IDATEFROMEPOCH",
1609
+ "IDATEYMDFROMEPOCH"
1610
+ ].map(function (sqlFunc) {
1611
+ return [
1612
+ [-30610224000, 10000101000000, "-0 SECOND"],
1613
+ [-30610224000, null, "-1 SECOND"],
1614
+ [253402214400, 99991231000000, "+0 DAY"],
1615
+ [253402214400, null, "+1 DAY"]
1616
+ ].map(function ([valIn, valExpect, modifier]) {
1617
+ return [
1618
+ sqlFunc,
1619
+ valIn,
1620
+ idateArgNormalize(sqlFunc, valExpect, "expect"),
1621
+ modifier
1622
+ ];
1623
+ });
1624
+ }).flat());
1625
+ promiseList.push([
1626
+ "IDATEFROM_JULIAN",
1627
+ "IDATEYMDFROM_JULIAN"
1628
+ ].map(function (sqlFunc) {
1629
+ return [
1630
+ [10000101000000, "2086302.5"],
1631
+ [10000101000000, 2086302.5],
1632
+ [10000301000000, 2086361.5],
1633
+ [10040229000000, 2087821.5],
1634
+ [99960229235959, 5372083.49998843, 5372082.5],
1635
+ [99970301235959, 5372449.49998843, 5372448.5],
1636
+ [99991231235959, "5373484.49998843", "5373483.5"],
1637
+ [99991231235959, 5373484.49998843, 5373483.5]
1638
+ ].map(function ([valExpect, valIn, valInYmd]) {
1639
+ return [
1640
+ sqlFunc,
1641
+ (
1642
+ (/^IDATEYMDFROM|_YMD$/).test(sqlFunc)
1643
+ ? valInYmd || valIn
1644
+ : valIn
1645
+ ),
1646
+ idateArgNormalize(sqlFunc, valExpect, "expect")
1647
+ ];
1648
+ });
1649
+ }).flat());
1650
+ promiseList.push([
1651
+ "IDATEFROM_JULIAN",
1652
+ "IDATEYMDFROM_JULIAN"
1653
+ ].map(function (sqlFunc) {
1654
+ return [
1655
+ [2086302.5, 10000101000000, "-0 SECOND"],
1656
+ [2086302.5, null, "-1 SECOND"],
1657
+ [5373483.5, 99991231000000, "+0 DAY"],
1658
+ [5373483.5, null, "+1 DAY"]
1659
+ ].map(function ([valIn, valExpect, modifier]) {
1660
+ return [
1661
+ sqlFunc,
1662
+ valIn,
1663
+ idateArgNormalize(sqlFunc, valExpect, "expect"),
1664
+ modifier
1665
+ ];
1666
+ });
1667
+ }).flat());
1668
+ promiseList.push([
1669
+ "IDATEFROM_TEXT",
1670
+ "IDATEYMDFROM_TEXT"
1671
+ ].map(function (sqlFunc) {
1672
+ return [
1673
+ ["1000-01-01 00:00:00", 10000101000000],
1674
+ ["1000-02-29 00:00:00", 10000301000000],
1675
+ ["1000-03-01 00:00:00", 10000301000000],
1676
+ ["1004-02-29 00:00:00", 10040229000000],
1677
+ ["9996-02-29 23:59:59", 99960229235959],
1678
+ ["9997-02-29 23:59:59", 99970301235959],
1679
+ ["9997-03-01 23:59:59", 99970301235959],
1680
+ ["9999-12-31 23:59:59", 99991231235959]
1681
+ ].map(function ([valIn, valExpect]) {
1682
+ return [sqlFunc, `${sqlFunc}_YMD`].map(function (sqlFunc) {
1683
+ return [
1684
+ sqlFunc,
1685
+ idateArgNormalize(sqlFunc, valIn, "input"),
1686
+ idateArgNormalize(sqlFunc, valExpect, "expect")
1687
+ ];
1688
+ });
1689
+ }).flat();
1690
+ }).flat());
1691
+ promiseList.push([
1692
+ "IDATETO('IEPOCH')",
1693
+ "IDATETOEPOCH"
1694
+ ].map(function (sqlFunc) {
1695
+ return [
1696
+ ["10000101000000", -30610224000],
1697
+ ["99991231235959", 253402300799, 253402214400],
1698
+ [10000101000000, -30610224000],
1699
+ [10000229000000, -30605126400],
1700
+ [10000301000000, -30605126400],
1701
+ [10040229000000, -30478982400],
1702
+ [99960229235959, 253281254399, 253281168000],
1703
+ [99970229235959, 253312876799, 253312790400],
1704
+ [99970301235959, 253312876799, 253312790400],
1705
+ [99991231235959, 253402300799, 253402214400],
1706
+ //
1707
+ ["1000-01-01 00:00:00", null],
1708
+ ["9999-12-31 23:59:59", null]
1709
+ ].map(function ([valIn, valExpect, valExpectYmd]) {
1710
+ return [sqlFunc, `${sqlFunc}_YMD`].map(function (sqlFunc) {
1711
+ return [
1712
+ sqlFunc,
1713
+ idateArgNormalize(sqlFunc, valIn, "input"),
1714
+ (
1715
+ (/^IDATEYMDFROM|_YMD$/).test(sqlFunc)
1716
+ ? valExpectYmd || valExpect
1717
+ : valExpect
1718
+ )
1719
+ ];
1720
+ });
1721
+ }).flat();
1722
+ }).flat());
1723
+ promiseList.push([
1724
+ "IDATETO('IJULIAN')"
1725
+ ].map(function (sqlFunc) {
1726
+ return [
1727
+ ["10000101000000", 2086302.5],
1728
+ ["99991231235959", 5373484.49998843, 5373483.5],
1729
+ [10000101000000, 2086302.5],
1730
+ [10000229000000, 2086361.5],
1731
+ [10000301000000, 2086361.5],
1732
+ [10040229000000, 2087821.5],
1733
+ [99960229235959, 5372083.49998843, 5372082.5],
1734
+ [99970229235959, 5372449.49998843, 5372448.5],
1735
+ [99970301235959, 5372449.49998843, 5372448.5],
1736
+ [99991231235959, 5373484.49998843, 5373483.5]
1737
+ ].map(function ([valIn, valExpect, valExpectYmd]) {
1738
+ return [sqlFunc, `${sqlFunc}_YMD`].map(function (sqlFunc) {
1739
+ return [
1740
+ sqlFunc,
1741
+ idateArgNormalize(sqlFunc, valIn, "input"),
1742
+ (
1743
+ (/^IDATEYMDFROM|_YMD$/).test(sqlFunc)
1744
+ ? valExpectYmd || valExpect
1745
+ : valExpect
1746
+ )
1747
+ ];
1748
+ });
1749
+ }).flat();
1750
+ }).flat());
1751
+ promiseList.push([
1752
+ "IDATETO('ITEXT')",
1753
+ "IDATETO('ITEXTYMD')"
1754
+ ].map(function (sqlFunc) {
1755
+ return [
1756
+ ["10000101000000", "1000-01-01 00:00:00"],
1757
+ ["99991231235959", "9999-12-31 23:59:59"],
1758
+ [10000101000000, "1000-01-01 00:00:00"],
1759
+ [10000229000000, "1000-03-01 00:00:00"],
1760
+ [10000301000000, "1000-03-01 00:00:00"],
1761
+ [10040229000000, "1004-02-29 00:00:00"],
1762
+ [99960229235959, "9996-02-29 23:59:59"],
1763
+ [99970229235959, "9997-03-01 23:59:59"],
1764
+ [99970301235959, "9997-03-01 23:59:59"],
1765
+ [99991231235959, "9999-12-31 23:59:59"]
1766
+ ].map(function ([valIn, valExpect]) {
1767
+ return [
1768
+ sqlFunc,
1769
+ idateArgNormalize(sqlFunc, valIn, "input"),
1770
+ idateArgNormalize(sqlFunc, valExpect, "expect")
1771
+ ];
1772
+ });
1773
+ }).flat());
1774
+ promiseList.push([
1775
+ "IDATETO('IY')",
1776
+ "IDATETO('IYM')",
1777
+ "IDATETO('IYMD')",
1778
+ "IDATETO('IYMDH')",
1779
+ "IDATETO('IYMDHM')",
1780
+ "IDATETO('IYMDHMS')"
1781
+ ].map(function (sqlFunc) {
1782
+ return [
1783
+ ["10000101000000", 10000101000000],
1784
+ ["99991231235959", 99991231235959],
1785
+ [10000101000000, 10000101000000],
1786
+ [10000101000000, null, -1],
1787
+ [10000229000000, 10000301000000],
1788
+ [10000301000000, 10000301000000],
1789
+ [10040229000000, 10040229000000],
1790
+ [99960229235959, 99960229235959],
1791
+ [99970229235959, 99970301235959],
1792
+ [99970301235959, 99970301235959],
1793
+ [99991231235959, 99991231235959],
1794
+ [99991231235959, null, 1]
1795
+ ].map(function ([valIn, valExpect, modifier]) {
1796
+ return [sqlFunc, `${sqlFunc}_YMD`].map(function (sqlFunc) {
1797
+ return [
1798
+ sqlFunc,
1799
+ idateArgNormalize(sqlFunc, valIn, "input"),
1800
+ idateArgNormalize(sqlFunc, valExpect, "expect"),
1801
+ modifier
1802
+ ];
1803
+ });
1804
+ }).flat();
1805
+ }).flat());
1806
+ await Promise.all(promiseList.flat().map(async function ([
1807
+ sqlFunc, valIn, valExpect, modifier
1808
+ ], ii) {
1809
+ let sql;
1810
+ let sqlFunc2 = sqlFunc.replace((/_JULIAN|_TEXT|_YMD/g), "");
1811
+ let valActual;
1812
+ sql = String(
1813
+ modifier === undefined
1814
+ ? `SELECT ${sqlFunc2}($valIn, '+0 SECOND');`
1815
+ : typeof modifier === "number"
1816
+ ? (
1817
+ (/^IDATEYMDFROM|YMD$/).test(sqlFunc)
1818
+ ? `SELECT ${sqlFunc2}($valIn, '${modifier} DAY');`
1819
+ : `SELECT ${sqlFunc2}($valIn, '${modifier} SECOND');`
1820
+ )
1821
+ : `SELECT ${sqlFunc2}($valIn, '${modifier}');`
1822
+ ).replace(")(", ", ");
1823
+ valActual = (
1824
+ await dbExecAndReturnLastValue({
1825
+ bindList: {
1826
+ valIn
1827
+ },
1828
+ db,
1829
+ sql
1830
+ })
1831
+ );
1832
+ assertJsonEqual(valActual, valExpect, {
1833
+ ii,
1834
+ modifier,
1835
+ sql,
1836
+ sqlFunc,
1837
+ valActual,
1838
+ valExpect,
1839
+ valIn
1840
+ });
1841
+ }));
1842
+ });
1843
+ jstestIt((
1844
+ "test sqlite-extension-math handling-behavior"
1845
+ ), async function test_sqlite_extension_math() {
1846
+ let db = await dbOpenAsync({});
1847
+ // test sqlmath-defined-func handling-behavior
1848
+ Object.entries({
1849
+ "''": {
1850
+ "CASTREALORNULL": 0,
1851
+ "CASTREALORZERO": 0,
1852
+ "CASTTEXTOREMPTY": "",
1853
+ "COPYBLOB": "",
1854
+ "SHA256": (
1855
+ "E3B0C44298FC1C149AFBF4C8996FB924"
1856
+ + "27AE41E4649B934CA495991B7852B855"
1857
+ )
1858
+ },
1859
+ "'-0.5'": {
1860
+ "CASTREALORNULL": -0.5,
1861
+ "CASTREALORZERO": -0.5,
1862
+ "CASTTEXTOREMPTY": "-0.5",
1863
+ "COPYBLOB": "-0.5",
1864
+ "SHA256": (
1865
+ "1B07B0CFFA0B3F596B5E048B01151688"
1866
+ + "86CC5183DD518655B5515EE5DDDAC6D1"
1867
+ )
1868
+ },
1869
+ "'-1'": {
1870
+ "CASTREALORNULL": -1,
1871
+ "CASTREALORZERO": -1,
1872
+ "CASTTEXTOREMPTY": "-1",
1873
+ "COPYBLOB": "-1",
1874
+ "COT": -0.642092615934331,
1875
+ "COTH": -1.31303528549933,
1876
+ "SHA256": (
1877
+ "1BAD6B8CF97131FCEAB8543E81F77571"
1878
+ + "95FBB1D36B376EE994AD1CF17699C464"
1879
+ ),
1880
+ "SIGN": -1,
1881
+ "SQRTWITHSIGN": -1
1882
+ },
1883
+ "'0'": {
1884
+ "CASTREALORNULL": 0,
1885
+ "CASTREALORZERO": 0,
1886
+ "CASTTEXTOREMPTY": "0",
1887
+ "COPYBLOB": "0",
1888
+ "COT": null,
1889
+ "COTH": null,
1890
+ "SHA256": (
1891
+ "5FECEB66FFC86F38D952786C6D696C79"
1892
+ + "C2DBC239DD4E91B46729D73A27FB57E9"
1893
+ ),
1894
+ "SIGN": 0,
1895
+ "SQRTWITHSIGN": 0
1896
+ },
1897
+ "'0.5'": {
1898
+ "CASTREALORNULL": 0.5,
1899
+ "CASTREALORZERO": 0.5,
1900
+ "CASTTEXTOREMPTY": "0.5",
1901
+ "COPYBLOB": "0.5",
1902
+ "SHA256": (
1903
+ "D2CBAD71FF333DE67D07EC676E352AB7"
1904
+ + "F38248EB69C942950157220607C55E84"
1905
+ )
1906
+ },
1907
+ "'1'": {
1908
+ "CASTREALORNULL": 1,
1909
+ "CASTREALORZERO": 1,
1910
+ "CASTTEXTOREMPTY": "1",
1911
+ "COPYBLOB": "1",
1912
+ "COT": 0.642092615934331,
1913
+ "COTH": 1.31303528549933,
1914
+ "SHA256": (
1915
+ "6B86B273FF34FCE19D6B804EFF5A3F57"
1916
+ + "47ADA4EAA22F1D49C01E52DDB7875B4B"
1917
+ ),
1918
+ "SIGN": 1,
1919
+ "SQRTWITHSIGN": 1
1920
+ },
1921
+ "'aa'": {
1922
+ "CASTREALORNULL": 0,
1923
+ "CASTREALORZERO": 0,
1924
+ "CASTTEXTOREMPTY": "aa",
1925
+ "COPYBLOB": "aa",
1926
+ "SHA256": (
1927
+ "961B6DD3EDE3CB8ECBAACBD68DE040CD"
1928
+ + "78EB2ED5889130CCEB4C49268EA4D506"
1929
+ )
1930
+ },
1931
+ "'abc'": {
1932
+ "SHA256": (
1933
+ "BA7816BF8F01CFEA414140DE5DAE2223"
1934
+ + "B00361A396177A9CB410FF61F20015AD"
1935
+ )
1936
+ },
1937
+ "'abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq'": {
1938
+ "SHA256": (
1939
+ "248D6A61D20638B8E5C026930C3E6039"
1940
+ + "A33CE45964FF2167F6ECEDD419DB06C1"
1941
+ )
1942
+ },
1943
+ "'hello'": {
1944
+ "CASTREALORNULL": 0,
1945
+ "CASTREALORZERO": 0,
1946
+ "CASTTEXTOREMPTY": "hello",
1947
+ "COPYBLOB": "hello",
1948
+ "SHA256": (
1949
+ "2CF24DBA5FB0A30E26E83B2AC5B9E29E"
1950
+ + "1B161E5C1FA7425E73043362938B9824"
1951
+ )
1952
+ },
1953
+ "-0.5": {
1954
+ "CASTREALORNULL": -0.5,
1955
+ "CASTREALORZERO": -0.5,
1956
+ "CASTTEXTOREMPTY": "-0.5",
1957
+ "COPYBLOB": -0.5,
1958
+ "SHA256": (
1959
+ "1B07B0CFFA0B3F596B5E048B01151688"
1960
+ + "86CC5183DD518655B5515EE5DDDAC6D1"
1961
+ )
1962
+ },
1963
+ "-0x7fffffffffffffff": {
1964
+ "COT": -0.0118008981305845,
1965
+ "COTH": -1,
1966
+ "SHA256": ( // '-9223372036854775807'
1967
+ "B7AE81320053F61245ED2D36E72E1D05"
1968
+ + "AD4235D8C784E60285F1EB1F06DA7845"
1969
+ ),
1970
+ "SIGN": -1,
1971
+ "SQRTWITHSIGN": -3037000499.97605
1972
+ },
1973
+ "-1": {
1974
+ "CASTREALORNULL": -1,
1975
+ "CASTREALORZERO": -1,
1976
+ "CASTTEXTOREMPTY": "-1",
1977
+ "COPYBLOB": -1,
1978
+ "COT": -0.642092615934331,
1979
+ "COTH": -1.31303528549933,
1980
+ "SHA256": (
1981
+ "1BAD6B8CF97131FCEAB8543E81F77571"
1982
+ + "95FBB1D36B376EE994AD1CF17699C464"
1983
+ ),
1984
+ "SIGN": -1,
1985
+ "SQRTWITHSIGN": -1
1986
+ },
1987
+ "-1e999": {
1988
+ "COT": null,
1989
+ "COTH": -1,
1990
+ "SHA256": ( // '-Inf'
1991
+ "8C1FB05600CEB1FF74474E66DDD603F5"
1992
+ + "FE8C839B03598A124E2AACB6A08C8837"
1993
+ ),
1994
+ "SIGN": -1,
1995
+ "SQRTWITHSIGN": null
1996
+ },
1997
+ "0": {
1998
+ "CASTREALORNULL": 0,
1999
+ "CASTREALORZERO": 0,
2000
+ "CASTTEXTOREMPTY": "0",
2001
+ "COPYBLOB": 0,
2002
+ "COT": null,
2003
+ "COTH": null,
2004
+ "SHA256": (
2005
+ "5FECEB66FFC86F38D952786C6D696C79"
2006
+ + "C2DBC239DD4E91B46729D73A27FB57E9"
2007
+ ),
2008
+ "SIGN": 0,
2009
+ "SQRTWITHSIGN": 0
2010
+ },
2011
+ "0.5": {
2012
+ "CASTREALORNULL": 0.5,
2013
+ "CASTREALORZERO": 0.5,
2014
+ "CASTTEXTOREMPTY": "0.5",
2015
+ "COPYBLOB": 0.5,
2016
+ "SHA256": (
2017
+ "D2CBAD71FF333DE67D07EC676E352AB7"
2018
+ + "F38248EB69C942950157220607C55E84"
2019
+ )
2020
+ },
2021
+ "0.5, 0.5": {
2022
+ "ROUNDORZERO": 1
2023
+ },
2024
+ "0.5, 1": {
2025
+ "ROUNDORZERO": 0.5
2026
+ },
2027
+ "0.5, NULL": {
2028
+ "ROUNDORZERO": 1
2029
+ },
2030
+ "0x7fffffffffffffff": {
2031
+ "COT": 0.0118008981305845,
2032
+ "COTH": 1,
2033
+ "SHA256": ( // '9223372036854775807'
2034
+ "B34A1C30A715F6BF8B7243AFA7FAB883"
2035
+ + "CE3612B7231716BDCBBDC1982E1AED29"
2036
+ ),
2037
+ "SIGN": 1,
2038
+ "SQRTWITHSIGN": 3037000499.97605
2039
+ },
2040
+ "0x8000000000000000": {
2041
+ "COT": -0.0118008981305845,
2042
+ "COTH": -1,
2043
+ "SHA256": ( // '-9223372036854775808'
2044
+ "85386477F3AF47E4A0B308EE3B3A688D"
2045
+ + "F16E8B2228105DD7D4DCD42A9807CB78"
2046
+ ),
2047
+ "SIGN": -1,
2048
+ "SQRTWITHSIGN": -3037000499.97605
2049
+ },
2050
+ "0xffffffffffffffff": {
2051
+ "COT": -0.642092615934331,
2052
+ "COTH": -1.31303528549933,
2053
+ "SHA256": ( // '-1'
2054
+ "1BAD6B8CF97131FCEAB8543E81F77571"
2055
+ + "95FBB1D36B376EE994AD1CF17699C464"
2056
+ ),
2057
+ "SIGN": -1,
2058
+ "SQRTWITHSIGN": -1
2059
+ },
2060
+ "1": {
2061
+ "CASTREALORNULL": 1,
2062
+ "CASTREALORZERO": 1,
2063
+ "CASTTEXTOREMPTY": "1",
2064
+ "COPYBLOB": 1,
2065
+ "COT": 0.642092615934331,
2066
+ "COTH": 1.31303528549933,
2067
+ "SHA256": (
2068
+ "6B86B273FF34FCE19D6B804EFF5A3F57"
2069
+ + "47ADA4EAA22F1D49C01E52DDB7875B4B"
2070
+ ),
2071
+ "SIGN": 1,
2072
+ "SQRTWITHSIGN": 1
2073
+ },
2074
+ "1e999": {
2075
+ "CASTREALORNULL": null,
2076
+ "CASTREALORZERO": 0,
2077
+ "COT": null,
2078
+ "COTH": 1,
2079
+ "SHA256": ( // 'Inf'
2080
+ "1DAEC9C71EE2A842CDEE6977AD8C562E"
2081
+ + "D4AA4FB1338BECD25D79A104B473D9D8"
2082
+ ),
2083
+ "SIGN": 1,
2084
+ "SQRTWITHSIGN": null
2085
+ },
2086
+ "NULL": {
2087
+ "CASTREALORNULL": null,
2088
+ "CASTREALORZERO": 0,
2089
+ "CASTTEXTOREMPTY": "",
2090
+ "COPYBLOB": null,
2091
+ "COT": null,
2092
+ "COTH": null,
2093
+ "SHA256": "",
2094
+ "SIGN": null,
2095
+ "SQRTWITHSIGN": null
2096
+ },
2097
+ "NULL, 0": {
2098
+ "ROUNDORZERO": 0
2099
+ },
2100
+ "NULL, 0.5": {
2101
+ "ROUNDORZERO": 0
2102
+ },
2103
+ "NULL, NULL": {
2104
+ "ROUNDORZERO": 0
2105
+ },
2106
+ "ZEROBLOB(0)": {
2107
+ "CASTREALORNULL": 0,
2108
+ "CASTREALORZERO": 0,
2109
+ "CASTTEXTOREMPTY": "",
2110
+ "COPYBLOB": null,
2111
+ "SHA256": (
2112
+ "E3B0C44298FC1C149AFBF4C8996FB924"
2113
+ + "27AE41E4649B934CA495991B7852B855"
2114
+ )
2115
+ },
2116
+ "ZEROBLOB(1)": {
2117
+ "CASTREALORNULL": 0,
2118
+ "CASTREALORZERO": 0,
2119
+ "CASTTEXTOREMPTY": "",
2120
+ "COPYBLOB": null,
2121
+ "SHA256": (
2122
+ "6E340B9CFFB37A989CA544E6BB780A2C"
2123
+ + "78901D3FB33738768511A30617AFA01D"
2124
+ )
2125
+ }
2126
+ }).forEach(function ([
2127
+ arg, funcDict
2128
+ ]) {
2129
+ Object.entries(funcDict).forEach(async function ([
2130
+ func, valExpect
2131
+ ]) {
2132
+ let sql;
2133
+ let valActual;
2134
+ sql = (
2135
+ func === "SHA256"
2136
+ ? `SELECT HEX(${func}(${arg}))`
2137
+ : `SELECT ${func}(${arg})`
2138
+ );
2139
+ valActual = noop(
2140
+ await dbExecAndReturnLastValue({
2141
+ db,
2142
+ sql
2143
+ })
2144
+ );
2145
+ assertJsonEqual(valActual, valExpect, {
2146
+ sql,
2147
+ valExpect
2148
+ });
2149
+ });
2150
+ });
2151
+ });
2152
+ jstestIt((
2153
+ "test sqlite-extension-quantile handling-behavior"
2154
+ ), async function test_sqlite_extension_quantile() {
2155
+ let db = await dbOpenAsync({});
2156
+ await (async function () {
2157
+ let valActual = await dbExecAndReturnLastTable({
2158
+ db,
2159
+ sql: (`
2160
+ -- test null-case handling-behavior
2161
+ DROP TABLE IF EXISTS __tmp1;
2162
+ CREATE TEMP TABLE __tmp1 (val REAL);
2163
+ SELECT
2164
+ 1 AS id,
2165
+ MEDIAN2(val) AS mdn,
2166
+ QUANTILE(val, 0.5) AS qnt,
2167
+ STDEV(val) AS std
2168
+ FROM __tmp1;
2169
+ `)
2170
+ });
2171
+ assertJsonEqual(
2172
+ valActual,
2173
+ [{id: 1, mdn: null, qnt: null, std: null}]
2174
+ );
2175
+ }());
2176
+ await Promise.all([
2177
+ [
2178
+ [[], -99, undefined],
2179
+ [[], 0, undefined],
2180
+ [[], 0.5, undefined],
2181
+ [[], 1, undefined],
2182
+ [[], 99, undefined],
2183
+ [[undefined, undefined, 1, 1, 2, 3, 4], 0.5, 2],
2184
+ [[undefined, undefined, 1, 2, 3, 4], 0.5, 2.5],
2185
+ [[undefined], 0.5, undefined]
2186
+ ],
2187
+ [
2188
+ [[], -99, 1],
2189
+ [[], 0, 1],
2190
+ [[], 0.125, 1.875],
2191
+ [[], 0.250, 2.75],
2192
+ [[], 0.375, 3.625],
2193
+ [[], 0.500, 4.5],
2194
+ [[], 0.625, 5.375],
2195
+ [[], 0.750, 6.25],
2196
+ [[], 0.875, 7.125],
2197
+ [[], 1, 8],
2198
+ [[], 99, 8],
2199
+ [[0.1], 0, 0.1],
2200
+ [[1.1], 0.125, 1.1],
2201
+ [[2.1], 0.250, 2.1],
2202
+ [[3.1], 0.375, 3.1],
2203
+ [[4.1], 0.500, 4.1],
2204
+ [[4.1], 0.625, 5],
2205
+ [[5.1], 0.750, 6],
2206
+ [[6.1], 0.875, 7],
2207
+ [[7.1], 1, 8],
2208
+ [[0], 0, 0],
2209
+ [[1], 0.125, 1],
2210
+ [[2], 0.250, 2],
2211
+ [[3], 0.375, 3],
2212
+ [[4], 0.500, 4],
2213
+ [[5], 0.625, 5],
2214
+ [[6], 0.750, 6],
2215
+ [[7], 0.875, 7],
2216
+ [[8], 1, 8],
2217
+ [[], 0, 1]
2218
+ ].map(function ([
2219
+ data, qq, valExpect
2220
+ ]) {
2221
+ return [
2222
+ data.concat([
2223
+ undefined, -Infinity, Infinity, NaN,
2224
+ "8", 7, 6, "5", "4", 3, 2, "1",
2225
+ undefined
2226
+ ]),
2227
+ qq,
2228
+ valExpect
2229
+ ];
2230
+ })
2231
+ ].flat().map(async function ([
2232
+ data, qq, valExpect
2233
+ ]) {
2234
+ let avg = 0;
2235
+ let data2;
2236
+ let valExpectMdn;
2237
+ let valExpectStd = 0;
2238
+ data2 = data.map(function (elem) {
2239
+ return Number(elem);
2240
+ }).filter(function (elem) {
2241
+ return Number.isFinite(elem);
2242
+ }).sort();
2243
+ valExpectMdn = (
2244
+ data2.length % 2 === 0
2245
+ ? 0.5 * (
2246
+ data2[0.5 * data2.length - 1] + data2[0.5 * data2.length]
2247
+ )
2248
+ : data2[0.5 * (data2.length - 1)]
2249
+ );
2250
+ data2.forEach(function (elem) {
2251
+ avg += elem;
2252
+ });
2253
+ avg *= 1 / data2.length;
2254
+ data2.forEach(function (elem) {
2255
+ valExpectStd += (elem - avg) ** 2;
2256
+ });
2257
+ valExpectStd = (
2258
+ data2.length <= 0
2259
+ ? null
2260
+ // : data2.length === 1
2261
+ // ? 0
2262
+ : Number(Math.sqrt(
2263
+ valExpectStd / (data2.length - 1)
2264
+ ).toFixed(8))
2265
+ );
2266
+ await Promise.all([
2267
+ data,
2268
+ Array.from(data).reverse()
2269
+ ].map(async function (data) {
2270
+ let valActual;
2271
+ valActual = await dbExecAndReturnLastRow({
2272
+ bindList: {
2273
+ tmp1: JSON.stringify(data)
2274
+ },
2275
+ db,
2276
+ sql: (`
2277
+ -- test null-case handling-behavior
2278
+ SELECT QUANTILE(value, ${qq}) AS qnt FROM JSON_EACH($tmp1) WHERE 0;
2279
+ -- test last-row handling-behavior
2280
+ SELECT
2281
+ MEDIAN2(value) AS mdn,
2282
+ QUANTILE(value, ${qq}) AS qnt,
2283
+ ROUND(stdev(value), 8) AS std
2284
+ FROM JSON_EACH($tmp1);
2285
+ `)
2286
+ });
2287
+ assertJsonEqual(
2288
+ valActual,
2289
+ {
2290
+ mdn: valExpectMdn,
2291
+ qnt: valExpect ?? null,
2292
+ std: valExpectStd
2293
+ },
2294
+ {
2295
+ data,
2296
+ qq,
2297
+ valActual,
2298
+ valExpect,
2299
+ valExpectMdn,
2300
+ valExpectStd
2301
+ }
2302
+ );
2303
+ }));
2304
+ }));
2305
+ });
2306
+ jstestIt((
2307
+ "test sqlite-extension-win_avgx handling-behavior"
2308
+ ), async function test_sqlite_extension_win_avgx() {
2309
+ let db = await dbOpenAsync({});
2310
+ let valIn;
2311
+ async function test_win_avgx_aggregate({
2312
+ aa,
2313
+ bb,
2314
+ valExpect,
2315
+ valExpect2
2316
+ }) {
2317
+ let sqlBetween = "";
2318
+ let valActual;
2319
+ if (aa !== undefined) {
2320
+ sqlBetween = (
2321
+ `ROWS BETWEEN ${aa - 1} PRECEDING AND ${bb} FOLLOWING`
2322
+ );
2323
+ }
2324
+ // test win_avg1-aggregate handling-behavior
2325
+ valActual = await dbExecAndReturnLastTable({
2326
+ bindList: {
2327
+ valIn: JSON.stringify(valIn)
2328
+ },
2329
+ db,
2330
+ sql: (`
2331
+ SELECT
2332
+ WIN_AVG1(value->>1) OVER (
2333
+ ORDER BY value->>0 ASC
2334
+ ${sqlBetween}
2335
+ ) AS val
2336
+ FROM JSON_EAcH($valIn);
2337
+ `)
2338
+ });
2339
+ valActual = valActual.map(function ({val}) {
2340
+ return Number(val.toFixed(4));
2341
+ });
2342
+ assertJsonEqual(valActual, valExpect);
2343
+ // test win_avg2-aggregate handling-behavior
2344
+ valActual = await dbExecAndReturnLastTable({
2345
+ bindList: {
2346
+ valIn: JSON.stringify(valIn)
2347
+ },
2348
+ db,
2349
+ sql: (`
2350
+ SELECT
2351
+ id2,
2352
+ DOUBLEARRAY_JSONTO(WIN_AVG2(
2353
+ value->>1,
2354
+ value->>1,
2355
+ value->>1,
2356
+ value->>1,
2357
+ value->>1,
2358
+ value->>1,
2359
+ value->>1,
2360
+ value->>1,
2361
+ value->>1,
2362
+ IIF(id2 = 1, -1, value->>1)
2363
+ ) OVER (
2364
+ ORDER BY value->>0 ASC
2365
+ ${sqlBetween}
2366
+ )) AS val
2367
+ FROM (
2368
+ SELECT
2369
+ *,
2370
+ ROW_NUMBER() OVER(ORDER BY id ASC) AS id2
2371
+ FROM JSON_EAcH($valIn)
2372
+ );
2373
+ `)
2374
+ });
2375
+ valActual = valActual.map(function ({val}, ii, list) {
2376
+ val = JSON.parse(val).map(function (elem, jj) {
2377
+ elem = Number(elem.toFixed(4));
2378
+ if (ii + (bb || 0) + 1 >= list.length && jj === 9) {
2379
+ assertJsonEqual(elem, valExpect2, valActual);
2380
+ } else {
2381
+ assertJsonEqual(elem, valExpect[ii], valActual);
2382
+ }
2383
+ return elem;
2384
+ });
2385
+ return val[0];
2386
+ });
2387
+ assertJsonEqual(valActual, valExpect);
2388
+ }
2389
+ valIn = [
2390
+ [11, NaN],
2391
+ [10, "10"],
2392
+ [9, 9],
2393
+ [8, "8"],
2394
+ [7, 7],
2395
+ [6, 6],
2396
+ [5, Infinity],
2397
+ [4, "4"],
2398
+ [3, 3],
2399
+ [2, 2],
2400
+ [1, "1"],
2401
+ [0, undefined]
2402
+ ];
2403
+ await Promise.all([
2404
+ (async function () {
2405
+ let valActual;
2406
+ // test win_avg2-error handling-behavior
2407
+ await assertErrorThrownAsync(function () {
2408
+ return dbExecAsync({
2409
+ db,
2410
+ sql: (`
2411
+ SELECT WIN_AVG2() FROM (SELECT 1);
2412
+ `)
2413
+ });
2414
+ }, "wrong number of arguments");
2415
+ // test win_avg1-null-case handling-behavior
2416
+ valActual = await dbExecAndReturnLastTable({
2417
+ db,
2418
+ sql: (`
2419
+ DROP TABLE IF EXISTS __tmp1;
2420
+ CREATE TEMP TABLE __tmp1 (val REAL);
2421
+ SELECT WIN_AVG1(1) FROM __tmp1;
2422
+ `)
2423
+ });
2424
+ valActual = valActual.map(function ({val}) {
2425
+ return val;
2426
+ });
2427
+ assertJsonEqual(valActual, [null]);
2428
+ // test win_avg2-null-case handling-behavior
2429
+ valActual = await dbExecAndReturnLastTable({
2430
+ db,
2431
+ sql: (`
2432
+ DROP TABLE IF EXISTS __tmp1;
2433
+ CREATE TEMP TABLE __tmp1 (val REAL);
2434
+ SELECT DOUBLEARRAY_JSONTO(WIN_AVG2(1, 2, 3)) FROM __tmp1;
2435
+ `)
2436
+ });
2437
+ valActual = valActual.map(function ({val}) {
2438
+ return val;
2439
+ });
2440
+ assertJsonEqual(valActual, [null]);
2441
+ }()),
2442
+ // test win_avg2-aggregate-normal handling-behavior
2443
+ test_win_avgx_aggregate({
2444
+ valExpect: [
2445
+ 0, 0.5, 1, 1.5,
2446
+ 2, 2.3333, 2.8571, 3.375,
2447
+ 3.8889, 4.4, 4.9091, 5.3333
2448
+ ],
2449
+ valExpect2: 4.4167
2450
+ }),
2451
+ // test win_avg2-aggregate-window handling-behavior
2452
+ test_win_avgx_aggregate({
2453
+ aa: 1,
2454
+ bb: 3,
2455
+ valExpect: [
2456
+ 1.5, 2.5, 3.25, 4.25,
2457
+ 5.25, 6.25, 7.5, 8.5,
2458
+ 9.25, 9.25, 9.25, 9.25
2459
+ ],
2460
+ valExpect2: 6.5
2461
+ }),
2462
+ test_win_avgx_aggregate({
2463
+ aa: 3,
2464
+ bb: 1,
2465
+ valExpect: [
2466
+ 0.5, 1, 1.5, 2.5,
2467
+ 3.25, 4.25, 5.25, 6.25,
2468
+ 7.5, 8.5, 9.25, 9.25
2469
+ ],
2470
+ valExpect2: 6.5
2471
+ }),
2472
+ test_win_avgx_aggregate({
2473
+ aa: 4,
2474
+ bb: 0,
2475
+ valExpect: [
2476
+ 0, 0.5, 1, 1.5,
2477
+ 2.5, 3.25, 4.25, 5.25,
2478
+ 6.25, 7.5, 8.5, 9.25
2479
+ ],
2480
+ valExpect2: 6.5
2481
+ })
2482
+ ]);
2483
+ });
2484
+ jstestIt((
2485
+ "test sqlite-extension-win_emax handling-behavior"
2486
+ ), async function test_sqlite_extension_win_emax() {
2487
+ let db = await dbOpenAsync({});
2488
+ let valIn;
2489
+ async function test_win_emax_aggregate({
2490
+ aa,
2491
+ bb,
2492
+ valExpect,
2493
+ valExpect2
2494
+ }) {
2495
+ let alpha = 2 * 1.0 / (4 + 1);
2496
+ let sqlBetween = "";
2497
+ let valActual;
2498
+ if (aa !== undefined) {
2499
+ sqlBetween = (
2500
+ `ROWS BETWEEN ${aa - 1} PRECEDING AND ${bb} FOLLOWING`
2501
+ );
2502
+ }
2503
+ // test win_ema1-aggregate handling-behavior
2504
+ valActual = await dbExecAsync({
2505
+ bindList: {
2506
+ valIn: JSON.stringify(valIn)
2507
+ },
2508
+ db,
2509
+ sql: (`
2510
+ SELECT
2511
+ WIN_EMA1(${alpha}, value->>1) OVER (
2512
+ ORDER BY value->>0 ASC
2513
+ ${sqlBetween}
2514
+ ) AS val
2515
+ FROM (
2516
+ SELECT
2517
+ *,
2518
+ ROW_NUMBER() OVER(ORDER BY id ASC) AS id2
2519
+ FROM JSON_EAcH($valIn)
2520
+ );
2521
+ `)
2522
+ });
2523
+ valActual = valActual[0].map(function ({val}) {
2524
+ return Number(val.toFixed(4));
2525
+ });
2526
+ assertJsonEqual(valActual, valExpect);
2527
+ // test win_ema2-aggregate handling-behavior
2528
+ valActual = await dbExecAsync({
2529
+ bindList: {
2530
+ valIn: JSON.stringify(valIn)
2531
+ },
2532
+ db,
2533
+ sql: (`
2534
+ SELECT
2535
+ id2,
2536
+ DOUBLEARRAY_JSONTO(WIN_EMA2(
2537
+ ${alpha},
2538
+ value->>1,
2539
+ value->>1,
2540
+ value->>1,
2541
+ value->>1,
2542
+ value->>1,
2543
+ value->>1,
2544
+ value->>1,
2545
+ value->>1,
2546
+ value->>1,
2547
+ IIF(id2 = 1, -1, value->>1)
2548
+ ) OVER (
2549
+ ORDER BY value->>0 ASC
2550
+ ${sqlBetween}
2551
+ )) AS val
2552
+ FROM (
2553
+ SELECT
2554
+ *,
2555
+ ROW_NUMBER() OVER(ORDER BY id ASC) AS id2
2556
+ FROM JSON_EAcH($valIn)
2557
+ );
2558
+ `)
2559
+ });
2560
+ valActual = valActual[0].map(function ({val}, ii, list) {
2561
+ val = JSON.parse(val).map(function (elem, jj) {
2562
+ elem = Number(elem.toFixed(4));
2563
+ if (ii + (bb || 0) + 1 >= list.length && jj === 9) {
2564
+ assertJsonEqual(elem, valExpect2, valActual);
2565
+ } else {
2566
+ assertJsonEqual(elem, valExpect[ii], valActual);
2567
+ }
2568
+ return elem;
2569
+ });
2570
+ return val[0];
2571
+ });
2572
+ assertJsonEqual(valActual, valExpect);
2573
+ }
2574
+ valIn = [
2575
+ [11, NaN],
2576
+ [10, "10"],
2577
+ [9, 9],
2578
+ [8, "8"],
2579
+ [7, 7],
2580
+ [6, 6],
2581
+ [5, Infinity],
2582
+ [4, "4"],
2583
+ [3, 3],
2584
+ [2, 2],
2585
+ [1, "1"],
2586
+ [0, undefined]
2587
+ ];
2588
+ await Promise.all([
2589
+ (async function () {
2590
+ let valActual;
2591
+ // test win_ema2-error handling-behavior
2592
+ await assertErrorThrownAsync(function () {
2593
+ return dbExecAsync({
2594
+ db,
2595
+ sql: (`
2596
+ SELECT WIN_EMA2(1) FROM (SELECT 1);
2597
+ `)
2598
+ });
2599
+ }, "wrong number of arguments");
2600
+ await assertErrorThrownAsync(function () {
2601
+ return dbExecAsync({
2602
+ db,
2603
+ sql: (`
2604
+ SELECT WIN_EMA2(NULL, 1) FROM (SELECT 1);
2605
+ `)
2606
+ });
2607
+ }, "invalid argument 'alpha'");
2608
+ // test win_ema1-null-case handling-behavior
2609
+ valActual = await dbExecAsync({
2610
+ db,
2611
+ sql: (`
2612
+ DROP TABLE IF EXISTS __tmp1;
2613
+ CREATE TEMP TABLE __tmp1 (val REAL);
2614
+ SELECT WIN_EMA1(1, 2) FROM __tmp1;
2615
+ `)
2616
+ });
2617
+ valActual = valActual[0].map(function ({val}) {
2618
+ return val;
2619
+ });
2620
+ assertJsonEqual(valActual, [null]);
2621
+ // test win_ema2-null-case handling-behavior
2622
+ valActual = await dbExecAsync({
2623
+ db,
2624
+ sql: (`
2625
+ DROP TABLE IF EXISTS __tmp1;
2626
+ CREATE TEMP TABLE __tmp1 (val REAL);
2627
+ SELECT DOUBLEARRAY_JSONTO(WIN_EMA2(1, 2, 3)) FROM __tmp1;
2628
+ `)
2629
+ });
2630
+ valActual = valActual[0].map(function ({val}) {
2631
+ return val;
2632
+ });
2633
+ assertJsonEqual(valActual, [null]);
2634
+ }()),
2635
+ // test win_emax-aggregate-normal handling-behavior
2636
+ test_win_emax_aggregate({
2637
+ valExpect: [
2638
+ 0.0000, 0.4000, 1.0400, 1.8240,
2639
+ 2.6944, 3.2166, 4.3300, 5.3980,
2640
+ 6.4388, 7.4633, 8.4780, 9.0868
2641
+ ],
2642
+ valExpect2: 4.6868
2643
+ }),
2644
+ // test win_emax-aggregate-window handling-behavior
2645
+ test_win_emax_aggregate({
2646
+ aa: 1,
2647
+ bb: 3,
2648
+ valExpect: [
2649
+ 1.824, 2.824, 3.424, 4.584,
2650
+ 5.680, 6.608, 7.824, 8.824,
2651
+ 9.424, 9.424, 9.424, 9.424
2652
+ ],
2653
+ valExpect2: 5.024
2654
+ }),
2655
+ test_win_emax_aggregate({
2656
+ aa: 3,
2657
+ bb: 1,
2658
+ valExpect: [
2659
+ 0.400, 1.040, 1.824, 2.824,
2660
+ 3.424, 4.584, 5.680, 6.608,
2661
+ 7.824, 8.824, 9.424, 9.424
2662
+ ],
2663
+ valExpect2: 5.024
2664
+ }),
2665
+ test_win_emax_aggregate({
2666
+ aa: 4,
2667
+ bb: 0,
2668
+ valExpect: [
2669
+ 0.000, 0.400, 1.040, 1.824,
2670
+ 2.824, 3.424, 4.584, 5.680,
2671
+ 6.608, 7.824, 8.824, 9.424
2672
+ ],
2673
+ valExpect2: 5.024
2674
+ })
2675
+ ]);
2676
+ });
2677
+ jstestIt((
2678
+ "test sqlite-extension-win_quantilex handling-behavior"
2679
+ ), async function test_sqlite_extension_win_quantilex() {
2680
+ let db = await dbOpenAsync({});
2681
+ let valIn;
2682
+ async function test_win_quantilex_aggregate({
2683
+ aa,
2684
+ bb,
2685
+ quantile,
2686
+ valExpect,
2687
+ valExpect2
2688
+ }) {
2689
+ let sqlBetween = "";
2690
+ let valActual;
2691
+ if (aa !== undefined) {
2692
+ sqlBetween = (
2693
+ `ROWS BETWEEN ${aa - 1} PRECEDING AND ${bb} FOLLOWING`
2694
+ );
2695
+ }
2696
+ // test win_quantile1-aggregate handling-behavior
2697
+ valActual = await dbExecAsync({
2698
+ bindList: {
2699
+ valIn: JSON.stringify(valIn)
2700
+ },
2701
+ db,
2702
+ sql: (`
2703
+ SELECT
2704
+ WIN_QUANTILE1(${quantile}, value->>1) OVER (
2705
+ ORDER BY value->>0 ASC
2706
+ ${sqlBetween}
2707
+ ) AS val
2708
+ FROM (
2709
+ SELECT
2710
+ *,
2711
+ ROW_NUMBER() OVER(ORDER BY id ASC) AS id2
2712
+ FROM JSON_EAcH($valIn)
2713
+ );
2714
+ `)
2715
+ });
2716
+ valActual = valActual[0].map(function ({val}) {
2717
+ return Number(val.toFixed(4));
2718
+ });
2719
+ assertJsonEqual(valActual, valExpect);
2720
+ // test win_quantile2-aggregate handling-behavior
2721
+ valActual = await dbExecAndReturnLastTable({
2722
+ bindList: {
2723
+ valIn: JSON.stringify(valIn)
2724
+ },
2725
+ db,
2726
+ sql: (`
2727
+ SELECT
2728
+ id2,
2729
+ DOUBLEARRAY_JSONTO(WIN_QUANTILE2(
2730
+ ${quantile}, value->>1,
2731
+ ${quantile}, value->>1,
2732
+ ${quantile}, value->>1,
2733
+ ${quantile}, value->>1,
2734
+ ${quantile}, value->>1,
2735
+ ${quantile}, value->>1,
2736
+ ${quantile}, value->>1,
2737
+ ${quantile}, value->>1,
2738
+ ${quantile}, value->>1,
2739
+ ${quantile}, IIF(id2 = 1, -1, value->>1)
2740
+ ) OVER (
2741
+ ORDER BY value->>0 ASC
2742
+ ${sqlBetween}
2743
+ )) AS val
2744
+ FROM (
2745
+ SELECT
2746
+ *,
2747
+ ROW_NUMBER() OVER(ORDER BY id ASC) AS id2
2748
+ FROM JSON_EAcH($valIn)
2749
+ );
2750
+ `)
2751
+ });
2752
+ valActual = valActual.map(function ({val}, ii, list) {
2753
+ val = JSON.parse(val).map(function (elem, jj) {
2754
+ elem = Number(elem.toFixed(4));
2755
+ if (ii + (bb || 0) + 1 >= list.length && jj === 9) {
2756
+ assertJsonEqual(elem, valExpect2, valActual);
2757
+ } else {
2758
+ assertJsonEqual(elem, valExpect[ii], valActual);
2759
+ }
2760
+ return elem;
2761
+ });
2762
+ return val[0];
2763
+ });
2764
+ assertJsonEqual(valActual, valExpect);
2765
+ }
2766
+ valIn = [
2767
+ [12, 11],
2768
+ [11, 10],
2769
+ [10, 9],
2770
+ [9, 8],
2771
+ [8, NaN],
2772
+ [7, 6],
2773
+ [6, "abcd"],
2774
+ [5, 4],
2775
+ [4, 3],
2776
+ [3, "2"],
2777
+ [2, "1"],
2778
+ [1, undefined]
2779
+ ];
2780
+ await Promise.all([
2781
+ (async function () {
2782
+ let valActual;
2783
+ // test win_quantile2-error handling-behavior
2784
+ await assertErrorThrownAsync(function () {
2785
+ return dbExecAsync({
2786
+ db,
2787
+ sql: (`
2788
+ SELECT WIN_QUANTILE2(1) FROM (SELECT 1);
2789
+ `)
2790
+ });
2791
+ }, "wrong number of arguments");
2792
+ await assertErrorThrownAsync(function () {
2793
+ return dbExecAsync({
2794
+ db,
2795
+ sql: (`
2796
+ SELECT WIN_QUANTILE2(NULL, 1) FROM (SELECT 1);
2797
+ `)
2798
+ });
2799
+ }, "argument 'quantile'");
2800
+ // test win_quantile1-null-case handling-behavior
2801
+ valActual = await dbExecAndReturnLastTable({
2802
+ db,
2803
+ sql: (`
2804
+ DROP TABLE IF EXISTS __tmp1;
2805
+ CREATE TEMP TABLE __tmp1 (val REAL);
2806
+ SELECT WIN_QUANTILE1(1, 2) FROM __tmp1;
2807
+ `)
2808
+ });
2809
+ valActual = valActual.map(function ({val}) {
2810
+ return val;
2811
+ });
2812
+ assertJsonEqual(valActual, [null]);
2813
+ // test win_quantile2-null-case handling-behavior
2814
+ valActual = await dbExecAndReturnLastTable({
2815
+ db,
2816
+ sql: (`
2817
+ DROP TABLE IF EXISTS __tmp1;
2818
+ CREATE TEMP TABLE __tmp1 (val REAL);
2819
+ SELECT DOUBLEARRAY_JSONTO(WIN_QUANTILE2(1, 2, 3)) FROM __tmp1;
2820
+ `)
2821
+ });
2822
+ valActual = valActual.map(function ({val}) {
2823
+ return val;
2824
+ });
2825
+ assertJsonEqual(valActual, [null]);
2826
+ }()),
2827
+ // test win_quantilex-aggregate-normal handling-behavior
2828
+ test_win_quantilex_aggregate({
2829
+ quantile: 0,
2830
+ valExpect: [
2831
+ 0.0000, 0.0000, 0.0000, 0.0000,
2832
+ 0.0000, 0.0000, 0.0000, 0.0000,
2833
+ 0.0000, 0.0000, 0.0000, 0.0000
2834
+ ],
2835
+ valExpect2: -1
2836
+ }),
2837
+ test_win_quantilex_aggregate({
2838
+ quantile: 0.25,
2839
+ valExpect: [
2840
+ 0.0000, 0.2500, 0.5000, 0.7500,
2841
+ 1.0000, 0.2500, 0.5000, 0.7500,
2842
+ 1.0000, 1.2500, 1.5000, 1.7500
2843
+ ],
2844
+ valExpect2: 0.7500
2845
+ }),
2846
+ test_win_quantilex_aggregate({
2847
+ quantile: 0.33333333,
2848
+ valExpect: [
2849
+ 0.0000, 0.3333, 0.6667, 1.0000,
2850
+ 1.3333, 0.6667, 1.0000, 1.3333,
2851
+ 1.6667, 2.0000, 2.3333, 2.6667
2852
+ ],
2853
+ valExpect2: 1.6667
2854
+ }),
2855
+ test_win_quantilex_aggregate({
2856
+ quantile: 0.5,
2857
+ valExpect: [
2858
+ 0.0000, 0.5000, 1.0000, 1.5000,
2859
+ 2.0000, 1.5000, 2.0000, 2.5000,
2860
+ 3.0000, 3.5000, 4.0000, 5.0000
2861
+ ],
2862
+ valExpect2: 3.5000
2863
+ }),
2864
+ test_win_quantilex_aggregate({
2865
+ quantile: 0.66666667,
2866
+ valExpect: [
2867
+ 0.0000, 0.6667, 1.3333, 2.0000,
2868
+ 2.6667, 2.3333, 3.0000, 3.6667,
2869
+ 4.6667, 6.0000, 6.0000, 6.6667
2870
+ ],
2871
+ valExpect2: 6.0000
2872
+ }),
2873
+ test_win_quantilex_aggregate({
2874
+ quantile: 0.75,
2875
+ valExpect: [
2876
+ 0.0000, 0.7500, 1.5000, 2.2500,
2877
+ 3.0000, 2.7500, 3.5000, 4.5000,
2878
+ 6.0000, 6.0000, 7.0000, 8.2500
2879
+ ],
2880
+ valExpect2: 6.5000
2881
+ }),
2882
+ test_win_quantilex_aggregate({
2883
+ quantile: 1,
2884
+ valExpect: [
2885
+ 0.0000, 1.0000, 2.0000, 3.0000,
2886
+ 4.0000, 4.0000, 6.0000, 6.0000,
2887
+ 8.0000, 9.0000, 10.0000, 11.0000
2888
+ ],
2889
+ valExpect2: 10.0000
2890
+ }),
2891
+ // test win_quantilex-aggregate-window handling-behavior
2892
+ test_win_quantilex_aggregate({
2893
+ aa: 8,
2894
+ bb: 0,
2895
+ quantile: 0,
2896
+ valExpect: [
2897
+ 0.0000, 0.0000, 0.0000, 0.0000,
2898
+ 0.0000, 0.0000, 0.0000, 0.0000,
2899
+ 0.0000, 0.0000, 0.0000, 0.0000
2900
+ ],
2901
+ valExpect2: -1
2902
+ }),
2903
+ test_win_quantilex_aggregate({
2904
+ aa: 8,
2905
+ bb: 0,
2906
+ quantile: 0.25,
2907
+ valExpect: [
2908
+ 0.0000, 0.2500, 0.5000, 0.7500,
2909
+ 1.0000, 0.2500, 0.5000, 0.7500,
2910
+ 1.7500, 2.7500, 3.7500, 5.5000
2911
+ ],
2912
+ valExpect2: 3
2913
+ }),
2914
+ test_win_quantilex_aggregate({
2915
+ aa: 8,
2916
+ bb: 0,
2917
+ quantile: 0.33333333,
2918
+ valExpect: [
2919
+ 0.0000, 0.3333, 0.6667, 1.0000,
2920
+ 1.3333, 0.6667, 1.0000, 1.3333,
2921
+ 2.3333, 3.3333, 4.6667, 6.0000
2922
+ ],
2923
+ valExpect2: 4.6667
2924
+ }),
2925
+ test_win_quantilex_aggregate({
2926
+ aa: 8,
2927
+ bb: 0,
2928
+ quantile: 0.5000,
2929
+ valExpect: [
2930
+ 0.0000, 0.5000, 1.0000, 1.5000,
2931
+ 2.0000, 1.5000, 2.0000, 2.5000,
2932
+ 3.5000, 5.0000, 6.0000, 7.0000
2933
+ ],
2934
+ valExpect2: 6.0000
2935
+ }),
2936
+ test_win_quantilex_aggregate({
2937
+ aa: 8,
2938
+ bb: 0,
2939
+ quantile: 0.66666667,
2940
+ valExpect: [
2941
+ 0.0000, 0.6667, 1.3333, 2.0000,
2942
+ 2.6667, 2.3333, 3.0000, 3.6667,
2943
+ 5.3333, 6.0000, 7.3333, 8.6667
2944
+ ],
2945
+ valExpect2: 7.3333
2946
+ }),
2947
+ test_win_quantilex_aggregate({
2948
+ aa: 8,
2949
+ bb: 0,
2950
+ quantile: 0.75,
2951
+ valExpect: [
2952
+ 0.0000, 0.7500, 1.5000, 2.2500,
2953
+ 3.0000, 2.7500, 3.5000, 4.5000,
2954
+ 6.0000, 6.5000, 8.2500, 9.2500
2955
+ ],
2956
+ valExpect2: 8.2500
2957
+ }),
2958
+ test_win_quantilex_aggregate({
2959
+ aa: 8,
2960
+ bb: 0,
2961
+ quantile: 1.0000,
2962
+ valExpect: [
2963
+ 0.0000, 1.0000, 2.0000, 3.0000,
2964
+ 4.0000, 4.0000, 6.0000, 6.0000,
2965
+ 8.0000, 9.0000, 10.0000, 11.0000
2966
+ ],
2967
+ valExpect2: 10.0000
2968
+ })
2969
+ ]);
2970
+ });
2971
+ jstestIt((
2972
+ "test sqlite-extension-win_sinefit2 handling-behavior"
2973
+ ), async function test_sqlite_extension_win_sinefit2() {
2974
+ let db = await dbOpenAsync({});
2975
+ let id3 = 9;
2976
+ let id4 = 10;
2977
+ let valExpect0;
2978
+ let valIn;
2979
+ function sqlSinefitExtractLnr(wsf, ii, suffix) {
2980
+ return (`
2981
+ ROUND(SINEFIT_EXTRACT(${wsf}, ${ii}, 'gyy', 0), 8) AS gyy${suffix},
2982
+ ROUND(SINEFIT_EXTRACT(${wsf}, ${ii}, 'laa', 0), 8) AS laa${suffix},
2983
+ ROUND(SINEFIT_EXTRACT(${wsf}, ${ii}, 'lbb', 0), 8) AS lbb${suffix},
2984
+ ROUND(SINEFIT_EXTRACT(${wsf}, ${ii}, 'lee', 0), 8) AS lee${suffix},
2985
+ ROUND(SINEFIT_EXTRACT(${wsf}, ${ii}, 'lxy', 0), 8) AS lxy${suffix},
2986
+ ROUND(SINEFIT_EXTRACT(${wsf}, ${ii}, 'lyy', 0), 8) AS lyy${suffix},
2987
+ ROUND(SINEFIT_EXTRACT(${wsf}, ${ii}, 'mee', 0), 8) AS mee${suffix},
2988
+ ROUND(SINEFIT_EXTRACT(${wsf}, ${ii}, 'mrr', 0), 8) AS mrr${suffix},
2989
+ ROUND(SINEFIT_EXTRACT(${wsf}, ${ii}, 'mxe', 0), 8) AS mxe${suffix},
2990
+ ROUND(SINEFIT_EXTRACT(${wsf}, ${ii}, 'mxx', 0), 8) AS mxx${suffix},
2991
+ ROUND(SINEFIT_EXTRACT(${wsf}, ${ii}, 'myy', 0), 8) AS myy${suffix},
2992
+ ROUND(SINEFIT_EXTRACT(${wsf}, ${ii}, 'nnn', 0), 8) AS nnn${suffix},
2993
+ ROUND(SINEFIT_EXTRACT(${wsf}, ${ii}, 'rra', 0), 8) AS rra${suffix},
2994
+ ROUND(SINEFIT_EXTRACT(${wsf}, ${ii}, 'rrb', 0), 8) AS rrb${suffix},
2995
+ ROUND(SINEFIT_EXTRACT(${wsf}, ${ii}, 'xxa', 0), 8) AS xxa${suffix},
2996
+ ROUND(SINEFIT_EXTRACT(${wsf}, ${ii}, 'xxb', 0), 8) AS xxb${suffix},
2997
+ ROUND(SINEFIT_EXTRACT(${wsf}, ${ii}, 'yya', 0), 8) AS yya${suffix},
2998
+ ROUND(SINEFIT_EXTRACT(${wsf}, ${ii}, 'yyb', 0), 8) AS yyb${suffix}
2999
+ `);
3000
+ }
3001
+ async function test_win_sinefit2_aggregate({
3002
+ aa,
3003
+ bb,
3004
+ valExpect,
3005
+ valExpect2,
3006
+ valExpect3
3007
+ }) {
3008
+ let sqlBetween = "";
3009
+ let valActual;
3010
+ let xxr = 2;
3011
+ if (aa !== undefined) {
3012
+ sqlBetween = (
3013
+ `ROWS BETWEEN ${aa - 1} PRECEDING AND ${bb} FOLLOWING`
3014
+ );
3015
+ }
3016
+ // test win_sinefit2-aggregate handling-behavior
3017
+ valActual = await dbExecAndReturnLastTable({
3018
+ bindList: {
3019
+ valIn
3020
+ },
3021
+ db,
3022
+ sql: (`
3023
+ DROP TABLE IF EXISTS __sinefit_win;
3024
+ CREATE TEMP TABLE __sinefit_win AS
3025
+ SELECT
3026
+ id2,
3027
+ __wsf,
3028
+ SINEFIT_EXTRACT(__wsf, 0, 'xxb', 0) AS xxb1,
3029
+ SINEFIT_EXTRACT(__wsf, 0, 'yyb', 0) AS yyb1,
3030
+ SINEFIT_EXTRACT(__wsf, 8, 'xxb', 0) AS xxb2,
3031
+ SINEFIT_EXTRACT(__wsf, 8, 'yyb', 0) AS yyb2,
3032
+ SINEFIT_EXTRACT(__wsf, 9, 'xxb', 0) AS xxb3,
3033
+ SINEFIT_EXTRACT(__wsf, 9, 'yyb', 0) AS yyb3
3034
+ FROM (
3035
+ SELECT
3036
+ id2,
3037
+ WIN_SINEFIT2(
3038
+ 1, ${xxr},
3039
+ value->>0, value->>1,
3040
+ value->>0, value->>1,
3041
+ value->>0, value->>1,
3042
+ value->>0, value->>1,
3043
+ value->>0, value->>1,
3044
+ value->>0, value->>1,
3045
+ value->>0, value->>1,
3046
+ value->>0, value->>1,
3047
+ value->>0, value->>1,
3048
+ value->>0, IIF(id2 = ${id3}, -1, value->>1)
3049
+ ) OVER (
3050
+ ORDER BY NULL ASC
3051
+ ${sqlBetween}
3052
+ ) AS __wsf
3053
+ FROM (
3054
+ SELECT
3055
+ *,
3056
+ ROW_NUMBER() OVER(ORDER BY id ASC) AS id2
3057
+ FROM JSON_EAcH($valIn)
3058
+ )
3059
+ );
3060
+ UPDATE __sinefit_win
3061
+ SET
3062
+ __wsf = SINEFIT_REFITLAST(
3063
+ __wsf,
3064
+ 0, 0,
3065
+ 0, 0,
3066
+ 0, 0,
3067
+ 0, 0,
3068
+ 0, 0,
3069
+ 0, 0,
3070
+ 0, 0,
3071
+ 0, 0,
3072
+ 0, 0,
3073
+ 0, 0
3074
+ )
3075
+ WHERE id2 = ${id4};
3076
+ UPDATE __sinefit_win
3077
+ SET
3078
+ __wsf = SINEFIT_REFITLAST(
3079
+ __wsf,
3080
+ xxb1, yyb1,
3081
+ xxb1, yyb1,
3082
+ xxb1, yyb1,
3083
+ xxb1, yyb1,
3084
+ xxb1, yyb1,
3085
+ xxb1, yyb1,
3086
+ xxb1, yyb1,
3087
+ xxb1, yyb1,
3088
+ xxb2, yyb2,
3089
+ xxb3, yyb3
3090
+ )
3091
+ WHERE id2 = ${id4};
3092
+ SELECT
3093
+ id2,
3094
+ ${sqlSinefitExtractLnr("__wsf", 0, "1")},
3095
+ ${sqlSinefitExtractLnr("__wsf", 8, "2")},
3096
+ ${sqlSinefitExtractLnr("__wsf", 9, "3")}
3097
+ FROM __sinefit_win;
3098
+ `)
3099
+ });
3100
+ valActual = valActual.map(function ({
3101
+ id2,
3102
+ laa1,
3103
+ laa2,
3104
+ laa3,
3105
+ lbb1,
3106
+ lbb2,
3107
+ lbb3,
3108
+ lee1,
3109
+ lee2,
3110
+ lee3,
3111
+ lxy1,
3112
+ lxy2,
3113
+ lxy3,
3114
+ lyy1,
3115
+ lyy2,
3116
+ lyy3,
3117
+ mee1,
3118
+ mee2,
3119
+ mee3,
3120
+ mrr1,
3121
+ mrr2,
3122
+ mrr3,
3123
+ mxe1,
3124
+ mxe2,
3125
+ mxe3,
3126
+ mxx1,
3127
+ mxx2,
3128
+ mxx3,
3129
+ myy1,
3130
+ myy2,
3131
+ myy3,
3132
+ nnn1,
3133
+ nnn2,
3134
+ nnn3,
3135
+ rra1,
3136
+ rra2,
3137
+ rra3,
3138
+ rrb1,
3139
+ rrb2,
3140
+ rrb3,
3141
+ xxa1,
3142
+ xxa2,
3143
+ xxa3,
3144
+ xxb1,
3145
+ xxb2,
3146
+ xxb3,
3147
+ yya1,
3148
+ yya2,
3149
+ yya3,
3150
+ yyb1,
3151
+ yyb2,
3152
+ yyb3
3153
+ }, ii, list) {
3154
+ let obj1;
3155
+ let obj2;
3156
+ let obj3;
3157
+ obj1 = {
3158
+ id2,
3159
+ "laa": laa1,
3160
+ "lbb": lbb1,
3161
+ "lee": lee1,
3162
+ "lxy": lxy1,
3163
+ "lyy": lyy1,
3164
+ "mee": mee1,
3165
+ "mrr": mrr1,
3166
+ "mxe": mxe1,
3167
+ "mxx": mxx1,
3168
+ "myy": myy1,
3169
+ "nnn": nnn1,
3170
+ "rra": rra1,
3171
+ "rrb": rrb1,
3172
+ "xxa": xxa1,
3173
+ "xxb": xxb1,
3174
+ "yya": yya1,
3175
+ "yyb": yyb1
3176
+ };
3177
+ obj2 = {
3178
+ id2,
3179
+ "laa": laa2,
3180
+ "lbb": lbb2,
3181
+ "lee": lee2,
3182
+ "lxy": lxy2,
3183
+ "lyy": lyy2,
3184
+ "mee": mee2,
3185
+ "mrr": mrr2,
3186
+ "mxe": mxe2,
3187
+ "mxx": mxx2,
3188
+ "myy": myy2,
3189
+ "nnn": nnn2,
3190
+ "rra": rra2,
3191
+ "rrb": rrb2,
3192
+ "xxa": xxa2,
3193
+ "xxb": xxb2,
3194
+ "yya": yya2,
3195
+ "yyb": yyb2
3196
+ };
3197
+ obj3 = {
3198
+ id2,
3199
+ "laa": laa3,
3200
+ "lbb": lbb3,
3201
+ "lee": lee3,
3202
+ "lxy": lxy3,
3203
+ "lyy": lyy3,
3204
+ "mee": mee3,
3205
+ "mrr": mrr3,
3206
+ "mxe": mxe3,
3207
+ "mxx": mxx3,
3208
+ "myy": myy3,
3209
+ "nnn": nnn3,
3210
+ "rra": rra3,
3211
+ "rrb": rrb3,
3212
+ "xxa": xxa3,
3213
+ "xxb": xxb3,
3214
+ "yya": yya3,
3215
+ "yyb": yyb3
3216
+ };
3217
+ switch (list.length - ii) {
3218
+ case 1:
3219
+ assertJsonEqual(obj2, obj1, valActual);
3220
+ assertJsonEqual(obj3, valExpect3, valActual);
3221
+ break;
3222
+ case 2:
3223
+ assertJsonEqual(obj2, obj1, valActual);
3224
+ assertJsonEqual(obj3, valExpect2, valActual);
3225
+ break;
3226
+ default:
3227
+ assertJsonEqual(obj2, obj1, valActual);
3228
+ assertJsonEqual(obj3, obj1, valActual);
3229
+ }
3230
+ return obj1;
3231
+ });
3232
+ assertJsonEqual(valActual, valExpect);
3233
+ }
3234
+ valExpect0 = [
3235
+ {
3236
+ "id2": 1,
3237
+ "laa": null,
3238
+ "lbb": null,
3239
+ "lee": null,
3240
+ "lxy": null,
3241
+ "lyy": 0,
3242
+ "mee": null,
3243
+ "mrr": 0,
3244
+ "mxe": null,
3245
+ "mxx": 2,
3246
+ "myy": 0,
3247
+ "nnn": 1,
3248
+ "rra": 0,
3249
+ "rrb": 0,
3250
+ "xxa": 0,
3251
+ "xxb": 2,
3252
+ "yya": 0,
3253
+ "yyb": 0
3254
+ },
3255
+ {
3256
+ "id2": 2,
3257
+ "laa": null,
3258
+ "lbb": null,
3259
+ "lee": null,
3260
+ "lxy": null,
3261
+ "lyy": 1,
3262
+ "mee": 0.70710678,
3263
+ "mrr": 0,
3264
+ "mxe": 0,
3265
+ "mxx": 2,
3266
+ "myy": 0.5,
3267
+ "nnn": 2,
3268
+ "rra": 0,
3269
+ "rrb": 0,
3270
+ "xxa": 2,
3271
+ "xxb": 2,
3272
+ "yya": 0,
3273
+ "yyb": 1
3274
+ },
3275
+ {
3276
+ "id2": 3,
3277
+ "laa": -4.5,
3278
+ "lbb": 2.5,
3279
+ "lee": 0.40824829,
3280
+ "lxy": 0.94491118,
3281
+ "lyy": 3,
3282
+ "mee": 1.52752523,
3283
+ "mrr": 0,
3284
+ "mxe": 0.57735027,
3285
+ "mxx": 2.33333333,
3286
+ "myy": 1.33333333,
3287
+ "nnn": 3,
3288
+ "rra": 0,
3289
+ "rrb": 0,
3290
+ "xxa": 2,
3291
+ "xxb": 3,
3292
+ "yya": 0,
3293
+ "yyb": 3
3294
+ },
3295
+ {
3296
+ "id2": 4,
3297
+ "laa": -3,
3298
+ "lbb": 1.81818182,
3299
+ "lee": 0.47673129,
3300
+ "lxy": 0.95346259,
3301
+ "lyy": 4.27272727,
3302
+ "mee": 1.82574186,
3303
+ "mrr": -0.06818182,
3304
+ "mxe": 0.95742711,
3305
+ "mxx": 2.75,
3306
+ "myy": 2,
3307
+ "nnn": 4,
3308
+ "rra": 0,
3309
+ "rrb": -0.27272727,
3310
+ "xxa": 2,
3311
+ "xxb": 4,
3312
+ "yya": 0,
3313
+ "yyb": 4
3314
+ },
3315
+ {
3316
+ "id2": 5,
3317
+ "laa": -2.29411765,
3318
+ "lbb": 1.52941176,
3319
+ "lee": 0.50874702,
3320
+ "lxy": 0.96164474,
3321
+ "lyy": 5.35294118,
3322
+ "mee": 2.07364414,
3323
+ "mrr": -0.12513369,
3324
+ "mxe": 1.30384048,
3325
+ "mxx": 3.2,
3326
+ "myy": 2.6,
3327
+ "nnn": 5,
3328
+ "rra": 0,
3329
+ "rrb": -0.35294118,
3330
+ "xxa": 2,
3331
+ "xxb": 5,
3332
+ "yya": 0,
3333
+ "yyb": 5
3334
+ },
3335
+ {
3336
+ "id2": 6,
3337
+ "laa": -2.54385965,
3338
+ "lbb": 1.63157895,
3339
+ "lee": 0.50725727,
3340
+ "lxy": 0.97080629,
3341
+ "lyy": 5.61403509,
3342
+ "mee": 2.31660671,
3343
+ "mrr": -0.03995059,
3344
+ "mxe": 1.37840488,
3345
+ "mxx": 3.5,
3346
+ "myy": 3.16666667,
3347
+ "nnn": 6,
3348
+ "rra": 0,
3349
+ "rrb": 0.38596491,
3350
+ "xxa": 2,
3351
+ "xxb": 5,
3352
+ "yya": 0,
3353
+ "yyb": 6
3354
+ },
3355
+ {
3356
+ "id2": 7,
3357
+ "laa": -2.65,
3358
+ "lbb": 1.675,
3359
+ "lee": 0.48550416,
3360
+ "lxy": 0.9752227,
3361
+ "lyy": 5.725,
3362
+ "mee": 2.37045304,
3363
+ "mrr": 0.00504235,
3364
+ "mxe": 1.38013112,
3365
+ "mxx": 3.71428571,
3366
+ "myy": 3.57142857,
3367
+ "nnn": 7,
3368
+ "rra": 0,
3369
+ "rrb": 0.275,
3370
+ "xxa": 2,
3371
+ "xxb": 5,
3372
+ "yya": 0,
3373
+ "yyb": 6
3374
+ },
3375
+ {
3376
+ "id2": 8,
3377
+ "laa": -2.5,
3378
+ "lbb": 1.625,
3379
+ "lee": 0.46770717,
3380
+ "lxy": 0.97991187,
3381
+ "lyy": 7.25,
3382
+ "mee": 2.50713268,
3383
+ "mrr": -0.02683794,
3384
+ "mxe": 1.51185789,
3385
+ "mxx": 4,
3386
+ "myy": 4,
3387
+ "nnn": 8,
3388
+ "rra": 0,
3389
+ "rrb": -0.25,
3390
+ "xxa": 2,
3391
+ "xxb": 6,
3392
+ "yya": 0,
3393
+ "yyb": 7
3394
+ },
3395
+ {
3396
+ "id2": 9,
3397
+ "laa": 0.75,
3398
+ "lbb": 0.85,
3399
+ "lee": 0.94207218,
3400
+ "lxy": 0.89597867,
3401
+ "lyy": 9.25,
3402
+ "mee": 2.26778684,
3403
+ "mrr": -0.18308794,
3404
+ "mxe": 2.39045722,
3405
+ "mxx": 5,
3406
+ "myy": 5,
3407
+ "nnn": 8,
3408
+ "rra": 0,
3409
+ "rrb": -1.25,
3410
+ "xxa": 2,
3411
+ "xxb": 10,
3412
+ "yya": 0,
3413
+ "yyb": 8
3414
+ },
3415
+ {
3416
+ "id2": 10,
3417
+ "laa": 2.75,
3418
+ "lbb": 0.55,
3419
+ "lee": 0.8587782,
3420
+ "lxy": 0.81989159,
3421
+ "lyy": 3.85,
3422
+ "mee": 1.60356745,
3423
+ "mrr": -0.03933794,
3424
+ "mxe": 2.39045722,
3425
+ "mxx": 5,
3426
+ "myy": 5.5,
3427
+ "nnn": 8,
3428
+ "rra": -0.87387387,
3429
+ "rrb": 1.15,
3430
+ "xxa": 0,
3431
+ "xxb": 2,
3432
+ "yya": 0,
3433
+ "yyb": 5
3434
+ }
3435
+ ];
3436
+ valIn = [
3437
+ [2, "abcd"],
3438
+ [NaN, 1],
3439
+ [3, 3],
3440
+ [4, 4],
3441
+ [5, 5],
3442
+ [5, 6],
3443
+ [5, undefined],
3444
+ [6, 7],
3445
+ //
3446
+ [10, 8],
3447
+ [2, 5]
3448
+ ];
3449
+ await Promise.all([
3450
+ (async function () {
3451
+ let valActual;
3452
+ // test win_sinefit2-error handling-behavior
3453
+ await assertErrorThrownAsync(function () {
3454
+ return dbExecAsync({
3455
+ db,
3456
+ sql: (`
3457
+ SELECT WIN_SINEFIT2(1, 2, 3) FROM (SELECT 1);
3458
+ `)
3459
+ });
3460
+ }, "wrong number of arguments");
3461
+ // test win_sinefit2-null-case handling-behavior
3462
+ valActual = await dbExecAndReturnLastTable({
3463
+ db,
3464
+ sql: (`
3465
+ DROP TABLE IF EXISTS __tmp1;
3466
+ CREATE TEMP TABLE __tmp1 (val REAL);
3467
+ SELECT DOUBLEARRAY_JSONTO(WIN_SINEFIT2(1, 2, 3, 4)) FROM __tmp1;
3468
+ `)
3469
+ });
3470
+ valActual = valActual.map(function ({val}) {
3471
+ return val;
3472
+ });
3473
+ assertJsonEqual(valActual, [null]);
3474
+ }()),
3475
+ // test win_sinefit2-aggregate-normal handling-behavior
3476
+ (async function () {
3477
+ let valActual;
3478
+ valActual = await dbExecAndReturnLastRow({
3479
+ bindList: {
3480
+ valIn
3481
+ },
3482
+ db,
3483
+ sql: (`
3484
+ SELECT
3485
+ ${sqlSinefitExtractLnr("__wsf", 0, "")}
3486
+ FROM (
3487
+ SELECT
3488
+ WIN_SINEFIT2(1, NULL, value->>0, value->>1) AS __wsf
3489
+ FROM (
3490
+ SELECT
3491
+ *,
3492
+ ROW_NUMBER() OVER(ORDER BY id ASC) AS id2
3493
+ FROM JSON_EAcH($valIn)
3494
+ )
3495
+ );
3496
+ `)
3497
+ });
3498
+ assertJsonEqual(
3499
+ valActual,
3500
+ {
3501
+ "gyy": 0.19611614,
3502
+ "laa": 0.77941176,
3503
+ "lbb": 0.84558824,
3504
+ "lee": 1.40010504,
3505
+ "lxy": 0.81541829,
3506
+ "lyy": 2.47058824,
3507
+ "mee": 2.54950976,
3508
+ "mrr": 0.06110045,
3509
+ "mxe": 2.45854519,
3510
+ "mxx": 4.4,
3511
+ "myy": 4.5,
3512
+ "nnn": 10,
3513
+ "rra": 0,
3514
+ "rrb": 2.52941176,
3515
+ "xxa": 2,
3516
+ "xxb": 2,
3517
+ "yya": 0,
3518
+ "yyb": 5
3519
+ }
3520
+ );
3521
+ }()),
3522
+ // test win_sinefit2-aggregate-window handling-behavior
3523
+ (async function () {
3524
+ let valActual;
3525
+ let valExpect;
3526
+ valExpect = {
3527
+ "gyy": -1.02062073,
3528
+ "laa": -0.82025678,
3529
+ "lbb": 0.14621969,
3530
+ "lee": 2.23885734,
3531
+ "lxy": 0.865665,
3532
+ "lyy": 6.63694722,
3533
+ "mee": 4.89897949,
3534
+ "mrr": -0.79455058,
3535
+ "mxe": 29.00344807,
3536
+ "mxx": 74,
3537
+ "myy": 10,
3538
+ "nnn": 6,
3539
+ "rra": 0,
3540
+ "rrb": -1.63694722,
3541
+ "xxa": 34,
3542
+ "xxb": 51,
3543
+ "yya": 5,
3544
+ "yyb": 5
3545
+ };
3546
+ valActual = await dbExecAndReturnLastRow({
3547
+ db,
3548
+ sql: (`
3549
+ SELECT
3550
+ ${sqlSinefitExtractLnr("__wsf", 0, "")}
3551
+ FROM (
3552
+ SELECT
3553
+ WIN_SINEFIT2(1, NULL, xx, yy) AS __wsf
3554
+ FROM (
3555
+ SELECT 34 AS xx, 5 AS yy
3556
+ UNION ALL SELECT 108, 17
3557
+ UNION ALL SELECT 64, 11
3558
+ UNION ALL SELECT 88, 8
3559
+ UNION ALL SELECT 99, 14
3560
+ UNION ALL SELECT 51, 5
3561
+ )
3562
+ )
3563
+ `)
3564
+ });
3565
+ assertJsonEqual(valActual, valExpect);
3566
+ }()),
3567
+ // test win_sinefit2-aggregate-window handling-behavior
3568
+ test_win_sinefit2_aggregate({
3569
+ aa: 8,
3570
+ bb: 0,
3571
+ valExpect: valExpect0,
3572
+ valExpect2: {
3573
+ "id2": id3,
3574
+ "laa": 5.25,
3575
+ "lbb": -0.275,
3576
+ "lee": 2.49624718,
3577
+ "lxy": -0.23918696,
3578
+ "lyy": 2.5,
3579
+ "mee": 2.74837614,
3580
+ "mrr": -0.46433794,
3581
+ "mxe": 2.39045722,
3582
+ "mxx": 5,
3583
+ "myy": 3.875,
3584
+ "nnn": 8,
3585
+ "rra": 0,
3586
+ "rrb": -3.5,
3587
+ "xxa": 2,
3588
+ "xxb": 10,
3589
+ "yya": 0,
3590
+ "yyb": -1
3591
+ },
3592
+ valExpect3: {
3593
+ "id2": id4,
3594
+ "laa": 7.25,
3595
+ "lbb": -0.575,
3596
+ "lee": 1.95735791,
3597
+ "lxy": -0.5490214,
3598
+ "lyy": 6.1,
3599
+ "mee": 2.50356888,
3600
+ "mrr": -0.60183794,
3601
+ "mxe": 2.39045722,
3602
+ "mxx": 5,
3603
+ "myy": 4.375,
3604
+ "nnn": 8,
3605
+ "rra": -3.79279279,
3606
+ "rrb": -1.1,
3607
+ "xxa": 0,
3608
+ "xxb": 2,
3609
+ "yya": 0,
3610
+ "yyb": 5
3611
+ }
3612
+ }),
3613
+ // test win_sinefit2-spx handling-behavior
3614
+ (async function () {
3615
+ let testDataSpx;
3616
+ let ttSinefit = 128;
3617
+ let valActual;
3618
+ let valExpect;
3619
+ testDataSpx = (`
3620
+ ##
3621
+ date close
3622
+ 2018-12-31 2506.85 2019-01-02 2510.03 2019-01-03 2447.89 2019-01-04 2531.94
3623
+ 2019-01-07 2549.69 2019-01-08 2574.41 2019-01-09 2584.96 2019-01-10 2596.64
3624
+ 2019-01-11 2596.26 2019-01-14 2582.61 2019-01-15 2610.30 2019-01-16 2616.10
3625
+ 2019-01-17 2635.96 2019-01-18 2670.71 2019-01-22 2632.90 2019-01-23 2638.70
3626
+ 2019-01-24 2642.33 2019-01-25 2664.76 2019-01-28 2643.85 2019-01-29 2640.00
3627
+ 2019-01-30 2681.05 2019-01-31 2704.10 2019-02-01 2706.53 2019-02-04 2724.87
3628
+ 2019-02-05 2737.70 2019-02-06 2731.61 2019-02-07 2706.05 2019-02-08 2707.88
3629
+ 2019-02-11 2709.80 2019-02-12 2744.73 2019-02-13 2753.03 2019-02-14 2745.73
3630
+ 2019-02-15 2775.60 2019-02-19 2779.76 2019-02-20 2784.70 2019-02-21 2774.88
3631
+ 2019-02-22 2792.67 2019-02-25 2796.11 2019-02-26 2793.90 2019-02-27 2792.38
3632
+ 2019-02-28 2784.49 2019-03-01 2803.69 2019-03-04 2792.81 2019-03-05 2789.65
3633
+ 2019-03-06 2771.45 2019-03-07 2748.93 2019-03-08 2743.07 2019-03-11 2783.30
3634
+ 2019-03-12 2791.52 2019-03-13 2810.92 2019-03-14 2808.48 2019-03-15 2822.48
3635
+ 2019-03-18 2832.94 2019-03-19 2832.57 2019-03-20 2824.23 2019-03-21 2854.88
3636
+ 2019-03-22 2800.71 2019-03-25 2798.36 2019-03-26 2818.46 2019-03-27 2805.37
3637
+ 2019-03-28 2815.44 2019-03-29 2834.40 2019-04-01 2867.19 2019-04-02 2867.24
3638
+ 2019-04-03 2873.40 2019-04-04 2879.39 2019-04-05 2892.74 2019-04-08 2895.77
3639
+ 2019-04-09 2878.20 2019-04-10 2888.21 2019-04-11 2888.32 2019-04-12 2907.41
3640
+ 2019-04-15 2905.58 2019-04-16 2907.06 2019-04-17 2900.45 2019-04-18 2905.03
3641
+ 2019-04-22 2907.97 2019-04-23 2933.68 2019-04-24 2927.25 2019-04-25 2926.17
3642
+ 2019-04-26 2939.88 2019-04-29 2943.03 2019-04-30 2945.83 2019-05-01 2923.73
3643
+ 2019-05-02 2917.52 2019-05-03 2945.64 2019-05-06 2932.47 2019-05-07 2884.05
3644
+ 2019-05-08 2879.42 2019-05-09 2870.72 2019-05-10 2881.40 2019-05-13 2811.87
3645
+ 2019-05-14 2834.41 2019-05-15 2850.96 2019-05-16 2876.32 2019-05-17 2859.53
3646
+ 2019-05-20 2840.23 2019-05-21 2864.36 2019-05-22 2856.27 2019-05-23 2822.24
3647
+ 2019-05-24 2826.06 2019-05-28 2802.39 2019-05-29 2783.02 2019-05-30 2788.86
3648
+ 2019-05-31 2752.06 2019-06-03 2744.45 2019-06-04 2803.27 2019-06-05 2826.15
3649
+ 2019-06-06 2843.49 2019-06-07 2873.34 2019-06-10 2886.73 2019-06-11 2885.72
3650
+ 2019-06-12 2879.84 2019-06-13 2891.64 2019-06-14 2886.98 2019-06-17 2889.67
3651
+ 2019-06-18 2917.75 2019-06-19 2926.46 2019-06-20 2954.18 2019-06-21 2950.46
3652
+ 2019-06-24 2945.35 2019-06-25 2917.38 2019-06-26 2913.78 2019-06-27 2924.92
3653
+ 2019-06-28 2941.76 2019-07-01 2964.33 2019-07-02 2973.01 2019-07-03 2995.82
3654
+ 2019-07-05 2990.41 2019-07-08 2975.95 2019-07-09 2979.63 2019-07-10 2993.07
3655
+ 2019-07-11 2999.91 2019-07-12 3013.77 2019-07-15 3014.30 2019-07-16 3004.04
3656
+ 2019-07-17 2984.42 2019-07-18 2995.11 2019-07-19 2976.61 2019-07-22 2985.03
3657
+ 2019-07-23 3005.47 2019-07-24 3019.56 2019-07-25 3003.67 2019-07-26 3025.86
3658
+ 2019-07-29 3020.97 2019-07-30 3013.18 2019-07-31 2980.38 2019-08-01 2953.56
3659
+ 2019-08-02 2932.05 2019-08-05 2844.74 2019-08-06 2881.77 2019-08-07 2883.98
3660
+ 2019-08-08 2938.09 2019-08-09 2918.65 2019-08-12 2882.70 2019-08-13 2926.32
3661
+ 2019-08-14 2840.60 2019-08-15 2847.60 2019-08-16 2888.68 2019-08-19 2923.65
3662
+ 2019-08-20 2900.51 2019-08-21 2924.43 2019-08-22 2922.95 2019-08-23 2847.11
3663
+ 2019-08-26 2878.38 2019-08-27 2869.16 2019-08-28 2887.94 2019-08-29 2924.58
3664
+ 2019-08-30 2926.46 2019-09-03 2906.27 2019-09-04 2937.78 2019-09-05 2976.00
3665
+ 2019-09-06 2978.71 2019-09-09 2978.43 2019-09-10 2979.39 2019-09-11 3000.93
3666
+ 2019-09-12 3009.57 2019-09-13 3007.39 2019-09-16 2997.96 2019-09-17 3005.70
3667
+ 2019-09-18 3006.73 2019-09-19 3006.79 2019-09-20 2992.07 2019-09-23 2991.78
3668
+ 2019-09-24 2966.60 2019-09-25 2984.87 2019-09-26 2977.62 2019-09-27 2961.79
3669
+ 2019-09-30 2976.74 2019-10-01 2940.25 2019-10-02 2887.61 2019-10-03 2910.63
3670
+ 2019-10-04 2952.01 2019-10-07 2938.79 2019-10-08 2893.06 2019-10-09 2919.40
3671
+ 2019-10-10 2938.13 2019-10-11 2970.27 2019-10-14 2966.15 2019-10-15 2995.68
3672
+ 2019-10-16 2989.69 2019-10-17 2997.95 2019-10-18 2986.20 2019-10-21 3006.72
3673
+ 2019-10-22 2995.99 2019-10-23 3004.52 2019-10-24 3010.29 2019-10-25 3022.55
3674
+ 2019-10-28 3039.42 2019-10-29 3036.89 2019-10-30 3046.77 2019-10-31 3037.56
3675
+ 2019-11-01 3066.91 2019-11-04 3078.27 2019-11-05 3074.62 2019-11-06 3076.78
3676
+ 2019-11-07 3085.18 2019-11-08 3093.08 2019-11-11 3087.01 2019-11-12 3091.84
3677
+ 2019-11-13 3094.04 2019-11-14 3096.63 2019-11-15 3120.46 2019-11-18 3122.03
3678
+ 2019-11-19 3120.18 2019-11-20 3108.46 2019-11-21 3103.54 2019-11-22 3110.29
3679
+ 2019-11-25 3133.64 2019-11-26 3140.52 2019-11-27 3153.63 2019-11-29 3140.98
3680
+ 2019-12-02 3113.87 2019-12-03 3093.20 2019-12-04 3112.76 2019-12-05 3117.43
3681
+ 2019-12-06 3145.91 2019-12-09 3135.96 2019-12-10 3132.52 2019-12-11 3141.63
3682
+ 2019-12-12 3168.57 2019-12-13 3168.80 2019-12-16 3191.45 2019-12-17 3192.52
3683
+ 2019-12-18 3191.14 2019-12-19 3205.37 2019-12-20 3221.22 2019-12-23 3224.01
3684
+ 2019-12-24 3223.38 2019-12-26 3239.91 2019-12-27 3240.02 2019-12-30 3221.29
3685
+ 2019-12-31 3230.78 2020-01-02 3257.85 2020-01-03 3234.85 2020-01-06 3246.28
3686
+ 2020-01-07 3237.18 2020-01-08 3253.05 2020-01-09 3274.70 2020-01-10 3265.35
3687
+ 2020-01-13 3288.13 2020-01-14 3283.15 2020-01-15 3289.29 2020-01-16 3316.81
3688
+ 2020-01-17 3329.62 2020-01-21 3320.79 2020-01-22 3321.75 2020-01-23 3325.54
3689
+ 2020-01-24 3295.47 2020-01-27 3243.63 2020-01-28 3276.24 2020-01-29 3273.40
3690
+ 2020-01-30 3283.66 2020-01-31 3225.52 2020-02-03 3248.92 2020-02-04 3297.59
3691
+ 2020-02-05 3334.69 2020-02-06 3345.78 2020-02-07 3327.71 2020-02-10 3352.09
3692
+ 2020-02-11 3357.75 2020-02-12 3379.45 2020-02-13 3373.94 2020-02-14 3380.16
3693
+ 2020-02-18 3370.29 2020-02-19 3386.15 2020-02-20 3373.23 2020-02-21 3337.75
3694
+ 2020-02-24 3225.89 2020-02-25 3128.21 2020-02-26 3116.39 2020-02-27 2978.76
3695
+ 2020-02-28 2954.22 2020-03-02 3090.23 2020-03-03 3003.37 2020-03-04 3130.12
3696
+ 2020-03-05 3023.94 2020-03-06 2972.37 2020-03-09 2746.56 2020-03-10 2882.23
3697
+ 2020-03-11 2741.38 2020-03-12 2480.64 2020-03-13 2711.02 2020-03-16 2386.13
3698
+ 2020-03-17 2529.19 2020-03-18 2398.10 2020-03-19 2409.39 2020-03-20 2304.92
3699
+ 2020-03-23 2237.40 2020-03-24 2447.33 2020-03-25 2475.56 2020-03-26 2630.07
3700
+ 2020-03-27 2541.47 2020-03-30 2626.65 2020-03-31 2584.59 2020-04-01 2470.50
3701
+ 2020-04-02 2526.90 2020-04-03 2488.65 2020-04-06 2663.68 2020-04-07 2659.41
3702
+ 2020-04-08 2749.98 2020-04-09 2789.82 2020-04-13 2761.63 2020-04-14 2846.06
3703
+ 2020-04-15 2783.36 2020-04-16 2799.55 2020-04-17 2874.56 2020-04-20 2823.16
3704
+ 2020-04-21 2736.56 2020-04-22 2799.31 2020-04-23 2797.80 2020-04-24 2836.74
3705
+ 2020-04-27 2878.48 2020-04-28 2863.39 2020-04-29 2939.51 2020-04-30 2912.43
3706
+ 2020-05-01 2830.71 2020-05-04 2842.74 2020-05-05 2868.44 2020-05-06 2848.42
3707
+ 2020-05-07 2881.19 2020-05-08 2929.80 2020-05-11 2930.19 2020-05-12 2870.12
3708
+ 2020-05-13 2820.00 2020-05-14 2852.50 2020-05-15 2863.70 2020-05-18 2953.91
3709
+ 2020-05-19 2922.94 2020-05-20 2971.61 2020-05-21 2948.51 2020-05-22 2955.45
3710
+ 2020-05-26 2991.77 2020-05-27 3036.13 2020-05-28 3029.73 2020-05-29 3044.31
3711
+ 2020-06-01 3055.73 2020-06-02 3080.82 2020-06-03 3122.87 2020-06-04 3112.35
3712
+ 2020-06-05 3193.93 2020-06-08 3232.39 2020-06-09 3207.18 2020-06-10 3190.14
3713
+ 2020-06-11 3002.10 2020-06-12 3041.31 2020-06-15 3066.59 2020-06-16 3124.74
3714
+ 2020-06-17 3113.49 2020-06-18 3115.34 2020-06-19 3097.74 2020-06-22 3117.86
3715
+ 2020-06-23 3131.29 2020-06-24 3050.33 2020-06-25 3083.76 2020-06-26 3009.05
3716
+ 2020-06-29 3053.24 2020-06-30 3100.29 2020-07-01 3115.86 2020-07-02 3130.01
3717
+ 2020-07-06 3179.72 2020-07-07 3145.32 2020-07-08 3169.94 2020-07-09 3152.05
3718
+ 2020-07-10 3185.04 2020-07-13 3155.22 2020-07-14 3197.52 2020-07-15 3226.56
3719
+ 2020-07-16 3215.57 2020-07-17 3224.73 2020-07-20 3251.84 2020-07-21 3257.30
3720
+ 2020-07-22 3276.02 2020-07-23 3235.66 2020-07-24 3215.63 2020-07-27 3239.41
3721
+ 2020-07-28 3218.44 2020-07-29 3258.44 2020-07-30 3246.22 2020-07-31 3271.12
3722
+ 2020-08-03 3294.61 2020-08-04 3306.51 2020-08-05 3327.77 2020-08-06 3349.16
3723
+ 2020-08-07 3351.28 2020-08-10 3360.47 2020-08-11 3333.69 2020-08-12 3380.35
3724
+ 2020-08-13 3373.43 2020-08-14 3372.85 2020-08-17 3381.99 2020-08-18 3389.78
3725
+ 2020-08-19 3374.85 2020-08-20 3385.51 2020-08-21 3397.16 2020-08-24 3431.28
3726
+ 2020-08-25 3443.62 2020-08-26 3478.73 2020-08-27 3484.55 2020-08-28 3508.01
3727
+ 2020-08-31 3500.31 2020-09-01 3526.65 2020-09-02 3580.84 2020-09-03 3455.06
3728
+ 2020-09-04 3426.96 2020-09-08 3331.84 2020-09-09 3398.96 2020-09-10 3339.19
3729
+ 2020-09-11 3340.97 2020-09-14 3383.54 2020-09-15 3401.20 2020-09-16 3385.49
3730
+ 2020-09-17 3357.01 2020-09-18 3319.47 2020-09-21 3281.06 2020-09-22 3315.57
3731
+ 2020-09-23 3236.92 2020-09-24 3246.59 2020-09-25 3298.46 2020-09-28 3351.60
3732
+ 2020-09-29 3335.47 2020-09-30 3363.00 2020-10-01 3380.80 2020-10-02 3348.42
3733
+ 2020-10-05 3408.60 2020-10-06 3360.97 2020-10-07 3419.44 2020-10-08 3446.83
3734
+ 2020-10-09 3477.14 2020-10-12 3534.22 2020-10-13 3511.93 2020-10-14 3488.67
3735
+ 2020-10-15 3483.34 2020-10-16 3483.81 2020-10-19 3426.92 2020-10-20 3443.12
3736
+ 2020-10-21 3435.56 2020-10-22 3453.49 2020-10-23 3465.39 2020-10-26 3400.97
3737
+ 2020-10-27 3390.68 2020-10-28 3271.03 2020-10-29 3310.11 2020-10-30 3269.96
3738
+ 2020-11-02 3310.24 2020-11-03 3369.16 2020-11-04 3443.44 2020-11-05 3510.45
3739
+ 2020-11-06 3509.44 2020-11-09 3550.50 2020-11-10 3545.53 2020-11-11 3572.66
3740
+ 2020-11-12 3537.01 2020-11-13 3585.15 2020-11-16 3626.91 2020-11-17 3609.53
3741
+ 2020-11-18 3567.79 2020-11-19 3581.87 2020-11-20 3557.54 2020-11-23 3577.59
3742
+ 2020-11-24 3635.41 2020-11-25 3629.65 2020-11-27 3638.35 2020-11-30 3621.63
3743
+ 2020-12-01 3662.45 2020-12-02 3669.01 2020-12-03 3666.72 2020-12-04 3699.12
3744
+ 2020-12-07 3691.96 2020-12-08 3702.25 2020-12-09 3672.82 2020-12-10 3668.10
3745
+ 2020-12-11 3663.46 2020-12-14 3647.49 2020-12-15 3694.62 2020-12-16 3701.17
3746
+ 2020-12-17 3722.48 2020-12-18 3709.41 2020-12-21 3694.92 2020-12-22 3687.26
3747
+ 2020-12-23 3690.01 2020-12-24 3703.06 2020-12-28 3735.36 2020-12-29 3727.04
3748
+ 2020-12-30 3732.04 2020-12-31 3756.07 2021-01-04 3700.65 2021-01-05 3726.86
3749
+ 2021-01-06 3748.14 2021-01-07 3803.79 2021-01-08 3824.68 2021-01-11 3799.61
3750
+ 2021-01-12 3801.19 2021-01-13 3809.84 2021-01-14 3795.54 2021-01-15 3768.25
3751
+ 2021-01-19 3798.91 2021-01-20 3851.85 2021-01-21 3853.07 2021-01-22 3841.47
3752
+ 2021-01-25 3855.36 2021-01-26 3849.62 2021-01-27 3750.77 2021-01-28 3787.38
3753
+ 2021-01-29 3714.24 2021-02-01 3773.86 2021-02-02 3826.31 2021-02-03 3830.17
3754
+ 2021-02-04 3871.74 2021-02-05 3886.83 2021-02-08 3915.59 2021-02-09 3911.23
3755
+ 2021-02-10 3909.88 2021-02-11 3916.38 2021-02-12 3934.83 2021-02-16 3932.59
3756
+ 2021-02-17 3931.33 2021-02-18 3913.97 2021-02-19 3906.71 2021-02-22 3876.50
3757
+ 2021-02-23 3881.37 2021-02-24 3925.43 2021-02-25 3829.34 2021-02-26 3811.15
3758
+ 2021-03-01 3901.82 2021-03-02 3870.29 2021-03-03 3819.72 2021-03-04 3768.47
3759
+ 2021-03-05 3841.94 2021-03-08 3821.35 2021-03-09 3875.44 2021-03-10 3898.81
3760
+ 2021-03-11 3939.34 2021-03-12 3943.34 2021-03-15 3968.94 2021-03-16 3962.71
3761
+ 2021-03-17 3974.12 2021-03-18 3915.46 2021-03-19 3913.10 2021-03-22 3940.59
3762
+ 2021-03-23 3910.52 2021-03-24 3889.14 2021-03-25 3909.52 2021-03-26 3974.54
3763
+ 2021-03-29 3971.09 2021-03-30 3958.55 2021-03-31 3972.89 2021-04-01 4019.87
3764
+ 2021-04-05 4077.91 2021-04-06 4073.94 2021-04-07 4079.95 2021-04-08 4097.17
3765
+ 2021-04-09 4128.80 2021-04-12 4127.99 2021-04-13 4141.59 2021-04-14 4124.66
3766
+ 2021-04-15 4170.42 2021-04-16 4185.47 2021-04-19 4163.26 2021-04-20 4134.94
3767
+ 2021-04-21 4173.42 2021-04-22 4134.98 2021-04-23 4180.17 2021-04-26 4187.62
3768
+ 2021-04-27 4186.72 2021-04-28 4183.18 2021-04-29 4211.47 2021-04-30 4181.17
3769
+ 2021-05-03 4192.66 2021-05-04 4164.66 2021-05-05 4167.59 2021-05-06 4201.62
3770
+ 2021-05-07 4232.60 2021-05-10 4188.43 2021-05-11 4152.10 2021-05-12 4063.04
3771
+ 2021-05-13 4112.50 2021-05-14 4173.85 2021-05-17 4163.29 2021-05-18 4127.83
3772
+ 2021-05-19 4115.68 2021-05-20 4159.12 2021-05-21 4155.86 2021-05-24 4197.05
3773
+ 2021-05-25 4188.13 2021-05-26 4195.99 2021-05-27 4200.88 2021-05-28 4204.11
3774
+ 2021-06-01 4202.04 2021-06-02 4208.12 2021-06-03 4192.85 2021-06-04 4229.89
3775
+ 2021-06-07 4226.52 2021-06-08 4227.26 2021-06-09 4219.55 2021-06-10 4239.18
3776
+ 2021-06-11 4247.44 2021-06-14 4255.15 2021-06-15 4246.59 2021-06-16 4223.70
3777
+ 2021-06-17 4221.86 2021-06-18 4166.45 2021-06-21 4224.79 2021-06-22 4246.44
3778
+ 2021-06-23 4241.84 2021-06-24 4266.49 2021-06-25 4280.70 2021-06-28 4290.61
3779
+ 2021-06-29 4291.80 2021-06-30 4297.50 2021-07-01 4319.94 2021-07-02 4352.34
3780
+ 2021-07-06 4343.54 2021-07-07 4358.13 2021-07-08 4320.82 2021-07-09 4369.55
3781
+ 2021-07-12 4384.63 2021-07-13 4369.21 2021-07-14 4374.30 2021-07-15 4360.03
3782
+ 2021-07-16 4327.16 2021-07-19 4258.49 2021-07-20 4323.06 2021-07-21 4358.69
3783
+ 2021-07-22 4367.48 2021-07-23 4411.79 2021-07-26 4422.30 2021-07-27 4401.46
3784
+ 2021-07-28 4400.64 2021-07-29 4419.15 2021-07-30 4395.26 2021-08-02 4387.16
3785
+ 2021-08-03 4423.15 2021-08-04 4402.66 2021-08-05 4429.10 2021-08-06 4436.52
3786
+ 2021-08-09 4432.35 2021-08-10 4436.75 2021-08-11 4442.41 2021-08-12 4460.83
3787
+ 2021-08-13 4468.00 2021-08-16 4479.71 2021-08-17 4448.08 2021-08-18 4400.27
3788
+ 2021-08-19 4405.80 2021-08-20 4441.67 2021-08-23 4479.53 2021-08-24 4486.23
3789
+ 2021-08-25 4496.19 2021-08-26 4470.00 2021-08-27 4509.37 2021-08-30 4528.79
3790
+ 2021-08-31 4522.68 2021-09-01 4524.09 2021-09-02 4536.95 2021-09-03 4535.43
3791
+ 2021-09-07 4520.03 2021-09-08 4514.07 2021-09-09 4493.28 2021-09-10 4458.58
3792
+ 2021-09-13 4468.73 2021-09-14 4443.05 2021-09-15 4480.70 2021-09-16 4473.75
3793
+ 2021-09-17 4432.99 2021-09-20 4357.73 2021-09-21 4354.19 2021-09-22 4395.64
3794
+ 2021-09-23 4448.98 2021-09-24 4455.48 2021-09-27 4443.11 2021-09-28 4352.63
3795
+ 2021-09-29 4359.46 2021-09-30 4307.54 2021-10-01 4357.04 2021-10-04 4300.46
3796
+ 2021-10-05 4345.72 2021-10-06 4363.55 2021-10-07 4399.76 2021-10-08 4391.34
3797
+ 2021-10-11 4361.19 2021-10-12 4350.65 2021-10-13 4363.80 2021-10-14 4438.26
3798
+ 2021-10-15 4471.37 2021-10-18 4486.46 2021-10-19 4519.63 2021-10-20 4536.19
3799
+ 2021-10-21 4549.78 2021-10-22 4544.90 2021-10-25 4566.48 2021-10-26 4574.79
3800
+ 2021-10-27 4551.68 2021-10-28 4596.42 2021-10-29 4605.38 2021-11-01 4613.67
3801
+ 2021-11-02 4630.65 2021-11-03 4660.57 2021-11-04 4680.06 2021-11-05 4697.53
3802
+ 2021-11-08 4701.70 2021-11-09 4685.25 2021-11-10 4646.71 2021-11-11 4649.27
3803
+ 2021-11-12 4682.85 2021-11-15 4682.80 2021-11-16 4700.90 2021-11-17 4688.67
3804
+ 2021-11-18 4704.54 2021-11-19 4697.96 2021-11-22 4682.94 2021-11-23 4690.70
3805
+ 2021-11-24 4701.46 2021-11-26 4594.62 2021-11-29 4655.27 2021-11-30 4567.00
3806
+ 2021-12-01 4513.04 2021-12-02 4577.10 2021-12-03 4538.43 2021-12-06 4591.67
3807
+ 2021-12-07 4686.75 2021-12-08 4701.21 2021-12-09 4667.45 2021-12-10 4712.02
3808
+ 2021-12-13 4668.97 2021-12-14 4634.09 2021-12-15 4709.85 2021-12-16 4668.67
3809
+ 2021-12-17 4620.64 2021-12-20 4568.02 2021-12-21 4649.23 2021-12-22 4696.56
3810
+ 2021-12-23 4725.79 2021-12-27 4791.19 2021-12-28 4786.35 2021-12-29 4793.06
3811
+ 2021-12-30 4778.73 2021-12-31 4766.18 2022-01-03 4796.56 2022-01-04 4793.54
3812
+ 2022-01-05 4700.58 2022-01-06 4696.05 2022-01-07 4677.03 2022-01-10 4670.29
3813
+ 2022-01-11 4713.07 2022-01-12 4726.35 2022-01-13 4659.03 2022-01-14 4662.85
3814
+ 2022-01-18 4577.11 2022-01-19 4532.76 2022-01-20 4482.73 2022-01-21 4397.94
3815
+ 2022-01-24 4410.13 2022-01-25 4356.45 2022-01-26 4349.93 2022-01-27 4326.51
3816
+ 2022-01-28 4431.85 2022-01-31 4515.55 2022-02-01 4546.54 2022-02-02 4589.38
3817
+ 2022-02-03 4477.44 2022-02-04 4500.53 2022-02-07 4483.87 2022-02-08 4521.54
3818
+ 2022-02-09 4587.18 2022-02-10 4504.08 2022-02-11 4418.64 2022-02-14 4401.67
3819
+ 2022-02-15 4471.07 2022-02-16 4475.01 2022-02-17 4380.26 2022-02-18 4348.87
3820
+ 2022-02-22 4304.76 2022-02-23 4225.50 2022-02-24 4288.70 2022-02-25 4384.65
3821
+ 2022-02-28 4373.94 2022-03-01 4306.26 2022-03-02 4386.54 2022-03-03 4363.49
3822
+ 2022-03-04 4328.87 2022-03-07 4201.09 2022-03-08 4170.70 2022-03-09 4277.88
3823
+ 2022-03-10 4259.52 2022-03-11 4204.31 2022-03-14 4173.11 2022-03-15 4262.45
3824
+ 2022-03-16 4357.86 2022-03-17 4411.67 2022-03-18 4463.12 2022-03-21 4461.18
3825
+ 2022-03-22 4511.61 2022-03-23 4456.24 2022-03-24 4520.16 2022-03-25 4543.06
3826
+ 2022-03-28 4575.52 2022-03-29 4631.60 2022-03-30 4602.45 2022-03-31 4530.41
3827
+ 2022-04-01 4545.86 2022-04-04 4582.64 2022-04-05 4525.12 2022-04-06 4481.15
3828
+ 2022-04-07 4500.21 2022-04-08 4488.28 2022-04-11 4412.53 2022-04-12 4397.45
3829
+ 2022-04-13 4446.59 2022-04-14 4392.59 2022-04-18 4391.69 2022-04-19 4462.21
3830
+ 2022-04-20 4459.45 2022-04-21 4393.66 2022-04-22 4271.78 2022-04-25 4296.12
3831
+ 2022-04-26 4175.20 2022-04-27 4183.96 2022-04-28 4287.50 2022-04-29 4131.93
3832
+ 2022-05-02 4155.38 2022-05-03 4175.48 2022-05-04 4300.17 2022-05-05 4146.87
3833
+ 2022-05-06 4123.34 2022-05-09 3991.24 2022-05-10 4001.05 2022-05-11 3935.18
3834
+ 2022-05-12 3930.08 2022-05-13 4023.89 2022-05-16 4008.01 2022-05-17 4088.85
3835
+ 2022-05-18 3923.68 2022-05-19 3900.79 2022-05-20 3901.36 2022-05-23 3973.75
3836
+ 2022-05-24 3941.48 2022-05-25 3978.73 2022-05-26 4057.84 2022-05-27 4158.24
3837
+ 2022-05-31 4132.15 2022-06-01 4101.23 2022-06-02 4176.82 2022-06-03 4108.54
3838
+ 2022-06-06 4121.43 2022-06-07 4160.68 2022-06-08 4115.77 2022-06-09 4017.82
3839
+ 2022-06-10 3900.86 2022-06-13 3749.63 2022-06-14 3735.48 2022-06-15 3789.99
3840
+ 2022-06-16 3666.77 2022-06-17 3674.84 2022-06-21 3764.79 2022-06-22 3759.89
3841
+ 2022-06-23 3795.73 2022-06-24 3911.74 2022-06-27 3900.11 2022-06-28 3821.55
3842
+ 2022-06-29 3818.83 2022-06-30 3785.38 2022-07-01 3825.33 2022-07-05 3831.39
3843
+ 2022-07-06 3845.08 2022-07-07 3902.62 2022-07-08 3899.38 2022-07-11 3854.43
3844
+ 2022-07-12 3818.80 2022-07-13 3801.78 2022-07-14 3790.38 2022-07-15 3863.16
3845
+ 2022-07-18 3830.85 2022-07-19 3936.69 2022-07-20 3959.90 2022-07-21 3998.95
3846
+ 2022-07-22 3961.63 2022-07-25 3966.84 2022-07-26 3921.05 2022-07-27 4023.61
3847
+ 2022-07-28 4072.43 2022-07-29 4130.29 2022-08-01 4118.63 2022-08-02 4091.19
3848
+ 2022-08-03 4155.17 2022-08-04 4151.94 2022-08-05 4145.19 2022-08-08 4140.06
3849
+ 2022-08-09 4122.47 2022-08-10 4210.24 2022-08-11 4207.27 2022-08-12 4280.15
3850
+ 2022-08-15 4297.14 2022-08-16 4305.20 2022-08-17 4274.04 2022-08-18 4283.74
3851
+ 2022-08-19 4228.48 2022-08-22 4137.99 2022-08-23 4128.73 2022-08-24 4140.77
3852
+ 2022-08-25 4199.12 2022-08-26 4057.66 2022-08-29 4030.61 2022-08-30 3986.16
3853
+ 2022-08-31 3955.00 2022-09-01 3966.85 2022-09-02 3924.26 2022-09-06 3908.19
3854
+ 2022-09-07 3979.87 2022-09-08 4006.18 2022-09-09 4067.36 2022-09-12 4110.41
3855
+ 2022-09-13 3932.69 2022-09-14 3946.01 2022-09-15 3901.35 2022-09-16 3873.33
3856
+ 2022-09-19 3899.89 2022-09-20 3855.93 2022-09-21 3789.93 2022-09-22 3757.99
3857
+ 2022-09-23 3693.23 2022-09-26 3655.04 2022-09-27 3647.29 2022-09-28 3719.04
3858
+ 2022-09-29 3640.47 2022-09-30 3585.62 2022-10-03 3678.43 2022-10-04 3790.93
3859
+ 2022-10-05 3783.28 2022-10-06 3744.52 2022-10-07 3639.66 2022-10-10 3612.39
3860
+ 2022-10-11 3588.84 2022-10-12 3577.03 2022-10-13 3669.91 2022-10-14 3583.07
3861
+ 2022-10-17 3677.95 2022-10-18 3719.98 2022-10-19 3695.16 2022-10-20 3665.78
3862
+ 2022-10-21 3752.75 2022-10-24 3797.34 2022-10-25 3859.11 2022-10-26 3830.60
3863
+ 2022-10-27 3807.30 2022-10-28 3901.06 2022-10-31 3871.98 2022-11-01 3856.10
3864
+ 2022-11-02 3759.69 2022-11-03 3719.89 2022-11-04 3770.55 2022-11-07 3806.80
3865
+ 2022-11-08 3828.11 2022-11-09 3748.57 2022-11-10 3956.37 2022-11-11 3992.93
3866
+ 2022-11-14 3957.25 2022-11-15 3991.73 2022-11-16 3958.79 2022-11-17 3946.56
3867
+ 2022-11-18 3965.34 2022-11-21 3949.94 2022-11-22 4003.58 2022-11-23 4027.26
3868
+ 2022-11-25 4026.12 2022-11-28 3963.94 2022-11-29 3957.63 2022-11-30 4080.11
3869
+ 2022-12-01 4076.57 2022-12-02 4071.70 2022-12-05 3998.84 2022-12-06 3941.26
3870
+ 2022-12-07 3933.92 2022-12-08 3963.51 2022-12-09 3934.38 2022-12-12 3990.56
3871
+ 2022-12-13 4019.65 2022-12-14 3995.32 2022-12-15 3895.75 2022-12-16 3852.36
3872
+ 2022-12-19 3817.66 2022-12-20 3821.62 2022-12-21 3878.44 2022-12-22 3822.39
3873
+ 2022-12-23 3844.82 2022-12-27 3829.25 2022-12-28 3783.22 2022-12-29 3849.28
3874
+ 2022-12-30 3839.50 2023-01-03 3824.14 2023-01-04 3852.97 2023-01-05 3808.10
3875
+ ##
3876
+ `);
3877
+ testDataSpx = testDataSpx.replace((/ (20..-)/g), "\n$1");
3878
+ testDataSpx = testDataSpx.trim().split("\n").slice(2, -1);
3879
+ testDataSpx = testDataSpx.map(function (elem, ii) {
3880
+ elem = elem.split(" ");
3881
+ return {
3882
+ date: elem[0],
3883
+ ii,
3884
+ priceClose: Number(elem[1])
3885
+ };
3886
+ });
3887
+ valActual = await dbExecAndReturnLastTable({
3888
+ bindList: {
3889
+ testDataSpx
3890
+ },
3891
+ db,
3892
+ sql: (`
3893
+ DROP TABLE IF EXISTS __sinefit_csv;
3894
+ CREATE TEMP TABLE __sinefit_csv AS
3895
+ SELECT
3896
+ *,
3897
+ WIN_SINEFIT2(1, NULL, ii, yy, ii, yy) OVER (
3898
+ ORDER BY date ASC
3899
+ ROWS BETWEEN ${ttSinefit - 1} PRECEDING AND 0 FOLLOWING
3900
+ ) AS __wsf
3901
+ FROM (
3902
+ SELECT
3903
+ value->>'ii' AS ii,
3904
+ value->>'date' AS date,
3905
+ value->>'priceClose' AS yy,
3906
+ 0 AS rr
3907
+ FROM JSON_EAcH($testDataSpx)
3908
+ );
3909
+ UPDATE __sinefit_csv
3910
+ SET
3911
+ rr = yy - predict_lnr
3912
+ FROM (
3913
+ SELECT
3914
+ ii + 1 AS ii,
3915
+ SINEFIT_EXTRACT(__wsf, 0, 'predict_lnr', ii + 1) AS predict_lnr
3916
+ FROM __sinefit_csv
3917
+ ) AS __join1
3918
+ WHERE __join1.ii = __sinefit_csv.ii;
3919
+ SELECT
3920
+ *,
3921
+ SINEFIT_EXTRACT(__wsf, 0, 'saa', 0) AS saa,
3922
+ SINEFIT_EXTRACT(__wsf, 0, 'spp', 0) AS spp,
3923
+ SINEFIT_EXTRACT(__wsf, 0, 'sww', 0) AS sww,
3924
+ ${sqlSinefitExtractLnr("__wsf", 0, "")}
3925
+ FROM __sinefit_csv
3926
+ JOIN (
3927
+ SELECT
3928
+ MEDIAN2(rr) AS rr_avg,
3929
+ STDEV(rr) AS rr_err
3930
+ FROM __sinefit_csv
3931
+ )
3932
+ LEFT JOIN (
3933
+ SELECT
3934
+ ii + 1 AS ii,
3935
+ SINEFIT_EXTRACT(__wsf, 0, 'predict_snr', ii + 1) AS predict_snr
3936
+ FROM __sinefit_csv
3937
+ ) USING (ii);
3938
+ `)
3939
+ });
3940
+ valActual = (
3941
+ "date saa sww spp"
3942
+ + " ii linear_residual predict_sine\n"
3943
+ + valActual.map(function (elem) {
3944
+ return [
3945
+ elem.date,
3946
+ elem.saa,
3947
+ elem.sww,
3948
+ elem.spp,
3949
+ elem.ii,
3950
+ (elem.rr - elem.rr_avg) / elem.rr_err,
3951
+ elem.predict_snr / 100
3952
+ ].map(function (num) {
3953
+ return (
3954
+ typeof num === "number"
3955
+ ? num.toFixed(4)
3956
+ : num
3957
+ );
3958
+ }).join(" ");
3959
+ }).join("\n")
3960
+ );
3961
+ valActual = valActual.replace((/ /g), " null ");
3962
+ valActual = valActual.replace((/ \n/g), "\n");
3963
+ valActual = valActual.replace((/ /g), "\t");
3964
+ valActual = valActual.trim() + "\n";
3965
+ await fsWriteFileUnlessTest(
3966
+ "test_data_sinefit.csv",
3967
+ valActual,
3968
+ String("1").replace(npm_config_mode_test_save, "force")
3969
+ );
3970
+ valExpect = await fsReadFileUnlessTest(
3971
+ "test_data_sinefit.csv",
3972
+ "force"
3973
+ );
3974
+ assertJsonEqual(valActual, valExpect);
3975
+ }())
3976
+ ]);
3977
+ });
3978
+ jstestIt((
3979
+ "test sqlite-extension-win_sumx handling-behavior"
3980
+ ), async function test_sqlite_extension_win_sumx() {
3981
+ let db = await dbOpenAsync({});
3982
+ let valIn;
3983
+ async function test_win_sumx_aggregate({
3984
+ aa,
3985
+ bb,
3986
+ valExpect,
3987
+ valExpect2
3988
+ }) {
3989
+ let sqlBetween = "";
3990
+ let valActual;
3991
+ if (aa !== undefined) {
3992
+ sqlBetween = (
3993
+ `ROWS BETWEEN ${aa - 1} PRECEDING AND ${bb} FOLLOWING`
3994
+ );
3995
+ }
3996
+ // test win_sum1-aggregate handling-behavior
3997
+ valActual = await dbExecAndReturnLastTable({
3998
+ bindList: {
3999
+ valIn: JSON.stringify(valIn)
4000
+ },
4001
+ db,
4002
+ sql: (`
4003
+ SELECT
4004
+ WIN_SUM1(value->>1) OVER (
4005
+ ORDER BY value->>0 ASC
4006
+ ${sqlBetween}
4007
+ ) AS val
4008
+ FROM JSON_EAcH($valIn);
4009
+ `)
4010
+ });
4011
+ valActual = valActual.map(function ({val}) {
4012
+ return Number(val.toFixed(4));
4013
+ });
4014
+ assertJsonEqual(valActual, valExpect);
4015
+ // test win_sum2-aggregate handling-behavior
4016
+ valActual = await dbExecAndReturnLastTable({
4017
+ bindList: {
4018
+ valIn: JSON.stringify(valIn)
4019
+ },
4020
+ db,
4021
+ sql: (`
4022
+ SELECT
4023
+ id2,
4024
+ DOUBLEARRAY_JSONTO(WIN_SUM2(
4025
+ value->>1,
4026
+ value->>1,
4027
+ value->>1,
4028
+ value->>1,
4029
+ value->>1,
4030
+ value->>1,
4031
+ value->>1,
4032
+ value->>1,
4033
+ value->>1,
4034
+ IIF(id2 = 1, -1, value->>1)
4035
+ ) OVER (
4036
+ ORDER BY value->>0 ASC
4037
+ ${sqlBetween}
4038
+ )) AS val
4039
+ FROM (
4040
+ SELECT
4041
+ *,
4042
+ ROW_NUMBER() OVER(ORDER BY id ASC) AS id2
4043
+ FROM JSON_EAcH($valIn)
4044
+ );
4045
+ `)
4046
+ });
4047
+ valActual = valActual.map(function ({val}, ii, list) {
4048
+ val = JSON.parse(val).map(function (elem, jj) {
4049
+ elem = Number(elem.toFixed(4));
4050
+ if (ii + (bb || 0) + 1 >= list.length && jj === 9) {
4051
+ assertJsonEqual(elem, valExpect2, valActual);
4052
+ } else {
4053
+ assertJsonEqual(elem, valExpect[ii], valActual);
4054
+ }
4055
+ return elem;
4056
+ });
4057
+ return val[0];
4058
+ });
4059
+ assertJsonEqual(valActual, valExpect);
4060
+ }
4061
+ valIn = [
4062
+ [11, NaN],
4063
+ [10, "10"],
4064
+ [9, 9],
4065
+ [8, "8"],
4066
+ [7, 7],
4067
+ [6, 6],
4068
+ [5, Infinity],
4069
+ [4, "4"],
4070
+ [3, 3],
4071
+ [2, 2],
4072
+ [1, "1"],
4073
+ [0, undefined]
4074
+ ];
4075
+ await Promise.all([
4076
+ (async function () {
4077
+ let valActual;
4078
+ // test win_sum2-error handling-behavior
4079
+ await assertErrorThrownAsync(function () {
4080
+ return dbExecAsync({
4081
+ db,
4082
+ sql: (`
4083
+ SELECT WIN_SUM2() FROM (SELECT 1);
4084
+ `)
4085
+ });
4086
+ }, "wrong number of arguments");
4087
+ // test win_sum1-null-case handling-behavior
4088
+ valActual = await dbExecAndReturnLastTable({
4089
+ db,
4090
+ sql: (`
4091
+ DROP TABLE IF EXISTS __tmp1;
4092
+ CREATE TEMP TABLE __tmp1 (val REAL);
4093
+ SELECT WIN_SUM1(1) FROM __tmp1;
4094
+ `)
4095
+ });
4096
+ valActual = valActual.map(function ({val}) {
4097
+ return val;
4098
+ });
4099
+ assertJsonEqual(valActual, [null]);
4100
+ // test win_sum2-null-case handling-behavior
4101
+ valActual = await dbExecAndReturnLastTable({
4102
+ db,
4103
+ sql: (`
4104
+ DROP TABLE IF EXISTS __tmp1;
4105
+ CREATE TEMP TABLE __tmp1 (val REAL);
4106
+ SELECT DOUBLEARRAY_JSONTO(WIN_SUM2(1, 2, 3)) FROM __tmp1;
4107
+ `)
4108
+ });
4109
+ valActual = valActual.map(function ({val}) {
4110
+ return val;
4111
+ });
4112
+ assertJsonEqual(valActual, [null]);
4113
+ }()),
4114
+ // test win_sum2-aggregate-normal handling-behavior
4115
+ test_win_sumx_aggregate({
4116
+ valExpect: [
4117
+ 0, 1, 3, 6,
4118
+ 10, 14, 20, 27,
4119
+ 35, 44, 54, 64
4120
+ ],
4121
+ valExpect2: 53
4122
+ }),
4123
+ // test win_sum2-aggregate-window handling-behavior
4124
+ test_win_sumx_aggregate({
4125
+ aa: 1,
4126
+ bb: 3,
4127
+ valExpect: [
4128
+ 6, 10, 13, 17,
4129
+ 21, 25, 30, 34,
4130
+ 37, 37, 37, 37
4131
+ ],
4132
+ valExpect2: 26
4133
+ }),
4134
+ test_win_sumx_aggregate({
4135
+ aa: 3,
4136
+ bb: 1,
4137
+ valExpect: [
4138
+ 1, 3, 6, 10,
4139
+ 13, 17, 21, 25,
4140
+ 30, 34, 37, 37
4141
+ ],
4142
+ valExpect2: 26
4143
+ }),
4144
+ test_win_sumx_aggregate({
4145
+ aa: 4,
4146
+ bb: 0,
4147
+ valExpect: [
4148
+ 0, 1, 3, 6,
4149
+ 10, 13, 17, 21,
4150
+ 25, 30, 34, 37
4151
+ ],
4152
+ valExpect2: 26
4153
+ })
4154
+ ]);
4155
+ });
4156
+ });
4157
+
4158
+ jstestDescribe((
4159
+ "test_sqlmathWebworkerInit"
4160
+ ), function test_sqlmathWebworkerInit() {
4161
+ jstestIt((
4162
+ "test sqlmathWebworkerInit handling-behavior"
4163
+ ), async function () {
4164
+ let db = await dbOpenAsync({
4165
+ dbData: new ArrayBuffer()
4166
+ });
4167
+ sqlmathWebworkerInit({
4168
+ db,
4169
+ modeTest: true
4170
+ });
4171
+ });
4172
+ });
4173
+
4174
+ export {
4175
+ debugInline
4176
+ };