-
Notifications
You must be signed in to change notification settings - Fork 5.5k
Add quotes to column names and disable UpperCase conversion in BaseJdbcClient #25628
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
Conversation
e578541 to
aaf469c
Compare
|
@agrawalreetika imported this issue as lakehouse/presto #25628 |
BryanCutler
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @agrawalreetika this looks ok, but I'm wondering since storesUpperCaseIdentifiers only applies to unquoted identifiers, and presto wraps all identifiers, then should we even be checking storesUpperCaseIdentifiers at all?
Thanks for your reveiw @BryanCutler . I am very sure, why is it kept in there. |
It does sounds like it is already disabled by quoting the identifiers, but I'm not too sure, so there should be a larger discussion to make sure all cases are covered. Another thing I don't quite understand is if the db returns true for |
|
My understanding here is that when And as |
But you say Presto will always wrap with a delimiter, so what cases would this be needed?
It is a change of behavior because if It seems ok to me, if all identifiers are quoted now then the result of |
| String sql = format( | ||
| "ALTER TABLE %s RENAME TO %s", | ||
| quoted(catalogName, oldTable.getSchemaName(), oldTableName), | ||
| quoted(newTableName)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
are the changes here covered in other case-sensitive related tests?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oracle tests are diabled in Presto as of now, @namya28 is working on enabling it. I can add case-senetive related test class once its enabled. I tested this scenario with my oracle instance for now.
| DatabaseMetaData metadata = connection.getMetaData(); | ||
| String newTableName = newTable.getTableName(); | ||
| String oldTableName = oldTable.getTableName(); | ||
| if (metadata.storesUpperCaseIdentifiers() && !caseSensitiveNameMatchingEnabled) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Was the storesUpperCaseIdentifiers just missing for Oracle before or is there something different with it? Please add these Oracle changes explicitly to the PR description.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OracleClient had renameTable implementation which had storesUpperCaseIdentifiers missing and converting table names to uppercase by default only for rename operation w/o check. So added it here. I can separate out this in different commit
| String remoteSchema = toRemoteSchemaName(session, identity, connection, schemaTableName.getSchemaName()); | ||
| String remoteTable = toRemoteTableName(session, identity, connection, remoteSchema, schemaTableName.getTableName()); | ||
| if (uppercase) { | ||
| if (uppercase && !caseSensitiveNameMatchingEnabled) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why do we have one field for "caseInsensitiveNameMatching" and another "caseSensitiveNameMatchingEnabled". what are they each for?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the review @rschlussel
caseInsensitiveNameMatching was originally introduced to support case-insensitive matching of schema and table names, useful for databases like MySQL. It works by converting identifiers to lowercase before matching, but this can cause issues when databases contain identifiers that differ only by case (e.g., Test vs TEST).
The new caseSensitiveNameMatchingEnabled flag offers broader support for case-sensitive handling of all identifiers — schema, table, and column names — via the normalizeIdentifier API. When enabled, Presto preserves the case of user-supplied identifiers, allowing connectors to apply database-specific case sensitivity rules. When disabled, Presto defaults to lowercasing identifiers. More details about this in here
b265785 to
aae2ea2
Compare
|
@BryanCutler PR is now rebased on the latest master also added a description for all 3 commits. Please take a look. |
aae2ea2 to
63bf0ff
Compare
hantangwangd
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the change, overall looks good to me exception one little question. By the way, is the Oracle test enabled?
| quoted(handle.getCatalogName(), handle.getSchemaName(), handle.getTableName()), | ||
| jdbcColumn.getColumnName(), | ||
| newColumnName); | ||
| quoted(jdbcColumn.getColumnName()), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not very sure, but do we need to execute toUpperCase for jdbcColumn.getColumnName() in the above if clause as well?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@hantangwangd So I tried checking this with Oracle -
The data returned in JdbcTableHandle & JdbcColumnHandle is from an existing DB (Oracle in this case) so its returned as UPPERCASE for the database -

So I think its conversion is not added already in BaseJdbcClient already renameColumn & dropColumn but I think there is no harm adding schema, table and column name conversion inside metadata.storesUpperCaseIdentifiers() check even for these 2 operations as well like its done in addColumn
Lmk what do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And about enabling tests for Oracle, its being done as part of #25762
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, agree with you that adding these conversions into the storesUpperCaseIdentifiers() check clause brings no harm, but just make the code more consistent and easier to understand.
And about enabling tests for Oracle, its being done as part of #25762
Thanks for the message. Got it!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Made changes, please review when you get a chance.
63bf0ff to
5c9d326
Compare
5c9d326 to
2833043
Compare
2833043 to
3d2d888
Compare
hantangwangd
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the fix, LGTM!
Description
Add quotes to column names and disable UpperCase conversion in BaseJdbcClient
This PR has 2 commits -
storesUpperCaseIdentifiers()check for dropColumn, similar to renameColumn & addColumnMotivation and Context
As per the JDBC specification,
storesUpperCaseIdentifiers()only applies to unquoted identifiers. Since Presto already quotes all identifiers when interacting with JDBC connectors, the result of this method should not influence identifier casing whencaseSensitiveNameMatchingEnabledis true.According to the JDBC specification:
This PR updates
BaseJdbcClientto respect the newly introducedcaseSensitiveNameMatchingEnabledflag when interacting with JDBC metadata.Presto wraps all identifiers (schemas, tables, columns) with connector-specific delimiters (e.g., "MyTable"), which makes them case-sensitive as per the SQL standard. However, the existing logic blindly uppercases schema and table names when the JDBC DatabaseMetaData.storesUpperCaseIdentifiers() method returns true.
Impact
Improve BaseJdbcClient for case-sensitive scenarios
Test Plan
Contributor checklist
Release Notes