Add the ability to parse FOREIGN KEYs. Foreign keys are still ignored,

but at least they now do not cause a syntax error. (CVS 603)

FossilOrigin-Name: 6fdcee3c99e994ef3ab83a0cc57344cdb16210df
This commit is contained in:
drh 2002-06-02 18:19:00 +00:00
parent e4de1feb3e
commit 04738cb9ff
6 changed files with 117 additions and 15 deletions

View File

@ -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

View File

@ -1 +1 @@
7acbf84b492202d8b5a05276a95b475027eb5f58
6fdcee3c99e994ef3ab83a0cc57344cdb16210df

View File

@ -12,10 +12,10 @@
** 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

View 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.

View 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 },

View 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