@malloydata/malloy 0.0.435 → 0.0.437
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 +10 -14
- 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/expr-props.js +1 -1
- package/dist/lang/ast/expressions/pick-when.js +7 -0
- package/dist/lang/ast/expressions/time-literal.js +6 -1
- 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/drill.js +7 -1
- 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/lib/Malloy/MalloyLexer.js +976 -978
- 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/query_query.js +11 -2
- 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
|
@@ -300,19 +300,19 @@ class DatabricksDialect extends dialect_1.Dialect {
|
|
|
300
300
|
sqlNowExpr() {
|
|
301
301
|
return 'CURRENT_TIMESTAMP()';
|
|
302
302
|
}
|
|
303
|
+
// Civil time is a TIMESTAMP whose reading in the session zone, UTC, is
|
|
304
|
+
// the civil time
|
|
303
305
|
sqlConvertToCivilTime(expr, timezone, _typeDef) {
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
sql: `FROM_UTC_TIMESTAMP(${expr}, ${this.sqlTimezoneLiteral(timezone)})`,
|
|
308
|
-
typeDef: { type: 'timestamp' },
|
|
309
|
-
};
|
|
306
|
+
return timezone === 'UTC'
|
|
307
|
+
? expr
|
|
308
|
+
: `FROM_UTC_TIMESTAMP(${expr}, ${this.sqlTimezoneLiteral(timezone)})`;
|
|
310
309
|
}
|
|
311
310
|
sqlConvertFromCivilTime(expr, timezone, _destTypeDef) {
|
|
312
|
-
|
|
313
|
-
|
|
311
|
+
return timezone === 'UTC'
|
|
312
|
+
? expr
|
|
313
|
+
: `TO_UTC_TIMESTAMP(${expr}, ${this.sqlTimezoneLiteral(timezone)})`;
|
|
314
314
|
}
|
|
315
|
-
sqlTruncate(expr, unit,
|
|
315
|
+
sqlTruncate(expr, unit, _civilType) {
|
|
316
316
|
// Databricks DATE_TRUNC starts weeks on Monday; Malloy wants Sunday.
|
|
317
317
|
// Add 1 day before truncating, subtract 1 day after.
|
|
318
318
|
if (unit === 'week') {
|
|
@@ -320,7 +320,7 @@ class DatabricksDialect extends dialect_1.Dialect {
|
|
|
320
320
|
}
|
|
321
321
|
return `DATE_TRUNC('${unit}', ${expr})`;
|
|
322
322
|
}
|
|
323
|
-
sqlOffsetTime(expr, op, magnitude, unit,
|
|
323
|
+
sqlOffsetTime(expr, op, magnitude, unit, _civilType) {
|
|
324
324
|
// Use TIMESTAMPADD which accepts expressions for magnitude,
|
|
325
325
|
// unlike INTERVAL which only accepts literals in Databricks.
|
|
326
326
|
let offsetUnit = unit.toUpperCase();
|
|
@@ -336,31 +336,23 @@ class DatabricksDialect extends dialect_1.Dialect {
|
|
|
336
336
|
const n = op === '+' ? offsetMag : `-(${offsetMag})`;
|
|
337
337
|
return `TIMESTAMPADD(${offsetUnit}, ${n}, ${expr})`;
|
|
338
338
|
}
|
|
339
|
-
|
|
340
|
-
const
|
|
341
|
-
|
|
342
|
-
if (malloy_types_1.TD.isTimestamp(te.e.typeDef)) {
|
|
343
|
-
const tz = (0, dialect_1.qtz)(qi);
|
|
344
|
-
if (tz) {
|
|
345
|
-
extractFrom = `FROM_UTC_TIMESTAMP(${extractFrom}, ${this.sqlTimezoneLiteral(tz)})`;
|
|
346
|
-
}
|
|
347
|
-
}
|
|
348
|
-
if (extractionMap[te.units]) {
|
|
339
|
+
sqlCivilExtract(expr, units, _civilType) {
|
|
340
|
+
const extractUnits = extractionMap[units];
|
|
341
|
+
if (extractUnits) {
|
|
349
342
|
// DAYOFWEEK, DAYOFYEAR are functions
|
|
350
|
-
return `${
|
|
343
|
+
return `${extractUnits}(${expr})`;
|
|
351
344
|
}
|
|
352
|
-
return `EXTRACT(${units} FROM ${
|
|
345
|
+
return `EXTRACT(${units} FROM ${expr})`;
|
|
346
|
+
}
|
|
347
|
+
sqlCivilToDate(expr) {
|
|
348
|
+
return `CAST(${expr} AS DATE)`;
|
|
349
|
+
}
|
|
350
|
+
sqlDateToCivil(expr) {
|
|
351
|
+
return `CAST(${expr} AS TIMESTAMP)`;
|
|
353
352
|
}
|
|
354
|
-
sqlCast(
|
|
353
|
+
sqlCast(_qi, cast) {
|
|
355
354
|
const srcSQL = cast.e.sql || 'internal-error-in-sql-generation';
|
|
356
|
-
const {
|
|
357
|
-
const tz = (0, dialect_1.qtz)(qi);
|
|
358
|
-
if (op === 'timestamp::date' && tz) {
|
|
359
|
-
return `CAST(FROM_UTC_TIMESTAMP(${srcSQL}, ${this.sqlTimezoneLiteral(tz)}) AS DATE)`;
|
|
360
|
-
}
|
|
361
|
-
else if (op === 'date::timestamp' && tz) {
|
|
362
|
-
return `TO_UTC_TIMESTAMP(CAST(${srcSQL} AS TIMESTAMP_NTZ), ${this.sqlTimezoneLiteral(tz)})`;
|
|
363
|
-
}
|
|
355
|
+
const { srcTypeDef, dstTypeDef, dstSQLType } = this.sqlCastPrep(cast);
|
|
364
356
|
if (!malloy_types_1.TD.eq(srcTypeDef, dstTypeDef)) {
|
|
365
357
|
if (cast.safe) {
|
|
366
358
|
return `TRY_CAST(${srcSQL} AS ${dstSQLType})`;
|
|
@@ -378,11 +370,7 @@ class DatabricksDialect extends dialect_1.Dialect {
|
|
|
378
370
|
sqlDateLiteral(_qi, literal) {
|
|
379
371
|
return `DATE '${literal}'`;
|
|
380
372
|
}
|
|
381
|
-
|
|
382
|
-
const tz = timezone || (0, dialect_1.qtz)(qi);
|
|
383
|
-
if (tz) {
|
|
384
|
-
return `TO_UTC_TIMESTAMP(TIMESTAMP_NTZ '${literal}', ${this.sqlTimezoneLiteral(tz)})`;
|
|
385
|
-
}
|
|
373
|
+
sqlCivilLiteral(literal) {
|
|
386
374
|
return `TIMESTAMP '${literal}'`;
|
|
387
375
|
}
|
|
388
376
|
sqlTimestamptzLiteral(_qi, _literal, _timezone) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Expr, Sampling, AtomicTypeDef, MeasureTimeExpr, TimeExtractExpr, TypecastExpr, RegexMatchExpr, TimeLiteralExpr, RecordLiteralNode, ArrayLiteralNode, BasicAtomicTypeDef, OrderBy, TimestampUnit, ATimestampTypeDef, TimeExpr, TemporalFieldType } from '../model/malloy_types';
|
|
1
|
+
import type { Expr, Sampling, AtomicTypeDef, MeasureTimeExpr, TimeExtractExpr, TypecastExpr, RegexMatchExpr, TimeLiteralExpr, RecordLiteralNode, ArrayLiteralNode, BasicAtomicTypeDef, OrderBy, TimestampUnit, ATimestampTypeDef, TimeExpr, TemporalFieldType, ExtractUnit } from '../model/malloy_types';
|
|
2
2
|
import type { DialectFunctionOverloadDef } from './functions';
|
|
3
3
|
import type { ValidateTablePathResult } from './table-path';
|
|
4
4
|
/**
|
|
@@ -68,10 +68,26 @@ export interface QueryInfo {
|
|
|
68
68
|
queryTimezone?: string;
|
|
69
69
|
systemTimezone?: string;
|
|
70
70
|
}
|
|
71
|
+
/**
|
|
72
|
+
* The two kinds of civil time: a calendar date, and a date with a time of
|
|
73
|
+
* day. Neither has a zone.
|
|
74
|
+
*/
|
|
75
|
+
export declare const CivilTime: {
|
|
76
|
+
readonly Date: "date";
|
|
77
|
+
readonly DateAndTime: "date_and_time";
|
|
78
|
+
};
|
|
79
|
+
export type CivilTime = (typeof CivilTime)[keyof typeof CivilTime];
|
|
80
|
+
/** Add or subtract `magnitude` units of time */
|
|
81
|
+
export interface TimeOffset {
|
|
82
|
+
op: '+' | '-';
|
|
83
|
+
magnitude: string;
|
|
84
|
+
unit: TimestampUnit;
|
|
85
|
+
}
|
|
71
86
|
export type FieldReferenceType = 'table' | 'nest source' | 'array[scalar]' | 'array[record]' | 'record';
|
|
72
87
|
export declare const dayIndex: number;
|
|
73
88
|
export declare function inDays(units: string): boolean;
|
|
74
|
-
|
|
89
|
+
/** The query time zone, or UTC when the query has none. */
|
|
90
|
+
export declare function queryZone(qi: QueryInfo): string;
|
|
75
91
|
/**
|
|
76
92
|
* The per-element condition for an aggregate turtle (sqlAggregateTurtle). On
|
|
77
93
|
* the normal path it gates each row by its group_set (and a projection's own
|
|
@@ -283,175 +299,43 @@ export declare abstract class Dialect {
|
|
|
283
299
|
sqlLiteralNumber(literal: string): string;
|
|
284
300
|
ignoreInProject(_fieldName: string): boolean;
|
|
285
301
|
abstract sqlNowExpr(): string;
|
|
286
|
-
abstract sqlTimeExtractExpr(qi: QueryInfo, xFrom: TimeExtractExpr): string;
|
|
287
302
|
abstract sqlMeasureTimeExpr(e: MeasureTimeExpr): string;
|
|
288
303
|
/**
|
|
289
|
-
* Generate SQL for
|
|
290
|
-
*
|
|
291
|
-
* Most casts are simple: `CAST(expr AS type)` or `TRY_CAST(expr AS type)` for safe casts.
|
|
292
|
-
*
|
|
293
|
-
* However, when a query timezone is set, casts between temporal types (date, timestamp, timestamptz)
|
|
294
|
-
* require special handling to ensure correct timezone semantics:
|
|
295
|
-
*
|
|
296
|
-
* **Timezone-Aware Cast Semantics:**
|
|
297
|
-
*
|
|
298
|
-
* 1. **TIMESTAMP → DATE**:
|
|
299
|
-
* - TIMESTAMP represents UTC wall clock
|
|
300
|
-
* - Convert to query timezone, then extract date
|
|
301
|
-
* - Example: TIMESTAMP '2020-02-20 00:00:00' with tz 'America/Mexico_City' → '2020-02-19'
|
|
302
|
-
*
|
|
303
|
-
* 2. **TIMESTAMPTZ → DATE**:
|
|
304
|
-
* - TIMESTAMPTZ represents absolute instant
|
|
305
|
-
* - Convert to query timezone, then extract date
|
|
306
|
-
* - Example: TIMESTAMPTZ '2020-02-20 00:00:00 UTC' with tz 'America/Mexico_City' → '2020-02-19'
|
|
307
|
-
*
|
|
308
|
-
* 3. **DATE → TIMESTAMP**:
|
|
309
|
-
* - DATE represents civil date
|
|
310
|
-
* - Interpret as midnight in query timezone, return UTC wall clock
|
|
311
|
-
* - Example: DATE '2020-02-20' with tz 'America/Mexico_City' → TIMESTAMP '2020-02-20 06:00:00' (UTC)
|
|
312
|
-
*
|
|
313
|
-
* 4. **DATE → TIMESTAMPTZ**:
|
|
314
|
-
* - DATE represents civil date
|
|
315
|
-
* - Interpret as midnight in query timezone, create instant
|
|
316
|
-
* - Example: DATE '2020-02-20' with tz 'America/Mexico_City' → instant at 2020-02-20 06:00:00 UTC
|
|
317
|
-
*
|
|
318
|
-
* 5. **TIMESTAMPTZ → TIMESTAMP**:
|
|
319
|
-
* - TIMESTAMPTZ represents absolute instant
|
|
320
|
-
* - Extract wall clock in query timezone, return as TIMESTAMP
|
|
321
|
-
* - Example: TIMESTAMPTZ '2020-02-20 00:00:00 UTC' with tz 'America/Mexico_City' → TIMESTAMP '2020-02-19 18:00:00'
|
|
322
|
-
*
|
|
323
|
-
* 6. **TIMESTAMP → TIMESTAMPTZ**:
|
|
324
|
-
* - TIMESTAMP represents UTC wall clock
|
|
325
|
-
* - Interpret as being in query timezone
|
|
326
|
-
* - Example: TIMESTAMP '2020-02-20 00:00:00' with tz 'America/Mexico_City' → instant at 2020-02-20 06:00:00 UTC
|
|
327
|
-
*
|
|
328
|
-
* **Implementation Notes:**
|
|
329
|
-
*
|
|
330
|
-
* - Dialects without timestamptz support (MySQL, BigQuery, StandardSQL) only need cases 1-3
|
|
331
|
-
* - Without query timezone, most casts are simple `CAST(expr AS type)`
|
|
332
|
-
*
|
|
333
|
-
* @param qi - Query info containing timezone and other context
|
|
334
|
-
* @param cast - The typecast expression to generate SQL for
|
|
335
|
-
* @returns SQL string for the cast operation
|
|
304
|
+
* Generate SQL for a cast. Casts between date, timestamp and timestamptz
|
|
305
|
+
* never reach here; they are made by sqlTimeCast.
|
|
336
306
|
*/
|
|
337
307
|
abstract sqlCast(qi: QueryInfo, cast: TypecastExpr): string;
|
|
338
308
|
abstract sqlRegexpMatch(df: RegexMatchExpr): string;
|
|
309
|
+
/** The civil time which `timezone` shows at the instant `expr`. */
|
|
310
|
+
abstract sqlConvertToCivilTime(expr: string, timezone: string, typeDef: ATimestampTypeDef): string;
|
|
339
311
|
/**
|
|
340
|
-
*
|
|
341
|
-
*
|
|
342
|
-
* Each dialect selects its own SQL type to represent civil time (e.g., plain TIMESTAMP,
|
|
343
|
-
* TIMESTAMP WITH TIME ZONE, or DATETIME). The civil space is where timezone-aware
|
|
344
|
-
* truncation and interval arithmetic happen. Operations like sqlTruncate and sqlOffsetTime
|
|
345
|
-
* are aware of the civil space and work correctly within it.
|
|
346
|
-
*
|
|
347
|
-
* @param expr The SQL expression for the Malloy timestamp (plain or timestamptz)
|
|
348
|
-
* @param timezone The target timezone for civil operations
|
|
349
|
-
* @param typeDef The Malloy type of the input expression
|
|
350
|
-
* @returns Object with SQL expression and the SQL type it evaluates to (the civil type)
|
|
351
|
-
*/
|
|
352
|
-
abstract sqlConvertToCivilTime(expr: string, timezone: string, typeDef: AtomicTypeDef): {
|
|
353
|
-
sql: string;
|
|
354
|
-
typeDef: AtomicTypeDef;
|
|
355
|
-
};
|
|
356
|
-
/**
|
|
357
|
-
* Converts from civil time back to a Malloy timestamp type.
|
|
358
|
-
*
|
|
359
|
-
* This is the inverse of sqlConvertToCivilTime. Takes a value in the dialect's
|
|
360
|
-
* civil space and converts it back to either a plain timestamp (UTC) or a
|
|
361
|
-
* timestamptz, depending on the destination type.
|
|
362
|
-
*
|
|
363
|
-
* @param expr The SQL expression in civil time
|
|
364
|
-
* @param timezone The timezone of the civil time
|
|
365
|
-
* @param destTypeDef The destination Malloy timestamp type (plain or timestamptz)
|
|
366
|
-
* @returns SQL expression representing the Malloy timestamp
|
|
312
|
+
* The instant at which `timezone` shows the civil time `expr`, as a
|
|
313
|
+
* value of `destTypeDef`.
|
|
367
314
|
*/
|
|
368
315
|
abstract sqlConvertFromCivilTime(expr: string, timezone: string, destTypeDef: ATimestampTypeDef): string;
|
|
316
|
+
/** The start of the unit containing `expr`. A week starts on Sunday. */
|
|
317
|
+
abstract sqlTruncate(expr: string, unit: TimestampUnit, civilType: CivilTime): string;
|
|
318
|
+
abstract sqlOffsetTime(expr: string, op: '+' | '-', magnitude: string, unit: TimestampUnit, civilType: CivilTime): string;
|
|
319
|
+
/** One field of `expr`. A day_of_week counts from 1 on Sunday. */
|
|
320
|
+
abstract sqlCivilExtract(expr: string, units: ExtractUnit, civilType: CivilTime): string;
|
|
321
|
+
/** The date part of the civil time `expr`. */
|
|
322
|
+
abstract sqlCivilToDate(expr: string): string;
|
|
323
|
+
/** Midnight at the start of the date `expr`, as civil time. */
|
|
324
|
+
abstract sqlDateToCivil(expr: string): string;
|
|
325
|
+
/** The civil time written as `literal`, 'YYYY-MM-DD HH:MM:SS'. */
|
|
326
|
+
abstract sqlCivilLiteral(literal: string): string;
|
|
327
|
+
sqlTimeExtractExpr(qi: QueryInfo, from: TimeExtractExpr): string;
|
|
369
328
|
/**
|
|
370
|
-
*
|
|
371
|
-
*
|
|
372
|
-
* @param expr The SQL expression to truncate
|
|
373
|
-
* @param unit The unit to truncate to (year, month, day, hour, etc.)
|
|
374
|
-
* @param typeDef The Malloy type of the expression (date, timestamp, etc.)
|
|
375
|
-
* @param inCivilTime If true, the expression is already in civil (local) time and should not
|
|
376
|
-
* be converted. If false, may need timezone conversion for timestamps.
|
|
377
|
-
* @param timezone Optional timezone for the operation. Only provided when timezone-aware
|
|
378
|
-
* truncation is needed but inCivilTime is false.
|
|
379
|
-
* @returns SQL expression representing the truncated time
|
|
329
|
+
* Truncation and/or offset, the offset applied after the truncation.
|
|
330
|
+
* Doing both in one pass converts to and from civil time only once.
|
|
380
331
|
*/
|
|
381
|
-
|
|
332
|
+
sqlTruncAndOffset(baseExpr: TimeExpr, qi: QueryInfo, truncateTo?: TimestampUnit, offset?: TimeOffset): string;
|
|
333
|
+
private civilTruncAndOffset;
|
|
382
334
|
/**
|
|
383
|
-
*
|
|
384
|
-
*
|
|
385
|
-
* @param expr The SQL expression to offset
|
|
386
|
-
* @param op The operation: '+' for addition, '-' for subtraction
|
|
387
|
-
* @param magnitude The SQL expression for the interval magnitude (e.g., '6', '(delta_val)')
|
|
388
|
-
* @param unit The interval unit (year, month, day, hour, etc.)
|
|
389
|
-
* @param typeDef The Malloy type of the expression (date, timestamp, etc.)
|
|
390
|
-
* @param inCivilTime If true, the expression is already in civil (local) time and should not
|
|
391
|
-
* be converted. If false, may need timezone conversion for timestamps.
|
|
392
|
-
* @param timezone Optional timezone for the operation. Only provided when timezone-aware
|
|
393
|
-
* offset is needed but inCivilTime is false.
|
|
394
|
-
* @returns SQL expression representing the offset time
|
|
335
|
+
* A cast between date, timestamp and timestamptz, or undefined for any
|
|
336
|
+
* other cast.
|
|
395
337
|
*/
|
|
396
|
-
|
|
397
|
-
/**
|
|
398
|
-
* Determines whether a truncation and/or offset operation needs to be performed in
|
|
399
|
-
* civil (local) time, and if so, which timezone to use.
|
|
400
|
-
*
|
|
401
|
-
* Calendar-based operations (day, week, month, quarter, year) typically need civil time
|
|
402
|
-
* computation because these units can cross DST boundaries, changing the UTC offset.
|
|
403
|
-
*
|
|
404
|
-
* Default implementation:
|
|
405
|
-
* - Returns true for timestamps with truncation or calendar-unit offsets
|
|
406
|
-
* - Uses the query timezone from QueryInfo, or 'UTC' if none specified
|
|
407
|
-
* - Returns false for dates or sub-day offsets (hour, minute, second)
|
|
408
|
-
*
|
|
409
|
-
* Dialects can override this if they have different rules about which operations
|
|
410
|
-
* require civil time computation.
|
|
411
|
-
*
|
|
412
|
-
* @param typeDef The Malloy type of the base expression
|
|
413
|
-
* @param truncateTo The truncation unit, if any
|
|
414
|
-
* @param offsetUnit The offset unit, if any
|
|
415
|
-
* @param qi Query information including timezone settings
|
|
416
|
-
* @returns Object with `needed` boolean and optional `tz` string
|
|
417
|
-
*/
|
|
418
|
-
needsCivilTimeComputation(typeDef: AtomicTypeDef, truncateTo: TimestampUnit | undefined, offsetUnit: TimestampUnit | undefined, qi: QueryInfo): {
|
|
419
|
-
needed: boolean;
|
|
420
|
-
tz: string | undefined;
|
|
421
|
-
};
|
|
422
|
-
/**
|
|
423
|
-
* Unified function for truncation and/or offset operations. This turns out to
|
|
424
|
-
* be a very common operation and one which can be optimized by doing it together.
|
|
425
|
-
*
|
|
426
|
-
* Much of the complexity has to do with getting timezone values set up so that
|
|
427
|
-
* they will truncate/offset in the query timezone instead of UTC.
|
|
428
|
-
*
|
|
429
|
-
* The intention is that this implementation will work for all dialects, and all
|
|
430
|
-
* the dialect peculiarities are handled with the new primitives introduced to
|
|
431
|
-
* support this function:
|
|
432
|
-
* - needsCivilTimeComputation: Determines if operation needs civil time
|
|
433
|
-
* - sqlConvertToCivilTime/sqlConvertFromCivilTime: Timezone conversion
|
|
434
|
-
* - sqlTruncate: Truncation operation
|
|
435
|
-
* - sqlOffsetTime: Interval arithmetic
|
|
436
|
-
*
|
|
437
|
-
* OFFSET TIMESTAMP BEHAVIOR:
|
|
438
|
-
* - Plain timestamps (offset=false): Always return plain TIMESTAMP in UTC
|
|
439
|
-
* - Offset timestamps (offset=true):
|
|
440
|
-
* - Simple path: Operate in native embedded timezone, return TIMESTAMPTZ
|
|
441
|
-
* - Civil path: Convert to query timezone (preserving instant), operate there,
|
|
442
|
-
* return TIMESTAMPTZ in query timezone via sqlConvertFromCivilTime
|
|
443
|
-
* - BigQuery/MySQL: No offset timestamp support, this logic never runs
|
|
444
|
-
*
|
|
445
|
-
* @param baseExpr The time expression to operate on (already compiled, with .sql populated)
|
|
446
|
-
* @param qi Query information including timezone
|
|
447
|
-
* @param truncateTo Optional truncation unit (year, month, day, etc.)
|
|
448
|
-
* @param offset Optional offset to apply (after truncation if both present)
|
|
449
|
-
*/
|
|
450
|
-
sqlTruncAndOffset(baseExpr: TimeExpr, qi: QueryInfo, truncateTo?: TimestampUnit, offset?: {
|
|
451
|
-
op: '+' | '-';
|
|
452
|
-
magnitude: string;
|
|
453
|
-
unit: TimestampUnit;
|
|
454
|
-
}): string;
|
|
338
|
+
sqlTimeCast(qi: QueryInfo, cast: TypecastExpr): string | undefined;
|
|
455
339
|
/**
|
|
456
340
|
* Generate SQL for a DATE literal.
|
|
457
341
|
* @param literal - The date string in format 'YYYY-MM-DD'
|
|
@@ -459,18 +343,10 @@ export declare abstract class Dialect {
|
|
|
459
343
|
*/
|
|
460
344
|
abstract sqlDateLiteral(qi: QueryInfo, literal: string): string;
|
|
461
345
|
/**
|
|
462
|
-
*
|
|
463
|
-
*
|
|
464
|
-
* @param timezone - Optional timezone name (e.g., 'America/Los_Angeles')
|
|
465
|
-
* - If undefined: Create plain timestamp literal from the literal string
|
|
466
|
-
* - If defined: The literal string represents a civil time in the given timezone.
|
|
467
|
-
* Convert it to a plain timestamp (typically by interpreting as timestamptz
|
|
468
|
-
* in that timezone, then casting to plain timestamp). This happens when:
|
|
469
|
-
* 1. A constant with timezone is used (constants don't have dialect context)
|
|
470
|
-
* 2. A literal with timezone is used in a dialect that doesn't support offset timestamps
|
|
471
|
-
* @returns SQL that produces a plain TIMESTAMP value
|
|
346
|
+
* The timestamp at which `timezone`, or the query time zone when there is
|
|
347
|
+
* none, shows the civil time `literal`.
|
|
472
348
|
*/
|
|
473
|
-
|
|
349
|
+
sqlTimestampLiteral(qi: QueryInfo, literal: string, timezone: string | undefined): string;
|
|
474
350
|
/**
|
|
475
351
|
* Generate SQL for an offset TIMESTAMP literal (TIMESTAMP WITH TIME ZONE).
|
|
476
352
|
* Only called for dialects where hasOffsetTimestamp = true.
|
|
@@ -548,6 +424,16 @@ export declare abstract class Dialect {
|
|
|
548
424
|
* SQL to generate to get a boolean value for a boolean expression
|
|
549
425
|
*/
|
|
550
426
|
sqlBoolean(bv: boolean): string;
|
|
427
|
+
/**
|
|
428
|
+
* Malloy's `not`: of NULL, true. A dialect with booleanType 'none' has no
|
|
429
|
+
* boolean value for COALESCE to return, so the test is written as a
|
|
430
|
+
* condition.
|
|
431
|
+
*/
|
|
432
|
+
sqlNot(condition: string): string;
|
|
433
|
+
/**
|
|
434
|
+
* A condition Malloy defines as true when SQL says NULL: `!=` and `!~`
|
|
435
|
+
*/
|
|
436
|
+
sqlNullIsTrue(condition: string): string;
|
|
551
437
|
/**
|
|
552
438
|
* What a boolean value looks like in a query result
|
|
553
439
|
*/
|
package/dist/dialect/dialect.js
CHANGED
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
* SPDX-License-Identifier: MIT
|
|
5
5
|
*/
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.Dialect = exports.dayIndex = exports.EscapeStyle = exports.MAX_DECIMAL38 = exports.MIN_DECIMAL38 = exports.MAX_INT128 = exports.MIN_INT128 = exports.MAX_INT64 = exports.MIN_INT64 = exports.MAX_INT32 = exports.MIN_INT32 = void 0;
|
|
7
|
+
exports.Dialect = exports.dayIndex = exports.CivilTime = exports.EscapeStyle = exports.MAX_DECIMAL38 = exports.MIN_DECIMAL38 = exports.MAX_INT128 = exports.MIN_INT128 = exports.MAX_INT64 = exports.MIN_INT64 = exports.MAX_INT32 = exports.MIN_INT32 = void 0;
|
|
8
8
|
exports.inDays = inDays;
|
|
9
|
-
exports.
|
|
9
|
+
exports.queryZone = queryZone;
|
|
10
10
|
exports.turtleGroupSetCondition = turtleGroupSetCondition;
|
|
11
11
|
const malloy_types_1 = require("../model/malloy_types");
|
|
12
12
|
const table_path_1 = require("./table-path");
|
|
@@ -37,6 +37,14 @@ exports.EscapeStyle = {
|
|
|
37
37
|
Backslash: 'backslash',
|
|
38
38
|
Unset: 'unset',
|
|
39
39
|
};
|
|
40
|
+
/**
|
|
41
|
+
* The two kinds of civil time: a calendar date, and a date with a time of
|
|
42
|
+
* day. Neither has a zone.
|
|
43
|
+
*/
|
|
44
|
+
exports.CivilTime = {
|
|
45
|
+
Date: 'date',
|
|
46
|
+
DateAndTime: 'date_and_time',
|
|
47
|
+
};
|
|
40
48
|
const allUnits = [
|
|
41
49
|
'microsecond',
|
|
42
50
|
'millisecond',
|
|
@@ -53,14 +61,10 @@ exports.dayIndex = allUnits.indexOf('day');
|
|
|
53
61
|
function inDays(units) {
|
|
54
62
|
return allUnits.indexOf(units) >= exports.dayIndex;
|
|
55
63
|
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
if (tz === undefined || tz === qi.systemTimezone) {
|
|
61
|
-
return undefined;
|
|
62
|
-
}
|
|
63
|
-
return tz;
|
|
64
|
+
/** The query time zone, or UTC when the query has none. */
|
|
65
|
+
function queryZone(qi) {
|
|
66
|
+
var _a;
|
|
67
|
+
return (_a = qi.queryTimezone) !== null && _a !== void 0 ? _a : 'UTC';
|
|
64
68
|
}
|
|
65
69
|
/**
|
|
66
70
|
* The per-element condition for an aggregate turtle (sqlAggregateTurtle). On
|
|
@@ -431,96 +435,70 @@ class Dialect {
|
|
|
431
435
|
ignoreInProject(_fieldName) {
|
|
432
436
|
return false;
|
|
433
437
|
}
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
* Default implementation:
|
|
442
|
-
* - Returns true for timestamps with truncation or calendar-unit offsets
|
|
443
|
-
* - Uses the query timezone from QueryInfo, or 'UTC' if none specified
|
|
444
|
-
* - Returns false for dates or sub-day offsets (hour, minute, second)
|
|
445
|
-
*
|
|
446
|
-
* Dialects can override this if they have different rules about which operations
|
|
447
|
-
* require civil time computation.
|
|
448
|
-
*
|
|
449
|
-
* @param typeDef The Malloy type of the base expression
|
|
450
|
-
* @param truncateTo The truncation unit, if any
|
|
451
|
-
* @param offsetUnit The offset unit, if any
|
|
452
|
-
* @param qi Query information including timezone settings
|
|
453
|
-
* @returns Object with `needed` boolean and optional `tz` string
|
|
454
|
-
*/
|
|
455
|
-
needsCivilTimeComputation(typeDef, truncateTo, offsetUnit, qi) {
|
|
456
|
-
// Calendar units that can cross DST boundaries
|
|
457
|
-
const calendarUnits = ['day', 'week', 'month', 'quarter', 'year'];
|
|
458
|
-
const isCalendarTruncate = truncateTo !== undefined && calendarUnits.includes(truncateTo);
|
|
459
|
-
const isCalendarOffset = offsetUnit !== undefined && calendarUnits.includes(offsetUnit);
|
|
460
|
-
const tz = qtz(qi);
|
|
461
|
-
// Timestamps with calendar truncation/offset need civil time computation
|
|
462
|
-
// BUT only if there's actually a timezone to convert to/from
|
|
463
|
-
const needed = malloy_types_1.TD.isAnyTimestamp(typeDef) &&
|
|
464
|
-
(isCalendarTruncate || isCalendarOffset) &&
|
|
465
|
-
tz !== undefined;
|
|
466
|
-
return { needed, tz };
|
|
438
|
+
sqlTimeExtractExpr(qi, from) {
|
|
439
|
+
const time = from.e;
|
|
440
|
+
if (malloy_types_1.TD.isAnyTimestamp(time.typeDef)) {
|
|
441
|
+
const civil = this.sqlConvertToCivilTime(time.sql, queryZone(qi), time.typeDef);
|
|
442
|
+
return this.sqlCivilExtract(civil, from.units, exports.CivilTime.DateAndTime);
|
|
443
|
+
}
|
|
444
|
+
return this.sqlCivilExtract(time.sql, from.units, exports.CivilTime.Date);
|
|
467
445
|
}
|
|
468
446
|
/**
|
|
469
|
-
*
|
|
470
|
-
*
|
|
471
|
-
*
|
|
472
|
-
* Much of the complexity has to do with getting timezone values set up so that
|
|
473
|
-
* they will truncate/offset in the query timezone instead of UTC.
|
|
474
|
-
*
|
|
475
|
-
* The intention is that this implementation will work for all dialects, and all
|
|
476
|
-
* the dialect peculiarities are handled with the new primitives introduced to
|
|
477
|
-
* support this function:
|
|
478
|
-
* - needsCivilTimeComputation: Determines if operation needs civil time
|
|
479
|
-
* - sqlConvertToCivilTime/sqlConvertFromCivilTime: Timezone conversion
|
|
480
|
-
* - sqlTruncate: Truncation operation
|
|
481
|
-
* - sqlOffsetTime: Interval arithmetic
|
|
482
|
-
*
|
|
483
|
-
* OFFSET TIMESTAMP BEHAVIOR:
|
|
484
|
-
* - Plain timestamps (offset=false): Always return plain TIMESTAMP in UTC
|
|
485
|
-
* - Offset timestamps (offset=true):
|
|
486
|
-
* - Simple path: Operate in native embedded timezone, return TIMESTAMPTZ
|
|
487
|
-
* - Civil path: Convert to query timezone (preserving instant), operate there,
|
|
488
|
-
* return TIMESTAMPTZ in query timezone via sqlConvertFromCivilTime
|
|
489
|
-
* - BigQuery/MySQL: No offset timestamp support, this logic never runs
|
|
490
|
-
*
|
|
491
|
-
* @param baseExpr The time expression to operate on (already compiled, with .sql populated)
|
|
492
|
-
* @param qi Query information including timezone
|
|
493
|
-
* @param truncateTo Optional truncation unit (year, month, day, etc.)
|
|
494
|
-
* @param offset Optional offset to apply (after truncation if both present)
|
|
447
|
+
* Truncation and/or offset, the offset applied after the truncation.
|
|
448
|
+
* Doing both in one pass converts to and from civil time only once.
|
|
495
449
|
*/
|
|
496
450
|
sqlTruncAndOffset(baseExpr, qi, truncateTo, offset) {
|
|
497
|
-
|
|
498
|
-
if (malloy_types_1.TD.isAnyTimestamp(
|
|
499
|
-
|
|
500
|
-
if (needsCivil && tz) {
|
|
501
|
-
// Civil time path: convert to local time, operate, convert back to UTC
|
|
502
|
-
const civilResult = this.sqlConvertToCivilTime(baseExpr.sql, tz, baseExpr.typeDef);
|
|
503
|
-
let expr = civilResult.sql;
|
|
504
|
-
const civilTypeDef = civilResult.typeDef;
|
|
505
|
-
if (truncateTo) {
|
|
506
|
-
expr = this.sqlTruncate(expr, truncateTo, civilTypeDef, true, tz);
|
|
507
|
-
}
|
|
508
|
-
if (offset) {
|
|
509
|
-
expr = this.sqlOffsetTime(expr, offset.op, offset.magnitude, offset.unit, civilTypeDef, true, tz);
|
|
510
|
-
}
|
|
511
|
-
return this.sqlConvertFromCivilTime(expr, tz, baseExpr.typeDef);
|
|
512
|
-
}
|
|
451
|
+
const timeType = baseExpr.typeDef;
|
|
452
|
+
if (!malloy_types_1.TD.isAnyTimestamp(timeType)) {
|
|
453
|
+
return this.civilTruncAndOffset(baseExpr.sql, exports.CivilTime.Date, truncateTo, offset);
|
|
513
454
|
}
|
|
514
|
-
|
|
515
|
-
|
|
455
|
+
const usesQueryZone = truncateTo !== undefined ||
|
|
456
|
+
(offset !== undefined && (0, malloy_types_1.isDateUnit)(offset.unit));
|
|
457
|
+
const zone = usesQueryZone ? queryZone(qi) : 'UTC';
|
|
458
|
+
const civil = this.sqlConvertToCivilTime(baseExpr.sql, zone, timeType);
|
|
459
|
+
return this.sqlConvertFromCivilTime(this.civilTruncAndOffset(civil, exports.CivilTime.DateAndTime, truncateTo, offset), zone, timeType);
|
|
460
|
+
}
|
|
461
|
+
civilTruncAndOffset(expr, civilType, truncateTo, offset) {
|
|
462
|
+
let sql = expr;
|
|
516
463
|
if (truncateTo) {
|
|
517
|
-
sql = this.sqlTruncate(sql, truncateTo,
|
|
464
|
+
sql = this.sqlTruncate(sql, truncateTo, civilType);
|
|
518
465
|
}
|
|
519
466
|
if (offset) {
|
|
520
|
-
sql = this.sqlOffsetTime(sql, offset.op, offset.magnitude, offset.unit,
|
|
467
|
+
sql = this.sqlOffsetTime(sql, offset.op, offset.magnitude, offset.unit, civilType);
|
|
521
468
|
}
|
|
522
469
|
return sql;
|
|
523
470
|
}
|
|
471
|
+
/**
|
|
472
|
+
* A cast between date, timestamp and timestamptz, or undefined for any
|
|
473
|
+
* other cast.
|
|
474
|
+
*/
|
|
475
|
+
sqlTimeCast(qi, cast) {
|
|
476
|
+
var _a;
|
|
477
|
+
const { srcTypeDef, dstTypeDef } = this.sqlCastPrep(cast);
|
|
478
|
+
const expr = (_a = cast.e.sql) !== null && _a !== void 0 ? _a : '';
|
|
479
|
+
if (malloy_types_1.TD.isAnyTimestamp(srcTypeDef)) {
|
|
480
|
+
if (malloy_types_1.TD.isDate(dstTypeDef)) {
|
|
481
|
+
return this.sqlCivilToDate(this.sqlConvertToCivilTime(expr, queryZone(qi), srcTypeDef));
|
|
482
|
+
}
|
|
483
|
+
if (malloy_types_1.TD.isAnyTimestamp(dstTypeDef) &&
|
|
484
|
+
dstTypeDef.type !== srcTypeDef.type) {
|
|
485
|
+
// The same instant in another SQL type. A round trip through civil
|
|
486
|
+
// time in any zone keeps the instant; UTC costs the least.
|
|
487
|
+
return this.sqlConvertFromCivilTime(this.sqlConvertToCivilTime(expr, 'UTC', srcTypeDef), 'UTC', dstTypeDef);
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
if (malloy_types_1.TD.isDate(srcTypeDef) && malloy_types_1.TD.isAnyTimestamp(dstTypeDef)) {
|
|
491
|
+
return this.sqlConvertFromCivilTime(this.sqlDateToCivil(expr), queryZone(qi), dstTypeDef);
|
|
492
|
+
}
|
|
493
|
+
return undefined;
|
|
494
|
+
}
|
|
495
|
+
/**
|
|
496
|
+
* The timestamp at which `timezone`, or the query time zone when there is
|
|
497
|
+
* none, shows the civil time `literal`.
|
|
498
|
+
*/
|
|
499
|
+
sqlTimestampLiteral(qi, literal, timezone) {
|
|
500
|
+
return this.sqlConvertFromCivilTime(this.sqlCivilLiteral(literal), timezone !== null && timezone !== void 0 ? timezone : queryZone(qi), { type: 'timestamp' });
|
|
501
|
+
}
|
|
524
502
|
/**
|
|
525
503
|
* Reject characters that can break SQL literals or
|
|
526
504
|
* be changed by SQL formatting. Timezone-name validity belongs to the
|
|
@@ -574,6 +552,7 @@ class Dialect {
|
|
|
574
552
|
* @returns The SQL translation of the expression, or undefined
|
|
575
553
|
*/
|
|
576
554
|
exprToSQL(qi, df) {
|
|
555
|
+
var _a;
|
|
577
556
|
switch (df.node) {
|
|
578
557
|
case 'now':
|
|
579
558
|
return this.sqlNowExpr();
|
|
@@ -603,7 +582,7 @@ class Dialect {
|
|
|
603
582
|
case 'extract':
|
|
604
583
|
return this.sqlTimeExtractExpr(qi, df);
|
|
605
584
|
case 'cast':
|
|
606
|
-
return this.sqlCast(qi, df);
|
|
585
|
+
return (_a = this.sqlTimeCast(qi, df)) !== null && _a !== void 0 ? _a : this.sqlCast(qi, df);
|
|
607
586
|
case 'regexpMatch':
|
|
608
587
|
return this.sqlRegexpMatch(df);
|
|
609
588
|
case '/': {
|
|
@@ -756,6 +735,26 @@ class Dialect {
|
|
|
756
735
|
}
|
|
757
736
|
return bv ? 'true' : 'false';
|
|
758
737
|
}
|
|
738
|
+
/**
|
|
739
|
+
* Malloy's `not`: of NULL, true. A dialect with booleanType 'none' has no
|
|
740
|
+
* boolean value for COALESCE to return, so the test is written as a
|
|
741
|
+
* condition.
|
|
742
|
+
*/
|
|
743
|
+
sqlNot(condition) {
|
|
744
|
+
if (this.booleanType === 'none') {
|
|
745
|
+
return `(CASE WHEN ${condition} THEN 1 ELSE 0 END = 0)`;
|
|
746
|
+
}
|
|
747
|
+
return `COALESCE(NOT ${condition},TRUE)`;
|
|
748
|
+
}
|
|
749
|
+
/**
|
|
750
|
+
* A condition Malloy defines as true when SQL says NULL: `!=` and `!~`
|
|
751
|
+
*/
|
|
752
|
+
sqlNullIsTrue(condition) {
|
|
753
|
+
if (this.booleanType === 'none') {
|
|
754
|
+
return `(CASE WHEN NOT (${condition}) THEN 1 ELSE 0 END = 0)`;
|
|
755
|
+
}
|
|
756
|
+
return `COALESCE(${condition},true)`;
|
|
757
|
+
}
|
|
759
758
|
/**
|
|
760
759
|
* What a boolean value looks like in a query result
|
|
761
760
|
*/
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Sampling, AtomicTypeDef, RegexMatchExpr, MeasureTimeExpr, BasicAtomicTypeDef, RecordLiteralNode, OrderBy, TimestampUnit } from '../../model/malloy_types';
|
|
2
2
|
import type { DialectFunctionOverloadDef } from '../functions';
|
|
3
|
-
import type { CompiledOrderBy, DialectFieldList, FieldReferenceType, IntegerTypeMapping } from '../dialect';
|
|
3
|
+
import type { CivilTime, CompiledOrderBy, DialectFieldList, FieldReferenceType, IntegerTypeMapping } from '../dialect';
|
|
4
4
|
import { PostgresBase } from '../pg_impl';
|
|
5
5
|
import type { ValidateTablePathResult } from '../table-path';
|
|
6
6
|
export declare class DuckDBDialect extends PostgresBase {
|
|
@@ -62,7 +62,7 @@ export declare class DuckDBDialect extends PostgresBase {
|
|
|
62
62
|
castToString(expression: string): string;
|
|
63
63
|
concat(...values: string[]): string;
|
|
64
64
|
validateTypeName(sqlType: string): boolean;
|
|
65
|
-
sqlOffsetTime(expr: string, op: '+' | '-', magnitude: string, unit: TimestampUnit,
|
|
65
|
+
sqlOffsetTime(expr: string, op: '+' | '-', magnitude: string, unit: TimestampUnit, _civilType: CivilTime): string;
|
|
66
66
|
sqlRegexpMatch(df: RegexMatchExpr): string;
|
|
67
67
|
sqlMeasureTimeExpr(df: MeasureTimeExpr): string;
|
|
68
68
|
sqlLiteralRecord(lit: RecordLiteralNode): string;
|
|
@@ -332,7 +332,7 @@ class DuckDBDialect extends pg_impl_1.PostgresBase {
|
|
|
332
332
|
// Brackets: INT[ ]
|
|
333
333
|
return sqlType.match(/^[A-Za-z\s(),[\]0-9]*$/) !== null;
|
|
334
334
|
}
|
|
335
|
-
sqlOffsetTime(expr, op, magnitude, unit,
|
|
335
|
+
sqlOffsetTime(expr, op, magnitude, unit, _civilType) {
|
|
336
336
|
// DuckDB doesn't support INTERVAL '1' WEEK, convert to days
|
|
337
337
|
let offsetUnit = unit;
|
|
338
338
|
let offsetMag = magnitude;
|
package/dist/dialect/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export type { DialectFunctionOverloadDef, DefinitionBlueprint, DefinitionBlueprintMap, OverloadedDefinitionBlueprint, } from './functions/util';
|
|
2
2
|
export { arg, anyExprType, makeParam, overload, minScalar, minAggregate, maxScalar, spread, param, variadicParam, literal, sql, } from './functions/util';
|
|
3
|
-
export { Dialect,
|
|
3
|
+
export { Dialect, queryZone } from './dialect';
|
|
4
4
|
export type { DialectFieldList, CompiledOrderBy, LateralJoinExpression, QueryInfo, FieldReferenceType, GroupByClauseType, OrderByClauseType, } from './dialect';
|
|
5
5
|
export { StandardSQLDialect } from './standardsql';
|
|
6
6
|
export { PostgresDialect } from './postgres';
|