sl@0: # 2001 September 15 sl@0: # sl@0: # The author disclaims copyright to this source code. In place of sl@0: # a legal notice, here is a blessing: sl@0: # sl@0: # May you do good and not evil. sl@0: # May you find forgiveness for yourself and forgive others. sl@0: # May you share freely, never taking more than you give. sl@0: # sl@0: #*********************************************************************** sl@0: # This file implements regression tests for SQLite library. The sl@0: # focus of this file is exercising the code in main.c. sl@0: # sl@0: # $Id: main.test,v 1.29 2008/07/12 14:52:20 drh Exp $ sl@0: sl@0: set testdir [file dirname $argv0] sl@0: source $testdir/tester.tcl sl@0: sl@0: # Only do the next group of tests if the sqlite3_complete API is available sl@0: # sl@0: ifcapable {complete} { sl@0: sl@0: # Tests of the sqlite_complete() function. sl@0: # sl@0: do_test main-1.1 { sl@0: db complete {This is a test} sl@0: } {0} sl@0: do_test main-1.2 { sl@0: db complete { sl@0: } sl@0: } {1} sl@0: do_test main-1.3 { sl@0: db complete { sl@0: -- a comment ; sl@0: } sl@0: } {1} sl@0: do_test main-1.4 { sl@0: db complete { sl@0: -- a comment ; sl@0: ; sl@0: } sl@0: } {1} sl@0: do_test main-1.5 { sl@0: db complete {DROP TABLE 'xyz;} sl@0: } {0} sl@0: do_test main-1.6 { sl@0: db complete {DROP TABLE 'xyz';} sl@0: } {1} sl@0: do_test main-1.7 { sl@0: db complete {DROP TABLE "xyz;} sl@0: } {0} sl@0: do_test main-1.8 { sl@0: db complete {DROP TABLE "xyz';} sl@0: } {0} sl@0: do_test main-1.9 { sl@0: db complete {DROP TABLE "xyz";} sl@0: } {1} sl@0: do_test main-1.10 { sl@0: db complete {DROP TABLE xyz; hi} sl@0: } {0} sl@0: do_test main-1.11 { sl@0: db complete {DROP TABLE xyz; } sl@0: } {1} sl@0: do_test main-1.12 { sl@0: db complete {DROP TABLE xyz; -- hi } sl@0: } {1} sl@0: do_test main-1.13 { sl@0: db complete {DROP TABLE xyz; -- hi sl@0: } sl@0: } {1} sl@0: do_test main-1.14 { sl@0: db complete {SELECT a-b FROM t1; } sl@0: } {1} sl@0: do_test main-1.15 { sl@0: db complete {SELECT a/e FROM t1 } sl@0: } {0} sl@0: do_test main-1.16 { sl@0: db complete { sl@0: CREATE TABLE abc(x,y); sl@0: } sl@0: } {1} sl@0: ifcapable {trigger} { sl@0: do_test main-1.17 { sl@0: db complete { sl@0: CREATE TRIGGER xyz AFTER DELETE abc BEGIN UPDATE pqr; sl@0: } sl@0: } {0} sl@0: do_test main-1.18 { sl@0: db complete { sl@0: CREATE TRIGGER xyz AFTER DELETE abc BEGIN UPDATE pqr; END; sl@0: } sl@0: } {1} sl@0: do_test main-1.19 { sl@0: db complete { sl@0: CREATE TRIGGER xyz AFTER DELETE abc BEGIN sl@0: UPDATE pqr; sl@0: unknown command; sl@0: } sl@0: } {0} sl@0: do_test main-1.20 { sl@0: db complete { sl@0: CREATE TRIGGER xyz AFTER DELETE backend BEGIN sl@0: UPDATE pqr; sl@0: } sl@0: } {0} sl@0: do_test main-1.21 { sl@0: db complete { sl@0: CREATE TRIGGER xyz AFTER DELETE end BEGIN sl@0: SELECT a, b FROM end; sl@0: } sl@0: } {0} sl@0: do_test main-1.22 { sl@0: db complete { sl@0: CREATE TRIGGER xyz AFTER DELETE end BEGIN sl@0: SELECT a, b FROM end; sl@0: END; sl@0: } sl@0: } {1} sl@0: do_test main-1.23 { sl@0: db complete { sl@0: CREATE TRIGGER xyz AFTER DELETE end BEGIN sl@0: SELECT a, b FROM end; sl@0: END; sl@0: SELECT a, b FROM end; sl@0: } sl@0: } {1} sl@0: do_test main-1.24 { sl@0: db complete { sl@0: CREATE TRIGGER xyz AFTER DELETE [;end;] BEGIN sl@0: UPDATE pqr; sl@0: } sl@0: } {0} sl@0: do_test main-1.25 { sl@0: db complete { sl@0: CREATE TRIGGER xyz AFTER DELETE backend BEGIN sl@0: UPDATE cantor SET a=[;end;];;; sl@0: } sl@0: } {0} sl@0: do_test main-1.26 { sl@0: db complete { sl@0: CREATE -- a comment sl@0: TRIGGER exy AFTER DELETE backend BEGIN sl@0: UPDATE pqr SET a=5; sl@0: } sl@0: } {0} sl@0: do_test main-1.27.1 { sl@0: db complete { sl@0: CREATE -- a comment sl@0: TRIGGERX tangentxx AFTER DELETE backend BEGIN sl@0: UPDATE pqr SET a=5; sl@0: } sl@0: } {1} sl@0: do_test main-1.27.2 { sl@0: db complete { sl@0: CREATE/**/TRIGGER tiger00 AFTER DELETE backend BEGIN sl@0: UPDATE pqr SET a=5; sl@0: } sl@0: } {0} sl@0: ifcapable {explain} { sl@0: do_test main-1.27.3 { sl@0: db complete { sl@0: /* */ EXPLAIN -- A comment sl@0: CREATE/**/TRIGGER ezxyz12 AFTER DELETE backend BEGIN sl@0: UPDATE pqr SET a=5; sl@0: } sl@0: } {0} sl@0: } sl@0: do_test main-1.27.4 { sl@0: db complete { sl@0: BOGUS token sl@0: CREATE TRIGGER xyz AFTER DELETE backend BEGIN sl@0: UPDATE pqr SET a=5; sl@0: } sl@0: } {1} sl@0: ifcapable {explain} { sl@0: do_test main-1.27.5 { sl@0: db complete { sl@0: EXPLAIN sl@0: CREATE TEMP TRIGGER xyz AFTER DELETE backend BEGIN sl@0: UPDATE pqr SET a=5; sl@0: } sl@0: } {0} sl@0: } sl@0: do_test main-1.28 { sl@0: db complete { sl@0: CREATE TEMPORARY TRIGGER xyz AFTER DELETE backend BEGIN sl@0: UPDATE pqr SET a=5; sl@0: } sl@0: } {0} sl@0: do_test main-1.29 { sl@0: db complete { sl@0: CREATE TRIGGER xyz AFTER DELETE backend BEGIN sl@0: UPDATE pqr SET a=5; sl@0: EXPLAIN select * from xyz; sl@0: } sl@0: } {0} sl@0: sl@0: } ;# end ifcapable {complete} sl@0: sl@0: } sl@0: do_test main-1.30 { sl@0: db complete { sl@0: CREATE TABLE /* In comment ; */ sl@0: } sl@0: } {0} sl@0: do_test main-1.31 { sl@0: db complete { sl@0: CREATE TABLE /* In comment ; */ hi; sl@0: } sl@0: } {1} sl@0: do_test main-1.31 { sl@0: db complete { sl@0: CREATE TABLE /* In comment ; */; sl@0: } sl@0: } {1} sl@0: do_test main-1.32 { sl@0: db complete { sl@0: stuff; sl@0: /* sl@0: CREATE TABLE sl@0: multiple lines sl@0: of text sl@0: */ sl@0: } sl@0: } {1} sl@0: do_test main-1.33 { sl@0: db complete { sl@0: /* sl@0: CREATE TABLE sl@0: multiple lines sl@0: of text; sl@0: } sl@0: } {0} sl@0: do_test main-1.34 { sl@0: db complete { sl@0: /* sl@0: CREATE TABLE sl@0: multiple lines "*/ sl@0: of text; sl@0: } sl@0: } {1} sl@0: do_test main-1.35 { sl@0: db complete {hi /**/ there;} sl@0: } {1} sl@0: do_test main-1.36 { sl@0: db complete {hi there/***/;} sl@0: } {1} sl@0: do_test main-1.37 { sl@0: db complete {hi there/**} sl@0: } {0} sl@0: do_test main-1.38 { sl@0: db complete {hi [there} sl@0: } {0} sl@0: sl@0: ifcapable {trigger} { sl@0: # Characters less than \040 can never be part of an identifier. sl@0: # Characters greater than \u177 are always identifier characters. sl@0: do_test main-1.100 { sl@0: db complete "create \037\036\035\034trigger\001\002;" sl@0: } {1} sl@0: do_test main-1.101 { sl@0: db complete "create trigger\200;" sl@0: } {1} sl@0: do_test main-1.102 { sl@0: db complete "create \200trigger;" sl@0: } {1} sl@0: } sl@0: sl@0: sl@0: # Try to open a database with a corrupt database file. sl@0: # sl@0: do_test main-2.0 { sl@0: catch {db close} sl@0: file delete -force test.db sl@0: set fd [open test.db w] sl@0: puts $fd hi! sl@0: close $fd sl@0: set v [catch {sqlite3 db test.db} msg] sl@0: if {$v} {lappend v $msg} {lappend v {}} sl@0: } {0 {}} sl@0: sl@0: # Here are some tests for tokenize.c. sl@0: # sl@0: do_test main-3.1 { sl@0: catch {db close} sl@0: foreach f [glob -nocomplain testdb/*] {file delete -force $f} sl@0: file delete -force testdb sl@0: sqlite3 db testdb sl@0: set v [catch {execsql {SELECT * from T1 where x!!5}} msg] sl@0: lappend v $msg sl@0: } {1 {unrecognized token: "!!"}} sl@0: do_test main-3.2 { sl@0: catch {db close} sl@0: foreach f [glob -nocomplain testdb/*] {file delete -force $f} sl@0: file delete -force testdb sl@0: sqlite3 db testdb sl@0: set v [catch {execsql {SELECT * from T1 where ^x}} msg] sl@0: lappend v $msg sl@0: } {1 {unrecognized token: "^"}} sl@0: do_test main-3.2.2 { sl@0: catchsql {select 'abc} sl@0: } {1 {unrecognized token: "'abc"}} sl@0: do_test main-3.2.3 { sl@0: catchsql {select "abc} sl@0: } {1 {unrecognized token: ""abc"}} sl@0: do_test main-3.2.4 { sl@0: catchsql {select [abc} sl@0: } {1 {unrecognized token: "[abc"}} sl@0: do_test main-3.2.5 { sl@0: catchsql {select x'4869} sl@0: } {1 {unrecognized token: "x'4869"}} sl@0: do_test main-3.2.6 { sl@0: catchsql {select x'4869'} sl@0: } {0 Hi} sl@0: do_test main-3.2.7 { sl@0: catchsql {select x'48695'} sl@0: } {1 {unrecognized token: "x'48695'"}} sl@0: do_test main-3.2.8 { sl@0: catchsql {select x'486x'} sl@0: } {1 {unrecognized token: "x'486x'"}} sl@0: do_test main-3.2.9 { sl@0: catchsql {select $abc(} sl@0: } {1 {unrecognized token: "$abc("}} sl@0: do_test main-3.2.10 { sl@0: catchsql {select $abc(x} sl@0: } {1 {unrecognized token: "$abc(x"}} sl@0: set xyz 123 sl@0: do_test main-3.2.11 { sl@0: catchsql {select $::xyz} sl@0: } {0 123} sl@0: namespace eval ::testnamespace { sl@0: variable xyz 321 sl@0: } sl@0: do_test main-3.2.12 { sl@0: catchsql {select $testnamespace::xyz} sl@0: } {0 321} sl@0: do_test main-3.2.13 { sl@0: catchsql {select $(abc)} sl@0: } {1 {unrecognized token: "$"}} sl@0: do_test main-3.2.14 { sl@0: set hi\u1234x 987 sl@0: db eval "select \$hi\u1234x" sl@0: } {987} sl@0: do_test main-3.2.15 { sl@0: catchsql "select 456\u1234" sl@0: } [list 1 "unrecognized token: \"456\u1234\""] sl@0: do_test main-3.2.16 { sl@0: catchsql {select cast(3.14e+4 AS integer)} sl@0: } {0 31400} sl@0: do_test main-3.2.17 { sl@0: catchsql {select cast(3.14e+04 AS integer)} sl@0: } {0 31400} sl@0: do_test main-3.2.18 { sl@0: catchsql {select cast(3.14e+004 AS integer)} sl@0: } {0 31400} sl@0: do_test main-3.2.19 { sl@0: catchsql {select cast(3.14e4 AS integer)} sl@0: } {0 31400} sl@0: do_test main-3.2.20 { sl@0: catchsql {select cast(3.14e04 AS integer)} sl@0: } {0 31400} sl@0: do_test main-3.2.21 { sl@0: catchsql {select cast(3.14e004 AS integer)} sl@0: } {0 31400} sl@0: do_test main-3.2.16 { sl@0: catchsql {select cast(3.14E+4 AS integer)} sl@0: } {0 31400} sl@0: do_test main-3.2.17 { sl@0: catchsql {select cast(3.14E+04 AS integer)} sl@0: } {0 31400} sl@0: do_test main-3.2.18 { sl@0: catchsql {select cast(3.14E+004 AS integer)} sl@0: } {0 31400} sl@0: do_test main-3.2.19 { sl@0: catchsql {select cast(3.14E4 AS integer)} sl@0: } {0 31400} sl@0: do_test main-3.2.20 { sl@0: catchsql {select cast(3.14E04 AS integer)} sl@0: } {0 31400} sl@0: do_test main-3.2.21 { sl@0: catchsql {select cast(3.14E004 AS integer)} sl@0: } {0 31400} sl@0: do_test main-3.2.22 { sl@0: catchsql {select cast(3.14e-4 * 1e8 AS integer)} sl@0: } {0 31400} sl@0: do_test main-3.2.23 { sl@0: catchsql {select cast(3.14E-04 * 1E08 AS integer)} sl@0: } {0 31400} sl@0: do_test main-3.2.24 { sl@0: catchsql {select cast(3.14e-004 * 01.0E+8 AS integer)} sl@0: } {0 31400} sl@0: do_test main-3.2.25 { sl@0: catchsql {select 123/*abc} sl@0: } {0 123} sl@0: do_test main-3.2.26 { sl@0: catchsql {select 123/***abc} sl@0: } {0 123} sl@0: do_test main-3.2.27 { sl@0: catchsql {select 123/*/*2} sl@0: } {0 123} sl@0: do_test main-3.2.28 { sl@0: catchsql {select 123/**/*2} sl@0: } {0 246} sl@0: do_test main-3.2.29 { sl@0: catchsql {select 123/} sl@0: } {1 {near "/": syntax error}} sl@0: do_test main-3.2.30 { sl@0: catchsql {select 123--5} sl@0: } {0 123} sl@0: sl@0: sl@0: do_test main-3.3 { sl@0: catch {db close} sl@0: foreach f [glob -nocomplain testdb/*] {file delete -force $f} sl@0: file delete -force testdb sl@0: sqlite3 db testdb sl@0: execsql { sl@0: create table T1(X REAL); /* C-style comments allowed */ sl@0: insert into T1 values(0.5); sl@0: insert into T1 values(0.5e2); sl@0: insert into T1 values(0.5e-002); sl@0: insert into T1 values(5e-002); sl@0: insert into T1 values(-5.0e-2); sl@0: insert into T1 values(-5.1e-2); sl@0: insert into T1 values(0.5e2); sl@0: insert into T1 values(0.5E+02); sl@0: insert into T1 values(5E+02); sl@0: insert into T1 values(5.0E+03); sl@0: select x*10 from T1 order by x*5; sl@0: } sl@0: } {-0.51 -0.5 0.05 0.5 5.0 500.0 500.0 500.0 5000.0 50000.0} sl@0: do_test main-3.4 { sl@0: set v [catch {execsql {create bogus}} msg] sl@0: lappend v $msg sl@0: } {1 {near "bogus": syntax error}} sl@0: do_test main-3.5 { sl@0: set v [catch {execsql {create}} msg] sl@0: lappend v $msg sl@0: } {1 {near "create": syntax error}} sl@0: do_test main-3.6 { sl@0: catchsql {SELECT 'abc' + #9} sl@0: } {1 {near "#9": syntax error}} sl@0: sl@0: # The following test-case tests the linked list code used to manage sl@0: # sqlite3_vfs structures. sl@0: if {$::tcl_platform(platform)=="unix"} { sl@0: ifcapable threadsafe { sl@0: do_test main-4.1 { sl@0: sl@0: sqlite3_crash_enable 1 sl@0: sqlite3_crash_enable 0 sl@0: sl@0: sqlite3async_enable 1 sl@0: sqlite3async_enable 0 sl@0: sl@0: sqlite3_crash_enable 1 sl@0: sqlite3async_enable 1 sl@0: sqlite3_crash_enable 0 sl@0: sqlite3async_enable 0 sl@0: sl@0: sqlite3_crash_enable 1 sl@0: sqlite3async_enable 1 sl@0: sqlite3async_enable 0 sl@0: sqlite3_crash_enable 0 sl@0: sl@0: sqlite3async_enable 1 sl@0: sqlite3_crash_enable 1 sl@0: sqlite3_crash_enable 0 sl@0: sqlite3async_enable 0 sl@0: sl@0: sqlite3async_enable 1 sl@0: sqlite3_crash_enable 1 sl@0: sqlite3async_enable 0 sl@0: sqlite3_crash_enable 0 sl@0: } {} sl@0: do_test main-4.2 { sl@0: set rc [catch {sqlite3 db test.db -vfs crash} msg] sl@0: list $rc $msg sl@0: } {1 {no such vfs: crash}} sl@0: do_test main-4.3 { sl@0: set rc [catch {sqlite3 db test.db -vfs async} msg] sl@0: list $rc $msg sl@0: } {1 {no such vfs: async}} sl@0: } sl@0: } sl@0: sl@0: finish_test