@lightdash/warehouses 2.162.1 → 2.162.3
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.
- package/dist/.tsbuildinfo +1 -1
- package/dist/warehouseClients/AthenaWarehouseClient.d.ts +2 -1
- package/dist/warehouseClients/AthenaWarehouseClient.d.ts.map +1 -1
- package/dist/warehouseClients/AthenaWarehouseClient.js +23 -1
- package/dist/warehouseClients/BigqueryWarehouseClient.d.ts +6 -1
- package/dist/warehouseClients/BigqueryWarehouseClient.d.ts.map +1 -1
- package/dist/warehouseClients/BigqueryWarehouseClient.js +31 -2
- package/dist/warehouseClients/BigqueryWarehouseClient.test.js +5 -0
- package/dist/warehouseClients/ClickhouseWarehouseClient.d.ts +2 -1
- package/dist/warehouseClients/ClickhouseWarehouseClient.d.ts.map +1 -1
- package/dist/warehouseClients/ClickhouseWarehouseClient.js +35 -2
- package/dist/warehouseClients/DatabricksWarehouseClient.d.ts +10 -1
- package/dist/warehouseClients/DatabricksWarehouseClient.d.ts.map +1 -1
- package/dist/warehouseClients/DatabricksWarehouseClient.js +34 -8
- package/dist/warehouseClients/DatabricksWarehouseClient.test.js +7 -1
- package/dist/warehouseClients/SnowflakeWarehouseClient.d.ts +3 -1
- package/dist/warehouseClients/SnowflakeWarehouseClient.d.ts.map +1 -1
- package/dist/warehouseClients/SnowflakeWarehouseClient.js +38 -7
- package/dist/warehouseClients/SnowflakeWarehouseClient.mock.d.ts +3 -1
- package/dist/warehouseClients/SnowflakeWarehouseClient.mock.d.ts.map +1 -1
- package/dist/warehouseClients/SnowflakeWarehouseClient.mock.js +5 -1
- package/dist/warehouseClients/SnowflakeWarehouseClient.test.js +8 -1
- package/dist/warehouseClients/TrinoWarehouseClient.d.ts +2 -1
- package/dist/warehouseClients/TrinoWarehouseClient.d.ts.map +1 -1
- package/dist/warehouseClients/TrinoWarehouseClient.js +35 -7
- package/dist/warehouseClients/TrinoWarehouseClient.test.js +5 -0
- package/dist/warehouseClients/numericKinds.test.d.ts +2 -0
- package/dist/warehouseClients/numericKinds.test.d.ts.map +1 -0
- package/dist/warehouseClients/numericKinds.test.js +168 -0
- package/package.json +2 -2
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.TrinoWarehouseClient = exports.TrinoSqlBuilder = exports.getTrinoTimestampDomain = exports.TrinoTypes = void 0;
|
|
6
|
+
exports.TrinoWarehouseClient = exports.TrinoSqlBuilder = exports.getTrinoNumericKind = exports.getTrinoTimestampDomain = exports.TrinoTypes = void 0;
|
|
7
7
|
const common_1 = require("@lightdash/common");
|
|
8
8
|
const trino_client_1 = require("trino-client");
|
|
9
9
|
const coerceTagToString_1 = require("../utils/coerceTagToString");
|
|
@@ -77,6 +77,26 @@ const getTrinoTimestampDomain = (type) => {
|
|
|
77
77
|
}
|
|
78
78
|
};
|
|
79
79
|
exports.getTrinoTimestampDomain = getTrinoTimestampDomain;
|
|
80
|
+
// The column type string carries the decimal scale: decimal(p,s)
|
|
81
|
+
const getTrinoNumericKind = (type) => {
|
|
82
|
+
switch (removeNumericTypeParameters(type)) {
|
|
83
|
+
case TrinoTypes.TINYINT:
|
|
84
|
+
case TrinoTypes.SMALLINT:
|
|
85
|
+
case TrinoTypes.INTEGER:
|
|
86
|
+
case TrinoTypes.BIGINT:
|
|
87
|
+
return { kind: 'integer' };
|
|
88
|
+
case TrinoTypes.REAL:
|
|
89
|
+
case TrinoTypes.DOUBLE:
|
|
90
|
+
return { kind: 'float' };
|
|
91
|
+
case TrinoTypes.DECIMAL: {
|
|
92
|
+
const scale = type.match(/\(\s*\d+\s*,\s*(\d+)\s*\)/);
|
|
93
|
+
return scale ? { kind: 'decimal', scale: Number(scale[1]) } : null;
|
|
94
|
+
}
|
|
95
|
+
default:
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
exports.getTrinoNumericKind = getTrinoNumericKind;
|
|
80
100
|
const convertDataTypeToDimensionType = (type) => {
|
|
81
101
|
const typeWithoutParameters = removeNumericTypeParameters(type);
|
|
82
102
|
switch (typeWithoutParameters) {
|
|
@@ -263,12 +283,20 @@ class TrinoWarehouseClient extends WarehouseBaseClient_1.default {
|
|
|
263
283
|
'Unexpected error in query execution');
|
|
264
284
|
}
|
|
265
285
|
const schema = queryResult.value.columns ?? [];
|
|
266
|
-
const fields = schema.reduce((acc, column) =>
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
286
|
+
const fields = schema.reduce((acc, column) => {
|
|
287
|
+
// The full type string carries the decimal scale that rawType drops
|
|
288
|
+
const type = column.type ??
|
|
289
|
+
column.typeSignature.rawType ??
|
|
290
|
+
TrinoTypes.VARCHAR;
|
|
291
|
+
const numericKind = (0, exports.getTrinoNumericKind)(type);
|
|
292
|
+
return {
|
|
293
|
+
...acc,
|
|
294
|
+
[normalizeColumnName(column.name)]: {
|
|
295
|
+
type: convertDataTypeToDimensionType(type),
|
|
296
|
+
...(numericKind ? { numericKind } : {}),
|
|
297
|
+
},
|
|
298
|
+
};
|
|
299
|
+
}, {});
|
|
272
300
|
// stream initial data, if available
|
|
273
301
|
if (queryResult.value.data) {
|
|
274
302
|
await streamCallback({
|
|
@@ -52,6 +52,11 @@ describe('TrinoWarehouseClient', () => {
|
|
|
52
52
|
acc[key.toLowerCase()] = warehouseClient.expectedFields[key];
|
|
53
53
|
return acc;
|
|
54
54
|
}, {});
|
|
55
|
+
// The mock's number column is a Trino integer, which reports its kind
|
|
56
|
+
lowerCaseFields.mynumbercolumn = {
|
|
57
|
+
...lowerCaseFields.mynumbercolumn,
|
|
58
|
+
numericKind: { kind: 'integer' },
|
|
59
|
+
};
|
|
55
60
|
const lowerCaseRow = Object.keys(warehouseClient.expectedRow).reduce((acc, key) => {
|
|
56
61
|
acc[key.toLowerCase()] = warehouseClient.expectedRow[key];
|
|
57
62
|
return acc;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"numericKinds.test.d.ts","sourceRoot":"","sources":["../../src/warehouseClients/numericKinds.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const TCLIService_types_1 = require("@databricks/sql/thrift/TCLIService_types");
|
|
4
|
+
const vitest_1 = require("vitest");
|
|
5
|
+
const AthenaWarehouseClient_1 = require("./AthenaWarehouseClient");
|
|
6
|
+
const BigqueryWarehouseClient_1 = require("./BigqueryWarehouseClient");
|
|
7
|
+
const ClickhouseWarehouseClient_1 = require("./ClickhouseWarehouseClient");
|
|
8
|
+
const DatabricksWarehouseClient_1 = require("./DatabricksWarehouseClient");
|
|
9
|
+
const SnowflakeWarehouseClient_1 = require("./SnowflakeWarehouseClient");
|
|
10
|
+
const TrinoWarehouseClient_1 = require("./TrinoWarehouseClient");
|
|
11
|
+
// The typed read binds a NUMBER column by the kind its driver reports; a
|
|
12
|
+
// column without one binds as DOUBLE and loses digits above 2^53
|
|
13
|
+
(0, vitest_1.describe)('numeric kinds reported by warehouse drivers', () => {
|
|
14
|
+
(0, vitest_1.describe)('Snowflake', () => {
|
|
15
|
+
(0, vitest_1.it)('reads NUMBER with scale 0 as an integer and with a scale as a decimal', () => {
|
|
16
|
+
(0, vitest_1.expect)((0, SnowflakeWarehouseClient_1.getSnowflakeNumericKind)('FIXED', 0)).toEqual({
|
|
17
|
+
kind: 'integer',
|
|
18
|
+
});
|
|
19
|
+
(0, vitest_1.expect)((0, SnowflakeWarehouseClient_1.getSnowflakeNumericKind)('NUMBER', 4)).toEqual({
|
|
20
|
+
kind: 'decimal',
|
|
21
|
+
scale: 4,
|
|
22
|
+
});
|
|
23
|
+
(0, vitest_1.expect)((0, SnowflakeWarehouseClient_1.getSnowflakeNumericKind)('fixed', 2)).toEqual({
|
|
24
|
+
kind: 'decimal',
|
|
25
|
+
scale: 2,
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
(0, vitest_1.it)('reads REAL as a float and reports nothing without a scale or for other types', () => {
|
|
29
|
+
(0, vitest_1.expect)((0, SnowflakeWarehouseClient_1.getSnowflakeNumericKind)('REAL', 0)).toEqual({
|
|
30
|
+
kind: 'float',
|
|
31
|
+
});
|
|
32
|
+
(0, vitest_1.expect)((0, SnowflakeWarehouseClient_1.getSnowflakeNumericKind)('FIXED', undefined)).toBeNull();
|
|
33
|
+
(0, vitest_1.expect)((0, SnowflakeWarehouseClient_1.getSnowflakeNumericKind)('TEXT', 0)).toBeNull();
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
(0, vitest_1.describe)('BigQuery', () => {
|
|
37
|
+
(0, vitest_1.it)('reads INT64 as an integer and FLOAT64 as a float', () => {
|
|
38
|
+
(0, vitest_1.expect)((0, BigqueryWarehouseClient_1.getBigqueryNumericKind)({ type: 'INTEGER' })).toEqual({
|
|
39
|
+
kind: 'integer',
|
|
40
|
+
});
|
|
41
|
+
(0, vitest_1.expect)((0, BigqueryWarehouseClient_1.getBigqueryNumericKind)({ type: 'INT64' })).toEqual({
|
|
42
|
+
kind: 'integer',
|
|
43
|
+
});
|
|
44
|
+
(0, vitest_1.expect)((0, BigqueryWarehouseClient_1.getBigqueryNumericKind)({ type: 'FLOAT64' })).toEqual({
|
|
45
|
+
kind: 'float',
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
(0, vitest_1.it)('reads NUMERIC at its declared scale, else at the default of 9', () => {
|
|
49
|
+
(0, vitest_1.expect)((0, BigqueryWarehouseClient_1.getBigqueryNumericKind)({ type: 'NUMERIC', scale: '2' })).toEqual({ kind: 'decimal', scale: 2 });
|
|
50
|
+
(0, vitest_1.expect)((0, BigqueryWarehouseClient_1.getBigqueryNumericKind)({ type: 'NUMERIC' })).toEqual({
|
|
51
|
+
kind: 'decimal',
|
|
52
|
+
scale: 9,
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
(0, vitest_1.it)('reads BIGNUMERIC only when its declared precision fits a DuckDB decimal', () => {
|
|
56
|
+
(0, vitest_1.expect)((0, BigqueryWarehouseClient_1.getBigqueryNumericKind)({
|
|
57
|
+
type: 'BIGNUMERIC',
|
|
58
|
+
precision: '30',
|
|
59
|
+
scale: '4',
|
|
60
|
+
})).toEqual({ kind: 'decimal', scale: 4 });
|
|
61
|
+
(0, vitest_1.expect)((0, BigqueryWarehouseClient_1.getBigqueryNumericKind)({ type: 'BIGNUMERIC' })).toBeNull();
|
|
62
|
+
(0, vitest_1.expect)((0, BigqueryWarehouseClient_1.getBigqueryNumericKind)({ type: 'BIGNUMERIC', scale: '4' })).toBeNull();
|
|
63
|
+
(0, vitest_1.expect)((0, BigqueryWarehouseClient_1.getBigqueryNumericKind)({
|
|
64
|
+
type: 'BIGNUMERIC',
|
|
65
|
+
precision: '60',
|
|
66
|
+
scale: '4',
|
|
67
|
+
})).toBeNull();
|
|
68
|
+
(0, vitest_1.expect)((0, BigqueryWarehouseClient_1.getBigqueryNumericKind)({ type: 'STRING' })).toBeNull();
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
(0, vitest_1.describe)('Trino', () => {
|
|
72
|
+
(0, vitest_1.it)('reads the kind and the decimal scale from the column type string', () => {
|
|
73
|
+
(0, vitest_1.expect)((0, TrinoWarehouseClient_1.getTrinoNumericKind)('bigint')).toEqual({ kind: 'integer' });
|
|
74
|
+
(0, vitest_1.expect)((0, TrinoWarehouseClient_1.getTrinoNumericKind)('tinyint')).toEqual({
|
|
75
|
+
kind: 'integer',
|
|
76
|
+
});
|
|
77
|
+
(0, vitest_1.expect)((0, TrinoWarehouseClient_1.getTrinoNumericKind)('double')).toEqual({ kind: 'float' });
|
|
78
|
+
(0, vitest_1.expect)((0, TrinoWarehouseClient_1.getTrinoNumericKind)('real')).toEqual({ kind: 'float' });
|
|
79
|
+
(0, vitest_1.expect)((0, TrinoWarehouseClient_1.getTrinoNumericKind)('decimal(10,2)')).toEqual({
|
|
80
|
+
kind: 'decimal',
|
|
81
|
+
scale: 2,
|
|
82
|
+
});
|
|
83
|
+
(0, vitest_1.expect)((0, TrinoWarehouseClient_1.getTrinoNumericKind)('decimal(38, 0)')).toEqual({
|
|
84
|
+
kind: 'decimal',
|
|
85
|
+
scale: 0,
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
(0, vitest_1.it)('reports nothing for a decimal without a scale or for other types', () => {
|
|
89
|
+
(0, vitest_1.expect)((0, TrinoWarehouseClient_1.getTrinoNumericKind)('decimal')).toBeNull();
|
|
90
|
+
(0, vitest_1.expect)((0, TrinoWarehouseClient_1.getTrinoNumericKind)('varchar')).toBeNull();
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
(0, vitest_1.describe)('Databricks', () => {
|
|
94
|
+
(0, vitest_1.it)('reads integers, floats and a decimal with its scale qualifier', () => {
|
|
95
|
+
(0, vitest_1.expect)((0, DatabricksWarehouseClient_1.getDatabricksNumericKind)({
|
|
96
|
+
type: TCLIService_types_1.TTypeId.BIGINT_TYPE,
|
|
97
|
+
})).toEqual({ kind: 'integer' });
|
|
98
|
+
(0, vitest_1.expect)((0, DatabricksWarehouseClient_1.getDatabricksNumericKind)({
|
|
99
|
+
type: TCLIService_types_1.TTypeId.DOUBLE_TYPE,
|
|
100
|
+
})).toEqual({ kind: 'float' });
|
|
101
|
+
(0, vitest_1.expect)((0, DatabricksWarehouseClient_1.getDatabricksNumericKind)({
|
|
102
|
+
type: TCLIService_types_1.TTypeId.DECIMAL_TYPE,
|
|
103
|
+
typeQualifiers: {
|
|
104
|
+
qualifiers: {
|
|
105
|
+
precision: { i32Value: 18 },
|
|
106
|
+
scale: { i32Value: 3 },
|
|
107
|
+
},
|
|
108
|
+
},
|
|
109
|
+
})).toEqual({ kind: 'decimal', scale: 3 });
|
|
110
|
+
});
|
|
111
|
+
(0, vitest_1.it)('reports nothing for a decimal without a scale qualifier or for other types', () => {
|
|
112
|
+
(0, vitest_1.expect)((0, DatabricksWarehouseClient_1.getDatabricksNumericKind)({
|
|
113
|
+
type: TCLIService_types_1.TTypeId.DECIMAL_TYPE,
|
|
114
|
+
})).toBeNull();
|
|
115
|
+
(0, vitest_1.expect)((0, DatabricksWarehouseClient_1.getDatabricksNumericKind)({
|
|
116
|
+
type: TCLIService_types_1.TTypeId.STRING_TYPE,
|
|
117
|
+
})).toBeNull();
|
|
118
|
+
});
|
|
119
|
+
});
|
|
120
|
+
(0, vitest_1.describe)('ClickHouse', () => {
|
|
121
|
+
(0, vitest_1.it)('reads integers and floats through Nullable and LowCardinality wrappers', () => {
|
|
122
|
+
(0, vitest_1.expect)((0, ClickhouseWarehouseClient_1.getClickhouseNumericKind)('Int64')).toEqual({
|
|
123
|
+
kind: 'integer',
|
|
124
|
+
});
|
|
125
|
+
(0, vitest_1.expect)((0, ClickhouseWarehouseClient_1.getClickhouseNumericKind)('Nullable(UInt64)')).toEqual({
|
|
126
|
+
kind: 'integer',
|
|
127
|
+
});
|
|
128
|
+
(0, vitest_1.expect)((0, ClickhouseWarehouseClient_1.getClickhouseNumericKind)('LowCardinality(Nullable(Float64))')).toEqual({ kind: 'float' });
|
|
129
|
+
});
|
|
130
|
+
(0, vitest_1.it)('reads the scale of Decimal(P, S), the spelling the server sends for every decimal', () => {
|
|
131
|
+
(0, vitest_1.expect)((0, ClickhouseWarehouseClient_1.getClickhouseNumericKind)('Decimal(18, 4)')).toEqual({
|
|
132
|
+
kind: 'decimal',
|
|
133
|
+
scale: 4,
|
|
134
|
+
});
|
|
135
|
+
(0, vitest_1.expect)((0, ClickhouseWarehouseClient_1.getClickhouseNumericKind)('Nullable(Decimal(10,2))')).toEqual({ kind: 'decimal', scale: 2 });
|
|
136
|
+
(0, vitest_1.expect)((0, ClickhouseWarehouseClient_1.getClickhouseNumericKind)('Decimal(38, 10)')).toEqual({
|
|
137
|
+
kind: 'decimal',
|
|
138
|
+
scale: 10,
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
(0, vitest_1.it)('reports nothing for a decimal wider than 38 digits or for other types', () => {
|
|
142
|
+
(0, vitest_1.expect)((0, ClickhouseWarehouseClient_1.getClickhouseNumericKind)('Decimal(76, 10)')).toBeNull();
|
|
143
|
+
(0, vitest_1.expect)((0, ClickhouseWarehouseClient_1.getClickhouseNumericKind)('String')).toBeNull();
|
|
144
|
+
});
|
|
145
|
+
});
|
|
146
|
+
(0, vitest_1.describe)('Athena', () => {
|
|
147
|
+
(0, vitest_1.it)('reads integers, floats and a decimal with the scale ColumnInfo reports', () => {
|
|
148
|
+
(0, vitest_1.expect)((0, AthenaWarehouseClient_1.getAthenaNumericKind)('bigint', 0)).toEqual({
|
|
149
|
+
kind: 'integer',
|
|
150
|
+
});
|
|
151
|
+
(0, vitest_1.expect)((0, AthenaWarehouseClient_1.getAthenaNumericKind)('double', 0)).toEqual({
|
|
152
|
+
kind: 'float',
|
|
153
|
+
});
|
|
154
|
+
(0, vitest_1.expect)((0, AthenaWarehouseClient_1.getAthenaNumericKind)('decimal', 2)).toEqual({
|
|
155
|
+
kind: 'decimal',
|
|
156
|
+
scale: 2,
|
|
157
|
+
});
|
|
158
|
+
(0, vitest_1.expect)((0, AthenaWarehouseClient_1.getAthenaNumericKind)('decimal(10,2)', 2)).toEqual({
|
|
159
|
+
kind: 'decimal',
|
|
160
|
+
scale: 2,
|
|
161
|
+
});
|
|
162
|
+
});
|
|
163
|
+
(0, vitest_1.it)('reports nothing for a decimal without a scale or for other types', () => {
|
|
164
|
+
(0, vitest_1.expect)((0, AthenaWarehouseClient_1.getAthenaNumericKind)('decimal', undefined)).toBeNull();
|
|
165
|
+
(0, vitest_1.expect)((0, AthenaWarehouseClient_1.getAthenaNumericKind)('varchar', undefined)).toBeNull();
|
|
166
|
+
});
|
|
167
|
+
});
|
|
168
|
+
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lightdash/warehouses",
|
|
3
|
-
"version": "2.162.
|
|
3
|
+
"version": "2.162.3",
|
|
4
4
|
"description": "Warehouse connectors for Lightdash",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"snowflake-sdk": "2.3.4",
|
|
29
29
|
"ssh2": "1.14.0",
|
|
30
30
|
"trino-client": "0.2.9",
|
|
31
|
-
"@lightdash/common": "2.162.
|
|
31
|
+
"@lightdash/common": "2.162.3"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
34
|
"oxlint": "1.75.0",
|