Home | History | Annotate | Download | only in test
      1 # 2003 June 21
      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.
     12 #
     13 # This file implements tests for miscellanous features that were
     14 # left out of other test files.
     15 #
     16 # $Id: misc2.test,v 1.28 2007/09/12 17:01:45 danielk1977 Exp $
     17 
     18 set testdir [file dirname $argv0]
     19 source $testdir/tester.tcl
     20 
     21 # The tests in this file were written before SQLite supported recursive
     22 # trigger invocation, and some tests depend on that to pass. So disable
     23 # recursive triggers for this file.
     24 catchsql { pragma recursive_triggers = off } 
     25 
     26 ifcapable {trigger} {
     27 # Test for ticket #360
     28 #
     29 do_test misc2-1.1 {
     30   catchsql {
     31     CREATE TABLE FOO(bar integer);
     32     CREATE TRIGGER foo_insert BEFORE INSERT ON foo BEGIN
     33       SELECT CASE WHEN (NOT new.bar BETWEEN 0 AND 20)
     34              THEN raise(rollback, 'aiieee') END;
     35     END;
     36     INSERT INTO foo(bar) VALUES (1);
     37   }
     38 } {0 {}}
     39 do_test misc2-1.2 {
     40   catchsql {
     41     INSERT INTO foo(bar) VALUES (111);
     42   }
     43 } {1 aiieee}
     44 } ;# endif trigger
     45 
     46 # Make sure ROWID works on a view and a subquery.  Ticket #364
     47 #
     48 do_test misc2-2.1 {
     49   execsql {
     50     CREATE TABLE t1(a,b,c);
     51     INSERT INTO t1 VALUES(1,2,3);
     52     CREATE TABLE t2(a,b,c);
     53     INSERT INTO t2 VALUES(7,8,9);
     54   }
     55 } {}
     56 ifcapable subquery {
     57   do_test misc2-2.2 {
     58     execsql {
     59       SELECT rowid, * FROM (SELECT * FROM t1, t2);
     60     }
     61   } {{} 1 2 3 7 8 9}
     62 }
     63 ifcapable view {
     64   do_test misc2-2.3 {
     65     execsql {
     66       CREATE VIEW v1 AS SELECT * FROM t1, t2;
     67       SELECT rowid, * FROM v1;
     68     }
     69   } {{} 1 2 3 7 8 9}
     70 } ;# ifcapable view
     71 
     72 # Ticket #2002 and #1952.
     73 ifcapable subquery {
     74   do_test misc2-2.4 {
     75     execsql2 {
     76       SELECT * FROM (SELECT a, b AS 'a', c AS 'a', 4 AS 'a' FROM t1)
     77     }
     78   } {a 1 a:1 2 a:2 3 a:3 4}
     79 }
     80 
     81 # Check name binding precedence.  Ticket #387
     82 #
     83 do_test misc2-3.1 {
     84   catchsql {
     85     SELECT t1.b+t2.b AS a, t1.a, t2.a FROM t1, t2 WHERE a==10
     86   }
     87 } {1 {ambiguous column name: a}}
     88 
     89 # Make sure 32-bit integer overflow is handled properly in queries.
     90 # ticket #408
     91 #
     92 do_test misc2-4.1 {
     93   execsql {
     94     INSERT INTO t1 VALUES(4000000000,'a','b');
     95     SELECT a FROM t1 WHERE a>1;
     96   }
     97 } {4000000000}
     98 do_test misc2-4.2 {
     99   execsql {
    100     INSERT INTO t1 VALUES(2147483648,'b2','c2');
    101     INSERT INTO t1 VALUES(2147483647,'b3','c3');
    102     SELECT a FROM t1 WHERE a>2147483647;
    103   }
    104 } {4000000000 2147483648}
    105 do_test misc2-4.3 {
    106   execsql {
    107     SELECT a FROM t1 WHERE a<2147483648;
    108   }
    109 } {1 2147483647}
    110 do_test misc2-4.4 {
    111   execsql {
    112     SELECT a FROM t1 WHERE a<=2147483648;
    113   }
    114 } {1 2147483648 2147483647}
    115 do_test misc2-4.5 {
    116   execsql {
    117     SELECT a FROM t1 WHERE a<10000000000;
    118   }
    119 } {1 4000000000 2147483648 2147483647}
    120 do_test misc2-4.6 {
    121   execsql {
    122     SELECT a FROM t1 WHERE a<1000000000000 ORDER BY 1;
    123   }
    124 } {1 2147483647 2147483648 4000000000}
    125 
    126 # There were some issues with expanding a SrcList object using a call
    127 # to sqliteSrcListAppend() if the SrcList had previously been duplicated
    128 # using a call to sqliteSrcListDup().  Ticket #416.  The following test
    129 # makes sure the problem has been fixed.
    130 #
    131 ifcapable view {
    132 do_test misc2-5.1 {
    133   execsql {
    134     CREATE TABLE x(a,b);
    135     CREATE VIEW y AS 
    136       SELECT x1.b AS p, x2.b AS q FROM x AS x1, x AS x2 WHERE x1.a=x2.a;
    137     CREATE VIEW z AS
    138       SELECT y1.p, y2.p FROM y AS y1, y AS y2 WHERE y1.q=y2.q;
    139     SELECT * from z;
    140   }
    141 } {}
    142 }
    143 
    144 # Make sure we can open a database with an empty filename.  What this
    145 # does is store the database in a temporary file that is deleted when
    146 # the database is closed.  Ticket #432.
    147 #
    148 do_test misc2-6.1 {
    149   db close
    150   sqlite3 db {}
    151   execsql {
    152     CREATE TABLE t1(a,b);
    153     INSERT INTO t1 VALUES(1,2);
    154     SELECT * FROM t1;
    155   }
    156 } {1 2}
    157 
    158 # Make sure we get an error message (not a segfault) on an attempt to
    159 # update a table from within the callback of a select on that same
    160 # table.
    161 #
    162 # 2006-08-16:  This has changed.  It is now permitted to update
    163 # the table being SELECTed from within the callback of the query.
    164 #
    165 ifcapable tclvar {
    166   do_test misc2-7.1 {
    167     db close
    168     file delete -force test.db
    169     sqlite3 db test.db
    170     execsql {
    171       CREATE TABLE t1(x);
    172       INSERT INTO t1 VALUES(1);
    173       INSERT INTO t1 VALUES(2);
    174       INSERT INTO t1 VALUES(3);
    175       SELECT * FROM t1;
    176     }
    177   } {1 2 3}
    178   do_test misc2-7.2 {
    179     set rc [catch {
    180       db eval {SELECT rowid FROM t1} {} {
    181         db eval "DELETE FROM t1 WHERE rowid=$rowid"
    182       }
    183     } msg]
    184     lappend rc $msg
    185   } {0 {}}
    186   do_test misc2-7.3 {
    187     execsql {SELECT * FROM t1}
    188   } {}
    189   do_test misc2-7.4 {
    190     execsql {
    191       DELETE FROM t1;
    192       INSERT INTO t1 VALUES(1);
    193       INSERT INTO t1 VALUES(2);
    194       INSERT INTO t1 VALUES(3);
    195       INSERT INTO t1 VALUES(4);
    196     }
    197     db eval {SELECT rowid, x FROM t1} {
    198       if {$x & 1} {
    199         db eval {DELETE FROM t1 WHERE rowid=$rowid}
    200       }
    201     }
    202     execsql {SELECT * FROM t1}
    203   } {2 4}
    204   do_test misc2-7.5 {
    205     execsql {
    206       DELETE FROM t1;
    207       INSERT INTO t1 VALUES(1);
    208       INSERT INTO t1 VALUES(2);
    209       INSERT INTO t1 VALUES(3);
    210       INSERT INTO t1 VALUES(4);
    211     }
    212     db eval {SELECT rowid, x FROM t1} {
    213       if {$x & 1} {
    214         db eval {DELETE FROM t1 WHERE rowid=$rowid+1}
    215       }
    216     }
    217     execsql {SELECT * FROM t1}
    218   } {1 3}
    219   do_test misc2-7.6 {
    220     execsql {
    221       DELETE FROM t1;
    222       INSERT INTO t1 VALUES(1);
    223       INSERT INTO t1 VALUES(2);
    224       INSERT INTO t1 VALUES(3);
    225       INSERT INTO t1 VALUES(4);
    226     }
    227     db eval {SELECT rowid, x FROM t1} {
    228       if {$x & 1} {
    229         db eval {DELETE FROM t1}
    230       }
    231     }
    232     execsql {SELECT * FROM t1}
    233   } {}
    234   do_test misc2-7.7 {
    235     execsql {
    236       DELETE FROM t1;
    237       INSERT INTO t1 VALUES(1);
    238       INSERT INTO t1 VALUES(2);
    239       INSERT INTO t1 VALUES(3);
    240       INSERT INTO t1 VALUES(4);
    241     }
    242     db eval {SELECT rowid, x FROM t1} {
    243       if {$x & 1} {
    244         db eval {UPDATE t1 SET x=x+100 WHERE rowid=$rowid}
    245       }
    246     }
    247     execsql {SELECT * FROM t1}
    248   } {101 2 103 4}
    249   do_test misc2-7.8 {
    250     execsql {
    251       DELETE FROM t1;
    252       INSERT INTO t1 VALUES(1);
    253     }
    254     db eval {SELECT rowid, x FROM t1} {
    255       if {$x<10} {
    256         db eval {INSERT INTO t1 VALUES($x+1)}
    257       }
    258     }
    259     execsql {SELECT * FROM t1}
    260   } {1 2 3 4 5 6 7 8 9 10}
    261   
    262   # Repeat the tests 7.1 through 7.8 about but this time do the SELECTs
    263   # in reverse order so that we exercise the sqlite3BtreePrev() routine
    264   # instead of sqlite3BtreeNext()
    265   #
    266   do_test misc2-7.11 {
    267     db close
    268     file delete -force test.db
    269     sqlite3 db test.db
    270     execsql {
    271       CREATE TABLE t1(x);
    272       INSERT INTO t1 VALUES(1);
    273       INSERT INTO t1 VALUES(2);
    274       INSERT INTO t1 VALUES(3);
    275       SELECT * FROM t1;
    276     }
    277   } {1 2 3}
    278   do_test misc2-7.12 {
    279     set rc [catch {
    280       db eval {SELECT rowid FROM t1 ORDER BY rowid DESC} {} {
    281         db eval "DELETE FROM t1 WHERE rowid=$rowid"
    282       }
    283     } msg]
    284     lappend rc $msg
    285   } {0 {}}
    286   do_test misc2-7.13 {
    287     execsql {SELECT * FROM t1}
    288   } {}
    289   do_test misc2-7.14 {
    290     execsql {
    291       DELETE FROM t1;
    292       INSERT INTO t1 VALUES(1);
    293       INSERT INTO t1 VALUES(2);
    294       INSERT INTO t1 VALUES(3);
    295       INSERT INTO t1 VALUES(4);
    296     }
    297     db eval {SELECT rowid, x FROM t1 ORDER BY rowid DESC} {
    298       if {$x & 1} {
    299         db eval {DELETE FROM t1 WHERE rowid=$rowid}
    300       }
    301     }
    302     execsql {SELECT * FROM t1}
    303   } {2 4}
    304   do_test misc2-7.15 {
    305     execsql {
    306       DELETE FROM t1;
    307       INSERT INTO t1 VALUES(1);
    308       INSERT INTO t1 VALUES(2);
    309       INSERT INTO t1 VALUES(3);
    310       INSERT INTO t1 VALUES(4);
    311     }
    312     db eval {SELECT rowid, x FROM t1} {
    313       if {$x & 1} {
    314         db eval {DELETE FROM t1 WHERE rowid=$rowid+1}
    315       }
    316     }
    317     execsql {SELECT * FROM t1}
    318   } {1 3}
    319   do_test misc2-7.16 {
    320     execsql {
    321       DELETE FROM t1;
    322       INSERT INTO t1 VALUES(1);
    323       INSERT INTO t1 VALUES(2);
    324       INSERT INTO t1 VALUES(3);
    325       INSERT INTO t1 VALUES(4);
    326     }
    327     db eval {SELECT rowid, x FROM t1 ORDER BY rowid DESC} {
    328       if {$x & 1} {
    329         db eval {DELETE FROM t1}
    330       }
    331     }
    332     execsql {SELECT * FROM t1}
    333   } {}
    334   do_test misc2-7.17 {
    335     execsql {
    336       DELETE FROM t1;
    337       INSERT INTO t1 VALUES(1);
    338       INSERT INTO t1 VALUES(2);
    339       INSERT INTO t1 VALUES(3);
    340       INSERT INTO t1 VALUES(4);
    341     }
    342     db eval {SELECT rowid, x FROM t1 ORDER BY rowid DESC} {
    343       if {$x & 1} {
    344         db eval {UPDATE t1 SET x=x+100 WHERE rowid=$rowid}
    345       }
    346     }
    347     execsql {SELECT * FROM t1}
    348   } {101 2 103 4}
    349   do_test misc2-7.18 {
    350     execsql {
    351       DELETE FROM t1;
    352       INSERT INTO t1(rowid,x) VALUES(10,10);
    353     }
    354     db eval {SELECT rowid, x FROM t1 ORDER BY rowid DESC} {
    355       if {$x>1} {
    356         db eval {INSERT INTO t1(rowid,x) VALUES($x-1,$x-1)}
    357       }
    358     }
    359     execsql {SELECT * FROM t1}
    360   } {1 2 3 4 5 6 7 8 9 10}
    361 }
    362 
    363 db close
    364 file delete -force test.db
    365 sqlite3 db test.db
    366 catchsql { pragma recursive_triggers = off } 
    367 
    368 # Ticket #453.  If the SQL ended with "-", the tokenizer was calling that
    369 # an incomplete token, which caused problem.  The solution was to just call
    370 # it a minus sign.
    371 #
    372 do_test misc2-8.1 {
    373   catchsql {-}
    374 } {1 {near "-": syntax error}}
    375 
    376 # Ticket #513.  Make sure the VDBE stack does not grow on a 3-way join.
    377 #
    378 ifcapable tempdb {
    379   do_test misc2-9.1 {
    380     execsql {
    381       BEGIN;
    382       CREATE TABLE counts(n INTEGER PRIMARY KEY);
    383       INSERT INTO counts VALUES(0);
    384       INSERT INTO counts VALUES(1);
    385       INSERT INTO counts SELECT n+2 FROM counts;
    386       INSERT INTO counts SELECT n+4 FROM counts;
    387       INSERT INTO counts SELECT n+8 FROM counts;
    388       COMMIT;
    389   
    390       CREATE TEMP TABLE x AS
    391       SELECT dim1.n, dim2.n, dim3.n
    392       FROM counts AS dim1, counts AS dim2, counts AS dim3
    393       WHERE dim1.n<10 AND dim2.n<10 AND dim3.n<10;
    394   
    395       SELECT count(*) FROM x;
    396     }
    397   } {1000}
    398   do_test misc2-9.2 {
    399     execsql {
    400       DROP TABLE x;
    401       CREATE TEMP TABLE x AS
    402       SELECT dim1.n, dim2.n, dim3.n
    403       FROM counts AS dim1, counts AS dim2, counts AS dim3
    404       WHERE dim1.n>=6 AND dim2.n>=6 AND dim3.n>=6;
    405   
    406       SELECT count(*) FROM x;
    407     }
    408   } {1000}
    409   do_test misc2-9.3 {
    410     execsql {
    411       DROP TABLE x;
    412       CREATE TEMP TABLE x AS
    413       SELECT dim1.n, dim2.n, dim3.n, dim4.n
    414       FROM counts AS dim1, counts AS dim2, counts AS dim3, counts AS dim4
    415       WHERE dim1.n<5 AND dim2.n<5 AND dim3.n<5 AND dim4.n<5;
    416   
    417       SELECT count(*) FROM x;
    418     }
    419   } [expr 5*5*5*5]
    420 }
    421 
    422 # Ticket #1229.  Sometimes when a "NEW.X" appears in a SELECT without
    423 # a FROM clause deep within a trigger, the code generator is unable to
    424 # trace the NEW.X back to an original table and thus figure out its
    425 # declared datatype.
    426 #
    427 # The SQL code below was causing a segfault.
    428 #
    429 ifcapable subquery&&trigger {
    430   do_test misc2-10.1 {
    431     execsql {
    432       CREATE TABLE t1229(x);
    433       CREATE TRIGGER r1229 BEFORE INSERT ON t1229 BEGIN
    434         INSERT INTO t1229 SELECT y FROM (SELECT new.x y);
    435       END;
    436       INSERT INTO t1229 VALUES(1);
    437     }
    438   } {}
    439 }
    440 
    441 finish_test
    442