Skip to content

Commit

Permalink
Revert "Forbid table rewrite in ALTER TABLE ADD COLUMN ... DEFAULT us…
Browse files Browse the repository at this point in the history
…ing volatile functions if DDL replication is turned on"

This reverts commit 17c4922.
  • Loading branch information
Zheng (Zane) Li committed Apr 28, 2022
1 parent 17c4922 commit 06549e4
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 43 deletions.
10 changes: 0 additions & 10 deletions src/backend/catalog/heap.c
Original file line number Diff line number Diff line change
Expand Up @@ -2328,18 +2328,8 @@ AddRelationNewConstraints(Relation rel,

/* If the DEFAULT is volatile we cannot use a missing value */
if (colDef->missingMode && contain_volatile_functions((Node *) expr))
{
colDef->missingMode = false;

if (XLogLogicalInfoActive() &&
ddl_need_xlog(rel->rd_id, false))
{
elog(ERROR,
"cannot rewrite table using volatile functions in DDL statement when DDL replication is turned on. "
"Please rewrite the DDL statement so it does not generate nondeterministic data.");
}
}

defOid = StoreAttrDefault(rel, colDef->attnum, expr, is_internal,
colDef->missingMode);

Expand Down
49 changes: 16 additions & 33 deletions src/test/subscription/t/030_rep_ddls.pl
Original file line number Diff line number Diff line change
Expand Up @@ -244,111 +244,111 @@ BEGIN
$result_sub = $node_subscriber->safe_psql('postgres', "SELECT count(*) from s1.view1;");
is($result, qq($result_sub), 'CREATE of s1.view1 is replicated');

# Test CREATE TABLE AS stmt
# TEST CREATE TABLE AS stmt
$node_publisher->safe_psql('postgres', "CREATE TABLE s1.t3 AS SELECT a, b from s1.t1;");

$node_publisher->wait_for_catchup('mysub');

$result = $node_subscriber->safe_psql('postgres', "SELECT count(*) from s1.t3;");
is($result, qq(2), 'CREATE TABLE s1.t3 AS is replicated with data');

# Test CREATE TABLE AS stmt ... WITH NO DATA
# TEST CREATE TABLE AS stmt ... WITH NO DATA
$node_publisher->safe_psql('postgres', "CREATE TABLE s1.t4 AS SELECT a, b from s1.t1 WITH NO DATA;");

$node_publisher->wait_for_catchup('mysub');

$result = $node_subscriber->safe_psql('postgres', "SELECT count(*) from s1.t4;");
is($result, qq(0), 'CREATE TABLE s1.t4 AS is replicated with no data');

# Test SELECT INTO stmt
# TEST SELECT INTO stmt
$node_publisher->safe_psql('postgres', "SELECT b into s1.t6 from s1.t1 where a > 1");

$node_publisher->wait_for_catchup('mysub');

$result = $node_subscriber->safe_psql('postgres', "SELECT count(*) from s1.t6;");
is($result, qq(1), 'SELECT INTO s1.t6 is replicated with data');

# Test Create DomainStmt
# TEST Create DomainStmt
$node_publisher->safe_psql('postgres', "CREATE DOMAIN s1.space_check AS VARCHAR NOT NULL CHECK (value !~ '\s');");

$node_publisher->wait_for_catchup('mysub');

$result = $node_subscriber->safe_psql('postgres', "SELECT t.typnotnull from pg_catalog.pg_type t where t.typname='space_check';");
is($result, qq(t), 'CreateDomain Stmt is replicatted');

# Test AlterDomainStmt
# TEST AlterDomainStmt
$node_publisher->safe_psql('postgres', "Alter domain s1.space_check drop not null;");

$node_publisher->wait_for_catchup('mysub');

$result = $node_subscriber->safe_psql('postgres', "SELECT t.typnotnull from pg_catalog.pg_type t where t.typname='space_check';");
is($result, qq(f), 'ALTER DOMAIN Stmt is replicated');

#Test DEFINE Stmt
#TEST DEFINE Stmt
$node_publisher->safe_psql('postgres', "CREATE AGGREGATE s1.inc_sum(int) (sfunc = int4pl,stype = int,initcond = 10);");

$node_publisher->wait_for_catchup('mysub');

$result = $node_subscriber->safe_psql('postgres', "SELECT count(*) from pg_catalog.pg_proc p where p.proname='inc_sum';");
is($result, qq(1), 'Define stmt is replicated');

# Test CompositeTypeStmt
#TEST CompositeTypeStmt
$node_publisher->safe_psql('postgres', "CREATE TYPE s1.compfoo AS (f1 int, f2 text);");

$node_publisher->wait_for_catchup('mysub');

$result = $node_subscriber->safe_psql('postgres', "SELECT count(*) from pg_catalog.pg_type t where t.typname='compfoo';");
is($result, qq(1), 'CompositeType Stmt is replicated');

# Test CreateEnum Stmt
#TEST CreateEnum Stmt
$node_publisher->safe_psql('postgres', "CREATE TYPE s1.mood AS ENUM ('sad', 'ok', 'happy');");

$node_publisher->wait_for_catchup('mysub');

$result = $node_subscriber->safe_psql('postgres', "SELECT count(*) from pg_catalog.pg_type t where t.typname='mood';");
is($result, qq(1), 'CreateEnumType Stmt is replicated');

# Test AlterEnum Stmt
#TEST AlterEnum Stmt
$node_publisher->safe_psql('postgres', "ALTER TYPE s1.mood RENAME VALUE 'sad' to 'fine';");

$node_publisher->wait_for_catchup('mysub');

$result = $node_subscriber->safe_psql('postgres', "SELECT count(*) FROM pg_catalog.pg_enum e, pg_catalog.pg_type t WHERE e.enumtypid = t.oid AND t.typname='mood' AND e.enumlabel='fine';");
is($result, qq(1), 'AlterEnumType Stmt is replicated');

# Test CreateRange Stmt
#TEST CreateRange Stmt
$node_publisher->safe_psql('postgres', "CREATE TYPE floatrange AS RANGE (subtype = float8,subtype_diff = float8mi);");

$node_publisher->wait_for_catchup('mysub');

$result = $node_subscriber->safe_psql('postgres', "SELECT count(*) from pg_catalog.pg_type t where t.typname='floatrange';");
is($result, qq(1), 'CreateRange Stmt is replicated');

# Test VIEW Stmt
#TEST VIEW Stmt
$node_publisher->safe_psql('postgres', "CREATE VIEW s1.vista AS SELECT 'Hello World';");

$node_publisher->wait_for_catchup('mysub');

$result = $node_subscriber->safe_psql('postgres', "SELECT count(*) from pg_catalog.pg_class c where c.relname='vista';");
is($result, qq(1), 'VIEW Stmt is replicated');

# Test CreateFunction Stmt
#TEST CreateFunction Stmt
$node_publisher->safe_psql('postgres', "CREATE FUNCTION s1.add(a integer, b integer) RETURNS integer LANGUAGE SQL IMMUTABLE RETURN a + b;");

$node_publisher->wait_for_catchup('mysub');

$result = $node_subscriber->safe_psql('postgres', "SELECT count(*) from pg_catalog.pg_proc p where p.proname='add';");
is($result, qq(1), 'CreateFunction Stmt is replicated');

# Test CreateCast Stmt
#TEST CreateCast Stmt
$node_publisher->safe_psql('postgres', "CREATE CAST (int AS int4) WITH FUNCTION add(int,int) AS ASSIGNMENT;");

$node_publisher->wait_for_catchup('mysub');

$result = $node_subscriber->safe_psql('postgres', "SELECT count(*) FROM pg_catalog.pg_cast c, pg_catalog.pg_proc p WHERE p.proname='add' AND c.castfunc=p.oid;");
is($result, qq(1), 'CreateCast Stmt is replicated');

# Test DDL in function
#TEST DDL in function
$node_publisher->safe_psql('postgres', qq{
CREATE OR REPLACE FUNCTION func_ddl (tname varchar(20))
RETURNS VOID AS \$\$
Expand All @@ -368,7 +368,7 @@ BEGIN
$result = $node_subscriber->safe_psql('postgres', "SELECT count(*) FROM s1.func_table where c3 = 22;");
is($result, qq(1), 'DDLs in function are replicated');

# Test DDL in procedure
#TEST DDL in procedure
$node_publisher->safe_psql('postgres', qq{
CREATE OR REPLACE procedure proc_ddl (tname varchar(20))
LANGUAGE plpgsql AS \$\$
Expand All @@ -386,24 +386,7 @@ BEGIN
$result = $node_subscriber->safe_psql('postgres', "SELECT count(*) FROM s1.proc_table where c3 = 22;");
is($result, qq(1), 'DDLs in procedure are replicated');

# Test Alter table alter column type stmt is replicated
$node_publisher->safe_psql('postgres', "ALTER TABLE test_rep ALTER COLUMN name type TEXT;");

$node_publisher->wait_for_catchup('mysub');

$result = $node_subscriber->safe_psql('postgres', "SELECT data_type FROM information_schema.columns WHERE table_name = 'test_rep' and column_name = 'name';");
is($result, qq(text), 'Alter table column type stmt is replicated');

# Test certain DDLs are not replicated
# Test DDL statement that rewrites table with volatile functions are not replicated
my $ret;
my $stdout;
my $stderr;
($ret, $stdout, $stderr) = $node_publisher->psql('postgres', "ALTER TABLE test_rep ADD COLUMN bar double precision DEFAULT 3 * random();", $stderr, on_error_die => 0, on_error_stop => 0);

ok( $stderr =~
m/ERROR: cannot rewrite table using volatile functions in DDL statement when DDL replication is turned on. Please rewrite the DDL statement so it does not generate nondeterministic data./,
"Throws ERROR when executing: ALTER TABLE ADD COLUMN ... DEFAULT random().");
#TODO TEST certain DDLs are not replicated

pass "DDL replication tests passed!";

Expand Down

0 comments on commit 06549e4

Please sign in to comment.