Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PG17 compatibility: Fix Test Failure in multi_alter_table_add_const #7733

Merged
merged 2 commits into from
Dec 23, 2024

Conversation

m3hm3t
Copy link
Contributor

@m3hm3t m3hm3t commented Nov 11, 2024

In earlier versions of PostgreSQL, exclusion constraints were not allowed on partitioned tables. This is why the error in your regression test (ERROR: exclusion constraints are not supported on partitioned tables) was raised in PostgreSQL 16. In PostgreSQL 17, exclusion constraints are now allowed on partitioned tables, which is why the error no longer appears when you attempt to add an exclusion constraint.

The constraint exclusion mechanism, described in the documentation, relies on CHECK constraints to decide which partitions or child tables need to be queried.

CHECK constraints

 -- Check "ADD EXCLUDE" errors out for partitioned table since the postgres does not allow it
 ALTER TABLE AT_AddConstNoName.citus_local_partitioned_table ADD EXCLUDE(partition_col WITH =);
-ERROR:  exclusion constraints are not supported on partitioned tables
 -- Check "ADD CHECK"
 SET client_min_messages TO DEBUG1;
 ALTER TABLE AT_AddConstNoName.citus_local_partitioned_table ADD CHECK (dist_col > 0);
 DEBUG:  the constraint name on the shards of the partition is too long, switching to sequential and local execution mode to prevent self deadlocks: longlonglonglonglonglonglonglonglonglonglonglo_537570f5_5_check
 DEBUG:  verifying table "longlonglonglonglonglonglonglonglonglonglonglonglonglonglongabc"
 DEBUG:  verifying table "p1"
 RESET client_min_messages;
 SELECT con.conname
     FROM pg_catalog.pg_constraint con
       INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
       INNER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace
           WHERE rel.relname = 'citus_local_partitioned_table';
                      conname                      
 --------------------------------------------------
+ citus_local_partitioned_table_partition_col_excl
  citus_local_partitioned_table_check
-(1 row)
+(2 rows)

@m3hm3t m3hm3t self-assigned this Nov 11, 2024
Copy link

codecov bot commented Nov 11, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Please upload report for BASE (release-13.0@2d843cb). Learn more about missing BASE report.

Additional details and impacted files
@@               Coverage Diff               @@
##             release-13.0    #7733   +/-   ##
===============================================
  Coverage                ?   89.65%           
===============================================
  Files                   ?      274           
  Lines                   ?    59611           
  Branches                ?     7437           
===============================================
  Hits                    ?    53443           
  Misses                  ?     4035           
  Partials                ?     2133           

@m3hm3t m3hm3t marked this pull request as ready for review November 11, 2024 20:48
@m3hm3t m3hm3t changed the title Fix Test Failure in multi_alter_table_add_const in PG17 PG17 compatibility: Fix Test Failure in multi_alter_table_add_const in PG17 Nov 12, 2024
Copy link
Member

@naisila naisila left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given that we lack in documentation right now, let me introduce this concept here as it's a good PR for it.
For new things that PG allows, like an exclusion constraint on partitioned tables, first we make sure that it works as it is supposed to in Citus.
If it does, our general practice is to create a new file to test it, namely pg17.sql where we add all such things. We will populate this file with other things as we go on with the support. (For this reason we have pg16.sql pg15.sql tests etc.) I will include this in the documentation for new PG support.

With that in mind, could you adjust this PR accordingly? I don't think we need to add a new output file for multi_alter_table_add_constraints. Instead, we can create pg17.sql file which will have pg17.out and pg17_0.out, and include this particular test case there. In this case, the pg17_0.out file will have the error exclusion constraints are not supported on partitioned tables.

@naisila naisila changed the title PG17 compatibility: Fix Test Failure in multi_alter_table_add_const in PG17 PG17 compatibility: Fix Test Failure in multi_alter_table_add_const Nov 12, 2024
@m3hm3t m3hm3t marked this pull request as draft November 15, 2024 08:39
@m3hm3t m3hm3t force-pushed the m3hm3t/multi_alter_table_add_const branch 2 times, most recently from fa4854a to 765d397 Compare November 15, 2024 15:35
@m3hm3t
Copy link
Contributor Author

m3hm3t commented Nov 15, 2024

Given that we lack in documentation right now, let me introduce this concept here as it's a good PR for it. For new things that PG allows, like an exclusion constraint on partitioned tables, first we make sure that it works as it is supposed to in Citus. If it does, our general practice is to create a new file to test it, namely pg17.sql where we add all such things. We will populate this file with other things as we go on with the support. (For this reason we have pg16.sql pg15.sql tests etc.) I will include this in the documentation for new PG support.

With that in mind, could you adjust this PR accordingly? I don't think we need to add a new output file for multi_alter_table_add_constraints. Instead, we can create pg17.sql file which will have pg17.out and pg17_0.out, and include this particular test case there. In this case, the pg17_0.out file will have the error exclusion constraints are not supported on partitioned tables.

@naisila Can you review the solution? If it is acceptable, I will update the PR to prepare it for merging into the release branch.

@m3hm3t m3hm3t marked this pull request as ready for review November 15, 2024 16:35
@naisila naisila force-pushed the naisila/pg17_support branch from b29c332 to 1cf690f Compare November 17, 2024 20:46
@@ -785,38 +785,6 @@ SELECT con.conname
\c - - :master_host :master_port
ALTER TABLE AT_AddConstNoName.citus_local_partitioned_table DROP CONSTRAINT citus_local_partitioned_table_partition_col_key;

-- Check "ADD EXCLUDE" errors out for partitioned table since the postgres does not allow it
ALTER TABLE AT_AddConstNoName.citus_local_partitioned_table ADD EXCLUDE(partition_col WITH =);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that in this test, we only need to remove the line that adds the exclusion constraint, not the rest.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done


\c - - :master_host :master_port
-- Check "ADD EXCLUDE" errors out for partitioned table since the postgres does not allow it before PG 17
ALTER TABLE AT_AddConstNoName.citus_local_partitioned_table ADD EXCLUDE(partition_col WITH =);
Copy link
Member

@naisila naisila Nov 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given that this is now something new that Citus supports, we don't necessarily need to add the exact same test that was in multi_alter_table_add_constraints_without_name.sql. We should include that particular test case for sure, i.e. ALTER TABLE ADD EXCLUDE CONSTRAINT, but we can (should) do more to test this feature.

If we consider this as a new feature in Citus (even though it doesnt need extra code work, apparently), we can create a "simpler/more readable" test, e.g. with the following steps:

Create distributed partitioned table dist_blabla
create partitioned citus local table citus_local_blabla
add exclude constraint with name in dist_blabla
check that its propagated to the workers properly
add exclude constraint with name in citus_local_blabla
check that it was added correctly
add exclusin constraints without name in both tables
verify previous command worked
alter the constraints (if meaningful?)
verify previous command worked
drop constraints
verify previous command worked
something else you can think of?

A test like the above is actually what we run when we want to make sure that something works as it should in Citus. (i.e. something is distributed properly)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@naisila

I’ve prepared a draft of the test based on this plan. Could you review it, please?
Should this test be in the pg17.sql file?

-- Test for exclusion constraints on partitioned and distributed partitioned tables in Citus environment

-- Step 1: Create a distributed partitioned table
CREATE TABLE distributed_partitioned_table (
    id serial PRIMARY KEY,
    partition_col int NOT NULL
) DISTRIBUTED BY (id)
PARTITION BY RANGE (partition_col);

-- Step 2: Create a partitioned Citus local table
CREATE TABLE local_partitioned_table (
    id serial PRIMARY KEY,
    partition_col int NOT NULL
) PARTITION BY RANGE (partition_col);

-- Step 3: Add an exclusion constraint with a name to the distributed partitioned table
ALTER TABLE distributed_partitioned_table ADD CONSTRAINT dist_exclude_named EXCLUDE USING gist (partition_col WITH =);

-- Step 4: Verify propagation of exclusion constraint to worker nodes
\c - - :public_worker_1_host :worker_1_port
SELECT * FROM pg_dist_shard_exclude WHERE constraint_name = dist_exclude_named;

-- Step 5: Add an exclusion constraint with a name to the Citus local partitioned table
\c - - :master_host :master_port
ALTER TABLE local_partitioned_table ADD CONSTRAINT local_exclude_named EXCLUDE USING gist (partition_col WITH =);

-- Step 6: Verify the exclusion constraint on the local partitioned table
SELECT conname FROM pg_constraint WHERE conname = 'local_exclude_named';

-- Step 7: Add exclusion constraints without names to both tables
ALTER TABLE distributed_partitioned_table ADD EXCLUDE USING gist (partition_col WITH =);
ALTER TABLE local_partitioned_table ADD EXCLUDE USING gist (partition_col WITH =);

-- Step 8: Verify the unnamed exclusion constraints were added
SELECT * FROM pg_constraint WHERE conrelid = 'local_partitioned_table'::regclass;
\c - - :public_worker_1_host :worker_1_port
SELECT * FROM pg_constraint WHERE conrelid = 'distributed_partitioned_table'::regclass;

-- Step 9: Drop the exclusion constraints from both tables
\c - - :master_host :master_port
ALTER TABLE distributed_partitioned_table DROP CONSTRAINT dist_exclude_named;
ALTER TABLE local_partitioned_table DROP CONSTRAINT local_exclude_named;

-- Step 10: Verify the constraints were dropped
SELECT * FROM pg_constraint WHERE conname = 'dist_exclude_named';
SELECT * FROM pg_constraint WHERE conname = 'local_exclude_named';

-- Step 11: Clean up - Drop the tables
DROP TABLE IF EXISTS distributed_partitioned_table;
DROP TABLE IF EXISTS local_partitioned_table;

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very nice tests!

Should this test be in the pg17.sql file?

Yes

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tests are added

@naisila naisila force-pushed the naisila/pg17_support branch 9 times, most recently from e108bb8 to c396ce6 Compare November 22, 2024 13:27
@m3hm3t m3hm3t marked this pull request as draft November 28, 2024 15:02
@m3hm3t m3hm3t force-pushed the m3hm3t/multi_alter_table_add_const branch from 765d397 to bb75e64 Compare November 28, 2024 15:03
@m3hm3t m3hm3t requested a review from colm-mchugh December 3, 2024 15:32
Copy link
Member

@naisila naisila left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mostly looks good, thanks! Added some small comments.

src/test/regress/sql/pg17.sql Outdated Show resolved Hide resolved
src/test/regress/sql/pg17.sql Outdated Show resolved Hide resolved
src/test/regress/sql/pg17.sql Outdated Show resolved Hide resolved
-- Test for exclusion constraints on partitioned and distributed partitioned tables in Citus environment
-- Step 1: Create a distributed partitioned table
\c - - :master_host :master_port
CREATE TABLE distributed_partitioned_table (
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Almost forgot: let's also add partitions to the partitioned tables so that they become more meaningful partitioned tables.

You can see this example https://github.com/citusdata/citus/blob/main/src/test/regress/sql/multi_alter_table_add_constraints_without_name.sql#L730-L734

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Altered the test

@m3hm3t m3hm3t force-pushed the m3hm3t/pg17_support branch from ed02286 to 383e4a2 Compare December 16, 2024 19:36
@m3hm3t m3hm3t force-pushed the m3hm3t/multi_alter_table_add_const branch 2 times, most recently from afea11c to 60af89b Compare December 16, 2024 19:44
@m3hm3t m3hm3t requested a review from naisila December 17, 2024 06:24
Copy link
Member

@naisila naisila left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sometimes I reach a deadlock when the partition name is long. Steps to reproduce:

-- create partitioned table
CREATE TABLE distributed_partitioned_table (
    id serial NOT NULL,
    partition_col int NOT NULL,
    PRIMARY KEY (id, partition_col)
) PARTITION BY RANGE (partition_col);

-- add normal length name partition
CREATE TABLE distributed_partitioned_table_p1 PARTITION OF distributed_partitioned_table 
FOR VALUES FROM (1) TO (100);

-- add long name partition
CREATE TABLE distributed_partitioned_table_p2_longlonglonglonglonglonglong_name PARTITION OF distributed_partitioned_table 
FOR VALUES FROM (100) TO (200);

-- distribute
SELECT create_distributed_table('distributed_partitioned_table', 'id');

-- Add an exclusion constraint with a name to the distributed partitioned table
-- this seems to deadlock sometimes for the long name partition
SET client_min_messages TO DEBUG1;
ALTER TABLE distributed_partitioned_table ADD CONSTRAINT dist_exclude_named EXCLUDE USING btree (id WITH =, partition_col WITH =);
DEBUG:  ALTER TABLE / ADD EXCLUDE will create implicit index "dist_exclude_named" for table "distributed_partitioned_table"
DEBUG:  ALTER TABLE / ADD EXCLUDE will create implicit index "distributed_partitioned_table_p1_id_partition_col_excl" for table "distributed_partitioned_table_p1"
DEBUG:  building index "distributed_partitioned_table_p1_id_partition_col_excl" on table "distributed_partitioned_table_p1" serially
DEBUG:  index "distributed_partitioned_table_p1_id_partition_col_excl" can safely use deduplication
DEBUG:  ALTER TABLE / ADD EXCLUDE will create implicit index "distributed_partitioned_table_p2_longlong_id_partition_col_excl" for table "distributed_partitioned_table_p2_longlonglonglonglonglonglong_n"
DEBUG:  building index "distributed_partitioned_table_p2_longlong_id_partition_col_excl" on table "distributed_partitioned_table_p2_longlonglonglonglonglonglong_n" serially
DEBUG:  index "distributed_partitioned_table_p2_longlong_id_partition_col_excl" can safely use deduplication

ERROR:  canceling the transaction since it was involved in a distributed deadlock

I am still investigating this. In some local tests I did, we switch to local execution for many cases, I couldn't understand why we don't switch in this case.
Meanwhile I suggest you also add some long name tests as in https://github.com/citusdata/citus/blob/main/src/test/regress/sql/multi_alter_table_add_constraints_without_name.sql#L489-L490
Also, for you to get familiar with this deadlock issue, we have a number of functions in the codebase starting with SwitchToSequential....

src/test/regress/sql/pg17.sql Outdated Show resolved Hide resolved
@m3hm3t m3hm3t force-pushed the m3hm3t/pg17_support branch from 383e4a2 to f9682a6 Compare December 19, 2024 18:21
@m3hm3t m3hm3t force-pushed the m3hm3t/multi_alter_table_add_const branch 2 times, most recently from df83d21 to 9113cac Compare December 19, 2024 18:22
@m3hm3t
Copy link
Contributor Author

m3hm3t commented Dec 19, 2024

I am still investigating this. In some local tests I did, we switch to local execution for many cases, I couldn't understand why we don't switch in this case. Meanwhile I suggest you also add some long name tests as in https://github.com/citusdata/citus/blob/main/src/test/regress/sql/multi_alter_table_add_constraints_without_name.sql#L489-L490 Also, for you to get familiar with this deadlock issue, we have a number of functions in the codebase starting with SwitchToSequential....

@naisila
I added long name tests. Could you check them? Thanks.

Copy link
Member

@naisila naisila left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to also address the code for the deadlock error I encountered above.

@naisila
Copy link
Member

naisila commented Dec 20, 2024

It seems like this is a general constraint issue, and not related to the EXCLUDE constraint, so we can merge only tests in this PR.

-- this also fails
ALTER TABLE distributed_partitioned_table ADD CONSTRAINT dist_unique_named UNIQUE(id, partition_col);

ERROR:  canceling the transaction since it was involved in a distributed deadlock

another_col int,
partition_col timestamp
) PARTITION BY RANGE (partition_col);
ERROR: schema "at_addconstnoname" does not exist
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test output is full of these errors of non-existing schema

@naisila
Copy link
Member

naisila commented Dec 23, 2024

No need to worry about the deadlock issue, it is not related to only EXCLUDE constraint, but all constraints #7799

So, only updating the test output in this PR is enough

@m3hm3t m3hm3t force-pushed the m3hm3t/pg17_support branch from f9682a6 to 08618fc Compare December 23, 2024 10:40
@m3hm3t m3hm3t force-pushed the m3hm3t/multi_alter_table_add_const branch 2 times, most recently from 8ab00e6 to c05378c Compare December 23, 2024 10:54
Copy link
Member

@naisila naisila left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@m3hm3t m3hm3t changed the base branch from m3hm3t/pg17_support to release-13.0 December 23, 2024 12:02
update

update

.

move the tests

update

update

update

style

update

update

update

review update

update

Update src/test/regress/sql/pg17.sql

Co-authored-by: Naisila Puka <[email protected]>

comment update

review update

fix whitespace
@m3hm3t m3hm3t force-pushed the m3hm3t/multi_alter_table_add_const branch from c458006 to ee56260 Compare December 23, 2024 12:04
@m3hm3t m3hm3t merged commit 351b1ca into release-13.0 Dec 23, 2024
121 checks passed
@m3hm3t m3hm3t deleted the m3hm3t/multi_alter_table_add_const branch December 23, 2024 12:24
naisila added a commit that referenced this pull request Dec 24, 2024
This is the final commit that adds
PG17 compatibility with Citus's current capabilities.

You can use Citus community, release-13.0 branch, with PG17.1.

---------

Specifically, this commit:

- Enables PG17 in the configure script.

- Adds PG17 tests to CI using test images that have 17.1

- Fixes an upgrade test: see below for details
In `citus_prepare_upgrade()`, don't drop any_value when upgrading from
PG16+, because PG16+ has its own any_value function. Attempting to do so
results in the error seen in [pg16-pg17
upgrade](https://github.com/citusdata/citus/actions/runs/11768444117/job/32778340003?pr=7661):
```
ERROR:  cannot drop function any_value(anyelement) because it is required by the database system
CONTEXT:  SQL statement "DROP AGGREGATE IF EXISTS pg_catalog.any_value(anyelement)"
```
When 16 becomes the minimum supported Postgres version, the drop
statements can be removed.

---------

Several PG17 Compatibility commits have been merged before this final one.
All these subtasks are done #7653

See the list below:

Compilation PR: #7699
Ruleutils PR: #7725
Sister PR for tests: citusdata/the-process#159

Helpful smaller PRs:
- #7714
- #7726
- #7731
- #7732
- #7733
- #7738
- #7745
- #7747
- #7748
- #7749
- #7752
- #7755
- #7757
- #7759
- #7760
- #7761
- #7762
- #7765
- #7766
- #7768
- #7769
- #7771
- #7774
- #7776
- #7780
- #7781
- #7785
- #7788
- #7793
- #7796

---------

Co-authored-by: Colm <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants