@malloydata/db-postgres 0.0.394 → 0.0.396
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.
|
@@ -30,7 +30,7 @@ export declare class PostgresConnection extends BaseConnection implements Connec
|
|
|
30
30
|
getDigest(): string;
|
|
31
31
|
get supportsNesting(): boolean;
|
|
32
32
|
protected getClient(): Promise<Client>;
|
|
33
|
-
protected runPostgresQuery(sqlCommand: string, _pageSize: number, _rowIndex: number, deJSON: boolean): Promise<MalloyQueryData>;
|
|
33
|
+
protected runPostgresQuery(sqlCommand: string, _pageSize: number, _rowIndex: number, deJSON: boolean, values?: unknown[]): Promise<MalloyQueryData>;
|
|
34
34
|
fetchSelectSchema(sqlRef: SQLSourceRequest): Promise<SQLSourceDef | string>;
|
|
35
35
|
private schemaFromQuery;
|
|
36
36
|
fetchTableSchema(tableKey: string, tablePath: string): Promise<TableSourceDef | string>;
|
|
@@ -49,7 +49,7 @@ export declare class PooledPostgresConnection extends PostgresConnection impleme
|
|
|
49
49
|
isPool(): this is PooledConnection;
|
|
50
50
|
drain(): Promise<void>;
|
|
51
51
|
getPool(): Promise<Pool>;
|
|
52
|
-
protected runPostgresQuery(sqlCommand: string, _pageSize: number, _rowIndex: number, deJSON: boolean): Promise<MalloyQueryData>;
|
|
52
|
+
protected runPostgresQuery(sqlCommand: string, _pageSize: number, _rowIndex: number, deJSON: boolean, values?: unknown[]): Promise<MalloyQueryData>;
|
|
53
53
|
runSQLStream(sqlCommand: string, { rowLimit, abortSignal }?: RunSQLOptions): AsyncIterableIterator<QueryRecord>;
|
|
54
54
|
close(): Promise<void>;
|
|
55
55
|
}
|
|
@@ -32,6 +32,24 @@ const pg_1 = require("pg");
|
|
|
32
32
|
const pg_query_stream_1 = __importDefault(require("pg-query-stream"));
|
|
33
33
|
const DEFAULT_PAGE_SIZE = 1000;
|
|
34
34
|
const SCHEMA_PAGE_SIZE = 1000;
|
|
35
|
+
/**
|
|
36
|
+
* Decode a canonical Postgres dotted-table path into its underlying
|
|
37
|
+
* identifier strings as they appear in `information_schema`. The schema
|
|
38
|
+
* lookup is a string-literal comparison, not an identifier reference,
|
|
39
|
+
* so Postgres's bare-name lowercase folding doesn't happen for us — we
|
|
40
|
+
* apply it here: bare segments → lowercase, `"…"` segments → as-is.
|
|
41
|
+
*/
|
|
42
|
+
function decodeDottedSegments(input) {
|
|
43
|
+
const result = (0, malloy_1.decodeDottedTablePath)(input, {
|
|
44
|
+
quoteChar: '"',
|
|
45
|
+
escapeStyle: 'doubled',
|
|
46
|
+
bareIdentRegex: /^[A-Za-z_][A-Za-z0-9_$]*/,
|
|
47
|
+
dialectName: 'Postgres',
|
|
48
|
+
});
|
|
49
|
+
if (!result.ok)
|
|
50
|
+
return undefined;
|
|
51
|
+
return result.segments.map(s => (s.quoted ? s.value : s.value.toLowerCase()));
|
|
52
|
+
}
|
|
35
53
|
class PostgresConnection extends connection_1.BaseConnection {
|
|
36
54
|
constructor(arg, queryOptionsReader, configReader) {
|
|
37
55
|
super();
|
|
@@ -105,11 +123,11 @@ class PostgresConnection extends connection_1.BaseConnection {
|
|
|
105
123
|
connectionString,
|
|
106
124
|
});
|
|
107
125
|
}
|
|
108
|
-
async runPostgresQuery(sqlCommand, _pageSize, _rowIndex, deJSON) {
|
|
126
|
+
async runPostgresQuery(sqlCommand, _pageSize, _rowIndex, deJSON, values) {
|
|
109
127
|
const client = await this.getClient();
|
|
110
128
|
await client.connect();
|
|
111
129
|
await this.connectionSetup(client);
|
|
112
|
-
let result = await client.query(sqlCommand);
|
|
130
|
+
let result = await client.query(sqlCommand, values);
|
|
113
131
|
if (Array.isArray(result)) {
|
|
114
132
|
result = result.pop();
|
|
115
133
|
}
|
|
@@ -222,8 +240,8 @@ class PostgresConnection extends connection_1.BaseConnection {
|
|
|
222
240
|
await client.end();
|
|
223
241
|
return structDef;
|
|
224
242
|
}
|
|
225
|
-
async schemaFromQuery(infoQuery, structDef) {
|
|
226
|
-
const { rows, totalRows } = await this.runPostgresQuery(infoQuery, SCHEMA_PAGE_SIZE, 0, false);
|
|
243
|
+
async schemaFromQuery(infoQuery, structDef, values) {
|
|
244
|
+
const { rows, totalRows } = await this.runPostgresQuery(infoQuery, SCHEMA_PAGE_SIZE, 0, false, values);
|
|
227
245
|
if (!totalRows) {
|
|
228
246
|
throw new Error('Unable to read schema.');
|
|
229
247
|
}
|
|
@@ -249,20 +267,25 @@ class PostgresConnection extends connection_1.BaseConnection {
|
|
|
249
267
|
connection: this.name,
|
|
250
268
|
fields: [],
|
|
251
269
|
};
|
|
252
|
-
|
|
253
|
-
|
|
270
|
+
// tablePath is canonical SQL — bare segments (case-folded to lower by
|
|
271
|
+
// Postgres) or `"…"` quoted segments (case-preserving, `""` escape).
|
|
272
|
+
// The information_schema lookup needs the raw identifier strings, not
|
|
273
|
+
// the SQL surface form, so decode each segment.
|
|
274
|
+
const segments = decodeDottedSegments(tablePath);
|
|
275
|
+
if (segments === undefined || segments.length < 2) {
|
|
254
276
|
return 'Default schema not yet supported in Postgres';
|
|
255
277
|
}
|
|
278
|
+
const [schema, table] = segments.slice(-2);
|
|
256
279
|
const infoQuery = `
|
|
257
280
|
SELECT column_name, c.data_type, e.data_type as element_type
|
|
258
281
|
FROM information_schema.columns c LEFT JOIN information_schema.element_types e
|
|
259
282
|
ON ((c.table_catalog, c.table_schema, c.table_name, 'TABLE', c.dtd_identifier)
|
|
260
283
|
= (e.object_catalog, e.object_schema, e.object_name, e.object_type, e.collection_type_identifier))
|
|
261
|
-
WHERE table_name =
|
|
262
|
-
AND table_schema =
|
|
284
|
+
WHERE table_name = $1
|
|
285
|
+
AND table_schema = $2
|
|
263
286
|
`;
|
|
264
287
|
try {
|
|
265
|
-
await this.schemaFromQuery(infoQuery, structDef);
|
|
288
|
+
await this.schemaFromQuery(infoQuery, structDef, [table, schema]);
|
|
266
289
|
}
|
|
267
290
|
catch (error) {
|
|
268
291
|
return `Error fetching schema for ${tablePath}: ${error.message}`;
|
|
@@ -363,9 +386,9 @@ class PooledPostgresConnection extends PostgresConnection {
|
|
|
363
386
|
}
|
|
364
387
|
return this._pool;
|
|
365
388
|
}
|
|
366
|
-
async runPostgresQuery(sqlCommand, _pageSize, _rowIndex, deJSON) {
|
|
389
|
+
async runPostgresQuery(sqlCommand, _pageSize, _rowIndex, deJSON, values) {
|
|
367
390
|
const pool = await this.getPool();
|
|
368
|
-
let result = await pool.query(sqlCommand);
|
|
391
|
+
let result = await pool.query(sqlCommand, values);
|
|
369
392
|
if (Array.isArray(result)) {
|
|
370
393
|
result = result.pop();
|
|
371
394
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@malloydata/db-postgres",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.396",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"prepublishOnly": "npm run build"
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"@malloydata/malloy": "0.0.
|
|
26
|
+
"@malloydata/malloy": "0.0.396",
|
|
27
27
|
"@types/pg": "^8.6.1",
|
|
28
28
|
"pg": "^8.7.1",
|
|
29
29
|
"pg-query-stream": "4.2.3"
|