os/persistentdata/persistentstorage/sqlite3api/TEST/TclScript/limit.test
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/persistentdata/persistentstorage/sqlite3api/TEST/TclScript/limit.test	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,472 @@
     1.4 +# 2001 November 6
     1.5 +#
     1.6 +# The author disclaims copyright to this source code.  In place of
     1.7 +# a legal notice, here is a blessing:
     1.8 +#
     1.9 +#    May you do good and not evil.
    1.10 +#    May you find forgiveness for yourself and forgive others.
    1.11 +#    May you share freely, never taking more than you give.
    1.12 +#
    1.13 +#***********************************************************************
    1.14 +# This file implements regression tests for SQLite library.  The
    1.15 +# focus of this file is testing the LIMIT ... OFFSET ... clause
    1.16 +#  of SELECT statements.
    1.17 +#
    1.18 +# $Id: limit.test,v 1.32 2008/08/02 03:50:39 drh Exp $
    1.19 +
    1.20 +set testdir [file dirname $argv0]
    1.21 +source $testdir/tester.tcl
    1.22 +
    1.23 +# Build some test data
    1.24 +#
    1.25 +execsql {
    1.26 +  CREATE TABLE t1(x int, y int);
    1.27 +  BEGIN;
    1.28 +}
    1.29 +for {set i 1} {$i<=32} {incr i} {
    1.30 +  for {set j 0} {(1<<$j)<$i} {incr j} {}
    1.31 +  execsql "INSERT INTO t1 VALUES([expr {32-$i}],[expr {10-$j}])"
    1.32 +}
    1.33 +execsql {
    1.34 +  COMMIT;
    1.35 +}
    1.36 +
    1.37 +do_test limit-1.0 {
    1.38 +  execsql {SELECT count(*) FROM t1}
    1.39 +} {32}
    1.40 +do_test limit-1.1 {
    1.41 +  execsql {SELECT count(*) FROM t1 LIMIT  5}
    1.42 +} {32}
    1.43 +do_test limit-1.2.1 {
    1.44 +  execsql {SELECT x FROM t1 ORDER BY x LIMIT 5}
    1.45 +} {0 1 2 3 4}
    1.46 +do_test limit-1.2.2 {
    1.47 +  execsql {SELECT x FROM t1 ORDER BY x LIMIT 5 OFFSET 2}
    1.48 +} {2 3 4 5 6}
    1.49 +do_test limit-1.2.3 {
    1.50 +  execsql {SELECT x FROM t1 ORDER BY x+1 LIMIT 5 OFFSET -2}
    1.51 +} {0 1 2 3 4}
    1.52 +do_test limit-1.2.4 {
    1.53 +  execsql {SELECT x FROM t1 ORDER BY x+1 LIMIT 2, -5}
    1.54 +} {2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31}
    1.55 +do_test limit-1.2.5 {
    1.56 +  execsql {SELECT x FROM t1 ORDER BY x+1 LIMIT -2, 5}
    1.57 +} {0 1 2 3 4}
    1.58 +do_test limit-1.2.6 {
    1.59 +  execsql {SELECT x FROM t1 ORDER BY x+1 LIMIT -2, -5}
    1.60 +} {0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31}
    1.61 +do_test limit-1.2.7 {
    1.62 +  execsql {SELECT x FROM t1 ORDER BY x LIMIT 2, 5}
    1.63 +} {2 3 4 5 6}
    1.64 +do_test limit-1.3 {
    1.65 +  execsql {SELECT x FROM t1 ORDER BY x LIMIT 5 OFFSET 5}
    1.66 +} {5 6 7 8 9}
    1.67 +do_test limit-1.4.1 {
    1.68 +  execsql {SELECT x FROM t1 ORDER BY x LIMIT 50 OFFSET 30}
    1.69 +} {30 31}
    1.70 +do_test limit-1.4.2 {
    1.71 +  execsql {SELECT x FROM t1 ORDER BY x LIMIT 30, 50}
    1.72 +} {30 31}
    1.73 +do_test limit-1.5 {
    1.74 +  execsql {SELECT x FROM t1 ORDER BY x LIMIT 50 OFFSET 50}
    1.75 +} {}
    1.76 +do_test limit-1.6 {
    1.77 +  execsql {SELECT * FROM t1 AS a, t1 AS b ORDER BY a.x, b.x LIMIT 5}
    1.78 +} {0 5 0 5 0 5 1 5 0 5 2 5 0 5 3 5 0 5 4 5}
    1.79 +do_test limit-1.7 {
    1.80 +  execsql {SELECT * FROM t1 AS a, t1 AS b ORDER BY a.x, b.x LIMIT 5 OFFSET 32}
    1.81 +} {1 5 0 5 1 5 1 5 1 5 2 5 1 5 3 5 1 5 4 5}
    1.82 +
    1.83 +ifcapable {view && subquery} {
    1.84 +  do_test limit-2.1 {
    1.85 +    execsql {
    1.86 +      CREATE VIEW v1 AS SELECT * FROM t1 LIMIT 2;
    1.87 +      SELECT count(*) FROM (SELECT * FROM v1);
    1.88 +    }
    1.89 +  } 2
    1.90 +} ;# ifcapable view
    1.91 +do_test limit-2.2 {
    1.92 +  execsql {
    1.93 +    CREATE TABLE t2 AS SELECT * FROM t1 LIMIT 2;
    1.94 +    SELECT count(*) FROM t2;
    1.95 +  }
    1.96 +} 2
    1.97 +ifcapable subquery {
    1.98 +  do_test limit-2.3 {
    1.99 +    execsql {
   1.100 +      SELECT count(*) FROM t1 WHERE rowid IN (SELECT rowid FROM t1 LIMIT 2);
   1.101 +    }
   1.102 +  } 2
   1.103 +}
   1.104 +
   1.105 +ifcapable subquery {
   1.106 +  do_test limit-3.1 {
   1.107 +    execsql {
   1.108 +      SELECT z FROM (SELECT y*10+x AS z FROM t1 ORDER BY x LIMIT 10)
   1.109 +      ORDER BY z LIMIT 5;
   1.110 +    }
   1.111 +  } {50 51 52 53 54}
   1.112 +}
   1.113 +
   1.114 +do_test limit-4.1 {
   1.115 +  ifcapable subquery { 
   1.116 +    execsql {
   1.117 +      BEGIN;
   1.118 +      CREATE TABLE t3(x);
   1.119 +      INSERT INTO t3 SELECT x FROM t1 ORDER BY x LIMIT 10 OFFSET 1;
   1.120 +      INSERT INTO t3 SELECT x+(SELECT max(x) FROM t3) FROM t3;
   1.121 +      INSERT INTO t3 SELECT x+(SELECT max(x) FROM t3) FROM t3;
   1.122 +      INSERT INTO t3 SELECT x+(SELECT max(x) FROM t3) FROM t3;
   1.123 +      INSERT INTO t3 SELECT x+(SELECT max(x) FROM t3) FROM t3;
   1.124 +      INSERT INTO t3 SELECT x+(SELECT max(x) FROM t3) FROM t3;
   1.125 +      INSERT INTO t3 SELECT x+(SELECT max(x) FROM t3) FROM t3;
   1.126 +      INSERT INTO t3 SELECT x+(SELECT max(x) FROM t3) FROM t3;
   1.127 +      INSERT INTO t3 SELECT x+(SELECT max(x) FROM t3) FROM t3;
   1.128 +      INSERT INTO t3 SELECT x+(SELECT max(x) FROM t3) FROM t3;
   1.129 +      INSERT INTO t3 SELECT x+(SELECT max(x) FROM t3) FROM t3;
   1.130 +      END;
   1.131 +      SELECT count(*) FROM t3;
   1.132 +    }
   1.133 +  } else {
   1.134 +    execsql {
   1.135 +      BEGIN;
   1.136 +      CREATE TABLE t3(x);
   1.137 +      INSERT INTO t3 SELECT x FROM t1 ORDER BY x LIMIT 10 OFFSET 1;
   1.138 +    }
   1.139 +    for {set i 0} {$i<10} {incr i} {
   1.140 +      set max_x_t3 [execsql {SELECT max(x) FROM t3}]
   1.141 +      execsql "INSERT INTO t3 SELECT x+$max_x_t3 FROM t3;"
   1.142 +    }
   1.143 +    execsql {
   1.144 +      END;
   1.145 +      SELECT count(*) FROM t3;
   1.146 +    }
   1.147 +  }
   1.148 +} {10240}
   1.149 +do_test limit-4.2 {
   1.150 +  execsql {
   1.151 +    SELECT x FROM t3 LIMIT 2 OFFSET 10000
   1.152 +  }
   1.153 +} {10001 10002}
   1.154 +do_test limit-4.3 {
   1.155 +  execsql {
   1.156 +    CREATE TABLE t4 AS SELECT x,
   1.157 +       'abcdefghijklmnopqrstuvwyxz ABCDEFGHIJKLMNOPQRSTUVWYXZ' || x ||
   1.158 +       'abcdefghijklmnopqrstuvwyxz ABCDEFGHIJKLMNOPQRSTUVWYXZ' || x ||
   1.159 +       'abcdefghijklmnopqrstuvwyxz ABCDEFGHIJKLMNOPQRSTUVWYXZ' || x ||
   1.160 +       'abcdefghijklmnopqrstuvwyxz ABCDEFGHIJKLMNOPQRSTUVWYXZ' || x ||
   1.161 +       'abcdefghijklmnopqrstuvwyxz ABCDEFGHIJKLMNOPQRSTUVWYXZ' || x AS y
   1.162 +    FROM t3 LIMIT 1000;
   1.163 +    SELECT x FROM t4 ORDER BY y DESC LIMIT 1 OFFSET 999;
   1.164 +  }
   1.165 +} {1000}
   1.166 +
   1.167 +do_test limit-5.1 {
   1.168 +  execsql {
   1.169 +    CREATE TABLE t5(x,y);
   1.170 +    INSERT INTO t5 SELECT x-y, x+y FROM t1 WHERE x BETWEEN 10 AND 15
   1.171 +        ORDER BY x LIMIT 2;
   1.172 +    SELECT * FROM t5 ORDER BY x;
   1.173 +  }
   1.174 +} {5 15 6 16}
   1.175 +do_test limit-5.2 {
   1.176 +  execsql {
   1.177 +    DELETE FROM t5;
   1.178 +    INSERT INTO t5 SELECT x-y, x+y FROM t1 WHERE x BETWEEN 10 AND 15
   1.179 +        ORDER BY x DESC LIMIT 2;
   1.180 +    SELECT * FROM t5 ORDER BY x;
   1.181 +  }
   1.182 +} {9 19 10 20}
   1.183 +do_test limit-5.3 {
   1.184 +  execsql {
   1.185 +    DELETE FROM t5;
   1.186 +    INSERT INTO t5 SELECT x-y, x+y FROM t1 WHERE x ORDER BY x DESC LIMIT 31;
   1.187 +    SELECT * FROM t5 ORDER BY x LIMIT 2;
   1.188 +  }
   1.189 +} {-4 6 -3 7}
   1.190 +do_test limit-5.4 {
   1.191 +  execsql {
   1.192 +    SELECT * FROM t5 ORDER BY x DESC, y DESC LIMIT 2;
   1.193 +  }
   1.194 +} {21 41 21 39}
   1.195 +do_test limit-5.5 {
   1.196 +  execsql {
   1.197 +    DELETE FROM t5;
   1.198 +    INSERT INTO t5 SELECT a.x*100+b.x, a.y*100+b.y FROM t1 AS a, t1 AS b
   1.199 +                   ORDER BY 1, 2 LIMIT 1000;
   1.200 +    SELECT count(*), sum(x), sum(y), min(x), max(x), min(y), max(y) FROM t5;
   1.201 +  }
   1.202 +} {1000 1528204 593161 0 3107 505 1005}
   1.203 +
   1.204 +# There is some contraversy about whether LIMIT 0 should be the same as
   1.205 +# no limit at all or if LIMIT 0 should result in zero output rows.
   1.206 +#
   1.207 +do_test limit-6.1 {
   1.208 +  execsql {
   1.209 +    BEGIN;
   1.210 +    CREATE TABLE t6(a);
   1.211 +    INSERT INTO t6 VALUES(1);
   1.212 +    INSERT INTO t6 VALUES(2);
   1.213 +    INSERT INTO t6 SELECT a+2 FROM t6;
   1.214 +    COMMIT;
   1.215 +    SELECT * FROM t6;
   1.216 +  }
   1.217 +} {1 2 3 4}
   1.218 +do_test limit-6.2 {
   1.219 +  execsql {
   1.220 +    SELECT * FROM t6 LIMIT -1 OFFSET -1;
   1.221 +  }
   1.222 +} {1 2 3 4}
   1.223 +do_test limit-6.3 {
   1.224 +  execsql {
   1.225 +    SELECT * FROM t6 LIMIT 2 OFFSET -123;
   1.226 +  }
   1.227 +} {1 2}
   1.228 +do_test limit-6.4 {
   1.229 +  execsql {
   1.230 +    SELECT * FROM t6 LIMIT -432 OFFSET 2;
   1.231 +  }
   1.232 +} {3 4}
   1.233 +do_test limit-6.5 {
   1.234 +  execsql {
   1.235 +    SELECT * FROM t6 LIMIT -1
   1.236 +  }
   1.237 +} {1 2 3 4}
   1.238 +do_test limit-6.6 {
   1.239 +  execsql {
   1.240 +    SELECT * FROM t6 LIMIT -1 OFFSET 1
   1.241 +  }
   1.242 +} {2 3 4}
   1.243 +do_test limit-6.7 {
   1.244 +  execsql {
   1.245 +    SELECT * FROM t6 LIMIT 0
   1.246 +  }
   1.247 +} {}
   1.248 +do_test limit-6.8 {
   1.249 +  execsql {
   1.250 +    SELECT * FROM t6 LIMIT 0 OFFSET 1
   1.251 +  }
   1.252 +} {}
   1.253 +
   1.254 +# Make sure LIMIT works well with compound SELECT statements.
   1.255 +# Ticket #393
   1.256 +#
   1.257 +ifcapable compound {
   1.258 +do_test limit-7.1.1 {
   1.259 +  catchsql {
   1.260 +    SELECT x FROM t2 LIMIT 5 UNION ALL SELECT a FROM t6;
   1.261 +  }
   1.262 +} {1 {LIMIT clause should come after UNION ALL not before}}
   1.263 +do_test limit-7.1.2 {
   1.264 +  catchsql {
   1.265 +    SELECT x FROM t2 LIMIT 5 UNION SELECT a FROM t6;
   1.266 +  }
   1.267 +} {1 {LIMIT clause should come after UNION not before}}
   1.268 +do_test limit-7.1.3 {
   1.269 +  catchsql {
   1.270 +    SELECT x FROM t2 LIMIT 5 EXCEPT SELECT a FROM t6 LIMIT 3;
   1.271 +  }
   1.272 +} {1 {LIMIT clause should come after EXCEPT not before}}
   1.273 +do_test limit-7.1.4 {
   1.274 +  catchsql {
   1.275 +    SELECT x FROM t2 LIMIT 0,5 INTERSECT SELECT a FROM t6;
   1.276 +  }
   1.277 +} {1 {LIMIT clause should come after INTERSECT not before}}
   1.278 +do_test limit-7.2 {
   1.279 +  execsql {
   1.280 +    SELECT x FROM t2 UNION ALL SELECT a FROM t6 LIMIT 5;
   1.281 +  }
   1.282 +} {31 30 1 2 3}
   1.283 +do_test limit-7.3 {
   1.284 +  execsql {
   1.285 +    SELECT x FROM t2 UNION ALL SELECT a FROM t6 LIMIT 3 OFFSET 1;
   1.286 +  }
   1.287 +} {30 1 2}
   1.288 +do_test limit-7.4 {
   1.289 +  execsql {
   1.290 +    SELECT x FROM t2 UNION ALL SELECT a FROM t6 ORDER BY 1 LIMIT 3 OFFSET 1;
   1.291 +  }
   1.292 +} {2 3 4}
   1.293 +do_test limit-7.5 {
   1.294 +  execsql {
   1.295 +    SELECT x FROM t2 UNION SELECT x+2 FROM t2 LIMIT 2 OFFSET 1;
   1.296 +  }
   1.297 +} {31 32}
   1.298 +do_test limit-7.6 {
   1.299 +  execsql {
   1.300 +    SELECT x FROM t2 UNION SELECT x+2 FROM t2 ORDER BY 1 DESC LIMIT 2 OFFSET 1;
   1.301 +  }
   1.302 +} {32 31}
   1.303 +do_test limit-7.7 {
   1.304 +  execsql {
   1.305 +    SELECT a+9 FROM t6 EXCEPT SELECT y FROM t2 LIMIT 2;
   1.306 +  }
   1.307 +} {11 12}
   1.308 +do_test limit-7.8 {
   1.309 +  execsql {
   1.310 +    SELECT a+9 FROM t6 EXCEPT SELECT y FROM t2 ORDER BY 1 DESC LIMIT 2;
   1.311 +  }
   1.312 +} {13 12}
   1.313 +do_test limit-7.9 {
   1.314 +  execsql {
   1.315 +    SELECT a+26 FROM t6 INTERSECT SELECT x FROM t2 LIMIT 1;
   1.316 +  }
   1.317 +} {30}
   1.318 +do_test limit-7.10 {
   1.319 +  execsql {
   1.320 +    SELECT a+27 FROM t6 INTERSECT SELECT x FROM t2 LIMIT 1;
   1.321 +  }
   1.322 +} {30}
   1.323 +do_test limit-7.11 {
   1.324 +  execsql {
   1.325 +    SELECT a+27 FROM t6 INTERSECT SELECT x FROM t2 LIMIT 1 OFFSET 1;
   1.326 +  }
   1.327 +} {31}
   1.328 +do_test limit-7.12 {
   1.329 +  execsql {
   1.330 +    SELECT a+27 FROM t6 INTERSECT SELECT x FROM t2 
   1.331 +       ORDER BY 1 DESC LIMIT 1 OFFSET 1;
   1.332 +  }
   1.333 +} {30}
   1.334 +} ;# ifcapable compound
   1.335 +
   1.336 +# Tests for limit in conjunction with distinct.  The distinct should
   1.337 +# occur before both the limit and the offset.  Ticket #749.
   1.338 +#
   1.339 +do_test limit-8.1 {
   1.340 +  execsql {
   1.341 +    SELECT DISTINCT cast(round(x/100) as integer) FROM t3 LIMIT 5;
   1.342 +  }
   1.343 +} {0 1 2 3 4}
   1.344 +do_test limit-8.2 {
   1.345 +  execsql {
   1.346 +    SELECT DISTINCT cast(round(x/100) as integer) FROM t3 LIMIT 5 OFFSET 5;
   1.347 +  }
   1.348 +} {5 6 7 8 9}
   1.349 +do_test limit-8.3 {
   1.350 +  execsql {
   1.351 +    SELECT DISTINCT cast(round(x/100) as integer) FROM t3 LIMIT 5 OFFSET 25;
   1.352 +  }
   1.353 +} {25 26 27 28 29}
   1.354 +
   1.355 +# Make sure limits on multiple subqueries work correctly.
   1.356 +# Ticket #1035
   1.357 +#
   1.358 +ifcapable subquery {
   1.359 +  do_test limit-9.1 {
   1.360 +    execsql {
   1.361 +      SELECT * FROM (SELECT * FROM t6 LIMIT 3);
   1.362 +    }
   1.363 +  } {1 2 3}
   1.364 +}
   1.365 +do_test limit-9.2.1 {
   1.366 +  execsql {
   1.367 +    CREATE TABLE t7 AS SELECT * FROM t6;
   1.368 +  }
   1.369 +} {}
   1.370 +ifcapable subquery {
   1.371 +  do_test limit-9.2.2 {
   1.372 +    execsql {
   1.373 +      SELECT * FROM (SELECT * FROM t7 LIMIT 3);
   1.374 +    }
   1.375 +  } {1 2 3}
   1.376 +}
   1.377 +ifcapable compound {
   1.378 +  ifcapable subquery {
   1.379 +    do_test limit-9.3 {
   1.380 +      execsql {
   1.381 +        SELECT * FROM (SELECT * FROM t6 LIMIT 3)
   1.382 +        UNION
   1.383 +        SELECT * FROM (SELECT * FROM t7 LIMIT 3)
   1.384 +        ORDER BY 1
   1.385 +      }
   1.386 +    } {1 2 3}
   1.387 +    do_test limit-9.4 {
   1.388 +      execsql {
   1.389 +        SELECT * FROM (SELECT * FROM t6 LIMIT 3)
   1.390 +        UNION
   1.391 +        SELECT * FROM (SELECT * FROM t7 LIMIT 3)
   1.392 +        ORDER BY 1
   1.393 +        LIMIT 2
   1.394 +      }
   1.395 +    } {1 2}
   1.396 +  }
   1.397 +  do_test limit-9.5 {
   1.398 +    catchsql {
   1.399 +      SELECT * FROM t6 LIMIT 3
   1.400 +      UNION
   1.401 +      SELECT * FROM t7 LIMIT 3
   1.402 +    }
   1.403 +  } {1 {LIMIT clause should come after UNION not before}}
   1.404 +}
   1.405 +
   1.406 +# Test LIMIT and OFFSET using SQL variables.
   1.407 +do_test limit-10.1 {
   1.408 +  set limit 10
   1.409 +  db eval {
   1.410 +    SELECT x FROM t1 LIMIT :limit;
   1.411 +  }
   1.412 +} {31 30 29 28 27 26 25 24 23 22}
   1.413 +do_test limit-10.2 {
   1.414 +  set limit 5
   1.415 +  set offset 5
   1.416 +  db eval {
   1.417 +    SELECT x FROM t1 LIMIT :limit OFFSET :offset;
   1.418 +  }
   1.419 +} {26 25 24 23 22}
   1.420 +do_test limit-10.3 {
   1.421 +  set limit -1
   1.422 +  db eval {
   1.423 +    SELECT x FROM t1 WHERE x<10 LIMIT :limit;
   1.424 +  }
   1.425 +} {9 8 7 6 5 4 3 2 1 0}
   1.426 +do_test limit-10.4 {
   1.427 +  set limit 1.5
   1.428 +  set rc [catch {
   1.429 +  db eval {
   1.430 +    SELECT x FROM t1 WHERE x<10 LIMIT :limit;
   1.431 +  } } msg]
   1.432 +  list $rc $msg
   1.433 +} {1 {datatype mismatch}}
   1.434 +do_test limit-10.5 {
   1.435 +  set limit "hello world"
   1.436 +  set rc [catch {
   1.437 +  db eval {
   1.438 +    SELECT x FROM t1 WHERE x<10 LIMIT :limit;
   1.439 +  } } msg]
   1.440 +  list $rc $msg
   1.441 +} {1 {datatype mismatch}}
   1.442 +
   1.443 +ifcapable subquery {
   1.444 +do_test limit-11.1 {
   1.445 +  db eval {
   1.446 +     SELECT x FROM (SELECT x FROM t1 ORDER BY x LIMIT 0) ORDER BY x
   1.447 +  }
   1.448 +} {}
   1.449 +} ;# ifcapable subquery
   1.450 +
   1.451 +# Test error processing.
   1.452 +#
   1.453 +do_test limit-12.1 {
   1.454 +  catchsql {
   1.455 +     SELECT * FROM t1 LIMIT replace(1)
   1.456 +  }
   1.457 +} {1 {wrong number of arguments to function replace()}}
   1.458 +do_test limit-12.2 {
   1.459 +  catchsql {
   1.460 +     SELECT * FROM t1 LIMIT 5 OFFSET replace(1)
   1.461 +  }
   1.462 +} {1 {wrong number of arguments to function replace()}}
   1.463 +do_test limit-12.3 {
   1.464 +  catchsql {
   1.465 +     SELECT * FROM t1 LIMIT x
   1.466 +  }
   1.467 +} {1 {no such column: x}}
   1.468 +do_test limit-12.4 {
   1.469 +  catchsql {
   1.470 +     SELECT * FROM t1 LIMIT 1 OFFSET x
   1.471 +  }
   1.472 +} {1 {no such column: x}}
   1.473 +
   1.474 +
   1.475 +finish_test