Skip to content

Commit

Permalink
feat(snowflake-driver): Add ignore case statements flag (#9131)
Browse files Browse the repository at this point in the history
* 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]>
  • Loading branch information
KSDaemon and mike-taylor-nomihealth authored Jan 24, 2025
1 parent 5a540db commit db3b0fd
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 0 deletions.
6 changes: 6 additions & 0 deletions docs/pages/product/configuration/data-sources/snowflake.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ redirect_from:
- [The region][snowflake-docs-regions] for the [Snowflake][snowflake] warehouse
- The username/password for the [Snowflake][snowflake] account

## Snowflake quoted identifiers

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

## Setup

<WarningBox>
Expand Down
33 changes: 33 additions & 0 deletions packages/cubejs-backend-shared/src/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1529,6 +1529,39 @@ const variables: Record<string, (...args: any) => any> = {
]
),

/**
* Snowflake case sensitivity for identifiers (like database columns).
*/
snowflakeQuotedIdentIgnoreCase: ({
dataSource
}: {
dataSource: string,
}) => {
const val = process.env[
keyByDataSource(
'CUBEJS_DB_SNOWFLAKE_QUOTED_IDENTIFIERS_IGNORE_CASE',
dataSource,
)
];
if (val) {
if (val.toLocaleLowerCase() === 'true') {
return true;
} else if (val.toLowerCase() === 'false') {
return false;
} else {
throw new TypeError(
`The ${
keyByDataSource(
'CUBEJS_DB_SNOWFLAKE_QUOTED_IDENTIFIERS_IGNORE_CASE',
dataSource,
)
} must be either 'true' or 'false'.`
);
}
} else {
return false;
}
},
/** ****************************************************************
* Presto Driver *
***************************************************************** */
Expand Down
8 changes: 8 additions & 0 deletions packages/cubejs-snowflake-driver/src/SnowflakeDriver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ interface SnowflakeDriverOptions {
resultPrefetch?: number,
exportBucket?: SnowflakeDriverExportBucket,
executionTimeout?: number,
identIgnoreCase?: boolean,
application: string,
readOnly?: boolean,

Expand Down Expand Up @@ -213,6 +214,7 @@ export class SnowflakeDriver extends BaseDriver implements DriverInterface {
'CUBEJS_DB_SNOWFLAKE_PRIVATE_KEY_PATH',
'CUBEJS_DB_SNOWFLAKE_PRIVATE_KEY_PASS',
'CUBEJS_DB_SNOWFLAKE_OAUTH_TOKEN_PATH',
'CUBEJS_DB_SNOWFLAKE_QUOTED_IDENTIFIERS_IGNORE_CASE',
];
}

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

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

0 comments on commit db3b0fd

Please sign in to comment.