Skip to content

Commit db3b0fd

Browse files
feat(snowflake-driver): Add ignore case statements flag (#9131)
* Fixing case statements in snowflake driver * Fixes case sensitivity for snowflake to be default and env driven Adds env var for the snowflake driver to enable or disable the case sensitivity and if not set will default to case insensitive * Updating snowflake driver to respect case by default with added override. * fix types for identIgnoreCase in snowflake driver * fix --------- Co-authored-by: Micheal Taylor <[email protected]>
1 parent 5a540db commit db3b0fd

File tree

3 files changed

+47
-0
lines changed

3 files changed

+47
-0
lines changed

docs/pages/product/configuration/data-sources/snowflake.mdx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,12 @@ redirect_from:
1212
- [The region][snowflake-docs-regions] for the [Snowflake][snowflake] warehouse
1313
- The username/password for the [Snowflake][snowflake] account
1414

15+
## Snowflake quoted identifiers
16+
17+
Due to an issue in snowflakes opinion about quoted identifers we set a session value to override
18+
snowflake defaults for users that have set an account value for: QUOTED_IDENTIFIERS_IGNORE_CASE
19+
you can learn more about this here: https://docs.snowflake.com/en/sql-reference/identifiers-syntax#double-quoted-identifiers
20+
1521
## Setup
1622

1723
<WarningBox>

packages/cubejs-backend-shared/src/env.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1529,6 +1529,39 @@ const variables: Record<string, (...args: any) => any> = {
15291529
]
15301530
),
15311531

1532+
/**
1533+
* Snowflake case sensitivity for identifiers (like database columns).
1534+
*/
1535+
snowflakeQuotedIdentIgnoreCase: ({
1536+
dataSource
1537+
}: {
1538+
dataSource: string,
1539+
}) => {
1540+
const val = process.env[
1541+
keyByDataSource(
1542+
'CUBEJS_DB_SNOWFLAKE_QUOTED_IDENTIFIERS_IGNORE_CASE',
1543+
dataSource,
1544+
)
1545+
];
1546+
if (val) {
1547+
if (val.toLocaleLowerCase() === 'true') {
1548+
return true;
1549+
} else if (val.toLowerCase() === 'false') {
1550+
return false;
1551+
} else {
1552+
throw new TypeError(
1553+
`The ${
1554+
keyByDataSource(
1555+
'CUBEJS_DB_SNOWFLAKE_QUOTED_IDENTIFIERS_IGNORE_CASE',
1556+
dataSource,
1557+
)
1558+
} must be either 'true' or 'false'.`
1559+
);
1560+
}
1561+
} else {
1562+
return false;
1563+
}
1564+
},
15321565
/** ****************************************************************
15331566
* Presto Driver *
15341567
***************************************************************** */

packages/cubejs-snowflake-driver/src/SnowflakeDriver.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,7 @@ interface SnowflakeDriverOptions {
173173
resultPrefetch?: number,
174174
exportBucket?: SnowflakeDriverExportBucket,
175175
executionTimeout?: number,
176+
identIgnoreCase?: boolean,
176177
application: string,
177178
readOnly?: boolean,
178179

@@ -213,6 +214,7 @@ export class SnowflakeDriver extends BaseDriver implements DriverInterface {
213214
'CUBEJS_DB_SNOWFLAKE_PRIVATE_KEY_PATH',
214215
'CUBEJS_DB_SNOWFLAKE_PRIVATE_KEY_PASS',
215216
'CUBEJS_DB_SNOWFLAKE_OAUTH_TOKEN_PATH',
217+
'CUBEJS_DB_SNOWFLAKE_QUOTED_IDENTIFIERS_IGNORE_CASE',
216218
];
217219
}
218220

@@ -279,6 +281,7 @@ export class SnowflakeDriver extends BaseDriver implements DriverInterface {
279281
exportBucket: this.getExportBucket(dataSource),
280282
resultPrefetch: 1,
281283
executionTimeout: getEnv('dbQueryTimeout', { dataSource }),
284+
identIgnoreCase: getEnv('snowflakeQuotedIdentIgnoreCase', { dataSource }),
282285
exportBucketCsvEscapeSymbol: getEnv('dbExportBucketCsvEscapeSymbol', { dataSource }),
283286
application: 'CubeDev_Cube',
284287
...config
@@ -451,6 +454,11 @@ export class SnowflakeDriver extends BaseDriver implements DriverInterface {
451454
await this.execute(connection, 'ALTER SESSION SET TIMEZONE = \'UTC\'', [], false);
452455
await this.execute(connection, `ALTER SESSION SET STATEMENT_TIMEOUT_IN_SECONDS = ${this.config.executionTimeout}`, [], false);
453456

457+
// We only want to ignore the case if someone sets the value to true explicitly
458+
// since the default assumption is that casing matters
459+
if (this.config.identIgnoreCase) {
460+
await this.execute(connection, 'ALTER SESSION SET QUOTED_IDENTIFIERS_IGNORE_CASE = TRUE', [], false);
461+
}
454462
return connection;
455463
} catch (e) {
456464
this.connection = null;

0 commit comments

Comments
 (0)