@lightdash/warehouses 2.196.0 → 2.196.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -58,7 +58,6 @@ export declare class DatabricksWarehouseClient extends WarehouseBaseClient<Creat
58
58
  schema: any;
59
59
  table: any;
60
60
  }[]>;
61
- getTables(schema?: string, tags?: Record<string, string>): Promise<WarehouseCatalog>;
62
61
  getFields(tableName: string, schema?: string, database?: string, tags?: Record<string, string>): Promise<WarehouseCatalog>;
63
62
  }
64
63
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"DatabricksWarehouseClient.d.ts","sourceRoot":"","sources":["../../src/warehouseClients/DatabricksWarehouseClient.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"DatabricksWarehouseClient.d.ts","sourceRoot":"","sources":["../../src/warehouseClients/DatabricksWarehouseClient.ts"],"names":[],"mappings":"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"}
@@ -484,11 +484,13 @@ class DatabricksWarehouseClient extends WarehouseBaseClient_1.default {
484
484
  return acc;
485
485
  }, { [catalog]: {} });
486
486
  }
487
+ // Every table_type in Unity Catalog is queryable: managed and external
488
+ // tables, views, materialized views, streaming tables and foreign tables
487
489
  async getAllTables() {
488
490
  const query = `
489
491
  SELECT table_catalog, table_schema, table_name
490
492
  FROM information_schema.tables
491
- WHERE table_type = 'MANAGED'
493
+ WHERE table_schema <> 'information_schema'
492
494
  ORDER BY 1,2,3
493
495
  `;
494
496
  const { rows } = await this.runQuery(query, {}, undefined, undefined);
@@ -498,18 +500,6 @@ class DatabricksWarehouseClient extends WarehouseBaseClient_1.default {
498
500
  table: row.table_name,
499
501
  }));
500
502
  }
501
- async getTables(schema, tags) {
502
- const schemaFilter = schema ? `AND table_schema = ?` : '';
503
- const query = `
504
- SELECT table_catalog, table_schema, table_name
505
- FROM information_schema.tables
506
- WHERE table_type = 'BASE TABLE'
507
- ${schemaFilter}
508
- ORDER BY 1,2,3
509
- `;
510
- const { rows } = await this.runQuery(query, tags, undefined, schema ? [schema] : undefined);
511
- return this.parseWarehouseCatalog(rows, mapFieldType, exports.getDatabricksTimestampDomain);
512
- }
513
503
  async getFields(tableName, schema, database, tags) {
514
504
  const query = `
515
505
  SELECT table_catalog,
@@ -283,3 +283,25 @@ describe('DatabricksSqlBuilder escaping', () => {
283
283
  expect(escapedBlock).toBe('test value');
284
284
  });
285
285
  });
286
+ describe('DatabricksWarehouseClient getAllTables', () => {
287
+ it('lists every relation type in Unity Catalog, not only managed tables', async () => {
288
+ const warehouse = new DatabricksWarehouseClient_1.DatabricksWarehouseClient(DatabricksWarehouseClient_mock_1.credentials);
289
+ const runQuery = vi.spyOn(warehouse, 'runQuery').mockResolvedValueOnce({
290
+ rows: [
291
+ {
292
+ table_catalog: 'main',
293
+ table_schema: 'analytics',
294
+ table_name: 'orders_view',
295
+ },
296
+ ],
297
+ fields: {},
298
+ });
299
+ const tables = await warehouse.getAllTables();
300
+ const [query] = runQuery.mock.calls[0];
301
+ expect(query).not.toContain('table_type');
302
+ expect(query).toContain("table_schema <> 'information_schema'");
303
+ expect(tables).toEqual([
304
+ { database: 'main', schema: 'analytics', table: 'orders_view' },
305
+ ]);
306
+ });
307
+ });
@@ -81,12 +81,22 @@ export declare class PostgresClient<T extends CreatePostgresLikeCredentials> ext
81
81
  schema: string;
82
82
  table: string;
83
83
  }[]): Promise<Record<string, any>>;
84
+ private serverVersion;
85
+ protected getServerVersion(): Promise<string>;
86
+ protected supportsMatviews(): Promise<boolean>;
87
+ protected isRedshift(): Promise<boolean>;
84
88
  getAllTables(): Promise<{
85
89
  database: any;
86
90
  schema: any;
87
91
  table: any;
88
92
  }[]>;
93
+ protected bindFieldsFilters(tableName: string, schema?: string, database?: string): {
94
+ values: string[];
95
+ schemaParam: string | undefined;
96
+ databaseParam: string | undefined;
97
+ };
89
98
  getFields(tableName: string, schema?: string, database?: string, tags?: Record<string, string>): Promise<WarehouseCatalog>;
99
+ protected parsePostgresCatalog(rows: Record<string, AnyType>[]): WarehouseCatalog;
90
100
  parseError(error: pg.DatabaseError, query?: string): WarehouseQueryError;
91
101
  }
92
102
  export declare class PostgresWarehouseClient extends PostgresClient<CreatePostgresCredentials> {
@@ -1 +1 @@
1
- {"version":3,"file":"PostgresWarehouseClient.d.ts","sourceRoot":"","sources":["../../src/warehouseClients/PostgresWarehouseClient.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"PostgresWarehouseClient.d.ts","sourceRoot":"","sources":["../../src/warehouseClients/PostgresWarehouseClient.ts"],"names":[],"mappings":"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"}
@@ -487,13 +487,7 @@ class PostgresClient extends WarehouseBaseClient_1.default {
487
487
  tableFilters.length <= 0) {
488
488
  return {};
489
489
  }
490
- const { rows: pgVersionRows } = await this.runQuery('SELECT version()');
491
- const pgVersionString = pgVersionRows[0]?.version ?? '';
492
- const versionRegex = /PostgreSQL (\d+)\./;
493
- const versionMatch = pgVersionString.match(versionRegex);
494
- const supportsMatviews = versionMatch && versionMatch[1]
495
- ? parseInt(versionMatch[1], 10) >= 12
496
- : false;
490
+ const supportsMatviews = await this.supportsMatviews();
497
491
  const query = `
498
492
  SELECT table_catalog,
499
493
  table_schema,
@@ -513,7 +507,7 @@ class PostgresClient extends WarehouseBaseClient_1.default {
513
507
  n.nspname AS table_schema,
514
508
  c.relname AS table_name,
515
509
  a.attname AS column_name,
516
- pg_catalog.format_type(a.atttypid, a.atttypmod) AS data_type
510
+ pg_catalog.format_type(a.atttypid, NULL) AS data_type
517
511
  FROM pg_catalog.pg_attribute a
518
512
  JOIN pg_catalog.pg_class c ON a.attrelid = c.oid
519
513
  JOIN pg_catalog.pg_namespace n ON c.relnamespace = n.oid
@@ -546,26 +540,56 @@ class PostgresClient extends WarehouseBaseClient_1.default {
546
540
  }, {});
547
541
  return catalog;
548
542
  }
543
+ getServerVersion() {
544
+ this.serverVersion ?? (this.serverVersion = this.runQuery('SELECT version()').then(({ rows }) => String(rows[0]?.version ?? '')));
545
+ return this.serverVersion;
546
+ }
547
+ // Redshift reports itself as PostgreSQL 8.x and has no pg_matviews
548
+ async supportsMatviews() {
549
+ const versionMatch = (await this.getServerVersion()).match(/PostgreSQL (\d+)\./);
550
+ return versionMatch?.[1] ? parseInt(versionMatch[1], 10) >= 12 : false;
551
+ }
552
+ async isRedshift() {
553
+ return (await this.getServerVersion()).includes('Redshift');
554
+ }
555
+ // A session only sees its own database, so no catalog filter is needed
549
556
  async getAllTables() {
550
- const databaseName = this.config.database;
551
- const whereSql = databaseName ? `AND table_catalog = $1` : '';
552
- const filterSystemTables = `AND table_schema NOT IN ('information_schema', 'pg_catalog')`;
557
+ const supportsMatviews = await this.supportsMatviews();
553
558
  const query = `
554
559
  SELECT table_catalog, table_schema, table_name
555
560
  FROM information_schema.tables
556
- WHERE table_type = 'BASE TABLE'
557
- ${whereSql}
558
- ${filterSystemTables}
561
+ WHERE table_type IN ('BASE TABLE', 'VIEW', 'FOREIGN')
562
+ AND table_schema NOT IN ('information_schema', 'pg_catalog')
563
+ ${supportsMatviews
564
+ ? `
565
+ UNION ALL
566
+ SELECT current_database() AS table_catalog,
567
+ schemaname AS table_schema,
568
+ matviewname AS table_name
569
+ FROM pg_catalog.pg_matviews
570
+ WHERE schemaname NOT IN ('information_schema', 'pg_catalog')`
571
+ : ''}
559
572
  ORDER BY 1, 2, 3
560
573
  `;
561
- const { rows } = await this.runQuery(query, {}, undefined, databaseName ? [databaseName] : []);
574
+ const { rows } = await this.runQuery(query);
562
575
  return rows.map((row) => ({
563
576
  database: row.table_catalog,
564
577
  schema: row.table_schema,
565
578
  table: row.table_name,
566
579
  }));
567
580
  }
581
+ // Positional parameters for a field lookup, so optional filters keep their numbering
582
+ bindFieldsFilters(tableName, schema, database) {
583
+ const values = [tableName];
584
+ const schemaParam = schema ? `$${values.push(schema)}` : undefined;
585
+ const databaseParam = database
586
+ ? `$${values.push(database)}`
587
+ : undefined;
588
+ return { values, schemaParam, databaseParam };
589
+ }
568
590
  async getFields(tableName, schema, database, tags) {
591
+ const { values, schemaParam, databaseParam } = this.bindFieldsFilters(tableName, schema, database);
592
+ const supportsMatviews = await this.supportsMatviews();
569
593
  const query = `
570
594
  SELECT table_catalog,
571
595
  table_schema,
@@ -574,17 +598,31 @@ class PostgresClient extends WarehouseBaseClient_1.default {
574
598
  data_type
575
599
  FROM information_schema.columns
576
600
  WHERE table_name = $1
577
- ${schema ? 'AND table_schema = $2' : ''}
578
- ${database ? 'AND table_catalog = $3' : ''}
601
+ ${schemaParam ? `AND table_schema = ${schemaParam}` : ''}
602
+ ${databaseParam ? `AND table_catalog = ${databaseParam}` : ''}
603
+ ${supportsMatviews
604
+ ? `
605
+ UNION ALL
606
+ SELECT current_database() AS table_catalog,
607
+ n.nspname AS table_schema,
608
+ c.relname AS table_name,
609
+ a.attname AS column_name,
610
+ pg_catalog.format_type(a.atttypid, NULL) AS data_type
611
+ FROM pg_catalog.pg_attribute a
612
+ JOIN pg_catalog.pg_class c ON a.attrelid = c.oid
613
+ JOIN pg_catalog.pg_namespace n ON c.relnamespace = n.oid
614
+ WHERE c.relkind = 'm'
615
+ AND c.relname = $1
616
+ ${schemaParam ? `AND n.nspname = ${schemaParam}` : ''}
617
+ ${databaseParam ? `AND current_database() = ${databaseParam}` : ''}
618
+ AND a.attnum > 0
619
+ AND NOT a.attisdropped`
620
+ : ''}
579
621
  `;
580
- const values = [tableName];
581
- if (schema) {
582
- values.push(schema);
583
- }
584
- if (database) {
585
- values.push(database);
586
- }
587
622
  const { rows } = await this.runQuery(query, tags, undefined, values);
623
+ return this.parsePostgresCatalog(rows);
624
+ }
625
+ parsePostgresCatalog(rows) {
588
626
  return this.parseWarehouseCatalog(rows, mapFieldType, exports.getPostgresTimestampDomain);
589
627
  }
590
628
  parseError(error, query = '') {
@@ -171,6 +171,82 @@ describe('PostgresWarehouseClient', () => {
171
171
  'orders',
172
172
  ]);
173
173
  });
174
+ describe('getAllTables', () => {
175
+ it('lists tables, views and materialized views', async () => {
176
+ const warehouse = new PostgresWarehouseClient_1.PostgresWarehouseClient(PostgresWarehouseClient_mock_1.credentials);
177
+ const runQuery = vi
178
+ .spyOn(warehouse, 'runQuery')
179
+ .mockResolvedValueOnce({
180
+ rows: [{ version: 'PostgreSQL 15.4' }],
181
+ fields: {},
182
+ })
183
+ .mockResolvedValueOnce({
184
+ rows: [
185
+ {
186
+ table_catalog: 'warehouse',
187
+ table_schema: 'public',
188
+ table_name: 'orders_view',
189
+ },
190
+ ],
191
+ fields: {},
192
+ });
193
+ const tables = await warehouse.getAllTables();
194
+ const [query] = runQuery.mock.calls[1];
195
+ expect(query).toContain("table_type IN ('BASE TABLE', 'VIEW', 'FOREIGN')");
196
+ expect(query).toContain('FROM pg_catalog.pg_matviews');
197
+ expect(tables).toEqual([
198
+ {
199
+ database: 'warehouse',
200
+ schema: 'public',
201
+ table: 'orders_view',
202
+ },
203
+ ]);
204
+ });
205
+ it('skips pg_matviews on servers that predate it', async () => {
206
+ const warehouse = new PostgresWarehouseClient_1.PostgresWarehouseClient(PostgresWarehouseClient_mock_1.credentials);
207
+ const runQuery = vi
208
+ .spyOn(warehouse, 'runQuery')
209
+ .mockResolvedValueOnce({
210
+ rows: [{ version: 'PostgreSQL 8.0.2' }],
211
+ fields: {},
212
+ })
213
+ .mockResolvedValueOnce({ rows: [], fields: {} });
214
+ await warehouse.getAllTables();
215
+ expect(runQuery.mock.calls[1][0]).not.toContain('pg_matviews');
216
+ });
217
+ });
218
+ describe('getFields', () => {
219
+ it('includes materialized view columns and binds filters in order', async () => {
220
+ const warehouse = new PostgresWarehouseClient_1.PostgresWarehouseClient(PostgresWarehouseClient_mock_1.credentials);
221
+ const runQuery = vi
222
+ .spyOn(warehouse, 'runQuery')
223
+ .mockResolvedValueOnce({
224
+ rows: [{ version: 'PostgreSQL 15.4' }],
225
+ fields: {},
226
+ })
227
+ .mockResolvedValueOnce({
228
+ rows: [
229
+ {
230
+ table_catalog: 'warehouse',
231
+ table_schema: 'public',
232
+ table_name: 'orders_mv',
233
+ column_name: 'amount',
234
+ data_type: 'numeric',
235
+ },
236
+ ],
237
+ fields: {},
238
+ });
239
+ const fields = await warehouse.getFields('orders_mv', undefined, 'warehouse');
240
+ const [query, , , values] = runQuery.mock.calls[1];
241
+ expect(query).toContain("c.relkind = 'm'");
242
+ expect(query).toContain('table_catalog = $2');
243
+ expect(query).not.toContain('$3');
244
+ expect(values).toEqual(['orders_mv', 'warehouse']);
245
+ expect(fields).toEqual({
246
+ warehouse: { public: { orders_mv: { amount: 'number' } } },
247
+ });
248
+ });
249
+ });
174
250
  });
175
251
  describe('PostgresWarehouseClient statement timeout', () => {
176
252
  const mockPoolWithQuery = (queryMock) => {
@@ -1,4 +1,4 @@
1
- import { AnyType, CreateRedshiftCredentials, SupportedDbtAdapter, WarehouseResults, WarehouseTypes } from '@lightdash/common';
1
+ import { AnyType, CreateRedshiftCredentials, SupportedDbtAdapter, WarehouseCatalog, WarehouseResults, WarehouseTypes } from '@lightdash/common';
2
2
  import { PostgresClient, PostgresSqlBuilder } from './PostgresWarehouseClient';
3
3
  export declare class RedshiftSqlBuilder extends PostgresSqlBuilder {
4
4
  type: WarehouseTypes;
@@ -14,6 +14,12 @@ export declare class RedshiftWarehouseClient extends PostgresClient<CreateRedshi
14
14
  tags?: Record<string, string>;
15
15
  timezone?: string;
16
16
  }): Promise<void>;
17
+ getAllTables(): Promise<{
18
+ database: any;
19
+ schema: any;
20
+ table: any;
21
+ }[]>;
22
+ getFields(tableName: string, schema?: string, database?: string, tags?: Record<string, string>): Promise<WarehouseCatalog>;
17
23
  private resolveIamPoolConfig;
18
24
  }
19
25
  //# sourceMappingURL=RedshiftWarehouseClient.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"RedshiftWarehouseClient.d.ts","sourceRoot":"","sources":["../../src/warehouseClients/RedshiftWarehouseClient.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,OAAO,EACP,yBAAyB,EAEzB,mBAAmB,EACnB,gBAAgB,EAChB,cAAc,EACjB,MAAM,mBAAmB,CAAC;AAI3B,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAsC/E,qBAAa,kBAAmB,SAAQ,kBAAkB;IACtD,IAAI,iBAA2B;IAE/B,cAAc,IAAI,mBAAmB,CAEpC;CACJ;AAED,qBAAa,uBAAwB,SAAQ,cAAc,CAAC,yBAAyB,CAAC;IAClF,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAoB;IAExC,OAAO,CAAC,mBAAmB,CAEX;IAEhB,YAAY,WAAW,EAAE,yBAAyB,EA8BjD;IAED,OAAO,CAAC,MAAM,CAAC,mBAAmB;IAgB5B,WAAW,CACb,GAAG,EAAE,MAAM,EACX,cAAc,EAAE,CAAC,IAAI,EAAE,gBAAgB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,EAChE,OAAO,EAAE;QACL,MAAM,CAAC,EAAE,OAAO,EAAE,CAAC;QACnB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC;KACrB,GACF,OAAO,CAAC,IAAI,CAAC,CAUf;YAEa,oBAAoB;CA4BrC"}
1
+ {"version":3,"file":"RedshiftWarehouseClient.d.ts","sourceRoot":"","sources":["../../src/warehouseClients/RedshiftWarehouseClient.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,OAAO,EACP,yBAAyB,EAEzB,mBAAmB,EACnB,gBAAgB,EAChB,gBAAgB,EAChB,cAAc,EACjB,MAAM,mBAAmB,CAAC;AAI3B,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAsC/E,qBAAa,kBAAmB,SAAQ,kBAAkB;IACtD,IAAI,iBAA2B;IAE/B,cAAc,IAAI,mBAAmB,CAEpC;CACJ;AAED,qBAAa,uBAAwB,SAAQ,cAAc,CAAC,yBAAyB,CAAC;IAClF,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAoB;IAExC,OAAO,CAAC,mBAAmB,CAEX;IAEhB,YAAY,WAAW,EAAE,yBAAyB,EA8BjD;IAED,OAAO,CAAC,MAAM,CAAC,mBAAmB;IAgB5B,WAAW,CACb,GAAG,EAAE,MAAM,EACX,cAAc,EAAE,CAAC,IAAI,EAAE,gBAAgB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,EAChE,OAAO,EAAE;QACL,MAAM,CAAC,EAAE,OAAO,EAAE,CAAC;QACnB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC;KACrB,GACF,OAAO,CAAC,IAAI,CAAC,CAUf;IAKK,YAAY;;;;SAiBjB;IAEK,SAAS,CACX,SAAS,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,MAAM,EACf,QAAQ,CAAC,EAAE,MAAM,EACjB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC9B,OAAO,CAAC,gBAAgB,CAAC,CAuB3B;YAEa,oBAAoB;CA4BrC"}
@@ -121,6 +121,48 @@ class RedshiftWarehouseClient extends PostgresWarehouseClient_1.PostgresClient {
121
121
  }
122
122
  return super.streamQuery(sql, streamCallback, options);
123
123
  }
124
+ // information_schema omits late-binding views and Spectrum external tables;
125
+ // the SVV_* views cover them alongside regular tables and views. A Redshift
126
+ // project pointed at plain Postgres keeps the Postgres catalog.
127
+ async getAllTables() {
128
+ if (!(await this.isRedshift()))
129
+ return super.getAllTables();
130
+ const query = `
131
+ SELECT table_catalog, table_schema, table_name
132
+ FROM svv_tables
133
+ WHERE table_catalog = $1
134
+ AND table_schema NOT IN ('information_schema', 'pg_catalog', 'pg_internal')
135
+ ORDER BY 1, 2, 3
136
+ `;
137
+ const { rows } = await this.runQuery(query, {}, undefined, [
138
+ this.credentials.dbname,
139
+ ]);
140
+ return rows.map((row) => ({
141
+ database: row.table_catalog,
142
+ schema: row.table_schema,
143
+ table: row.table_name,
144
+ }));
145
+ }
146
+ async getFields(tableName, schema, database, tags) {
147
+ if (!(await this.isRedshift())) {
148
+ return super.getFields(tableName, schema, database, tags);
149
+ }
150
+ const { values, schemaParam, databaseParam } = this.bindFieldsFilters(tableName, schema, database);
151
+ const query = `
152
+ SELECT table_catalog,
153
+ table_schema,
154
+ table_name,
155
+ column_name,
156
+ data_type
157
+ FROM svv_columns
158
+ WHERE table_name = $1
159
+ ${schemaParam ? `AND table_schema = ${schemaParam}` : ''}
160
+ ${databaseParam ? `AND table_catalog = ${databaseParam}` : ''}
161
+ ORDER BY ordinal_position
162
+ `;
163
+ const { rows } = await this.runQuery(query, tags, undefined, values);
164
+ return this.parsePostgresCatalog(rows);
165
+ }
124
166
  async resolveIamPoolConfig() {
125
167
  const now = Date.now();
126
168
  if (this.cachedIamPoolConfig &&
@@ -2,18 +2,25 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const common_1 = require("@lightdash/common");
4
4
  const RedshiftWarehouseClient_1 = require("./RedshiftWarehouseClient");
5
+ const credentials = {
6
+ type: common_1.WarehouseTypes.REDSHIFT,
7
+ host: 'localhost',
8
+ user: 'analytics',
9
+ password: 'password',
10
+ port: 5439,
11
+ dbname: 'warehouse',
12
+ schema: 'public',
13
+ authenticationType: common_1.RedshiftAuthenticationType.PASSWORD,
14
+ };
15
+ const redshiftVersion = {
16
+ rows: [
17
+ { version: 'PostgreSQL 8.0.2 on i686-pc-linux-gnu, Redshift 1.0.77' },
18
+ ],
19
+ fields: {},
20
+ };
5
21
  describe('RedshiftWarehouseClient', () => {
6
22
  it('keeps catalog filters in the Redshift query', async () => {
7
- const warehouse = new RedshiftWarehouseClient_1.RedshiftWarehouseClient({
8
- type: common_1.WarehouseTypes.REDSHIFT,
9
- host: 'localhost',
10
- user: 'analytics',
11
- password: 'password',
12
- port: 5439,
13
- dbname: 'warehouse',
14
- schema: 'public',
15
- authenticationType: common_1.RedshiftAuthenticationType.PASSWORD,
16
- });
23
+ const warehouse = new RedshiftWarehouseClient_1.RedshiftWarehouseClient(credentials);
17
24
  const runQuery = vi
18
25
  .spyOn(warehouse, 'runQuery')
19
26
  .mockResolvedValueOnce({
@@ -30,4 +37,72 @@ describe('RedshiftWarehouseClient', () => {
30
37
  expect(catalogQuery).toContain("table_name IN ('orders')");
31
38
  expect(runQuery.mock.calls[1][3]).toBeUndefined();
32
39
  });
40
+ it('lists tables and views from svv_tables scoped to the database', async () => {
41
+ const warehouse = new RedshiftWarehouseClient_1.RedshiftWarehouseClient(credentials);
42
+ const runQuery = vi
43
+ .spyOn(warehouse, 'runQuery')
44
+ .mockResolvedValueOnce(redshiftVersion)
45
+ .mockResolvedValueOnce({
46
+ rows: [
47
+ {
48
+ table_catalog: 'warehouse',
49
+ table_schema: 'public',
50
+ table_name: 'orders_lbv',
51
+ },
52
+ ],
53
+ fields: {},
54
+ });
55
+ const tables = await warehouse.getAllTables();
56
+ const [query, , , values] = runQuery.mock.calls[1];
57
+ expect(query).toContain('FROM svv_tables');
58
+ expect(query).toContain('table_catalog = $1');
59
+ expect(values).toEqual(['warehouse']);
60
+ expect(tables).toEqual([
61
+ { database: 'warehouse', schema: 'public', table: 'orders_lbv' },
62
+ ]);
63
+ });
64
+ it('reads columns from svv_columns so late-binding views resolve', async () => {
65
+ const warehouse = new RedshiftWarehouseClient_1.RedshiftWarehouseClient(credentials);
66
+ const runQuery = vi
67
+ .spyOn(warehouse, 'runQuery')
68
+ .mockResolvedValueOnce(redshiftVersion)
69
+ .mockResolvedValueOnce({
70
+ rows: [
71
+ {
72
+ table_catalog: 'warehouse',
73
+ table_schema: 'public',
74
+ table_name: 'orders_lbv',
75
+ column_name: 'quantity',
76
+ data_type: 'integer',
77
+ },
78
+ ],
79
+ fields: {},
80
+ });
81
+ const fields = await warehouse.getFields('orders_lbv', 'public', 'warehouse');
82
+ const [query, , , values] = runQuery.mock.calls[1];
83
+ expect(query).toContain('FROM svv_columns');
84
+ expect(values).toEqual(['orders_lbv', 'public', 'warehouse']);
85
+ expect(fields).toEqual({
86
+ warehouse: {
87
+ public: { orders_lbv: { quantity: 'number' } },
88
+ },
89
+ });
90
+ });
91
+ it('keeps the Postgres catalog when the server is not Redshift', async () => {
92
+ const warehouse = new RedshiftWarehouseClient_1.RedshiftWarehouseClient(credentials);
93
+ const runQuery = vi
94
+ .spyOn(warehouse, 'runQuery')
95
+ .mockResolvedValueOnce({
96
+ rows: [{ version: 'PostgreSQL 15.4' }],
97
+ fields: {},
98
+ })
99
+ .mockResolvedValueOnce({ rows: [], fields: {} })
100
+ .mockResolvedValueOnce({ rows: [], fields: {} });
101
+ await warehouse.getAllTables();
102
+ await warehouse.getFields('orders', 'public');
103
+ expect(runQuery).toHaveBeenCalledTimes(3);
104
+ expect(runQuery.mock.calls[1][0]).toContain('FROM information_schema.tables');
105
+ expect(runQuery.mock.calls[1][0]).not.toContain('svv_tables');
106
+ expect(runQuery.mock.calls[2][0]).toContain('FROM information_schema.columns');
107
+ });
33
108
  });
@@ -60,7 +60,6 @@ export declare class TrinoWarehouseClient extends WarehouseBaseClient<CreateTrin
60
60
  }): Promise<void>;
61
61
  getCatalog(requests: TableInfo[]): Promise<WarehouseCatalog>;
62
62
  private sanitizeInput;
63
- getTables(schema?: string, tags?: Record<string, string>): Promise<WarehouseCatalog>;
64
63
  getFields(tableName: string, schema?: string, database?: string, tags?: Record<string, string>): Promise<WarehouseCatalog>;
65
64
  getAllTables(): Promise<{
66
65
  database: any;
@@ -1 +1 @@
1
- {"version":3,"file":"TrinoWarehouseClient.d.ts","sourceRoot":"","sources":["../../src/warehouseClients/TrinoWarehouseClient.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"TrinoWarehouseClient.d.ts","sourceRoot":"","sources":["../../src/warehouseClients/TrinoWarehouseClient.ts"],"names":[],"mappings":"AAAA,OAAO,EAEH,sBAAsB,EAEtB,MAAM,EAIN,mBAAmB,EACnB,gBAAgB,EAGhB,gBAAgB,EAChB,cAAc,EACd,KAAK,iBAAiB,EACtB,KAAK,eAAe,EACvB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAEH,iBAAiB,EAKpB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAO5C,OAAO,mBAAmB,MAAM,uBAAuB,CAAC;AACxD,OAAO,uBAAuB,MAAM,2BAA2B,CAAC;AAiBhE,oBAAY,UAAU;IAClB,OAAO,YAAY;IACnB,OAAO,YAAY;IACnB,QAAQ,aAAa;IACrB,OAAO,YAAY;IACnB,MAAM,WAAW;IACjB,IAAI,SAAS;IACb,MAAM,WAAW;IACjB,OAAO,YAAY;IACnB,OAAO,YAAY;IACnB,IAAI,SAAS;IACb,SAAS,cAAc;IACvB,IAAI,SAAS;IACb,IAAI,SAAS;IACb,IAAI,SAAS;IACb,OAAO,wBAAwB;IAC/B,SAAS,cAAc;IACvB,YAAY,6BAA6B;IACzC,mBAAmB,2BAA2B;IAC9C,iBAAiB,2BAA2B;IAC5C,KAAK,UAAU;IACf,GAAG,QAAQ;IACX,GAAG,QAAQ;IACX,SAAS,cAAc;IACvB,IAAI,SAAS;CAChB;AAED,UAAU,SAAS;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACjB;AAyBD,eAAO,MAAM,uBAAuB,SAC1B,UAAU,GAAG,MAAM,KAC1B,eAAe,GAAG,SASpB,CAAC;AAGF,eAAO,MAAM,mBAAmB,SACtB,UAAU,GAAG,MAAM,KAC1B,iBAAiB,GAAG,IAiBtB,CAAC;AA4FF,qBAAa,eAAgB,SAAQ,uBAAuB;IACxD,QAAQ,CAAC,IAAI,wBAAwB;IAErC,cAAc,IAAI,mBAAmB,CAEpC;IAGD,0BAA0B,IAAI,OAAO,CAEpC;IAED,wBAAwB,IAAI,MAAM,CAEjC;IAED,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAWhD;IAED,eAAe,IAAI,MAAM,CAExB;IAED,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAiBlC;IAED,eAAe,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAGlC;IAED,UAAU,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAE7B;IAED,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,gBAAgB,GAAG,MAAM,CAI5D;IAED,uBAAuB,CACnB,iBAAiB,EAAE,MAAM,EACzB,eAAe,EAAE,MAAM,GACxB,MAAM,CAGR;IAED,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAGrC;CACJ;AAED,qBAAa,oBAAqB,SAAQ,mBAAmB,CAAC,sBAAsB,CAAC;IACjF,iBAAiB,EAAE,iBAAiB,CAAC;IAErC,YAAY,WAAW,EAAE,sBAAsB,EAS9C;YAEa,UAAU;IAkBlB,WAAW,CACb,GAAG,EAAE,MAAM,EACX,cAAc,EAAE,CAAC,IAAI,EAAE,gBAAgB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,EAChE,OAAO,EAAE;QACL,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC;KACrB,GACF,OAAO,CAAC,IAAI,CAAC,CA6Gf;IAEK,UAAU,CAAC,QAAQ,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC,gBAAgB,CAAC,CA0BjE;IAED,OAAO,CAAC,aAAa;IAQf,SAAS,CACX,SAAS,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,MAAM,EACf,QAAQ,CAAC,EAAE,MAAM,EACjB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC9B,OAAO,CAAC,gBAAgB,CAAC,CA2B3B;IAEK,YAAY;;;;SAoBjB;CACJ"}
@@ -364,20 +364,6 @@ class TrinoWarehouseClient extends WarehouseBaseClient_1.default {
364
364
  return sql.replaceAll(this.sqlBuilder.getStringQuoteChar(), this.sqlBuilder.getEscapeStringQuoteChar() +
365
365
  this.sqlBuilder.getStringQuoteChar());
366
366
  }
367
- async getTables(schema, tags) {
368
- const schemaFilter = schema
369
- ? `AND table_schema = '${this.sanitizeInput(schema)}'`
370
- : '';
371
- const query = `
372
- SELECT table_catalog, table_schema, table_name
373
- FROM information_schema.tables
374
- WHERE table_type = 'BASE TABLE'
375
- ${schemaFilter}
376
- ORDER BY 1,2,3
377
- `;
378
- const { rows } = await this.runQuery(query, tags);
379
- return this.parseWarehouseCatalog(rows, convertDataTypeToDimensionType, exports.getTrinoTimestampDomain);
380
- }
381
367
  async getFields(tableName, schema, database, tags) {
382
368
  const query = `
383
369
  SELECT table_catalog,
@@ -406,7 +392,7 @@ class TrinoWarehouseClient extends WarehouseBaseClient_1.default {
406
392
  const query = `
407
393
  SELECT table_catalog, table_schema, table_name
408
394
  FROM information_schema.tables
409
- WHERE table_type = 'BASE TABLE'
395
+ WHERE table_type IN ('BASE TABLE', 'VIEW')
410
396
  ${whereSql}
411
397
  ${filterSystemTables}
412
398
  ORDER BY 1, 2, 3
@@ -201,3 +201,24 @@ describe('TrinoSqlBuilder temporal literals', () => {
201
201
  expect(builder.castToNaiveTimestamp(epoch)).toBe("TIMESTAMP '1970-01-01 00:00:00.000'");
202
202
  });
203
203
  });
204
+ describe('TrinoWarehouseClient getAllTables', () => {
205
+ it('lists tables and views', async () => {
206
+ const warehouse = new TrinoWarehouseClient_1.TrinoWarehouseClient(TrinoWarehouseClient_mock_1.credentials);
207
+ const runQuery = vi.spyOn(warehouse, 'runQuery').mockResolvedValueOnce({
208
+ rows: [
209
+ {
210
+ table_catalog: 'hive',
211
+ table_schema: 'analytics',
212
+ table_name: 'orders_view',
213
+ },
214
+ ],
215
+ fields: {},
216
+ });
217
+ const tables = await warehouse.getAllTables();
218
+ const [query] = runQuery.mock.calls[0];
219
+ expect(query).toContain("table_type IN ('BASE TABLE', 'VIEW')");
220
+ expect(tables).toEqual([
221
+ { database: 'hive', schema: 'analytics', table: 'orders_view' },
222
+ ]);
223
+ });
224
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lightdash/warehouses",
3
- "version": "2.196.0",
3
+ "version": "2.196.2",
4
4
  "description": "Warehouse connectors for Lightdash",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -21,7 +21,7 @@
21
21
  "@databricks/sql": "1.13.0",
22
22
  "@duckdb/node-api": "1.5.2-r.2",
23
23
  "@google-cloud/bigquery": "8.3.1",
24
- "@lightdash/common": "2.196.0",
24
+ "@lightdash/common": "2.196.2",
25
25
  "node-fetch": "2.7.0",
26
26
  "pg": "8.13.1",
27
27
  "pg-cursor": "2.10.0",