]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Add the ability to parse FOREIGN KEYs. Foreign keys are still ignored,
authordrh <drh@noemail.net>
Sun, 2 Jun 2002 18:19:00 +0000 (18:19 +0000)
committerdrh <drh@noemail.net>
Sun, 2 Jun 2002 18:19:00 +0000 (18:19 +0000)
but at least they now do not cause a syntax error. (CVS 603)

FossilOrigin-Name: 6fdcee3c99e994ef3ab83a0cc57344cdb16210df

manifest
manifest.uuid
src/expr.c
src/parse.y
src/tokenize.c
test/table.test

index b8c64658d298cba7d1604e79182933ae77f6a60f..f5476b0c1584d232e0b1a377a32a9026f24e15ff 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Enhance\sthe\sORDER\sBY\sclause\sso\sthat\san\sinteger\sterm\smeans\sto\ssort\sby\sthe\ncorresponding\scolumn.\s(CVS\s602)
-D 2002-06-02T16:09:02
+C Add\sthe\sability\sto\sparse\sFOREIGN\sKEYs.\s\sForeign\skeys\sare\sstill\signored,\nbut\sat\sleast\sthey\snow\sdo\snot\scause\sa\ssyntax\serror.\s(CVS\s603)
+D 2002-06-02T18:19:00
 F Makefile.in 6291a33b87d2a395aafd7646ee1ed562c6f2c28c
 F Makefile.template 4e11752e0b5c7a043ca50af4296ec562857ba495
 F README a4c0ba11354ef6ba0776b400d057c59da47a4cc0
@@ -23,7 +23,7 @@ F src/btree.h 8abeabfe6e0b1a990b64fa457592a6482f6674f3
 F src/build.c 36e42718a7a94f554ea39508993378482f5335c7
 F src/delete.c a2b098cbbf518e6b641847e26de85827793bc523
 F src/encode.c 346b12b46148506c32038524b95c4631ab46d760
-F src/expr.c 4ee07b536119e7ee4f572e1ca83ad86c1aef0058
+F src/expr.c 4c1b3b3dd0263a36661976a2071f947bf6a4048b
 F src/func.c 061a520a122da7e4f9dcac15697bb996aac7d5df
 F src/hash.c 6a6236b89c8c060c65dabd300a1c8ce7c10edb72
 F src/hash.h dca065dda89d4575f3176e75e9a3dc0f4b4fb8b9
@@ -34,7 +34,7 @@ F src/os.c 9cc40c5384baba4a85e160e67807645ca98ba3cc
 F src/os.h 4a361fccfbc4e7609b3e1557f604f94c1e96ad10
 F src/pager.c 1e41053c949cea1f09d8dafada5fe8f90785e650
 F src/pager.h 6fddfddd3b73aa8abc081b973886320e3c614f0e
-F src/parse.y c681da701bf142967325b8791f22418e2d81552d
+F src/parse.y 68c0ab3d6bc938d1edcd087a18f28246c763076a
 F src/printf.c d8032ee18b860c812eeff596c9bebfdacb7930fd
 F src/random.c 19e8e00fe0df32a742f115773f57651be327cabe
 F src/select.c ad9061b4735ccd79fc073415979882cd5c424c71
@@ -48,7 +48,7 @@ F src/test1.c 09d95048b66ce6dcd2bae90f443589043d7d631e
 F src/test2.c 669cc22781c6461a273416ec1a7414d25c081730
 F src/test3.c 4e52fff8b01f08bd202f7633feda5639b7ba2b5e
 F src/threadtest.c 81f0598e0f031c1bd506af337fdc1b7e8dff263f
-F src/tokenize.c facec7dc0b4a13e17ad67702f548dac2f7c6a732
+F src/tokenize.c 35c63867d03fcaf81fe520f8d8206981d0c7270e
 F src/trigger.c d02f8e3510c7c2ad948a0e8c3bb0cca8adaf80c5
 F src/update.c f68375173bf5338cae3e97012708e10f206aedd9
 F src/util.c 7cf46b5612f5d12601c697374b9c6b38b2332ce8
@@ -95,7 +95,7 @@ F test/select5.test c2a6c4a003316ee42cbbd689eebef8fdce0db2ac
 F test/select6.test efb8d0c07a440441db87db2c4ade6904e1407e85
 F test/sort.test 3b996ce7ca385f9cd559944ac0f4027a23aa546b
 F test/subselect.test f3bc1dcbddddcea08d818fcff75228ad3464fc83
-F test/table.test d9fd161dc9a2dbe0795d836336019ea6d0952ef8
+F test/table.test 42511f98a3e9bbee62913e3ae1774777faa23d35
 F test/tableapi.test 3c80421a889e1d106df16e5800fa787f0d2914a6
 F test/tclsqlite.test 79deeffd7cd637ca0f06c5dbbf2f44d272079533
 F test/temptable.test daa83489eea2e9aaeeece09675c28be84c72cb67
@@ -136,7 +136,7 @@ F www/speed.tcl da8afcc1d3ccc5696cfb388a68982bc3d9f7f00f
 F www/sqlite.tcl 8b5884354cb615049aed83039f8dfe1552a44279
 F www/tclsqlite.tcl 1db15abeb446aad0caf0b95b8b9579720e4ea331
 F www/vdbe.tcl 2013852c27a02a091d39a766bc87cff329f21218
-P df9cc852ad02dbec5558d3915a0303f7e7b79b2b
-R d820e9b413015f44b726f7ec86a28058
+P 7acbf84b492202d8b5a05276a95b475027eb5f58
+R 877ef09a15f8898a71498bdf36c4a9ea
 U drh
-Z 52b5b2062ca7af0b018c152f36b11673
+Z 5f9a38c2f7b726600f68471f0ff58f27
index 56899c72e71b902e8c15272bbde1c720ec0ca399..c907224632143caceecb869986a3bbddf9a94873 100644 (file)
@@ -1 +1 @@
-7acbf84b492202d8b5a05276a95b475027eb5f58
\ No newline at end of file
+6fdcee3c99e994ef3ab83a0cc57344cdb16210df
\ No newline at end of file
index b5bb89c99e016acff857a4c236ffdd4b7d951954..924719b7b37f1825a55b9bee43ef14115c32783e 100644 (file)
 ** This file contains routines used for analyzing expressions and
 ** for generating VDBE code that evaluates expressions in SQLite.
 **
-** $Id: expr.c,v 1.67 2002/06/02 16:09:02 drh Exp $
+** $Id: expr.c,v 1.68 2002/06/02 18:19:00 drh Exp $
 */
 #include "sqliteInt.h"
-
+#include <ctype.h>
 
 /*
 ** Construct a new expression node and return a pointer to it.  Memory
index f78a9995ca3991c5c8d5ec8754f911d60393db22..aac2ec4bb8543c34ec782d9cccecdc1fd9433099 100644 (file)
@@ -14,7 +14,7 @@
 ** the parser.  Lemon will also generate a header file containing
 ** numeric codes for all of the tokens.
 **
-** @(#) $Id: parse.y,v 1.69 2002/05/24 16:14:15 drh Exp $
+** @(#) $Id: parse.y,v 1.70 2002/06/02 18:19:00 drh Exp $
 */
 %token_prefix TK_
 %token_type {Token}
@@ -115,9 +115,11 @@ id(A) ::= AFTER(X).      {A = X;}
 id(A) ::= ASC(X).        {A = X;}
 id(A) ::= BEFORE(X).     {A = X;}
 id(A) ::= BEGIN(X).      {A = X;}
+id(A) ::= CASCADE(X).    {A = X;}
 id(A) ::= CLUSTER(X).    {A = X;}
 id(A) ::= CONFLICT(X).   {A = X;}
 id(A) ::= COPY(X).       {A = X;}
+id(A) ::= DEFERRED(X).   {A = X;}
 id(A) ::= DELIMITERS(X). {A = X;}
 id(A) ::= DESC(X).       {A = X;}
 id(A) ::= EACH(X).       {A = X;}
@@ -125,15 +127,21 @@ id(A) ::= END(X).        {A = X;}
 id(A) ::= EXPLAIN(X).    {A = X;}
 id(A) ::= FAIL(X).       {A = X;}
 id(A) ::= FOR(X).        {A = X;}
+id(A) ::= FULL(X).       {A = X;}
 id(A) ::= ID(X).         {A = X;}
 id(A) ::= IGNORE(X).     {A = X;}
+id(A) ::= IMMEDATE(X).   {A = X;}
+id(A) ::= INITIALLY(X).  {A = X;}
 id(A) ::= INSTEAD(X).    {A = X;}
+id(A) ::= MATCH(X).      {A = X;}
 id(A) ::= JOIN(X).       {A = X;}
 id(A) ::= KEY(X).        {A = X;}
 id(A) ::= OF(X).         {A = X;}
 id(A) ::= OFFSET(X).     {A = X;}
+id(A) ::= PARTIAL(X).    {A = X;}
 id(A) ::= PRAGMA(X).     {A = X;}
 id(A) ::= REPLACE(X).    {A = X;}
+id(A) ::= RESTRICT(X).   {A = X;}
 id(A) ::= ROW(X).        {A = X;}
 id(A) ::= STATEMENT(X).  {A = X;}
 id(A) ::= TEMP(X).       {A = X;}
@@ -179,6 +187,29 @@ ccons ::= NOT NULL onconf(R).               {sqliteAddNotNull(pParse, R);}
 ccons ::= PRIMARY KEY sortorder onconf(R).  {sqliteAddPrimaryKey(pParse,0,R);}
 ccons ::= UNIQUE onconf(R).            {sqliteCreateIndex(pParse,0,0,0,R,0,0);}
 ccons ::= CHECK LP expr RP onconf.
+ccons ::= references.
+ccons ::= defer_subclause.
+
+// A REFERENCES clause is parsed but the current implementation does not
+// do anything with it.
+//
+references ::= REFERENCES ids LP idxlist RP refargs.
+references ::= REFERENCES ids refargs.
+refargs ::= .
+refargs ::= refargs refarg.
+refarg ::= MATCH FULL.
+refarg ::= MATCH PARTIAL.
+refarg ::= ON DELETE refact.
+refarg ::= ON UPDATE refact.
+refact ::= SET NULL.
+refact ::= SET DEFAULT.
+refact ::= CASCADE.
+refact ::= RESTRICT.
+defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt.
+defer_subclause ::= DEFERRABLE init_deferred_pred_opt.
+init_deferred_pred_opt ::= .
+init_deferred_pred_opt ::= INITIALLY DEFERRED.
+init_deferred_pred_opt ::= INITIALLY IMMEDIATE.
 
 // For the time being, the only constraint we care about is the primary
 // key and UNIQUE.  Both create indices.
@@ -194,6 +225,9 @@ tcons ::= PRIMARY KEY LP idxlist(X) RP onconf(R).
 tcons ::= UNIQUE LP idxlist(X) RP onconf(R).
                                        {sqliteCreateIndex(pParse,0,0,X,R,0,0);}
 tcons ::= CHECK expr onconf.
+tcons ::= FOREIGN KEY LP idxlist RP references defer_subclause_opt.
+defer_subclause_opt ::= .
+defer_subclause_opt ::= defer_subclause.
 
 // The following is a non-standard extension that allows us to declare the
 // default behavior when there is a constraint conflict.
index b566f09e8d4b330118cf27134ac8371febab2c14..5be1b3354561e55c41fa7c0f2892e33337febe4e 100644 (file)
@@ -15,7 +15,7 @@
 ** individual tokens and sends those tokens one-by-one over to the
 ** parser for analysis.
 **
-** $Id: tokenize.c,v 1.43 2002/05/24 16:14:15 drh Exp $
+** $Id: tokenize.c,v 1.44 2002/06/02 18:19:00 drh Exp $
 */
 #include "sqliteInt.h"
 #include "os.h"
@@ -48,6 +48,7 @@ static Keyword aKeywordTable[] = {
   { "BEGIN",             0, TK_BEGIN,            0 },
   { "BETWEEN",           0, TK_BETWEEN,          0 },
   { "BY",                0, TK_BY,               0 },
+  { "CASCADE",           0, TK_CASCADE,          0 },
   { "CASE",              0, TK_CASE,             0 },
   { "CHECK",             0, TK_CHECK,            0 },
   { "CLUSTER",           0, TK_CLUSTER,          0 },
@@ -57,6 +58,8 @@ static Keyword aKeywordTable[] = {
   { "COPY",              0, TK_COPY,             0 },
   { "CREATE",            0, TK_CREATE,           0 },
   { "DEFAULT",           0, TK_DEFAULT,          0 },
+  { "DEFERRED",          0, TK_DEFERRED,         0 },
+  { "DEFERRABLE",        0, TK_DEFERRABLE,       0 },
   { "DELETE",            0, TK_DELETE,           0 },
   { "DELIMITERS",        0, TK_DELIMITERS,       0 },
   { "DESC",              0, TK_DESC,             0 },
@@ -69,13 +72,17 @@ static Keyword aKeywordTable[] = {
   { "EXPLAIN",           0, TK_EXPLAIN,          0 },
   { "FAIL",              0, TK_FAIL,             0 },
   { "FOR",               0, TK_FOR,              0 },
+  { "FOREIGN",           0, TK_FOREIGN,          0 },
   { "FROM",              0, TK_FROM,             0 },
+  { "FULL",              0, TK_FULL,             0 },
   { "GLOB",              0, TK_GLOB,             0 },
   { "GROUP",             0, TK_GROUP,            0 },
   { "HAVING",            0, TK_HAVING,           0 },
   { "IGNORE",            0, TK_IGNORE,           0 },
+  { "IMMEDIATE",         0, TK_IMMEDIATE,        0 },
   { "IN",                0, TK_IN,               0 },
   { "INDEX",             0, TK_INDEX,            0 },
+  { "INITIALLY",         0, TK_INITIALLY,        0 },
   { "INSERT",            0, TK_INSERT,           0 },
   { "INSTEAD",           0, TK_INSTEAD,          0 },
   { "INTERSECT",         0, TK_INTERSECT,        0 },
@@ -86,6 +93,7 @@ static Keyword aKeywordTable[] = {
   { "KEY",               0, TK_KEY,              0 },
   { "LIKE",              0, TK_LIKE,             0 },
   { "LIMIT",             0, TK_LIMIT,            0 },
+  { "MATCH",             0, TK_MATCH,            0 },
   { "NOT",               0, TK_NOT,              0 },
   { "NOTNULL",           0, TK_NOTNULL,          0 },
   { "NULL",              0, TK_NULL,             0 },
@@ -94,9 +102,12 @@ static Keyword aKeywordTable[] = {
   { "ON",                0, TK_ON,               0 },
   { "OR",                0, TK_OR,               0 },
   { "ORDER",             0, TK_ORDER,            0 },
+  { "PARTIAL",           0, TK_PARTIAL,          0 },
   { "PRAGMA",            0, TK_PRAGMA,           0 },
   { "PRIMARY",           0, TK_PRIMARY,          0 },
+  { "REFERENCES",        0, TK_REFERENCES,       0 },
   { "REPLACE",           0, TK_REPLACE,          0 },
+  { "RESTRICT",          0, TK_RESTRICT,         0 },
   { "ROLLBACK",          0, TK_ROLLBACK,         0 },
   { "ROW",               0, TK_ROW,              0 },
   { "SELECT",            0, TK_SELECT,           0 },
index 1b403fe2645c7c342a8e0f66b819e1940aa69c16..6c8c00bb7876bd078ead075b95ed98351ffcfd84 100644 (file)
@@ -11,7 +11,7 @@
 # This file implements regression tests for SQLite library.  The
 # focus of this file is testing the CREATE TABLE statement.
 #
-# $Id: table.test,v 1.16 2002/05/22 21:27:04 drh Exp $
+# $Id: table.test,v 1.17 2002/06/02 18:19:00 drh Exp $
 
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
@@ -378,5 +378,62 @@ do_test table-9.1 {
   }
 } {1 {duplicate column name: a}}
 
+# Check the foreign key syntax.
+#
+do_test table-10.1 {
+  catchsql {
+    CREATE TABLE t6(a REFERENCES t4(a) NOT NULL);
+    INSERT INTO t6 VALUES(NULL);
+  }
+} {1 {constraint failed}}
+do_test table-10.2 {
+  catchsql {
+    DROP TABLE t6;
+    CREATE TABLE t6(a REFERENCES t4(a) MATCH PARTIAL);
+  }
+} {0 {}}
+do_test table-10.3 {
+  catchsql {
+    DROP TABLE t6;
+    CREATE TABLE t6(a REFERENCES t4 MATCH FULL ON DELETE SET NULL NOT NULL);
+  }
+} {0 {}}
+do_test table-10.4 {
+  catchsql {
+    DROP TABLE t6;
+    CREATE TABLE t6(a REFERENCES t4 MATCH FULL ON UPDATE SET DEFAULT DEFAULT 1);
+  }
+} {0 {}}
+do_test table-10.5 {
+  catchsql {
+    DROP TABLE t6;
+    CREATE TABLE t6(a NOT NULL NOT DEFERRABLE INITIALLY IMMEDIATE);
+  }
+} {0 {}}
+do_test table-10.6 {
+  catchsql {
+    DROP TABLE t6;
+    CREATE TABLE t6(a NOT NULL DEFERRABLE INITIALLY DEFERRED);
+  }
+} {0 {}}
+do_test table-10.7 {
+  catchsql {
+    DROP TABLE t6;
+    CREATE TABLE t6(a,
+      FOREIGN KEY (a) REFERENCES t4(b) DEFERRABLE INITIALLY DEFERRED
+    );
+  }
+} {0 {}}
+do_test table-10.8 {
+  catchsql {
+    DROP TABLE t6;
+    CREATE TABLE t6(a,b,c,
+      FOREIGN KEY (b,c) REFERENCES t4(x,y) MATCH PARTIAL
+        ON UPDATE SET NULL ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED
+    );
+  }
+} {0 {}}
+
+
 
 finish_test