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

Inconsistent Application of Identifier Formatting in Migration Commands for Oracle Dialect Result in Migration Failures #5801

Open
Kytech opened this issue Feb 14, 2024 · 0 comments · May be fixed by #6058

Comments

@Kytech
Copy link
Contributor

Kytech commented Feb 14, 2024

Environment

Knex version: 3.1.0
Database + version: Oracle 19c
OS: Windows 11 and Linux (Ubuntu and Alpine Distros)

Bug

  1. Explain what kind of behavior you are getting and what you think it should do

Knex encounters issues in Oracle database when certain migration commands, particularly rename and drop commands, are executed when a custom wrapIdentifier option is specified in the knexfile - particularly when this option is used to normalize casing and formatting of database objects (ex. camelCase to UPPER_SNAKE_CASE)

  1. Error message

Error indicating that the table/trigger/sequence/etc. to drop or rename does not exist, even when the exact same string used to create the database object is provided as the target for a delete or rename operation.

  1. Reduced test code
const knex = require('knex')
const { snakecase, uppercase } = require('stringcase')

const db = knex({
  client: 'oracledb',
  connection: {
    host: '<DB HOSTNAME>',
    database: '<DATABASE>',
    user: '<USER>',
    password: '<PASSWORD>',
  },
  wrapIdentifier: (value, origImpl, queryContext) => origImpl(uppercase(snakecase(value))),
})

await db.scema.createTable('exampleTable', (table) => { 
    // Resultant table name is "EXAMPLE_TABLE" and is created sucessfully
    // auto-generated sequence for this table is named "example_table_seq"
    // table builder statements
});

await db.schema.renameTable('exampleTable', 'newTable');
// Fails with error from Oracle stating that table "exampleTable" does not exist - Name was not formatted

await db.schema.dropTableIfExists('exampleTable');
// drops "EXAMPLE_TABLE", attempts to drop "EXAMPLE_TABLE_SEQ"
// Oracle throws an error because "EXAMPLE_TABLE_SEQ" does not exist

Proposed Fix and Further Explanation

I have opened a PR with a fix to the issue, #6058 though this PR has not yet been reviewed by the maintainers.

Knex quotes database object names in the queries passed to oracle, which results in these objects preserving the case in their names, where tables would otherwise be treated in a case-insensitive way if unquoted, which explains the issue with example_table_seq illustrated above, even though all the underscore characters line up.

For a more in-depth explanation of the cause of the issue, please see the referenced PR, which also details my proposed fix to the issue.

@atiertant

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