Skip to content

Conversation

kneth
Copy link
Contributor

@kneth kneth commented Feb 16, 2025

All Submissions:

  • Have you followed the guidelines in our Contributing document?
  • Have you checked to ensure there aren't other open Pull Requests for the same update/change?

Postgres compatible databases like https://github.com/crate/crate can use PG JDBC as driver. Often the PG JDBC driver is used by a tool or integration (JetBrains DataGrip to name one). As CrateDB isn't fully PG compatible, this patch will make life a bit easier for our users. The issue has been reported as crate/crate#17393.

@davecramer
Copy link
Member

I think I'd rather change all of the code referring to current_database to not use SQL at all. The connection knows the database. I don't thin it is necessary to use this function

@jankohlmann
Copy link

@davecramer are you thinking about reverting #3390 ?

@davecramer
Copy link
Member

Probably not reverting it but changing the way it is done.
In the one you are changing you could simply do select 'db' as current_database where db is the database in the connection URL, or whatever is returned in the startup parameters

@vlsi
Copy link
Member

vlsi commented Feb 19, 2025

Frankly, I see no issues leaving it as current_database() as current_database. I would probably prefer this one.

It would make query easier to understand and test. It would naturally avoid "concatenate string sql on every execution" as well.
WDYT?

Comment on lines 83 to 91
void getColumnsForSchema() throws Exception {
DatabaseMetaData dbmd = conn.getMetaData();

ResultSet rs = dbmd.getColumns(null, "%", "decimaltest", "%");
assertTrue(rs.next());
assertEquals("a", rs.getString("COLUMN_NAME"));
assertEquals(0, rs.getInt("DECIMAL_DIGITS"));
Copy link
Member

Choose a reason for hiding this comment

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

Can we add a verification for the current_database column name?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I have added it to the test. Notice that getColumns reports the current database in the TABLE_CAT column: https://github.com/pgjdbc/pgjdbc/blob/master/pgjdbc/src/main/java/org/postgresql/jdbc/PgDatabaseMetaData.java#L1671

Copy link
Member

Choose a reason for hiding this comment

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

I thought current_database was returned via client=facing APIs, however, now I see it is used only in the internals.

However, it looks like the specific usage could be completely removed from SQL and we could use something like

byte[] catalogName = /* rs.getBytes("current_database") */; // replace with a known literal
...
tuple[0] = catalogName;

Copy link
Member

Choose a reason for hiding this comment

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

Yes, I had this in mind as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Latest commit is removing current_database() where possible and use either the argument or use the connection's catalog name.

@davecramer
Copy link
Member

Frankly, I see no issues leaving it as current_database() as current_database. I would probably prefer this one.

It would make query easier to understand and test. It would naturally avoid "concatenate string sql on every execution" as well. WDYT?

If #3528 fixes all of the performance regressions then we can leave this one as is.

@kneth
Copy link
Contributor Author

kneth commented Feb 19, 2025

Thank you for taken the time to review my PR. I have expanded the test as outlined in #3526 (review)

@vlsi
Copy link
Member

vlsi commented Feb 19, 2025

, or whatever is returned in the startup parameters

It looks like the startup parameters do not return the database name.

At the same time, there's current_catalog function and information_schema.information_schema_catalog_name table returning catalog_name which is different from current_database.

So it looks like we should use those functions rather than current_database() if we want to treat catalogs somehow.
Is there a reason to ignore current_catalog PostgreSQL function?

@davecramer
Copy link
Member

, or whatever is returned in the startup parameters

It looks like the startup parameters do not return the database name.

Interesting, somehow I though it was.

At the same time, there's current_catalog function and information_schema.information_schema_catalog_name table returning catalog_name which is different from current_database.

So it looks like we should use those functions rather than current_database() if we want to treat catalogs somehow. Is there a reason to ignore current_catalog PostgreSQL function?

Only if it creates a performance regression.

@vlsi
Copy link
Member

vlsi commented Feb 21, 2025

Ok, PostgreSQL has a regression test that ensures current_database() should return the same value as current_catalog: https://github.com/postgres/postgres/blob/7d6d2c4bbd730bd9af191d46d4fb01d5f5c30cf1/src/test/regress/expected/expressions.out#L91-L94

At the same time, it looks like current_catalog was added for the SQL standard compatibility somewhere around 8.4.

So it is fine to keep using current_database().

@@ -57,6 +57,13 @@ public PgDatabaseMetaData(PgConnection conn) {
private int nameDataLength; // length for name datatype
private int indexMaxKeys; // maximum number of keys in an index.

private byte[] getCatalogName(@Nullable String catalog) throws SQLException {
if (catalog == null) {
return connection.getCatalog().getBytes();
Copy link
Member

Choose a reason for hiding this comment

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

We should use connection's encoding here. Otherwise there's a risk the bytes will be decoded differently

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good point - I have added the encoded

@davecramer
Copy link
Member

Ok, PostgreSQL has a regression test that ensures current_database() should return the same value as current_catalog: https://github.com/postgres/postgres/blob/7d6d2c4bbd730bd9af191d46d4fb01d5f5c30cf1/src/test/regress/expected/expressions.out#L91-L94

At the same time, it looks like current_catalog was added for the SQL standard compatibility somewhere around 8.4.

So it is fine to keep using current_database().

Assuming no performance regression

@kneth
Copy link
Contributor Author

kneth commented Feb 27, 2025

@davecramer @vlsi Do you need any changes before you can merge my PR?

When merging, you should probably merge #3528 too so the performance is improved.

@kneth kneth force-pushed the kneth/set-column-name-explicitely branch from 2fc2e79 to ab8e2fb Compare April 22, 2025 14:34
@kneth kneth force-pushed the kneth/set-column-name-explicitely branch from ab8e2fb to de7a693 Compare April 22, 2025 14:49
@kneth kneth force-pushed the kneth/set-column-name-explicitely branch from 798d192 to 4766e04 Compare April 23, 2025 09:47
@kneth kneth force-pushed the kneth/set-column-name-explicitely branch from 88373e1 to ceeca4d Compare April 23, 2025 11:04
@kneth
Copy link
Contributor Author

kneth commented Apr 23, 2025

@davecramer @vlsi I have rebased my branch on master, and tests pass locally (gradlew test). Is it possible to advance the PR to a state where it can be merged?

}
return catalog.getBytes(Charset.defaultCharset());
}

Copy link
Member

Choose a reason for hiding this comment

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

From what I can tell we check to see if the catalog is null before calling this function.
Moot point: If we get a SQLException we should just throw it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

There are many checks like the following in the code:

if (catalog != null) {
  sql += " AND current_database() = " + escapeQuotes(catalog);
}

They will not exclude null. Likewise, the additional checks in #3588 don't exclude catalog to be null afaik.

Removing the try/catch makes sense as errors can bubble up to the application.

Copy link
Member

Choose a reason for hiding this comment

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

In retrospect I should have removed all of those in #3588. By the time we get to the query we know that if the catalog is not null then it is the same as current_database() If you want to make those changes I'd appreciate it. Otherwise I'll make them which might make your's harder to rebase.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'll take a look at it!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@davecramer @vlsi I gave it a shot, and I took the liberty to modify the condition as suggested in #3588 (comment)

@davecramer
Copy link
Member

There's still a considerable amount of whitespace changes in this PR. Mostly around ( and beginning lines.

@kneth kneth force-pushed the kneth/set-column-name-explicitely branch from 7764e57 to 8e6f12c Compare April 24, 2025 11:25
@kneth
Copy link
Contributor Author

kneth commented Apr 24, 2025

@davecramer says

[...] whitespace changes [...]

I have restored the white spaces

@kneth kneth force-pushed the kneth/set-column-name-explicitely branch from 40414fe to 5f5eb0f Compare April 24, 2025 15:50
@davecramer
Copy link
Member

Yes, checkstyle seems a little specific at times, but one more fix and we should be good to go

@kneth
Copy link
Contributor Author

kneth commented Apr 25, 2025

@davecramer

one more fix

... and done 😄

@davecramer davecramer merged commit 1e0c88d into pgjdbc:master Apr 25, 2025
15 of 17 checks passed
@kneth
Copy link
Contributor Author

kneth commented Apr 25, 2025

Thank you for merging

@davecramer
Copy link
Member

Thank you for merging

Thank you for persisting through this process

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants