From: drh Date: Tue, 7 Aug 2012 01:37:15 +0000 (+0000) Subject: Parser bug fix: Make sure the table constraints allowed by prior releases X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=25c48f72a89ef568b37c8bc64f5b354fb11ee50c;p=thirdparty%2Fsqlite.git Parser bug fix: Make sure the table constraints allowed by prior releases can still be parsed, even if they are technically not allowed by the syntax diagram. This is a cherry-pick of [a1c014d8a87c8940b3], [38bf90af1ede6ee64e], and [e536ac041815b118c4]. FossilOrigin-Name: 28aed847c6a9d5a3eae4627e1c23eb5cb9c3aabe --- diff --git a/manifest b/manifest index 648d798026..a20f68fb10 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Cherrypick\scommit\s[1d5e744cc6]\sfrom\sthe\strunk\sin\sorder\sto\savoid\sleaving\sa\sfile-ddescriptor\sopen\sin\stest\sscripts\scapi3.test\sand\scapi3c.test. -D 2012-04-03T19:43:07.319 +C Parser\sbug\sfix:\s\sMake\ssure\sthe\stable\sconstraints\sallowed\sby\sprior\sreleases\ncan\sstill\sbe\sparsed,\seven\sif\sthey\sare\stechnically\snot\sallowed\sby\sthe\nsyntax\sdiagram.\s\sThis\sis\sa\scherry-pick\sof\n[a1c014d8a87c8940b3],\s[38bf90af1ede6ee64e],\sand\s[e536ac041815b118c4]. +D 2012-08-07T01:37:15.857 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 7bd2fa7753fc9de38994b8d4fa7f10deb19966a5 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -174,7 +174,7 @@ F src/os_unix.c 5e6ead4f8f4236f0ed016ca4518300985daddf7e F src/os_win.c 12e76b4aa5426022939f92e894a5c20dd40be7f4 F src/pager.c ce4fde5951bf71b4f5316ff5afd0219ff7e99b3f F src/pager.h ef1eaf8593e78f73885c1dfac27ad83bee23bdc5 -F src/parse.y eb054bb40a5bf90d3422a01ed0e5df229461727a +F src/parse.y f29df90bd3adc64b33114ab1de9fb7768fcf2099 F src/pcache.c f8043b433a57aba85384a531e3937a804432a346 F src/pcache.h 1b5dcc3dc8103d03e625b177023ee67764fa6b7c F src/pcache1.c b30b1c35908346ecc43d8d9d17f2ddf6817f8f60 @@ -326,7 +326,7 @@ F test/capi3c.test 01f197d73f4d4d66316483662f475cab7ab5bd60 F test/capi3d.test 17b57ca28be3e37e14c2ba8f787d292d84b724a1 F test/capi3e.test f7408dda65c92b9056199fdc180f893015f83dde F test/cast.test 4c275cbdc8202d6f9c54a3596701719868ac7dc3 -F test/check.test 06795c188bf1776673fd2ac0787aa1c7238970d8 +F test/check.test 193f47ed43a8d29aca12b30cd30ceb105fbe710d F test/coalesce.test cee0dccb9fbd2d494b77234bccf9dc6c6786eb91 F test/collate1.test e3eaa48c21e150814be1a7b852d2a8af24458d04 F test/collate2.test 04cebe4a033be319d6ddbb3bbc69464e01700b49 @@ -678,6 +678,7 @@ F test/schema.test 8f7999be894260f151adf15c2c7540f1c6d6a481 F test/schema2.test 906408621ea881fdb496d878b1822572a34e32c5 F test/schema3.test 1bc1008e1f8cb5654b248c55f27249366eb7ed38 F test/schema4.test e6a66e20cc69f0e306667c08be7fda3d11707dc5 +F test/schema5.test 0103e4c0313b3725b5ae5600bdca53006ab53db3 F test/securedel.test 87a2561151af1f1e349071a89fdd77059f50113c F test/select1.test deba017eed9daa5af33de868676c997e7eebb931 F test/select2.test 352480e0e9c66eda9c3044e412abdf5be0215b56 @@ -1004,7 +1005,10 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 0c0150f2a349460d685e63be1a747d2bfbe5c8c4 -R 4a632657509f5ed1cfb05420592ec8ff -U dan -Z fcb9e7416b7e86cf09e8dde2e964f1f0 +P 86b8481be7e76cccc92d14ce762d21bfb69504af +R d9c8a43a6410094e092cf6045974ba35 +T *branch * apple-osx-ml +T *sym-apple-osx-ml * +T -sym-apple-osx * +U drh +Z 565276e401b412a4ad16f78979ba3010 diff --git a/manifest.uuid b/manifest.uuid index f79a3ec6b5..2e71a8b129 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -86b8481be7e76cccc92d14ce762d21bfb69504af \ No newline at end of file +28aed847c6a9d5a3eae4627e1c23eb5cb9c3aabe \ No newline at end of file diff --git a/src/parse.y b/src/parse.y index 49406e1e76..94433d5391 100644 --- a/src/parse.y +++ b/src/parse.y @@ -185,6 +185,7 @@ column(A) ::= columnid(X) type carglist. { columnid(A) ::= nm(X). { sqlite3AddColumn(pParse,&X); A = X; + pParse->constraintName.n = 0; } @@ -273,10 +274,9 @@ signed ::= minus_num. // "carglist" is a list of additional constraints that come after the // column name and column type in a CREATE TABLE statement. // -carglist ::= carglist cname ccons. +carglist ::= carglist ccons. carglist ::= . -cname ::= CONSTRAINT nm(X). {pParse->constraintName = X;} -cname ::= . {pParse->constraintName.n = 0;} +ccons ::= CONSTRAINT nm(X). {pParse->constraintName = X;} ccons ::= DEFAULT term(X). {sqlite3AddDefaultValue(pParse,&X);} ccons ::= DEFAULT LP expr(X) RP. {sqlite3AddDefaultValue(pParse,&X);} ccons ::= DEFAULT PLUS term(X). {sqlite3AddDefaultValue(pParse,&X);} @@ -339,10 +339,13 @@ init_deferred_pred_opt(A) ::= . {A = 0;} init_deferred_pred_opt(A) ::= INITIALLY DEFERRED. {A = 1;} init_deferred_pred_opt(A) ::= INITIALLY IMMEDIATE. {A = 0;} -conslist_opt(A) ::= . {A.n = 0; A.z = 0;} -conslist_opt(A) ::= COMMA(X) conslist. {A = X;} -conslist ::= conslist COMMA cname tcons. -conslist ::= cname tcons. +conslist_opt(A) ::= . {A.n = 0; A.z = 0;} +conslist_opt(A) ::= COMMA(X) conslist. {A = X;} +conslist ::= conslist tconscomma tcons. +conslist ::= tcons. +tconscomma ::= COMMA. {pParse->constraintName.n = 0;} +tconscomma ::= . +tcons ::= CONSTRAINT nm(X). {pParse->constraintName = X;} tcons ::= PRIMARY KEY LP idxlist(X) autoinc(I) RP onconf(R). {sqlite3AddPrimaryKey(pParse,X,R,I,0);} tcons ::= UNIQUE LP idxlist(X) RP onconf(R). diff --git a/test/check.test b/test/check.test index 4d1a44117d..bf0b770a00 100644 --- a/test/check.test +++ b/test/check.test @@ -153,6 +153,48 @@ do_test check-2.6 { } } {1 {constraint three failed}} +# Undocumented behavior: The CONSTRAINT name clause can follow a constraint. +# Such a clause is ignored. But the parser must accept it for backwards +# compatibility. +# +do_test check-2.10 { + execsql { + CREATE TABLE t2b( + x INTEGER CHECK( typeof(coalesce(x,0))=='integer' ) CONSTRAINT one, + y TEXT PRIMARY KEY constraint two, + z INTEGER, + UNIQUE(x,z) constraint three + ); + } +} {} +do_test check-2.11 { + catchsql { + INSERT INTO t2b VALUES('xyzzy','hi',5); + } +} {1 {constraint failed}} +do_test check-2.12 { + execsql { + CREATE TABLE t2c( + x INTEGER CONSTRAINT x_one CONSTRAINT x_two + CHECK( typeof(coalesce(x,0))=='integer' ) + CONSTRAINT x_two CONSTRAINT x_three, + y INTEGER, z INTEGER, + CONSTRAINT u_one UNIQUE(x,y,z) CONSTRAINT u_two + ); + } +} {} +do_test check-2.13 { + catchsql { + INSERT INTO t2c VALUES('xyzzy',7,8); + } +} {1 {constraint x_two failed}} +do_test check-2.cleanup { + execsql { + DROP TABLE IF EXISTS t2b; + DROP TABLE IF EXISTS t2c; + } +} {} + ifcapable subquery { do_test check-3.1 { catchsql { diff --git a/test/schema5.test b/test/schema5.test new file mode 100644 index 0000000000..6dea5e8f5f --- /dev/null +++ b/test/schema5.test @@ -0,0 +1,69 @@ +# 2010 September 28 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# +# This file checks corner cases in the CREATE TABLE syntax to make +# sure that legacy syntax (syntax that is disallowed according to the +# syntax diagrams) is still accepted, so that older databases that use +# that syntax can still be read. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +# Table constraints should be separated by commas, but they do not have +# to be. +# +do_test schema5-1.1 { + db eval { + CREATE TABLE t1(a,b,c, PRIMARY KEY(a) UNIQUE (a) CONSTRAINT one); + INSERT INTO t1 VALUES(1,2,3); + SELECT * FROM t1; + } +} {1 2 3} +do_test schema5-1.2 { + catchsql {INSERT INTO t1 VALUES(1,3,4);} +} {1 {column a is not unique}} +do_test schema5-1.3 { + db eval { + DROP TABLE t1; + CREATE TABLE t1(a,b,c, + CONSTRAINT one PRIMARY KEY(a) CONSTRAINT two CHECK(b<10) UNIQUE(b) + CONSTRAINT three + ); + INSERT INTO t1 VALUES(1,2,3); + SELECT * FROM t1; + } +} {1 2 3} +do_test schema5-1.4 { + catchsql {INSERT INTO t1 VALUES(10,11,12);} +} {1 {constraint two failed}} +do_test schema5-1.5 { + db eval { + DROP TABLE t1; + CREATE TABLE t1(a,b,c, + UNIQUE(a) CONSTRAINT one, + PRIMARY KEY(b,c) CONSTRAINT two + ); + INSERT INTO t1 VALUES(1,2,3); + } +} {} +do_test schema5-1.6 { + catchsql {INSERT INTO t1 VALUES(1,3,4)} +} {1 {column a is not unique}} +do_test schema5-1.7 { + catchsql {INSERT INTO t1 VALUES(10,2,3)} +} {1 {columns b, c are not unique}} + + + + + +finish_test