@malloydata/malloy 0.0.280 → 0.0.282

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 (70) hide show
  1. package/dist/api/core.js +16 -4
  2. package/dist/api/util.d.ts +3 -1
  3. package/dist/api/util.js +63 -5
  4. package/dist/dialect/dialect.d.ts +10 -1
  5. package/dist/dialect/dialect.js +19 -2
  6. package/dist/dialect/mysql/mysql.d.ts +2 -2
  7. package/dist/dialect/mysql/mysql.js +1 -1
  8. package/dist/dialect/standardsql/dialect_functions.js +22 -0
  9. package/dist/index.d.ts +1 -1
  10. package/dist/index.js +4 -2
  11. package/dist/lang/ast/expressions/boolean.d.ts +2 -0
  12. package/dist/lang/ast/expressions/boolean.js +6 -0
  13. package/dist/lang/ast/expressions/expr-func.js +10 -18
  14. package/dist/lang/ast/expressions/expr-not.js +1 -1
  15. package/dist/lang/ast/expressions/expr-number.d.ts +2 -0
  16. package/dist/lang/ast/expressions/expr-number.js +6 -0
  17. package/dist/lang/ast/expressions/expr-string.d.ts +2 -0
  18. package/dist/lang/ast/expressions/expr-string.js +6 -22
  19. package/dist/lang/ast/expressions/time-literal.d.ts +9 -2
  20. package/dist/lang/ast/expressions/time-literal.js +52 -7
  21. package/dist/lang/ast/field-space/def-space.d.ts +16 -0
  22. package/dist/lang/ast/field-space/def-space.js +39 -0
  23. package/dist/lang/ast/field-space/passthrough-space.d.ts +21 -0
  24. package/dist/lang/ast/field-space/passthrough-space.js +56 -0
  25. package/dist/lang/ast/field-space/permissive-space.d.ts +11 -0
  26. package/dist/lang/ast/field-space/permissive-space.js +23 -0
  27. package/dist/lang/ast/field-space/query-spaces.d.ts +6 -0
  28. package/dist/lang/ast/field-space/query-spaces.js +6 -0
  29. package/dist/lang/ast/index.d.ts +2 -0
  30. package/dist/lang/ast/index.js +2 -0
  31. package/dist/lang/ast/query-builders/reduce-builder.js +3 -1
  32. package/dist/lang/ast/query-items/field-declaration.d.ts +3 -26
  33. package/dist/lang/ast/query-items/field-declaration.js +21 -65
  34. package/dist/lang/ast/query-items/field-references.d.ts +4 -0
  35. package/dist/lang/ast/query-items/field-references.js +12 -1
  36. package/dist/lang/ast/query-properties/drill.d.ts +25 -0
  37. package/dist/lang/ast/query-properties/drill.js +323 -0
  38. package/dist/lang/ast/query-properties/filters.d.ts +11 -0
  39. package/dist/lang/ast/query-properties/filters.js +57 -0
  40. package/dist/lang/ast/query-properties/nest.js +3 -1
  41. package/dist/lang/ast/source-elements/named-source.js +7 -4
  42. package/dist/lang/ast/types/literal.d.ts +7 -0
  43. package/dist/lang/ast/types/literal.js +24 -0
  44. package/dist/lang/ast/view-elements/reference-view.js +2 -0
  45. package/dist/lang/lib/Malloy/MalloyLexer.d.ts +165 -164
  46. package/dist/lang/lib/Malloy/MalloyLexer.js +1095 -1085
  47. package/dist/lang/lib/Malloy/MalloyParser.d.ts +262 -236
  48. package/dist/lang/lib/Malloy/MalloyParser.js +2271 -2084
  49. package/dist/lang/lib/Malloy/MalloyParserListener.d.ts +22 -0
  50. package/dist/lang/lib/Malloy/MalloyParserVisitor.d.ts +14 -0
  51. package/dist/lang/malloy-to-ast.d.ts +2 -0
  52. package/dist/lang/malloy-to-ast.js +8 -0
  53. package/dist/lang/malloy-to-stable-query.d.ts +7 -1
  54. package/dist/lang/malloy-to-stable-query.js +191 -8
  55. package/dist/lang/parse-log.d.ts +14 -0
  56. package/dist/lang/test/expr-to-str.js +2 -0
  57. package/dist/lang/test/parse-expects.d.ts +1 -0
  58. package/dist/lang/test/parse-expects.js +8 -0
  59. package/dist/malloy.d.ts +2 -1
  60. package/dist/malloy.js +3 -0
  61. package/dist/model/composite_source_utils.d.ts +1 -0
  62. package/dist/model/composite_source_utils.js +4 -0
  63. package/dist/model/malloy_query.d.ts +2 -2
  64. package/dist/model/malloy_query.js +31 -22
  65. package/dist/model/malloy_types.d.ts +8 -0
  66. package/dist/to_stable.d.ts +2 -0
  67. package/dist/to_stable.js +77 -16
  68. package/dist/version.d.ts +1 -1
  69. package/dist/version.js +1 -1
  70. package/package.json +4 -4
package/dist/api/core.js CHANGED
@@ -415,7 +415,7 @@ function newCompileQueryState(request) {
415
415
  };
416
416
  }
417
417
  function statedCompileQuery(state) {
418
- var _a;
418
+ var _a, _b;
419
419
  const result = _statedCompileModel(state);
420
420
  // TODO this can expose the internal URL... is there a better way to handle URL-less errors from the compiler?
421
421
  const defaultURL = state.translator.sourceURL;
@@ -462,10 +462,22 @@ function statedCompileQuery(state) {
462
462
  const sourceAnnotations = (0, annotation_1.annotationToTaglines)(source.annotation).map(l => ({
463
463
  value: l,
464
464
  }));
465
+ const sourceMetadataTag = malloy_tag_1.Tag.withPrefix('#(malloy) ');
466
+ sourceMetadataTag.set(['source', 'name'], translatedQuery.sourceExplore);
467
+ const sourceArguments = (_b = translatedQuery.sourceArguments) !== null && _b !== void 0 ? _b : ((0, model_1.isSourceDef)(source) ? source.arguments : undefined);
468
+ if (sourceArguments) {
469
+ const args = Object.entries(sourceArguments);
470
+ for (let i = 0; i < args.length; i++) {
471
+ const [name, value] = args[i];
472
+ const literal = (0, util_1.nodeToLiteralValue)(value.value);
473
+ if (literal !== undefined) {
474
+ (0, to_stable_1.writeLiteralToTag)(sourceMetadataTag, ['source', 'parameters', i, 'value'], literal);
475
+ }
476
+ sourceMetadataTag.set(['source', 'parameters', i, 'name'], name);
477
+ }
478
+ }
465
479
  annotations.push({
466
- value: malloy_tag_1.Tag.withPrefix('#(malloy) ')
467
- .set(['source_name'], translatedQuery.sourceExplore)
468
- .toString(),
480
+ value: sourceMetadataTag.toString(),
469
481
  });
470
482
  if (translatedQuery.queryName) {
471
483
  annotations.push({
@@ -1,6 +1,7 @@
1
1
  import type { InfoConnection as LegacyInfoConnection, Connection as LegacyConnection } from '../connection';
2
2
  import type { Result } from '../malloy';
3
- import type { QueryData } from '../model';
3
+ import type { Expr } from '../model';
4
+ import { type QueryData } from '../model';
4
5
  import type { Connection, InfoConnection } from './connection';
5
6
  import type * as Malloy from '@malloydata/malloy-interfaces';
6
7
  import type { LogMessage } from '../lang';
@@ -8,5 +9,6 @@ export declare function wrapLegacyInfoConnection(connection: LegacyInfoConnectio
8
9
  export declare function wrapLegacyConnection(connection: LegacyConnection): Connection;
9
10
  export declare function mapData(data: QueryData, schema: Malloy.Schema): Malloy.Data;
10
11
  export declare function wrapResult(result: Result): Malloy.Result;
12
+ export declare function nodeToLiteralValue(expr?: Expr | null): Malloy.LiteralValue | undefined;
11
13
  export declare const DEFAULT_LOG_RANGE: Malloy.DocumentRange;
12
14
  export declare function mapLogs(logs: LogMessage[], defaultURL: string): Malloy.LogMessage[];
package/dist/api/util.js CHANGED
@@ -11,9 +11,11 @@ exports.wrapLegacyInfoConnection = wrapLegacyInfoConnection;
11
11
  exports.wrapLegacyConnection = wrapLegacyConnection;
12
12
  exports.mapData = mapData;
13
13
  exports.wrapResult = wrapResult;
14
+ exports.nodeToLiteralValue = nodeToLiteralValue;
14
15
  exports.mapLogs = mapLogs;
15
16
  const malloy_tag_1 = require("@malloydata/malloy-tag");
16
17
  const annotation_1 = require("../annotation");
18
+ const model_1 = require("../model");
17
19
  const to_stable_1 = require("../to_stable");
18
20
  const luxon_1 = require("luxon");
19
21
  function wrapLegacyInfoConnection(connection) {
@@ -193,13 +195,22 @@ function wrapResult(result) {
193
195
  annotations.push(metadataAnnot);
194
196
  }
195
197
  annotations.push(...(struct.resultMetadata ? [] : []));
198
+ const sourceMetadataTag = malloy_tag_1.Tag.withPrefix('#(malloy) ');
196
199
  if (result.sourceExplore) {
197
- annotations.push({
198
- value: malloy_tag_1.Tag.withPrefix('#(malloy) ')
199
- .set(['source_name'], result.sourceExplore.name)
200
- .toString(),
201
- });
200
+ sourceMetadataTag.set(['source', 'name'], result.sourceExplore.name);
201
+ }
202
+ if (result._sourceArguments) {
203
+ const args = Object.entries(result._sourceArguments);
204
+ for (let i = 0; i < args.length; i++) {
205
+ const [name, value] = args[i];
206
+ const literal = nodeToLiteralValue(value.value);
207
+ if (literal !== undefined) {
208
+ (0, to_stable_1.writeLiteralToTag)(sourceMetadataTag, ['source', 'parameters', i, 'value'], literal);
209
+ }
210
+ sourceMetadataTag.set(['source', 'parameters', i, 'name'], name);
211
+ }
202
212
  }
213
+ annotations.push({ value: sourceMetadataTag.toString() });
203
214
  annotations.push({
204
215
  value: malloy_tag_1.Tag.withPrefix('#(malloy) ')
205
216
  .set(['query_name'], result.resultExplore.name)
@@ -214,6 +225,53 @@ function wrapResult(result) {
214
225
  sql: result.sql,
215
226
  };
216
227
  }
228
+ function nodeToLiteralValue(expr) {
229
+ switch (expr === null || expr === void 0 ? void 0 : expr.node) {
230
+ case 'numberLiteral':
231
+ return {
232
+ kind: 'number_literal',
233
+ number_value: Number.parseFloat(expr.literal),
234
+ };
235
+ case 'null':
236
+ return { kind: 'null_literal' };
237
+ case 'stringLiteral':
238
+ return { kind: 'string_literal', string_value: expr.literal };
239
+ case 'filterLiteral':
240
+ return {
241
+ kind: 'filter_expression_literal',
242
+ filter_expression_value: expr.filterSrc,
243
+ // TODO type?
244
+ };
245
+ case 'true':
246
+ return { kind: 'boolean_literal', boolean_value: true };
247
+ case 'false':
248
+ return { kind: 'boolean_literal', boolean_value: false };
249
+ case 'timeLiteral': {
250
+ if (expr.typeDef.type === 'date') {
251
+ if (expr.typeDef.timeframe === undefined ||
252
+ (0, model_1.isDateUnit)(expr.typeDef.timeframe)) {
253
+ return {
254
+ kind: 'date_literal',
255
+ date_value: expr.literal,
256
+ timezone: expr.timezone,
257
+ granularity: expr.typeDef.timeframe,
258
+ };
259
+ }
260
+ return undefined;
261
+ }
262
+ else {
263
+ return {
264
+ kind: 'timestamp_literal',
265
+ timestamp_value: expr.literal,
266
+ timezone: expr.timezone,
267
+ granularity: expr.typeDef.timeframe,
268
+ };
269
+ }
270
+ }
271
+ default:
272
+ return undefined;
273
+ }
274
+ }
217
275
  exports.DEFAULT_LOG_RANGE = {
218
276
  start: {
219
277
  line: 0,
@@ -24,6 +24,7 @@ export declare function inDays(units: string): boolean;
24
24
  export declare function qtz(qi: QueryInfo): string | undefined;
25
25
  export type OrderByClauseType = 'output_name' | 'ordinal' | 'expression';
26
26
  export type OrderByRequest = 'query' | 'turtle' | 'analytical';
27
+ export type BooleanTypeSupport = 'supported' | 'simulated' | 'none';
27
28
  export declare abstract class Dialect {
28
29
  abstract name: string;
29
30
  abstract defaultNumberType: string;
@@ -58,7 +59,7 @@ export declare abstract class Dialect {
58
59
  supportsFullJoin: boolean;
59
60
  nestedArrays: boolean;
60
61
  compoundObjectInSchema: boolean;
61
- booleanAsNumbers: boolean;
62
+ booleanType: BooleanTypeSupport;
62
63
  likeEscape: boolean;
63
64
  abstract getDialectFunctionOverrides(): {
64
65
  [name: string]: DialectFunctionOverloadDef[];
@@ -143,5 +144,13 @@ export declare abstract class Dialect {
143
144
  * but some SQL dialects use an ESCAPE clause.
144
145
  */
145
146
  sqlLike(likeOp: 'LIKE' | 'NOT LIKE', left: string, likeStr: string): string;
147
+ /**
148
+ * SQL to generate to get a boolean value for a boolean expression
149
+ */
150
+ sqlBoolean(bv: boolean): string;
151
+ /**
152
+ * What a boolean value looks like in a query result
153
+ */
154
+ resultBoolean(bv: boolean): boolean | 0 | 1;
146
155
  }
147
156
  export {};
@@ -85,8 +85,7 @@ class Dialect {
85
85
  this.nestedArrays = true;
86
86
  // An array or record will reveal type of contents on schema read
87
87
  this.compoundObjectInSchema = true;
88
- // No true boolean type, e.g. true=1 and false=0, set this to true
89
- this.booleanAsNumbers = false;
88
+ this.booleanType = 'supported';
90
89
  // Like characters are escaped with ESCAPE clause
91
90
  this.likeEscape = true;
92
91
  }
@@ -264,6 +263,24 @@ class Dialect {
264
263
  const compare = `${left} ${likeOp} ${this.sqlLiteralString(escaped)}`;
265
264
  return escapeClause ? `${compare} ESCAPE '^'` : compare;
266
265
  }
266
+ /**
267
+ * SQL to generate to get a boolean value for a boolean expression
268
+ */
269
+ sqlBoolean(bv) {
270
+ if (this.booleanType === 'none') {
271
+ return bv ? '(1=1)' : '(1-0)';
272
+ }
273
+ return bv ? 'true' : 'false';
274
+ }
275
+ /**
276
+ * What a boolean value looks like in a query result
277
+ */
278
+ resultBoolean(bv) {
279
+ if (this.booleanType !== 'supported') {
280
+ return bv ? 1 : 0;
281
+ }
282
+ return bv ? true : false;
283
+ }
267
284
  }
268
285
  exports.Dialect = Dialect;
269
286
  //# sourceMappingURL=dialect.js.map
@@ -1,5 +1,5 @@
1
1
  import type { Sampling, MeasureTimeExpr, TimeLiteralNode, RegexMatchExpr, TimeDeltaExpr, TimeTruncExpr, TimeExtractExpr, TypecastExpr, BasicAtomicTypeDef, AtomicTypeDef, ArrayLiteralNode, RecordLiteralNode } from '../../model/malloy_types';
2
- import type { DialectFieldList, FieldReferenceType, OrderByClauseType, QueryInfo } from '../dialect';
2
+ import type { BooleanTypeSupport, DialectFieldList, FieldReferenceType, OrderByClauseType, QueryInfo } from '../dialect';
3
3
  import { Dialect } from '../dialect';
4
4
  import type { DialectFunctionOverloadDef } from '../functions';
5
5
  export declare class MySQLDialect extends Dialect {
@@ -29,7 +29,7 @@ export declare class MySQLDialect extends Dialect {
29
29
  supportsComplexFilteredSources: boolean;
30
30
  supportsArraysInData: boolean;
31
31
  compoundObjectInSchema: boolean;
32
- booleanAsNumbers: boolean;
32
+ booleanType: BooleanTypeSupport;
33
33
  orderByClause: OrderByClauseType;
34
34
  malloyTypeToSQLType(malloyType: AtomicTypeDef): string;
35
35
  sqlTypeToMalloyType(sqlType: string): BasicAtomicTypeDef;
@@ -93,7 +93,7 @@ class MySQLDialect extends dialect_1.Dialect {
93
93
  this.supportsComplexFilteredSources = false;
94
94
  this.supportsArraysInData = false;
95
95
  this.compoundObjectInSchema = false;
96
- this.booleanAsNumbers = true;
96
+ this.booleanType = 'simulated';
97
97
  this.orderByClause = 'ordinal';
98
98
  }
99
99
  malloyTypeToSQLType(malloyType) {
@@ -60,10 +60,32 @@ const string_agg_distinct = {
60
60
  },
61
61
  },
62
62
  };
63
+ const max_by = {
64
+ generic: { 'T': ['string', 'number', 'date', 'timestamp', 'boolean', 'json'] },
65
+ takes: {
66
+ 'value': { dimension: T },
67
+ 'order_by_val': { dimension: 'any' },
68
+ },
69
+ returns: { measure: T },
70
+ impl: { function: 'MAX_BY' },
71
+ isSymmetric: true,
72
+ };
73
+ const min_by = {
74
+ generic: { 'T': ['string', 'number', 'date', 'timestamp', 'boolean', 'json'] },
75
+ takes: {
76
+ 'value': { dimension: T },
77
+ 'order_by_val': { dimension: 'any' },
78
+ },
79
+ returns: { measure: T },
80
+ impl: { function: 'MIN_BY' },
81
+ isSymmetric: true,
82
+ };
63
83
  exports.STANDARDSQL_DIALECT_FUNCTIONS = {
64
84
  date_from_unix_date,
65
85
  string_agg,
66
86
  string_agg_distinct,
87
+ max_by,
88
+ min_by,
67
89
  hll_accumulate: {
68
90
  default: {
69
91
  takes: { 'value': { dimension: T } },
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
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, QueryRunStats, NamedQuery, 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, } from './model';
4
- export { isSourceDef, Segment, isBasicAtomic, isJoined, isJoinedSource, isSamplingEnable, isSamplingPercent, isSamplingRows, isRepeatedRecord, isBasicArray, mkArrayDef, mkFieldDef, expressionIsAggregate, expressionIsAnalytic, expressionIsCalculation, expressionIsScalar, expressionIsUngroupedAggregate, indent, composeSQLExpr, } from './model';
4
+ export { isSourceDef, Segment, isBasicAtomic, isJoined, isJoinedSource, isSamplingEnable, isSamplingPercent, isSamplingRows, isRepeatedRecord, isBasicArray, mkArrayDef, mkFieldDef, expressionIsAggregate, expressionIsAnalytic, expressionIsCalculation, expressionIsScalar, expressionIsUngroupedAggregate, indent, composeSQLExpr, isTimestampUnit, isDateUnit, } 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 './malloy';
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.EmptyURLReader = exports.SingleConnectionRuntime = exports.ConnectionRuntime = exports.AtomicFieldType = exports.Runtime = exports.Malloy = exports.Model = exports.MalloyTranslator = exports.malloyToQuery = 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.Segment = 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.annotationToTaglines = exports.annotationToTag = exports.sqlKey = exports.API = exports.sourceDefToSourceInfo = exports.modelDefToModelInfo = exports.toAsyncGenerator = 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 = void 0;
36
+ exports.ConnectionRuntime = exports.AtomicFieldType = exports.Runtime = exports.Malloy = exports.Model = exports.MalloyTranslator = exports.malloyToQuery = 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.Segment = 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.annotationToTaglines = exports.annotationToTag = exports.sqlKey = exports.API = exports.sourceDefToSourceInfo = exports.modelDefToModelInfo = exports.toAsyncGenerator = 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;
38
38
  /*
39
39
  * Copyright 2023 Google LLC
40
40
  *
@@ -101,6 +101,8 @@ Object.defineProperty(exports, "expressionIsScalar", { enumerable: true, get: fu
101
101
  Object.defineProperty(exports, "expressionIsUngroupedAggregate", { enumerable: true, get: function () { return model_1.expressionIsUngroupedAggregate; } });
102
102
  Object.defineProperty(exports, "indent", { enumerable: true, get: function () { return model_1.indent; } });
103
103
  Object.defineProperty(exports, "composeSQLExpr", { enumerable: true, get: function () { return model_1.composeSQLExpr; } });
104
+ Object.defineProperty(exports, "isTimestampUnit", { enumerable: true, get: function () { return model_1.isTimestampUnit; } });
105
+ Object.defineProperty(exports, "isDateUnit", { enumerable: true, get: function () { return model_1.isDateUnit; } });
104
106
  var lang_1 = require("./lang");
105
107
  Object.defineProperty(exports, "malloyToQuery", { enumerable: true, get: function () { return lang_1.malloyToQuery; } });
106
108
  // Needed for tests only
@@ -1,3 +1,4 @@
1
+ import type * as Malloy from '@malloydata/malloy-interfaces';
1
2
  import type { ExprValue } from '../types/expr-value';
2
3
  import { ExpressionDef } from '../types/expression-def';
3
4
  export declare class Boolean extends ExpressionDef {
@@ -5,4 +6,5 @@ export declare class Boolean extends ExpressionDef {
5
6
  elementType: string;
6
7
  constructor(value: 'true' | 'false');
7
8
  getExpression(): ExprValue;
9
+ getStableLiteral(): Malloy.LiteralValue;
8
10
  }
@@ -67,6 +67,12 @@ class Boolean extends expression_def_1.ExpressionDef {
67
67
  getExpression() {
68
68
  return { ...TDU.boolT, value: { node: this.value } };
69
69
  }
70
+ getStableLiteral() {
71
+ return {
72
+ kind: 'boolean_literal',
73
+ boolean_value: this.value === 'true',
74
+ };
75
+ }
70
76
  }
71
77
  exports.Boolean = Boolean;
72
78
  //# sourceMappingURL=boolean.js.map
@@ -297,29 +297,18 @@ class ExprFunc extends expression_def_1.ExpressionDef {
297
297
  else {
298
298
  const literal = str.literal;
299
299
  const parts = parseSQLInterpolation(literal);
300
- const unsupportedInterpolations = parts
301
- .filter(part => part.type === 'interpolation' && part.name.includes('.'))
302
- .map(unsupportedPart => unsupportedPart.type === 'interpolation'
303
- ? `\${${unsupportedPart.name}}`
304
- : `\${${unsupportedPart.value}}`);
305
- if (unsupportedInterpolations.length > 0) {
306
- const unsupportedInterpolationMsg = unsupportedInterpolations.length === 1
307
- ? `'.' paths are not yet supported in sql interpolations, found ${unsupportedInterpolations.at(0)}`
308
- : `'.' paths are not yet supported in sql interpolations, found (${unsupportedInterpolations.join(', ')})`;
309
- return this.loggedErrorExpr('unsupported-sql-function-interpolation', unsupportedInterpolationMsg);
310
- }
311
300
  const expr = [];
312
301
  for (const part of parts) {
313
302
  if (part.type === 'string') {
314
303
  expr.push(part.value);
315
304
  }
316
- else if (part.name === 'TABLE') {
305
+ else if (part.path.length === 1 && part.path[0] === 'TABLE') {
317
306
  expr.push({ node: 'source-reference' });
318
307
  }
319
308
  else {
320
- const name = new field_space_1.FieldName(part.name);
321
- this.has({ name });
322
- const result = fs.lookup([name]);
309
+ const names = part.path.map(p => new field_space_1.FieldName(p));
310
+ this.has({ names });
311
+ const result = fs.lookup(names);
323
312
  if (result.found === undefined) {
324
313
  return this.loggedErrorExpr('sql-function-interpolation-not-found', `Invalid interpolation: ${result.error.message}`);
325
314
  }
@@ -327,12 +316,13 @@ class ExprFunc extends expression_def_1.ExpressionDef {
327
316
  return this.loggedErrorExpr('filter-expression-error', 'Filter expressions cannot be used in sql_ functions');
328
317
  }
329
318
  if (result.found.refType === 'parameter') {
330
- expr.push({ node: 'parameter', path: [part.name] });
319
+ expr.push({ node: 'parameter', path: part.path });
331
320
  }
332
321
  else {
333
322
  expr.push({
334
323
  node: 'field',
335
- path: [part.name],
324
+ // TODO when we have namespaces, this will need to be replaced with the resolved path
325
+ path: part.path,
336
326
  at: this.args[0].location,
337
327
  });
338
328
  }
@@ -483,7 +473,9 @@ function parseSQLInterpolation(template) {
483
473
  }
484
474
  parts.push({
485
475
  type: 'interpolation',
486
- name: remaining.slice(nextInterp + 2, interpEnd + nextInterp),
476
+ path: remaining
477
+ .slice(nextInterp + 2, interpEnd + nextInterp)
478
+ .split('.'),
487
479
  });
488
480
  remaining = remaining.slice(interpEnd + nextInterp + 1);
489
481
  }
@@ -67,7 +67,7 @@ class ExprNot extends unary_1.Unary {
67
67
  getExpression(fs) {
68
68
  var _a;
69
69
  const notThis = this.expr.getExpression(fs);
70
- if ((_a = fs.dialectObj()) === null || _a === void 0 ? void 0 : _a.booleanAsNumbers) {
70
+ if (((_a = fs.dialectObj()) === null || _a === void 0 ? void 0 : _a.booleanType) !== 'supported') {
71
71
  if (this.legalChildTypes.find(t => t.type === 'number') === undefined) {
72
72
  this.legalChildTypes.push(TDU.numberT);
73
73
  }
@@ -1,3 +1,4 @@
1
+ import type * as Malloy from '@malloydata/malloy-interfaces';
1
2
  import type { ExprValue } from '../types/expr-value';
2
3
  import type { FieldSpace } from '../types/field-space';
3
4
  import { ExpressionDef } from '../types/expression-def';
@@ -7,4 +8,5 @@ export declare class ExprNumber extends ExpressionDef {
7
8
  constructor(n: string);
8
9
  getExpression(_fs: FieldSpace): ExprValue;
9
10
  constantExpression(): ExprValue;
11
+ getStableLiteral(): Malloy.LiteralValue;
10
12
  }
@@ -44,6 +44,12 @@ class ExprNumber extends expression_def_1.ExpressionDef {
44
44
  value: { node: 'numberLiteral', literal: this.n },
45
45
  });
46
46
  }
47
+ getStableLiteral() {
48
+ return {
49
+ kind: 'number_literal',
50
+ number_value: Number(this.n),
51
+ };
52
+ }
47
53
  }
48
54
  exports.ExprNumber = ExprNumber;
49
55
  //# sourceMappingURL=expr-number.js.map
@@ -1,3 +1,4 @@
1
+ import type * as Malloy from '@malloydata/malloy-interfaces';
1
2
  import { ExpressionDef } from '../types/expression-def';
2
3
  import type { FieldSpace } from '../types/field-space';
3
4
  import type { ExprValue } from '../types/expr-value';
@@ -6,4 +7,5 @@ export declare class ExprString extends ExpressionDef {
6
7
  value: string;
7
8
  constructor(src: string);
8
9
  getExpression(_fs: FieldSpace): ExprValue;
10
+ getStableLiteral(): Malloy.LiteralValue;
9
11
  }
@@ -1,26 +1,4 @@
1
1
  "use strict";
2
- /*
3
- * Copyright 2023 Google LLC
4
- *
5
- * Permission is hereby granted, free of charge, to any person obtaining
6
- * a copy of this software and associated documentation files
7
- * (the "Software"), to deal in the Software without restriction,
8
- * including without limitation the rights to use, copy, modify, merge,
9
- * publish, distribute, sublicense, and/or sell copies of the Software,
10
- * and to permit persons to whom the Software is furnished to do so,
11
- * subject to the following conditions:
12
- *
13
- * The above copyright notice and this permission notice shall be
14
- * included in all copies or substantial portions of the Software.
15
- *
16
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20
- * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
- */
24
2
  Object.defineProperty(exports, "__esModule", { value: true });
25
3
  exports.ExprString = void 0;
26
4
  const expression_def_1 = require("../types/expression-def");
@@ -37,6 +15,12 @@ class ExprString extends expression_def_1.ExpressionDef {
37
15
  value: { node: 'stringLiteral', literal: this.value },
38
16
  });
39
17
  }
18
+ getStableLiteral() {
19
+ return {
20
+ kind: 'string_literal',
21
+ string_value: this.value,
22
+ };
23
+ }
40
24
  }
41
25
  exports.ExprString = ExprString;
42
26
  //# sourceMappingURL=expr-string.js.map
@@ -1,3 +1,4 @@
1
+ import type * as Malloy from '@malloydata/malloy-interfaces';
1
2
  import type { TemporalFieldType, TimestampUnit, TimeLiteralNode } from '../../../model/malloy_types';
2
3
  import type { ExprValue } from '../types/expr-value';
3
4
  import type { FieldSpace } from '../types/field-space';
@@ -13,15 +14,21 @@ interface TimeText {
13
14
  /**
14
15
  * Literals specified with an @ in Malloy all become one of these
15
16
  */
16
- declare abstract class TimeLiteral extends ExpressionDef {
17
+ export declare abstract class TimeLiteral extends ExpressionDef {
17
18
  readonly units: TimestampUnit | undefined;
18
19
  readonly timeType: TemporalFieldType;
19
20
  literalPart: string;
20
21
  nextLit?: string;
21
22
  timeZone?: string;
22
23
  constructor(tm: TimeText, units: TimestampUnit | undefined, timeType: TemporalFieldType);
23
- protected makeLiteral(val: string, typ: TemporalFieldType): TimeLiteralNode;
24
+ protected makeLiteral(val: string, typ: TemporalFieldType, units: TimestampUnit | undefined): TimeLiteralNode;
24
25
  protected makeValue(val: string, dataType: TemporalFieldType): TimeResult;
26
+ getStableLiteral(): Malloy.LiteralValue;
27
+ getValue(): (import("../../../model/malloy_types").DateTypeDef & import("../../../model/malloy_types").TypeInfo & import("../types/expr-result").WithValue & {
28
+ timeframe?: TimestampUnit;
29
+ }) | (import("../../../model/malloy_types").TimestampTypeDef & import("../../../model/malloy_types").TypeInfo & import("../types/expr-result").WithValue & {
30
+ timeframe?: TimestampUnit;
31
+ });
25
32
  getExpression(_fs: FieldSpace): ExprValue;
26
33
  getNext(): ExprValue | undefined;
27
34
  granular(): boolean;
@@ -22,7 +22,7 @@
22
22
  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
23
  */
24
24
  Object.defineProperty(exports, "__esModule", { value: true });
25
- exports.LiteralYear = exports.LiteralQuarter = exports.LiteralMonth = exports.LiteralWeek = exports.LiteralDay = exports.LiteralHour = exports.LiteralTimestamp = exports.TimeFormatError = void 0;
25
+ exports.LiteralYear = exports.LiteralQuarter = exports.LiteralMonth = exports.LiteralWeek = exports.LiteralDay = exports.LiteralHour = exports.LiteralTimestamp = exports.TimeLiteral = exports.TimeFormatError = void 0;
26
26
  const luxon_1 = require("luxon");
27
27
  const malloy_types_1 = require("../../../model/malloy_types");
28
28
  const expr_value_1 = require("../types/expr-value");
@@ -69,11 +69,16 @@ class TimeLiteral extends expression_def_1.ExpressionDef {
69
69
  this.timeZone = tm.tzSpec;
70
70
  }
71
71
  }
72
- makeLiteral(val, typ) {
72
+ makeLiteral(val, typ, units) {
73
73
  const timeFrag = {
74
74
  node: 'timeLiteral',
75
75
  literal: val,
76
- typeDef: { type: typ },
76
+ typeDef: typ === 'timestamp'
77
+ ? { type: typ, timeframe: units }
78
+ : {
79
+ type: typ,
80
+ timeframe: units !== undefined && (0, malloy_types_1.isDateUnit)(units) ? units : undefined,
81
+ },
77
82
  };
78
83
  if (this.timeZone) {
79
84
  timeFrag.timezone = this.timeZone;
@@ -81,13 +86,52 @@ class TimeLiteral extends expression_def_1.ExpressionDef {
81
86
  return timeFrag;
82
87
  }
83
88
  makeValue(val, dataType) {
84
- const value = this.makeLiteral(val, dataType);
89
+ const value = this.makeLiteral(val, dataType, this.units);
85
90
  return (0, expr_value_1.literalTimeResult)({
86
91
  value,
87
- dataType: { type: dataType },
92
+ dataType: value.typeDef,
88
93
  timeframe: this.units,
89
94
  });
90
95
  }
96
+ getStableLiteral() {
97
+ const value = this.getValue();
98
+ let granularity = value.timeframe;
99
+ if (value.value.node !== 'timeLiteral') {
100
+ // TODO should probably just throw...
101
+ return {
102
+ kind: 'timestamp_literal',
103
+ timestamp_value: '1970-01-01 00:00:00',
104
+ granularity,
105
+ };
106
+ }
107
+ const timeValue = value.value.literal;
108
+ const timezone = value.value.timezone;
109
+ if (value.type === 'timestamp') {
110
+ return {
111
+ kind: 'timestamp_literal',
112
+ timestamp_value: timeValue,
113
+ granularity,
114
+ timezone,
115
+ };
116
+ }
117
+ else {
118
+ if (granularity === 'hour' ||
119
+ granularity === 'minute' ||
120
+ granularity === 'second') {
121
+ // TODO should probably just throw...
122
+ granularity = 'day';
123
+ }
124
+ return {
125
+ kind: 'date_literal',
126
+ date_value: timeValue,
127
+ granularity,
128
+ timezone,
129
+ };
130
+ }
131
+ }
132
+ getValue() {
133
+ return this.makeValue(this.literalPart, this.timeType);
134
+ }
91
135
  getExpression(_fs) {
92
136
  return this.makeValue(this.literalPart, this.timeType);
93
137
  }
@@ -100,6 +144,7 @@ class TimeLiteral extends expression_def_1.ExpressionDef {
100
144
  return this.nextLit !== undefined;
101
145
  }
102
146
  }
147
+ exports.TimeLiteral = TimeLiteral;
103
148
  class LiteralTimestamp extends TimeLiteral {
104
149
  constructor(tm, units) {
105
150
  super(tm, units, 'timestamp');
@@ -208,12 +253,12 @@ class DateBasedLiteral extends GranularLiteral {
208
253
  }
209
254
  getExpression(_fs) {
210
255
  const dateValue = this.makeValue(this.literalPart, 'date');
211
- const timestamp = this.makeLiteral(`${this.literalPart} 00:00:00`, 'timestamp');
256
+ const timestamp = this.makeLiteral(`${this.literalPart} 00:00:00`, 'timestamp', this.units);
212
257
  return { ...dateValue, morphic: { timestamp }, evalSpace: 'literal' };
213
258
  }
214
259
  getNext() {
215
260
  const dateValue = this.makeValue(this.nextLit, 'date');
216
- const timestamp = this.makeLiteral(`${this.nextLit} 00:00:00`, 'timestamp');
261
+ const timestamp = this.makeLiteral(`${this.nextLit} 00:00:00`, 'timestamp', this.units);
217
262
  return { ...dateValue, morphic: { timestamp } };
218
263
  }
219
264
  }
@@ -0,0 +1,16 @@
1
+ import type { AccessModifierLabel } from '../../../model';
2
+ import type { AtomicFieldDeclaration } from '../query-items/field-declaration';
3
+ import type { FieldName, FieldSpace } from '../types/field-space';
4
+ import type { LookupResult } from '../types/lookup-result';
5
+ import { PassthroughSpace } from './passthrough-space';
6
+ /**
7
+ * Used to detect references to fields in the statement which defines them
8
+ */
9
+ export declare class DefSpace extends PassthroughSpace {
10
+ readonly realFS: FieldSpace;
11
+ readonly circular: AtomicFieldDeclaration;
12
+ foundCircle: boolean;
13
+ constructor(realFS: FieldSpace, circular: AtomicFieldDeclaration);
14
+ lookup(symbol: FieldName[]): LookupResult;
15
+ accessProtectionLevel(): AccessModifierLabel;
16
+ }