diff --git a/src/box/sql/build.c b/src/box/sql/build.c index d812eb9a5c1484b6db374071ab058da0f5512659..4c99a85e00db166ae86c95e9fc2e11fab2a06a99 100644 --- a/src/box/sql/build.c +++ b/src/box/sql/build.c @@ -2072,10 +2072,16 @@ sql_drop_table(struct Parse *parse_context, struct SrcList *table_name_list, * removing indexes from _index space and eventually * tuple with corresponding space_id from _space. */ - - sql_clear_stat_spaces(parse_context, space_name, NULL); struct Table *tab = sqlite3HashFind(&db->pSchema->tblHash, space_name); - sqlite3FkDropTable(parse_context, table_name_list, tab); + struct FKey *fk = sqlite3FkReferences(tab); + if (fk != NULL && fk->pFrom->def->id != tab->def->id) { + diag_set(ClientError, ER_DROP_SPACE, space_name, + "other objects depend on it"); + parse_context->rc = SQL_TARANTOOL_ERROR; + parse_context->nErr++; + goto exit_drop_table; + } + sql_clear_stat_spaces(parse_context, space_name, NULL); sql_code_drop_table(parse_context, space, is_view); exit_drop_table: @@ -2117,6 +2123,26 @@ sqlite3CreateForeignKey(Parse * pParse, /* Parsing context */ char *z; assert(pTo != 0); + char *normalized_name = strndup(pTo->z, pTo->n); + if (normalized_name == NULL) { + diag_set(OutOfMemory, pTo->n, "strndup", "normalized name"); + goto fk_end; + } + sqlite3NormalizeName(normalized_name); + uint32_t parent_id = box_space_id_by_name(normalized_name, + strlen(normalized_name)); + if (parent_id == BOX_ID_NIL && + strcmp(normalized_name, p->def->name) != 0) { + diag_set(ClientError, ER_NO_SUCH_SPACE, normalized_name); + pParse->rc = SQL_TARANTOOL_ERROR; + pParse->nErr++; + goto fk_end; + } + struct space *parent_space = space_by_id(parent_id); + if (parent_space != NULL && parent_space->def->opts.is_view) { + sqlite3ErrorMsg(pParse, "referenced table can't be view"); + goto fk_end; + } if (p == 0) goto fk_end; if (pFromCol == 0) { @@ -2138,8 +2164,8 @@ sqlite3CreateForeignKey(Parse * pParse, /* Parsing context */ } else { nCol = pFromCol->nExpr; } - nByte = - sizeof(*pFKey) + (nCol - 1) * sizeof(pFKey->aCol[0]) + pTo->n + 1; + nByte = sizeof(*pFKey) + (nCol - 1) * sizeof(pFKey->aCol[0]) + + strlen(normalized_name) + 1; if (pToCol) { for (i = 0; i < pToCol->nExpr; i++) { nByte += sqlite3Strlen30(pToCol->a[i].zName) + 1; @@ -2153,10 +2179,8 @@ sqlite3CreateForeignKey(Parse * pParse, /* Parsing context */ pFKey->pNextFrom = p->pFKey; z = (char *)&pFKey->aCol[nCol]; pFKey->zTo = z; - memcpy(z, pTo->z, pTo->n); - z[pTo->n] = 0; - sqlite3NormalizeName(z); - z += pTo->n + 1; + memcpy(z, normalized_name, strlen(normalized_name) + 1); + z += strlen(normalized_name) + 1; pFKey->nCol = nCol; if (pFromCol == 0) { pFKey->aCol[0].iFrom = p->def->field_count - 1; @@ -2210,6 +2234,7 @@ sqlite3CreateForeignKey(Parse * pParse, /* Parsing context */ fk_end: sqlite3DbFree(db, pFKey); + free(normalized_name); #endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */ sql_expr_list_delete(db, pFromCol); sql_expr_list_delete(db, pToCol); diff --git a/src/box/sql/fkey.c b/src/box/sql/fkey.c index 6dd91306be76973dd22d848af76b20fb79432289..248bd31bfc91a0a187bd7ae171c6a6c94d391612 100644 --- a/src/box/sql/fkey.c +++ b/src/box/sql/fkey.c @@ -318,11 +318,9 @@ sqlite3FkLocateIndex(Parse * pParse, /* Parse context to store any error in */ } if (index == NULL) { - if (!pParse->disableTriggers) { - sqlite3ErrorMsg(pParse, - "foreign key mismatch - \"%w\" referencing \"%w\"", - pFKey->pFrom->def->name, pFKey->zTo); - } + sqlite3ErrorMsg(pParse, "foreign key mismatch - " + "\"%w\" referencing \"%w\"", + pFKey->pFrom->def->name, pFKey->zTo); sqlite3DbFree(pParse->db, aiCol); return 1; } @@ -736,46 +734,6 @@ sql_fk_trigger_delete(struct sqlite3 *db, struct sql_trigger *trigger) sqlite3DbFree(db, trigger); } -/** - * This function is called to generate code that runs when table - * pTab is being dropped from the database. The SrcList passed as - * the second argument to this function contains a single entry - * guaranteed to resolve to table pTab. - * - * Normally, no code is required. However, if the table is - * parent table of a FK constraint, then the equivalent - * of "DELETE FROM <tbl>" is executed in a single transaction - * before dropping the table from the database. If any FK - * violations occur, rollback transaction and halt VDBE. Triggers - * are disabled while running this DELETE, but foreign key - * actions are not. - */ -void -sqlite3FkDropTable(Parse *parser, SrcList *name, Table *table) -{ - struct session *user_session = current_session(); - if ((user_session->sql_flags & SQLITE_ForeignKeys) == 0 || - table->def->opts.is_view || sqlite3FkReferences(table) == NULL) - return; - struct Vdbe *v = sqlite3GetVdbe(parser); - assert(v != NULL); - parser->disableTriggers = 1; - /* Staring new transaction before DELETE FROM <tbl> */ - sqlite3VdbeAddOp0(v, OP_TTransaction); - sql_table_delete_from(parser, sqlite3SrcListDup(parser->db, name, 0), - NULL); - parser->disableTriggers = 0; - /* - * If the DELETE has generated immediate foreign key - * constraint violations, rollback, halt the VDBE and - * return an error at this point, before any modifications - * of the _space and _index spaces. This is because these - * spaces don't support multistatement transactions. - * Otherwise, just commit changes. - */ - sqlite3VdbeAddOp0(v, OP_FkCheckCommit); -} - /* * The second argument points to an FKey object representing a foreign key * for which pTab is the child table. An UPDATE statement against pTab @@ -884,7 +842,6 @@ sqlite3FkCheck(Parse * pParse, /* Parse context */ { sqlite3 *db = pParse->db; /* Database handle */ FKey *pFKey; /* Used to iterate through FKs */ - int isIgnoreErrors = pParse->disableTriggers; struct session *user_session = current_session(); /* Exactly one of regOld and regNew should be non-zero. */ @@ -903,7 +860,6 @@ sqlite3FkCheck(Parse * pParse, /* Parse context */ int *aiFree = 0; int *aiCol; int iCol; - int i; int bIgnore = 0; if (aChange @@ -917,42 +873,10 @@ sqlite3FkCheck(Parse * pParse, /* Parse context */ * schema items cannot be located, set an error in pParse and return * early. */ - if (pParse->disableTriggers) { - pTo = sqlite3HashFind(&db->pSchema->tblHash, - pFKey->zTo); - } else { - pTo = sqlite3LocateTable(pParse, 0, pFKey->zTo); - } - if (!pTo - || sqlite3FkLocateIndex(pParse, pTo, pFKey, &pIdx, - &aiFree)) { - assert(isIgnoreErrors == 0 - || (regOld != 0 && regNew == 0)); - if (!isIgnoreErrors || db->mallocFailed) + pTo = sqlite3LocateTable(pParse, 0, pFKey->zTo); + if (pTo == NULL || sqlite3FkLocateIndex(pParse, pTo, pFKey, + &pIdx, &aiFree) != 0) return; - if (pTo == 0) { - /* If isIgnoreErrors is true, then a table is being dropped. In this - * case SQLite runs a "DELETE FROM xxx" on the table being dropped - * before actually dropping it in order to check FK constraints. - * If the parent table of an FK constraint on the current table is - * missing, behave as if it is empty. i.e. decrement the relevant - * FK counter for each row of the current table with non-NULL keys. - */ - Vdbe *v = sqlite3GetVdbe(pParse); - int iJump = - sqlite3VdbeCurrentAddr(v) + pFKey->nCol + 1; - for (i = 0; i < pFKey->nCol; i++) { - int iReg = - pFKey->aCol[i].iFrom + regOld + 1; - sqlite3VdbeAddOp2(v, OP_IsNull, iReg, - iJump); - VdbeCoverage(v); - } - sqlite3VdbeAddOp2(v, OP_FkCounter, - pFKey->isDeferred, -1); - } - continue; - } assert(pFKey->nCol == 1 || (aiFree && pIdx)); if (aiFree) { @@ -1012,11 +936,9 @@ sqlite3FkCheck(Parse * pParse, /* Parse context */ continue; } - if (sqlite3FkLocateIndex(pParse, pTab, pFKey, &pIdx, &aiCol)) { - if (!isIgnoreErrors || db->mallocFailed) - return; - continue; - } + if (sqlite3FkLocateIndex(pParse, pTab, pFKey, &pIdx, + &aiCol) != 0) + return; assert(aiCol || pFKey->nCol == 1); /* Create a SrcList structure containing the child table. We need the diff --git a/src/box/sql/sqliteInt.h b/src/box/sql/sqliteInt.h index 73c33d9d6ec5f0f91438d9b2e2b4bea09996f265..fd3c64203986deffd524f0aea1d9dd62032505dd 100644 --- a/src/box/sql/sqliteInt.h +++ b/src/box/sql/sqliteInt.h @@ -2857,7 +2857,6 @@ struct Parse { u32 newmask; /* Mask of new.* columns referenced */ u8 eTriggerOp; /* TK_UPDATE, TK_INSERT or TK_DELETE */ u8 eOrconf; /* Default ON CONFLICT policy for trigger steps */ - u8 disableTriggers; /* True to disable triggers */ /** Region to make SQL temp allocations. */ struct region region; @@ -4633,7 +4632,6 @@ void sqlite3WithPush(Parse *, With *, u8); */ #if !defined(SQLITE_OMIT_FOREIGN_KEY) void sqlite3FkCheck(Parse *, Table *, int, int, int *); -void sqlite3FkDropTable(Parse *, SrcList *, Table *); void sqlite3FkActions(Parse *, Table *, ExprList *, int, int *); int sqlite3FkRequired(Table *, int *); u32 sqlite3FkOldmask(Parse *, Table *); @@ -4641,7 +4639,6 @@ FKey *sqlite3FkReferences(Table *); #else #define sqlite3FkActions(a,b,c,d,e) #define sqlite3FkCheck(a,b,c,d,e,f) -#define sqlite3FkDropTable(a,b,c) #define sqlite3FkOldmask(a,b) 0 #define sqlite3FkRequired(b,c) 0 #endif diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c index ca89908caa37270b990a701daf8caab6facc1f27..192de1ae2c72abc10c56ca8fa5f6a3d67b4c352c 100644 --- a/src/box/sql/vdbe.c +++ b/src/box/sql/vdbe.c @@ -2942,36 +2942,6 @@ case OP_Savepoint: { break; } -/* Opcode: FkCheckCommit * * * * * - * - * This opcode is used and required by DROP TABLE statement, - * since deleted rows should be rollbacked in case of foreign keys - * constraint violations. In case of rollback, instruction - * also causes the VM to halt, because it makes no sense to continue - * execution with FK violations. If there is no FK violations, then - * just commit changes - deleted rows. - * - * Do not use this instruction in any statement implementation - * except for DROP TABLE! - */ -case OP_FkCheckCommit: { - if (!box_txn()) { - sqlite3VdbeError(p, "cannot commit or rollback - " \ - "no transaction is active"); - rc = SQLITE_ERROR; - goto abort_due_to_error; - } - if ((rc = sqlite3VdbeCheckFk(p, 0) != SQLITE_OK)) { - box_txn_rollback(); - sqlite3VdbeHalt(p); - goto vdbe_return; - } else { - rc = box_txn_commit() == 0 ? SQLITE_OK : SQL_TARANTOOL_ERROR; - if (rc) goto abort_due_to_error; - } - break; -} - /* Opcode: CheckViewReferences P1 * * * * * Synopsis: r[P1] = space id * diff --git a/test/sql-tap/alter.test.lua b/test/sql-tap/alter.test.lua index cfe280121e61bdc2a9f17591a5eaaec224fe29ef..a1f6a24b436b4f8c3aabd2a98ac5939edab1045d 100755 --- a/test/sql-tap/alter.test.lua +++ b/test/sql-tap/alter.test.lua @@ -313,9 +313,9 @@ test:do_execsql_test( DROP TABLE IF EXISTS t1; DROP TABLE IF EXISTS t2; DROP TABLE IF EXISTS t3; + CREATE TABLE t2(id INT PRIMARY KEY); + CREATE TABLE t3(id INT PRIMARY KEY); CREATE TABLE t1(a PRIMARY KEY, b, c, FOREIGN KEY(b) REFERENCES t2(id), FOREIGN KEY(c) REFERENCES t3(id)); - CREATE TABLE t2(id PRIMARY KEY); - CREATE TABLE t3(id PRIMARY KEY); INSERT INTO t2 VALUES(1); INSERT INTO t3 VALUES(2); INSERT INTO t1 VALUES(1, 1, 2); diff --git a/test/sql-tap/fkey1.test.lua b/test/sql-tap/fkey1.test.lua index bca82d93dd0f5e9cbd7defa5a34c1d42b6ba87f5..494af4b4a2f7065440a7f262be39f29ccff7b7ab 100755 --- a/test/sql-tap/fkey1.test.lua +++ b/test/sql-tap/fkey1.test.lua @@ -6,6 +6,15 @@ test:plan(19) test:do_execsql_test( "fkey1-1.1", + [[ + CREATE TABLE t2(x PRIMARY KEY, y TEXT); + ]], { + -- <fkey1-1.1> + -- </fkey1-1.1> + }) + +test:do_execsql_test( + "fkey1-1.2", [[ CREATE TABLE t1( a INTEGER PRIMARY KEY, @@ -19,15 +28,6 @@ test:do_execsql_test( -- </fkey1-1.1> }) -test:do_execsql_test( - "fkey1-1.2", - [[ - CREATE TABLE t2(x PRIMARY KEY, y TEXT); - ]], { - -- <fkey1-1.2> - -- </fkey1-1.2> - }) - test:do_execsql_test( "fkey1-1.3", [[ diff --git a/test/sql-tap/fkey2.test.lua b/test/sql-tap/fkey2.test.lua index 9d04a04b06e980427784572aedc68801d58c6446..062597e9b17cb0e030c2cc590ad85ace5858bb2e 100755 --- a/test/sql-tap/fkey2.test.lua +++ b/test/sql-tap/fkey2.test.lua @@ -1,6 +1,6 @@ #!/usr/bin/env tarantool test = require("sqltester") -test:plan(121) +test:plan(117) -- This file implements regression tests for foreign keys. @@ -15,9 +15,6 @@ test:do_execsql_test( CREATE TABLE t7(a, b INTEGER PRIMARY KEY); CREATE TABLE t8(c PRIMARY KEY REFERENCES t7, d); - - CREATE TABLE t9(a PRIMARY KEY REFERENCES nosuchtable, b); - CREATE TABLE t10(a PRIMARY KEY REFERENCES t9(c), b); ]], { -- <fkey2-1.1> -- </fkey2-1.1> @@ -301,21 +298,19 @@ test:do_catchsql_test( test:do_catchsql_test( "fkey2-1.29", [[ - INSERT INTO t9 VALUES(1, 3); + CREATE TABLE t9(a PRIMARY KEY REFERENCES nosuchtable, b); ]], { - -- <fkey2-1.29> - 1, "no such table: NOSUCHTABLE" - -- </fkey2-1.29> + 1, "Space 'NOSUCHTABLE' does not exist" }) test:do_catchsql_test( "fkey2-1.30", [[ - INSERT INTO t10 VALUES(1, 3); + INSERT INTO t9 VALUES(1, 3); ]], { - -- <fkey2-1.30> - 1, "foreign key mismatch - \"T10\" referencing \"T9\"" - -- </fkey2-1.30> + -- <fkey2-1.29> + 1, "no such table: T9" + -- </fkey2-1.29> }) test:do_execsql_test( @@ -729,14 +724,11 @@ test:do_catchsql_test( test:do_catchsql_test( "fkey2-7.2", [[ - DROP TABLE IF EXISTS c; - DROP TABLE IF EXISTS p; - CREATE TABLE c(x PRIMARY KEY REFERENCES v(y)); - CREATE VIEW v AS SELECT x AS y FROM c; - INSERT INTO c DEFAULT VALUES; + CREATE VIEW v AS SELECT b AS y FROM p; + CREATE TABLE d(x PRIMARY KEY REFERENCES v(y)); ]], { -- <fkey2-7.2> - 1, "foreign key mismatch - \"C\" referencing \"V\"" + 1, "referenced table can't be view" -- </fkey2-7.2> }) @@ -745,6 +737,7 @@ test:do_catchsql_test( [[ DROP VIEW v; DROP TABLE IF EXISTS c; + DROP TABLE IF EXISTS p; CREATE TABLE p(a COLLATE binary, b PRIMARY KEY); CREATE UNIQUE INDEX idx ON p(a COLLATE "unicode_ci"); CREATE TABLE c(x PRIMARY KEY REFERENCES p(a)); @@ -1050,15 +1043,15 @@ test:do_execsql_test( -- -- </fkey2-10.5> -- }) -test:do_execsql_test( +test:do_catchsql_test( "fkey2-10.6", [[ DROP TABLE IF EXISTS t2; DROP TABLE IF EXISTS t1; CREATE TABLE t1(a PRIMARY KEY, b REFERENCES nosuchtable); - DROP TABLE t1; ]], { -- <fkey2-10.6> + 1, "Space 'NOSUCHTABLE' does not exist" -- </fkey2-10.6> }) @@ -1081,61 +1074,20 @@ test:do_catchsql_test( DROP TABLE t1; ]], { -- <fkey2-10.8> - 1, "FOREIGN KEY constraint failed" + 1, "Can't drop space 'T1': other objects depend on it" -- </fkey2-10.8> }) test:do_execsql_test( "fkey2-10.9", [[ - DELETE FROM t2; + DROP TABLE t2; DROP TABLE t1; ]], { -- <fkey2-10.9> -- </fkey2-10.9> }) -test:do_catchsql_test( - "fkey2-10.10", - [[ - INSERT INTO t2 VALUES('x'); - ]], { - -- <fkey2-10.10> - 1, "no such table: T1" - -- </fkey2-10.10> - }) - -test:do_execsql_test( - "fkey2-10.11", - [[ - CREATE TABLE t1(x PRIMARY KEY); - INSERT INTO t1 VALUES('x'); - INSERT INTO t2 VALUES('x'); - ]], { - -- <fkey2-10.11> - -- </fkey2-10.11> - }) - -test:do_catchsql_test( - "fkey2-10.12", - [[ - DROP TABLE t1; - ]], { - -- <fkey2-10.12> - 1, "FOREIGN KEY constraint failed" - -- </fkey2-10.12> - }) - -test:do_execsql_test( - "fkey2-10.13", - [[ - DROP TABLE t2; - DROP TABLE t1; - ]], { - -- <fkey2-10.13> - -- </fkey2-10.13> - }) - test:do_execsql_test( "fkey2-10.14", [[ @@ -1186,7 +1138,7 @@ test:do_execsql_test( -- </fkey2-10.17> }) -test:do_execsql_test( +test:do_catchsql_test( "fkey2-10.18", [[ CREATE TABLE b1(a PRIMARY KEY, b); @@ -1194,28 +1146,30 @@ test:do_execsql_test( DROP TABLE b1; ]], { -- <fkey2-10.18> + 1, "Can't drop space 'B1': other objects depend on it" -- </fkey2-10.18> }) -test:do_execsql_test( +test:do_catchsql_test( "fkey2-10.19", [[ CREATE TABLE b3(a PRIMARY KEY, b REFERENCES b2 DEFERRABLE INITIALLY DEFERRED); DROP TABLE b2; ]], { -- <fkey2-10.19> + 1, "Can't drop space 'B2': other objects depend on it" -- </fkey2-10.19> }) -test:do_execsql_test( +test:do_catchsql_test( "fkey2-10.20", [[ DROP VIEW IF EXISTS v; + CREATE VIEW v AS SELECT * FROM b1; CREATE TABLE t1(x PRIMARY KEY REFERENCES v); - CREATE VIEW v AS SELECT * FROM t1; - DROP VIEW v; ]], { -- <fkey2-10.20> + 1, "referenced table can't be view" -- </fkey2-10.20> }) diff --git a/test/sql-tap/fkey3.test.lua b/test/sql-tap/fkey3.test.lua index 82796ba337a2d0f37b54238fa021ac764993dadf..d7055b0965612cb97923144e53fc5d836dbcaefa 100755 --- a/test/sql-tap/fkey3.test.lua +++ b/test/sql-tap/fkey3.test.lua @@ -36,7 +36,7 @@ test:do_catchsql_test( DROP TABLE t1; ]], { -- <fkey3-1.3.1> - 1, "FOREIGN KEY constraint failed" + 1, "Can't drop space 'T1': other objects depend on it" -- </fkey3-1.3.1> }) @@ -46,7 +46,7 @@ test:do_catchsql_test( DROP TABLE t1; ]], { -- <fkey3-1.3.2> - 1, "FOREIGN KEY constraint failed" + 1, "Can't drop space 'T1': other objects depend on it" -- </fkey3-1.3.2> }) diff --git a/test/sql-tap/gh-2953-drop-table-with-FK.test.lua b/test/sql-tap/gh-2953-drop-table-with-FK.test.lua deleted file mode 100755 index 43e541d788d02814fc8edde0212a0658b2648e6a..0000000000000000000000000000000000000000 --- a/test/sql-tap/gh-2953-drop-table-with-FK.test.lua +++ /dev/null @@ -1,122 +0,0 @@ -#!/usr/bin/env tarantool - -test = require("sqltester") -test:plan(11) - -test:do_execsql_test( - "drop-table-fk-1.1", - [[ - DROP TABLE IF EXISTS t3; - DROP TABLE IF EXISTS t2; - CREATE TABLE t2(id PRIMARY KEY); - CREATE TABLE t3(id PRIMARY KEY REFERENCES t2(id)); - INSERT INTO t2 VALUES(1), (2), (3); - INSERT INTO t3 VALUES(3); - ]], { - -- <drop-table-fk-1.1> - -- <drop-table-fk-1.1> - }) - -test:do_catchsql_test( - "drop-table-fk-1.2", - [[ - DROP TABLE t2; - ]], { - -- <drop-table-fk-1.2> - 1, "FOREIGN KEY constraint failed" - -- <drop-table-fk-1.2> - }) - -test:do_catchsql_test( - "drop-table-fk-1.3", - [[ - DROP TABLE t2; - ]], { - -- <drop-table-fk-1.3> - 1, "FOREIGN KEY constraint failed" - -- <drop-table-fk-1.3> - }) - -test:do_execsql_test( - "drop-table-fk-1.4", - [[ - SELECT * FROM t2; - ]], { - -- <drop-table-fk-1.4> - 1, 2, 3 - -- <drop-table-fk-1.4> - }) - -test:do_catchsql_test( - "drop-table-fk-1.5", - [[ - DELETE FROM t2 WHERE id = 3; - ]], { - -- <drop-table-fk-1.5> - 1, "FOREIGN KEY constraint failed" - -- <drop-table-fk-1.5> - }) - -test:do_execsql_test( - "drop-table-fk-1.6", - [[ - SELECT * FROM t2; - ]], { - -- <drop-table-fk-1.6> - 1, 2, 3 - -- <drop-table-fk-1.6> - }) - -test:do_catchsql_test( - "drop-table-fk-1.7", - [[ - DELETE FROM t2; - ]], { - -- <drop-table-fk-1.7> - 1, "FOREIGN KEY constraint failed" - -- <drop-table-fk-1.7> - }) - -test:do_execsql_test( - "drop-table-fk-1.8", - [[ - SELECT * FROM t2; - ]], { - -- <drop-table-fk-1.8> - 1, 2, 3 - -- <drop-table-fk-1.8> - }) - -test:do_execsql_test( - "drop-table-fk-1.9", - [[ - DROP TABLE t3; - DROP TABLE t2; - ]], { - -- <drop-table-fk-1.9> - -- <drop-table-fk-1.9> - }) - -test:do_execsql_test( - "drop-table-fk-2.1", - [[ - CREATE TABLE t2(id PRIMARY KEY); - CREATE TABLE t3(id PRIMARY KEY REFERENCES t2(id) ON DELETE CASCADE); - INSERT INTO t2 VALUES(1), (2), (3); - INSERT INTO t3 VALUES(3); - ]], { - -- <drop-table-fk-2.1> - -- <drop-table-fk-2.1> - }) - -test:do_execsql_test( - "drop-table-fk-2.2", - [[ - DROP TABLE t2; - SELECT * FROM t3; - ]], { - -- <drop-table-fk-2.2> - -- <drop-table-fk-2.2> - }) - -test:finish_test() diff --git a/test/sql-tap/table.test.lua b/test/sql-tap/table.test.lua index c521b309c5b40ae162a2f9eac3e2cd388d3aa113..3f8182fc469e55ef3d650392353ea9b32c54a4ea 100755 --- a/test/sql-tap/table.test.lua +++ b/test/sql-tap/table.test.lua @@ -730,6 +730,7 @@ test:do_catchsql_test( "table-10.2", [[ DROP TABLE t6; + CREATE TABLE t4(a INT PRIMARY KEY); CREATE TABLE t6(a REFERENCES t4(a) MATCH PARTIAL primary key); ]], { -- <table-10.2> diff --git a/test/sql-tap/tkt-b1d3a2e531.test.lua b/test/sql-tap/tkt-b1d3a2e531.test.lua index d5f34ccfc40e57d3b1e5406143ebe92efc9e1938..e140cf82a17e16272b1a1e7751a285a1b5eb6a8e 100755 --- a/test/sql-tap/tkt-b1d3a2e531.test.lua +++ b/test/sql-tap/tkt-b1d3a2e531.test.lua @@ -124,7 +124,7 @@ test:do_catchsql_test( DROP TABLE cc1; ]], { -- <3.2> - 1, "FOREIGN KEY constraint failed" + 1, "Can't drop space 'PP1': other objects depend on it" -- </3.2> })