]> gitweb.factorcode.org Git - factor.git/commitdiff
db.sqlite: Fix NULL returns for INTEGER columns in sqlite
authorDoug Coleman <doug.coleman@gmail.com>
Fri, 22 Jul 2016 15:19:54 +0000 (08:19 -0700)
committerDoug Coleman <doug.coleman@gmail.com>
Fri, 22 Jul 2016 15:20:56 +0000 (08:20 -0700)
The api for getting integer/double columns from sqlite3 returns a zero, but the value could still be NULL, so an extra api check for the sqlite type is required.

Fixes #1674.

basis/db/sqlite/ffi/ffi.factor
basis/db/sqlite/lib/lib.factor
basis/db/sqlite/sqlite-tests.factor

index f505add8535a65dc6f086914a2e9c48665559f4a..1c0defc317835c7704b7e6c5aee95c72fd11a93f 100644 (file)
@@ -132,7 +132,7 @@ FUNCTION: c-string sqlite3_column_decltype ( sqlite3_stmt* pStmt, int col )
 FUNCTION: int sqlite3_column_int ( sqlite3_stmt* pStmt, int col )
 FUNCTION: sqlite3_int64 sqlite3_column_int64 ( sqlite3_stmt* pStmt, int col )
 ! Bind the same function as above, but for unsigned 64bit integers
-FUNCTION-ALIAS: sqlite3-column-uint64
+FUNCTION-ALIAS: sqlite3_column_uint64
     sqlite3_uint64 sqlite3_column_int64 ( sqlite3_stmt* pStmt, int col )
 FUNCTION: double sqlite3_column_double ( sqlite3_stmt* pStmt, int col )
 FUNCTION: c-string sqlite3_column_name ( sqlite3_stmt* pStmt, int col )
index b36edc29203a277e22f9f58cb7fc4cffdda02762..862df5b8ed1b0ee4749c2d3eefa25a55f8e41bfa 100644 (file)
@@ -133,6 +133,24 @@ ERROR: sqlite-sql-error < sql-error n string ;
 : sqlite-column-name ( handle index -- string ) sqlite3_column_name ;
 : sqlite-column-type ( handle index -- string ) sqlite3_column_type ;
 
+
+: sqlite3-column-null ( sqlite n obj -- obj/f )
+    [ sqlite3_column_type SQLITE_NULL = f ] dip ? ; inline
+
+! sqlite_column_int returns 0 for both a ``0`` and for ``NULL``
+! so call sqlite3_column_type if it's 0
+: sqlite3-column-int ( handle index -- int/f )
+    2dup sqlite3_column_int dup 0 = [ sqlite3-column-null ] [ 2nip ] if ;
+
+: sqlite3-column-int64 ( handle index -- int/f )
+    2dup sqlite3_column_int64 dup 0 = [ sqlite3-column-null ] [ 2nip ] if ;
+
+: sqlite3-column-uint64 ( handle index -- int/f )
+    2dup sqlite3_column_uint64 dup 0 = [ sqlite3-column-null ] [ 2nip ] if ;
+
+: sqlite3-column-double ( handle index -- int/f )
+    2dup sqlite3_column_double dup 0.0 = [ sqlite3-column-null ] [ 2nip ] if ;
+
 : sqlite-column-blob ( handle index -- byte-array/f )
     [ sqlite3_column_bytes ] 2keep
     pick zero? [
@@ -146,12 +164,12 @@ ERROR: sqlite-sql-error < sql-error n string ;
     {
         { +db-assigned-id+ [ sqlite3_column_int64  ] }
         { +random-id+ [ sqlite3-column-uint64 ] }
-        { INTEGER [ sqlite3_column_int ] }
-        { BIG-INTEGER [ sqlite3_column_int64 ] }
-        { SIGNED-BIG-INTEGER [ sqlite3_column_int64 ] }
+        { INTEGER [ sqlite3-column-int ] }
+        { BIG-INTEGER [ sqlite3-column-int64 ] }
+        { SIGNED-BIG-INTEGER [ sqlite3-column-int64 ] }
         { UNSIGNED-BIG-INTEGER [ sqlite3-column-uint64 ] }
-        { BOOLEAN [ sqlite3_column_int 1 = ] }
-        { DOUBLE [ sqlite3_column_double ] }
+        { BOOLEAN [ sqlite3-column-int 1 = ] }
+        { DOUBLE [ sqlite3-column-double ] }
         { TEXT [ sqlite3_column_text ] }
         { VARCHAR [ sqlite3_column_text ] }
         { DATE [ sqlite3_column_text dup [ ymd>timestamp ] when ] }
index b5866a71f3fc258b8fe8b4f84ff1829684687f25..cd804fc765fba3a7f304191e8786085d42070ea7 100644 (file)
@@ -172,3 +172,34 @@ watch "WATCH" {
         ] with-transaction
     ] with-db
 ] unit-test
+
+! Reported by AlexIljin
+{ f } [
+    TUPLE: num-test1 num ;
+    num-test1 "NUM_TEST" { { "num" "NUM" INTEGER } } define-persistent
+    "resource:num-test-bad.db" <sqlite-db> [
+        num-test1 ensure-table
+        num-test1 new insert-tuple
+        num-test1 new select-tuple
+    ] with-db num>>
+] unit-test
+
+{ f } [
+    TUPLE: num-test2 num ;
+    num-test2 "NUM_TEST" { { "num" "NUM" DOUBLE } } define-persistent
+    "resource:num-test-bad.db" <sqlite-db> [
+        num-test2 ensure-table
+        num-test2 new insert-tuple
+        num-test2 new select-tuple
+    ] with-db num>>
+] unit-test
+
+{ f } [
+    TUPLE: num-test3 num ;
+    num-test3 "NUM_TEST" { { "num" "NUM" BOOLEAN } } define-persistent
+    "resource:num-test-bad.db" <sqlite-db> [
+        num-test3 ensure-table
+        num-test3 new insert-tuple
+        num-test3 new select-tuple
+    ] with-db num>>
+] unit-test