xref: /sqlite-3.40.0/test/tabfunc01.test (revision 2d053314)
1# 2015-08-19
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#
12# This file implements tests for table-valued-functions implemented using
13# eponymous virtual tables.
14#
15
16set testdir [file dirname $argv0]
17source $testdir/tester.tcl
18set testprefix tabfunc01
19
20ifcapable !vtab {
21  finish_test
22  return
23}
24load_static_extension db series
25load_static_extension db array
26
27do_execsql_test tabfunc01-1.1 {
28  SELECT *, '|' FROM generate_series WHERE start=1 AND stop=9 AND step=2;
29} {1 | 3 | 5 | 7 | 9 |}
30do_execsql_test tabfunc01-1.2 {
31  SELECT *, '|' FROM generate_series LIMIT 5;
32} {0 | 1 | 2 | 3 | 4 |}
33do_catchsql_test tabfunc01-1.3 {
34  CREATE VIRTUAL TABLE t1 USING generate_series;
35} {1 {no such module: generate_series}}
36do_execsql_test tabfunc01-1.4 {
37  SELECT * FROM generate_series(1,9,2);
38} {1 3 5 7 9}
39do_execsql_test tabfunc01-1.5 {
40  SELECT * FROM generate_series(1,9);
41} {1 2 3 4 5 6 7 8 9}
42do_execsql_test tabfunc01-1.6 {
43  SELECT * FROM generate_series(1,10) WHERE step=3;
44} {1 4 7 10}
45do_catchsql_test tabfunc01-1.7 {
46  SELECT * FROM generate_series(1,9,2,11);
47} {1 {too many arguments on generate_series() - max 3}}
48
49do_execsql_test tabfunc01-1.8 {
50  SELECT * FROM generate_series(0,32,5) ORDER BY rowid DESC;
51} {30 25 20 15 10 5 0}
52do_execsql_test tabfunc01-1.9 {
53  SELECT rowid, * FROM generate_series(0,32,5) ORDER BY value DESC;
54} {1 30 2 25 3 20 4 15 5 10 6 5 7 0}
55do_execsql_test tabfunc01-1.10 {
56  SELECT rowid, * FROM generate_series(0,32,5) ORDER BY +value DESC;
57} {7 30 6 25 5 20 4 15 3 10 2 5 1 0}
58
59do_execsql_test tabfunc01-1.20 {
60  CREATE VIEW v1(a,b) AS VALUES(1,2),(3,4);
61  SELECT * FROM v1;
62} {1 2 3 4}
63do_catchsql_test tabfunc01-1.21.1 {
64  SELECT * FROM v1(55);
65} {1 {'v1' is not a function}}
66do_catchsql_test tabfunc01-1.21.2 {
67  SELECT * FROM v1();
68} {1 {'v1' is not a function}}
69do_execsql_test tabfunc01-1.22 {
70  CREATE VIEW v2(x) AS SELECT value FROM generate_series(1,5);
71  SELECT * FROM v2;
72} {1 2 3 4 5}
73do_catchsql_test tabfunc01-1.23.1 {
74  SELECT * FROM v2(55);
75} {1 {'v2' is not a function}}
76do_catchsql_test tabfunc01-1.23.2 {
77  SELECT * FROM v2();
78} {1 {'v2' is not a function}}
79do_execsql_test tabfunc01-1.24 {
80  CREATE TABLE t0(x);
81  INSERT INTO t0(x) VALUES(123),(456),(789);
82  SELECT * FROM t0 ORDER BY x;
83} {123 456 789}
84do_catchsql_test tabfunc01-1.25 {
85  SELECT * FROM t0(55) ORDER BY x;
86} {1 {'t0' is not a function}}
87do_catchsql_test tabfunc01-1.26 {
88  WITH w0 AS (SELECT * FROM t0)
89  INSERT INTO t0(x) SELECT * FROM w0()
90} {1 {'w0' is not a function}}
91
92do_execsql_test tabfunc01-2.1 {
93  CREATE TABLE t1(x);
94  INSERT INTO t1(x) VALUES(2),(3);
95  SELECT *, '|' FROM t1, generate_series(1,x) ORDER BY 1, 2
96} {2 1 | 2 2 | 3 1 | 3 2 | 3 3 |}
97do_execsql_test tabfunc01-2.2 {
98  SELECT *, '|' FROM (SELECT x FROM t1) AS y, generate_series(1,y.x)
99  ORDER BY 1, 2;
100} {2 1 | 2 2 | 3 1 | 3 2 | 3 3 |}
101
102do_execsql_test tabfunc01-2.50 {
103  SELECT * FROM generate_series() LIMIT 5;
104} {0 1 2 3 4}
105
106do_execsql_test tabfunc01-3.1 {
107  SELECT DISTINCT value FROM generate_series(1,x), t1 ORDER BY 1;
108} {1 2 3}
109
110# Eponymous virtual table exists in the "main" schema only
111#
112do_execsql_test tabfunc01-4.1 {
113  SELECT * FROM main.generate_series(1,4)
114} {1 2 3 4}
115do_catchsql_test tabfunc01-4.2 {
116  SELECT * FROM temp.generate_series(1,4)
117} {1 {no such table: temp.generate_series}}
118do_catchsql_test tabfunc01-4.3 {
119  ATTACH ':memory:' AS aux1;
120  CREATE TABLE aux1.t1(a,b,c);
121  SELECT * FROM aux1.generate_series(1,4)
122} {1 {no such table: aux1.generate_series}}
123
124# The next series of tests is verifying that virtual table are able
125# to optimize the IN operator, even on terms that are not marked "omit".
126# When the generate_series virtual table is compiled for the testfixture,
127# the special -DSQLITE_SERIES_CONSTRAINT_VERIFY=1 option is used, which
128# causes the xBestIndex method of generate_series to leave the
129# sqlite3_index_constraint_usage.omit flag set to 0, which should cause
130# the SQLite core to verify the start=, stop=, and step= constraints on
131# each step of output.  At one point, the IN operator could not be used
132# by virtual tables unless omit was set.
133#
134do_execsql_test tabfunc01-500 {
135  SELECT * FROM generate_series WHERE start IN (1,7) AND stop=20 AND step=10
136  ORDER BY +1;
137} {1 7 11 17}
138
139
140do_test tabfunc01-600 {
141  set TAIL {}
142  set VM [sqlite3_prepare db {SELECT * FROM intarray(?2,?3)} -1 TAIL]
143  set TAIL
144} {}
145do_test tabfunc01-610 {
146  sqlite3_bind_intarray $VM 2 11 22 33 44 55
147  sqlite3_bind_int $VM 3 4
148  sqlite3_step $VM
149} SQLITE_ROW
150do_test tabfunc01-620 {
151  sqlite3_column_int $VM 0
152} 11
153do_test tabfunc01-621 {
154  sqlite3_step $VM
155  sqlite3_column_int $VM 0
156} 22
157sqlite3_finalize $VM
158
159do_test tabfunc01-650 {
160  db eval {
161    DROP TABLE IF EXISTS t6;
162    CREATE TABLE t6(x INTEGER PRIMARY KEY, y BLOB);
163    WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<100)
164      INSERT INTO t6(x,y) SELECT x, randomblob(x) FROM c;
165  }
166  set TAIL {}
167  set VM [sqlite3_prepare db {
168     SELECT length(y) FROM t6 WHERE x IN (SELECT value FROM intarray(?1,3));
169  } -1 TAIL]
170  string trim $TAIL
171} {}
172do_test tabfunc01-660 {
173  sqlite3_bind_intarray $VM 1 11 22 33 44 55
174  sqlite3_step $VM
175} SQLITE_ROW
176do_test tabfunc01-661 {
177  sqlite3_column_int $VM 0
178} 11
179sqlite3_finalize $VM
180
181do_test tabfunc01-670 {
182  set TAIL {}
183  set VM [sqlite3_prepare db {
184     SELECT length(y) FROM t6 WHERE x IN intarray(?1,3);
185  } -1 TAIL]
186  string trim $TAIL
187} {}
188do_test tabfunc01-671 {
189  sqlite3_bind_intarray $VM 1 11 22 33 44 55
190  sqlite3_step $VM
191} SQLITE_ROW
192do_test tabfunc01-672 {
193  sqlite3_column_int $VM 0
194} 11
195sqlite3_finalize $VM
196
197catch {sqlite3_bind_intarray}
198
199finish_test
200