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(mssql): columnInfo() now works with case-sensitive database [fixes #4573] #4633

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 2 additions & 1 deletion lib/dialects/mssql/query/mssql-querycompiler.js
Expand Up @@ -429,7 +429,8 @@ class QueryCompiler_MSSQL extends QueryCompiler {
schema = this.client.customWrapIdentifier(schema, identity);
}

let sql = `select [COLUMN_NAME], [COLUMN_DEFAULT], [DATA_TYPE], [CHARACTER_MAXIMUM_LENGTH], [IS_NULLABLE] from information_schema.columns where table_name = ? and table_catalog = ?`;
// GOTCHA: INFORMATION_SCHEMA.COLUMNS must be capitalized to work when the database has a case-sensitive collation. [#4573]
let sql = `select [COLUMN_NAME], [COLUMN_DEFAULT], [DATA_TYPE], [CHARACTER_MAXIMUM_LENGTH], [IS_NULLABLE] from INFORMATION_SCHEMA.COLUMNS where table_name = ? and table_catalog = ?`;
const bindings = [table, this.client.database()];

if (schema) {
Expand Down
6 changes: 3 additions & 3 deletions test/integration/query/additional.js
Expand Up @@ -300,7 +300,7 @@ module.exports = function (knex) {
[drivers.SQLite]: "SELECT name FROM sqlite_master WHERE type='table';",
[drivers.Oracle]: 'select TABLE_NAME from USER_TABLES',
[drivers.MsSQL]:
"SELECT table_name FROM information_schema.tables WHERE table_schema='dbo'",
"SELECT table_name FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='dbo'",
};
return knex
.raw(tables[knex.client.driverName])
Expand Down Expand Up @@ -417,7 +417,7 @@ module.exports = function (knex) {
);
tester(
'mssql',
"select [COLUMN_NAME], [COLUMN_DEFAULT], [DATA_TYPE], [CHARACTER_MAXIMUM_LENGTH], [IS_NULLABLE] from information_schema.columns where table_name = ? and table_catalog = ? and table_schema = 'dbo'",
"select [COLUMN_NAME], [COLUMN_DEFAULT], [DATA_TYPE], [CHARACTER_MAXIMUM_LENGTH], [IS_NULLABLE] from INFORMATION_SCHEMA.COLUMNS where table_name = ? and table_catalog = ? and table_schema = 'dbo'",
['datatype_test', 'knex_test'],
{
enum_value: {
Expand Down Expand Up @@ -493,7 +493,7 @@ module.exports = function (knex) {
);
tester(
'mssql',
"select [COLUMN_NAME], [COLUMN_DEFAULT], [DATA_TYPE], [CHARACTER_MAXIMUM_LENGTH], [IS_NULLABLE] from information_schema.columns where table_name = ? and table_catalog = ? and table_schema = 'dbo'",
"select [COLUMN_NAME], [COLUMN_DEFAULT], [DATA_TYPE], [CHARACTER_MAXIMUM_LENGTH], [IS_NULLABLE] from INFORMATION_SCHEMA.COLUMNS where table_name = ? and table_catalog = ? and table_schema = 'dbo'",
null,
{
defaultValue: null,
Expand Down
43 changes: 43 additions & 0 deletions test/integration/schema/index.js
Expand Up @@ -1463,6 +1463,49 @@ module.exports = (knex) => {
.then(() =>
knex.schema.withSchema(testSchemaName).dropTableIfExists('test2')
));

describe('case-sensitive collation support', () => {
let k;
const databaseName = 'knex_test_CS_AS_SC';
const collation = 'Latin1_General_100_CS_AS_SC';
const tableName = 'Test';
before(async () => {
await knex.schema.raw(
`IF EXISTS(SELECT name FROM sys.databases WHERE name = :databaseName) DROP DATABASE :databaseName:; CREATE DATABASE :databaseName: COLLATE ${collation}`,
{ databaseName }
);

const Knex = require('../../../knex');
const config = require('../../knexfile');
k = Knex({
client: 'mssql',
connection: {
...config.mssql.connection,
database: databaseName,
},
});

// Verify configuration is using the correct database.
const [{ name }] = await k.raw('SELECT DB_NAME() AS name');
expect(name).to.equal(databaseName);

await k.schema.createTable(tableName, function () {
this.increments();
});
});
after(async () => {
await k.schema.dropTable(tableName);
await k.destroy();
await knex.schema.raw(
`IF EXISTS(SELECT name FROM sys.databases WHERE name = :databaseName) DROP DATABASE :databaseName:`,
{ databaseName }
);
});
it('should get columnInfo from a case-sensitive database', async () => {
const info = await k(tableName).columnInfo();
expect(info).not.to.equal(undefined);
});
});
});
});

Expand Down