OLD | NEW |
(Empty) | |
| 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]] {1 {too many columns in index}} |
| 254 |
| 255 #--------------------------------------------------------------------------- |
| 256 # Check that adding a WITH clause to an INSERT disables the xfer |
| 257 # optimization. |
| 258 # |
| 259 proc do_xfer_test {tn bXfer sql {res {}}} { |
| 260 set ::sqlite3_xferopt_count 0 |
| 261 uplevel [list do_test $tn [subst -nocommands { |
| 262 set dres [db eval {$sql}] |
| 263 list [set ::sqlite3_xferopt_count] [set dres] |
| 264 }] [list $bXfer $res]] |
| 265 } |
| 266 |
| 267 do_execsql_test 5.1 { |
| 268 DROP TABLE IF EXISTS t1; |
| 269 DROP TABLE IF EXISTS t2; |
| 270 CREATE TABLE t1(a, b); |
| 271 CREATE TABLE t2(a, b); |
| 272 } |
| 273 |
| 274 do_xfer_test 5.2 1 { INSERT INTO t1 SELECT * FROM t2 } |
| 275 do_xfer_test 5.3 0 { INSERT INTO t1 SELECT a, b FROM t2 } |
| 276 do_xfer_test 5.4 0 { INSERT INTO t1 SELECT b, a FROM t2 } |
| 277 do_xfer_test 5.5 0 { |
| 278 WITH x AS (SELECT a, b FROM t2) INSERT INTO t1 SELECT * FROM x |
| 279 } |
| 280 do_xfer_test 5.6 0 { |
| 281 WITH x AS (SELECT a, b FROM t2) INSERT INTO t1 SELECT * FROM t2 |
| 282 } |
| 283 do_xfer_test 5.7 0 { |
| 284 INSERT INTO t1 WITH x AS ( SELECT * FROM t2 ) SELECT * FROM x |
| 285 } |
| 286 do_xfer_test 5.8 0 { |
| 287 INSERT INTO t1 WITH x(a,b) AS ( SELECT * FROM t2 ) SELECT * FROM x |
| 288 } |
| 289 |
| 290 #--------------------------------------------------------------------------- |
| 291 # Check that syntax (and other) errors in statements with WITH clauses |
| 292 # attached to them do not cause problems (e.g. memory leaks). |
| 293 # |
| 294 do_execsql_test 6.1 { |
| 295 DROP TABLE IF EXISTS t1; |
| 296 DROP TABLE IF EXISTS t2; |
| 297 CREATE TABLE t1(a, b); |
| 298 CREATE TABLE t2(a, b); |
| 299 } |
| 300 |
| 301 do_catchsql_test 6.2 { |
| 302 WITH x AS (SELECT * FROM t1) |
| 303 INSERT INTO t2 VALUES(1, 2,); |
| 304 } {1 {near ")": syntax error}} |
| 305 |
| 306 do_catchsql_test 6.3 { |
| 307 WITH x AS (SELECT * FROM t1) |
| 308 INSERT INTO t2 SELECT a, b, FROM t1; |
| 309 } {1 {near "FROM": syntax error}} |
| 310 |
| 311 do_catchsql_test 6.3 { |
| 312 WITH x AS (SELECT * FROM t1) |
| 313 INSERT INTO t2 SELECT a, b FROM abc; |
| 314 } {1 {no such table: abc}} |
| 315 |
| 316 do_catchsql_test 6.4 { |
| 317 WITH x AS (SELECT * FROM t1) |
| 318 INSERT INTO t2 SELECT a, b, FROM t1 a a a; |
| 319 } {1 {near "FROM": syntax error}} |
| 320 |
| 321 do_catchsql_test 6.5 { |
| 322 WITH x AS (SELECT * FROM t1) |
| 323 DELETE FROM t2 WHERE; |
| 324 } {1 {near ";": syntax error}} |
| 325 |
| 326 do_catchsql_test 6.6 { |
| 327 WITH x AS (SELECT * FROM t1) DELETE FROM t2 WHERE |
| 328 } {/1 {near .* syntax error}/} |
| 329 |
| 330 do_catchsql_test 6.7 { |
| 331 WITH x AS (SELECT * FROM t1) DELETE FROM t2 WHRE 1; |
| 332 } {/1 {near .* syntax error}/} |
| 333 |
| 334 do_catchsql_test 6.8 { |
| 335 WITH x AS (SELECT * FROM t1) UPDATE t2 SET a = 10, b = ; |
| 336 } {/1 {near .* syntax error}/} |
| 337 |
| 338 do_catchsql_test 6.9 { |
| 339 WITH x AS (SELECT * FROM t1) UPDATE t2 SET a = 10, b = 1 WHERE a===b; |
| 340 } {/1 {near .* syntax error}/} |
| 341 |
| 342 do_catchsql_test 6.10 { |
| 343 WITH x(a,b) AS ( |
| 344 SELECT 1, 1 |
| 345 UNION ALL |
| 346 SELECT a*b,a+b FROM x WHERE c=2 |
| 347 ) |
| 348 SELECT * FROM x |
| 349 } {1 {no such column: c}} |
| 350 |
| 351 #------------------------------------------------------------------------- |
| 352 # Recursive queries in IN(...) expressions. |
| 353 # |
| 354 do_execsql_test 7.1 { |
| 355 CREATE TABLE t5(x INTEGER); |
| 356 CREATE TABLE t6(y INTEGER); |
| 357 |
| 358 WITH s(x) AS ( VALUES(7) UNION ALL SELECT x+7 FROM s WHERE x<49 ) |
| 359 INSERT INTO t5 |
| 360 SELECT * FROM s; |
| 361 |
| 362 INSERT INTO t6 |
| 363 WITH s(x) AS ( VALUES(2) UNION ALL SELECT x+2 FROM s WHERE x<49 ) |
| 364 SELECT * FROM s; |
| 365 } |
| 366 |
| 367 do_execsql_test 7.2 { |
| 368 SELECT * FROM t6 WHERE y IN (SELECT x FROM t5) |
| 369 } {14 28 42} |
| 370 |
| 371 do_execsql_test 7.3 { |
| 372 WITH ss AS (SELECT x FROM t5) |
| 373 SELECT * FROM t6 WHERE y IN (SELECT x FROM ss) |
| 374 } {14 28 42} |
| 375 |
| 376 do_execsql_test 7.4 { |
| 377 WITH ss(x) AS ( VALUES(7) UNION ALL SELECT x+7 FROM ss WHERE x<49 ) |
| 378 SELECT * FROM t6 WHERE y IN (SELECT x FROM ss) |
| 379 } {14 28 42} |
| 380 |
| 381 do_execsql_test 7.5 { |
| 382 SELECT * FROM t6 WHERE y IN ( |
| 383 WITH ss(x) AS ( VALUES(7) UNION ALL SELECT x+7 FROM ss WHERE x<49 ) |
| 384 SELECT x FROM ss |
| 385 ) |
| 386 } {14 28 42} |
| 387 |
| 388 #------------------------------------------------------------------------- |
| 389 # At one point the following was causing an assertion failure and a |
| 390 # memory leak. |
| 391 # |
| 392 do_execsql_test 8.1 { |
| 393 CREATE TABLE t7(y); |
| 394 INSERT INTO t7 VALUES(NULL); |
| 395 CREATE VIEW v AS SELECT * FROM t7 ORDER BY y; |
| 396 } |
| 397 |
| 398 do_execsql_test 8.2 { |
| 399 WITH q(a) AS ( |
| 400 SELECT 1 |
| 401 UNION |
| 402 SELECT a+1 FROM q, v WHERE a<5 |
| 403 ) |
| 404 SELECT * FROM q; |
| 405 } {1 2 3 4 5} |
| 406 |
| 407 do_execsql_test 8.3 { |
| 408 WITH q(a) AS ( |
| 409 SELECT 1 |
| 410 UNION ALL |
| 411 SELECT a+1 FROM q, v WHERE a<5 |
| 412 ) |
| 413 SELECT * FROM q; |
| 414 } {1 2 3 4 5} |
| 415 |
| 416 |
| 417 finish_test |
| 418 |
OLD | NEW |