diff --git a/docs/pages/product/configuration/data-sources/snowflake.mdx b/docs/pages/product/configuration/data-sources/snowflake.mdx index 47c716af545d5..d0156397ccb36 100644 --- a/docs/pages/product/configuration/data-sources/snowflake.mdx +++ b/docs/pages/product/configuration/data-sources/snowflake.mdx @@ -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 diff --git a/packages/cubejs-backend-shared/src/env.ts b/packages/cubejs-backend-shared/src/env.ts index a8f5563555bb9..3755afa0b4926 100644 --- a/packages/cubejs-backend-shared/src/env.ts +++ b/packages/cubejs-backend-shared/src/env.ts @@ -1478,6 +1478,39 @@ const variables: Record 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 true; + } + }, /** **************************************************************** * Presto Driver * ***************************************************************** */ diff --git a/packages/cubejs-snowflake-driver/src/SnowflakeDriver.ts b/packages/cubejs-snowflake-driver/src/SnowflakeDriver.ts index ccf19191fa980..c362028934530 100644 --- a/packages/cubejs-snowflake-driver/src/SnowflakeDriver.ts +++ b/packages/cubejs-snowflake-driver/src/SnowflakeDriver.ts @@ -173,6 +173,7 @@ interface SnowflakeDriverOptions { resultPrefetch?: number, exportBucket?: SnowflakeDriverExportBucket, executionTimeout?: number, + caseSensitiveIdentifiers?: boolean, application: string, readOnly?: boolean, @@ -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', ]; } @@ -279,6 +281,7 @@ export class SnowflakeDriver extends BaseDriver implements DriverInterface { exportBucket: this.getExportBucket(dataSource), resultPrefetch: 1, executionTimeout: getEnv('dbQueryTimeout', { dataSource }), + ignoreCase: getEnv('snowflakeQuotedIdentIgnoreCase', { dataSource }), exportBucketCsvEscapeSymbol: getEnv('dbExportBucketCsvEscapeSymbol', { dataSource }), application: 'CubeDev_Cube', ...config @@ -450,7 +453,12 @@ 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 false explicitly since the default assumption + // is that casing matters + if (!this.ignoreCase) { + await this.execute(connection, 'ALTER SESSION SET QUOTED_IDENTIFIERS_IGNORE_CASE = FALSE', [], false); + } return connection; } catch (e) { this.connection = null;