modernc.org/cc@v1.0.1/v2/testdata/_sqlite/test/with2.test (about)

     1  # 2014 January 11
     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.  The
    12  # focus of this file is testing the WITH clause.
    13  #
    14  
    15  set testdir [file dirname $argv0]
    16  source $testdir/tester.tcl
    17  set ::testprefix with2
    18  
    19  ifcapable {!cte} {
    20    finish_test
    21    return
    22  }
    23  
    24  do_execsql_test 1.0 {
    25    CREATE TABLE t1(a);
    26    INSERT INTO t1 VALUES(1);
    27    INSERT INTO t1 VALUES(2);
    28  }
    29  
    30  do_execsql_test 1.1 {
    31    WITH x1 AS (SELECT * FROM t1)
    32    SELECT sum(a) FROM x1;
    33  } {3}
    34  
    35  do_execsql_test 1.2 {
    36    WITH x1 AS (SELECT * FROM t1)
    37    SELECT (SELECT sum(a) FROM x1);
    38  } {3}
    39  
    40  do_execsql_test 1.3 {
    41    WITH x1 AS (SELECT * FROM t1)
    42    SELECT (SELECT sum(a) FROM x1);
    43  } {3}
    44  
    45  do_execsql_test 1.4 {
    46    CREATE TABLE t2(i);
    47    INSERT INTO t2 VALUES(2);
    48    INSERT INTO t2 VALUES(3);
    49    INSERT INTO t2 VALUES(5);
    50  
    51    WITH x1   AS (SELECT i FROM t2),
    52         i(a) AS (
    53           SELECT min(i)-1 FROM x1 UNION SELECT a+1 FROM i WHERE a<10
    54         )
    55    SELECT a FROM i WHERE a NOT IN x1
    56  } {1 4 6 7 8 9 10}
    57  
    58  do_execsql_test 1.5 {
    59    WITH x1 AS (SELECT a FROM t1),
    60         x2 AS (SELECT i FROM t2),
    61         x3 AS (SELECT * FROM x1, x2 WHERE x1.a IN x2 AND x2.i IN x1)
    62    SELECT * FROM x3 
    63  } {2 2}
    64  
    65  do_execsql_test 1.6 {
    66    CREATE TABLE t3 AS SELECT 3 AS x;
    67    CREATE TABLE t4 AS SELECT 4 AS x;
    68  
    69    WITH x1 AS (SELECT * FROM t3),
    70         x2 AS (
    71           WITH t3 AS (SELECT * FROM t4)
    72           SELECT * FROM x1
    73         )
    74    SELECT * FROM x2;
    75  } {3}
    76  
    77  do_execsql_test 1.7 {
    78    WITH x2 AS (
    79           WITH t3 AS (SELECT * FROM t4)
    80           SELECT * FROM t3
    81         )
    82    SELECT * FROM x2;
    83  } {4}
    84  
    85  do_execsql_test 1.8 {
    86    WITH x2 AS (
    87           WITH t3 AS (SELECT * FROM t4)
    88           SELECT * FROM main.t3
    89         )
    90    SELECT * FROM x2;
    91  } {3}
    92  
    93  do_execsql_test 1.9 {
    94    WITH x1 AS (SELECT * FROM t1)
    95    SELECT (SELECT sum(a) FROM x1), (SELECT max(a) FROM x1);
    96  } {3 2}
    97  
    98  do_execsql_test 1.10 {
    99    WITH x1 AS (SELECT * FROM t1)
   100    SELECT (SELECT sum(a) FROM x1), (SELECT max(a) FROM x1), a FROM x1;
   101  } {3 2 1 3 2 2}
   102  
   103  do_execsql_test 1.11 {
   104    WITH 
   105    i(x) AS ( 
   106      WITH 
   107      j(x) AS ( SELECT * FROM i ), 
   108      i(x) AS ( SELECT * FROM t1 )
   109      SELECT * FROM j
   110    )
   111    SELECT * FROM i;
   112  } {1 2}
   113  
   114  do_execsql_test 1.12 {
   115    WITH r(i) AS (
   116      VALUES('.')
   117      UNION ALL
   118      SELECT i || '.' FROM r, (
   119        SELECT x FROM x INTERSECT SELECT y FROM y
   120      ) WHERE length(i) < 10
   121    ),
   122    x(x) AS ( VALUES(1) UNION ALL VALUES(2) UNION ALL VALUES(3) ),
   123    y(y) AS ( VALUES(2) UNION ALL VALUES(4) UNION ALL VALUES(6) )
   124  
   125    SELECT * FROM r;
   126  } {. .. ... .... ..... ...... ....... ........ ......... ..........}
   127  
   128  do_execsql_test 1.13 {
   129    WITH r(i) AS (
   130      VALUES('.')
   131      UNION ALL
   132      SELECT i || '.' FROM r, ( SELECT x FROM x WHERE x=2 ) WHERE length(i) < 10
   133    ),
   134    x(x) AS ( VALUES(1) UNION ALL VALUES(2) UNION ALL VALUES(3) )
   135  
   136    SELECT * FROM r ORDER BY length(i) DESC;
   137  } {.......... ......... ........ ....... ...... ..... .... ... .. .}
   138  
   139  do_execsql_test 1.14 {
   140    WITH 
   141    t4(x) AS ( 
   142      VALUES(4)
   143      UNION ALL 
   144      SELECT x+1 FROM t4 WHERE x<10
   145    )
   146    SELECT * FROM t4;
   147  } {4 5 6 7 8 9 10}
   148  
   149  do_execsql_test 1.15 {
   150    WITH 
   151    t4(x) AS ( 
   152      VALUES(4)
   153      UNION ALL 
   154      SELECT x+1 FROM main.t4 WHERE x<10
   155    )
   156    SELECT * FROM t4;
   157  } {4 5}
   158  
   159  do_catchsql_test 1.16 {
   160    WITH 
   161    t4(x) AS ( 
   162      VALUES(4)
   163      UNION ALL 
   164      SELECT x+1 FROM t4, main.t4, t4 WHERE x<10
   165    )
   166    SELECT * FROM t4;
   167  } {1 {multiple references to recursive table: t4}}
   168  
   169  
   170  #---------------------------------------------------------------------------
   171  # Check that variables can be used in CTEs.
   172  #
   173  set ::min [expr 3]
   174  set ::max [expr 9]
   175  do_execsql_test 2.1 {
   176    WITH i(x) AS (
   177      VALUES($min) UNION ALL SELECT x+1 FROM i WHERE x < $max
   178    )
   179    SELECT * FROM i;
   180  } {3 4 5 6 7 8 9}
   181  
   182  do_execsql_test 2.2 {
   183    WITH i(x) AS (
   184      VALUES($min) UNION ALL SELECT x+1 FROM i WHERE x < $max
   185    )
   186    SELECT x FROM i JOIN i AS j USING (x);
   187  } {3 4 5 6 7 8 9}
   188  
   189  #---------------------------------------------------------------------------
   190  # Check that circular references are rejected.
   191  #
   192  do_catchsql_test 3.1 {
   193    WITH i(x, y) AS ( VALUES(1, (SELECT x FROM i)) )
   194    SELECT * FROM i;
   195  } {1 {circular reference: i}}
   196  
   197  do_catchsql_test 3.2 {
   198    WITH 
   199    i(x) AS ( SELECT * FROM j ),
   200    j(x) AS ( SELECT * FROM k ),
   201    k(x) AS ( SELECT * FROM i )
   202    SELECT * FROM i;
   203  } {1 {circular reference: i}}
   204  
   205  do_catchsql_test 3.3 {
   206    WITH 
   207    i(x) AS ( SELECT * FROM (SELECT * FROM j) ),
   208    j(x) AS ( SELECT * FROM (SELECT * FROM i) )
   209    SELECT * FROM i;
   210  } {1 {circular reference: i}}
   211  
   212  do_catchsql_test 3.4 {
   213    WITH 
   214    i(x) AS ( SELECT * FROM (SELECT * FROM j) ),
   215    j(x) AS ( SELECT * FROM (SELECT * FROM i) )
   216    SELECT * FROM j;
   217  } {1 {circular reference: j}}
   218  
   219  do_catchsql_test 3.5 {
   220    WITH 
   221    i(x) AS ( 
   222      WITH j(x) AS ( SELECT * FROM i )
   223      SELECT * FROM j
   224    )
   225    SELECT * FROM i;
   226  } {1 {circular reference: i}}
   227  
   228  #---------------------------------------------------------------------------
   229  # Try empty and very long column lists.
   230  #
   231  do_catchsql_test 4.1 {
   232    WITH x() AS ( SELECT 1,2,3 )
   233    SELECT * FROM x;
   234  } {1 {near ")": syntax error}}
   235  
   236  proc genstmt {n} {
   237    for {set i 1} {$i<=$n} {incr i} {
   238      lappend cols "c$i"
   239      lappend vals $i
   240    }
   241    return "
   242      WITH x([join $cols ,]) AS (SELECT [join $vals ,])
   243      SELECT (c$n == $n) FROM x
   244    "
   245  }
   246  
   247  do_execsql_test  4.2 [genstmt 10] 1
   248  do_execsql_test  4.3 [genstmt 100] 1
   249  do_execsql_test  4.4 [genstmt 255] 1
   250  set nLimit [sqlite3_limit db SQLITE_LIMIT_COLUMN -1]
   251  do_execsql_test  4.5 [genstmt [expr $nLimit-1]] 1
   252  do_execsql_test  4.6 [genstmt $nLimit] 1
   253  do_catchsql_test 4.7 [genstmt [expr $nLimit+1]] \
   254    {1 {too many columns in result set}}
   255  
   256  #---------------------------------------------------------------------------
   257  # Check that adding a WITH clause to an INSERT disables the xfer 
   258  # optimization.
   259  #
   260  proc do_xfer_test {tn bXfer sql {res {}}} {
   261    set ::sqlite3_xferopt_count 0
   262    uplevel [list do_test $tn [subst -nocommands {
   263      set dres [db eval {$sql}]
   264      list [set ::sqlite3_xferopt_count] [set dres]
   265    }] [list $bXfer $res]]
   266  }
   267  
   268  do_execsql_test 5.1 {
   269    DROP TABLE IF EXISTS t1;
   270    DROP TABLE IF EXISTS t2;
   271    CREATE TABLE t1(a, b);
   272    CREATE TABLE t2(a, b);
   273  }
   274  
   275  do_xfer_test 5.2 1 { INSERT INTO t1 SELECT * FROM t2 }
   276  do_xfer_test 5.3 0 { INSERT INTO t1 SELECT a, b FROM t2 }
   277  do_xfer_test 5.4 0 { INSERT INTO t1 SELECT b, a FROM t2 }
   278  do_xfer_test 5.5 0 { 
   279    WITH x AS (SELECT a, b FROM t2) INSERT INTO t1 SELECT * FROM x 
   280  }
   281  do_xfer_test 5.6 0 { 
   282    WITH x AS (SELECT a, b FROM t2) INSERT INTO t1 SELECT * FROM t2 
   283  }
   284  do_xfer_test 5.7 0 { 
   285   INSERT INTO t1 WITH x AS ( SELECT * FROM t2 ) SELECT * FROM x
   286  }
   287  do_xfer_test 5.8 0 { 
   288   INSERT INTO t1 WITH x(a,b) AS ( SELECT * FROM t2 ) SELECT * FROM x
   289  }
   290  
   291  #---------------------------------------------------------------------------
   292  # Check that syntax (and other) errors in statements with WITH clauses
   293  # attached to them do not cause problems (e.g. memory leaks).
   294  #
   295  do_execsql_test 6.1 {
   296    DROP TABLE IF EXISTS t1;
   297    DROP TABLE IF EXISTS t2;
   298    CREATE TABLE t1(a, b);
   299    CREATE TABLE t2(a, b);
   300  }
   301  
   302  do_catchsql_test 6.2 {
   303    WITH x AS (SELECT * FROM t1)
   304    INSERT INTO t2 VALUES(1, 2,);
   305  } {1 {near ")": syntax error}}
   306  
   307  do_catchsql_test 6.3 {
   308    WITH x AS (SELECT * FROM t1)
   309    INSERT INTO t2 SELECT a, b, FROM t1;
   310  } {1 {near "FROM": syntax error}}
   311  
   312  do_catchsql_test 6.3 {
   313    WITH x AS (SELECT * FROM t1)
   314    INSERT INTO t2 SELECT a, b FROM abc;
   315  } {1 {no such table: abc}}
   316  
   317  do_catchsql_test 6.4 {
   318    WITH x AS (SELECT * FROM t1)
   319    INSERT INTO t2 SELECT a, b, FROM t1 a a a;
   320  } {1 {near "FROM": syntax error}}
   321  
   322  do_catchsql_test 6.5 {
   323    WITH x AS (SELECT * FROM t1)
   324    DELETE FROM t2 WHERE;
   325  } {1 {near ";": syntax error}}
   326  
   327  do_catchsql_test 6.6 { 
   328    WITH x AS (SELECT * FROM t1) DELETE FROM t2 WHERE
   329  } {/1 {near .* syntax error}/}
   330  
   331  do_catchsql_test 6.7 { 
   332    WITH x AS (SELECT * FROM t1) DELETE FROM t2 WHRE 1;
   333  } {/1 {near .* syntax error}/}
   334  
   335  do_catchsql_test 6.8 { 
   336    WITH x AS (SELECT * FROM t1) UPDATE t2 SET a = 10, b = ;
   337  } {/1 {near .* syntax error}/}
   338  
   339  do_catchsql_test 6.9 { 
   340    WITH x AS (SELECT * FROM t1) UPDATE t2 SET a = 10, b = 1 WHERE a===b;
   341  } {/1 {near .* syntax error}/}
   342  
   343  do_catchsql_test 6.10 {
   344    WITH x(a,b) AS (
   345      SELECT 1, 1
   346      UNION ALL
   347      SELECT a*b,a+b FROM x WHERE c=2
   348    )
   349    SELECT * FROM x
   350  } {1 {no such column: c}}
   351  
   352  #-------------------------------------------------------------------------
   353  # Recursive queries in IN(...) expressions.
   354  #
   355  do_execsql_test 7.1 {
   356    CREATE TABLE t5(x INTEGER);
   357    CREATE TABLE t6(y INTEGER);
   358  
   359    WITH s(x) AS ( VALUES(7) UNION ALL SELECT x+7 FROM s WHERE x<49 )
   360    INSERT INTO t5 
   361    SELECT * FROM s;
   362  
   363    INSERT INTO t6 
   364    WITH s(x) AS ( VALUES(2) UNION ALL SELECT x+2 FROM s WHERE x<49 )
   365    SELECT * FROM s;
   366  }
   367  
   368  do_execsql_test 7.2 {
   369    SELECT * FROM t6 WHERE y IN (SELECT x FROM t5)
   370  } {14 28 42}
   371  
   372  do_execsql_test 7.3 {
   373    WITH ss AS (SELECT x FROM t5)
   374    SELECT * FROM t6 WHERE y IN (SELECT x FROM ss)
   375  } {14 28 42}
   376  
   377  do_execsql_test 7.4 {
   378    WITH ss(x) AS ( VALUES(7) UNION ALL SELECT x+7 FROM ss WHERE x<49 )
   379    SELECT * FROM t6 WHERE y IN (SELECT x FROM ss)
   380  } {14 28 42}
   381  
   382  do_execsql_test 7.5 {
   383    SELECT * FROM t6 WHERE y IN (
   384      WITH ss(x) AS ( VALUES(7) UNION ALL SELECT x+7 FROM ss WHERE x<49 )
   385      SELECT x FROM ss
   386    )
   387  } {14 28 42}
   388  
   389  #-------------------------------------------------------------------------
   390  # At one point the following was causing an assertion failure and a 
   391  # memory leak.
   392  #
   393  do_execsql_test 8.1 {
   394    CREATE TABLE t7(y);
   395    INSERT INTO t7 VALUES(NULL);
   396    CREATE VIEW v AS SELECT * FROM t7 ORDER BY y;
   397  }
   398  
   399  do_execsql_test 8.2 {
   400    WITH q(a) AS (
   401      SELECT 1
   402      UNION 
   403      SELECT a+1 FROM q, v WHERE a<5
   404    )
   405    SELECT * FROM q;
   406  } {1 2 3 4 5}
   407  
   408  do_execsql_test 8.3 {
   409    WITH q(a) AS (
   410      SELECT 1
   411      UNION ALL
   412      SELECT a+1 FROM q, v WHERE a<5
   413    )
   414    SELECT * FROM q;
   415  } {1 2 3 4 5}
   416  
   417  
   418  finish_test