@@ -609,3 +609,108 @@ suite('StatementSync.prototype.setAllowBareNamedParameters()', () => {
609609 } ) ;
610610 } ) ;
611611} ) ;
612+
613+ suite ( 'StatementSync.prototype.setReadNullAsUndefined()' , ( ) => {
614+ test ( 'NULL conversion can be toggled' , ( t ) => {
615+ const db = new DatabaseSync ( nextDb ( ) ) ;
616+ t . after ( ( ) => { db . close ( ) ; } ) ;
617+
618+ db . exec ( `
619+ CREATE TABLE data(key INTEGER PRIMARY KEY, val TEXT) STRICT;
620+ INSERT INTO data (key, val) VALUES (1, NULL);
621+ ` ) ;
622+
623+ const query = db . prepare ( 'SELECT val FROM data WHERE key = 1' ) ;
624+ t . assert . deepStrictEqual ( query . get ( ) , { __proto__ : null , val : null } ) ;
625+
626+ t . assert . strictEqual ( query . setReadNullAsUndefined ( true ) , undefined ) ;
627+ t . assert . deepStrictEqual ( query . get ( ) , { __proto__ : null , val : undefined } ) ;
628+
629+ t . assert . strictEqual ( query . setReadNullAsUndefined ( false ) , undefined ) ;
630+ t . assert . deepStrictEqual ( query . get ( ) , { __proto__ : null , val : null } ) ;
631+ } ) ;
632+
633+ test ( 'throws when input is not a boolean' , ( t ) => {
634+ const db = new DatabaseSync ( nextDb ( ) ) ;
635+ t . after ( ( ) => { db . close ( ) ; } ) ;
636+
637+ db . exec ( 'CREATE TABLE data(key INTEGER PRIMARY KEY, val TEXT) STRICT;' ) ;
638+
639+ const stmt = db . prepare ( 'SELECT val FROM data' ) ;
640+ t . assert . throws ( ( ) => {
641+ stmt . setReadNullAsUndefined ( ) ;
642+ } , {
643+ code : 'ERR_INVALID_ARG_TYPE' ,
644+ message : / T h e " r e a d N u l l A s U n d e f i n e d " a r g u m e n t m u s t b e a b o o l e a n / ,
645+ } ) ;
646+ } ) ;
647+
648+ test ( 'returns array rows with undefined when both flags are set' , ( t ) => {
649+ const db = new DatabaseSync ( nextDb ( ) ) ;
650+ t . after ( ( ) => { db . close ( ) ; } ) ;
651+
652+ db . exec ( `
653+ CREATE TABLE data(key INTEGER PRIMARY KEY, val TEXT) STRICT;
654+ INSERT INTO data (key, val) VALUES (1, NULL);
655+ ` ) ;
656+
657+ const query = db . prepare ( 'SELECT key, val FROM data WHERE key = 1' ) ;
658+ query . setReturnArrays ( true ) ;
659+ query . setReadNullAsUndefined ( true ) ;
660+
661+ t . assert . deepStrictEqual ( query . get ( ) , [ 1 , undefined ] ) ;
662+ } ) ;
663+
664+ test ( 'applies to all()' , ( t ) => {
665+ const db = new DatabaseSync ( nextDb ( ) ) ;
666+ t . after ( ( ) => { db . close ( ) ; } ) ;
667+
668+ db . exec ( `
669+ CREATE TABLE data(key INTEGER PRIMARY KEY, val TEXT) STRICT;
670+ INSERT INTO data (key, val) VALUES (1, NULL), (2, 'two');
671+ ` ) ;
672+
673+ const query = db . prepare ( 'SELECT key, val FROM data ORDER BY key' ) ;
674+ query . setReadNullAsUndefined ( true ) ;
675+
676+ t . assert . deepStrictEqual ( query . all ( ) , [
677+ { __proto__ : null , key : 1 , val : undefined } ,
678+ { __proto__ : null , key : 2 , val : 'two' } ,
679+ ] ) ;
680+ } ) ;
681+
682+ test ( 'applies to iterate()' , ( t ) => {
683+ const db = new DatabaseSync ( nextDb ( ) ) ;
684+ t . after ( ( ) => { db . close ( ) ; } ) ;
685+
686+ db . exec ( `
687+ CREATE TABLE data(key INTEGER PRIMARY KEY, val TEXT) STRICT;
688+ INSERT INTO data (key, val) VALUES (1, NULL), (2, NULL);
689+ ` ) ;
690+
691+ const query = db . prepare ( 'SELECT key, val FROM data ORDER BY key' ) ;
692+ query . setReadNullAsUndefined ( true ) ;
693+
694+ const iter = query . iterate ( ) ;
695+ t . assert . deepStrictEqual ( iter . next ( ) . value , { __proto__ : null , key : 1 , val : undefined } ) ;
696+ t . assert . deepStrictEqual ( iter . next ( ) . value , { __proto__ : null , key : 2 , val : undefined } ) ;
697+ t . assert . strictEqual ( iter . next ( ) . done , true ) ;
698+ } ) ;
699+
700+ test ( 'does not change NULL passed to user-defined functions' , ( t ) => {
701+ const db = new DatabaseSync ( nextDb ( ) ) ;
702+ t . after ( ( ) => { db . close ( ) ; } ) ;
703+
704+ db . exec ( 'CREATE TABLE data(val TEXT) STRICT; INSERT INTO data VALUES (NULL);' ) ;
705+
706+ let seen ;
707+ db . function ( 'echo' , ( x ) => { seen = x ; return x ; } ) ;
708+
709+ const query = db . prepare ( 'SELECT echo(val) AS out FROM data' ) ;
710+ query . setReadNullAsUndefined ( true ) ;
711+
712+ t . assert . deepStrictEqual ( query . get ( ) , { __proto__ : null , out : undefined } ) ;
713+ t . assert . strictEqual ( seen , null ) ;
714+ } ) ;
715+ } ) ;
716+
0 commit comments