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: Incorrect SQL statements when creating a table with a dot in its name #1871

Merged
merged 8 commits into from
Oct 11, 2023

Conversation

joc-a
Copy link
Collaborator

@joc-a joc-a commented Sep 27, 2023

When providing a table with a dot in its name, it's necessary to quote it so that the part before the dot is not treated as a schema name. If it is treated like a schema name, it fails to find that schema and throws an error. Adding quotes previously caused the name to be broken apart. The fix is to only break the name apart if is NOT already quoted.

Old behaviour:
Provided table name = "SomeNamespace.SomeTable"
Name in SQL statements = "SomeNamespace"."SomeTable"

New behaviour:
Provided table name = "SomeNamespace.SomeTable"
Name in SQL statements = "SomeNamespace.SomeTable"

Oracle is excluded from this fix because it throws this error:

java.sql.SQLSyntaxErrorException: ORA-04043: object "SOMENAMESPACE.SOMETABLE" does not exist

A problem with casing for table names is suspected with INSERT statements. Needs further investigation.

Post-investigation:
Oracle names are not case-sensitive. They can be made case-sensitive by using quotes around them. The Oracle JDBC driver converts the entire SQL INSERT statement to upper case before extracting the table name from it. This happens regardless of whether there is a dot in the name. Even when a name is quoted, the driver converts it to upper case. Therefore, the INSERT statement fails when it contains a quoted table name because it attempts to insert into a table that does not exist (“SOMENAMESPACE.SOMETABLE” is not found) . It does not fail when the table name is not quoted because the case would not matter in that scenario.

Created an issue to further investigate case sensitivity in the Oracle driver.

@joc-a joc-a force-pushed the joc/fix-error-dot-table-name branch 5 times, most recently from 284e9a7 to 587510a Compare September 28, 2023 15:20
@joc-a joc-a linked an issue Sep 29, 2023 that may be closed by this pull request
@joc-a joc-a force-pushed the joc/fix-error-dot-table-name branch from 8d84140 to c955b7c Compare September 29, 2023 15:49
@joc-a joc-a marked this pull request as ready for review October 2, 2023 08:26
@joc-a joc-a requested review from e5l and bog-walk October 2, 2023 08:27
Copy link
Member

@e5l e5l left a comment

Choose a reason for hiding this comment

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

lgtm

The test failed because fallbackSeqName = null_id_seq. The reason tableName was null is that its declaration in the test was missing get().
@joc-a joc-a force-pushed the joc/fix-error-dot-table-name branch from c955b7c to 70e7548 Compare October 9, 2023 21:11
tester.exists() was returning false because of issues with processing the quoted table name that led to a mismatch
@joc-a joc-a force-pushed the joc/fix-error-dot-table-name branch from 70e7548 to 4227ddf Compare October 9, 2023 21:42
In `String.metadataMatchesTable`, we should not use `table.tableNameWithoutSchemeSanitized` because "sanitization" in this case should be dialect-aware (aka we should be removing only what is considered a valid quote string in MySQL, which is the backtick). This means that if a table has double quotes (") in MySQL, they should not be removed when we compare it with the table name returned from the metadata, because the metadata (DatabaseMetaData.getTables method) returns it WITH the double quotes. If a name is quoted with backticks (`) instead, the metadata returns it WITHOUT backticks.

For example:
For table name "\"IdentifierTable\"", metadata returns -> "testdb."IdentifierTable""
For table name "`SomeNamespace.SomeTable`", metadata returns -> "testdb.SomeNamespace.SomeTable"
@@ -444,7 +445,7 @@ class CreateTableTests : DatabaseTestsBase() {
fun createTableWithExplicitForeignKeyName4() {
val fkName = "MyForeignKey4"
val parent = object : LongIdTable() {
override val tableName = "parent4"
override val tableName get() = "parent4"
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

tableName was "null" before adding get()

@joc-a joc-a requested review from bog-walk and e5l October 10, 2023 14:38
@joc-a joc-a merged commit 3656269 into main Oct 11, 2023
5 checks passed
@joc-a joc-a deleted the joc/fix-error-dot-table-name branch October 11, 2023 11:33
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.

Having dot symbols within table names produces incorrect SQL statements
3 participants