From: drh Date: Mon, 7 May 2012 19:21:36 +0000 (+0000) Subject: Adjust the parser so that certain legacy schema constructs (that are not X-Git-Tag: version-3.7.12~13 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=4dc330dd33b177b8e24e8649d75542988a970a23;p=thirdparty%2Fsqlite.git Adjust the parser so that certain legacy schema constructs (that are not valid according to the syntax diagram) continue to be accepted, so that older databases that happen to use those constructs are still readable. This fixes an issue introduced by check-in [1b75f301affac6] FossilOrigin-Name: a1c014d8a87c8940b3a037d8d8cc4d5678809802 --- diff --git a/manifest b/manifest index 6872f43e39..a098cfa41d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\sWindows\sdirectory\schecking\schanges\sto\strunk. -D 2012-05-07T18:10:12.605 +C Adjust\sthe\sparser\sso\sthat\scertain\slegacy\sschema\sconstructs\s(that\sare\snot\nvalid\saccording\sto\sthe\ssyntax\sdiagram)\scontinue\sto\sbe\saccepted,\sso\sthat\nolder\sdatabases\sthat\shappen\sto\suse\sthose\sconstructs\sare\sstill\sreadable.\nThis\sfixes\san\sissue\sintroduced\sby\scheck-in\s[1b75f301affac6] +D 2012-05-07T19:21:36.465 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2f37e468503dbe79d35c9f6dffcf3fae1ae9ec20 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -163,7 +163,7 @@ F src/os_unix.c 424d46e0edab969293c2223f09923b2178171f47 F src/os_win.c 412d6434133c7c81dc48b7702f3ea5e61c309e5c F src/pager.c bb5635dde0b152797836d1c72275284724bb563c F src/pager.h ef1eaf8593e78f73885c1dfac27ad83bee23bdc5 -F src/parse.y eb054bb40a5bf90d3422a01ed0e5df229461727a +F src/parse.y ad29af00e73d3afd84820f5738e072c506d8d77b F src/pcache.c f8043b433a57aba85384a531e3937a804432a346 F src/pcache.h 1b5dcc3dc8103d03e625b177023ee67764fa6b7c F src/pcache1.c b30b1c35908346ecc43d8d9d17f2ddf6817f8f60 @@ -315,7 +315,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 @@ -995,7 +995,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh a8a0a3babda96dfb1ff51adda3cbbf3dfb7266c2 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P bfa61e781cb442be641486e7e55a1518e888d830 b08530e1a02cba03afefd65dc101e074e8847c07 -R fce36c453dc0cfdd0c18e985348b50c5 -U mistachkin -Z 6287c2c1d24bbcf6d142a68d76da7aa1 +P a4555a53eab3f5d2f142c78a6b71189544e80ae6 +R b1ed928fe6d7cc7f56cb67cfef4cacc0 +U drh +Z a9d5fb0a817384840c4a8fbe0a536a67 diff --git a/manifest.uuid b/manifest.uuid index ded09514db..f24cea68b2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a4555a53eab3f5d2f142c78a6b71189544e80ae6 \ No newline at end of file +a1c014d8a87c8940b3a037d8d8cc4d5678809802 \ No newline at end of file diff --git a/src/parse.y b/src/parse.y index 49406e1e76..3b3ab21d79 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);} @@ -341,8 +341,10 @@ 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 ::= conslist COMMA cname tcons cname. +conslist ::= cname tcons cname. +cname ::= . {pParse->constraintName.n = 0;} +cname ::= 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 {