@malloydata/malloy 0.0.79 → 0.0.80-dev230824170739

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.
@@ -1,4 +1,4 @@
1
- import { DialectFragment, Expr, ExtractUnit, Sampling, StructDef, TimeFieldType, TimeValue, TimestampUnit, TypecastFragment } from '../model/malloy_types';
1
+ import { DialectFragment, Expr, ExtractUnit, Sampling, StructDef, TimeFieldType, TimeValue, TimestampUnit, TypecastFragment, FieldAtomicTypeDef } from '../model/malloy_types';
2
2
  import { DialectFunctionOverloadDef } from './functions';
3
3
  interface DialectField {
4
4
  type: string;
@@ -77,5 +77,8 @@ export declare abstract class Dialect {
77
77
  sqlSampleTable(tableSQL: string, sample: Sampling | undefined): string;
78
78
  sqlOrderBy(orderTerms: string[]): string;
79
79
  sqlTzStr(qi: QueryInfo): string;
80
+ abstract sqlTypeToMalloyType(sqlType: string): FieldAtomicTypeDef | undefined;
81
+ abstract malloyTypeToSQLType(malloyType: FieldAtomicTypeDef): string;
82
+ abstract validateTypeName(sqlType: string): boolean;
80
83
  }
81
84
  export {};
@@ -1,4 +1,4 @@
1
- import { DateUnit, Expr, ExtractUnit, Sampling, StructDef, TimeFieldType, TimeValue, TimestampUnit, TypecastFragment } from '../../model/malloy_types';
1
+ import { DateUnit, Expr, ExtractUnit, Sampling, StructDef, TimeFieldType, TimeValue, TimestampUnit, TypecastFragment, FieldAtomicTypeDef } from '../../model/malloy_types';
2
2
  import { DialectFunctionOverloadDef } from '../functions';
3
3
  import { Dialect, DialectFieldList, QueryInfo } from '../dialect';
4
4
  export declare class DuckDBDialect extends Dialect {
@@ -54,6 +54,9 @@ export declare class DuckDBDialect extends Dialect {
54
54
  sqlLiteralString(literal: string): string;
55
55
  sqlLiteralRegexp(literal: string): string;
56
56
  getGlobalFunctionDef(name: string): DialectFunctionOverloadDef[] | undefined;
57
+ malloyTypeToSQLType(malloyType: FieldAtomicTypeDef): string;
58
+ sqlTypeToMalloyType(sqlType: string): FieldAtomicTypeDef | undefined;
57
59
  castToString(expression: string): string;
58
60
  concat(...values: string[]): string;
61
+ validateTypeName(sqlType: string): boolean;
59
62
  }
@@ -29,14 +29,28 @@ const functions_1 = require("./functions");
29
29
  const dialect_1 = require("../dialect");
30
30
  // need to refactor runSQL to take a SQLBlock instead of just a sql string.
31
31
  const hackSplitComment = '-- hack: split on this';
32
- const castMap = {
33
- 'number': 'double precision',
34
- 'string': 'varchar',
35
- };
36
32
  const pgExtractionMap = {
37
33
  'day_of_week': 'dow',
38
34
  'day_of_year': 'doy',
39
35
  };
36
+ const duckDBToMalloyTypes = {
37
+ 'BIGINT': { type: 'number', numberType: 'integer' },
38
+ 'INTEGER': { type: 'number', numberType: 'integer' },
39
+ 'TINYINT': { type: 'number', numberType: 'integer' },
40
+ 'SMALLINT': { type: 'number', numberType: 'integer' },
41
+ 'UBIGINT': { type: 'number', numberType: 'integer' },
42
+ 'UINTEGER': { type: 'number', numberType: 'integer' },
43
+ 'UTINYINT': { type: 'number', numberType: 'integer' },
44
+ 'USMALLINT': { type: 'number', numberType: 'integer' },
45
+ 'HUGEINT': { type: 'number', numberType: 'integer' },
46
+ 'DOUBLE': { type: 'number', numberType: 'float' },
47
+ 'VARCHAR': { type: 'string' },
48
+ 'DATE': { type: 'date' },
49
+ 'TIMESTAMP': { type: 'timestamp' },
50
+ 'TIME': { type: 'string' },
51
+ 'DECIMAL': { type: 'number', numberType: 'float' },
52
+ 'BOOLEAN': { type: 'boolean' },
53
+ };
40
54
  class DuckDBDialect extends dialect_1.Dialect {
41
55
  constructor() {
42
56
  super(...arguments);
@@ -262,9 +276,11 @@ class DuckDBDialect extends dialect_1.Dialect {
262
276
  return (0, malloy_types_1.mkExpr) `CAST((${cast.expr})::TIMESTAMP AT TIME ZONE '${tz}' AS TIMESTAMP)`;
263
277
  }
264
278
  if (cast.srcType !== cast.dstType) {
265
- const dstType = castMap[cast.dstType] || cast.dstType;
279
+ const dstType = typeof cast.dstType === 'string'
280
+ ? this.malloyTypeToSQLType({ type: cast.dstType })
281
+ : cast.dstType.raw;
266
282
  const castFunc = cast.safe ? 'TRY_CAST' : 'CAST';
267
- return (0, malloy_types_1.mkExpr) `${castFunc}(${cast.expr} AS ${dstType})`;
283
+ return (0, malloy_types_1.mkExpr) `${castFunc}(${cast.expr} AS ${dstType})`;
268
284
  }
269
285
  return cast.expr;
270
286
  }
@@ -335,12 +351,37 @@ class DuckDBDialect extends dialect_1.Dialect {
335
351
  getGlobalFunctionDef(name) {
336
352
  return functions_1.DUCKDB_FUNCTIONS.get(name);
337
353
  }
354
+ malloyTypeToSQLType(malloyType) {
355
+ if (malloyType.type === 'number') {
356
+ if (malloyType.numberType === 'integer') {
357
+ return 'integer';
358
+ }
359
+ else {
360
+ return 'double precision';
361
+ }
362
+ }
363
+ else if (malloyType.type === 'string') {
364
+ return 'varchar';
365
+ }
366
+ return malloyType.type;
367
+ }
368
+ sqlTypeToMalloyType(sqlType) {
369
+ return duckDBToMalloyTypes[sqlType.toUpperCase()];
370
+ }
338
371
  castToString(expression) {
339
372
  return `CAST(${expression} as VARCHAR)`;
340
373
  }
341
374
  concat(...values) {
342
375
  return values.join(' || ');
343
376
  }
377
+ validateTypeName(sqlType) {
378
+ // Letters: BIGINT
379
+ // Numbers: INT8
380
+ // Spaces: TIMESTAMP WITH TIME ZONE
381
+ // Parentheses, Commas: DECIMAL(1, 1)
382
+ // Brackets: INT[ ]
383
+ return sqlType.match(/^[A-Za-z\s(),[\]0-9]*$/) !== null;
384
+ }
344
385
  }
345
386
  exports.DuckDBDialect = DuckDBDialect;
346
387
  //# sourceMappingURL=duckdb.js.map
@@ -1,4 +1,4 @@
1
- import { DateUnit, Expr, ExtractUnit, Sampling, TimeFieldType, TimeValue, TimestampUnit, TypecastFragment } from '../../model/malloy_types';
1
+ import { DateUnit, Expr, ExtractUnit, Sampling, TimeFieldType, TimeValue, TimestampUnit, TypecastFragment, FieldAtomicTypeDef } from '../../model/malloy_types';
2
2
  import { DialectFunctionOverloadDef } from '../functions';
3
3
  import { Dialect, DialectFieldList, QueryInfo } from '../dialect';
4
4
  export declare class PostgresDialect extends Dialect {
@@ -55,6 +55,9 @@ export declare class PostgresDialect extends Dialect {
55
55
  sqlLiteralString(literal: string): string;
56
56
  sqlLiteralRegexp(literal: string): string;
57
57
  getGlobalFunctionDef(name: string): DialectFunctionOverloadDef[] | undefined;
58
+ malloyTypeToSQLType(malloyType: FieldAtomicTypeDef): string;
59
+ sqlTypeToMalloyType(sqlType: string): FieldAtomicTypeDef | undefined;
58
60
  castToString(expression: string): string;
59
61
  concat(...values: string[]): string;
62
+ validateTypeName(sqlType: string): boolean;
60
63
  }
@@ -27,10 +27,6 @@ const utils_1 = require("../../model/utils");
27
27
  const malloy_types_1 = require("../../model/malloy_types");
28
28
  const functions_1 = require("./functions");
29
29
  const dialect_1 = require("../dialect");
30
- const castMap = {
31
- 'number': 'double precision',
32
- 'string': 'varchar',
33
- };
34
30
  const pgExtractionMap = {
35
31
  'day_of_week': 'dow',
36
32
  'day_of_year': 'doy',
@@ -51,6 +47,31 @@ const inSeconds = {
51
47
  'day': 24 * 3600,
52
48
  'week': 7 * 24 * 3600,
53
49
  };
50
+ const postgresToMalloyTypes = {
51
+ 'character varying': { type: 'string' },
52
+ 'name': { type: 'string' },
53
+ 'text': { type: 'string' },
54
+ 'date': { type: 'date' },
55
+ 'integer': { type: 'number', numberType: 'integer' },
56
+ 'bigint': { type: 'number', numberType: 'integer' },
57
+ 'double precision': { type: 'number', numberType: 'float' },
58
+ 'timestamp without time zone': { type: 'timestamp' },
59
+ 'oid': { type: 'string' },
60
+ 'boolean': { type: 'boolean' },
61
+ // ARRAY: "string",
62
+ 'timestamp': { type: 'timestamp' },
63
+ '"char"': { type: 'string' },
64
+ 'character': { type: 'string' },
65
+ 'smallint': { type: 'number', numberType: 'integer' },
66
+ 'xid': { type: 'string' },
67
+ 'real': { type: 'number', numberType: 'float' },
68
+ 'interval': { type: 'string' },
69
+ 'inet': { type: 'string' },
70
+ 'regtype': { type: 'string' },
71
+ 'numeric': { type: 'number', numberType: 'float' },
72
+ 'bytea': { type: 'string' },
73
+ 'pg_ndistinct': { type: 'number', numberType: 'integer' },
74
+ };
54
75
  class PostgresDialect extends dialect_1.Dialect {
55
76
  constructor() {
56
77
  super(...arguments);
@@ -276,12 +297,14 @@ class PostgresDialect extends dialect_1.Dialect {
276
297
  return (0, malloy_types_1.mkExpr) `CAST((${cast.expr})::TIMESTAMP AT TIME ZONE '${tz}' AS TIMESTAMP)`;
277
298
  }
278
299
  if (cast.srcType !== cast.dstType) {
279
- const dstType = castMap[cast.dstType] || cast.dstType;
300
+ const dstType = typeof cast.dstType === 'string'
301
+ ? this.malloyTypeToSQLType({ type: cast.dstType })
302
+ : cast.dstType.raw;
280
303
  if (cast.safe) {
281
304
  throw new Error("Postgres dialect doesn't support Safe Cast");
282
305
  }
283
306
  const castFunc = 'CAST';
284
- return (0, malloy_types_1.mkExpr) `${castFunc}(${cast.expr} AS ${dstType})`;
307
+ return (0, malloy_types_1.mkExpr) `${castFunc}(${cast.expr} AS ${dstType})`;
285
308
  }
286
309
  return cast.expr;
287
310
  }
@@ -357,12 +380,37 @@ class PostgresDialect extends dialect_1.Dialect {
357
380
  getGlobalFunctionDef(name) {
358
381
  return functions_1.POSTGRES_FUNCTIONS.get(name);
359
382
  }
383
+ malloyTypeToSQLType(malloyType) {
384
+ if (malloyType.type === 'number') {
385
+ if (malloyType.numberType === 'integer') {
386
+ return 'integer';
387
+ }
388
+ else {
389
+ return 'double precision';
390
+ }
391
+ }
392
+ else if (malloyType.type === 'string') {
393
+ return 'varchar';
394
+ }
395
+ return malloyType.type;
396
+ }
397
+ sqlTypeToMalloyType(sqlType) {
398
+ return postgresToMalloyTypes[sqlType.toLowerCase()];
399
+ }
360
400
  castToString(expression) {
361
401
  return `CAST(${expression} as VARCHAR)`;
362
402
  }
363
403
  concat(...values) {
364
404
  return values.join(' || ');
365
405
  }
406
+ validateTypeName(sqlType) {
407
+ // Letters: BIGINT
408
+ // Numbers: INT8
409
+ // Spaces: TIMESTAMP WITH TIME ZONE
410
+ // Parentheses, Commas: NUMERIC(5, 2)
411
+ // Square Brackets: INT64[]
412
+ return sqlType.match(/^[A-Za-z\s(),[\]0-9]*$/) !== null;
413
+ }
366
414
  }
367
415
  exports.PostgresDialect = PostgresDialect;
368
416
  //# sourceMappingURL=postgres.js.map
@@ -1,4 +1,4 @@
1
- import { Expr, ExtractUnit, Sampling, TimeValue, TimestampUnit, TypecastFragment } from '../../model/malloy_types';
1
+ import { Expr, ExtractUnit, Sampling, TimeValue, TimestampUnit, TypecastFragment, FieldAtomicTypeDef } from '../../model/malloy_types';
2
2
  import { DialectFunctionOverloadDef } from '../functions';
3
3
  import { Dialect, DialectFieldList, QueryInfo } from '../dialect';
4
4
  export declare class StandardSQLDialect extends Dialect {
@@ -51,6 +51,9 @@ export declare class StandardSQLDialect extends Dialect {
51
51
  sqlLiteralString(literal: string): string;
52
52
  sqlLiteralRegexp(literal: string): string;
53
53
  getGlobalFunctionDef(name: string): DialectFunctionOverloadDef[] | undefined;
54
+ malloyTypeToSQLType(malloyType: FieldAtomicTypeDef): string;
55
+ sqlTypeToMalloyType(sqlType: string): FieldAtomicTypeDef | undefined;
54
56
  castToString(expression: string): string;
55
57
  concat(...values: string[]): string;
58
+ validateTypeName(sqlType: string): boolean;
56
59
  }
@@ -27,9 +27,6 @@ const utils_1 = require("../../model/utils");
27
27
  const malloy_types_1 = require("../../model/malloy_types");
28
28
  const functions_1 = require("./functions");
29
29
  const dialect_1 = require("../dialect");
30
- const castMap = {
31
- 'number': 'float64',
32
- };
33
30
  // These are the units that "TIMESTAMP_ADD" "TIMESTAMP_DIFF" accept
34
31
  function timestampMeasureable(units) {
35
32
  return [
@@ -57,6 +54,25 @@ function qtz(qi) {
57
54
  return tz;
58
55
  }
59
56
  }
57
+ const bqToMalloyTypes = {
58
+ 'DATE': { type: 'date' },
59
+ 'STRING': { type: 'string' },
60
+ 'INTEGER': { type: 'number', numberType: 'integer' },
61
+ 'INT64': { type: 'number', numberType: 'integer' },
62
+ 'FLOAT': { type: 'number', numberType: 'float' },
63
+ 'FLOAT64': { type: 'number', numberType: 'float' },
64
+ 'NUMERIC': { type: 'number', numberType: 'float' },
65
+ 'BIGNUMERIC': { type: 'number', numberType: 'float' },
66
+ 'TIMESTAMP': { type: 'timestamp' },
67
+ 'BOOLEAN': { type: 'boolean' },
68
+ 'BOOL': { type: 'boolean' },
69
+ 'JSON': { type: 'json' },
70
+ // TODO (https://cloud.google.com/bigquery/docs/reference/rest/v2/tables#tablefieldschema):
71
+ // BYTES
72
+ // DATETIME
73
+ // TIME
74
+ // GEOGRAPHY
75
+ };
60
76
  class StandardSQLDialect extends dialect_1.Dialect {
61
77
  constructor() {
62
78
  super(...arguments);
@@ -335,9 +351,11 @@ ${(0, utils_1.indent)(sql)}
335
351
  return (0, malloy_types_1.mkExpr) `TIMESTAMP(${cast.expr}, '${tz}')`;
336
352
  }
337
353
  if (cast.srcType !== cast.dstType) {
338
- const dstType = castMap[cast.dstType] || cast.dstType;
354
+ const dstType = typeof cast.dstType === 'string'
355
+ ? this.malloyTypeToSQLType({ type: cast.dstType })
356
+ : cast.dstType.raw;
339
357
  const castFunc = cast.safe ? 'SAFE_CAST' : 'CAST';
340
- return (0, malloy_types_1.mkExpr) `${castFunc}(${cast.expr} AS ${dstType})`;
358
+ return (0, malloy_types_1.mkExpr) `${castFunc}(${cast.expr} AS ${dstType})`;
341
359
  }
342
360
  return cast.expr;
343
361
  }
@@ -417,12 +435,34 @@ ${(0, utils_1.indent)(sql)}
417
435
  getGlobalFunctionDef(name) {
418
436
  return functions_1.STANDARDSQL_FUNCTIONS.get(name);
419
437
  }
438
+ malloyTypeToSQLType(malloyType) {
439
+ if (malloyType.type === 'number') {
440
+ if (malloyType.numberType === 'integer') {
441
+ return 'INT64';
442
+ }
443
+ else {
444
+ return 'FLOAT64';
445
+ }
446
+ }
447
+ return malloyType.type;
448
+ }
449
+ sqlTypeToMalloyType(sqlType) {
450
+ return bqToMalloyTypes[sqlType.toUpperCase()];
451
+ }
420
452
  castToString(expression) {
421
453
  return `CAST(${expression} as STRING)`;
422
454
  }
423
455
  concat(...values) {
424
456
  return values.join(' || ');
425
457
  }
458
+ validateTypeName(sqlType) {
459
+ // Letters: BIGINT
460
+ // Numbers: INT8
461
+ // Spaces,
462
+ // Parentheses, Commas: NUMERIC(5, 2)
463
+ // Angle Brackets: ARRAY<INT64>
464
+ return sqlType.match(/^[A-Za-z\s(),<>0-9]*$/) !== null;
465
+ }
426
466
  }
427
467
  exports.StandardSQLDialect = StandardSQLDialect;
428
468
  //# sourceMappingURL=standardsql.js.map
package/dist/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ export { DuckDBDialect, StandardSQLDialect, PostgresDialect } from './dialect';
1
2
  export type { QueryDataRow, Fragment, StructDef, StructRelationship, NamedStructDefs, MalloyQueryData, AtomicFieldType as AtomicFieldTypeInner, DateUnit, ExtractUnit, TimestampUnit, TimeFieldType, QueryData, QueryValue, FieldTypeDef, Expr, DialectFragment, TimeValue, FilterExpression, SQLBlock, FieldAtomicDef, FieldDef, FilteredAliasedName, PipeSegment, QueryFieldDef, TurtleDef, SearchValueMapResult, SearchIndexResult, ModelDef, Query, QueryRunStats, NamedQuery, NamedModelObject, ExpressionType, FunctionDef, FunctionOverloadDef, FunctionParameterDef, ExpressionValueType, TypeDesc, FieldValueType, ExpressionTypeDesc, FunctionParamTypeDesc, DocumentLocation, DocumentRange, DocumentPosition, Annotation, } from './model';
2
3
  export { Segment, isFilteredAliasedName, flattenQuery, expressionIsCalculation, } from './model';
3
4
  export { HighlightType, MalloyTranslator, } from './lang';
package/dist/index.js CHANGED
@@ -22,7 +22,11 @@
22
22
  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
23
  */
24
24
  Object.defineProperty(exports, "__esModule", { value: true });
25
- exports.Tag = exports.toAsyncGenerator = exports.Explore = exports.DataWriter = exports.Parse = exports.JSONWriter = exports.CSVWriter = exports.QueryMaterializer = exports.Result = exports.TimestampTimeframe = exports.DateTimeframe = exports.SourceRelationship = exports.JoinRelationship = exports.MalloyError = exports.FixedConnectionMap = exports.InMemoryURLReader = exports.EmptyURLReader = exports.SingleConnectionRuntime = exports.ConnectionRuntime = exports.AtomicFieldType = exports.Runtime = exports.Malloy = exports.MalloyTranslator = exports.HighlightType = exports.expressionIsCalculation = exports.flattenQuery = exports.isFilteredAliasedName = exports.Segment = void 0;
25
+ exports.Tag = exports.toAsyncGenerator = exports.Explore = exports.DataWriter = exports.Parse = exports.JSONWriter = exports.CSVWriter = exports.QueryMaterializer = exports.Result = exports.TimestampTimeframe = exports.DateTimeframe = exports.SourceRelationship = exports.JoinRelationship = exports.MalloyError = exports.FixedConnectionMap = exports.InMemoryURLReader = exports.EmptyURLReader = exports.SingleConnectionRuntime = exports.ConnectionRuntime = exports.AtomicFieldType = exports.Runtime = exports.Malloy = exports.MalloyTranslator = exports.HighlightType = exports.expressionIsCalculation = exports.flattenQuery = exports.isFilteredAliasedName = exports.Segment = exports.PostgresDialect = exports.StandardSQLDialect = exports.DuckDBDialect = void 0;
26
+ var dialect_1 = require("./dialect");
27
+ Object.defineProperty(exports, "DuckDBDialect", { enumerable: true, get: function () { return dialect_1.DuckDBDialect; } });
28
+ Object.defineProperty(exports, "StandardSQLDialect", { enumerable: true, get: function () { return dialect_1.StandardSQLDialect; } });
29
+ Object.defineProperty(exports, "PostgresDialect", { enumerable: true, get: function () { return dialect_1.PostgresDialect; } });
26
30
  var model_1 = require("./model");
27
31
  // Used in Composer Demo
28
32
  Object.defineProperty(exports, "Segment", { enumerable: true, get: function () { return model_1.Segment; } });
@@ -1,13 +1,16 @@
1
+ import { CastType } from '../../../model';
1
2
  import { ExprValue } from '../types/expr-value';
2
3
  import { ExpressionDef } from '../types/expression-def';
3
4
  import { FieldSpace } from '../types/field-space';
4
- export type CastType = 'string' | 'number' | 'boolean' | 'date' | 'timestamp';
5
- export declare function isCastType(t: string): t is CastType;
6
5
  export declare class ExprCast extends ExpressionDef {
7
6
  readonly expr: ExpressionDef;
8
- readonly castType: CastType;
7
+ readonly castType: CastType | {
8
+ raw: string;
9
+ };
9
10
  readonly safe: boolean;
10
11
  elementType: string;
11
- constructor(expr: ExpressionDef, castType: CastType, safe?: boolean);
12
+ constructor(expr: ExpressionDef, castType: CastType | {
13
+ raw: string;
14
+ }, safe?: boolean);
12
15
  getExpression(fs: FieldSpace): ExprValue;
13
16
  }
@@ -22,14 +22,10 @@
22
22
  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
23
  */
24
24
  Object.defineProperty(exports, "__esModule", { value: true });
25
- exports.ExprCast = exports.isCastType = void 0;
25
+ exports.ExprCast = void 0;
26
26
  const time_utils_1 = require("../time-utils");
27
27
  const expression_def_1 = require("../types/expression-def");
28
28
  const utils_1 = require("./utils");
29
- function isCastType(t) {
30
- return ['string', 'number', 'boolean', 'date', 'timestamp'].includes(t);
31
- }
32
- exports.isCastType = isCastType;
33
29
  class ExprCast extends expression_def_1.ExpressionDef {
34
30
  constructor(expr, castType, safe = false) {
35
31
  super({ expr: expr });
@@ -39,9 +35,28 @@ class ExprCast extends expression_def_1.ExpressionDef {
39
35
  this.elementType = 'cast';
40
36
  }
41
37
  getExpression(fs) {
38
+ var _a, _b, _c;
42
39
  const expr = this.expr.getExpression(fs);
40
+ let dataType = 'unsupported';
41
+ if (typeof this.castType === 'string') {
42
+ dataType = this.castType;
43
+ }
44
+ else {
45
+ const dialect = fs.dialectObj();
46
+ if (dialect) {
47
+ if (dialect.validateTypeName(this.castType.raw)) {
48
+ // TODO theoretically `sqlTypeToMalloyType` can get number subtypes,
49
+ // but `TypeDesc` does not support them.
50
+ dataType =
51
+ (_c = (_b = (_a = fs.dialectObj()) === null || _a === void 0 ? void 0 : _a.sqlTypeToMalloyType(this.castType.raw)) === null || _b === void 0 ? void 0 : _b.type) !== null && _c !== void 0 ? _c : 'unsupported';
52
+ }
53
+ else {
54
+ this.log(`Cast type \`${this.castType.raw}\` is invalid for ${dialect.name} dialect`);
55
+ }
56
+ }
57
+ }
43
58
  return {
44
- dataType: this.castType,
59
+ dataType,
45
60
  expressionType: expr.expressionType,
46
61
  value: (0, utils_1.compressExpr)((0, time_utils_1.castTo)(this.castType, expr.value, expr.dataType, this.safe)),
47
62
  evalSpace: expr.evalSpace,
@@ -1,4 +1,4 @@
1
- import { AtomicFieldType, Parameter } from '../../../model/malloy_types';
1
+ import { Parameter, CastType } from '../../../model/malloy_types';
2
2
  import { ConstantSubExpression } from '../expressions/constant-sub-expression';
3
3
  import { MalloyElement } from '../types/malloy-element';
4
4
  interface HasInit {
@@ -11,7 +11,7 @@ export declare class HasParameter extends MalloyElement {
11
11
  elementType: string;
12
12
  readonly name: string;
13
13
  readonly isCondition: boolean;
14
- readonly type?: AtomicFieldType;
14
+ readonly type?: CastType;
15
15
  readonly default?: ConstantSubExpression;
16
16
  constructor(init: HasInit);
17
17
  parameter(): Parameter;
@@ -31,7 +31,7 @@ class HasParameter extends malloy_element_1.MalloyElement {
31
31
  this.elementType = 'hasParameter';
32
32
  this.name = init.name;
33
33
  this.isCondition = init.isCondition;
34
- if (init.type && (0, malloy_types_1.isAtomicFieldType)(init.type)) {
34
+ if (init.type && (0, malloy_types_1.isCastType)(init.type)) {
35
35
  this.type = init.type;
36
36
  }
37
37
  if (init.default) {
@@ -76,7 +76,7 @@ class FieldDeclaration extends malloy_element_1.MalloyElement {
76
76
  }
77
77
  const compressValue = (0, utils_1.compressExpr)(exprValue.value);
78
78
  const retType = exprValue.dataType;
79
- if ((0, malloy_types_1.isAtomicFieldType)(retType)) {
79
+ if ((0, malloy_types_1.isAtomicFieldType)(retType) && retType !== 'error') {
80
80
  const template = {
81
81
  name: exprName,
82
82
  type: retType,
@@ -130,7 +130,7 @@ class NamedSource extends source_1.Source {
130
130
  else {
131
131
  const pVal = pExpr.constantValue();
132
132
  let value = pVal.value;
133
- if (pVal.dataType !== decl.type) {
133
+ if (pVal.dataType !== decl.type && (0, malloy_types_1.isCastType)(decl.type)) {
134
134
  value = (0, time_utils_1.castTo)(decl.type, pVal.value, pVal.dataType, true);
135
135
  }
136
136
  decl.value = value;
@@ -1,7 +1,9 @@
1
- import { AtomicFieldType, Expr, Fragment, TimeFieldType, TimestampUnit, FieldValueType } from '../../model/malloy_types';
1
+ import { Expr, Fragment, TimeFieldType, TimestampUnit, FieldValueType, CastType } from '../../model/malloy_types';
2
2
  import { TimeResult } from './types/time-result';
3
3
  export declare function timeOffset(timeType: TimeFieldType, from: Expr, op: '+' | '-', n: Expr, timeframe: TimestampUnit): Expr;
4
- export declare function castTo(castType: AtomicFieldType, from: Expr, fromType: FieldValueType, safe?: boolean): Expr;
4
+ export declare function castTo(castType: CastType | {
5
+ raw: string;
6
+ }, from: Expr, fromType: FieldValueType, safe?: boolean): Expr;
5
7
  export declare function castTimestampToDate(from: Expr, safe?: boolean): Expr;
6
8
  export declare function castDateToTimestamp(from: Expr, safe?: boolean): Expr;
7
9
  export declare function resolution(timeframe: string): TimeFieldType;
@@ -265,24 +265,25 @@ export declare class MalloyParser extends Parser {
265
265
  static readonly RULE_id = 104;
266
266
  static readonly RULE_timeframe = 105;
267
267
  static readonly RULE_ungroup = 106;
268
- static readonly RULE_fieldExpr = 107;
269
- static readonly RULE_partialAllowedFieldExpr = 108;
270
- static readonly RULE_pickStatement = 109;
271
- static readonly RULE_pick = 110;
272
- static readonly RULE_argumentList = 111;
273
- static readonly RULE_fieldNameList = 112;
274
- static readonly RULE_fieldCollection = 113;
275
- static readonly RULE_collectionWildCard = 114;
276
- static readonly RULE_taggedRef = 115;
277
- static readonly RULE_refExpr = 116;
278
- static readonly RULE_collectionMember = 117;
279
- static readonly RULE_fieldPath = 118;
280
- static readonly RULE_joinName = 119;
281
- static readonly RULE_fieldName = 120;
282
- static readonly RULE_justExpr = 121;
283
- static readonly RULE_sqlExploreNameRef = 122;
284
- static readonly RULE_nameSQLBlock = 123;
285
- static readonly RULE_connectionName = 124;
268
+ static readonly RULE_malloyOrSQLType = 107;
269
+ static readonly RULE_fieldExpr = 108;
270
+ static readonly RULE_partialAllowedFieldExpr = 109;
271
+ static readonly RULE_pickStatement = 110;
272
+ static readonly RULE_pick = 111;
273
+ static readonly RULE_argumentList = 112;
274
+ static readonly RULE_fieldNameList = 113;
275
+ static readonly RULE_fieldCollection = 114;
276
+ static readonly RULE_collectionWildCard = 115;
277
+ static readonly RULE_taggedRef = 116;
278
+ static readonly RULE_refExpr = 117;
279
+ static readonly RULE_collectionMember = 118;
280
+ static readonly RULE_fieldPath = 119;
281
+ static readonly RULE_joinName = 120;
282
+ static readonly RULE_fieldName = 121;
283
+ static readonly RULE_justExpr = 122;
284
+ static readonly RULE_sqlExploreNameRef = 123;
285
+ static readonly RULE_nameSQLBlock = 124;
286
+ static readonly RULE_connectionName = 125;
286
287
  static readonly ruleNames: string[];
287
288
  private static readonly _LITERAL_NAMES;
288
289
  private static readonly _SYMBOLIC_NAMES;
@@ -400,6 +401,7 @@ export declare class MalloyParser extends Parser {
400
401
  id(): IdContext;
401
402
  timeframe(): TimeframeContext;
402
403
  ungroup(): UngroupContext;
404
+ malloyOrSQLType(): MalloyOrSQLTypeContext;
403
405
  fieldExpr(): FieldExprContext;
404
406
  fieldExpr(_p: number): FieldExprContext;
405
407
  partialAllowedFieldExpr(): PartialAllowedFieldExprContext;
@@ -1883,6 +1885,15 @@ export declare class UngroupContext extends ParserRuleContext {
1883
1885
  exitRule(listener: MalloyParserListener): void;
1884
1886
  accept<Result>(visitor: MalloyParserVisitor<Result>): Result;
1885
1887
  }
1888
+ export declare class MalloyOrSQLTypeContext extends ParserRuleContext {
1889
+ malloyType(): MalloyTypeContext | undefined;
1890
+ string(): StringContext | undefined;
1891
+ constructor(parent: ParserRuleContext | undefined, invokingState: number);
1892
+ get ruleIndex(): number;
1893
+ enterRule(listener: MalloyParserListener): void;
1894
+ exitRule(listener: MalloyParserListener): void;
1895
+ accept<Result>(visitor: MalloyParserVisitor<Result>): Result;
1896
+ }
1886
1897
  export declare class FieldExprContext extends ParserRuleContext {
1887
1898
  constructor(parent: ParserRuleContext | undefined, invokingState: number);
1888
1899
  get ruleIndex(): number;
@@ -1932,7 +1943,7 @@ export declare class ExprTimeTruncContext extends FieldExprContext {
1932
1943
  export declare class ExprCastContext extends FieldExprContext {
1933
1944
  fieldExpr(): FieldExprContext;
1934
1945
  DOUBLECOLON(): TerminalNode | undefined;
1935
- malloyType(): MalloyTypeContext;
1946
+ malloyOrSQLType(): MalloyOrSQLTypeContext;
1936
1947
  CAST(): TerminalNode | undefined;
1937
1948
  OPAREN(): TerminalNode | undefined;
1938
1949
  AS(): TerminalNode | undefined;
@@ -1945,7 +1956,7 @@ export declare class ExprCastContext extends FieldExprContext {
1945
1956
  export declare class ExprSafeCastContext extends FieldExprContext {
1946
1957
  fieldExpr(): FieldExprContext;
1947
1958
  TRIPLECOLON(): TerminalNode;
1948
- malloyType(): MalloyTypeContext;
1959
+ malloyOrSQLType(): MalloyOrSQLTypeContext;
1949
1960
  constructor(ctx: FieldExprContext);
1950
1961
  enterRule(listener: MalloyParserListener): void;
1951
1962
  exitRule(listener: MalloyParserListener): void;