@@ -3,6 +3,7 @@ import * as sqlite from 'node:sqlite';
33import { describe , expect , onTestFinished , test } from 'vitest' ;
44import {
55 CompatibilityContext ,
6+ CompatibilityEdition ,
67 javaScriptExpressionEngine ,
78 nodeSqliteExpressionEngine ,
89 SqliteValue
@@ -14,19 +15,22 @@ import {
1415} from '../../../../src/sync_plan/engine/scalar_expression_engine.js' ;
1516import { BinaryOperator } from '../../../../src/sync_plan/expression.js' ;
1617
17- const compatibility = CompatibilityContext . FULL_BACKWARDS_COMPATIBILITY ;
18-
1918describe ( 'sqlite' , ( ) => {
20- defineEngineTests ( false , ( ) => nodeSqliteExpressionEngine ( sqlite , compatibility ) ) ;
19+ defineEngineTests ( false , ( c ) => nodeSqliteExpressionEngine ( sqlite , c ) ) ;
2120} ) ;
2221
2322describe ( 'javascript' , ( ) => {
24- defineEngineTests ( true , ( ) => javaScriptExpressionEngine ( compatibility ) ) ;
23+ defineEngineTests ( true , javaScriptExpressionEngine ) ;
2524} ) ;
2625
27- function defineEngineTests ( isJavaScript : boolean , createEngine : ( ) => ScalarExpressionEngine ) {
26+ function defineEngineTests (
27+ isJavaScript : boolean ,
28+ createEngine : ( compatibility : CompatibilityContext ) => ScalarExpressionEngine
29+ ) {
30+ let compatibility = CompatibilityContext . FULL_BACKWARDS_COMPATIBILITY ;
31+
2832 function prepare ( stmt : ScalarStatement ) {
29- const engine = createEngine ( ) ;
33+ const engine = createEngine ( compatibility ) ;
3034 onTestFinished ( ( ) => engine . close ( ) ) ;
3135 return engine . prepareEvaluator ( stmt ) ;
3236 }
@@ -60,6 +64,12 @@ function defineEngineTests(isJavaScript: boolean, createEngine: () => ScalarExpr
6064 expect ( prepare ( { outputs : [ { type : 'lit_null' } ] } ) . evaluate ( [ ] ) ) . toStrictEqual ( [ [ null ] ] ) ;
6165 } ) ;
6266
67+ test ( 'not null' , ( ) => {
68+ expect (
69+ prepare ( { outputs : [ { type : 'unary' , operator : 'not' , operand : { type : 'lit_null' } } ] } ) . evaluate ( [ ] )
70+ ) . toStrictEqual ( [ [ isJavaScript ? 1n : null ] ] ) ;
71+ } ) ;
72+
6373 test ( 'literal double' , ( ) => {
6474 expect ( prepare ( { outputs : [ { type : 'lit_double' , value : 3 } ] } ) . evaluate ( [ ] ) ) . toStrictEqual ( [ [ 3 ] ] ) ;
6575 } ) ;
@@ -125,6 +135,10 @@ function defineEngineTests(isJavaScript: boolean, createEngine: () => ScalarExpr
125135 expect ( stmt . evaluate ( [ 1 , 2 , 3 ] ) ) . toStrictEqual ( [ [ 0n ] ] ) ;
126136 expect ( stmt . evaluate ( [ 4 , 2 , 3 ] ) ) . toStrictEqual ( [ [ 0n ] ] ) ;
127137 expect ( stmt . evaluate ( [ 1 , 1 , 1 ] ) ) . toStrictEqual ( [ [ 1n ] ] ) ;
138+
139+ expect ( stmt . evaluate ( [ null , 3 , 4 ] ) ) . toStrictEqual ( [ [ null ] ] ) ;
140+ expect ( stmt . evaluate ( [ 4 , null , 4 ] ) ) . toStrictEqual ( [ [ null ] ] ) ;
141+ expect ( stmt . evaluate ( [ 4 , 3 , null ] ) ) . toStrictEqual ( [ [ null ] ] ) ;
128142 } ) ;
129143
130144 test ( 'scalar in' , ( ) => {
@@ -261,12 +275,6 @@ function defineEngineTests(isJavaScript: boolean, createEngine: () => ScalarExpr
261275 expectFunction ( 'unixepoch' , [ 'now' ] , null ) ;
262276 expectFunction ( 'datetime' , [ 'now' ] , null ) ;
263277
264- const jsonObject = JSON . stringify ( { foo : { bar : [ 'baz' ] } } ) ;
265-
266- // Legacy JSON behavior, support paths without $. prefix
267- expectFunction ( '->' , [ jsonObject , 'foo.bar' ] , '["baz"]' ) ;
268- expectFunction ( '->>' , [ jsonObject , 'foo.bar.0' ] , 'baz' ) ;
269-
270278 const point = '010100000097900F7A36FB40C0F4FDD478E9D63240' ;
271279 expectFunction ( 'st_x' , [ point ] , - 33.9626 ) ;
272280 expectFunction ( 'st_y' , [ point ] , 18.8395 ) ;
@@ -275,4 +283,18 @@ function defineEngineTests(isJavaScript: boolean, createEngine: () => ScalarExpr
275283 expectFunction ( 'st_asgeojson' , [ geography ] , '{"type":"Point","coordinates":[-33.9626,18.8395]}' ) ;
276284 expectFunction ( 'st_astext' , [ geography ] , 'POINT(-33.9626 18.8395)' ) ;
277285 } ) ;
286+
287+ test ( 'legacy and fixed JSON behavior' , ( ) => {
288+ const jsonObject = JSON . stringify ( { foo : { bar : [ 'baz' ] } , 'foo.bar' : [ 'another' ] } ) ;
289+ compatibility = CompatibilityContext . FULL_BACKWARDS_COMPATIBILITY ;
290+
291+ // Legacy JSON behavior, support paths without $. prefix
292+ expectFunction ( '->' , [ jsonObject , 'foo.bar' ] , '["baz"]' ) ;
293+ expectFunction ( '->>' , [ jsonObject , 'foo.bar.0' ] , 'baz' ) ;
294+
295+ // New JSON behavior, require $. syntax.
296+ compatibility = new CompatibilityContext ( { edition : CompatibilityEdition . SYNC_STREAMS } ) ;
297+ expectFunction ( '->' , [ jsonObject , 'foo.bar' ] , '["another"]' ) ;
298+ expectFunction ( '->>' , [ jsonObject , 'foo.bar.0' ] , null ) ;
299+ } ) ;
278300}
0 commit comments