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

fix(pgcdc): fix uppercase-identifier of pgcdc #17754

Merged
merged 9 commits into from
Jul 23, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions ci/scripts/e2e-source-test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,23 @@ export PGHOST=db PGPORT=5432 PGUSER=postgres PGPASSWORD=postgres PGDATABASE=cdc_
createdb
psql < ./e2e_test/source/cdc/postgres_cdc.sql

# to test upper case database
psql -c "CREATE DATABASE \"UpperDb\";"

export PGHOST=db PGPORT=5432 PGUSER=postgres PGPASSWORD=postgres PGDATABASE=UpperDb
psql -d UpperDb -c "
CREATE SCHEMA \"UpperSchema\";
CREATE TABLE \"UpperSchema\".\"Orders\" (
id int PRIMARY KEY,
name varchar
);
INSERT INTO \"UpperSchema\".\"Orders\" VALUES (1, 'happy');
KeXiangWang marked this conversation as resolved.
Show resolved Hide resolved
"

risedev slt './e2e_test/source/cdc/cdc.upper_case.postgres.slt'

export PGHOST=db PGPORT=5432 PGUSER=postgres PGPASSWORD=postgres PGDATABASE=cdc_test

echo "--- starting risingwave cluster"
RUST_LOG="debug,risingwave_stream=info,risingwave_batch=info,risingwave_storage=info" \
risedev ci-start ci-1cn-1fe-with-recovery
Expand Down
44 changes: 44 additions & 0 deletions e2e_test/source/cdc/cdc.upper_case.postgres.slt
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# For upper case UpperDb
statement ok
create source pg_source_upper with (
connector = 'postgres-cdc',
hostname = '${PGHOST:localhost}',
port = '${PGPORT:5432}',
username = '${PGUSER:$USER}',
password = '${PGPASSWORD:}',
database.name = '${PGDATABASE:postgres}',
slot.name = 'pg_slot_upper'
);

statement ok
CREATE TABLE orders_shared (
id int PRIMARY KEY,
name varchar,
) FROM pg_source_upper TABLE 'UpperSchema.Orders';

query II
select * from orders_shared order by id;
----
1 happy

statement ok
create table orders (
id int,
name varchar,
PRIMARY KEY (id)
) with (
connector = 'postgres-cdc',
hostname = '${PGHOST:localhost}',
port = '${PGPORT:5432}',
username = '${PGUSER:$USER}',
password = '${PGPASSWORD:}',
database.name = '${PGDATABASE:postgres}',
schema.name = 'UpperSchema',
table.name = 'Order',
slot.name = 'orders'
);

query II
select * from orders order by id;
----
1 happy
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ private void validateTableSchema() throws SQLException {
// check primary key
// reference: https://wiki.postgresql.org/wiki/Retrieve_primary_key_columns
try (var stmt = jdbcConnection.prepareStatement(ValidatorUtils.getSql("postgres.pk"))) {
stmt.setString(1, this.schemaName + "." + this.tableName);
Copy link
Contributor

Choose a reason for hiding this comment

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

Why not just quote the object name?
String.format("\"%s\".\"%s\"", this.schemaName, this.tableName)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Can be another choice. I noticed that other sql statements use schemaName and tableName, so I think we should keep them consistent. Do you prefer "\"%s\".\"%s\""?

Copy link
Contributor

Choose a reason for hiding this comment

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

The change to the validate sql needs to join two more system tables, I think it can be avoided.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

updated.

Copy link
Contributor

@xiangjinwu xiangjinwu Jul 19, 2024

Choose a reason for hiding this comment

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

Slightly prefer to keep consistent with other places, unless the cost of join is high.

Strictly speaking the manual quoting above is wrong, but I do believe no one would challenge this in practice:

test=# create table "my_test""table" ("Foo" int); -- two quotes required
CREATE TABLE
test=# select relname, quote_ident(relname) from pg_class where relname ^@ 'my_te';
    relname    |   quote_ident    
---------------+------------------
 my_test"table | "my_test""table"
(1 row)

(pgdoc)

Embedded quotes are properly doubled

stmt.setString(1, String.format("\"%s\".\"%s\"", this.schemaName, this.tableName));
var res = stmt.executeQuery();
var pkFields = new HashSet<String>();
while (res.next()) {
Expand Down Expand Up @@ -521,7 +521,8 @@ protected void alterPublicationIfNeeded() throws SQLException {

String alterPublicationSql =
String.format(
"ALTER PUBLICATION %s ADD TABLE %s", pubName, schemaName + "." + tableName);
"ALTER PUBLICATION %s ADD TABLE %s",
pubName, String.format("\"%s\".\"%s\"", this.schemaName, this.tableName));
try (var stmt = jdbcConnection.createStatement()) {
LOG.info("Altered publication with statement: {}", alterPublicationSql);
stmt.execute(alterPublicationSql);
Expand Down
Loading