@malloydata/malloy 0.0.337 → 0.0.338

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.
Files changed (37) hide show
  1. package/dist/api/foundation/result.d.ts +4 -4
  2. package/dist/api/foundation/result.js +9 -9
  3. package/dist/api/foundation/writers.d.ts +1 -1
  4. package/dist/api/foundation/writers.js +9 -8
  5. package/dist/connection/registry.d.ts +1 -1
  6. package/dist/connection/types.d.ts +2 -2
  7. package/dist/dialect/dialect.d.ts +2 -1
  8. package/dist/dialect/dialect.js +3 -0
  9. package/dist/dialect/duckdb/duckdb.js +22 -1
  10. package/dist/dialect/mysql/mysql.d.ts +1 -0
  11. package/dist/dialect/mysql/mysql.js +1 -0
  12. package/dist/dialect/postgres/postgres.d.ts +1 -0
  13. package/dist/dialect/postgres/postgres.js +10 -0
  14. package/dist/dialect/standardsql/standardsql.js +21 -0
  15. package/dist/index.d.ts +2 -2
  16. package/dist/index.js +4 -2
  17. package/dist/lang/ast/expressions/expr-cast.d.ts +3 -3
  18. package/dist/lang/ast/expressions/expr-cast.js +4 -2
  19. package/dist/lang/ast/expressions/expr-func.d.ts +3 -3
  20. package/dist/lang/ast/expressions/expr-func.js +7 -9
  21. package/dist/lang/ast/expressions/for-range.js +1 -1
  22. package/dist/lang/ast/source-elements/named-source.js +4 -2
  23. package/dist/lang/ast/time-utils.d.ts +2 -2
  24. package/dist/lang/ast/time-utils.js +4 -5
  25. package/dist/lang/lib/Malloy/MalloyParser.d.ts +88 -45
  26. package/dist/lang/lib/Malloy/MalloyParser.js +2193 -1862
  27. package/dist/lang/lib/Malloy/MalloyParserListener.d.ts +33 -0
  28. package/dist/lang/lib/Malloy/MalloyParserVisitor.d.ts +21 -0
  29. package/dist/lang/malloy-to-ast.d.ts +4 -4
  30. package/dist/lang/malloy-to-ast.js +38 -22
  31. package/dist/model/malloy_types.d.ts +11 -8
  32. package/dist/model/malloy_types.js +23 -15
  33. package/dist/model/utils.d.ts +3 -5
  34. package/dist/model/utils.js +6 -10
  35. package/dist/version.d.ts +1 -1
  36. package/dist/version.js +1 -1
  37. package/package.json +5 -6
@@ -1,4 +1,4 @@
1
- import type { QueryData, QueryDataRow, QueryResult, QueryRunStats, ModelDef } from '../../model';
1
+ import type { QueryData, QueryRecord, QueryResult, QueryRunStats, ModelDef } from '../../model';
2
2
  import type { Explore, Field, AtomicField, StringField, NumberField, BooleanField, DateField, TimestampField, JSONField, UnsupportedField } from './core';
3
3
  import { PreparedResult } from './core';
4
4
  export type ResultJSON = {
@@ -163,17 +163,17 @@ export declare class DataRecord extends Data<{
163
163
  protected _field: Explore;
164
164
  readonly index: number | undefined;
165
165
  private cellCache;
166
- constructor(queryDataRow: QueryDataRow, index: number | undefined, field: Explore, parent: DataArrayOrRecord | undefined, parentRecord: DataRecord | undefined);
166
+ constructor(queryDataRow: QueryRecord, index: number | undefined, field: Explore, parent: DataArrayOrRecord | undefined, parentRecord: DataRecord | undefined);
167
167
  /**
168
168
  * @return Normalized data with JS native types (number | bigint, Date).
169
169
  * Use this for CSV output, tests, and general programmatic access.
170
170
  */
171
- toObject(): QueryDataRow;
171
+ toObject(): QueryRecord;
172
172
  /**
173
173
  * @return Normalized data with JSON-safe types (numbers as number | string, dates as ISO strings).
174
174
  * Use this for JSON serialization.
175
175
  */
176
- toJSON(): QueryDataRow;
176
+ toJSON(): QueryRecord;
177
177
  path(...path: (number | string)[]): DataColumn;
178
178
  cell(fieldOrName: string | Field): DataColumn;
179
179
  get value(): {
@@ -406,12 +406,12 @@ const JSON_NORMALIZERS = {
406
406
  * Walk a QueryData array and normalize values according to the given normalizers.
407
407
  */
408
408
  function walkQueryData(data, structDef, normalizers) {
409
- return data.map(row => walkQueryDataRow(row, structDef, normalizers));
409
+ return data.map(row => walkQueryRecord(row, structDef, normalizers));
410
410
  }
411
411
  /**
412
- * Walk a QueryDataRow and normalize values according to the given normalizers.
412
+ * Walk a QueryRecord and normalize values according to the given normalizers.
413
413
  */
414
- function walkQueryDataRow(row, structDef, normalizers) {
414
+ function walkQueryRecord(row, structDef, normalizers) {
415
415
  var _a;
416
416
  const result = {};
417
417
  for (const fieldDef of structDef.fields) {
@@ -458,7 +458,7 @@ function walkValue(value, fieldDef, normalizers) {
458
458
  }
459
459
  if ((0, model_1.isRepeatedRecord)(fieldDef)) {
460
460
  // Array of records - recurse into each record
461
- return value.map(item => walkQueryDataRow(item, fieldDef, normalizers));
461
+ return value.map(item => walkQueryRecord(item, fieldDef, normalizers));
462
462
  }
463
463
  else if ((0, model_1.isBasicArray)(fieldDef)) {
464
464
  // Scalar array - normalize each element based on elementTypeDef
@@ -470,7 +470,7 @@ function walkValue(value, fieldDef, normalizers) {
470
470
  // Handle records (non-array)
471
471
  if (fieldDef.type === 'record') {
472
472
  if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
473
- return walkQueryDataRow(value, fieldDef, normalizers);
473
+ return walkQueryRecord(value, fieldDef, normalizers);
474
474
  }
475
475
  }
476
476
  // Fallback - pass through
@@ -505,7 +505,7 @@ function walkScalarValue(value, typeDef, normalizers) {
505
505
  return value.map(item => walkScalarValue(item, elementType, normalizers));
506
506
  }
507
507
  else if ((0, model_1.isRepeatedRecord)(typeDef)) {
508
- return value.map(item => walkQueryDataRow(item, typeDef, normalizers));
508
+ return value.map(item => walkQueryRecord(item, typeDef, normalizers));
509
509
  }
510
510
  }
511
511
  // Pass through other types
@@ -612,14 +612,14 @@ class DataRecord extends Data {
612
612
  * Use this for CSV output, tests, and general programmatic access.
613
613
  */
614
614
  toObject() {
615
- return walkQueryDataRow(this.queryDataRow, this._field.structDef, OBJECT_NORMALIZERS);
615
+ return walkQueryRecord(this.queryDataRow, this._field.structDef, OBJECT_NORMALIZERS);
616
616
  }
617
617
  /**
618
618
  * @return Normalized data with JSON-safe types (numbers as number | string, dates as ISO strings).
619
619
  * Use this for JSON serialization.
620
620
  */
621
621
  toJSON() {
622
- return walkQueryDataRow(this.queryDataRow, this._field.structDef, JSON_NORMALIZERS);
622
+ return walkQueryRecord(this.queryDataRow, this._field.structDef, JSON_NORMALIZERS);
623
623
  }
624
624
  path(...path) {
625
625
  return getPath(this, path);
@@ -657,7 +657,7 @@ class DataRecord extends Data {
657
657
  }
658
658
  }
659
659
  else if (field.isExploreField()) {
660
- if (Array.isArray(value)) {
660
+ if ((0, model_1.isCompoundArrayData)(value)) {
661
661
  column = new DataArray(value, field, this, this);
662
662
  }
663
663
  else {
@@ -15,7 +15,7 @@ export declare class JSONWriter extends DataWriter {
15
15
  * CSV writer class that handles nested data.
16
16
  * This writer creates CSV using a DFS traversal of the result dataset.
17
17
  * Each trivial column value is converted to a CSV of 1x1 matrix and all the
18
- * columns are merged together to create a CSV that represents 1 QueryDataRow.
18
+ * columns are merged together to create a CSV that represents 1 QueryRecord.
19
19
  * Since this follows DFS, each non trivial data is rendered into a NxM matrix
20
20
  * where N is the number of rows in the nested data and M is the number of
21
21
  * columns it has.
@@ -5,6 +5,7 @@
5
5
  */
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
7
  exports.CSVWriter = exports.JSONWriter = exports.DataWriter = void 0;
8
+ const model_1 = require("../../model");
8
9
  // =============================================================================
9
10
  // DataWriter Base Class
10
11
  // =============================================================================
@@ -47,7 +48,7 @@ exports.JSONWriter = JSONWriter;
47
48
  * CSV writer class that handles nested data.
48
49
  * This writer creates CSV using a DFS traversal of the result dataset.
49
50
  * Each trivial column value is converted to a CSV of 1x1 matrix and all the
50
- * columns are merged together to create a CSV that represents 1 QueryDataRow.
51
+ * columns are merged together to create a CSV that represents 1 QueryRecord.
51
52
  * Since this follows DFS, each non trivial data is rendered into a NxM matrix
52
53
  * where N is the number of rows in the nested data and M is the number of
53
54
  * columns it has.
@@ -108,7 +109,7 @@ class CSVWriter extends DataWriter {
108
109
  for (const key in firstVal) {
109
110
  numKeys = numKeys + 1;
110
111
  const val = firstVal[key];
111
- if (Array.isArray(val)) {
112
+ if ((0, model_1.isCompoundArrayData)(val)) {
112
113
  const weight = this.getColWeight(val) - 1;
113
114
  numKeys = numKeys + weight;
114
115
  }
@@ -123,7 +124,7 @@ class CSVWriter extends DataWriter {
123
124
  csv.push(this.escape(key));
124
125
  const val = row[key];
125
126
  width++;
126
- if (Array.isArray(val)) {
127
+ if ((0, model_1.isCompoundArrayData)(val)) {
127
128
  const numKeys = this.getColWeight(val) - 1;
128
129
  width = width + numKeys;
129
130
  for (let i = 0; i < numKeys; i++) {
@@ -193,7 +194,11 @@ class CSVWriter extends DataWriter {
193
194
  const matrices = [];
194
195
  for (const key in row) {
195
196
  const val = row[key];
196
- if (!Array.isArray(val)) {
197
+ if ((0, model_1.isCompoundArrayData)(val)) {
198
+ const cell = this.getChildMatrix(val);
199
+ matrices.push(cell);
200
+ }
201
+ else {
197
202
  const cell = {
198
203
  rows: [this.stringify(val)],
199
204
  length: 1,
@@ -201,10 +206,6 @@ class CSVWriter extends DataWriter {
201
206
  };
202
207
  matrices.push(cell);
203
208
  }
204
- else {
205
- const cell = this.getChildMatrix(val);
206
- matrices.push(cell);
207
- }
208
209
  }
209
210
  return this.mergeMatrices(matrices);
210
211
  }
@@ -6,7 +6,7 @@ export type ConnectionTypeFactory = (config: ConnectionConfig) => Connection;
6
6
  /**
7
7
  * The type of a connection property value.
8
8
  */
9
- export type ConnectionPropertyType = 'string' | 'number' | 'boolean' | 'password' | 'file';
9
+ export type ConnectionPropertyType = 'string' | 'number' | 'boolean' | 'password' | 'file' | 'text';
10
10
  /**
11
11
  * Describes a single configuration property for a connection type.
12
12
  */
@@ -1,5 +1,5 @@
1
1
  import type { RunSQLOptions } from '../run_sql_options';
2
- import type { Annotation, MalloyQueryData, QueryDataRow, QueryRunStats, SQLSourceDef, TableSourceDef } from '../model/malloy_types';
2
+ import type { Annotation, MalloyQueryData, QueryRecord, QueryRunStats, SQLSourceDef, TableSourceDef } from '../model/malloy_types';
3
3
  import type { SQLSourceRequest } from '../lang/translate-response';
4
4
  /**
5
5
  * Options passed to fetchSchema methods.
@@ -90,7 +90,7 @@ export interface PersistSQLResults extends Connection {
90
90
  manifestTemporaryTable(sqlCommand: string): Promise<string>;
91
91
  }
92
92
  export interface StreamingConnection extends Connection {
93
- runSQLStream(sqlCommand: string, options?: RunSQLOptions): AsyncIterableIterator<QueryDataRow>;
93
+ runSQLStream(sqlCommand: string, options?: RunSQLOptions): AsyncIterableIterator<QueryRecord>;
94
94
  }
95
95
  /**
96
96
  * A mapping of connection names to connections.
@@ -74,6 +74,7 @@ export declare abstract class Dialect {
74
74
  supportsBigIntPrecision: boolean;
75
75
  supportsComplexFilteredSources: boolean;
76
76
  supportsTempTables: boolean;
77
+ maxIdentifierLength: number;
77
78
  hasModOperator: boolean;
78
79
  supportsLeftJoinUnnest: boolean;
79
80
  requiresExplicitUnnestOrdering: boolean;
@@ -368,7 +369,7 @@ export declare abstract class Dialect {
368
369
  sqlCastPrep(cast: TypecastExpr): {
369
370
  op: string;
370
371
  srcTypeDef: BasicAtomicTypeDef | undefined;
371
- dstTypeDef: BasicAtomicTypeDef | undefined;
372
+ dstTypeDef: AtomicTypeDef | undefined;
372
373
  dstSQLType: string;
373
374
  };
374
375
  /**
@@ -95,6 +95,9 @@ class Dialect {
95
95
  this.supportsComplexFilteredSources = true;
96
96
  // can create temp tables
97
97
  this.supportsTempTables = true;
98
+ // Maximum length of a table/view identifier. Used to truncate
99
+ // generated temp table names. 128 is a safe default for most databases.
100
+ this.maxIdentifierLength = 128;
98
101
  this.hasModOperator = true;
99
102
  // can LEFT JOIN UNNEST
100
103
  this.supportsLeftJoinUnnest = true;
@@ -289,9 +289,30 @@ class DuckDBDialect extends pg_impl_1.PostgresBase {
289
289
  else if (malloyType.type === 'string') {
290
290
  return 'varchar';
291
291
  }
292
- if (malloyType.type === 'timestamptz') {
292
+ else if (malloyType.type === 'timestamptz') {
293
293
  return 'timestamp with time zone';
294
294
  }
295
+ else if (malloyType.type === 'record') {
296
+ const typeSpec = [];
297
+ for (const f of malloyType.fields) {
298
+ if ((0, malloy_types_1.isAtomic)(f)) {
299
+ typeSpec.push(`${this.sqlMaybeQuoteIdentifier(f.name)} ${this.malloyTypeToSQLType(f)}`);
300
+ }
301
+ }
302
+ return `STRUCT(${typeSpec.join(', ')})`;
303
+ }
304
+ else if (malloyType.type === 'array') {
305
+ if ((0, malloy_types_1.isRepeatedRecord)(malloyType)) {
306
+ const typeSpec = [];
307
+ for (const f of malloyType.fields) {
308
+ if ((0, malloy_types_1.isAtomic)(f)) {
309
+ typeSpec.push(`${this.sqlMaybeQuoteIdentifier(f.name)} ${this.malloyTypeToSQLType(f)}`);
310
+ }
311
+ }
312
+ return `STRUCT(${typeSpec.join(', ')})[]`;
313
+ }
314
+ return `${this.malloyTypeToSQLType(malloyType.elementTypeDef)}[]`;
315
+ }
295
316
  return malloyType.type;
296
317
  }
297
318
  parseDuckDBType(sqlType) {
@@ -31,6 +31,7 @@ export declare class MySQLDialect extends Dialect {
31
31
  compoundObjectInSchema: boolean;
32
32
  booleanType: BooleanTypeSupport;
33
33
  orderByClause: OrderByClauseType;
34
+ maxIdentifierLength: number;
34
35
  malloyTypeToSQLType(malloyType: AtomicTypeDef): string;
35
36
  sqlTypeToMalloyType(sqlType: string): BasicAtomicTypeDef;
36
37
  quoteTablePath(tablePath: string): string;
@@ -120,6 +120,7 @@ class MySQLDialect extends dialect_1.Dialect {
120
120
  this.compoundObjectInSchema = false;
121
121
  this.booleanType = 'simulated';
122
122
  this.orderByClause = 'ordinal';
123
+ this.maxIdentifierLength = 64;
123
124
  }
124
125
  malloyTypeToSQLType(malloyType) {
125
126
  switch (malloyType.type) {
@@ -26,6 +26,7 @@ export declare class PostgresDialect extends PostgresBase {
26
26
  supportsComplexFilteredSources: boolean;
27
27
  compoundObjectInSchema: boolean;
28
28
  likeEscape: boolean;
29
+ maxIdentifierLength: number;
29
30
  quoteTablePath(tablePath: string): string;
30
31
  sqlGroupSetTable(groupSetCount: number): string;
31
32
  sqlAnyValue(groupSet: number, fieldName: string): string;
@@ -97,6 +97,7 @@ class PostgresDialect extends pg_impl_1.PostgresBase {
97
97
  this.supportsComplexFilteredSources = false;
98
98
  this.compoundObjectInSchema = false;
99
99
  this.likeEscape = false;
100
+ this.maxIdentifierLength = 63;
100
101
  }
101
102
  quoteTablePath(tablePath) {
102
103
  return tablePath
@@ -331,6 +332,15 @@ class PostgresDialect extends pg_impl_1.PostgresBase {
331
332
  else if (malloyType.type === 'string') {
332
333
  return 'varchar';
333
334
  }
335
+ else if (malloyType.type === 'record') {
336
+ throw new Error('PostgreSQL does not support CAST to record type');
337
+ }
338
+ else if (malloyType.type === 'array') {
339
+ if ((0, malloy_types_1.isRepeatedRecord)(malloyType)) {
340
+ throw new Error('PostgreSQL does not support CAST to array of records');
341
+ }
342
+ return `${this.malloyTypeToSQLType(malloyType.elementTypeDef)}[]`;
343
+ }
334
344
  return malloyType.type;
335
345
  }
336
346
  sqlTypeToMalloyType(rawSqlType) {
@@ -377,6 +377,27 @@ ${(0, utils_1.indent)(sql)}
377
377
  return 'FLOAT64';
378
378
  }
379
379
  }
380
+ else if (malloyType.type === 'record') {
381
+ const typeSpec = [];
382
+ for (const f of malloyType.fields) {
383
+ if ((0, malloy_types_1.isAtomic)(f)) {
384
+ typeSpec.push(`${f.name} ${this.malloyTypeToSQLType(f)}`);
385
+ }
386
+ }
387
+ return `STRUCT<${typeSpec.join(', ')}>`;
388
+ }
389
+ else if (malloyType.type === 'array') {
390
+ if ((0, malloy_types_1.isRepeatedRecord)(malloyType)) {
391
+ const typeSpec = [];
392
+ for (const f of malloyType.fields) {
393
+ if ((0, malloy_types_1.isAtomic)(f)) {
394
+ typeSpec.push(`${f.name} ${this.malloyTypeToSQLType(f)}`);
395
+ }
396
+ }
397
+ return `ARRAY<STRUCT<${typeSpec.join(', ')}>>`;
398
+ }
399
+ return `ARRAY<${this.malloyTypeToSQLType(malloyType.elementTypeDef)}>`;
400
+ }
380
401
  return malloyType.type;
381
402
  }
382
403
  sqlTypeToMalloyType(sqlType) {
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  export { DuckDBDialect, StandardSQLDialect, TrinoDialect, PostgresDialect, SnowflakeDialect, MySQLDialect, registerDialect, arg, qtz, overload, minScalar, anyExprType, minAggregate, maxScalar, sql, makeParam, param, variadicParam, literal, spread, Dialect, TinyParser, } from './dialect';
2
2
  export type { DialectFieldList, DialectFunctionOverloadDef, QueryInfo, MalloyStandardFunctionImplementations, DefinitionBlueprint, DefinitionBlueprintMap, OverloadedDefinitionBlueprint, TinyToken, } from './dialect';
3
- export type { QueryDataRow, StructDef, TableSourceDef, SQLSourceDef, SourceDef, JoinFieldDef, NamedSourceDefs, MalloyQueryData, DateUnit, ExtractUnit, TimestampUnit, TemporalFieldType, QueryData, QueryValue, Expr, FilterCondition, Argument, Parameter, FieldDef, PipeSegment, QueryFieldDef, IndexFieldDef, TurtleDef, SearchValueMapResult, SearchIndexResult, ModelDef, Query, QueryResult, QueryResultDef, QueryRunStats, QueryScalar, NamedQueryDef, NamedModelObject, ExpressionType, FunctionDef, FunctionOverloadDef, FunctionParameterDef, ExpressionValueType, TypeDesc, FunctionParamTypeDesc, DocumentLocation, DocumentRange, DocumentPosition, Sampling, Annotation, BasicAtomicTypeDef, BasicAtomicDef, AtomicTypeDef, AtomicFieldDef, ArrayDef, ArrayTypeDef, RecordTypeDef, RepeatedRecordTypeDef, RecordDef, RepeatedRecordDef, RecordLiteralNode, StringLiteralNode, ArrayLiteralNode, SourceComponentInfo, DateLiteralNode, TimestampLiteralNode, TimestamptzLiteralNode, TimeLiteralExpr, TypecastExpr, BuildManifest, BuildManifestEntry, } from './model';
4
- export { isSourceDef, isBasicAtomic, isJoined, isJoinedSource, isSamplingEnable, isSamplingPercent, isSamplingRows, isRepeatedRecord, isBasicArray, mkArrayDef, mkFieldDef, expressionIsAggregate, expressionIsAnalytic, expressionIsCalculation, expressionIsScalar, expressionIsUngroupedAggregate, indent, composeSQLExpr, isTimestampUnit, isDateUnit, constantExprToSQL, } from './model';
3
+ export type { QueryRecord, StructDef, TableSourceDef, SQLSourceDef, SourceDef, JoinFieldDef, NamedSourceDefs, MalloyQueryData, DateUnit, ExtractUnit, TimestampUnit, TemporalFieldType, QueryData, QueryValue, Expr, FilterCondition, Argument, Parameter, FieldDef, PipeSegment, QueryFieldDef, IndexFieldDef, TurtleDef, SearchValueMapResult, SearchIndexResult, ModelDef, Query, QueryResult, QueryResultDef, QueryRunStats, QueryScalar, NamedQueryDef, NamedModelObject, ExpressionType, FunctionDef, FunctionOverloadDef, FunctionParameterDef, ExpressionValueType, TypeDesc, FunctionParamTypeDesc, DocumentLocation, DocumentRange, DocumentPosition, Sampling, Annotation, BasicAtomicTypeDef, BasicAtomicDef, AtomicTypeDef, AtomicFieldDef, ArrayDef, ArrayTypeDef, RecordTypeDef, RepeatedRecordTypeDef, RecordDef, RepeatedRecordDef, RecordLiteralNode, StringLiteralNode, ArrayLiteralNode, SourceComponentInfo, DateLiteralNode, TimestampLiteralNode, TimestamptzLiteralNode, TimeLiteralExpr, TypecastExpr, BuildManifest, BuildManifestEntry, } from './model';
4
+ export { isSourceDef, isAtomic, isBasicAtomic, isCompoundArrayData, isJoined, isJoinedSource, isSamplingEnable, isSamplingPercent, isSamplingRows, isRepeatedRecord, isBasicArray, mkArrayDef, mkFieldDef, expressionIsAggregate, expressionIsAnalytic, expressionIsCalculation, expressionIsScalar, expressionIsUngroupedAggregate, indent, composeSQLExpr, isTimestampUnit, isDateUnit, constantExprToSQL, } from './model';
5
5
  export { malloyToQuery, MalloyTranslator, } from './lang';
6
6
  export type { LogMessage, TranslateResponse } from './lang';
7
7
  export { Model, Malloy, Runtime, AtomicFieldType, ConnectionRuntime, SingleConnectionRuntime, EmptyURLReader, InMemoryURLReader, FixedConnectionMap, MalloyError, JoinRelationship, SourceRelationship, DateTimeframe, TimestampTimeframe, PreparedResult, Result, QueryMaterializer, CSVWriter, JSONWriter, Parse, DataWriter, Explore, InMemoryModelCache, CacheManager, } from './api/foundation';
package/dist/index.js CHANGED
@@ -33,8 +33,8 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.ConnectionRuntime = exports.AtomicFieldType = exports.Runtime = exports.Malloy = exports.Model = exports.MalloyTranslator = exports.malloyToQuery = exports.constantExprToSQL = exports.isDateUnit = exports.isTimestampUnit = exports.composeSQLExpr = exports.indent = exports.expressionIsUngroupedAggregate = exports.expressionIsScalar = exports.expressionIsCalculation = exports.expressionIsAnalytic = exports.expressionIsAggregate = exports.mkFieldDef = exports.mkArrayDef = exports.isBasicArray = exports.isRepeatedRecord = exports.isSamplingRows = exports.isSamplingPercent = exports.isSamplingEnable = exports.isJoinedSource = exports.isJoined = exports.isBasicAtomic = exports.isSourceDef = exports.TinyParser = exports.Dialect = exports.spread = exports.literal = exports.variadicParam = exports.param = exports.makeParam = exports.sql = exports.maxScalar = exports.minAggregate = exports.anyExprType = exports.minScalar = exports.overload = exports.qtz = exports.arg = exports.registerDialect = exports.MySQLDialect = exports.SnowflakeDialect = exports.PostgresDialect = exports.TrinoDialect = exports.StandardSQLDialect = exports.DuckDBDialect = void 0;
37
- exports.makeDigest = exports.PersistSource = exports.annotationToTaglines = exports.annotationToTag = exports.sqlKey = exports.API = exports.extractMalloyObjectFromTag = exports.writeMalloyObjectToTag = exports.sourceDefToSourceInfo = exports.modelDefToModelInfo = exports.toAsyncGenerator = exports.createConnectionsFromConfig = exports.writeConnectionsConfig = exports.readConnectionsConfig = exports.getRegisteredConnectionTypes = exports.getConnectionProperties = exports.registerConnectionType = exports.CacheManager = exports.InMemoryModelCache = exports.Explore = exports.DataWriter = exports.Parse = exports.JSONWriter = exports.CSVWriter = exports.QueryMaterializer = exports.Result = exports.PreparedResult = exports.TimestampTimeframe = exports.DateTimeframe = exports.SourceRelationship = exports.JoinRelationship = exports.MalloyError = exports.FixedConnectionMap = exports.InMemoryURLReader = exports.EmptyURLReader = exports.SingleConnectionRuntime = void 0;
36
+ exports.Runtime = exports.Malloy = exports.Model = exports.MalloyTranslator = exports.malloyToQuery = exports.constantExprToSQL = exports.isDateUnit = exports.isTimestampUnit = exports.composeSQLExpr = exports.indent = exports.expressionIsUngroupedAggregate = exports.expressionIsScalar = exports.expressionIsCalculation = exports.expressionIsAnalytic = exports.expressionIsAggregate = exports.mkFieldDef = exports.mkArrayDef = exports.isBasicArray = exports.isRepeatedRecord = exports.isSamplingRows = exports.isSamplingPercent = exports.isSamplingEnable = exports.isJoinedSource = exports.isJoined = exports.isCompoundArrayData = exports.isBasicAtomic = exports.isAtomic = exports.isSourceDef = exports.TinyParser = exports.Dialect = exports.spread = exports.literal = exports.variadicParam = exports.param = exports.makeParam = exports.sql = exports.maxScalar = exports.minAggregate = exports.anyExprType = exports.minScalar = exports.overload = exports.qtz = exports.arg = exports.registerDialect = exports.MySQLDialect = exports.SnowflakeDialect = exports.PostgresDialect = exports.TrinoDialect = exports.StandardSQLDialect = exports.DuckDBDialect = void 0;
37
+ exports.makeDigest = exports.PersistSource = exports.annotationToTaglines = exports.annotationToTag = exports.sqlKey = exports.API = exports.extractMalloyObjectFromTag = exports.writeMalloyObjectToTag = exports.sourceDefToSourceInfo = exports.modelDefToModelInfo = exports.toAsyncGenerator = exports.createConnectionsFromConfig = exports.writeConnectionsConfig = exports.readConnectionsConfig = exports.getRegisteredConnectionTypes = exports.getConnectionProperties = exports.registerConnectionType = exports.CacheManager = exports.InMemoryModelCache = exports.Explore = exports.DataWriter = exports.Parse = exports.JSONWriter = exports.CSVWriter = exports.QueryMaterializer = exports.Result = exports.PreparedResult = exports.TimestampTimeframe = exports.DateTimeframe = exports.SourceRelationship = exports.JoinRelationship = exports.MalloyError = exports.FixedConnectionMap = exports.InMemoryURLReader = exports.EmptyURLReader = exports.SingleConnectionRuntime = exports.ConnectionRuntime = exports.AtomicFieldType = void 0;
38
38
  /*
39
39
  * Copyright 2023 Google LLC
40
40
  *
@@ -83,7 +83,9 @@ Object.defineProperty(exports, "TinyParser", { enumerable: true, get: function (
83
83
  var model_1 = require("./model");
84
84
  Object.defineProperty(exports, "isSourceDef", { enumerable: true, get: function () { return model_1.isSourceDef; } });
85
85
  // Used in Composer Demo
86
+ Object.defineProperty(exports, "isAtomic", { enumerable: true, get: function () { return model_1.isAtomic; } });
86
87
  Object.defineProperty(exports, "isBasicAtomic", { enumerable: true, get: function () { return model_1.isBasicAtomic; } });
88
+ Object.defineProperty(exports, "isCompoundArrayData", { enumerable: true, get: function () { return model_1.isCompoundArrayData; } });
87
89
  Object.defineProperty(exports, "isJoined", { enumerable: true, get: function () { return model_1.isJoined; } });
88
90
  Object.defineProperty(exports, "isJoinedSource", { enumerable: true, get: function () { return model_1.isJoinedSource; } });
89
91
  Object.defineProperty(exports, "isSamplingEnable", { enumerable: true, get: function () { return model_1.isSamplingEnable; } });
@@ -1,15 +1,15 @@
1
- import type { CastType } from '../../../model';
1
+ import type { AtomicTypeDef } from '../../../model/malloy_types';
2
2
  import type { ExprValue } from '../types/expr-value';
3
3
  import { ExpressionDef } from '../types/expression-def';
4
4
  import type { FieldSpace } from '../types/field-space';
5
5
  export declare class ExprCast extends ExpressionDef {
6
6
  readonly expr: ExpressionDef;
7
- readonly castType: CastType | {
7
+ readonly castType: AtomicTypeDef | {
8
8
  raw: string;
9
9
  };
10
10
  readonly safe: boolean;
11
11
  elementType: string;
12
- constructor(expr: ExpressionDef, castType: CastType | {
12
+ constructor(expr: ExpressionDef, castType: AtomicTypeDef | {
13
13
  raw: string;
14
14
  }, safe?: boolean);
15
15
  getExpression(fs: FieldSpace): ExprValue;
@@ -34,11 +34,13 @@ class ExprCast extends expression_def_1.ExpressionDef {
34
34
  this.safe = safe;
35
35
  this.elementType = 'cast';
36
36
  }
37
+ // TODO: Validate senseless casts (e.g. scalar to record) at translate time
38
+ // for better error messages than what the dialect/database produces.
37
39
  getExpression(fs) {
38
40
  const expr = this.expr.getExpression(fs);
39
41
  let dataType = { type: 'error' };
40
- if (typeof this.castType === 'string') {
41
- dataType = { type: this.castType };
42
+ if ('type' in this.castType) {
43
+ dataType = this.castType;
42
44
  }
43
45
  else {
44
46
  const dialect = fs.dialectObj();
@@ -1,4 +1,4 @@
1
- import type { CastType } from '../../../model/malloy_types';
1
+ import type { AtomicTypeDef } from '../../../model/malloy_types';
2
2
  import type { FieldReference } from '../query-items/field-references';
3
3
  import type { FunctionOrdering } from './function-ordering';
4
4
  import type { Limit } from '../query-properties/limit';
@@ -10,10 +10,10 @@ export declare class ExprFunc extends ExpressionDef {
10
10
  readonly name: string;
11
11
  readonly args: ExpressionDef[];
12
12
  readonly isRaw: boolean;
13
- readonly rawType: CastType | undefined;
13
+ readonly explicitType: AtomicTypeDef | undefined;
14
14
  readonly source?: FieldReference | undefined;
15
15
  elementType: string;
16
- constructor(name: string, args: ExpressionDef[], isRaw: boolean, rawType: CastType | undefined, source?: FieldReference | undefined);
16
+ constructor(name: string, args: ExpressionDef[], isRaw: boolean, explicitType: AtomicTypeDef | undefined, source?: FieldReference | undefined);
17
17
  canSupportPartitionBy(): boolean;
18
18
  canSupportOrderBy(): boolean;
19
19
  canSupportLimit(): boolean;
@@ -66,12 +66,12 @@ const utils_1 = require("../../../model/utils");
66
66
  const TDU = __importStar(require("../typedesc-utils"));
67
67
  const composite_source_utils_1 = require("../../composite-source-utils");
68
68
  class ExprFunc extends expression_def_1.ExpressionDef {
69
- constructor(name, args, isRaw, rawType, source) {
69
+ constructor(name, args, isRaw, explicitType, source) {
70
70
  super({ args: args });
71
71
  this.name = name;
72
72
  this.args = args;
73
73
  this.isRaw = isRaw;
74
- this.rawType = rawType;
74
+ this.explicitType = explicitType;
75
75
  this.source = source;
76
76
  this.elementType = 'function call()';
77
77
  this.has({ source: source });
@@ -111,7 +111,7 @@ class ExprFunc extends expression_def_1.ExpressionDef {
111
111
  return { found: func, error: undefined };
112
112
  }
113
113
  getPropsExpression(fs, props) {
114
- var _a, _b, _c, _d;
114
+ var _a, _b, _c, _d, _e;
115
115
  const argExprsWithoutImplicit = this.args.map(arg => arg.getExpression(fs));
116
116
  if (this.isRaw) {
117
117
  const funcCall = [`${this.name}(`];
@@ -123,16 +123,14 @@ class ExprFunc extends expression_def_1.ExpressionDef {
123
123
  });
124
124
  funcCall.push(')');
125
125
  const inferredType = (_a = argExprsWithoutImplicit[0]) !== null && _a !== void 0 ? _a : { type: 'number' };
126
- const dataType = this.rawType
127
- ? { type: this.rawType }
128
- : inferredType;
126
+ const dataType = (_b = this.explicitType) !== null && _b !== void 0 ? _b : inferredType;
129
127
  return (0, expr_value_1.computedExprValue)({
130
128
  dataType,
131
129
  value: (0, utils_1.composeSQLExpr)(funcCall),
132
130
  from: argExprsWithoutImplicit,
133
131
  });
134
132
  }
135
- const dialect = (_b = fs.dialectObj()) === null || _b === void 0 ? void 0 : _b.name;
133
+ const dialect = (_c = fs.dialectObj()) === null || _c === void 0 ? void 0 : _c.name;
136
134
  const { found: func, error } = this.findFunctionDef(dialect);
137
135
  if (func === undefined) {
138
136
  return (0, ast_utils_1.errorFor)(error);
@@ -140,7 +138,7 @@ class ExprFunc extends expression_def_1.ExpressionDef {
140
138
  // Find the 'implicit argument' for aggregate functions called like `some_join.some_field.agg(...args)`
141
139
  // where the full arg list is `(some_field, ...args)`.
142
140
  let implicitExpr = undefined;
143
- let structPath = (_c = this.source) === null || _c === void 0 ? void 0 : _c.path;
141
+ let structPath = (_d = this.source) === null || _d === void 0 ? void 0 : _d.path;
144
142
  if (this.source) {
145
143
  const lookup = this.source.getField(fs);
146
144
  const sourceFoot = lookup.found;
@@ -214,7 +212,7 @@ class ExprFunc extends expression_def_1.ExpressionDef {
214
212
  }
215
213
  const type = overload.returnType;
216
214
  const expressionType = (0, malloy_types_1.maxOfExpressionTypes)([
217
- (_d = type.expressionType) !== null && _d !== void 0 ? _d : 'scalar',
215
+ (_e = type.expressionType) !== null && _e !== void 0 ? _e : 'scalar',
218
216
  ...argExprs.map(e => e.expressionType),
219
217
  ]);
220
218
  if (!(0, malloy_types_1.expressionIsAggregate)(overload.returnType.expressionType) &&
@@ -117,7 +117,7 @@ class ForRange extends expression_def_1.ExpressionDef {
117
117
  from = tsVersion;
118
118
  }
119
119
  else {
120
- from = (0, time_utils_1.castTo)('timestamp', from, 'date');
120
+ from = (0, time_utils_1.castTo)({ type: 'timestamp' }, from, 'date');
121
121
  }
122
122
  rangeStart = new expr_time_1.ExprTime('timestamp', from, [startV]);
123
123
  }
@@ -154,8 +154,10 @@ class NamedSource extends source_1.Source {
154
154
  (0, expression_def_1.checkFilterExpression)(argument.value, parameter.filterType, value);
155
155
  }
156
156
  }
157
- if (pVal.type !== parameter.type && (0, malloy_types_1.isCastType)(parameter.type)) {
158
- value = (0, time_utils_1.castTo)(parameter.type, pVal.value, pVal.type, true);
157
+ // NOTE: isBasicAtomicType guard here excludes compound types from auto-casting.
158
+ // Revisit if parameters can ever have compound types.
159
+ if (pVal.type !== parameter.type && (0, malloy_types_1.isBasicAtomicType)(parameter.type)) {
160
+ value = (0, time_utils_1.castTo)({ type: parameter.type }, pVal.value, pVal.type, true);
159
161
  }
160
162
  outArguments[name] = {
161
163
  ...parameter,
@@ -1,7 +1,7 @@
1
- import type { Expr, TemporalFieldType, TimestampUnit, CastType, TypecastExpr, TimeDeltaExpr, ExpressionValueType } from '../../model/malloy_types';
1
+ import type { AtomicTypeDef, Expr, TemporalFieldType, TimestampUnit, TypecastExpr, TimeDeltaExpr, ExpressionValueType } from '../../model/malloy_types';
2
2
  import type { TimeResult } from './types/time-result';
3
3
  export declare function timeOffset(timeType: TemporalFieldType, from: Expr, op: '+' | '-', n: Expr, timeframe: TimestampUnit): TimeDeltaExpr;
4
- export declare function castTo(castType: CastType | {
4
+ export declare function castTo(castType: AtomicTypeDef | {
5
5
  raw: string;
6
6
  }, from: Expr, fromType: ExpressionValueType, safe?: boolean): TypecastExpr;
7
7
  export declare function resolution(timeframe: string): TemporalFieldType;
@@ -40,24 +40,23 @@ function timeOffset(timeType, from, op, n, timeframe) {
40
40
  }
41
41
  function castTo(castType, from, fromType, safe = false) {
42
42
  let cast;
43
- if (typeof castType !== 'string') {
43
+ if ('type' in castType) {
44
44
  cast = {
45
45
  node: 'cast',
46
- dstSQLType: castType.raw,
46
+ dstType: castType,
47
47
  e: from,
48
48
  safe,
49
49
  };
50
50
  }
51
51
  else {
52
- const dstType = { type: castType };
53
52
  cast = {
54
53
  node: 'cast',
55
- dstType,
54
+ dstSQLType: castType.raw,
56
55
  e: from,
57
56
  safe,
58
57
  };
59
58
  }
60
- if ((0, malloy_types_1.isCastType)(fromType)) {
59
+ if ((0, malloy_types_1.isBasicAtomicType)(fromType)) {
61
60
  cast.srcType = { type: fromType };
62
61
  }
63
62
  return cast;