@malloydata/malloy 0.0.434 → 0.0.436
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/api/foundation/build_targets.d.ts +5 -6
- package/dist/api/foundation/build_targets.js +74 -6
- package/dist/api/foundation/compile.d.ts +0 -1
- package/dist/api/foundation/compile.js +0 -3
- package/dist/api/foundation/core.d.ts +16 -4
- package/dist/api/foundation/core.js +23 -23
- package/dist/api/foundation/index.d.ts +1 -1
- package/dist/api/foundation/runtime.d.ts +21 -3
- package/dist/api/foundation/runtime.js +45 -54
- package/dist/api/foundation/types.d.ts +43 -4
- package/dist/connection/dbmeta.d.ts +29 -0
- package/dist/connection/dbmeta.js +46 -0
- package/dist/connection/index.d.ts +1 -0
- package/dist/connection/index.js +1 -0
- package/dist/dialect/databricks/databricks.d.ts +11 -12
- package/dist/dialect/databricks/databricks.js +24 -36
- package/dist/dialect/dialect.d.ts +70 -171
- package/dist/dialect/dialect.js +123 -92
- package/dist/dialect/dialect_map.js +2 -0
- package/dist/dialect/duckdb/duckdb.d.ts +2 -2
- package/dist/dialect/duckdb/duckdb.js +1 -1
- package/dist/dialect/index.d.ts +3 -2
- package/dist/dialect/index.js +4 -2
- package/dist/dialect/mysql/mysql.d.ts +11 -12
- package/dist/dialect/mysql/mysql.js +20 -32
- package/dist/dialect/pg_impl.d.ts +9 -10
- package/dist/dialect/pg_impl.js +27 -73
- package/dist/dialect/postgres/postgres.d.ts +4 -4
- package/dist/dialect/postgres/postgres.js +4 -12
- package/dist/dialect/snowflake/snowflake.d.ts +11 -13
- package/dist/dialect/snowflake/snowflake.js +30 -82
- package/dist/dialect/sqlserver/dialect_functions.d.ts +2 -0
- package/dist/dialect/sqlserver/dialect_functions.js +42 -0
- package/dist/dialect/sqlserver/function_overrides.d.ts +2 -0
- package/dist/dialect/sqlserver/function_overrides.js +55 -0
- package/dist/dialect/sqlserver/index.d.ts +1 -0
- package/dist/dialect/sqlserver/index.js +22 -0
- package/dist/dialect/sqlserver/sqlserver.d.ts +101 -0
- package/dist/dialect/sqlserver/sqlserver.js +537 -0
- package/dist/dialect/sqlserver/windows_zones.d.ts +1 -0
- package/dist/dialect/sqlserver/windows_zones.js +613 -0
- package/dist/dialect/standardsql/standardsql.d.ts +11 -16
- package/dist/dialect/standardsql/standardsql.js +22 -73
- package/dist/dialect/trino/trino.d.ts +16 -18
- package/dist/dialect/trino/trino.js +127 -181
- package/dist/index.d.ts +2 -2
- package/dist/index.js +6 -4
- package/dist/lang/ast/expressions/boolean-value.d.ts +24 -0
- package/dist/lang/ast/expressions/boolean-value.js +41 -0
- package/dist/lang/ast/expressions/case.js +7 -0
- package/dist/lang/ast/expressions/expr-alternation-tree.js +11 -0
- package/dist/lang/ast/expressions/expr-cast.js +5 -0
- package/dist/lang/ast/expressions/expr-coalesce.js +4 -0
- package/dist/lang/ast/expressions/expr-func.js +13 -2
- package/dist/lang/ast/expressions/expr-minus.js +5 -2
- package/dist/lang/ast/expressions/expr-null.js +4 -0
- package/dist/lang/ast/expressions/pick-when.js +7 -0
- package/dist/lang/ast/field-space/index-field-space.js +13 -1
- package/dist/lang/ast/field-space/query-spaces.js +11 -0
- package/dist/lang/ast/query-builders/reduce-builder.js +1 -1
- package/dist/lang/ast/query-items/field-declaration.d.ts +5 -0
- package/dist/lang/ast/query-items/field-declaration.js +22 -16
- package/dist/lang/ast/query-items/field-references.d.ts +6 -0
- package/dist/lang/ast/query-items/field-references.js +23 -0
- package/dist/lang/ast/query-properties/filters.js +3 -1
- package/dist/lang/ast/source-elements/named-source.js +0 -2
- package/dist/lang/ast/source-elements/sql-source.js +0 -3
- package/dist/lang/ast/source-elements/table-source.js +1 -2
- package/dist/lang/ast/statements/import-statement.js +17 -0
- package/dist/lang/ast/types/expression-def.js +17 -2
- package/dist/lang/ast/types/malloy-element.d.ts +24 -8
- package/dist/lang/ast/types/malloy-element.js +63 -44
- package/dist/lang/ast/view-elements/reference-view.js +4 -0
- package/dist/lang/ast/view-elements/refine-utils.js +1 -0
- package/dist/lang/composite-source-utils.js +10 -17
- package/dist/lang/parse-log.d.ts +12 -0
- package/dist/lang/parse-log.js +2 -0
- package/dist/lang/parse-malloy.d.ts +17 -2
- package/dist/lang/parse-malloy.js +48 -14
- package/dist/lang/parse-tree-walkers/find-external-references.d.ts +3 -3
- package/dist/lang/parse-tree-walkers/find-external-references.js +17 -16
- package/dist/lang/test/test-translator.d.ts +11 -1
- package/dist/lang/test/test-translator.js +51 -3
- package/dist/model/expression_compiler.js +9 -8
- package/dist/model/filter_compilers.js +13 -12
- package/dist/model/given_binding.d.ts +8 -0
- package/dist/model/given_binding.js +13 -0
- package/dist/model/index.d.ts +1 -1
- package/dist/model/index.js +2 -1
- package/dist/model/query_query.d.ts +3 -1
- package/dist/model/query_query.js +157 -139
- package/dist/model/source_def_utils.d.ts +7 -1
- package/dist/model/source_def_utils.js +20 -0
- package/dist/model/sql_compiled.d.ts +19 -20
- package/dist/model/sql_compiled.js +29 -17
- package/dist/test/index.js +16 -8
- package/dist/test/matchers.d.ts +1 -1
- package/dist/test/matchers.js +1 -1
- package/dist/test/test-models.js +6 -13
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/femto-config.motly +13 -1
- package/package.json +7 -5
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type { Sampling, AtomicTypeDef,
|
|
1
|
+
import type { Sampling, AtomicTypeDef, TypecastExpr, RegexMatchExpr, MeasureTimeExpr, BasicAtomicTypeDef, RecordLiteralNode, ArrayLiteralNode, TimestampUnit, ATimestampTypeDef, ExtractUnit } from '../../model/malloy_types';
|
|
2
2
|
import type { DialectFunctionOverloadDef } from '../functions';
|
|
3
3
|
import type { CompiledOrderBy, DialectFieldList, IntegerTypeMapping, OrderByRequest, QueryInfo } from '../dialect';
|
|
4
|
-
import { Dialect, type LateralJoinExpression } from '../dialect';
|
|
4
|
+
import { CivilTime, Dialect, type LateralJoinExpression } from '../dialect';
|
|
5
5
|
export declare class StandardSQLDialect extends Dialect {
|
|
6
6
|
name: string;
|
|
7
7
|
stringLiteralStyle: "backslash";
|
|
@@ -36,10 +36,6 @@ export declare class StandardSQLDialect extends Dialect {
|
|
|
36
36
|
private bqRejectBacktick;
|
|
37
37
|
sqlQuoteIdentifier(identifier: string): string;
|
|
38
38
|
tablePathBareIdentRegex: RegExp;
|
|
39
|
-
needsCivilTimeComputation(typeDef: AtomicTypeDef, truncateTo: TimestampUnit | undefined, offsetUnit: TimestampUnit | undefined, qi: QueryInfo): {
|
|
40
|
-
needed: boolean;
|
|
41
|
-
tz: string | undefined;
|
|
42
|
-
};
|
|
43
39
|
sqlGroupSetTable(groupSetCount: number): string;
|
|
44
40
|
sqlAnyValue(groupSet: number, fieldName: string): string;
|
|
45
41
|
sqlOrderBy(orderTerms: string[], obr?: OrderByRequest): string;
|
|
@@ -57,19 +53,18 @@ export declare class StandardSQLDialect extends Dialect {
|
|
|
57
53
|
sqlCreateFunctionCombineLastStage(lastStageName: string): string;
|
|
58
54
|
sqlSelectAliasAsStruct(alias: string, dialectFieldList: DialectFieldList): string;
|
|
59
55
|
sqlNowExpr(): string;
|
|
60
|
-
|
|
61
|
-
sqlConvertToCivilTime(expr: string, timezone: string, _typeDef:
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
sqlOffsetTime(expr: string, op: '+' | '-', magnitude: string, unit: TimestampUnit, typeDef: AtomicTypeDef, inCivilTime: boolean, _timezone?: string): string;
|
|
56
|
+
sqlCivilExtract(expr: string, units: ExtractUnit, _civilType: CivilTime): string;
|
|
57
|
+
sqlConvertToCivilTime(expr: string, timezone: string, _typeDef: ATimestampTypeDef): string;
|
|
58
|
+
sqlConvertFromCivilTime(expr: string, timezone: string, _destTypeDef: ATimestampTypeDef): string;
|
|
59
|
+
sqlTruncate(expr: string, unit: TimestampUnit, civilType: CivilTime): string;
|
|
60
|
+
sqlOffsetTime(expr: string, op: '+' | '-', magnitude: string, unit: TimestampUnit, civilType: CivilTime): string;
|
|
61
|
+
sqlCivilToDate(expr: string): string;
|
|
62
|
+
sqlDateToCivil(expr: string): string;
|
|
68
63
|
ignoreInProject(fieldName: string): boolean;
|
|
69
|
-
sqlCast(
|
|
64
|
+
sqlCast(_qi: QueryInfo, cast: TypecastExpr): string;
|
|
70
65
|
sqlRegexpMatch(match: RegexMatchExpr): string;
|
|
71
66
|
sqlDateLiteral(_qi: QueryInfo, literal: string): string;
|
|
72
|
-
|
|
67
|
+
sqlCivilLiteral(literal: string): string;
|
|
73
68
|
sqlTimestamptzLiteral(_qi: QueryInfo, _literal: string, _timezone: string): string;
|
|
74
69
|
sqlMeasureTimeExpr(measure: MeasureTimeExpr): string;
|
|
75
70
|
sqlSampleTable(tableSQL: string, sample: Sampling | undefined): string;
|
|
@@ -26,15 +26,6 @@ const extractMap = {
|
|
|
26
26
|
'day_of_week': 'dayofweek',
|
|
27
27
|
'day_of_year': 'dayofyear',
|
|
28
28
|
};
|
|
29
|
-
/**
|
|
30
|
-
* Return a non UTC timezone, if one was specificed.
|
|
31
|
-
*/
|
|
32
|
-
function qtz(qi) {
|
|
33
|
-
const tz = qi.queryTimezone;
|
|
34
|
-
if (tz && tz !== 'UTC') {
|
|
35
|
-
return tz;
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
29
|
const bqToMalloyTypes = {
|
|
39
30
|
'DATE': { type: 'date' },
|
|
40
31
|
'STRING': { type: 'string' },
|
|
@@ -124,17 +115,6 @@ class StandardSQLDialect extends dialect_1.Dialect {
|
|
|
124
115
|
this.bqRejectBacktick(identifier, 'identifier');
|
|
125
116
|
return super.sqlQuoteIdentifier(identifier);
|
|
126
117
|
}
|
|
127
|
-
needsCivilTimeComputation(typeDef, truncateTo, offsetUnit, qi) {
|
|
128
|
-
// In addition to using "civil" space for units where a query time zone is
|
|
129
|
-
// set, BigQuery also uses civil space for unit operations not supported
|
|
130
|
-
// by the TIMESTAMP functions.
|
|
131
|
-
const calendarUnits = ['day', 'week', 'month', 'quarter', 'year'];
|
|
132
|
-
const isCalendarTruncate = truncateTo !== undefined && calendarUnits.includes(truncateTo);
|
|
133
|
-
const isCalendarOffset = offsetUnit !== undefined && calendarUnits.includes(offsetUnit);
|
|
134
|
-
const needed = malloy_types_1.TD.isAnyTimestamp(typeDef) && (isCalendarTruncate || isCalendarOffset);
|
|
135
|
-
const tz = needed ? qtz(qi) || 'UTC' : undefined;
|
|
136
|
-
return { needed, tz };
|
|
137
|
-
}
|
|
138
118
|
sqlGroupSetTable(groupSetCount) {
|
|
139
119
|
return `CROSS JOIN (SELECT row_number() OVER() -1 group_set FROM UNNEST(GENERATE_ARRAY(0,${groupSetCount},1)))`;
|
|
140
120
|
}
|
|
@@ -249,64 +229,38 @@ ${(0, utils_1.indent)(sql)}
|
|
|
249
229
|
sqlNowExpr() {
|
|
250
230
|
return 'CURRENT_TIMESTAMP()';
|
|
251
231
|
}
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
const tz = malloy_types_1.TD.isAnyTimestamp(te.e.typeDef) && qtz(qi);
|
|
255
|
-
const tzAdd = tz ? ` AT TIME ZONE ${this.sqlTimezoneLiteral(tz)}` : '';
|
|
256
|
-
return `EXTRACT(${extractTo} FROM ${te.e.sql}${tzAdd})`;
|
|
232
|
+
sqlCivilExtract(expr, units, _civilType) {
|
|
233
|
+
return `EXTRACT(${extractMap[units] || units} FROM ${expr})`;
|
|
257
234
|
}
|
|
235
|
+
// Civil time is a DATETIME, which has no zone
|
|
258
236
|
sqlConvertToCivilTime(expr, timezone, _typeDef) {
|
|
259
|
-
|
|
260
|
-
return {
|
|
261
|
-
sql: `DATETIME(${expr}, ${this.sqlTimezoneLiteral(timezone)})`,
|
|
262
|
-
typeDef: { type: 'timestamp' },
|
|
263
|
-
};
|
|
237
|
+
return `DATETIME(${expr}, ${this.sqlTimezoneLiteral(timezone)})`;
|
|
264
238
|
}
|
|
265
239
|
sqlConvertFromCivilTime(expr, timezone, _destTypeDef) {
|
|
266
240
|
return `TIMESTAMP(${expr}, ${this.sqlTimezoneLiteral(timezone)})`;
|
|
267
241
|
}
|
|
268
|
-
sqlTruncate(expr, unit,
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
}
|
|
277
|
-
// TIMESTAMP truncation with optional timezone
|
|
278
|
-
const tzParam = timezone ? `, ${this.sqlTimezoneLiteral(timezone)}` : '';
|
|
279
|
-
return `TIMESTAMP_TRUNC(${expr}, ${unit}${tzParam})`;
|
|
280
|
-
}
|
|
281
|
-
sqlOffsetTime(expr, op, magnitude, unit, typeDef, inCivilTime, _timezone) {
|
|
282
|
-
if (inCivilTime) {
|
|
283
|
-
// Operating on DATETIME (civil time)
|
|
284
|
-
const funcName = op === '+' ? 'DATETIME_ADD' : 'DATETIME_SUB';
|
|
285
|
-
return `${funcName}(${expr}, INTERVAL ${magnitude} ${unit})`;
|
|
286
|
-
}
|
|
287
|
-
// Operating on DATE or TIMESTAMP
|
|
288
|
-
const baseType = typeDef.type;
|
|
289
|
-
if (baseType === 'date') {
|
|
290
|
-
const funcName = op === '+' ? 'DATE_ADD' : 'DATE_SUB';
|
|
291
|
-
return `${funcName}(${expr}, INTERVAL ${magnitude} ${unit})`;
|
|
292
|
-
}
|
|
293
|
-
// TIMESTAMP with sub-day units only (calendar units go through civil time)
|
|
294
|
-
const funcName = op === '+' ? 'TIMESTAMP_ADD' : 'TIMESTAMP_SUB';
|
|
242
|
+
sqlTruncate(expr, unit, civilType) {
|
|
243
|
+
return civilType === dialect_1.CivilTime.Date
|
|
244
|
+
? `DATE_TRUNC(${expr}, ${unit})`
|
|
245
|
+
: `DATETIME_TRUNC(${expr}, ${unit})`;
|
|
246
|
+
}
|
|
247
|
+
sqlOffsetTime(expr, op, magnitude, unit, civilType) {
|
|
248
|
+
const funcType = civilType === dialect_1.CivilTime.Date ? 'DATE' : 'DATETIME';
|
|
249
|
+
const funcName = `${funcType}_${op === '+' ? 'ADD' : 'SUB'}`;
|
|
295
250
|
return `${funcName}(${expr}, INTERVAL ${magnitude} ${unit})`;
|
|
296
251
|
}
|
|
252
|
+
sqlCivilToDate(expr) {
|
|
253
|
+
return `DATE(${expr})`;
|
|
254
|
+
}
|
|
255
|
+
sqlDateToCivil(expr) {
|
|
256
|
+
return `DATETIME(${expr})`;
|
|
257
|
+
}
|
|
297
258
|
ignoreInProject(fieldName) {
|
|
298
259
|
return fieldName === '_PARTITIONTIME';
|
|
299
260
|
}
|
|
300
|
-
sqlCast(
|
|
301
|
-
const {
|
|
302
|
-
const tz = qtz(qi);
|
|
261
|
+
sqlCast(_qi, cast) {
|
|
262
|
+
const { srcTypeDef, dstTypeDef, dstSQLType } = this.sqlCastPrep(cast);
|
|
303
263
|
const src = cast.e.sql || '';
|
|
304
|
-
if (op === 'timestamp::date' && tz) {
|
|
305
|
-
return `DATE(${src},${this.sqlTimezoneLiteral(tz)})`;
|
|
306
|
-
}
|
|
307
|
-
if (op === 'date::timestamp' && tz) {
|
|
308
|
-
return `TIMESTAMP(${src}, ${this.sqlTimezoneLiteral(tz)})`;
|
|
309
|
-
}
|
|
310
264
|
if (!malloy_types_1.TD.eq(srcTypeDef, dstTypeDef)) {
|
|
311
265
|
const castFunc = cast.safe ? 'SAFE_CAST' : 'CAST';
|
|
312
266
|
return `${castFunc}(${src} AS ${dstSQLType})`;
|
|
@@ -319,13 +273,8 @@ ${(0, utils_1.indent)(sql)}
|
|
|
319
273
|
sqlDateLiteral(_qi, literal) {
|
|
320
274
|
return `DATE('${literal}')`;
|
|
321
275
|
}
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
const tz = timezone || qtz(qi);
|
|
325
|
-
if (tz && tz !== 'UTC') {
|
|
326
|
-
timestampArgs += `,${this.sqlTimezoneLiteral(tz)}`;
|
|
327
|
-
}
|
|
328
|
-
return `TIMESTAMP(${timestampArgs})`;
|
|
276
|
+
sqlCivilLiteral(literal) {
|
|
277
|
+
return `DATETIME '${literal}'`;
|
|
329
278
|
}
|
|
330
279
|
sqlTimestamptzLiteral(_qi, _literal, _timezone) {
|
|
331
280
|
throw new Error('BigQuery does not support timestamptz');
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { Expr, Sampling, AtomicTypeDef, ATimestampTypeDef, TypecastExpr, RegexMatchExpr, MeasureTimeExpr, TimeExtractExpr, BasicAtomicTypeDef, RecordLiteralNode, OrderBy } from '../../model/malloy_types';
|
|
1
|
+
import type { Expr, Sampling, AtomicTypeDef, ATimestampTypeDef, TypecastExpr, RegexMatchExpr, MeasureTimeExpr, TimeExtractExpr, BasicAtomicTypeDef, RecordLiteralNode, OrderBy, TimestampUnit, ExtractUnit, TimeExpr } from '../../model/malloy_types';
|
|
2
2
|
import type { DialectFunctionOverloadDef } from '../functions';
|
|
3
|
-
import type { CompiledOrderBy, DialectFieldList, OrderByClauseType, QueryInfo } from '../dialect';
|
|
3
|
+
import type { CivilTime, CompiledOrderBy, DialectFieldList, OrderByClauseType, QueryInfo, TimeOffset } from '../dialect';
|
|
4
4
|
import { PostgresBase } from '../pg_impl';
|
|
5
5
|
export declare class TrinoDialect extends PostgresBase {
|
|
6
6
|
name: string;
|
|
@@ -52,14 +52,11 @@ export declare class TrinoDialect extends PostgresBase {
|
|
|
52
52
|
sqlCreateFunctionCombineLastStage(lastStageName: string, fieldList: DialectFieldList, orderBy: OrderBy[] | undefined): string;
|
|
53
53
|
sqlSelectAliasAsStruct(alias: string, fieldList: DialectFieldList): string;
|
|
54
54
|
keywords: string[];
|
|
55
|
-
sqlConvertToCivilTime(expr: string, timezone: string, typeDef:
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
sqlTruncate(expr: string, unit: string, _typeDef: AtomicTypeDef, _inCivilTime: boolean, _timezone?: string): string;
|
|
61
|
-
sqlOffsetTime(expr: string, op: '+' | '-', magnitude: string, unit: string, _typeDef: AtomicTypeDef, _inCivilTime: boolean, _timezone?: string): string;
|
|
62
|
-
sqlCast(qi: QueryInfo, cast: TypecastExpr): string;
|
|
55
|
+
sqlConvertToCivilTime(expr: string, timezone: string, typeDef: ATimestampTypeDef): string;
|
|
56
|
+
sqlConvertFromCivilTime(expr: string, timezone: string, destTypeDef: ATimestampTypeDef): string;
|
|
57
|
+
sqlTruncate(expr: string, unit: TimestampUnit, _civilType: CivilTime): string;
|
|
58
|
+
sqlOffsetTime(expr: string, op: '+' | '-', magnitude: string, unit: TimestampUnit, _civilType: CivilTime): string;
|
|
59
|
+
sqlCast(_qi: QueryInfo, cast: TypecastExpr): string;
|
|
63
60
|
sqlRegexpMatch(reCmp: RegexMatchExpr): string;
|
|
64
61
|
sqlMeasureTimeExpr(mf: MeasureTimeExpr): string;
|
|
65
62
|
sqlSampleTable(tableSQL: string, sample: Sampling | undefined): string;
|
|
@@ -77,9 +74,8 @@ export declare class TrinoDialect extends PostgresBase {
|
|
|
77
74
|
sqlStringAggDistinct(distinctKey: string, valueSQL: string, separatorSQL: string): string;
|
|
78
75
|
validateTypeName(sqlType: string): boolean;
|
|
79
76
|
sqlDateLiteral(_qi: QueryInfo, literal: string): string;
|
|
80
|
-
sqlTimestampLiteral(qi: QueryInfo, literal: string, timezone: string | undefined): string;
|
|
81
77
|
sqlTimestamptzLiteral(_qi: QueryInfo, literal: string, timezone: string): string;
|
|
82
|
-
|
|
78
|
+
sqlCivilExtract(expr: string, units: ExtractUnit, _civilType: CivilTime): string;
|
|
83
79
|
sqlLiteralRecord(lit: RecordLiteralNode): string;
|
|
84
80
|
}
|
|
85
81
|
export declare class PrestoDialect extends TrinoDialect {
|
|
@@ -90,13 +86,15 @@ export declare class PrestoDialect extends TrinoDialect {
|
|
|
90
86
|
sqlDateLiteral(_qi: QueryInfo, literal: string): string;
|
|
91
87
|
sqlTimestampLiteral(qi: QueryInfo, literal: string, timezone: string | undefined): string;
|
|
92
88
|
sqlTimestamptzLiteral(_qi: QueryInfo, literal: string, timezone: string): string;
|
|
93
|
-
sqlConvertToCivilTime(
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
89
|
+
sqlConvertToCivilTime(): string;
|
|
90
|
+
sqlConvertFromCivilTime(): string;
|
|
91
|
+
/** The instant `expr`, showing the clock of `timezone` */
|
|
92
|
+
private inZone;
|
|
93
|
+
/** An instant from inZone, as a value of `typeDef` */
|
|
94
|
+
private fromZone;
|
|
99
95
|
sqlTimeExtractExpr(qi: QueryInfo, from: TimeExtractExpr): string;
|
|
96
|
+
sqlTruncAndOffset(baseExpr: TimeExpr, qi: QueryInfo, truncateTo?: TimestampUnit, offset?: TimeOffset): string;
|
|
97
|
+
sqlTimeCast(qi: QueryInfo, cast: TypecastExpr): string | undefined;
|
|
100
98
|
sqlUnnestAlias(source: string, alias: string, _fieldList: DialectFieldList, needDistinctKey: boolean, isArray: boolean, _isInNestedPipeline: boolean): string;
|
|
101
99
|
getDialectFunctions(): {
|
|
102
100
|
[name: string]: DialectFunctionOverloadDef[];
|
|
@@ -23,15 +23,6 @@ function timestampMeasureable(units) {
|
|
|
23
23
|
'day',
|
|
24
24
|
].includes(units);
|
|
25
25
|
}
|
|
26
|
-
/**
|
|
27
|
-
* Return a non UTC timezone, if one was specificed.
|
|
28
|
-
*/
|
|
29
|
-
function qtz(qi) {
|
|
30
|
-
const tz = qi.queryTimezone;
|
|
31
|
-
if (tz && tz !== 'UTC') {
|
|
32
|
-
return tz;
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
26
|
const trinoToMalloyTypes = {
|
|
36
27
|
'varchar': { type: 'string' },
|
|
37
28
|
'integer': { type: 'number', numberType: 'integer' },
|
|
@@ -57,6 +48,33 @@ const trinoToMalloyTypes = {
|
|
|
57
48
|
// TIME
|
|
58
49
|
// GEOGRAPHY
|
|
59
50
|
};
|
|
51
|
+
function trinoTrunc(expr, unit) {
|
|
52
|
+
// Weeks start on Monday here, so truncate the following day
|
|
53
|
+
if (unit === 'week') {
|
|
54
|
+
return `(DATE_TRUNC('${unit}', (${expr} + INTERVAL '1' DAY)) - INTERVAL '1' DAY)`;
|
|
55
|
+
}
|
|
56
|
+
return `DATE_TRUNC('${unit}', ${expr})`;
|
|
57
|
+
}
|
|
58
|
+
function trinoDateAdd(expr, op, magnitude, unit) {
|
|
59
|
+
// DATE_ADD has no quarter or week
|
|
60
|
+
let offsetUnit = unit;
|
|
61
|
+
let offsetMag = magnitude;
|
|
62
|
+
if (unit === 'quarter') {
|
|
63
|
+
offsetUnit = 'month';
|
|
64
|
+
offsetMag = `${magnitude}*3`;
|
|
65
|
+
}
|
|
66
|
+
else if (unit === 'week') {
|
|
67
|
+
offsetUnit = 'day';
|
|
68
|
+
offsetMag = `${magnitude}*7`;
|
|
69
|
+
}
|
|
70
|
+
const n = op === '-' ? `(${offsetMag})*-1` : offsetMag;
|
|
71
|
+
return `DATE_ADD('${offsetUnit}', ${n}, ${expr})`;
|
|
72
|
+
}
|
|
73
|
+
function trinoExtract(expr, units) {
|
|
74
|
+
const extracted = `EXTRACT(${pg_impl_1.timeExtractMap[units] || units} FROM ${expr})`;
|
|
75
|
+
// Trino counts the days of a week from 1 on Monday
|
|
76
|
+
return units === 'day_of_week' ? `mod(${extracted}+1,7)` : extracted;
|
|
77
|
+
}
|
|
60
78
|
class TrinoDialect extends pg_impl_1.PostgresBase {
|
|
61
79
|
constructor() {
|
|
62
80
|
super(...arguments);
|
|
@@ -339,87 +357,34 @@ ${(0, utils_1.indent)(sql)}
|
|
|
339
357
|
const definitions = this.buildTypeExpression(fieldList);
|
|
340
358
|
return `CAST(ROW(${fields}) as ROW(${definitions}))`;
|
|
341
359
|
}
|
|
360
|
+
// Civil time is a TIMESTAMP, which Trino keeps without a zone
|
|
342
361
|
sqlConvertToCivilTime(expr, timezone, typeDef) {
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
// TIMESTAMP (UTC wall clock) → TIMESTAMPTZ in query timezone
|
|
347
|
-
return {
|
|
348
|
-
sql: `at_timezone(with_timezone(${expr}, 'UTC'), ${this.sqlTimezoneLiteral(timezone)})`,
|
|
349
|
-
typeDef: { type: 'timestamptz' },
|
|
350
|
-
};
|
|
362
|
+
const tz = this.sqlTimezoneLiteral(timezone);
|
|
363
|
+
if (malloy_types_1.TD.isTimestamptz(typeDef)) {
|
|
364
|
+
return `CAST(at_timezone(${expr}, ${tz}) AS TIMESTAMP)`;
|
|
351
365
|
}
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
typeDef: { type: 'timestamptz' },
|
|
356
|
-
};
|
|
366
|
+
return timezone === 'UTC'
|
|
367
|
+
? expr
|
|
368
|
+
: `CAST(at_timezone(with_timezone(${expr}, 'UTC'), ${tz}) AS TIMESTAMP)`;
|
|
357
369
|
}
|
|
358
|
-
sqlConvertFromCivilTime(expr,
|
|
359
|
-
|
|
360
|
-
if (destTypeDef
|
|
361
|
-
|
|
362
|
-
return expr;
|
|
363
|
-
}
|
|
364
|
-
// To TIMESTAMP: convert to UTC and cast to plain TIMESTAMP
|
|
365
|
-
return `CAST(at_timezone(${expr}, 'UTC') AS TIMESTAMP)`;
|
|
366
|
-
}
|
|
367
|
-
sqlTruncate(expr, unit, _typeDef, _inCivilTime, _timezone) {
|
|
368
|
-
// Trino starts weeks on Monday, Malloy wants Sunday
|
|
369
|
-
// Add 1 day before truncating, subtract 1 day after
|
|
370
|
-
if (unit === 'week') {
|
|
371
|
-
return `(DATE_TRUNC('${unit}', (${expr} + INTERVAL '1' DAY)) - INTERVAL '1' DAY)`;
|
|
370
|
+
sqlConvertFromCivilTime(expr, timezone, destTypeDef) {
|
|
371
|
+
const tz = this.sqlTimezoneLiteral(timezone);
|
|
372
|
+
if (malloy_types_1.TD.isTimestamptz(destTypeDef)) {
|
|
373
|
+
return `with_timezone(${expr}, ${tz})`;
|
|
372
374
|
}
|
|
373
|
-
return
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
if (unit === 'quarter') {
|
|
380
|
-
offsetUnit = 'month';
|
|
381
|
-
offsetMag = `${magnitude}*3`;
|
|
382
|
-
}
|
|
383
|
-
else if (unit === 'week') {
|
|
384
|
-
offsetUnit = 'day';
|
|
385
|
-
offsetMag = `${magnitude}*7`;
|
|
386
|
-
}
|
|
387
|
-
// Handle subtraction by negating
|
|
388
|
-
const n = op === '-' ? `(${offsetMag})*-1` : offsetMag;
|
|
389
|
-
return `DATE_ADD('${offsetUnit}', ${n}, ${expr})`;
|
|
375
|
+
return timezone === 'UTC'
|
|
376
|
+
? expr
|
|
377
|
+
: `CAST(at_timezone(with_timezone(${expr}, ${tz}), 'UTC') AS TIMESTAMP)`;
|
|
378
|
+
}
|
|
379
|
+
sqlTruncate(expr, unit, _civilType) {
|
|
380
|
+
return trinoTrunc(expr, unit);
|
|
390
381
|
}
|
|
391
|
-
|
|
382
|
+
sqlOffsetTime(expr, op, magnitude, unit, _civilType) {
|
|
383
|
+
return trinoDateAdd(expr, op, magnitude, unit);
|
|
384
|
+
}
|
|
385
|
+
sqlCast(_qi, cast) {
|
|
392
386
|
const { srcTypeDef, dstTypeDef, dstSQLType } = this.sqlCastPrep(cast);
|
|
393
|
-
const tz = qtz(qi);
|
|
394
387
|
const expr = cast.e.sql || '';
|
|
395
|
-
// Timezone-aware casts when query timezone is set
|
|
396
|
-
if (tz && srcTypeDef && dstTypeDef) {
|
|
397
|
-
// TIMESTAMP → DATE: interpret as UTC, convert to query timezone
|
|
398
|
-
if (malloy_types_1.TD.isTimestamp(srcTypeDef) && malloy_types_1.TD.isDate(dstTypeDef)) {
|
|
399
|
-
return `CAST(at_timezone(with_timezone(${expr}, 'UTC'), ${this.sqlTimezoneLiteral(tz)}) AS DATE)`;
|
|
400
|
-
}
|
|
401
|
-
// TIMESTAMPTZ → DATE: convert to query timezone
|
|
402
|
-
if (malloy_types_1.TD.isTimestamptz(srcTypeDef) && malloy_types_1.TD.isDate(dstTypeDef)) {
|
|
403
|
-
return `CAST(at_timezone(${expr}, ${this.sqlTimezoneLiteral(tz)}) AS DATE)`;
|
|
404
|
-
}
|
|
405
|
-
// DATE → TIMESTAMP: interpret date in query timezone, return UTC wall clock
|
|
406
|
-
if (malloy_types_1.TD.isDate(srcTypeDef) && malloy_types_1.TD.isTimestamp(dstTypeDef)) {
|
|
407
|
-
return `CAST(at_timezone(with_timezone(CAST(${expr} AS TIMESTAMP), ${this.sqlTimezoneLiteral(tz)}), 'UTC') AS TIMESTAMP)`;
|
|
408
|
-
}
|
|
409
|
-
// DATE → TIMESTAMPTZ: interpret date in query timezone
|
|
410
|
-
if (malloy_types_1.TD.isDate(srcTypeDef) && malloy_types_1.TD.isTimestamptz(dstTypeDef)) {
|
|
411
|
-
return `with_timezone(CAST(${expr} AS TIMESTAMP), ${this.sqlTimezoneLiteral(tz)})`;
|
|
412
|
-
}
|
|
413
|
-
// TIMESTAMPTZ → TIMESTAMP: convert to query timezone wall clock
|
|
414
|
-
if (malloy_types_1.TD.isTimestamptz(srcTypeDef) && malloy_types_1.TD.isTimestamp(dstTypeDef)) {
|
|
415
|
-
return `CAST(at_timezone(${expr}, ${this.sqlTimezoneLiteral(tz)}) AS TIMESTAMP)`;
|
|
416
|
-
}
|
|
417
|
-
// TIMESTAMP → TIMESTAMPTZ: interpret TIMESTAMP as being in query timezone
|
|
418
|
-
if (malloy_types_1.TD.isTimestamp(srcTypeDef) && malloy_types_1.TD.isTimestamptz(dstTypeDef)) {
|
|
419
|
-
return `with_timezone(${expr}, ${this.sqlTimezoneLiteral(tz)})`;
|
|
420
|
-
}
|
|
421
|
-
}
|
|
422
|
-
// No special handling needed, or no query timezone
|
|
423
388
|
if (!malloy_types_1.TD.eq(srcTypeDef, dstTypeDef)) {
|
|
424
389
|
const castFunc = cast.safe ? 'TRY_CAST' : 'CAST';
|
|
425
390
|
return `${castFunc}(${expr} AS ${dstSQLType})`;
|
|
@@ -567,37 +532,12 @@ ${(0, utils_1.indent)(sql)}
|
|
|
567
532
|
sqlDateLiteral(_qi, literal) {
|
|
568
533
|
return `DATE '${literal}'`;
|
|
569
534
|
}
|
|
570
|
-
sqlTimestampLiteral(qi, literal, timezone) {
|
|
571
|
-
const tz = timezone || qtz(qi);
|
|
572
|
-
if (tz) {
|
|
573
|
-
// Interpret wall clock time in timezone, convert to UTC wall clock, cast to TIMESTAMP
|
|
574
|
-
return `CAST(at_timezone(with_timezone(TIMESTAMP '${literal}', ${this.sqlTimezoneLiteral(tz)}), 'UTC') AS TIMESTAMP)`;
|
|
575
|
-
}
|
|
576
|
-
return `TIMESTAMP '${literal}'`;
|
|
577
|
-
}
|
|
578
535
|
sqlTimestamptzLiteral(_qi, literal, timezone) {
|
|
579
536
|
// Use with_timezone to create a TIMESTAMP WITH TIME ZONE
|
|
580
537
|
return `with_timezone(TIMESTAMP '${literal}', ${this.sqlTimezoneLiteral(timezone)})`;
|
|
581
538
|
}
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
let extractFrom = from.e.sql || '';
|
|
585
|
-
if (malloy_types_1.TD.isAnyTimestamp(from.e.typeDef)) {
|
|
586
|
-
const tz = qtz(qi);
|
|
587
|
-
if (tz) {
|
|
588
|
-
// Convert both TIMESTAMP and TIMESTAMPTZ to query timezone for extraction
|
|
589
|
-
if (from.e.typeDef.type === 'timestamp') {
|
|
590
|
-
// TIMESTAMP: interpret as UTC, convert to query timezone
|
|
591
|
-
extractFrom = `at_timezone(with_timezone(${extractFrom}, 'UTC'), ${this.sqlTimezoneLiteral(tz)})`;
|
|
592
|
-
}
|
|
593
|
-
else {
|
|
594
|
-
// TIMESTAMPTZ: convert to query timezone
|
|
595
|
-
extractFrom = `at_timezone(${extractFrom}, ${this.sqlTimezoneLiteral(tz)})`;
|
|
596
|
-
}
|
|
597
|
-
}
|
|
598
|
-
}
|
|
599
|
-
const extracted = `EXTRACT(${pgUnits} FROM ${extractFrom})`;
|
|
600
|
-
return from.units === 'day_of_week' ? `mod(${extracted}+1,7)` : extracted;
|
|
539
|
+
sqlCivilExtract(expr, units, _civilType) {
|
|
540
|
+
return trinoExtract(expr, units);
|
|
601
541
|
}
|
|
602
542
|
sqlLiteralRecord(lit) {
|
|
603
543
|
var _a, _b;
|
|
@@ -630,91 +570,97 @@ class PrestoDialect extends TrinoDialect {
|
|
|
630
570
|
return `DATE '${literal}'`;
|
|
631
571
|
}
|
|
632
572
|
sqlTimestampLiteral(qi, literal, timezone) {
|
|
633
|
-
const tz = timezone
|
|
634
|
-
if (tz) {
|
|
635
|
-
return `
|
|
573
|
+
const tz = timezone !== null && timezone !== void 0 ? timezone : (0, dialect_1.queryZone)(qi);
|
|
574
|
+
if (tz === 'UTC') {
|
|
575
|
+
return `TIMESTAMP '${literal}'`;
|
|
636
576
|
}
|
|
637
|
-
return `TIMESTAMP '${literal}'`;
|
|
577
|
+
return `CAST(TIMESTAMP '${literal} ${this.checkedTimezoneName(tz)}' AS TIMESTAMP)`;
|
|
638
578
|
}
|
|
639
579
|
sqlTimestamptzLiteral(_qi, literal, timezone) {
|
|
640
580
|
return `TIMESTAMP '${literal} ${this.checkedTimezoneName(timezone)}'`;
|
|
641
581
|
}
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
582
|
+
/*
|
|
583
|
+
* Presto cannot meet the civil contract: its only way to read a date and
|
|
584
|
+
* time of day as an instant in a zone is to parse a string, which fails
|
|
585
|
+
* on a time the zone skips. So Presto never converts to civil time. It
|
|
586
|
+
* places an instant in the zone as a TIMESTAMP WITH TIME ZONE, whose
|
|
587
|
+
* functions read the clock in that zone and resolve any skipped or
|
|
588
|
+
* repeated time themselves. A Presto TIMESTAMP is an instant shown in the
|
|
589
|
+
* session zone, which is UTC.
|
|
590
|
+
*/
|
|
591
|
+
sqlConvertToCivilTime() {
|
|
592
|
+
throw new Error('Presto has no civil time');
|
|
593
|
+
}
|
|
594
|
+
sqlConvertFromCivilTime() {
|
|
595
|
+
throw new Error('Presto has no civil time');
|
|
596
|
+
}
|
|
597
|
+
/** The instant `expr`, showing the clock of `timezone` */
|
|
598
|
+
inZone(expr, typeDef, timezone) {
|
|
599
|
+
if (malloy_types_1.TD.isTimestamp(typeDef) && timezone === 'UTC') {
|
|
652
600
|
return expr;
|
|
653
601
|
}
|
|
654
|
-
return `
|
|
602
|
+
return `(${expr}) AT TIME ZONE ${this.sqlTimezoneLiteral(timezone)}`;
|
|
655
603
|
}
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
// Timezone-aware casts when query timezone is set
|
|
661
|
-
// Presto uses AT TIME ZONE operator instead of Trino's with_timezone/at_timezone functions
|
|
662
|
-
if (tz && srcTypeDef && dstTypeDef) {
|
|
663
|
-
// TIMESTAMP → DATE: interpret as UTC, convert to query timezone
|
|
664
|
-
if (malloy_types_1.TD.isTimestamp(srcTypeDef) && malloy_types_1.TD.isDate(dstTypeDef)) {
|
|
665
|
-
return `CAST((${expr} AT TIME ZONE 'UTC') AT TIME ZONE ${this.sqlTimezoneLiteral(tz)} AS DATE)`;
|
|
666
|
-
}
|
|
667
|
-
// TIMESTAMPTZ → DATE: convert to query timezone
|
|
668
|
-
if (malloy_types_1.TD.isTimestamptz(srcTypeDef) && malloy_types_1.TD.isDate(dstTypeDef)) {
|
|
669
|
-
return `CAST(${expr} AT TIME ZONE ${this.sqlTimezoneLiteral(tz)} AS DATE)`;
|
|
670
|
-
}
|
|
671
|
-
// DATE → TIMESTAMP: interpret date in query timezone, return UTC wall clock
|
|
672
|
-
// Presto doesn't have a way to interpret TIMESTAMP in a non-UTC timezone,
|
|
673
|
-
// so we build a TIMESTAMPTZ literal string and cast it
|
|
674
|
-
if (malloy_types_1.TD.isDate(srcTypeDef) && malloy_types_1.TD.isTimestamp(dstTypeDef)) {
|
|
675
|
-
const tstzLiteral = `CAST(CAST(${expr} AS VARCHAR) || ' 00:00:00 ${this.checkedTimezoneName(tz)}' AS TIMESTAMP WITH TIME ZONE)`;
|
|
676
|
-
return `CAST(${tstzLiteral} AS TIMESTAMP)`;
|
|
677
|
-
}
|
|
678
|
-
// DATE → TIMESTAMPTZ: interpret date in query timezone
|
|
679
|
-
if (malloy_types_1.TD.isDate(srcTypeDef) && malloy_types_1.TD.isTimestamptz(dstTypeDef)) {
|
|
680
|
-
return `CAST(CAST(${expr} AS VARCHAR) || ' 00:00:00 ${this.checkedTimezoneName(tz)}' AS TIMESTAMP WITH TIME ZONE)`;
|
|
681
|
-
}
|
|
682
|
-
// TIMESTAMPTZ → TIMESTAMP: convert to query timezone wall clock
|
|
683
|
-
if (malloy_types_1.TD.isTimestamptz(srcTypeDef) && malloy_types_1.TD.isTimestamp(dstTypeDef)) {
|
|
684
|
-
return `CAST(${expr} AT TIME ZONE ${this.sqlTimezoneLiteral(tz)} AS TIMESTAMP)`;
|
|
685
|
-
}
|
|
686
|
-
// TIMESTAMP → TIMESTAMPTZ: interpret TIMESTAMP as UTC
|
|
687
|
-
if (malloy_types_1.TD.isTimestamp(srcTypeDef) && malloy_types_1.TD.isTimestamptz(dstTypeDef)) {
|
|
688
|
-
return `${expr} AT TIME ZONE 'UTC'`;
|
|
689
|
-
}
|
|
690
|
-
}
|
|
691
|
-
// No special handling needed, or no query timezone
|
|
692
|
-
if (!malloy_types_1.TD.eq(srcTypeDef, dstTypeDef)) {
|
|
693
|
-
const castFunc = cast.safe ? 'TRY_CAST' : 'CAST';
|
|
694
|
-
return `${castFunc}(${expr} AS ${dstSQLType})`;
|
|
604
|
+
/** An instant from inZone, as a value of `typeDef` */
|
|
605
|
+
fromZone(expr, typeDef, timezone) {
|
|
606
|
+
if (malloy_types_1.TD.isTimestamp(typeDef) && timezone !== 'UTC') {
|
|
607
|
+
return `CAST(${expr} AS TIMESTAMP)`;
|
|
695
608
|
}
|
|
696
609
|
return expr;
|
|
697
610
|
}
|
|
698
611
|
sqlTimeExtractExpr(qi, from) {
|
|
699
|
-
const
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
612
|
+
const time = from.e;
|
|
613
|
+
const expr = malloy_types_1.TD.isAnyTimestamp(time.typeDef)
|
|
614
|
+
? this.inZone(time.sql, time.typeDef, (0, dialect_1.queryZone)(qi))
|
|
615
|
+
: time.sql;
|
|
616
|
+
return trinoExtract(expr, from.units);
|
|
617
|
+
}
|
|
618
|
+
sqlTruncAndOffset(baseExpr, qi, truncateTo, offset) {
|
|
619
|
+
const timeType = baseExpr.typeDef;
|
|
620
|
+
// Adding hours, minutes or seconds to an instant needs no zone
|
|
621
|
+
const usesQueryZone = malloy_types_1.TD.isAnyTimestamp(timeType) &&
|
|
622
|
+
(truncateTo !== undefined ||
|
|
623
|
+
(offset !== undefined && (0, malloy_types_1.isDateUnit)(offset.unit)));
|
|
624
|
+
const zone = (0, dialect_1.queryZone)(qi);
|
|
625
|
+
let sql = usesQueryZone
|
|
626
|
+
? this.inZone(baseExpr.sql, timeType, zone)
|
|
627
|
+
: baseExpr.sql;
|
|
628
|
+
if (truncateTo) {
|
|
629
|
+
sql = trinoTrunc(sql, truncateTo);
|
|
630
|
+
}
|
|
631
|
+
if (offset) {
|
|
632
|
+
sql = trinoDateAdd(sql, offset.op, offset.magnitude, offset.unit);
|
|
633
|
+
}
|
|
634
|
+
return usesQueryZone ? this.fromZone(sql, timeType, zone) : sql;
|
|
635
|
+
}
|
|
636
|
+
sqlTimeCast(qi, cast) {
|
|
637
|
+
var _a;
|
|
638
|
+
const { srcTypeDef, dstTypeDef } = this.sqlCastPrep(cast);
|
|
639
|
+
const expr = (_a = cast.e.sql) !== null && _a !== void 0 ? _a : '';
|
|
640
|
+
const zone = (0, dialect_1.queryZone)(qi);
|
|
641
|
+
if (malloy_types_1.TD.isAnyTimestamp(srcTypeDef)) {
|
|
642
|
+
if (malloy_types_1.TD.isDate(dstTypeDef)) {
|
|
643
|
+
return `CAST(${this.inZone(expr, srcTypeDef, zone)} AS DATE)`;
|
|
644
|
+
}
|
|
645
|
+
if (malloy_types_1.TD.isTimestamp(dstTypeDef) && malloy_types_1.TD.isTimestamptz(srcTypeDef)) {
|
|
646
|
+
return `CAST(${expr} AS TIMESTAMP)`;
|
|
647
|
+
}
|
|
648
|
+
if (malloy_types_1.TD.isTimestamptz(dstTypeDef) && malloy_types_1.TD.isTimestamp(srcTypeDef)) {
|
|
649
|
+
return `(${expr}) AT TIME ZONE 'UTC'`;
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
if (malloy_types_1.TD.isDate(srcTypeDef) && malloy_types_1.TD.isAnyTimestamp(dstTypeDef)) {
|
|
653
|
+
if (zone === 'UTC') {
|
|
654
|
+
const midnight = `CAST(${expr} AS TIMESTAMP)`;
|
|
655
|
+
return malloy_types_1.TD.isTimestamp(dstTypeDef)
|
|
656
|
+
? midnight
|
|
657
|
+
: `(${midnight}) AT TIME ZONE 'UTC'`;
|
|
714
658
|
}
|
|
659
|
+
// Fails in a zone which skips the midnight starting the date
|
|
660
|
+
const midnight = `CAST(CAST(${expr} AS VARCHAR) || ' 00:00:00 ${this.checkedTimezoneName(zone)}' AS TIMESTAMP WITH TIME ZONE)`;
|
|
661
|
+
return this.fromZone(midnight, dstTypeDef, zone);
|
|
715
662
|
}
|
|
716
|
-
|
|
717
|
-
return from.units === 'day_of_week' ? `mod(${extracted}+1,7)` : extracted;
|
|
663
|
+
return undefined;
|
|
718
664
|
}
|
|
719
665
|
sqlUnnestAlias(source, alias, _fieldList, needDistinctKey, isArray, _isInNestedPipeline) {
|
|
720
666
|
if (isArray) {
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { DuckDBDialect, StandardSQLDialect, TrinoDialect, PostgresDialect, SnowflakeDialect, MySQLDialect, DatabricksDialect, registerDialect, arg,
|
|
1
|
+
export { DuckDBDialect, StandardSQLDialect, TrinoDialect, PostgresDialect, SnowflakeDialect, MySQLDialect, DatabricksDialect, SQLServerDialect, registerDialect, getDialect, arg, queryZone, overload, minScalar, anyExprType, minAggregate, maxScalar, sql, makeParam, param, variadicParam, literal, spread, Dialect, decodeDottedTablePath, validateDottedTablePath, } from './dialect';
|
|
2
2
|
export type { DialectFieldList, DialectFunctionOverloadDef, QueryInfo, MalloyStandardFunctionImplementations, DefinitionBlueprint, DefinitionBlueprintMap, OverloadedDefinitionBlueprint, DecodeDottedTablePathResult, DottedTablePathOptions, TablePathEscapeStyle, TablePathSegment, ValidateTablePathResult, } from './dialect';
|
|
3
3
|
export type { QueryRecord, StructDef, TableSourceDef, SQLSourceDef, SourceDef, JoinFieldDef, NamedSourceDefs, MalloyQueryData, DateUnit, ExtractUnit, TimestampUnit, TemporalFieldType, QueryData, QueryValue, Expr, FilterCondition, Argument, Parameter, FieldDef, PipeSegment, QueryFieldDef, IndexFieldDef, TurtleDef, SearchValueMapResult, SearchIndexResult, ModelDef, Query, QueryResult, QueryResultDef, QueryRunStats, QueryScalar, NamedQueryDef, NamedModelObject, ExpressionType, FunctionDef, FunctionOverloadDef, FunctionParameterDef, ExpressionValueType, TypeDesc, FunctionParamTypeDesc, DocumentLocation, DocumentRange, DocumentPosition, Sampling, BasicAtomicTypeDef, BasicAtomicDef, AtomicTypeDef, AtomicFieldDef, ArrayDef, ArrayTypeDef, RecordTypeDef, RepeatedRecordTypeDef, RecordDef, RepeatedRecordDef, RecordLiteralNode, StringLiteralNode, ArrayLiteralNode, SourceComponentInfo, DateLiteralNode, TimestampLiteralNode, TimestamptzLiteralNode, TimeLiteralExpr, TypecastExpr, BuildID, BuildManifest, BuildManifestEntry, GivenValue, VirtualMap, } from './model';
|
|
4
4
|
export { isSourceDef, isAtomic, isBasicAtomic, isCompoundArrayData, isJoined, isJoinedSource, isSamplingEnable, isSamplingPercent, isSamplingRows, isRepeatedRecord, isBasicArray, mkArrayDef, mkFieldDef, expressionIsAggregate, expressionIsAnalytic, expressionIsCalculation, expressionIsScalar, expressionIsUngroupedAggregate, indent, composeSQLExpr, isTimestampUnit, isDateUnit, constantExprToSQL, } from './model';
|
|
@@ -25,7 +25,7 @@ export { routeOf, payloadOf, annotationsForRoute, tagFromAnnotations, } from './
|
|
|
25
25
|
/** @deprecated — use the `.annotations` view on a Foundation entity
|
|
26
26
|
* (`entity.annotations.parseAsTag(route)` / `.texts(route)`). */
|
|
27
27
|
export { annotationToTag, annotationToTaglines, } from './api/foundation/annotation';
|
|
28
|
-
export type { BuildGraph, BuildNode, BuildPlan, BuildTarget, BuildTargets, ConnectionBuild, } from './api/foundation';
|
|
28
|
+
export type { BuildGraph, BuildNode, BuildPlan, BuildTarget, BuildTargetOptions, BuildTargets, ConnectionBuild, UnbuildableSource, } from './api/foundation';
|
|
29
29
|
export { PersistSource, EMPTY_BUILD_MANIFEST } from './api/foundation';
|
|
30
30
|
export { Reference } from './api/foundation';
|
|
31
31
|
export type { ReferenceKind } from './api/foundation';
|