diff --git a/docs/pages/product/configuration/data-sources/duckdb.mdx b/docs/pages/product/configuration/data-sources/duckdb.mdx index 2f363e61c770f..1478383721718 100644 --- a/docs/pages/product/configuration/data-sources/duckdb.mdx +++ b/docs/pages/product/configuration/data-sources/duckdb.mdx @@ -73,6 +73,7 @@ deployment][ref-demo-deployment] in Cube Cloud. | `CUBEJS_DB_DUCKDB_S3_USE_SSL` | Use SSL for connection | A boolean | ❌ | ❌ | | `CUBEJS_DB_DUCKDB_S3_URL_STYLE` | To choose the S3 URL style(vhost or path) | 'vhost' or 'path' | ❌ | ❌ | | `CUBEJS_DB_DUCKDB_S3_SESSION_TOKEN` | The token for the S3 session | A valid Session Token | ❌ | ✅ | +| `CUBEJS_DB_DUCKDB_EXTENSIONS` | A comma-separated list of DuckDB extensions to install and load | A comma-separated list of DuckDB extensions | ❌ | ✅ | ## Pre-Aggregation Feature Support diff --git a/docs/pages/reference/configuration/environment-variables.mdx b/docs/pages/reference/configuration/environment-variables.mdx index dba5d5f3074f7..ef79af22377a0 100644 --- a/docs/pages/reference/configuration/environment-variables.mdx +++ b/docs/pages/reference/configuration/environment-variables.mdx @@ -315,6 +315,14 @@ The S3 session token. | -------------------------------------- | ---------------------- | --------------------- | | A valid S3 session token | N/A | N/A | +## `CUBEJS_DB_DUCKDB_EXTENSIONS` + +A comma-separated list of DuckDB extensions to install and load. + +| Possible Values | Default in Development | Default in Production | +| ------------------------------------------- | ---------------------- | --------------------- | +| A comma-separated list of DuckDB extensions | N/A | N/A | + ## `CUBEJS_DB_ELASTIC_APIKEY_ID` The [ID of the API key from elastic.co][elastic-docs-api-keys]. Required when diff --git a/packages/cubejs-backend-shared/src/env.ts b/packages/cubejs-backend-shared/src/env.ts index 3096fefae7796..3d5a2c0e2e81c 100644 --- a/packages/cubejs-backend-shared/src/env.ts +++ b/packages/cubejs-backend-shared/src/env.ts @@ -1613,6 +1613,19 @@ const variables: Record any> = { ] ), + duckdbExtensions: ({ + dataSource + }: { + dataSource: string, + }) => { + const extensions = process.env[ + keyByDataSource('CUBEJS_DB_DUCKDB_EXTENSIONS', dataSource) + ]; + if (extensions) { + return extensions.split(',').map(e => e.trim()); + } + return []; + }, /** *************************************************************** * Presto Driver * **************************************************************** */ diff --git a/packages/cubejs-duckdb-driver/src/DuckDBDriver.ts b/packages/cubejs-duckdb-driver/src/DuckDBDriver.ts index 70b5b2cfa58ca..8fd887f29c9e4 100644 --- a/packages/cubejs-duckdb-driver/src/DuckDBDriver.ts +++ b/packages/cubejs-duckdb-driver/src/DuckDBDriver.ts @@ -134,6 +134,36 @@ export class DuckDBDriver extends BaseDriver implements DriverInterface { } } + // Install & load extensions if configured in env variable. + const extensions = getEnv('duckdbExtensions', this.config); + for (const extension of extensions) { + try { + await execAsync(`INSTALL ${extension}`); + } catch (e) { + if (this.logger) { + console.error(`DuckDB - error on installing ${extension}`, { + e + }); + } + + // DuckDB will lose connection_ref on connection on error, this will lead to broken connection object + throw e; + } + + try { + await execAsync(`LOAD ${extension}`); + } catch (e) { + if (this.logger) { + console.error(`DuckDB - error on loading ${extension}`, { + e + }); + } + + // DuckDB will lose connection_ref on connection on error, this will lead to broken connection object + throw e; + } + } + if (this.config.initSql) { try { await execAsync(this.config.initSql);