diff -cr cvs/pgsql/doc/src/sgml/ref/truncate.sgml cvs.build/pgsql/doc/src/sgml/ref/truncate.sgml *** cvs/pgsql/doc/src/sgml/ref/truncate.sgml 2005-02-22 20:06:18.000000000 +0100 --- cvs.build/pgsql/doc/src/sgml/ref/truncate.sgml 2006-02-02 08:54:29.000000000 +0100 *************** *** 20,26 **** ! TRUNCATE [ TABLE ] name [, ...] --- 20,26 ---- ! TRUNCATE [ TABLE ] name [, ...] [ CASCADE | RESTRICT ] *************** *** 59,67 **** TRUNCATE cannot be used on a table that has foreign-key ! references from other tables, unless all such tables are also truncated ! in the same command. Checking validity in such cases would require table ! scans, and the whole point is not to do one. --- 59,68 ---- TRUNCATE cannot be used on a table that has foreign-key ! references from other tables, unless either all such tables are also ! truncated in the same command or the CASCADE keyword is ! specified. Checking validity in such cases would require table scans, ! and the whole point is not to do one. *************** *** 80,87 **** TRUNCATE TABLE bigtable, fattable; ! Compatibility --- 81,97 ---- TRUNCATE TABLE bigtable, fattable; + + + Truncate the table othertable and cascade to tables that + are referencing othertable via foreign-key constraints: + + + TRUNCATE othertable CASCADE; + + ! Compatibility diff -cr cvs/pgsql/src/backend/catalog/heap.c cvs.build/pgsql/src/backend/catalog/heap.c *** cvs/pgsql/src/backend/catalog/heap.c 2005-11-22 19:17:08.000000000 +0100 --- cvs.build/pgsql/src/backend/catalog/heap.c 2006-02-02 08:54:29.000000000 +0100 *************** *** 2066,2072 **** get_rel_name(con->conrelid), get_rel_name(con->confrelid), NameStr(con->conname)), ! errhint("Truncate table \"%s\" at the same time.", get_rel_name(con->conrelid)))); } } --- 2066,2072 ---- get_rel_name(con->conrelid), get_rel_name(con->confrelid), NameStr(con->conname)), ! errhint("Truncate table \"%s\" at the same time or use TRUNCATE ... CASCADE.", get_rel_name(con->conrelid)))); } } diff -cr cvs/pgsql/src/backend/catalog/namespace.c cvs.build/pgsql/src/backend/catalog/namespace.c *** cvs/pgsql/src/backend/catalog/namespace.c 2005-11-22 19:17:08.000000000 +0100 --- cvs.build/pgsql/src/backend/catalog/namespace.c 2006-02-02 09:21:20.000000000 +0100 *************** *** 1379,1384 **** --- 1379,1409 ---- return rel; } + /* makeRangeVarFromRelId + * Utility routine to get a RangeVar variable from a RelId Oid + * + * If the relation is not found, return NULL if failOK = true, + * otherwise raise an error. + */ + RangeVar * + makeRangeVarFromRelId(Oid relId, bool failOK) + { + char *namespaceName; + char *relName; + Oid namespaceId = get_rel_namespace(relId); + + if (!OidIsValid(namespaceId)) + if (failOK) + return NULL; + else + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_TABLE), + errmsg("relation with OID %d does not exist", relId))); + namespaceName = get_namespace_name(namespaceId); + relName = get_rel_name(relId); + return makeRangeVar(namespaceName, relName); + } + /* * NameListToString * Utility routine to convert a qualified-name list into a string. diff -cr cvs/pgsql/src/backend/commands/tablecmds.c cvs.build/pgsql/src/backend/commands/tablecmds.c *** cvs/pgsql/src/backend/commands/tablecmds.c 2006-01-30 22:52:35.000000000 +0100 --- cvs.build/pgsql/src/backend/commands/tablecmds.c 2006-02-02 09:40:15.000000000 +0100 *************** *** 523,528 **** --- 523,590 ---- performDeletion(&object, behavior); } + /* This function is essentially copied from heap_truncate_check_FKs but I + * decided not to make them share the code because heap_truncate_check_FKs + * needs quite a lot of information for the error message and this function + * just returns an OID list. + * + * We look here for Relations referencing one of the Relations in the + * oids list. We also pass the list of Relations we have already as + * found_earlier. This function will be called until no more new OID is + * found. + * + * What gets found in one run will appear in oids in the next call. + */ + static + List* BuildReferencingRelationList(List* oids, List* found_earlier) + { + List *referencingRels = NIL; + Relation fkeyRel; + SysScanDesc fkeyScan; + HeapTuple tuple; + + /* + * Right now, it is a seqscan because there is no available index on + * confrelid (cf. heap_truncate_check_FKs()). + */ + fkeyRel = heap_open(ConstraintRelationId, AccessShareLock); + fkeyScan = systable_beginscan(fkeyRel, InvalidOid, false, + SnapshotNow, 0, NULL); + + while (HeapTupleIsValid(tuple = systable_getnext(fkeyScan))) + { + Form_pg_constraint con = (Form_pg_constraint) GETSTRUCT(tuple); + + /* Not a foreign key */ + if (con->contype != CONSTRAINT_FOREIGN) + continue; + + /* + * Are we interested in this constraint? We also check for the list + * we're constructing here as a kind of optimization. If we see the + * constraint for b referencing c first during the seqscan and then + * later the one for a referencing b, we can both it in the same scan + */ + if (!list_member_oid(oids, con->confrelid) && + !list_member_oid(referencingRels, con->confrelid)) + continue; + + /* + * Found a referencer that has to be truncated as well, add it to the + * list + */ + if (!list_member_oid(oids, con->conrelid) && + !list_member_oid(found_earlier, con->conrelid)) + referencingRels = lappend_oid(referencingRels, con->conrelid); + } + + systable_endscan(fkeyScan); + heap_close(fkeyRel, AccessShareLock); + + return referencingRels; + } + + /* * ExecuteTruncate * Executes a TRUNCATE command. *************** *** 534,550 **** * are all internal to the group that's being truncated. Finally all * relations are truncated and reindexed. */ void ! ExecuteTruncate(List *relations) { List *rels = NIL; ListCell *cell; foreach(cell, relations) { - RangeVar *rv = lfirst(cell); Relation rel; /* Grab exclusive lock in preparation for truncate */ rel = heap_openrv(rv, AccessExclusiveLock); --- 596,670 ---- * are all internal to the group that's being truncated. Finally all * relations are truncated and reindexed. */ + void ! ExecuteTruncate(List *relations, DropBehavior behavior) { List *rels = NIL; ListCell *cell; + RangeVar *rv; + List *directRels = NIL; + Oid relid; + + if (behavior == DROP_CASCADE) + { + List *cascadedRels = NIL; + List *newCascadedRels = NIL; + + /* build list of OIDs from RangeVars first */ + foreach(cell, relations) + { + /* false = failure is not ok */ + relid = RangeVarGetRelid(lfirst(cell), false); + cascadedRels = lappend_oid(cascadedRels, relid); + directRels = lappend_oid(directRels, relid); + } + + /* + * - cascadedRels contains all the OIDs of the Relations that are + * affected by the TRUNCATE that we have found so far. + * - newCascadedRels contains only those that we have found in the + * last run. + */ + newCascadedRels = cascadedRels; + do { + /* + * Only extend the list further with respect to what we've found in + * the last run (newCascadedRels). Pass the complete list of + * affected OIDs as well such that the function can check what we + * already have. + */ + newCascadedRels = BuildReferencingRelationList(newCascadedRels, + cascadedRels); + cascadedRels = list_union_oid(cascadedRels, newCascadedRels); + } while (list_length(newCascadedRels) > 0); + + /* add newly found relation OIDs to the relation list as RangeVars */ + foreach(cell, cascadedRels) + { + relid = lfirst_oid(cell); + rv = makeRangeVarFromRelId(relid, false); + relations = lappend(relations, rv); + } + } foreach(cell, relations) { Relation rel; + rv = lfirst(cell); + relid = RangeVarGetRelid(rv, false); + if (behavior == DROP_CASCADE && !list_member_oid(directRels, relid)) + /* + * We are about to execute a cascaded truncate, display the message + * only here. If we did it earlier there could be several + * cascade-messages and then an (e.g. permission) failure on one + * of the first tables beeing truncated which could be confusing + */ + ereport(NOTICE, + (errmsg("truncate cascades to table \"%s\"", + rv->relname))); + /* Grab exclusive lock in preparation for truncate */ rel = heap_openrv(rv, AccessExclusiveLock); *************** *** 591,599 **** } /* ! * Check foreign key references. */ ! heap_truncate_check_FKs(rels, false); /* * OK, truncate each table. --- 711,720 ---- } /* ! * Check foreign key references if not in cascade mode. */ ! if (behavior == DROP_RESTRICT) ! heap_truncate_check_FKs(rels, false); /* * OK, truncate each table. diff -cr cvs/pgsql/src/backend/parser/gram.y cvs.build/pgsql/src/backend/parser/gram.y *** cvs/pgsql/src/backend/parser/gram.y 2006-02-02 08:52:31.000000000 +0100 --- cvs.build/pgsql/src/backend/parser/gram.y 2006-02-02 08:54:29.000000000 +0100 *************** *** 2914,2923 **** *****************************************************************************/ TruncateStmt: ! TRUNCATE opt_table qualified_name_list { TruncateStmt *n = makeNode(TruncateStmt); n->relations = $3; $$ = (Node *)n; } ; --- 2914,2924 ---- *****************************************************************************/ TruncateStmt: ! TRUNCATE opt_table qualified_name_list opt_drop_behavior { TruncateStmt *n = makeNode(TruncateStmt); n->relations = $3; + n->behavior = $4; $$ = (Node *)n; } ; diff -cr cvs/pgsql/src/backend/tcop/utility.c cvs.build/pgsql/src/backend/tcop/utility.c *** cvs/pgsql/src/backend/tcop/utility.c 2005-11-29 02:25:49.000000000 +0100 --- cvs.build/pgsql/src/backend/tcop/utility.c 2006-02-02 08:54:29.000000000 +0100 *************** *** 631,637 **** { TruncateStmt *stmt = (TruncateStmt *) parsetree; ! ExecuteTruncate(stmt->relations); } break; --- 631,637 ---- { TruncateStmt *stmt = (TruncateStmt *) parsetree; ! ExecuteTruncate(stmt->relations, stmt->behavior); } break; diff -cr cvs/pgsql/src/bin/psql/tab-complete.c cvs.build/pgsql/src/bin/psql/tab-complete.c *** cvs/pgsql/src/bin/psql/tab-complete.c 2006-01-11 10:46:08.000000000 +0100 --- cvs.build/pgsql/src/bin/psql/tab-complete.c 2006-02-02 08:54:29.000000000 +0100 *************** *** 1686,1692 **** /* TRUNCATE */ else if (pg_strcasecmp(prev_wd, "TRUNCATE") == 0) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL); ! /* UNLISTEN */ else if (pg_strcasecmp(prev_wd, "UNLISTEN") == 0) COMPLETE_WITH_QUERY("SELECT pg_catalog.quote_ident(relname) FROM pg_catalog.pg_listener WHERE substring(pg_catalog.quote_ident(relname),1,%d)='%s' UNION SELECT '*'"); --- 1686,1699 ---- /* TRUNCATE */ else if (pg_strcasecmp(prev_wd, "TRUNCATE") == 0) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL); ! else if (pg_strcasecmp(prev2_wd, "TRUNCATE") == 0 || ! (pg_strcasecmp(prev3_wd, "TRUNCATE") == 0 && ! pg_strcasecmp(prev2_wd, "TABLE") == 0)) ! { ! static const char *const list_DROPCR[] = ! {"CASCADE", "RESTRICT", NULL}; ! COMPLETE_WITH_LIST(list_DROPCR); ! } /* UNLISTEN */ else if (pg_strcasecmp(prev_wd, "UNLISTEN") == 0) COMPLETE_WITH_QUERY("SELECT pg_catalog.quote_ident(relname) FROM pg_catalog.pg_listener WHERE substring(pg_catalog.quote_ident(relname),1,%d)='%s' UNION SELECT '*'"); diff -cr cvs/pgsql/src/include/catalog/namespace.h cvs.build/pgsql/src/include/catalog/namespace.h *** cvs/pgsql/src/include/catalog/namespace.h 2005-10-15 04:49:42.000000000 +0200 --- cvs.build/pgsql/src/include/catalog/namespace.h 2006-02-02 09:09:41.000000000 +0100 *************** *** 77,82 **** --- 77,83 ---- extern Oid LookupCreationNamespace(const char *nspname); extern Oid QualifiedNameGetCreationNamespace(List *names, char **objname_p); extern RangeVar *makeRangeVarFromNameList(List *names); + extern RangeVar *makeRangeVarFromRelId(Oid relId, bool failOK); extern char *NameListToString(List *names); extern char *NameListToQuotedString(List *names); diff -cr cvs/pgsql/src/include/commands/tablecmds.h cvs.build/pgsql/src/include/commands/tablecmds.h *** cvs/pgsql/src/include/commands/tablecmds.h 2005-11-21 13:49:32.000000000 +0100 --- cvs.build/pgsql/src/include/commands/tablecmds.h 2006-02-02 08:54:29.000000000 +0100 *************** *** 36,42 **** Oid oldNspOid, Oid newNspOid, bool hasDependEntry); ! extern void ExecuteTruncate(List *relations); extern void renameatt(Oid myrelid, const char *oldattname, --- 36,42 ---- Oid oldNspOid, Oid newNspOid, bool hasDependEntry); ! extern void ExecuteTruncate(List *relations, DropBehavior behavior); extern void renameatt(Oid myrelid, const char *oldattname, diff -cr cvs/pgsql/src/include/nodes/parsenodes.h cvs.build/pgsql/src/include/nodes/parsenodes.h *** cvs/pgsql/src/include/nodes/parsenodes.h 2006-01-23 23:52:37.000000000 +0100 --- cvs.build/pgsql/src/include/nodes/parsenodes.h 2006-02-02 08:54:29.000000000 +0100 *************** *** 1308,1313 **** --- 1308,1314 ---- { NodeTag type; List *relations; /* relations (RangeVars) to be truncated */ + DropBehavior behavior; /* RESTRICT or CASCADE behavior */ } TruncateStmt; /* ---------------------- diff -cr cvs/pgsql/src/test/regress/expected/truncate.out cvs.build/pgsql/src/test/regress/expected/truncate.out *** cvs/pgsql/src/test/regress/expected/truncate.out 2005-01-27 04:19:08.000000000 +0100 --- cvs.build/pgsql/src/test/regress/expected/truncate.out 2006-02-02 08:54:29.000000000 +0100 *************** *** 40,69 **** TRUNCATE TABLE truncate_a; -- fail ERROR: cannot truncate a table referenced in a foreign key constraint DETAIL: Table "trunc_b" references "truncate_a" via foreign key constraint "trunc_b_a_fkey". ! HINT: Truncate table "trunc_b" at the same time. TRUNCATE TABLE truncate_a,trunc_b; -- fail ERROR: cannot truncate a table referenced in a foreign key constraint DETAIL: Table "trunc_e" references "truncate_a" via foreign key constraint "trunc_e_a_fkey". ! HINT: Truncate table "trunc_e" at the same time. TRUNCATE TABLE truncate_a,trunc_b,trunc_e; -- ok TRUNCATE TABLE truncate_a,trunc_e; -- fail ERROR: cannot truncate a table referenced in a foreign key constraint DETAIL: Table "trunc_b" references "truncate_a" via foreign key constraint "trunc_b_a_fkey". ! HINT: Truncate table "trunc_b" at the same time. TRUNCATE TABLE trunc_c; -- fail ERROR: cannot truncate a table referenced in a foreign key constraint DETAIL: Table "trunc_d" references "trunc_c" via foreign key constraint "trunc_d_a_fkey". ! HINT: Truncate table "trunc_d" at the same time. TRUNCATE TABLE trunc_c,trunc_d; -- fail ERROR: cannot truncate a table referenced in a foreign key constraint DETAIL: Table "trunc_e" references "trunc_c" via foreign key constraint "trunc_e_b_fkey". ! HINT: Truncate table "trunc_e" at the same time. TRUNCATE TABLE trunc_c,trunc_d,trunc_e; -- ok TRUNCATE TABLE trunc_c,trunc_d,trunc_e,truncate_a; -- fail ERROR: cannot truncate a table referenced in a foreign key constraint DETAIL: Table "trunc_b" references "truncate_a" via foreign key constraint "trunc_b_a_fkey". ! HINT: Truncate table "trunc_b" at the same time. TRUNCATE TABLE trunc_c,trunc_d,trunc_e,truncate_a,trunc_b; -- ok -- circular references ALTER TABLE truncate_a ADD FOREIGN KEY (col1) REFERENCES trunc_c; -- Add some data to verify that truncating actually works ... --- 40,76 ---- TRUNCATE TABLE truncate_a; -- fail ERROR: cannot truncate a table referenced in a foreign key constraint DETAIL: Table "trunc_b" references "truncate_a" via foreign key constraint "trunc_b_a_fkey". ! HINT: Truncate table "trunc_b" at the same time or use TRUNCATE ... CASCADE. TRUNCATE TABLE truncate_a,trunc_b; -- fail ERROR: cannot truncate a table referenced in a foreign key constraint DETAIL: Table "trunc_e" references "truncate_a" via foreign key constraint "trunc_e_a_fkey". ! HINT: Truncate table "trunc_e" at the same time or use TRUNCATE ... CASCADE. TRUNCATE TABLE truncate_a,trunc_b,trunc_e; -- ok TRUNCATE TABLE truncate_a,trunc_e; -- fail ERROR: cannot truncate a table referenced in a foreign key constraint DETAIL: Table "trunc_b" references "truncate_a" via foreign key constraint "trunc_b_a_fkey". ! HINT: Truncate table "trunc_b" at the same time or use TRUNCATE ... CASCADE. TRUNCATE TABLE trunc_c; -- fail ERROR: cannot truncate a table referenced in a foreign key constraint DETAIL: Table "trunc_d" references "trunc_c" via foreign key constraint "trunc_d_a_fkey". ! HINT: Truncate table "trunc_d" at the same time or use TRUNCATE ... CASCADE. TRUNCATE TABLE trunc_c,trunc_d; -- fail ERROR: cannot truncate a table referenced in a foreign key constraint DETAIL: Table "trunc_e" references "trunc_c" via foreign key constraint "trunc_e_b_fkey". ! HINT: Truncate table "trunc_e" at the same time or use TRUNCATE ... CASCADE. TRUNCATE TABLE trunc_c,trunc_d,trunc_e; -- ok TRUNCATE TABLE trunc_c,trunc_d,trunc_e,truncate_a; -- fail ERROR: cannot truncate a table referenced in a foreign key constraint DETAIL: Table "trunc_b" references "truncate_a" via foreign key constraint "trunc_b_a_fkey". ! HINT: Truncate table "trunc_b" at the same time or use TRUNCATE ... CASCADE. TRUNCATE TABLE trunc_c,trunc_d,trunc_e,truncate_a,trunc_b; -- ok + TRUNCATE TABLE truncate_a RESTRICT; -- fail + ERROR: cannot truncate a table referenced in a foreign key constraint + DETAIL: Table "trunc_b" references "truncate_a" via foreign key constraint "trunc_b_a_fkey". + HINT: Truncate table "trunc_b" at the same time or use TRUNCATE ... CASCADE. + TRUNCATE TABLE truncate_a CASCADE; -- ok + NOTICE: truncate cascades to table "trunc_b" + NOTICE: truncate cascades to table "trunc_e" -- circular references ALTER TABLE truncate_a ADD FOREIGN KEY (col1) REFERENCES trunc_c; -- Add some data to verify that truncating actually works ... *************** *** 75,93 **** TRUNCATE TABLE trunc_c; ERROR: cannot truncate a table referenced in a foreign key constraint DETAIL: Table "trunc_d" references "trunc_c" via foreign key constraint "trunc_d_a_fkey". ! HINT: Truncate table "trunc_d" at the same time. TRUNCATE TABLE trunc_c,trunc_d; ERROR: cannot truncate a table referenced in a foreign key constraint DETAIL: Table "trunc_e" references "trunc_c" via foreign key constraint "trunc_e_b_fkey". ! HINT: Truncate table "trunc_e" at the same time. TRUNCATE TABLE trunc_c,trunc_d,trunc_e; ERROR: cannot truncate a table referenced in a foreign key constraint DETAIL: Table "truncate_a" references "trunc_c" via foreign key constraint "truncate_a_col1_fkey". ! HINT: Truncate table "truncate_a" at the same time. TRUNCATE TABLE trunc_c,trunc_d,trunc_e,truncate_a; ERROR: cannot truncate a table referenced in a foreign key constraint DETAIL: Table "trunc_b" references "truncate_a" via foreign key constraint "trunc_b_a_fkey". ! HINT: Truncate table "trunc_b" at the same time. TRUNCATE TABLE trunc_c,trunc_d,trunc_e,truncate_a,trunc_b; -- Verify that truncating did actually work SELECT * FROM truncate_a --- 82,100 ---- TRUNCATE TABLE trunc_c; ERROR: cannot truncate a table referenced in a foreign key constraint DETAIL: Table "trunc_d" references "trunc_c" via foreign key constraint "trunc_d_a_fkey". ! HINT: Truncate table "trunc_d" at the same time or use TRUNCATE ... CASCADE. TRUNCATE TABLE trunc_c,trunc_d; ERROR: cannot truncate a table referenced in a foreign key constraint DETAIL: Table "trunc_e" references "trunc_c" via foreign key constraint "trunc_e_b_fkey". ! HINT: Truncate table "trunc_e" at the same time or use TRUNCATE ... CASCADE. TRUNCATE TABLE trunc_c,trunc_d,trunc_e; ERROR: cannot truncate a table referenced in a foreign key constraint DETAIL: Table "truncate_a" references "trunc_c" via foreign key constraint "truncate_a_col1_fkey". ! HINT: Truncate table "truncate_a" at the same time or use TRUNCATE ... CASCADE. TRUNCATE TABLE trunc_c,trunc_d,trunc_e,truncate_a; ERROR: cannot truncate a table referenced in a foreign key constraint DETAIL: Table "trunc_b" references "truncate_a" via foreign key constraint "trunc_b_a_fkey". ! HINT: Truncate table "trunc_b" at the same time or use TRUNCATE ... CASCADE. TRUNCATE TABLE trunc_c,trunc_d,trunc_e,truncate_a,trunc_b; -- Verify that truncating did actually work SELECT * FROM truncate_a *************** *** 106,111 **** --- 113,145 ---- ---+--- (0 rows) + -- Add data again to test TRUNCATE ... CASCADE + INSERT INTO trunc_c VALUES (1); + INSERT INTO truncate_a VALUES (1); + INSERT INTO trunc_b VALUES (1); + INSERT INTO trunc_d VALUES (1); + INSERT INTO trunc_e VALUES (1,1); + TRUNCATE TABLE trunc_c CASCADE; -- ok + NOTICE: truncate cascades to table "trunc_d" + NOTICE: truncate cascades to table "trunc_e" + NOTICE: truncate cascades to table "truncate_a" + NOTICE: truncate cascades to table "trunc_b" + SELECT * FROM truncate_a + UNION ALL + SELECT * FROM trunc_c + UNION ALL + SELECT * FROM trunc_b + UNION ALL + SELECT * FROM trunc_d; + col1 + ------ + (0 rows) + + SELECT * FROM trunc_e; + a | b + ---+--- + (0 rows) + DROP TABLE truncate_a,trunc_c,trunc_b,trunc_d,trunc_e CASCADE; NOTICE: drop cascades to constraint trunc_e_a_fkey on table trunc_e NOTICE: drop cascades to constraint trunc_b_a_fkey on table trunc_b diff -cr cvs/pgsql/src/test/regress/sql/truncate.sql cvs.build/pgsql/src/test/regress/sql/truncate.sql *** cvs/pgsql/src/test/regress/sql/truncate.sql 2005-01-27 04:19:37.000000000 +0100 --- cvs.build/pgsql/src/test/regress/sql/truncate.sql 2006-02-02 08:54:29.000000000 +0100 *************** *** 30,35 **** --- 30,38 ---- TRUNCATE TABLE trunc_c,trunc_d,trunc_e,truncate_a; -- fail TRUNCATE TABLE trunc_c,trunc_d,trunc_e,truncate_a,trunc_b; -- ok + TRUNCATE TABLE truncate_a RESTRICT; -- fail + TRUNCATE TABLE truncate_a CASCADE; -- ok + -- circular references ALTER TABLE truncate_a ADD FOREIGN KEY (col1) REFERENCES trunc_c; *************** *** 55,58 **** --- 58,79 ---- SELECT * FROM trunc_d; SELECT * FROM trunc_e; + -- Add data again to test TRUNCATE ... CASCADE + INSERT INTO trunc_c VALUES (1); + INSERT INTO truncate_a VALUES (1); + INSERT INTO trunc_b VALUES (1); + INSERT INTO trunc_d VALUES (1); + INSERT INTO trunc_e VALUES (1,1); + + TRUNCATE TABLE trunc_c CASCADE; -- ok + + SELECT * FROM truncate_a + UNION ALL + SELECT * FROM trunc_c + UNION ALL + SELECT * FROM trunc_b + UNION ALL + SELECT * FROM trunc_d; + SELECT * FROM trunc_e; + DROP TABLE truncate_a,trunc_c,trunc_b,trunc_d,trunc_e CASCADE;