xref: /sqlite-3.40.0/test/vtab1.test (revision 962f9669)
1# 2006 June 10
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 creating and dropping virtual tables.
13#
14# $Id: vtab1.test,v 1.57 2008/08/01 17:51:47 danielk1977 Exp $
15
16set testdir [file dirname $argv0]
17source $testdir/tester.tcl
18set testprefix vtab1
19
20ifcapable !vtab||!schema_pragmas {
21  finish_test
22  return
23}
24
25#----------------------------------------------------------------------
26# Organization of tests in this file:
27#
28# vtab1-1.*: Error conditions and other issues surrounding creation/connection
29#            of a virtual module.
30# vtab1-2.*: Test sqlite3_declare_vtab() and the xConnect/xDisconnect methods.
31# vtab1-3.*: Table scans and WHERE clauses.
32# vtab1-4.*: Table scans and ORDER BY clauses.
33# vtab1-5.*: Test queries that include joins. This brings the
34#            sqlite3_index_info.estimatedCost variable into play.
35# vtab1-6.*: Test UPDATE/INSERT/DELETE on vtables.
36# vtab1-7.*: Test sqlite3_last_insert_rowid().
37#
38# This file uses the "echo" module (see src/test8.c). Refer to comments
39# in that file for the special behaviour of the Tcl $echo_module variable.
40#
41# TODO:
42#   * How to test the sqlite3_index_constraint_usage.omit field?
43#   * vtab1-5.*
44#
45# vtab1-14.*: Test 'IN' constraints - i.e. "SELECT * FROM t1 WHERE id IN(...)"
46#
47# vtab1-18.*: Check that the LIKE optimization is not applied when the lhs
48#             is a virtual table column.
49#
50
51
52#----------------------------------------------------------------------
53# Test cases vtab1.1.*
54#
55
56# We cannot create a virtual table if the module has not been registered.
57#
58do_test vtab1-1.1.1 {
59  explain {
60    CREATE VIRTUAL TABLE t1 USING echo;
61  }
62  catchsql {
63    CREATE VIRTUAL TABLE t1 USING echo;
64  }
65} {1 {no such module: echo}}
66do_test vtab1-1.1.2 {
67  catchsql {
68    CREATE VIRTUAL TABLE IF NOT EXISTS t1 USING echo;
69  }
70} {1 {no such module: echo}}
71do_test vtab1-1.2 {
72  execsql {
73    SELECT name FROM sqlite_master ORDER BY 1
74  }
75} {}
76
77# Register the module
78register_echo_module [sqlite3_connection_pointer db]
79
80# Once a module has been registered, virtual tables using that module
81# may be created. However if a module xCreate() fails to call
82# sqlite3_declare_vtab() an error will be raised and the table not created.
83#
84# The "echo" module does not invoke sqlite3_declare_vtab() if it is
85# passed zero arguments.
86#
87do_test vtab1-1.3.1 {
88  catchsql {
89    CREATE VIRTUAL TABLE t1 USING echo;
90  }
91} {1 {vtable constructor did not declare schema: t1}}
92do_test vtab1-1.3.2 {
93  catchsql {
94    CREATE VIRTUAL TABLE IF NOT EXISTS t1 USING echo;
95  }
96} {1 {vtable constructor did not declare schema: t1}}
97do_test vtab1-1.4 {
98  execsql {
99    SELECT name FROM sqlite_master ORDER BY 1
100  }
101} {}
102
103# The "echo" module xCreate method returns an error and does not create
104# the virtual table if it is passed an argument that does not correspond
105# to an existing real table in the same database.
106#
107do_test vtab1-1.5.1 {
108  catchsql {
109    CREATE VIRTUAL TABLE t1 USING echo(no_such_table);
110  }
111} {1 {vtable constructor failed: t1}}
112do_test vtab1-1.5.2 {
113  catchsql {
114    CREATE VIRTUAL TABLE IF NOT EXISTS t1 USING echo(no_such_table);
115  }
116} {1 {vtable constructor failed: t1}}
117do_test vtab1-1.6 {
118  execsql {
119    SELECT name FROM sqlite_master ORDER BY 1
120  }
121} {}
122
123# Ticket #2156.  Using the sqlite3_prepare_v2() API, make sure that
124# a CREATE VIRTUAL TABLE statement can be used multiple times.
125#
126do_test vtab1-1.2152.1 {
127  set DB [sqlite3_connection_pointer db]
128  set sql {CREATE VIRTUAL TABLE t2152a USING echo(t2152b)}
129  set STMT [sqlite3_prepare_v2 $DB $sql -1 TAIL]
130  sqlite3_step $STMT
131} SQLITE_ERROR
132do_test vtab-1.2152.2 {
133  sqlite3_reset $STMT
134  sqlite3_step $STMT
135} SQLITE_ERROR
136do_test vtab-1.2152.3 {
137  sqlite3_reset $STMT
138  db eval {CREATE TABLE t2152b(x,y)}
139  sqlite3_step $STMT
140} SQLITE_DONE
141do_test vtab-1.2152.4 {
142  sqlite3_finalize $STMT
143  db eval {DROP TABLE t2152a; DROP TABLE t2152b}
144} {}
145
146# Test to make sure nothing goes wrong and no memory is leaked if we
147# select an illegal table-name (i.e a reserved name or the name of a
148# table that already exists).
149#
150do_test vtab1-1.7.1 {
151  catchsql {
152    CREATE VIRTUAL TABLE sqlite_master USING echo;
153  }
154} {1 {object name reserved for internal use: sqlite_master}}
155do_test vtab1-1.7.2 {
156  catchsql {
157    CREATE VIRTUAL TABLE IF NOT EXISTS sqlite_master USING echo;
158  }
159} {1 {object name reserved for internal use: sqlite_master}}
160do_test vtab1-1.8.1 {
161  catchsql {
162    CREATE TABLE treal(a, b, c);
163    CREATE VIRTUAL TABLE treal USING echo(treal);
164  }
165} {1 {table treal already exists}}
166do_test vtab1-1.8.2 {
167  catchsql {
168    CREATE VIRTUAL TABLE IF NOT EXISTS treal USING echo(treal);
169  }
170} {0 {}}
171do_test vtab1-1.9 {
172  execsql {
173    DROP TABLE treal;
174    SELECT name FROM sqlite_master ORDER BY 1
175  }
176} {}
177
178do_test vtab1-1.10 {
179  execsql {
180    CREATE TABLE treal(a, b, c);
181    CREATE VIRTUAL TABLE techo USING echo(treal);
182  }
183  db close
184  sqlite3 db test.db
185  catchsql {
186    SELECT * FROM techo;
187  }
188} {1 {no such module: echo}}
189do_test vtab1-1.11 {
190  catchsql {
191    INSERT INTO techo VALUES(1, 2, 3);
192  }
193} {1 {no such module: echo}}
194do_test vtab1-1.12 {
195  catchsql {
196    UPDATE techo SET a = 10;
197  }
198} {1 {no such module: echo}}
199do_test vtab1-1.13 {
200  catchsql {
201    DELETE FROM techo;
202  }
203} {1 {no such module: echo}}
204do_test vtab1-1.14 {
205  catchsql {
206    PRAGMA table_info(techo)
207  }
208} {1 {no such module: echo}}
209do_test vtab1-1.15 {
210  catchsql {
211    DROP TABLE techo;
212  }
213} {1 {no such module: echo}}
214
215register_echo_module [sqlite3_connection_pointer db]
216register_echo_module [sqlite3_connection_pointer db]
217
218# Test an error message returned from a v-table constructor.
219#
220do_test vtab1-1.16 {
221  execsql {
222    DROP TABLE techo;
223    CREATE TABLE logmsg(log);
224  }
225  catchsql {
226    CREATE VIRTUAL TABLE techo USING echo(treal, logmsg);
227  }
228} {1 {table 'logmsg' already exists}}
229
230do_test vtab1-1.17 {
231  execsql {
232    DROP TABLE treal;
233    DROP TABLE logmsg;
234    SELECT sql FROM sqlite_master;
235  }
236} {}
237
238#----------------------------------------------------------------------
239# Test cases vtab1.2.*
240#
241# At this point, the database is completely empty. The echo module
242# has already been registered.
243
244# If a single argument is passed to the echo module during table
245# creation, it is assumed to be the name of a table in the same
246# database. The echo module attempts to set the schema of the
247# new virtual table to be the same as the existing database table.
248#
249do_test vtab1-2.1 {
250  execsql {
251    CREATE TABLE template(a, b, c);
252  }
253  execsql { PRAGMA table_info(template); }
254} [list         \
255  0 a {} 0 {} 0 \
256  1 b {} 0 {} 0 \
257  2 c {} 0 {} 0 \
258]
259do_test vtab1-2.2 {
260  execsql {
261    CREATE VIRTUAL TABLE t1 USING echo(template);
262  }
263  execsql { PRAGMA table_info(t1); }
264} [list         \
265  0 a {} 0 {} 0 \
266  1 b {} 0 {} 0 \
267  2 c {} 0 {} 0 \
268]
269
270# Test that the database can be unloaded. This should invoke the xDisconnect()
271# callback for the successfully create virtual table (t1).
272#
273do_test vtab1-2.3 {
274  set echo_module [list]
275  db close
276  set echo_module
277} [list xDisconnect]
278
279# Re-open the database. This should not cause any virtual methods to
280# be called. The invocation of xConnect() is delayed until the virtual
281# table schema is first required by the compiler.
282#
283do_test vtab1-2.4 {
284  set echo_module [list]
285  sqlite3 db test.db
286  db cache size 0
287  set echo_module
288} {}
289
290# Try to query the virtual table schema. This should fail, as the
291# echo module has not been registered with this database connection.
292#
293do_test vtab1.2.6 {
294  catchsql { PRAGMA table_info(t1); }
295} {1 {no such module: echo}}
296
297# Register the module
298register_echo_module [sqlite3_connection_pointer db]
299
300# Try to query the virtual table schema again. This time it should
301# invoke the xConnect method and succeed.
302#
303do_test vtab1.2.7 {
304  execsql { PRAGMA table_info(t1); }
305} [list         \
306  0 a {} 0 {} 0 \
307  1 b {} 0 {} 0 \
308  2 c {} 0 {} 0 \
309]
310do_test vtab1.2.8 {
311  set echo_module
312} {xConnect echo main t1 template}
313
314# Drop table t1. This should cause the xDestroy (but not xDisconnect) method
315# to be invoked.
316do_test vtab1-2.5 {
317  set echo_module ""
318  execsql {
319    DROP TABLE t1;
320  }
321  set echo_module
322} {xDestroy}
323
324do_test vtab1-2.6 {
325  execsql {
326    PRAGMA table_info(t1);
327  }
328} {}
329do_test vtab1-2.7 {
330  execsql {
331    SELECT sql FROM sqlite_master;
332  }
333} [list {CREATE TABLE template(a, b, c)}]
334# Clean up other test artifacts:
335do_test vtab1-2.8 {
336  execsql {
337    DROP TABLE template;
338    SELECT sql FROM sqlite_master;
339  }
340} [list]
341
342#----------------------------------------------------------------------
343# Test case vtab1-3 test table scans and the echo module's
344# xBestIndex/xFilter handling of WHERE conditions.
345
346do_test vtab1-3.1 {
347  set echo_module ""
348  execsql {
349    CREATE TABLE treal(a INTEGER, b INTEGER, c);
350    CREATE INDEX treal_idx ON treal(b);
351    CREATE VIRTUAL TABLE t1 USING echo(treal);
352  }
353  set echo_module
354} [list xCreate echo main t1 treal   \
355        xSync   echo(treal)  \
356        xCommit echo(treal)  \
357]
358
359# Test that a SELECT on t1 doesn't crash. No rows are returned
360# because the underlying real table is currently empty.
361#
362do_test vtab1-3.2 {
363  execsql {
364    SELECT a, b, c FROM t1;
365  }
366} {}
367
368# Put some data into the table treal. Then try a few simple SELECT
369# statements on t1.
370#
371do_test vtab1-3.3 {
372  execsql {
373    INSERT INTO treal VALUES(1, 2, 3);
374    INSERT INTO treal VALUES(4, 5, 6);
375    SELECT * FROM t1;
376  }
377} {1 2 3 4 5 6}
378do_test vtab1-3.4 {
379  execsql {
380    SELECT a FROM t1;
381  }
382} {1 4}
383do_test vtab1-3.5 {
384  execsql {
385    SELECT rowid FROM t1;
386  }
387} {1 2}
388do_test vtab1-3.6 {
389  set echo_module ""
390  execsql {
391    SELECT * FROM t1;
392  }
393} {1 2 3 4 5 6}
394do_test vtab1-3.7 {
395  execsql {
396    SELECT rowid, * FROM t1;
397  }
398} {1 1 2 3 2 4 5 6}
399do_test vtab1-3.8 {
400  execsql {
401    SELECT a AS d, b AS e, c AS f FROM t1;
402  }
403} {1 2 3 4 5 6}
404
405# Execute some SELECT statements with WHERE clauses on the t1 table.
406# Then check the echo_module variable (written to by the module methods
407# in test8.c) to make sure the xBestIndex() and xFilter() methods were
408# called correctly.
409#
410do_test vtab1-3.8 {
411  set echo_module ""
412  execsql {
413    SELECT * FROM t1;
414  }
415  set echo_module
416} [list xBestIndex {SELECT rowid, * FROM 'treal'} \
417        xFilter    {SELECT rowid, * FROM 'treal'} ]
418do_test vtab1-3.9 {
419  set echo_module ""
420  execsql {
421    SELECT * FROM t1 WHERE b = 5;
422  }
423} {4 5 6}
424do_test vtab1-3.10 {
425  set echo_module
426} [list xBestIndex {SELECT rowid, * FROM 'treal' WHERE b = ?}   \
427        xFilter    {SELECT rowid, * FROM 'treal' WHERE b = ?} 5 ]
428do_test vtab1-3.10 {
429  set echo_module ""
430  execsql {
431    SELECT * FROM t1 WHERE b >= 5 AND b <= 10;
432  }
433} {4 5 6}
434do_test vtab1-3.11 {
435  set echo_module
436} [list xBestIndex {SELECT rowid, * FROM 'treal' WHERE b >= ? AND b <= ?}      \
437        xFilter    {SELECT rowid, * FROM 'treal' WHERE b >= ? AND b <= ?} 5 10 ]
438do_test vtab1-3.12 {
439  set echo_module ""
440  execsql {
441    SELECT * FROM t1 WHERE b BETWEEN 2 AND 10;
442  }
443} {1 2 3 4 5 6}
444do_test vtab1-3.13 {
445  set echo_module
446} [list xBestIndex {SELECT rowid, * FROM 'treal' WHERE b >= ? AND b <= ?}      \
447        xFilter    {SELECT rowid, * FROM 'treal' WHERE b >= ? AND b <= ?} 2 10 ]
448
449# Add a function for the MATCH operator. Everything always matches!
450#proc test_match {lhs rhs} {
451#  lappend ::echo_module MATCH $lhs $rhs
452#  return 1
453#}
454#db function match test_match
455
456set echo_module ""
457do_test vtab1-3.12 {
458  set echo_module ""
459  catchsql {
460    SELECT * FROM t1 WHERE a MATCH 'string';
461  }
462} {1 {unable to use function MATCH in the requested context}}
463do_test vtab1-3.13 {
464  set echo_module
465} [list xBestIndex {SELECT rowid, * FROM 'treal'} \
466        xFilter    {SELECT rowid, * FROM 'treal'}]
467ifcapable subquery {
468# The echo module uses a subquery internally to implement the MATCH operator.
469do_test vtab1-3.14 {
470  set echo_module ""
471  execsql {
472    SELECT * FROM t1 WHERE b MATCH 'string';
473  }
474} {}
475do_test vtab1-3.15 {
476  set echo_module
477} [list xBestIndex \
478        {SELECT rowid, * FROM 'treal' WHERE b LIKE (SELECT '%'||?||'%')}  \
479        xFilter \
480        {SELECT rowid, * FROM 'treal' WHERE b LIKE (SELECT '%'||?||'%')} \
481        string ]
482}; #ifcapable subquery
483
484#----------------------------------------------------------------------
485# Test case vtab1-3 test table scans and the echo module's
486# xBestIndex/xFilter handling of ORDER BY clauses.
487
488# This procedure executes the SQL.  Then it checks to see if the OP_Sort
489# opcode was executed.  If an OP_Sort did occur, then "sort" is appended
490# to the result.  If no OP_Sort happened, then "nosort" is appended.
491#
492# This procedure is used to check to make sure sorting is or is not
493# occurring as expected.
494#
495proc cksort {sql} {
496  set ::sqlite_sort_count 0
497  set data [execsql $sql]
498  if {$::sqlite_sort_count} {set x sort} {set x nosort}
499  lappend data $x
500  return $data
501}
502
503do_test vtab1-4.1 {
504  set echo_module ""
505  cksort {
506    SELECT b FROM t1 ORDER BY b;
507  }
508} {2 5 nosort}
509do_test vtab1-4.2 {
510  set echo_module
511} [list xBestIndex {SELECT rowid, * FROM 'treal' ORDER BY b ASC} \
512        xFilter    {SELECT rowid, * FROM 'treal' ORDER BY b ASC} ]
513do_test vtab1-4.3 {
514  set echo_module ""
515  cksort {
516    SELECT b FROM t1 ORDER BY b DESC;
517  }
518} {5 2 nosort}
519do_test vtab1-4.4 {
520  set echo_module
521} [list xBestIndex {SELECT rowid, * FROM 'treal' ORDER BY b DESC} \
522        xFilter    {SELECT rowid, * FROM 'treal' ORDER BY b DESC} ]
523do_test vtab1-4.3 {
524  set echo_module ""
525  cksort {
526    SELECT b FROM t1 ORDER BY b||'';
527  }
528} {2 5 sort}
529do_test vtab1-4.4 {
530  set echo_module
531} [list xBestIndex {SELECT rowid, * FROM 'treal'} \
532        xFilter    {SELECT rowid, * FROM 'treal'} ]
533
534execsql {
535  DROP TABLE t1;
536  DROP TABLE treal;
537}
538
539#----------------------------------------------------------------------
540# Test cases vtab1-5 test SELECT queries that include joins on virtual
541# tables.
542
543proc filter {log} {
544  set out [list]
545  for {set ii 0} {$ii < [llength $log]} {incr ii} {
546    if {[lindex $log $ii] eq "xFilter"} {
547      lappend out xFilter
548      lappend out [lindex $log [expr $ii+1]]
549    }
550  }
551  return $out
552}
553
554do_test vtab1-5-1 {
555  execsql {
556    CREATE TABLE t1(a, b, c);
557    CREATE TABLE t2(d, e, f);
558    INSERT INTO t1 VALUES(1, 'red', 'green');
559    INSERT INTO t1 VALUES(2, 'blue', 'black');
560    INSERT INTO t2 VALUES(1, 'spades', 'clubs');
561    INSERT INTO t2 VALUES(2, 'hearts', 'diamonds');
562    CREATE VIRTUAL TABLE et1 USING echo(t1);
563    CREATE VIRTUAL TABLE et2 USING echo(t2);
564  }
565} {}
566
567do_test vtab1-5-2 {
568  set echo_module ""
569  execsql {
570    SELECT * FROM et1, et2;
571  }
572} [list \
573  1 red green 1 spades clubs     \
574  1 red green 2 hearts diamonds  \
575  2 blue black 1 spades clubs    \
576  2 blue black 2 hearts diamonds \
577]
578do_test vtab1-5-3 {
579  filter $echo_module
580} [list \
581  xFilter {SELECT rowid, * FROM 't1'} \
582  xFilter {SELECT rowid, * FROM 't2'} \
583  xFilter {SELECT rowid, * FROM 't2'} \
584]
585do_test vtab1-5-4 {
586  set echo_module ""
587  execsql {
588    SELECT * FROM et1, et2 WHERE et2.d = 2;
589  }
590} [list \
591  1 red green 2 hearts diamonds  \
592  2 blue black 2 hearts diamonds \
593]
594do_test vtab1-5-5 {
595  filter $echo_module
596} [list \
597  xFilter {SELECT rowid, * FROM 't1'} \
598  xFilter {SELECT rowid, * FROM 't2'} \
599  xFilter {SELECT rowid, * FROM 't2'} \
600]
601do_test vtab1-5-6 {
602  execsql {
603    CREATE INDEX i1 ON t2(d);
604  }
605
606  db close
607  sqlite3 db test.db
608  register_echo_module [sqlite3_connection_pointer db]
609
610  set ::echo_module ""
611  execsql {
612    SELECT * FROM et1, et2 WHERE et2.d = 2;
613  }
614} [list \
615  1 red green 2 hearts diamonds  \
616  2 blue black 2 hearts diamonds \
617]
618do_test vtab1-5-7 {
619  filter $::echo_module
620} [list \
621  xFilter {SELECT rowid, * FROM 't1'}             \
622  xFilter {SELECT rowid, * FROM 't2' WHERE d = ?} \
623  xFilter {SELECT rowid, * FROM 't2' WHERE d = ?} \
624]
625
626execsql {
627  DROP TABLE t1;
628  DROP TABLE t2;
629  DROP TABLE et1;
630  DROP TABLE et2;
631}
632
633#----------------------------------------------------------------------
634# Test cases vtab1-6 test INSERT, UPDATE and DELETE operations
635# on virtual tables.
636do_test vtab1-6-1 {
637  execsql { SELECT sql FROM sqlite_master }
638} {}
639do_test vtab1-6-2 {
640  execsql {
641    CREATE TABLE treal(a PRIMARY KEY, b, c);
642    CREATE VIRTUAL TABLE techo USING echo(treal);
643    SELECT name FROM sqlite_master WHERE type = 'table';
644  }
645} {treal techo}
646do_test vtab1-6-3.1.1 {
647  execsql {
648    PRAGMA count_changes=ON;
649    INSERT INTO techo VALUES(1, 2, 3);
650  }
651} {1}
652do_test vtab1-6-3.1.2 {
653  db changes
654} {1}
655do_test vtab1-6-3.2 {
656  execsql {
657    SELECT * FROM techo;
658  }
659} {1 2 3}
660do_test vtab1-6-4.1 {
661  execsql {
662    UPDATE techo SET a = 5;
663  }
664  db changes
665} {1}
666do_test vtab1-6-4.2 {
667  execsql {
668    SELECT * FROM techo;
669  }
670} {5 2 3}
671do_test vtab1-6-4.3 {
672  execsql {
673    UPDATE techo SET a=6 WHERE a<0;
674  }
675  db changes
676} {0}
677do_test vtab1-6-4.4 {
678  execsql {
679    SELECT * FROM techo;
680  }
681} {5 2 3}
682
683do_test vtab1-6-5.1 {
684 execsql {
685   UPDATE techo set a = a||b||c;
686 }
687 db changes
688} {1}
689do_test vtab1-6-5.2 {
690 execsql {
691   SELECT * FROM techo;
692 }
693} {523 2 3}
694
695do_test vtab1-6-6.1 {
696  execsql {
697    UPDATE techo set rowid = 10;
698  }
699  db changes
700} {1}
701do_test vtab1-6-6.2 {
702  execsql {
703    SELECT rowid FROM techo;
704  }
705} {10}
706
707do_test vtab1-6-7.1.1 {
708  execsql {
709    INSERT INTO techo VALUES(11,12,13);
710  }
711} {1}
712do_test vtab1-6-7.1.2 {
713  db changes
714} {1}
715do_test vtab1-6-7.2 {
716  execsql {
717    SELECT * FROM techo ORDER BY a;
718  }
719} {11 12 13 523 2 3}
720do_test vtab1-6-7.3 {
721  execsql {
722    UPDATE techo SET b=b+1000
723  }
724  db changes
725} {2}
726do_test vtab1-6-7.4 {
727  execsql {
728    SELECT * FROM techo ORDER BY a;
729  }
730} {11 1012 13 523 1002 3}
731
732
733do_test vtab1-6-8.1 {
734  execsql {
735    DELETE FROM techo WHERE a=5;
736  }
737  db changes
738} {0}
739do_test vtab1-6-8.2 {
740  execsql {
741    SELECT * FROM techo ORDER BY a;
742  }
743} {11 1012 13 523 1002 3}
744do_test vtab1-6-8.3 {
745  execsql {
746    DELETE FROM techo;
747  }
748  db changes
749} {2}
750do_test vtab1-6-8.4 {
751  execsql {
752    SELECT * FROM techo ORDER BY a;
753  }
754} {}
755execsql {PRAGMA count_changes=OFF}
756
757forcedelete test2.db
758forcedelete test2.db-journal
759sqlite3 db2 test2.db
760execsql {
761  CREATE TABLE techo(a PRIMARY KEY, b, c);
762} db2
763proc check_echo_table {tn} {
764  set ::data1 [execsql {SELECT rowid, * FROM techo}]
765  set ::data2 [execsql {SELECT rowid, * FROM techo} db2]
766  do_test $tn {
767    string equal $::data1 $::data2
768  } 1
769}
770set tn 0
771foreach stmt [list \
772  {INSERT INTO techo VALUES('abc', 'def', 'ghi')}                        \
773  {INSERT INTO techo SELECT a||'.'||rowid, b, c FROM techo}              \
774  {INSERT INTO techo SELECT a||'x'||rowid, b, c FROM techo}              \
775  {INSERT INTO techo SELECT a||'y'||rowid, b, c FROM techo}              \
776  {DELETE FROM techo WHERE (oid % 3) = 0}                                \
777  {UPDATE techo set rowid = 100 WHERE rowid = 1}                         \
778  {INSERT INTO techo(a, b) VALUES('hello', 'world')}                     \
779  {DELETE FROM techo}                                                    \
780] {
781  execsql $stmt
782  execsql $stmt db2
783  check_echo_table vtab1-6.8.[incr tn]
784}
785
786db2 close
787
788
789
790#----------------------------------------------------------------------
791# Test cases vtab1-7 tests that the value returned by
792# sqlite3_last_insert_rowid() is set correctly when rows are inserted
793# into virtual tables.
794do_test vtab1.7-1 {
795  execsql {
796    CREATE TABLE real_abc(a PRIMARY KEY, b, c);
797    CREATE VIRTUAL TABLE echo_abc USING echo(real_abc);
798  }
799} {}
800do_test vtab1.7-2 {
801  execsql {
802    INSERT INTO echo_abc VALUES(1, 2, 3);
803    SELECT last_insert_rowid();
804  }
805} {1}
806do_test vtab1.7-3 {
807  execsql {
808    INSERT INTO echo_abc(rowid) VALUES(31427);
809    SELECT last_insert_rowid();
810  }
811} {31427}
812do_test vtab1.7-4 {
813  execsql {
814    INSERT INTO echo_abc SELECT a||'.v2', b, c FROM echo_abc;
815    SELECT last_insert_rowid();
816  }
817} {31429}
818do_test vtab1.7-5 {
819  execsql {
820    SELECT rowid, a, b, c FROM echo_abc
821  }
822} [list 1     1    2  3  \
823        31427 {}   {} {} \
824        31428 1.v2 2  3  \
825        31429 {}  {} {}  \
826]
827
828# Now test that DELETE and UPDATE operations do not modify the value.
829do_test vtab1.7-6 {
830  execsql {
831    UPDATE echo_abc SET c = 5 WHERE b = 2;
832    SELECT last_insert_rowid();
833  }
834} {31429}
835do_test vtab1.7-7 {
836  execsql {
837    UPDATE echo_abc SET rowid = 5 WHERE rowid = 1;
838    SELECT last_insert_rowid();
839  }
840} {31429}
841do_test vtab1.7-8 {
842  execsql {
843    DELETE FROM echo_abc WHERE b = 2;
844    SELECT last_insert_rowid();
845  }
846} {31429}
847do_test vtab1.7-9 {
848  execsql {
849    SELECT rowid, a, b, c FROM echo_abc
850  }
851} [list 31427 {} {} {} \
852        31429 {} {} {} \
853]
854do_test vtab1.7-10 {
855  execsql {
856    DELETE FROM echo_abc WHERE b = 2;
857    SELECT last_insert_rowid();
858  }
859} {31429}
860do_test vtab1.7-11 {
861  execsql {
862    SELECT rowid, a, b, c FROM real_abc
863  }
864} [list 31427 {} {} {} \
865        31429 {} {} {} \
866]
867do_test vtab1.7-12 {
868  execsql {
869    DELETE FROM echo_abc;
870    SELECT last_insert_rowid();
871  }
872} {31429}
873do_test vtab1.7-13 {
874  execsql {
875    SELECT rowid, a, b, c FROM real_abc
876  }
877} {}
878
879ifcapable attach {
880  do_test vtab1.8-1 {
881    set echo_module ""
882    execsql {
883      ATTACH 'test2.db' AS aux;
884      CREATE VIRTUAL TABLE aux.e2 USING echo(real_abc);
885    }
886    set echo_module
887  } [list xCreate echo aux e2 real_abc   \
888          xSync   echo(real_abc)         \
889          xCommit echo(real_abc)         \
890  ]
891}
892do_test vtab1.8-2 {
893  catchsql {
894    DROP TABLE aux.e2;
895  }
896  execsql {
897    DROP TABLE treal;
898    DROP TABLE techo;
899    DROP TABLE echo_abc;
900    DROP TABLE real_abc;
901  }
902} {}
903
904do_test vtab1.9-1 {
905  set echo_module ""
906  execsql {
907    CREATE TABLE r(a, b, c);
908    CREATE VIRTUAL TABLE e USING echo(r, e_log);
909    SELECT name FROM sqlite_master;
910  }
911} {r e e_log}
912do_test vtab1.9-2 {
913  execsql {
914    DROP TABLE e;
915    SELECT name FROM sqlite_master;
916  }
917} {r}
918
919do_test vtab1.9-3 {
920  set echo_module ""
921  execsql {
922    CREATE VIRTUAL TABLE e USING echo(r, e_log, virtual 1 2 3 varchar(32));
923  }
924  set echo_module
925} [list                                                        \
926  xCreate echo main e r e_log {virtual 1 2 3 varchar(32)}      \
927  xSync echo(r)                                                \
928  xCommit echo(r)                                              \
929]
930
931do_test vtab1.10-1 {
932  execsql {
933    CREATE TABLE del(d);
934    CREATE VIRTUAL TABLE e2 USING echo(del);
935  }
936  db close
937  sqlite3 db test.db
938  register_echo_module [sqlite3_connection_pointer db]
939  execsql {
940    DROP TABLE del;
941  }
942  catchsql {
943    SELECT * FROM e2;
944  }
945} {1 {vtable constructor failed: e2}}
946do_test vtab1.10-2 {
947  set rc [catch {
948    set ptr [sqlite3_connection_pointer db]
949    sqlite3_declare_vtab $ptr {CREATE TABLE abc(a, b, c)}
950  } msg]
951  list $rc $msg
952} {1 {library routine called out of sequence}}
953do_test vtab1.10-3 {
954  set ::echo_module_begin_fail r
955  catchsql {
956    INSERT INTO e VALUES(1, 2, 3);
957  }
958} {1 {SQL logic error or missing database}}
959do_test vtab1.10-4 {
960  catch {execsql {
961    EXPLAIN SELECT * FROM e WHERE rowid = 2;
962    EXPLAIN QUERY PLAN SELECT * FROM e WHERE rowid = 2 ORDER BY rowid;
963  }}
964} {0}
965
966do_test vtab1.10-5 {
967  set echo_module ""
968  execsql {
969    SELECT * FROM e WHERE rowid||'' MATCH 'pattern';
970  }
971  set echo_module
972} [list \
973  xBestIndex {SELECT rowid, * FROM 'r'} \
974  xFilter {SELECT rowid, * FROM 'r'}    \
975]
976proc match_func {args} {return ""}
977do_test vtab1.10-6 {
978  set echo_module ""
979  db function match match_func
980  execsql {
981    SELECT * FROM e WHERE match('pattern', rowid, 'pattern2');
982  }
983  set echo_module
984} [list \
985  xBestIndex {SELECT rowid, * FROM 'r'} \
986  xFilter {SELECT rowid, * FROM 'r'}    \
987]
988
989
990# Testing the xFindFunction interface
991#
992catch {rename ::echo_glob_overload {}}
993do_test vtab1.11-1 {
994  execsql {
995    INSERT INTO r(a,b,c) VALUES(1,'?',99);
996    INSERT INTO r(a,b,c) VALUES(2,3,99);
997    SELECT a GLOB b FROM e
998  }
999} {1 0}
1000proc ::echo_glob_overload {a b} {
1001 return [list $b $a]
1002}
1003do_test vtab1.11-2 {
1004  execsql {
1005    SELECT a like 'b' FROM e
1006  }
1007} {0 0}
1008do_test vtab1.11-3 {
1009  execsql {
1010    SELECT a glob '2' FROM e
1011  }
1012} {{1 2} {2 2}}
1013do_test vtab1.11-4 {
1014  execsql {
1015    SELECT  glob('2',a) FROM e
1016  }
1017} {0 1}
1018do_test vtab1.11-5 {
1019  execsql {
1020    SELECT  glob(a,'2') FROM e
1021  }
1022} {{2 1} {2 2}}
1023
1024#----------------------------------------------------------------------
1025# Test the outcome if a constraint is encountered half-way through
1026# a multi-row INSERT that is inside a transaction
1027#
1028do_test vtab1.12-1 {
1029  execsql {
1030    CREATE TABLE b(a, b, c);
1031    CREATE TABLE c(a UNIQUE, b, c);
1032    INSERT INTO b VALUES(1, 'A', 'B');
1033    INSERT INTO b VALUES(2, 'C', 'D');
1034    INSERT INTO b VALUES(3, 'E', 'F');
1035    INSERT INTO c VALUES(3, 'G', 'H');
1036    CREATE VIRTUAL TABLE echo_c USING echo(c);
1037  }
1038} {}
1039
1040# First test outside of a transaction.
1041do_test vtab1.12-2 {
1042  catchsql { INSERT INTO echo_c SELECT * FROM b; }
1043} {1 {echo-vtab-error: UNIQUE constraint failed: c.a}}
1044do_test vtab1.12-2.1 {
1045  sqlite3_errmsg db
1046} {echo-vtab-error: UNIQUE constraint failed: c.a}
1047do_test vtab1.12-3 {
1048  execsql { SELECT * FROM c }
1049} {3 G H}
1050
1051# Now the real test - wrapped in a transaction.
1052do_test vtab1.12-4 {
1053  execsql  {BEGIN}
1054  catchsql { INSERT INTO echo_c SELECT * FROM b; }
1055} {1 {echo-vtab-error: UNIQUE constraint failed: c.a}}
1056do_test vtab1.12-5 {
1057  execsql { SELECT * FROM c }
1058} {3 G H}
1059do_test vtab1.12-6 {
1060  execsql { COMMIT }
1061  execsql { SELECT * FROM c }
1062} {3 G H}
1063
1064# At one point (ticket #2759), a WHERE clause of the form "<column> IS NULL"
1065# on a virtual table was causing an assert() to fail in the compiler.
1066#
1067# "IS NULL" clauses should not be passed through to the virtual table
1068# implementation. They are handled by SQLite after the vtab returns its
1069# data.
1070#
1071do_test vtab1.13-1 {
1072  execsql {
1073    SELECT * FROM echo_c WHERE a IS NULL
1074  }
1075} {}
1076do_test vtab1.13-2 {
1077  execsql {
1078    INSERT INTO c VALUES(NULL, 15, 16);
1079    SELECT * FROM echo_c WHERE a IS NULL
1080  }
1081} {{} 15 16}
1082do_test vtab1.13-3 {
1083  execsql {
1084    INSERT INTO c VALUES(15, NULL, 16);
1085    SELECT * FROM echo_c WHERE b IS NULL
1086  }
1087} {15 {} 16}
1088do_test vtab1.13-3 {
1089  execsql {
1090    SELECT * FROM echo_c WHERE b IS NULL AND a = 15;
1091  }
1092} {15 {} 16}
1093
1094
1095do_test vtab1-14.001 {
1096  execsql {SELECT rowid, * FROM echo_c WHERE +rowid IN (1,2,3)}
1097} {1 3 G H 2 {} 15 16 3 15 {} 16}
1098do_test vtab1-14.002 {
1099  execsql {SELECT rowid, * FROM echo_c WHERE rowid IN (1,2,3)}
1100} {1 3 G H 2 {} 15 16 3 15 {} 16}
1101do_test vtab1-14.003 {
1102  execsql {SELECT rowid, * FROM echo_c WHERE +rowid IN (0,1,5,2,'a',3,NULL)}
1103} {1 3 G H 2 {} 15 16 3 15 {} 16}
1104do_test vtab1-14.004 {
1105  execsql {SELECT rowid, * FROM echo_c WHERE rowid IN (0,1,5,'a',2,3,NULL)}
1106} {1 3 G H 2 {} 15 16 3 15 {} 16}
1107do_test vtab1-14.005 {
1108  execsql {SELECT rowid, * FROM echo_c WHERE rowid NOT IN (0,1,5,'a',2,3)}
1109} {}
1110do_test vtab1-14.006 {
1111  execsql {SELECT rowid, * FROM echo_c WHERE rowid NOT IN (0,5,'a',2,3)}
1112} {1 3 G H}
1113do_test vtab1-14.007 {
1114  execsql {SELECT rowid, * FROM echo_c WHERE +rowid NOT IN (0,5,'a',2,3,NULL)}
1115} {}
1116do_test vtab1-14.008 {
1117  execsql {SELECT rowid, * FROM echo_c WHERE rowid NOT IN (0,5,'a',2,3,NULL)}
1118} {}
1119do_test vtab1-14.011 {
1120  execsql {SELECT * FROM echo_c WHERE +a IN (1,3,8,'x',NULL,15,24)}
1121} {3 G H 15 {} 16}
1122do_test vtab1-14.012 {
1123  execsql {SELECT * FROM echo_c WHERE a IN (1,3,8,'x',NULL,15,24)}
1124} {3 G H 15 {} 16}
1125do_test vtab1-14.013 {
1126  execsql {SELECT * FROM echo_c WHERE a NOT IN (1,8,'x',15,24)}
1127} {3 G H}
1128do_test vtab1-14.014 {
1129  execsql {SELECT * FROM echo_c WHERE a NOT IN (1,8,'x',NULL,15,24)}
1130} {}
1131do_test vtab1-14.015 {
1132  execsql {SELECT * FROM echo_c WHERE +a NOT IN (1,8,'x',NULL,15,24)}
1133} {}
1134
1135
1136
1137#do_test vtab1-14.1 {
1138#  execsql { DELETE FROM c }
1139#  set echo_module ""
1140#  execsql { SELECT * FROM echo_c WHERE rowid IN (1, 2, 3) }
1141#  set echo_module
1142#} {/.*xBestIndex {SELECT rowid, . FROM 'c' WHERE rowid = .} xFilter {SELECT rowid, . FROM 'c'} 1/}
1143
1144do_test vtab1-14.2 {
1145  set echo_module ""
1146  execsql { SELECT * FROM echo_c WHERE rowid = 1 }
1147  set echo_module
1148} [list xBestIndex {SELECT rowid, * FROM 'c' WHERE rowid = ?} xFilter {SELECT rowid, * FROM 'c' WHERE rowid = ?} 1]
1149
1150do_test vtab1-14.3 {
1151  set echo_module ""
1152  execsql { SELECT * FROM echo_c WHERE a = 1 }
1153  set echo_module
1154} [list xBestIndex {SELECT rowid, * FROM 'c' WHERE a = ?} xFilter {SELECT rowid, * FROM 'c' WHERE a = ?} 1]
1155
1156#do_test vtab1-14.4 {
1157#  set echo_module ""
1158#  execsql { SELECT * FROM echo_c WHERE a IN (1, 2) }
1159#  set echo_module
1160#} {/xBestIndex {SELECT rowid, . FROM 'c' WHERE a = .} xFilter {SELECT rowid, . FROM 'c' WHERE a = .} 1/}
1161
1162do_test vtab1-15.1 {
1163  execsql {
1164    CREATE TABLE t1(a, b, c);
1165    CREATE VIRTUAL TABLE echo_t1 USING echo(t1);
1166  }
1167} {}
1168do_test vtab1-15.2 {
1169  execsql {
1170    INSERT INTO echo_t1(rowid) VALUES(45);
1171    SELECT rowid, * FROM echo_t1;
1172  }
1173} {45 {} {} {}}
1174do_test vtab1-15.3 {
1175  execsql {
1176    INSERT INTO echo_t1(rowid) VALUES(NULL);
1177    SELECT rowid, * FROM echo_t1;
1178  }
1179} {45 {} {} {} 46 {} {} {}}
1180do_test vtab1-15.4 {
1181  catchsql {
1182    INSERT INTO echo_t1(rowid) VALUES('new rowid');
1183  }
1184} {1 {datatype mismatch}}
1185
1186# The following tests - vtab1-16.* - are designed to test that setting
1187# sqlite3_vtab.zErrMsg variable can be used by the vtab interface to
1188# return an error message to the user.
1189#
1190do_test vtab1-16.1 {
1191  execsql {
1192    CREATE TABLE t2(a PRIMARY KEY, b, c);
1193    INSERT INTO t2 VALUES(1, 2, 3);
1194    INSERT INTO t2 VALUES(4, 5, 6);
1195    CREATE VIRTUAL TABLE echo_t2 USING echo(t2);
1196  }
1197} {}
1198
1199set tn 2
1200foreach method [list \
1201    xBestIndex       \
1202    xOpen            \
1203    xFilter          \
1204    xNext            \
1205    xColumn          \
1206    xRowid           \
1207] {
1208  do_test vtab1-16.$tn {
1209    set echo_module_fail($method,t2) "the $method method has failed"
1210    catchsql { SELECT rowid, * FROM echo_t2 WHERE a >= 1 }
1211  } "1 {echo-vtab-error: the $method method has failed}"
1212  unset echo_module_fail($method,t2)
1213  incr tn
1214}
1215
1216foreach method [list \
1217  xUpdate            \
1218  xBegin             \
1219  xSync              \
1220] {
1221  do_test vtab1-16.$tn {
1222    set echo_module_fail($method,t2) "the $method method has failed"
1223    catchsql { INSERT INTO echo_t2 VALUES(7, 8, 9) }
1224  } "1 {echo-vtab-error: the $method method has failed}"
1225  unset echo_module_fail($method,t2)
1226  incr tn
1227}
1228
1229ifcapable altertable {
1230  do_test vtab1-16.$tn {
1231    set echo_module_fail(xRename,t2) "the xRename method has failed"
1232    catchsql { ALTER TABLE echo_t2 RENAME TO another_name }
1233  } "1 {echo-vtab-error: the xRename method has failed}"
1234  unset echo_module_fail(xRename,t2)
1235  incr tn
1236}
1237
1238# The following test case exposes an instance in sqlite3_declare_vtab()
1239# an error message was set using a call similar to sqlite3_mprintf(zErr),
1240# where zErr is an arbitrary string. This is no good if the string contains
1241# characters that can be mistaken for printf() formatting directives.
1242#
1243do_test vtab1-17.1 {
1244  execsql {
1245    PRAGMA writable_schema = 1;
1246    INSERT INTO sqlite_master VALUES(
1247      'table', 't3', 't3', 0, 'INSERT INTO "%s%s" VALUES(1)'
1248    );
1249  }
1250  catchsql { CREATE VIRTUAL TABLE t4 USING echo(t3); }
1251} {1 {vtable constructor failed: t4}}
1252
1253# This test verifies that ticket 48f29963 is fixed.
1254#
1255do_test vtab1-17.1 {
1256  execsql {
1257    CREATE TABLE t5(a, b);
1258    CREATE VIRTUAL TABLE e5 USING echo_v2(t5);
1259    BEGIN;
1260      INSERT INTO e5 VALUES(1, 2);
1261      DROP TABLE e5;
1262      SAVEPOINT one;
1263      ROLLBACK TO one;
1264    COMMIT;
1265  }
1266} {}
1267
1268do_test vtab1-17.2 {
1269  execsql { DELETE FROM sqlite_master WHERE sql LIKE 'insert%' }
1270} {}
1271
1272#-------------------------------------------------------------------------
1273# The following tests - vtab1-18.* - test that the optimization of LIKE
1274# constraints in where.c plays well with virtual tables.
1275#
1276#   18.1.*: Case-insensitive LIKE.
1277#   18.2.*: Case-sensitive LIKE.
1278#
1279unset -nocomplain echo_module_begin_fail
1280
1281do_execsql_test 18.1.0 {
1282  CREATE TABLE t6(a, b TEXT);
1283  CREATE INDEX i6 ON t6(b, a);
1284  INSERT INTO t6 VALUES(1, 'Peter');
1285  INSERT INTO t6 VALUES(2, 'Andrew');
1286  INSERT INTO t6 VALUES(3, 'James');
1287  INSERT INTO t6 VALUES(4, 'John');
1288  INSERT INTO t6 VALUES(5, 'Phillip');
1289  INSERT INTO t6 VALUES(6, 'Bartholomew');
1290  CREATE VIRTUAL TABLE e6 USING echo(t6);
1291}
1292
1293foreach {tn sql res filter} {
1294  1.1 "SELECT a FROM e6 WHERE b>'James'" {4 1 5}
1295    {xFilter {SELECT rowid, * FROM 't6' WHERE b > ?} James}
1296
1297  1.2 "SELECT a FROM e6 WHERE b>='J' AND b<'K'" {3 4}
1298    {xFilter {SELECT rowid, * FROM 't6' WHERE b >= ? AND b < ?} J K}
1299
1300  1.3 "SELECT a FROM e6 WHERE b LIKE 'J%'" {3 4}
1301    {xFilter {SELECT rowid, * FROM 't6'}}
1302
1303  1.4 "SELECT a FROM e6 WHERE b LIKE 'j%'" {3 4}
1304    {xFilter {SELECT rowid, * FROM 't6'}}
1305} {
1306  set echo_module {}
1307  do_execsql_test 18.$tn.1 $sql $res
1308  do_test         18.$tn.2 { lrange $::echo_module 2 end } $filter
1309}
1310
1311do_execsql_test 18.2.0 {  PRAGMA case_sensitive_like = ON }
1312foreach {tn sql res filter} {
1313  2.1 "SELECT a FROM e6 WHERE b LIKE 'J%'" {3 4}
1314    {xFilter {SELECT rowid, * FROM 't6'}}
1315
1316  2.2 "SELECT a FROM e6 WHERE b LIKE 'j%'" {}
1317    {xFilter {SELECT rowid, * FROM 't6'}}
1318} {
1319  set echo_module {}
1320  do_execsql_test 18.$tn.1 $sql $res
1321  do_test         18.$tn.2 { lrange $::echo_module 2 end } $filter
1322}
1323do_execsql_test 18.2.x {  PRAGMA case_sensitive_like = OFF }
1324
1325#-------------------------------------------------------------------------
1326# Test that an existing module may not be overridden.
1327#
1328do_test 19.1 {
1329  sqlite3 db2 test.db
1330  register_echo_module [sqlite3_connection_pointer db2]
1331} SQLITE_OK
1332do_test 19.2 {
1333  register_echo_module [sqlite3_connection_pointer db2]
1334} SQLITE_MISUSE
1335do_test 19.3 {
1336  db2 close
1337} {}
1338
1339#-------------------------------------------------------------------------
1340# Test that the bug fixed by [b0c1ba655d69] really is fixed.
1341#
1342do_execsql_test 20.1 {
1343  CREATE TABLE t7 (a, b);
1344  CREATE TABLE t8 (c, d);
1345  CREATE INDEX i2 ON t7(a);
1346  CREATE INDEX i3 ON t7(b);
1347  CREATE INDEX i4 ON t8(c);
1348  CREATE INDEX i5 ON t8(d);
1349
1350  CREATE VIRTUAL TABLE t7v USING echo(t7);
1351  CREATE VIRTUAL TABLE t8v USING echo(t8);
1352}
1353
1354do_test 20.2 {
1355  for {set i 0} {$i < 1000} {incr i} {
1356    db eval {INSERT INTO t7 VALUES($i, $i)}
1357    db eval {INSERT INTO t8 VALUES($i, $i)}
1358  }
1359} {}
1360
1361do_execsql_test 20.3 {
1362  SELECT a, b FROM (
1363      SELECT a, b FROM t7 WHERE a=11 OR b=12
1364      UNION ALL
1365      SELECT c, d FROM t8 WHERE c=5 OR d=6
1366  )
1367  ORDER BY 1, 2;
1368} {5 5 6 6 11 11 12 12}
1369
1370do_execsql_test 20.4 {
1371  SELECT a, b FROM (
1372      SELECT a, b FROM t7v WHERE a=11 OR b=12
1373      UNION ALL
1374      SELECT c, d FROM t8v WHERE c=5 OR d=6
1375  )
1376  ORDER BY 1, 2;
1377} {5 5 6 6 11 11 12 12}
1378
1379#-------------------------------------------------------------------------
1380#
1381do_execsql_test 21.1 {
1382  CREATE TABLE t9(a,b,c);
1383  CREATE VIRTUAL TABLE t9v USING echo(t9);
1384
1385  INSERT INTO t9 VALUES(1,2,3);
1386  INSERT INTO t9 VALUES(3,2,1);
1387  INSERT INTO t9 VALUES(2,2,2);
1388}
1389
1390do_execsql_test 21.2 {
1391  SELECT * FROM t9v WHERE a<b;
1392} {1 2 3}
1393
1394do_execsql_test 21.3 {
1395  SELECT * FROM t9v WHERE a=b;
1396} {2 2 2}
1397
1398finish_test
1399