| OLD | NEW | 
 | (Empty) | 
|    1 # 2001 September 15 |  | 
|    2 # |  | 
|    3 # The author disclaims copyright to this source code.  In place of |  | 
|    4 # a legal notice, here is a blessing: |  | 
|    5 # |  | 
|    6 #    May you do good and not evil. |  | 
|    7 #    May you find forgiveness for yourself and forgive others. |  | 
|    8 #    May you share freely, never taking more than you give. |  | 
|    9 # |  | 
|   10 #*********************************************************************** |  | 
|   11 # This file implements regression tests for SQLite library. Specfically |  | 
|   12 # it tests that the different storage classes (integer, real, text etc.) |  | 
|   13 # all work correctly. |  | 
|   14 # |  | 
|   15 # $Id: types.test,v 1.20 2009/06/29 06:00:37 danielk1977 Exp $ |  | 
|   16  |  | 
|   17 set testdir [file dirname $argv0] |  | 
|   18 source $testdir/tester.tcl |  | 
|   19  |  | 
|   20 # Tests in this file are organized roughly as follows: |  | 
|   21 # |  | 
|   22 # types-1.*.*: Test that values are stored using the expected storage |  | 
|   23 #              classes when various forms of literals are inserted into |  | 
|   24 #              columns with different affinities. |  | 
|   25 # types-1.1.*: INSERT INTO <table> VALUES(...) |  | 
|   26 # types-1.2.*: INSERT INTO <table> SELECT... |  | 
|   27 # types-1.3.*: UPDATE <table> SET... |  | 
|   28 # |  | 
|   29 # types-2.*.*: Check that values can be stored and retrieving using the |  | 
|   30 #              various storage classes. |  | 
|   31 # types-2.1.*: INTEGER |  | 
|   32 # types-2.2.*: REAL |  | 
|   33 # types-2.3.*: NULL |  | 
|   34 # types-2.4.*: TEXT |  | 
|   35 # types-2.5.*: Records with a few different storage classes. |  | 
|   36 # |  | 
|   37 # types-3.*: Test that the '=' operator respects manifest types. |  | 
|   38 # |  | 
|   39  |  | 
|   40 # Disable encryption on the database for this test. |  | 
|   41 db close |  | 
|   42 set DB [sqlite3 db test.db; sqlite3_connection_pointer db] |  | 
|   43 sqlite3_rekey $DB {} |  | 
|   44  |  | 
|   45 # Create a table with one column for each type of affinity |  | 
|   46 do_test types-1.1.0 { |  | 
|   47   execsql { |  | 
|   48     CREATE TABLE t1(i integer, n numeric, t text, o blob); |  | 
|   49   } |  | 
|   50 } {} |  | 
|   51  |  | 
|   52 # Each element of the following list represents one test case. |  | 
|   53 # |  | 
|   54 # The first value of each sub-list is an SQL literal. The following |  | 
|   55 # four value are the storage classes that would be used if the |  | 
|   56 # literal were inserted into a column with affinity INTEGER, NUMERIC, TEXT |  | 
|   57 # or NONE, respectively. |  | 
|   58 set values { |  | 
|   59   { 5.0    integer integer text real    } |  | 
|   60   { 5.1    real    real    text real    } |  | 
|   61   { 5      integer integer text integer } |  | 
|   62   { '5.0'  integer integer text text    } |  | 
|   63   { '5.1'  real    real    text text    } |  | 
|   64   { '-5.0' integer integer text text    } |  | 
|   65   { '-5.0' integer integer text text    } |  | 
|   66   { '5'    integer integer text text    } |  | 
|   67   { 'abc'  text    text    text text    } |  | 
|   68   { NULL   null    null    null null    } |  | 
|   69 } |  | 
|   70 ifcapable {bloblit} { |  | 
|   71   lappend values  { X'00'  blob    blob    blob blob    } |  | 
|   72 } |  | 
|   73  |  | 
|   74 # This code tests that the storage classes specified above (in the $values |  | 
|   75 # table) are correctly assigned when values are inserted using a statement |  | 
|   76 # of the form: |  | 
|   77 # |  | 
|   78 # INSERT INTO <table> VALUE(<values>); |  | 
|   79 # |  | 
|   80 set tnum 1 |  | 
|   81 foreach val $values { |  | 
|   82   set lit [lindex $val 0] |  | 
|   83   execsql "DELETE FROM t1;" |  | 
|   84   execsql "INSERT INTO t1 VALUES($lit, $lit, $lit, $lit);" |  | 
|   85   do_test types-1.1.$tnum { |  | 
|   86     execsql { |  | 
|   87       SELECT typeof(i), typeof(n), typeof(t), typeof(o) FROM t1; |  | 
|   88     } |  | 
|   89   } [lrange $val 1 end] |  | 
|   90   incr tnum |  | 
|   91 } |  | 
|   92  |  | 
|   93 # This code tests that the storage classes specified above (in the $values |  | 
|   94 # table) are correctly assigned when values are inserted using a statement |  | 
|   95 # of the form: |  | 
|   96 # |  | 
|   97 # INSERT INTO t1 SELECT .... |  | 
|   98 # |  | 
|   99 set tnum 1 |  | 
|  100 foreach val $values { |  | 
|  101   set lit [lindex $val 0] |  | 
|  102   execsql "DELETE FROM t1;" |  | 
|  103   execsql "INSERT INTO t1 SELECT $lit, $lit, $lit, $lit;" |  | 
|  104   do_test types-1.2.$tnum { |  | 
|  105     execsql { |  | 
|  106       SELECT typeof(i), typeof(n), typeof(t), typeof(o) FROM t1; |  | 
|  107     } |  | 
|  108   } [lrange $val 1 end] |  | 
|  109   incr tnum |  | 
|  110 } |  | 
|  111  |  | 
|  112 # This code tests that the storage classes specified above (in the $values |  | 
|  113 # table) are correctly assigned when values are inserted using a statement |  | 
|  114 # of the form: |  | 
|  115 # |  | 
|  116 # UPDATE <table> SET <column> = <value>; |  | 
|  117 # |  | 
|  118 set tnum 1 |  | 
|  119 foreach val $values { |  | 
|  120   set lit [lindex $val 0] |  | 
|  121   execsql "UPDATE t1 SET i = $lit, n = $lit, t = $lit, o = $lit;" |  | 
|  122   do_test types-1.3.$tnum { |  | 
|  123     execsql { |  | 
|  124       SELECT typeof(i), typeof(n), typeof(t), typeof(o) FROM t1; |  | 
|  125     } |  | 
|  126   } [lrange $val 1 end] |  | 
|  127   incr tnum |  | 
|  128 } |  | 
|  129  |  | 
|  130 execsql { |  | 
|  131   DROP TABLE t1; |  | 
|  132 } |  | 
|  133  |  | 
|  134 # Open the table with root-page $rootpage at the btree |  | 
|  135 # level. Return a list that is the length of each record |  | 
|  136 # in the table, in the tables default scanning order. |  | 
|  137 proc record_sizes {rootpage} { |  | 
|  138   set bt [btree_open test.db 10 0] |  | 
|  139   btree_begin_transaction $bt |  | 
|  140   set c [btree_cursor $bt $rootpage 0] |  | 
|  141   btree_first $c |  | 
|  142   while 1 { |  | 
|  143     lappend res [btree_payload_size $c] |  | 
|  144     if {[btree_next $c]} break |  | 
|  145   } |  | 
|  146   btree_close_cursor $c |  | 
|  147   btree_close $bt |  | 
|  148   set res |  | 
|  149 } |  | 
|  150  |  | 
|  151  |  | 
|  152 # Create a table and insert some 1-byte integers. Make sure they  |  | 
|  153 # can be read back OK. These should be 3 byte records. |  | 
|  154 do_test types-2.1.1 { |  | 
|  155   execsql { |  | 
|  156     CREATE TABLE t1(a integer); |  | 
|  157     INSERT INTO t1 VALUES(0); |  | 
|  158     INSERT INTO t1 VALUES(120); |  | 
|  159     INSERT INTO t1 VALUES(-120); |  | 
|  160   } |  | 
|  161 } {} |  | 
|  162 do_test types-2.1.2 { |  | 
|  163   execsql { |  | 
|  164     SELECT a FROM t1; |  | 
|  165   } |  | 
|  166 } {0 120 -120} |  | 
|  167  |  | 
|  168 # Try some 2-byte integers (4 byte records) |  | 
|  169 do_test types-2.1.3 { |  | 
|  170   execsql { |  | 
|  171     INSERT INTO t1 VALUES(30000); |  | 
|  172     INSERT INTO t1 VALUES(-30000); |  | 
|  173   } |  | 
|  174 } {} |  | 
|  175 do_test types-2.1.4 { |  | 
|  176   execsql { |  | 
|  177     SELECT a FROM t1; |  | 
|  178   } |  | 
|  179 } {0 120 -120 30000 -30000} |  | 
|  180  |  | 
|  181 # 4-byte integers (6 byte records) |  | 
|  182 do_test types-2.1.5 { |  | 
|  183   execsql { |  | 
|  184     INSERT INTO t1 VALUES(2100000000); |  | 
|  185     INSERT INTO t1 VALUES(-2100000000); |  | 
|  186   } |  | 
|  187 } {} |  | 
|  188 do_test types-2.1.6 { |  | 
|  189   execsql { |  | 
|  190     SELECT a FROM t1; |  | 
|  191   } |  | 
|  192 } {0 120 -120 30000 -30000 2100000000 -2100000000} |  | 
|  193  |  | 
|  194 # 8-byte integers (10 byte records) |  | 
|  195 do_test types-2.1.7 { |  | 
|  196   execsql { |  | 
|  197     INSERT INTO t1 VALUES(9000000*1000000*1000000); |  | 
|  198     INSERT INTO t1 VALUES(-9000000*1000000*1000000); |  | 
|  199   } |  | 
|  200 } {} |  | 
|  201 do_test types-2.1.8 { |  | 
|  202   execsql { |  | 
|  203     SELECT a FROM t1; |  | 
|  204   } |  | 
|  205 } [list 0 120 -120 30000 -30000 2100000000 -2100000000 \ |  | 
|  206         9000000000000000000 -9000000000000000000] |  | 
|  207  |  | 
|  208 # Check that all the record sizes are as we expected. |  | 
|  209 ifcapable legacyformat { |  | 
|  210   do_test types-2.1.9 { |  | 
|  211     set root [db eval {select rootpage from sqlite_master where name = 't1'}] |  | 
|  212     record_sizes $root |  | 
|  213   } {3 3 3 4 4 6 6 10 10} |  | 
|  214 } else { |  | 
|  215   do_test types-2.1.9 { |  | 
|  216     set root [db eval {select rootpage from sqlite_master where name = 't1'}] |  | 
|  217     record_sizes $root |  | 
|  218   } {2 3 3 4 4 6 6 10 10} |  | 
|  219 } |  | 
|  220    |  | 
|  221 # Insert some reals. These should be 10 byte records. |  | 
|  222 do_test types-2.2.1 { |  | 
|  223   execsql { |  | 
|  224     CREATE TABLE t2(a float); |  | 
|  225     INSERT INTO t2 VALUES(0.0); |  | 
|  226     INSERT INTO t2 VALUES(12345.678); |  | 
|  227     INSERT INTO t2 VALUES(-12345.678); |  | 
|  228   } |  | 
|  229 } {} |  | 
|  230 do_test types-2.2.2 { |  | 
|  231   execsql { |  | 
|  232     SELECT a FROM t2; |  | 
|  233   } |  | 
|  234 } {0.0 12345.678 -12345.678} |  | 
|  235  |  | 
|  236 # Check that all the record sizes are as we expected. |  | 
|  237 ifcapable legacyformat { |  | 
|  238   do_test types-2.2.3 { |  | 
|  239     set root [db eval {select rootpage from sqlite_master where name = 't2'}] |  | 
|  240     record_sizes $root |  | 
|  241   } {3 10 10} |  | 
|  242 } else { |  | 
|  243   do_test types-2.2.3 { |  | 
|  244     set root [db eval {select rootpage from sqlite_master where name = 't2'}] |  | 
|  245     record_sizes $root |  | 
|  246   } {2 10 10} |  | 
|  247 } |  | 
|  248    |  | 
|  249 # Insert a NULL. This should be a two byte record. |  | 
|  250 do_test types-2.3.1 { |  | 
|  251   execsql { |  | 
|  252     CREATE TABLE t3(a nullvalue); |  | 
|  253     INSERT INTO t3 VALUES(NULL); |  | 
|  254   } |  | 
|  255 } {} |  | 
|  256 do_test types-2.3.2 { |  | 
|  257   execsql { |  | 
|  258     SELECT a ISNULL FROM t3; |  | 
|  259   } |  | 
|  260 } {1} |  | 
|  261  |  | 
|  262 # Check that all the record sizes are as we expected. |  | 
|  263 do_test types-2.3.3 { |  | 
|  264   set root [db eval {select rootpage from sqlite_master where name = 't3'}] |  | 
|  265   record_sizes $root |  | 
|  266 } {2} |  | 
|  267  |  | 
|  268 # Insert a couple of strings. |  | 
|  269 do_test types-2.4.1 { |  | 
|  270   set string10 abcdefghij |  | 
|  271   set string500 [string repeat $string10 50] |  | 
|  272   set string500000 [string repeat $string10 50000] |  | 
|  273  |  | 
|  274   execsql " |  | 
|  275     CREATE TABLE t4(a string); |  | 
|  276     INSERT INTO t4 VALUES('$string10'); |  | 
|  277     INSERT INTO t4 VALUES('$string500'); |  | 
|  278     INSERT INTO t4 VALUES('$string500000'); |  | 
|  279   " |  | 
|  280 } {} |  | 
|  281 do_test types-2.4.2 { |  | 
|  282   execsql { |  | 
|  283     SELECT a FROM t4; |  | 
|  284   } |  | 
|  285 } [list $string10 $string500 $string500000] |  | 
|  286  |  | 
|  287 # Check that all the record sizes are as we expected. This is dependant on |  | 
|  288 # the database encoding. |  | 
|  289 if { $sqlite_options(utf16)==0 || [execsql {pragma encoding}] == "UTF-8" } { |  | 
|  290   do_test types-2.4.3 { |  | 
|  291     set root [db eval {select rootpage from sqlite_master where name = 't4'}] |  | 
|  292     record_sizes $root |  | 
|  293   } {12 503 500004} |  | 
|  294 } else { |  | 
|  295   do_test types-2.4.3 { |  | 
|  296     set root [db eval {select rootpage from sqlite_master where name = 't4'}] |  | 
|  297     record_sizes $root |  | 
|  298   } {22 1003 1000004} |  | 
|  299 } |  | 
|  300  |  | 
|  301 do_test types-2.5.1 { |  | 
|  302   execsql { |  | 
|  303     DROP TABLE t1; |  | 
|  304     DROP TABLE t2; |  | 
|  305     DROP TABLE t3; |  | 
|  306     DROP TABLE t4; |  | 
|  307     CREATE TABLE t1(a, b, c); |  | 
|  308   } |  | 
|  309 } {} |  | 
|  310 do_test types-2.5.2 { |  | 
|  311   set string10 abcdefghij |  | 
|  312   set string500 [string repeat $string10 50] |  | 
|  313   set string500000 [string repeat $string10 50000] |  | 
|  314  |  | 
|  315   execsql "INSERT INTO t1 VALUES(NULL, '$string10', 4000);" |  | 
|  316   execsql "INSERT INTO t1 VALUES('$string500', 4000, NULL);" |  | 
|  317   execsql "INSERT INTO t1 VALUES(4000, NULL, '$string500000');" |  | 
|  318 } {} |  | 
|  319 do_test types-2.5.3 { |  | 
|  320   execsql { |  | 
|  321     SELECT * FROM t1; |  | 
|  322   } |  | 
|  323 } [list {} $string10 4000 $string500 4000 {} 4000 {} $string500000] |  | 
|  324  |  | 
|  325 finish_test |  | 
| OLD | NEW |