@malloydata/malloy 0.0.435 → 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/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 -2
- package/dist/api/foundation/runtime.js +44 -31
- package/dist/api/foundation/types.d.ts +43 -3
- 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 +56 -170
- package/dist/dialect/dialect.js +89 -90
- package/dist/dialect/duckdb/duckdb.d.ts +2 -2
- package/dist/dialect/duckdb/duckdb.js +1 -1
- package/dist/dialect/index.d.ts +1 -1
- package/dist/dialect/index.js +2 -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/sqlserver.d.ts +12 -13
- package/dist/dialect/sqlserver/sqlserver.js +46 -47
- 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 +2 -2
- 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/statements/import-statement.js +13 -0
- package/dist/lang/ast/types/expression-def.js +17 -2
- package/dist/lang/ast/types/malloy-element.d.ts +24 -1
- package/dist/lang/ast/types/malloy-element.js +63 -26
- 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/test/test-translator.d.ts +2 -1
- package/dist/lang/test/test-translator.js +37 -3
- package/dist/model/expression_compiler.js +8 -7
- 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/sql_compiled.d.ts +19 -20
- package/dist/model/sql_compiled.js +29 -17
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +4 -4
|
@@ -54,6 +54,7 @@ const sqlServerToMalloyTypes = {
|
|
|
54
54
|
'datetime': { type: 'timestamp' },
|
|
55
55
|
'datetime2': { type: 'timestamp' },
|
|
56
56
|
'smalldatetime': { type: 'timestamp' },
|
|
57
|
+
'datetimeoffset': { type: 'timestamptz' },
|
|
57
58
|
};
|
|
58
59
|
function parseSQLServerType(sqlType) {
|
|
59
60
|
var _a, _b;
|
|
@@ -160,7 +161,9 @@ class SQLServerDialect extends dialect_1.Dialect {
|
|
|
160
161
|
// condition is expected, `true` and `false` are (1=1) and (1=0), a `bit`
|
|
161
162
|
// column is an integer, and a cast to boolean is refused.
|
|
162
163
|
this.booleanType = 'none';
|
|
163
|
-
|
|
164
|
+
// A datetimeoffset is an instant. Its clock is read at UTC, or in the
|
|
165
|
+
// query's time zone, never at the offset it was written in.
|
|
166
|
+
this.hasTimestamptz = true;
|
|
164
167
|
// A bigint arrives from the driver as text and is read as a JavaScript number
|
|
165
168
|
this.supportsBigIntPrecision = false;
|
|
166
169
|
this.maxIdentifierLength = 128;
|
|
@@ -202,6 +205,8 @@ class SQLServerDialect extends dialect_1.Dialect {
|
|
|
202
205
|
return 'DATE';
|
|
203
206
|
case 'timestamp':
|
|
204
207
|
return 'DATETIME2';
|
|
208
|
+
case 'timestamptz':
|
|
209
|
+
return 'DATETIMEOFFSET';
|
|
205
210
|
case 'record':
|
|
206
211
|
case 'array':
|
|
207
212
|
return 'NVARCHAR(MAX)';
|
|
@@ -374,42 +379,31 @@ class SQLServerDialect extends dialect_1.Dialect {
|
|
|
374
379
|
sqlNowExpr() {
|
|
375
380
|
return 'SYSUTCDATETIME()';
|
|
376
381
|
}
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
if (malloy_types_1.TD.isAnyTimestamp(from.e.typeDef)) {
|
|
380
|
-
const tz = (0, dialect_1.qtz)(qi);
|
|
381
|
-
if (tz) {
|
|
382
|
-
extractFrom = this.sqlConvertToCivilTime(extractFrom !== null && extractFrom !== void 0 ? extractFrom : '', tz, from.e.typeDef).sql;
|
|
383
|
-
}
|
|
384
|
-
}
|
|
385
|
-
if (from.units === 'day_of_week') {
|
|
382
|
+
sqlCivilExtract(expr, units, _civilType) {
|
|
383
|
+
if (units === 'day_of_week') {
|
|
386
384
|
// Days since a Sunday, so the answer does not follow DATEFIRST
|
|
387
|
-
return `((DATEDIFF(day, '19000107', ${
|
|
385
|
+
return `((DATEDIFF(day, '19000107', ${expr}) % 7 + 7) % 7 + 1)`;
|
|
388
386
|
}
|
|
389
387
|
// Malloy's week of the year is the ISO week; DATEPART(week) counts from
|
|
390
388
|
// January 1st and follows DATEFIRST
|
|
391
|
-
const part =
|
|
389
|
+
const part = units === 'week' ? 'iso_week' : datePartMap[units];
|
|
392
390
|
if (part === undefined) {
|
|
393
|
-
throw new Error(`Unknown SQL Server date part '${
|
|
391
|
+
throw new Error(`Unknown SQL Server date part '${units}'`);
|
|
394
392
|
}
|
|
395
|
-
return `DATEPART(${part}, ${
|
|
393
|
+
return `DATEPART(${part}, ${expr})`;
|
|
394
|
+
}
|
|
395
|
+
sqlCivilToDate(expr) {
|
|
396
|
+
return `CAST(${expr} AS DATE)`;
|
|
396
397
|
}
|
|
397
|
-
|
|
398
|
+
sqlDateToCivil(expr) {
|
|
399
|
+
return `CAST(${expr} AS DATETIME2)`;
|
|
400
|
+
}
|
|
401
|
+
sqlCast(_qi, cast) {
|
|
398
402
|
const expr = cast.e.sql || '';
|
|
399
403
|
const { srcTypeDef, dstTypeDef, dstSQLType } = this.sqlCastPrep(cast);
|
|
400
404
|
if ((dstTypeDef === null || dstTypeDef === void 0 ? void 0 : dstTypeDef.type) === 'boolean') {
|
|
401
405
|
return this.unsupported('a cast to boolean: there are no boolean values');
|
|
402
406
|
}
|
|
403
|
-
const tz = (0, dialect_1.qtz)(qi);
|
|
404
|
-
if (tz && srcTypeDef && dstTypeDef) {
|
|
405
|
-
if (malloy_types_1.TD.isTimestamp(srcTypeDef) && malloy_types_1.TD.isDate(dstTypeDef)) {
|
|
406
|
-
const civil = this.sqlConvertToCivilTime(expr, tz, srcTypeDef).sql;
|
|
407
|
-
return `CAST(${civil} AS DATE)`;
|
|
408
|
-
}
|
|
409
|
-
if (malloy_types_1.TD.isDate(srcTypeDef) && malloy_types_1.TD.isTimestamp(dstTypeDef)) {
|
|
410
|
-
return this.sqlConvertFromCivilTime(`CAST(${expr} AS DATETIME2)`, tz, dstTypeDef);
|
|
411
|
-
}
|
|
412
|
-
}
|
|
413
407
|
if (!malloy_types_1.TD.eq(srcTypeDef, dstTypeDef)) {
|
|
414
408
|
const castFunc = cast.safe ? 'TRY_CAST' : 'CAST';
|
|
415
409
|
return `${castFunc}(${expr} AS ${dstSQLType})`;
|
|
@@ -422,16 +416,11 @@ class SQLServerDialect extends dialect_1.Dialect {
|
|
|
422
416
|
sqlDateLiteral(_qi, literal) {
|
|
423
417
|
return `CAST('${literal}' AS DATE)`;
|
|
424
418
|
}
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
const ts = `CAST('${literal}' AS DATETIME2)`;
|
|
428
|
-
if (tz) {
|
|
429
|
-
return this.sqlConvertFromCivilTime(ts, tz, { type: 'timestamp' });
|
|
430
|
-
}
|
|
431
|
-
return ts;
|
|
419
|
+
sqlCivilLiteral(literal) {
|
|
420
|
+
return `CAST('${literal}' AS DATETIME2)`;
|
|
432
421
|
}
|
|
433
|
-
sqlTimestamptzLiteral(_qi,
|
|
434
|
-
|
|
422
|
+
sqlTimestamptzLiteral(_qi, literal, timezone) {
|
|
423
|
+
return this.sqlConvertFromCivilTime(this.sqlCivilLiteral(literal), timezone, { type: 'timestamptz' });
|
|
435
424
|
}
|
|
436
425
|
// AT TIME ZONE takes a Windows time zone name
|
|
437
426
|
sqlTimezoneLiteral(timezone) {
|
|
@@ -441,24 +430,34 @@ class SQLServerDialect extends dialect_1.Dialect {
|
|
|
441
430
|
}
|
|
442
431
|
return this.sqlLiteralString(windowsName);
|
|
443
432
|
}
|
|
444
|
-
|
|
433
|
+
// Civil time is a datetime2, which has no zone. AT TIME ZONE 'UTC' labels
|
|
434
|
+
// a datetime2 as UTC and moves a datetimeoffset to UTC, so one expression
|
|
435
|
+
// reads the clock of either; a CAST alone would read a datetimeoffset's
|
|
436
|
+
// clock at the offset it was written in.
|
|
437
|
+
sqlConvertToCivilTime(expr, timezone, typeDef) {
|
|
445
438
|
if (timezone === 'UTC') {
|
|
446
|
-
return
|
|
439
|
+
return malloy_types_1.TD.isTimestamptz(typeDef)
|
|
440
|
+
? `CAST((${expr} AT TIME ZONE 'UTC') AS DATETIME2)`
|
|
441
|
+
: expr;
|
|
447
442
|
}
|
|
448
443
|
const tz = this.sqlTimezoneLiteral(timezone);
|
|
449
|
-
return {
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
444
|
+
return `CAST((${expr} AT TIME ZONE 'UTC') AT TIME ZONE ${tz} AS DATETIME2)`;
|
|
445
|
+
}
|
|
446
|
+
sqlConvertFromCivilTime(expr, timezone, destTypeDef) {
|
|
447
|
+
if (malloy_types_1.TD.isTimestamptz(destTypeDef)) {
|
|
448
|
+
// A datetime2 cast to datetimeoffset is at +00:00
|
|
449
|
+
return timezone === 'UTC'
|
|
450
|
+
? `CAST(${expr} AS DATETIMEOFFSET)`
|
|
451
|
+
: `(${expr} AT TIME ZONE ${this.sqlTimezoneLiteral(timezone)})`;
|
|
452
|
+
}
|
|
455
453
|
if (timezone === 'UTC') {
|
|
456
454
|
return expr;
|
|
457
455
|
}
|
|
458
456
|
const tz = this.sqlTimezoneLiteral(timezone);
|
|
459
457
|
return `CAST((${expr} AT TIME ZONE ${tz}) AT TIME ZONE 'UTC' AS DATETIME2)`;
|
|
460
458
|
}
|
|
461
|
-
sqlTruncate(expr, unit,
|
|
459
|
+
sqlTruncate(expr, unit, civilType) {
|
|
460
|
+
const isDate = civilType === dialect_1.CivilTime.Date;
|
|
462
461
|
// Truncation is DATEADD of the whole units since an anchor: 1900-01-01
|
|
463
462
|
// for a calendar unit, the value's own midnight for a clock unit, so the
|
|
464
463
|
// count fits an int. SQL Server 2017 has no DATETRUNC.
|
|
@@ -466,25 +465,25 @@ class SQLServerDialect extends dialect_1.Dialect {
|
|
|
466
465
|
if (unit === 'week') {
|
|
467
466
|
// Malloy weeks start on Sunday whatever DATEFIRST says, so count days
|
|
468
467
|
// from a known Sunday.
|
|
469
|
-
const day =
|
|
468
|
+
const day = isDate ? expr : midnight;
|
|
470
469
|
return `DATEADD(day, -((DATEDIFF(day, '19000107', ${expr}) % 7 + 7) % 7), ${day})`;
|
|
471
470
|
}
|
|
472
471
|
const part = datePartMap[unit];
|
|
473
472
|
if (part === undefined) {
|
|
474
473
|
throw new Error(`Unknown SQL Server date part '${unit}'`);
|
|
475
474
|
}
|
|
476
|
-
if (unit === 'day' && !
|
|
475
|
+
if (unit === 'day' && !isDate) {
|
|
477
476
|
return midnight;
|
|
478
477
|
}
|
|
479
478
|
if (unit === 'hour' || unit === 'minute' || unit === 'second') {
|
|
480
479
|
return `DATEADD(${part}, DATEDIFF(${part}, ${midnight}, ${expr}), ${midnight})`;
|
|
481
480
|
}
|
|
482
481
|
const truncated = `DATEADD(${part}, DATEDIFF(${part}, '19000101', ${expr}), '19000101')`;
|
|
483
|
-
return
|
|
482
|
+
return isDate
|
|
484
483
|
? `CAST(${truncated} AS DATE)`
|
|
485
484
|
: `CAST(${truncated} AS DATETIME2)`;
|
|
486
485
|
}
|
|
487
|
-
sqlOffsetTime(expr, op, magnitude, unit,
|
|
486
|
+
sqlOffsetTime(expr, op, magnitude, unit, _civilType) {
|
|
488
487
|
const part = datePartMap[unit];
|
|
489
488
|
if (part === undefined) {
|
|
490
489
|
throw new Error(`Unknown SQL Server date part '${unit}'`);
|
|
@@ -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[];
|