xref: /sqlite-3.40.0/test/vtab1.test (revision 8a29dfde)
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.52 2008/04/10 16:42:59 drh Exp $
15
16set testdir [file dirname $argv0]
17source $testdir/tester.tcl
18
19ifcapable !vtab||!schema_pragmas {
20  finish_test
21  return
22}
23
24#----------------------------------------------------------------------
25# Organization of tests in this file:
26#
27# vtab1-1.*: Error conditions and other issues surrounding creation/connection
28#            of a virtual module.
29# vtab1-2.*: Test sqlite3_declare_vtab() and the xConnect/xDisconnect methods.
30# vtab1-3.*: Table scans and WHERE clauses.
31# vtab1-4.*: Table scans and ORDER BY clauses.
32# vtab1-5.*: Test queries that include joins. This brings the
33#            sqlite3_index_info.estimatedCost variable into play.
34# vtab1-6.*: Test UPDATE/INSERT/DELETE on vtables.
35# vtab1-7.*: Test sqlite3_last_insert_rowid().
36#
37# This file uses the "echo" module (see src/test8.c). Refer to comments
38# in that file for the special behaviour of the Tcl $echo_module variable.
39#
40# TODO:
41#   * How to test the sqlite3_index_constraint_usage.omit field?
42#   * vtab1-5.*
43#
44
45
46#----------------------------------------------------------------------
47# Test cases vtab1.1.*
48#
49
50# We cannot create a virtual table if the module has not been registered.
51#
52do_test vtab1-1.1 {
53  catchsql {
54    CREATE VIRTUAL TABLE t1 USING echo;
55  }
56} {1 {no such module: echo}}
57do_test vtab1-1.2 {
58  execsql {
59    SELECT name FROM sqlite_master ORDER BY 1
60  }
61} {}
62
63# Register the module
64register_echo_module [sqlite3_connection_pointer db]
65
66# Once a module has been registered, virtual tables using that module
67# may be created. However if a module xCreate() fails to call
68# sqlite3_declare_vtab() an error will be raised and the table not created.
69#
70# The "echo" module does not invoke sqlite3_declare_vtab() if it is
71# passed zero arguments.
72#
73do_test vtab1-1.3 {
74  catchsql {
75    CREATE VIRTUAL TABLE t1 USING echo;
76  }
77} {1 {vtable constructor did not declare schema: t1}}
78do_test vtab1-1.4 {
79  execsql {
80    SELECT name FROM sqlite_master ORDER BY 1
81  }
82} {}
83
84# The "echo" module xCreate method returns an error and does not create
85# the virtual table if it is passed an argument that does not correspond
86# to an existing real table in the same database.
87#
88do_test vtab1-1.5 {
89  catchsql {
90    CREATE VIRTUAL TABLE t1 USING echo(no_such_table);
91  }
92} {1 {vtable constructor failed: t1}}
93do_test vtab1-1.6 {
94  execsql {
95    SELECT name FROM sqlite_master ORDER BY 1
96  }
97} {}
98
99# Ticket #2156.  Using the sqlite3_prepare_v2() API, make sure that
100# a CREATE VIRTUAL TABLE statement can be used multiple times.
101#
102do_test vtab1-1.2152.1 {
103  set DB [sqlite3_connection_pointer db]
104  set sql {CREATE VIRTUAL TABLE t2152a USING echo(t2152b)}
105  set STMT [sqlite3_prepare_v2 $DB $sql -1 TAIL]
106  sqlite3_step $STMT
107} SQLITE_ERROR
108do_test vtab-1.2152.2 {
109  sqlite3_reset $STMT
110  sqlite3_step $STMT
111} SQLITE_ERROR
112do_test vtab-1.2152.3 {
113  sqlite3_reset $STMT
114  db eval {CREATE TABLE t2152b(x,y)}
115  sqlite3_step $STMT
116} SQLITE_DONE
117do_test vtab-1.2152.4 {
118  sqlite3_finalize $STMT
119  db eval {DROP TABLE t2152a; DROP TABLE t2152b}
120} {}
121
122# Test to make sure nothing goes wrong and no memory is leaked if we
123# select an illegal table-name (i.e a reserved name or the name of a
124# table that already exists).
125#
126do_test vtab1-1.7 {
127  catchsql {
128    CREATE VIRTUAL TABLE sqlite_master USING echo;
129  }
130} {1 {object name reserved for internal use: sqlite_master}}
131do_test vtab1-1.8 {
132  catchsql {
133    CREATE TABLE treal(a, b, c);
134    CREATE VIRTUAL TABLE treal USING echo(treal);
135  }
136} {1 {table treal already exists}}
137do_test vtab1-1.9 {
138  execsql {
139    DROP TABLE treal;
140    SELECT name FROM sqlite_master ORDER BY 1
141  }
142} {}
143
144do_test vtab1-1.10 {
145  execsql {
146    CREATE TABLE treal(a, b, c);
147    CREATE VIRTUAL TABLE techo USING echo(treal);
148  }
149  db close
150  sqlite3 db test.db
151  catchsql {
152    SELECT * FROM techo;
153  }
154} {1 {no such module: echo}}
155do_test vtab1-1.11 {
156  catchsql {
157    INSERT INTO techo VALUES(1, 2, 3);
158  }
159} {1 {no such module: echo}}
160do_test vtab1-1.12 {
161  catchsql {
162    UPDATE techo SET a = 10;
163  }
164} {1 {no such module: echo}}
165do_test vtab1-1.13 {
166  catchsql {
167    DELETE FROM techo;
168  }
169} {1 {no such module: echo}}
170do_test vtab1-1.14 {
171  catchsql {
172    PRAGMA table_info(techo)
173  }
174} {1 {no such module: echo}}
175do_test vtab1-1.15 {
176  catchsql {
177    DROP TABLE techo;
178  }
179} {1 {no such module: echo}}
180
181register_echo_module [sqlite3_connection_pointer db]
182register_echo_module [sqlite3_connection_pointer db]
183
184# Test an error message returned from a v-table constructor.
185#
186do_test vtab1-1.16 {
187  execsql {
188    DROP TABLE techo;
189    CREATE TABLE logmsg(log);
190  }
191  catchsql {
192    CREATE VIRTUAL TABLE techo USING echo(treal, logmsg);
193  }
194} {1 {table 'logmsg' already exists}}
195
196do_test vtab1-1.17 {
197  execsql {
198    DROP TABLE treal;
199    DROP TABLE logmsg;
200    SELECT sql FROM sqlite_master;
201  }
202} {}
203
204#----------------------------------------------------------------------
205# Test cases vtab1.2.*
206#
207# At this point, the database is completely empty. The echo module
208# has already been registered.
209
210# If a single argument is passed to the echo module during table
211# creation, it is assumed to be the name of a table in the same
212# database. The echo module attempts to set the schema of the
213# new virtual table to be the same as the existing database table.
214#
215do_test vtab1-2.1 {
216  execsql {
217    CREATE TABLE template(a, b, c);
218  }
219  execsql { PRAGMA table_info(template); }
220} [list         \
221  0 a {} 0 {} 0 \
222  1 b {} 0 {} 0 \
223  2 c {} 0 {} 0 \
224]
225do_test vtab1-2.2 {
226  execsql {
227    CREATE VIRTUAL TABLE t1 USING echo(template);
228  }
229  execsql { PRAGMA table_info(t1); }
230} [list         \
231  0 a {} 0 {} 0 \
232  1 b {} 0 {} 0 \
233  2 c {} 0 {} 0 \
234]
235
236# Test that the database can be unloaded. This should invoke the xDisconnect()
237# callback for the successfully create virtual table (t1).
238#
239do_test vtab1-2.3 {
240  set echo_module [list]
241  db close
242  set echo_module
243} [list xDisconnect]
244
245# Re-open the database. This should not cause any virtual methods to
246# be called. The invocation of xConnect() is delayed until the virtual
247# table schema is first required by the compiler.
248#
249do_test vtab1-2.4 {
250  set echo_module [list]
251  sqlite3 db test.db
252  db cache size 0
253  set echo_module
254} {}
255
256# Try to query the virtual table schema. This should fail, as the
257# echo module has not been registered with this database connection.
258#
259do_test vtab1.2.6 {
260  catchsql { PRAGMA table_info(t1); }
261} {1 {no such module: echo}}
262
263# Register the module
264register_echo_module [sqlite3_connection_pointer db]
265
266# Try to query the virtual table schema again. This time it should
267# invoke the xConnect method and succeed.
268#
269do_test vtab1.2.7 {
270  execsql { PRAGMA table_info(t1); }
271} [list         \
272  0 a {} 0 {} 0 \
273  1 b {} 0 {} 0 \
274  2 c {} 0 {} 0 \
275]
276do_test vtab1.2.8 {
277  set echo_module
278} {xConnect echo main t1 template}
279
280# Drop table t1. This should cause the xDestroy (but not xDisconnect) method
281# to be invoked.
282do_test vtab1-2.5 {
283  set echo_module ""
284  execsql {
285    DROP TABLE t1;
286  }
287  set echo_module
288} {xDestroy}
289
290do_test vtab1-2.6 {
291  execsql {
292    PRAGMA table_info(t1);
293  }
294} {}
295do_test vtab1-2.7 {
296  execsql {
297    SELECT sql FROM sqlite_master;
298  }
299} [list {CREATE TABLE template(a, b, c)}]
300# Clean up other test artifacts:
301do_test vtab1-2.8 {
302  execsql {
303    DROP TABLE template;
304    SELECT sql FROM sqlite_master;
305  }
306} [list]
307
308#----------------------------------------------------------------------
309# Test case vtab1-3 test table scans and the echo module's
310# xBestIndex/xFilter handling of WHERE conditions.
311
312do_test vtab1-3.1 {
313  set echo_module ""
314  execsql {
315    CREATE TABLE treal(a INTEGER, b INTEGER, c);
316    CREATE INDEX treal_idx ON treal(b);
317    CREATE VIRTUAL TABLE t1 USING echo(treal);
318  }
319  set echo_module
320} [list xCreate echo main t1 treal   \
321        xSync   echo(treal)  \
322        xCommit echo(treal)  \
323]
324
325# Test that a SELECT on t1 doesn't crash. No rows are returned
326# because the underlying real table is currently empty.
327#
328do_test vtab1-3.2 {
329  execsql {
330    SELECT a, b, c FROM t1;
331  }
332} {}
333
334# Put some data into the table treal. Then try a few simple SELECT
335# statements on t1.
336#
337do_test vtab1-3.3 {
338  execsql {
339    INSERT INTO treal VALUES(1, 2, 3);
340    INSERT INTO treal VALUES(4, 5, 6);
341    SELECT * FROM t1;
342  }
343} {1 2 3 4 5 6}
344do_test vtab1-3.4 {
345  execsql {
346    SELECT a FROM t1;
347  }
348} {1 4}
349do_test vtab1-3.5 {
350  execsql {
351    SELECT rowid FROM t1;
352  }
353} {1 2}
354do_test vtab1-3.6 {
355  set echo_module ""
356  execsql {
357    SELECT * FROM t1;
358  }
359} {1 2 3 4 5 6}
360do_test vtab1-3.7 {
361  execsql {
362    SELECT rowid, * FROM t1;
363  }
364} {1 1 2 3 2 4 5 6}
365do_test vtab1-3.8 {
366  execsql {
367    SELECT a AS d, b AS e, c AS f FROM t1;
368  }
369} {1 2 3 4 5 6}
370
371# Execute some SELECT statements with WHERE clauses on the t1 table.
372# Then check the echo_module variable (written to by the module methods
373# in test8.c) to make sure the xBestIndex() and xFilter() methods were
374# called correctly.
375#
376do_test vtab1-3.8 {
377  set echo_module ""
378  execsql {
379    SELECT * FROM t1;
380  }
381  set echo_module
382} [list xBestIndex {SELECT rowid, * FROM 'treal'} \
383        xFilter    {SELECT rowid, * FROM 'treal'} ]
384do_test vtab1-3.9 {
385  set echo_module ""
386  execsql {
387    SELECT * FROM t1 WHERE b = 5;
388  }
389} {4 5 6}
390do_test vtab1-3.10 {
391  set echo_module
392} [list xBestIndex {SELECT rowid, * FROM 'treal' WHERE b = ?}   \
393        xFilter    {SELECT rowid, * FROM 'treal' WHERE b = ?} 5 ]
394do_test vtab1-3.10 {
395  set echo_module ""
396  execsql {
397    SELECT * FROM t1 WHERE b >= 5 AND b <= 10;
398  }
399} {4 5 6}
400do_test vtab1-3.11 {
401  set echo_module
402} [list xBestIndex {SELECT rowid, * FROM 'treal' WHERE b >= ? AND b <= ?}      \
403        xFilter    {SELECT rowid, * FROM 'treal' WHERE b >= ? AND b <= ?} 5 10 ]
404do_test vtab1-3.12 {
405  set echo_module ""
406  execsql {
407    SELECT * FROM t1 WHERE b BETWEEN 2 AND 10;
408  }
409} {1 2 3 4 5 6}
410do_test vtab1-3.13 {
411  set echo_module
412} [list xBestIndex {SELECT rowid, * FROM 'treal' WHERE b >= ? AND b <= ?}      \
413        xFilter    {SELECT rowid, * FROM 'treal' WHERE b >= ? AND b <= ?} 2 10 ]
414
415# Add a function for the MATCH operator. Everything always matches!
416#proc test_match {lhs rhs} {
417#  lappend ::echo_module MATCH $lhs $rhs
418#  return 1
419#}
420#db function match test_match
421
422set echo_module ""
423do_test vtab1-3.12 {
424  set echo_module ""
425  catchsql {
426    SELECT * FROM t1 WHERE a MATCH 'string';
427  }
428} {1 {unable to use function MATCH in the requested context}}
429do_test vtab1-3.13 {
430  set echo_module
431} [list xBestIndex {SELECT rowid, * FROM 'treal'} \
432        xFilter    {SELECT rowid, * FROM 'treal'}]
433ifcapable subquery {
434# The echo module uses a subquery internally to implement the MATCH operator.
435do_test vtab1-3.14 {
436  set echo_module ""
437  execsql {
438    SELECT * FROM t1 WHERE b MATCH 'string';
439  }
440} {}
441do_test vtab1-3.15 {
442  set echo_module
443} [list xBestIndex \
444        {SELECT rowid, * FROM 'treal' WHERE b LIKE (SELECT '%'||?||'%')}  \
445        xFilter \
446        {SELECT rowid, * FROM 'treal' WHERE b LIKE (SELECT '%'||?||'%')} \
447        string ]
448}; #ifcapable subquery
449
450#----------------------------------------------------------------------
451# Test case vtab1-3 test table scans and the echo module's
452# xBestIndex/xFilter handling of ORDER BY clauses.
453
454# This procedure executes the SQL.  Then it checks to see if the OP_Sort
455# opcode was executed.  If an OP_Sort did occur, then "sort" is appended
456# to the result.  If no OP_Sort happened, then "nosort" is appended.
457#
458# This procedure is used to check to make sure sorting is or is not
459# occurring as expected.
460#
461proc cksort {sql} {
462  set ::sqlite_sort_count 0
463  set data [execsql $sql]
464  if {$::sqlite_sort_count} {set x sort} {set x nosort}
465  lappend data $x
466  return $data
467}
468
469do_test vtab1-4.1 {
470  set echo_module ""
471  cksort {
472    SELECT b FROM t1 ORDER BY b;
473  }
474} {2 5 nosort}
475do_test vtab1-4.2 {
476  set echo_module
477} [list xBestIndex {SELECT rowid, * FROM 'treal' ORDER BY b ASC} \
478        xFilter    {SELECT rowid, * FROM 'treal' ORDER BY b ASC} ]
479do_test vtab1-4.3 {
480  set echo_module ""
481  cksort {
482    SELECT b FROM t1 ORDER BY b DESC;
483  }
484} {5 2 nosort}
485do_test vtab1-4.4 {
486  set echo_module
487} [list xBestIndex {SELECT rowid, * FROM 'treal' ORDER BY b DESC} \
488        xFilter    {SELECT rowid, * FROM 'treal' ORDER BY b DESC} ]
489do_test vtab1-4.3 {
490  set echo_module ""
491  cksort {
492    SELECT b FROM t1 ORDER BY b||'';
493  }
494} {2 5 sort}
495do_test vtab1-4.4 {
496  set echo_module
497} [list xBestIndex {SELECT rowid, * FROM 'treal'} \
498        xFilter    {SELECT rowid, * FROM 'treal'} ]
499
500execsql {
501  DROP TABLE t1;
502  DROP TABLE treal;
503}
504
505#----------------------------------------------------------------------
506# Test cases vtab1-5 test SELECT queries that include joins on virtual
507# tables.
508
509proc filter {log} {
510  set out [list]
511  for {set ii 0} {$ii < [llength $log]} {incr ii} {
512    if {[lindex $log $ii] eq "xFilter"} {
513      lappend out xFilter
514      lappend out [lindex $log [expr $ii+1]]
515    }
516  }
517  return $out
518}
519
520do_test vtab1-5-1 {
521  execsql {
522    CREATE TABLE t1(a, b, c);
523    CREATE TABLE t2(d, e, f);
524    INSERT INTO t1 VALUES(1, 'red', 'green');
525    INSERT INTO t1 VALUES(2, 'blue', 'black');
526    INSERT INTO t2 VALUES(1, 'spades', 'clubs');
527    INSERT INTO t2 VALUES(2, 'hearts', 'diamonds');
528    CREATE VIRTUAL TABLE et1 USING echo(t1);
529    CREATE VIRTUAL TABLE et2 USING echo(t2);
530  }
531} {}
532
533do_test vtab1-5-2 {
534  set echo_module ""
535  execsql {
536    SELECT * FROM et1, et2;
537  }
538} [list \
539  1 red green 1 spades clubs     \
540  1 red green 2 hearts diamonds  \
541  2 blue black 1 spades clubs    \
542  2 blue black 2 hearts diamonds \
543]
544do_test vtab1-5-3 {
545  filter $echo_module
546} [list \
547  xFilter {SELECT rowid, * FROM 't1'} \
548  xFilter {SELECT rowid, * FROM 't2'} \
549  xFilter {SELECT rowid, * FROM 't2'} \
550]
551do_test vtab1-5-4 {
552  set echo_module ""
553  execsql {
554    SELECT * FROM et1, et2 WHERE et2.d = 2;
555  }
556} [list \
557  1 red green 2 hearts diamonds  \
558  2 blue black 2 hearts diamonds \
559]
560do_test vtab1-5-5 {
561  filter $echo_module
562} [list \
563  xFilter {SELECT rowid, * FROM 't1'} \
564  xFilter {SELECT rowid, * FROM 't2'} \
565  xFilter {SELECT rowid, * FROM 't2'} \
566]
567do_test vtab1-5-6 {
568  execsql {
569    CREATE INDEX i1 ON t2(d);
570  }
571
572  db close
573  sqlite3 db test.db
574  register_echo_module [sqlite3_connection_pointer db]
575
576  set ::echo_module ""
577  execsql {
578    SELECT * FROM et1, et2 WHERE et2.d = 2;
579  }
580} [list \
581  1 red green 2 hearts diamonds  \
582  2 blue black 2 hearts diamonds \
583]
584do_test vtab1-5-7 {
585  filter $::echo_module
586} [list \
587  xFilter {SELECT rowid, * FROM 't2' WHERE d = ?} \
588  xFilter {SELECT rowid, * FROM 't1'}             \
589]
590
591execsql {
592  DROP TABLE t1;
593  DROP TABLE t2;
594  DROP TABLE et1;
595  DROP TABLE et2;
596}
597
598#----------------------------------------------------------------------
599# Test cases vtab1-6 test INSERT, UPDATE and DELETE operations
600# on virtual tables.
601do_test vtab1-6-1 {
602  execsql { SELECT sql FROM sqlite_master }
603} {}
604do_test vtab1-6-2 {
605  execsql {
606    CREATE TABLE treal(a PRIMARY KEY, b, c);
607    CREATE VIRTUAL TABLE techo USING echo(treal);
608    SELECT name FROM sqlite_master WHERE type = 'table';
609  }
610} {treal techo}
611do_test vtab1-6-3.1.1 {
612  execsql {
613    PRAGMA count_changes=ON;
614    INSERT INTO techo VALUES(1, 2, 3);
615  }
616} {1}
617do_test vtab1-6-3.1.2 {
618  db changes
619} {1}
620do_test vtab1-6-3.2 {
621  execsql {
622    SELECT * FROM techo;
623  }
624} {1 2 3}
625do_test vtab1-6-4.1 {
626  execsql {
627    UPDATE techo SET a = 5;
628  }
629  db changes
630} {1}
631do_test vtab1-6-4.2 {
632  execsql {
633    SELECT * FROM techo;
634  }
635} {5 2 3}
636do_test vtab1-6-4.3 {
637  execsql {
638    UPDATE techo SET a=6 WHERE a<0;
639  }
640  db changes
641} {0}
642do_test vtab1-6-4.4 {
643  execsql {
644    SELECT * FROM techo;
645  }
646} {5 2 3}
647
648do_test vtab1-6-5.1 {
649 execsql {
650   UPDATE techo set a = a||b||c;
651 }
652 db changes
653} {1}
654do_test vtab1-6-5.2 {
655 execsql {
656   SELECT * FROM techo;
657 }
658} {523 2 3}
659
660do_test vtab1-6-6.1 {
661  execsql {
662    UPDATE techo set rowid = 10;
663  }
664  db changes
665} {1}
666do_test vtab1-6-6.2 {
667  execsql {
668    SELECT rowid FROM techo;
669  }
670} {10}
671
672do_test vtab1-6-7.1.1 {
673  execsql {
674    INSERT INTO techo VALUES(11,12,13);
675  }
676} {1}
677do_test vtab1-6-7.1.2 {
678  db changes
679} {1}
680do_test vtab1-6-7.2 {
681  execsql {
682    SELECT * FROM techo ORDER BY a;
683  }
684} {11 12 13 523 2 3}
685do_test vtab1-6-7.3 {
686  execsql {
687    UPDATE techo SET b=b+1000
688  }
689  db changes
690} {2}
691do_test vtab1-6-7.4 {
692  execsql {
693    SELECT * FROM techo ORDER BY a;
694  }
695} {11 1012 13 523 1002 3}
696
697
698do_test vtab1-6-8.1 {
699  execsql {
700    DELETE FROM techo WHERE a=5;
701  }
702  db changes
703} {0}
704do_test vtab1-6-8.2 {
705  execsql {
706    SELECT * FROM techo ORDER BY a;
707  }
708} {11 1012 13 523 1002 3}
709do_test vtab1-6-8.3 {
710  execsql {
711    DELETE FROM techo;
712  }
713  db changes
714} {2}
715do_test vtab1-6-8.4 {
716  execsql {
717    SELECT * FROM techo ORDER BY a;
718  }
719} {}
720execsql {PRAGMA count_changes=OFF}
721
722file delete -force test2.db
723file delete -force test2.db-journal
724sqlite3 db2 test2.db
725execsql {
726  CREATE TABLE techo(a PRIMARY KEY, b, c);
727} db2
728proc check_echo_table {tn} {
729  set ::data1 [execsql {SELECT rowid, * FROM techo}]
730  set ::data2 [execsql {SELECT rowid, * FROM techo} db2]
731  do_test $tn {
732    string equal $::data1 $::data2
733  } 1
734}
735set tn 0
736foreach stmt [list \
737  {INSERT INTO techo VALUES('abc', 'def', 'ghi')}                        \
738  {INSERT INTO techo SELECT a||'.'||rowid, b, c FROM techo}              \
739  {INSERT INTO techo SELECT a||'x'||rowid, b, c FROM techo}              \
740  {INSERT INTO techo SELECT a||'y'||rowid, b, c FROM techo}              \
741  {DELETE FROM techo WHERE (oid % 3) = 0}                                \
742  {UPDATE techo set rowid = 100 WHERE rowid = 1}                         \
743  {INSERT INTO techo(a, b) VALUES('hello', 'world')}                     \
744  {DELETE FROM techo}                                                    \
745] {
746  execsql $stmt
747  execsql $stmt db2
748  check_echo_table vtab1-6.8.[incr tn]
749}
750
751db2 close
752
753
754
755#----------------------------------------------------------------------
756# Test cases vtab1-7 tests that the value returned by
757# sqlite3_last_insert_rowid() is set correctly when rows are inserted
758# into virtual tables.
759do_test vtab1.7-1 {
760  execsql {
761    CREATE TABLE real_abc(a PRIMARY KEY, b, c);
762    CREATE VIRTUAL TABLE echo_abc USING echo(real_abc);
763  }
764} {}
765do_test vtab1.7-2 {
766  execsql {
767    INSERT INTO echo_abc VALUES(1, 2, 3);
768    SELECT last_insert_rowid();
769  }
770} {1}
771do_test vtab1.7-3 {
772  execsql {
773    INSERT INTO echo_abc(rowid) VALUES(31427);
774    SELECT last_insert_rowid();
775  }
776} {31427}
777do_test vtab1.7-4 {
778  execsql {
779    INSERT INTO echo_abc SELECT a||'.v2', b, c FROM echo_abc;
780    SELECT last_insert_rowid();
781  }
782} {31429}
783do_test vtab1.7-5 {
784  execsql {
785    SELECT rowid, a, b, c FROM echo_abc
786  }
787} [list 1     1    2  3  \
788        31427 {}   {} {} \
789        31428 1.v2 2  3  \
790        31429 {}  {} {}  \
791]
792
793# Now test that DELETE and UPDATE operations do not modify the value.
794do_test vtab1.7-6 {
795  execsql {
796    UPDATE echo_abc SET c = 5 WHERE b = 2;
797    SELECT last_insert_rowid();
798  }
799} {31429}
800do_test vtab1.7-7 {
801  execsql {
802    UPDATE echo_abc SET rowid = 5 WHERE rowid = 1;
803    SELECT last_insert_rowid();
804  }
805} {31429}
806do_test vtab1.7-8 {
807  execsql {
808    DELETE FROM echo_abc WHERE b = 2;
809    SELECT last_insert_rowid();
810  }
811} {31429}
812do_test vtab1.7-9 {
813  execsql {
814    SELECT rowid, a, b, c FROM echo_abc
815  }
816} [list 31427 {} {} {} \
817        31429 {} {} {} \
818]
819do_test vtab1.7-10 {
820  execsql {
821    DELETE FROM echo_abc WHERE b = 2;
822    SELECT last_insert_rowid();
823  }
824} {31429}
825do_test vtab1.7-11 {
826  execsql {
827    SELECT rowid, a, b, c FROM real_abc
828  }
829} [list 31427 {} {} {} \
830        31429 {} {} {} \
831]
832do_test vtab1.7-12 {
833  execsql {
834    DELETE FROM echo_abc;
835    SELECT last_insert_rowid();
836  }
837} {31429}
838do_test vtab1.7-13 {
839  execsql {
840    SELECT rowid, a, b, c FROM real_abc
841  }
842} {}
843
844ifcapable attach {
845  do_test vtab1.8-1 {
846    set echo_module ""
847    execsql {
848      ATTACH 'test2.db' AS aux;
849      CREATE VIRTUAL TABLE aux.e2 USING echo(real_abc);
850    }
851    set echo_module
852  } [list xCreate echo aux e2 real_abc   \
853          xSync   echo(real_abc)         \
854          xCommit echo(real_abc)         \
855  ]
856}
857do_test vtab1.8-2 {
858  catchsql {
859    DROP TABLE aux.e2;
860  }
861  execsql {
862    DROP TABLE treal;
863    DROP TABLE techo;
864    DROP TABLE echo_abc;
865    DROP TABLE real_abc;
866  }
867} {}
868
869do_test vtab1.9-1 {
870  set echo_module ""
871  execsql {
872    CREATE TABLE r(a, b, c);
873    CREATE VIRTUAL TABLE e USING echo(r, e_log);
874    SELECT name FROM sqlite_master;
875  }
876} {r e e_log}
877do_test vtab1.9-2 {
878  execsql {
879    DROP TABLE e;
880    SELECT name FROM sqlite_master;
881  }
882} {r}
883
884do_test vtab1.9-3 {
885  set echo_module ""
886  execsql {
887    CREATE VIRTUAL TABLE e USING echo(r, e_log, virtual 1 2 3 varchar(32));
888  }
889  set echo_module
890} [list                                                        \
891  xCreate echo main e r e_log {virtual 1 2 3 varchar(32)}      \
892  xSync echo(r)                                                \
893  xCommit echo(r)                                              \
894]
895
896do_test vtab1.10-1 {
897  execsql {
898    CREATE TABLE del(d);
899    CREATE VIRTUAL TABLE e2 USING echo(del);
900  }
901  db close
902  sqlite3 db test.db
903  register_echo_module [sqlite3_connection_pointer db]
904  execsql {
905    DROP TABLE del;
906  }
907  catchsql {
908    SELECT * FROM e2;
909  }
910} {1 {vtable constructor failed: e2}}
911do_test vtab1.10-2 {
912  set rc [catch {
913    set ptr [sqlite3_connection_pointer db]
914    sqlite3_declare_vtab $ptr {CREATE TABLE abc(a, b, c)}
915  } msg]
916  list $rc $msg
917} {1 {library routine called out of sequence}}
918do_test vtab1.10-3 {
919  set ::echo_module_begin_fail r
920  catchsql {
921    INSERT INTO e VALUES(1, 2, 3);
922  }
923} {1 {SQL logic error or missing database}}
924do_test vtab1.10-4 {
925  catch {execsql {
926    EXPLAIN SELECT * FROM e WHERE rowid = 2;
927    EXPLAIN QUERY PLAN SELECT * FROM e WHERE rowid = 2 ORDER BY rowid;
928  }}
929} {0}
930
931do_test vtab1.10-5 {
932  set echo_module ""
933  execsql {
934    SELECT * FROM e WHERE rowid||'' MATCH 'pattern';
935  }
936  set echo_module
937} [list \
938  xBestIndex {SELECT rowid, * FROM 'r'} \
939  xFilter {SELECT rowid, * FROM 'r'}    \
940]
941proc match_func {args} {return ""}
942do_test vtab1.10-6 {
943  set echo_module ""
944  db function match match_func
945  execsql {
946    SELECT * FROM e WHERE match('pattern', rowid, 'pattern2');
947  }
948  set echo_module
949} [list \
950  xBestIndex {SELECT rowid, * FROM 'r'} \
951  xFilter {SELECT rowid, * FROM 'r'}    \
952]
953
954
955# Testing the xFindFunction interface
956#
957catch {rename ::echo_glob_overload {}}
958do_test vtab1.11-1 {
959  execsql {
960    INSERT INTO r(a,b,c) VALUES(1,'?',99);
961    INSERT INTO r(a,b,c) VALUES(2,3,99);
962    SELECT a GLOB b FROM e
963  }
964} {1 0}
965proc ::echo_glob_overload {a b} {
966 return [list $b $a]
967}
968do_test vtab1.11-2 {
969  execsql {
970    SELECT a like 'b' FROM e
971  }
972} {0 0}
973do_test vtab1.11-3 {
974  execsql {
975    SELECT a glob '2' FROM e
976  }
977} {{1 2} {2 2}}
978do_test vtab1.11-4 {
979  execsql {
980    SELECT  glob('2',a) FROM e
981  }
982} {0 1}
983do_test vtab1.11-5 {
984  execsql {
985    SELECT  glob(a,'2') FROM e
986  }
987} {{2 1} {2 2}}
988
989#----------------------------------------------------------------------
990# Test the outcome if a constraint is encountered half-way through
991# a multi-row INSERT that is inside a transaction
992#
993do_test vtab1.12-1 {
994  execsql {
995    CREATE TABLE b(a, b, c);
996    CREATE TABLE c(a UNIQUE, b, c);
997    INSERT INTO b VALUES(1, 'A', 'B');
998    INSERT INTO b VALUES(2, 'C', 'D');
999    INSERT INTO b VALUES(3, 'E', 'F');
1000    INSERT INTO c VALUES(3, 'G', 'H');
1001    CREATE VIRTUAL TABLE echo_c USING echo(c);
1002  }
1003} {}
1004
1005# First test outside of a transaction.
1006do_test vtab1.12-2 {
1007  catchsql { INSERT INTO echo_c SELECT * FROM b; }
1008} {1 {constraint failed}}
1009do_test vtab1.12-3 {
1010  execsql { SELECT * FROM c }
1011} {3 G H}
1012
1013breakpoint
1014
1015# Now the real test - wrapped in a transaction.
1016do_test vtab1.12-4 {
1017  execsql  {BEGIN}
1018  catchsql { INSERT INTO echo_c SELECT * FROM b; }
1019} {1 {constraint failed}}
1020do_test vtab1.12-5 {
1021  execsql { SELECT * FROM c }
1022} {3 G H}
1023do_test vtab1.12-6 {
1024  execsql { COMMIT }
1025  execsql { SELECT * FROM c }
1026} {3 G H}
1027
1028# At one point (ticket #2759), a WHERE clause of the form "<column> IS NULL"
1029# on a virtual table was causing an assert() to fail in the compiler.
1030#
1031# "IS NULL" clauses should not be passed through to the virtual table
1032# implementation. They are handled by SQLite after the vtab returns its
1033# data.
1034#
1035do_test vtab1.13-1 {
1036  execsql {
1037    SELECT * FROM echo_c WHERE a IS NULL
1038  }
1039} {}
1040do_test vtab1.13-2 {
1041  execsql {
1042    INSERT INTO c VALUES(NULL, 15, 16);
1043    SELECT * FROM echo_c WHERE a IS NULL
1044  }
1045} {{} 15 16}
1046do_test vtab1.13-3 {
1047  execsql {
1048    INSERT INTO c VALUES(15, NULL, 16);
1049    SELECT * FROM echo_c WHERE b IS NULL
1050  }
1051} {15 {} 16}
1052do_test vtab1.13-3 {
1053  execsql {
1054    SELECT * FROM echo_c WHERE b IS NULL AND a = 15;
1055  }
1056} {15 {} 16}
1057
1058unset -nocomplain echo_module_begin_fail
1059finish_test
1060