@malloydata/malloy 0.0.335 → 0.0.337

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 (88) hide show
  1. package/CONTEXT.md +4 -3
  2. package/MALLOY_API.md +129 -0
  3. package/dist/annotation.d.ts +0 -2
  4. package/dist/annotation.js +29 -23
  5. package/dist/api/asynchronous.d.ts +1 -1
  6. package/dist/api/foundation/cache.d.ts +32 -0
  7. package/dist/api/foundation/cache.js +92 -0
  8. package/dist/api/foundation/compile.d.ts +201 -0
  9. package/dist/api/foundation/compile.js +429 -0
  10. package/dist/api/foundation/core.d.ts +493 -0
  11. package/dist/api/foundation/core.js +1247 -0
  12. package/dist/api/foundation/document.d.ts +167 -0
  13. package/dist/api/foundation/document.js +206 -0
  14. package/dist/api/foundation/index.d.ts +10 -0
  15. package/dist/api/foundation/index.js +77 -0
  16. package/dist/api/foundation/readers.d.ts +53 -0
  17. package/dist/api/foundation/readers.js +134 -0
  18. package/dist/api/foundation/result.d.ts +185 -0
  19. package/dist/api/foundation/result.js +704 -0
  20. package/dist/api/foundation/runtime.d.ts +361 -0
  21. package/dist/api/foundation/runtime.js +733 -0
  22. package/dist/api/foundation/types.d.ts +54 -0
  23. package/dist/api/foundation/types.js +7 -0
  24. package/dist/api/foundation/writers.d.ts +42 -0
  25. package/dist/api/foundation/writers.js +230 -0
  26. package/dist/api/util.d.ts +1 -1
  27. package/dist/connection/base_connection.d.ts +5 -0
  28. package/dist/connection/index.d.ts +1 -0
  29. package/dist/connection/index.js +1 -0
  30. package/dist/connection/registry.d.ts +73 -0
  31. package/dist/connection/registry.js +106 -0
  32. package/dist/connection/types.d.ts +5 -15
  33. package/dist/dialect/duckdb/duckdb.js +2 -1
  34. package/dist/dialect/snowflake/snowflake.js +7 -1
  35. package/dist/dialect/trino/trino.js +7 -2
  36. package/dist/index.d.ts +9 -4
  37. package/dist/index.js +37 -26
  38. package/dist/lang/ast/error-factory.js +3 -5
  39. package/dist/lang/ast/source-elements/query-source.js +2 -7
  40. package/dist/lang/ast/source-elements/refined-source.js +11 -1
  41. package/dist/lang/ast/source-elements/sql-source.d.ts +1 -1
  42. package/dist/lang/ast/source-elements/sql-source.js +18 -3
  43. package/dist/lang/ast/sql-elements/sql-string.d.ts +2 -2
  44. package/dist/lang/ast/sql-elements/sql-string.js +18 -1
  45. package/dist/lang/ast/statements/define-source.js +7 -2
  46. package/dist/lang/ast/statements/import-statement.js +53 -21
  47. package/dist/lang/ast/types/document-compile-result.d.ts +1 -0
  48. package/dist/lang/ast/types/malloy-element.d.ts +3 -1
  49. package/dist/lang/ast/types/malloy-element.js +23 -7
  50. package/dist/lang/malloy-to-ast.d.ts +1 -1
  51. package/dist/lang/malloy-to-ast.js +1 -1
  52. package/dist/lang/parse-malloy.d.ts +3 -2
  53. package/dist/lang/parse-malloy.js +14 -25
  54. package/dist/lang/test/test-translator.js +1 -0
  55. package/dist/lang/translate-response.d.ts +1 -0
  56. package/dist/model/constant_expression_compiler.js +6 -7
  57. package/dist/model/index.d.ts +3 -1
  58. package/dist/model/index.js +15 -9
  59. package/dist/model/malloy_types.d.ts +89 -15
  60. package/dist/model/malloy_types.js +12 -0
  61. package/dist/model/persist_utils.d.ts +47 -0
  62. package/dist/model/persist_utils.js +257 -0
  63. package/dist/model/query_model_impl.d.ts +2 -4
  64. package/dist/model/query_model_impl.js +5 -13
  65. package/dist/model/query_node.d.ts +1 -2
  66. package/dist/model/query_node.js +3 -13
  67. package/dist/model/query_query.d.ts +17 -1
  68. package/dist/model/query_query.js +81 -36
  69. package/dist/model/source_def_utils.d.ts +50 -0
  70. package/dist/model/source_def_utils.js +154 -0
  71. package/dist/model/sql_block.d.ts +5 -1
  72. package/dist/model/sql_block.js +29 -4
  73. package/dist/model/sql_compiled.d.ts +29 -0
  74. package/dist/model/sql_compiled.js +102 -0
  75. package/dist/model/stage_writer.d.ts +1 -3
  76. package/dist/model/stage_writer.js +7 -25
  77. package/dist/model/utils.d.ts +20 -1
  78. package/dist/model/utils.js +40 -0
  79. package/dist/run_sql_options.d.ts +0 -1
  80. package/dist/taggable.d.ts +10 -0
  81. package/dist/taggable.js +7 -0
  82. package/dist/version.d.ts +1 -1
  83. package/dist/version.js +1 -1
  84. package/package.json +6 -4
  85. package/dist/malloy.d.ts +0 -1365
  86. package/dist/malloy.js +0 -3421
  87. package/dist/model/materialization/utils.d.ts +0 -3
  88. package/dist/model/materialization/utils.js +0 -41
@@ -0,0 +1,154 @@
1
+ "use strict";
2
+ /*
3
+ * Copyright Contributors to the Malloy project
4
+ * SPDX-License-Identifier: MIT
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.mkSourceID = mkSourceID;
8
+ exports.mkBuildID = mkBuildID;
9
+ exports.mkQuerySourceDef = mkQuerySourceDef;
10
+ exports.mkSQLSourceDef = mkSQLSourceDef;
11
+ exports.mkTableSourceDef = mkTableSourceDef;
12
+ exports.resolveSourceID = resolveSourceID;
13
+ exports.registerSource = registerSource;
14
+ exports.hasSourceRegistryEntry = hasSourceRegistryEntry;
15
+ const utils_1 = require("./utils");
16
+ const malloy_types_1 = require("./malloy_types");
17
+ function mkSourceID(name, url) {
18
+ return `${name}@${url !== null && url !== void 0 ? url : 'unknown'}`;
19
+ }
20
+ /**
21
+ * Create a BuildID from connection digest and SQL.
22
+ * BuildID is a hash that uniquely identifies a build artifact.
23
+ */
24
+ function mkBuildID(connectionDigest, sql) {
25
+ return (0, utils_1.makeDigest)(connectionDigest, sql);
26
+ }
27
+ /**
28
+ * Create a QuerySourceDef from query compilation output.
29
+ * Explicitly copies SourceDefBase fields - no spread.
30
+ */
31
+ function mkQuerySourceDef(base, query, name) {
32
+ return {
33
+ // Type discriminant
34
+ type: 'query_source',
35
+ // QuerySourceDef-specific
36
+ query,
37
+ // NamedObject
38
+ name,
39
+ as: base.as,
40
+ // HasLocation
41
+ location: base.location,
42
+ // StructDefBase
43
+ annotation: base.annotation,
44
+ modelAnnotation: base.modelAnnotation,
45
+ fields: base.fields,
46
+ // Filtered
47
+ filterList: base.filterList,
48
+ // ResultStructMetadata
49
+ resultMetadata: base.resultMetadata,
50
+ // SourceDefBase
51
+ arguments: query.sourceArguments,
52
+ parameters: base.parameters,
53
+ queryTimezone: base.queryTimezone,
54
+ connection: base.connection,
55
+ primaryKey: base.primaryKey,
56
+ dialect: base.dialect,
57
+ partitionComposite: base.partitionComposite,
58
+ errorFactory: base.errorFactory,
59
+ // PersistableSourceProperties - explicitly NOT copied
60
+ // sourceID: undefined,
61
+ // extends: undefined,
62
+ };
63
+ }
64
+ /**
65
+ * Create an SQLSourceDef from schema lookup result.
66
+ * Explicitly copies SourceDefBase fields - no spread.
67
+ */
68
+ function mkSQLSourceDef(base, selectStr, selectSegments) {
69
+ return {
70
+ // Type discriminant
71
+ type: 'sql_select',
72
+ // SQLSourceDef-specific
73
+ selectStr,
74
+ selectSegments,
75
+ // NamedObject
76
+ name: base.name,
77
+ as: base.as,
78
+ // HasLocation
79
+ location: base.location,
80
+ // StructDefBase
81
+ annotation: base.annotation,
82
+ modelAnnotation: base.modelAnnotation,
83
+ fields: base.fields,
84
+ // Filtered
85
+ filterList: base.filterList,
86
+ // ResultStructMetadata
87
+ resultMetadata: base.resultMetadata,
88
+ // SourceDefBase
89
+ arguments: base.arguments,
90
+ parameters: base.parameters,
91
+ queryTimezone: base.queryTimezone,
92
+ connection: base.connection,
93
+ primaryKey: base.primaryKey,
94
+ dialect: base.dialect,
95
+ partitionComposite: base.partitionComposite,
96
+ errorFactory: base.errorFactory,
97
+ // PersistableSourceProperties - explicitly NOT copied
98
+ // sourceID: undefined,
99
+ // extends: undefined,
100
+ };
101
+ }
102
+ /**
103
+ * Create a TableSourceDef. All fields specified, no base to copy from.
104
+ */
105
+ function mkTableSourceDef(name, connection, tablePath, dialect, fields) {
106
+ return {
107
+ type: 'table',
108
+ name,
109
+ connection,
110
+ tablePath,
111
+ dialect,
112
+ fields,
113
+ };
114
+ }
115
+ // =============================================================================
116
+ // Source Registry Utilities
117
+ // =============================================================================
118
+ /**
119
+ * Resolve a sourceID to a SourceDef using the sourceRegistry.
120
+ *
121
+ * @param modelDef The model definition containing the registry
122
+ * @param sourceID The sourceID to resolve
123
+ * @returns The SourceDef if found, undefined otherwise
124
+ */
125
+ function resolveSourceID(modelDef, sourceID) {
126
+ const value = modelDef.sourceRegistry[sourceID];
127
+ if (!value)
128
+ return undefined;
129
+ if ((0, malloy_types_1.isSourceRegistryReference)(value.entry)) {
130
+ const obj = modelDef.contents[value.entry.name];
131
+ return obj && (0, malloy_types_1.isSourceDef)(obj) && (0, malloy_types_1.isPersistableSourceDef)(obj)
132
+ ? obj
133
+ : undefined;
134
+ }
135
+ // It's a PersistableSourceDef
136
+ return value.entry;
137
+ }
138
+ /**
139
+ * Add an entry to the sourceRegistry.
140
+ *
141
+ * @param registry The sourceRegistry to modify (from ModelDef or Document)
142
+ * @param sourceID The sourceID to register
143
+ * @param entry Either a SourceRegistryReference (for namespace sources) or a PersistableSourceDef (for hidden deps)
144
+ */
145
+ function registerSource(registry, sourceID, entry) {
146
+ registry[sourceID] = { entry };
147
+ }
148
+ /**
149
+ * Check if a sourceID is already in the registry.
150
+ */
151
+ function hasSourceRegistryEntry(modelDef, sourceID) {
152
+ return sourceID in modelDef.sourceRegistry;
153
+ }
154
+ //# sourceMappingURL=source_def_utils.js.map
@@ -1,4 +1,8 @@
1
1
  import type { SQLSourceRequest } from '../lang/translate-response';
2
2
  import type { SQLPhraseSegment, ModelDef } from './malloy_types';
3
- export declare function compileSQLInterpolation(select: SQLPhraseSegment[], connection: string, partialModel: ModelDef | undefined): SQLSourceRequest;
3
+ /**
4
+ * The translator needs to know the output schema of an SQLSourceDef
5
+ * this will prepare an SQL string suitable to answer that question.
6
+ */
7
+ export declare function getSourceRequest(select: SQLPhraseSegment[], connection: string, partialModel: ModelDef | undefined): SQLSourceRequest;
4
8
  export declare function sqlKey(connectionName: string, sql: string): string;
@@ -22,12 +22,16 @@
22
22
  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
23
  */
24
24
  Object.defineProperty(exports, "__esModule", { value: true });
25
- exports.compileSQLInterpolation = compileSQLInterpolation;
25
+ exports.getSourceRequest = getSourceRequest;
26
26
  exports.sqlKey = sqlKey;
27
27
  const query_model_1 = require("./query_model");
28
28
  const malloy_types_1 = require("./malloy_types");
29
29
  const utils_1 = require("./utils");
30
- function compileSQLInterpolation(select, connection, partialModel) {
30
+ /**
31
+ * The translator needs to know the output schema of an SQLSourceDef
32
+ * this will prepare an SQL string suitable to answer that question.
33
+ */
34
+ function getSourceRequest(select, connection, partialModel) {
31
35
  let queryModel = undefined;
32
36
  let selectStr = '';
33
37
  let parenAlready = false;
@@ -36,8 +40,30 @@ function compileSQLInterpolation(select, connection, partialModel) {
36
40
  selectStr += segment.sql;
37
41
  parenAlready = segment.sql.match(/\(\s*$/) !== null;
38
42
  }
43
+ else if ((0, malloy_types_1.isSegmentSource)(segment)) {
44
+ // PersistableSourceDef (sql_select or query_source)
45
+ let compiledSql;
46
+ if (segment.type === 'sql_select') {
47
+ compiledSql = segment.selectStr;
48
+ }
49
+ else {
50
+ // query_source - compile the inner query
51
+ if (!queryModel) {
52
+ if (!partialModel) {
53
+ throw new Error('Internal error: Partial model missing when compiling SQL block');
54
+ }
55
+ queryModel = (0, query_model_1.makeQueryModel)(partialModel);
56
+ }
57
+ compiledSql = queryModel.compileQuery(segment.query, {
58
+ defaultRowLimit: undefined,
59
+ isPartialQuery: true,
60
+ }, false).sql;
61
+ }
62
+ selectStr += parenAlready ? compiledSql : `(${compiledSql})`;
63
+ parenAlready = false;
64
+ }
39
65
  else {
40
- // TODO catch exceptions and throw errors ...
66
+ // Query segment
41
67
  if (!queryModel) {
42
68
  if (!partialModel) {
43
69
  throw new Error('Internal error: Partial model missing when compiling SQL block');
@@ -49,7 +75,6 @@ function compileSQLInterpolation(select, connection, partialModel) {
49
75
  isPartialQuery: true,
50
76
  }, false).sql;
51
77
  selectStr += parenAlready ? compiledSql : `(${compiledSql})`;
52
- // console.log(selectStr);
53
78
  parenAlready = false;
54
79
  }
55
80
  }
@@ -0,0 +1,29 @@
1
+ import type { PrepareResultOptions, SQLSourceDef, PersistableSourceDef, Query } from './malloy_types';
2
+ /**
3
+ * Callback type for compiling a Query to SQL.
4
+ * opts is optional - omit for "full SQL" (BuildID computation),
5
+ * provide for "run SQL" (with manifest substitution).
6
+ */
7
+ export type CompileQueryCallback = (query: Query, opts?: PrepareResultOptions) => string;
8
+ /**
9
+ * Compile a SQLSourceDef to its final SQL string.
10
+ *
11
+ * If the source has selectSegments (interpolated persistent sources), each segment
12
+ * is expanded by looking up in the manifest or compiling inline.
13
+ *
14
+ * @param src The SQLSourceDef to compile
15
+ * @param opts PrepareResultOptions with buildManifest and connectionDigests
16
+ * @param quoteTablePath Dialect function to safely quote a table path
17
+ * @param compileQuery Callback to compile a Query to SQL
18
+ */
19
+ export declare function getCompiledSQL(src: SQLSourceDef, opts: PrepareResultOptions, quoteTablePath: (path: string) => string, compileQuery: CompileQueryCallback): string;
20
+ /**
21
+ * Get the SQL for a PersistableSourceDef.
22
+ *
23
+ * @param source The persistable source to compile
24
+ * @param quoteTablePath Dialect function to quote table paths
25
+ * @param compileQuery Callback to compile a Query to SQL
26
+ * @param opts Optional - if provided with manifest, nested sources may be substituted.
27
+ * Omit for "full SQL" (e.g., when computing BuildID).
28
+ */
29
+ export declare function getSourceSQL(source: PersistableSourceDef, quoteTablePath: (path: string) => string, compileQuery: CompileQueryCallback, opts?: PrepareResultOptions): string;
@@ -0,0 +1,102 @@
1
+ "use strict";
2
+ /*
3
+ * Copyright Contributors to the Malloy project
4
+ * SPDX-License-Identifier: MIT
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.getCompiledSQL = getCompiledSQL;
8
+ exports.getSourceSQL = getSourceSQL;
9
+ const malloy_types_1 = require("./malloy_types");
10
+ const source_def_utils_1 = require("./source_def_utils");
11
+ /**
12
+ * Compile a SQLSourceDef to its final SQL string.
13
+ *
14
+ * If the source has selectSegments (interpolated persistent sources), each segment
15
+ * is expanded by looking up in the manifest or compiling inline.
16
+ *
17
+ * @param src The SQLSourceDef to compile
18
+ * @param opts PrepareResultOptions with buildManifest and connectionDigests
19
+ * @param quoteTablePath Dialect function to safely quote a table path
20
+ * @param compileQuery Callback to compile a Query to SQL
21
+ */
22
+ function getCompiledSQL(src, opts, quoteTablePath, compileQuery) {
23
+ // If no segments, just return the pre-computed selectStr
24
+ if (!src.selectSegments || src.selectSegments.length === 0) {
25
+ return src.selectStr;
26
+ }
27
+ // Expand each segment
28
+ const parts = [];
29
+ for (const segment of src.selectSegments) {
30
+ parts.push(expandSegment(segment, opts, quoteTablePath, compileQuery));
31
+ }
32
+ return parts.join('');
33
+ }
34
+ /**
35
+ * Expand a single SQLPhraseSegment to SQL.
36
+ */
37
+ function expandSegment(segment, opts, quoteTablePath, compileQuery) {
38
+ // Plain SQL string
39
+ if ((0, malloy_types_1.isSegmentSQL)(segment)) {
40
+ return segment.sql;
41
+ }
42
+ // PersistableSourceDef (sql_select or query_source)
43
+ if ((0, malloy_types_1.isSegmentSource)(segment)) {
44
+ return expandPersistableSource(segment, opts, quoteTablePath, compileQuery);
45
+ }
46
+ // Query segment
47
+ return expandQuery(segment, opts, quoteTablePath, compileQuery);
48
+ }
49
+ /**
50
+ * Expand a PersistableSourceDef, checking manifest for pre-built table.
51
+ * Always returns a subquery form: (SELECT * FROM table) or (inline SQL)
52
+ */
53
+ function expandPersistableSource(source, opts, quoteTablePath, compileQuery) {
54
+ const { buildManifest, connectionDigests, strictPersist } = opts;
55
+ // Try manifest lookup if we have the required info
56
+ if (buildManifest && connectionDigests) {
57
+ const connDigest = connectionDigests[source.connection];
58
+ if (connDigest) {
59
+ // Get the SQL for this source to compute BuildID (no opts = full SQL)
60
+ const sql = getSourceSQL(source, quoteTablePath, compileQuery);
61
+ const buildId = (0, source_def_utils_1.mkBuildID)(connDigest, sql);
62
+ const entry = buildManifest.buildEntries[buildId];
63
+ if (entry) {
64
+ // Found in manifest - substitute with subquery from persisted table
65
+ return `(SELECT * FROM ${quoteTablePath(entry.tableName)})`;
66
+ }
67
+ // Not in manifest
68
+ if (strictPersist) {
69
+ throw new Error(`Persist source '${source.sourceID}' not found in manifest (buildId: ${buildId})`);
70
+ }
71
+ }
72
+ }
73
+ // No manifest or not found - expand inline as subquery
74
+ const sql = getSourceSQL(source, quoteTablePath, compileQuery, opts);
75
+ return `(${sql})`;
76
+ }
77
+ /**
78
+ * Expand a Query segment.
79
+ */
80
+ function expandQuery(query, opts, _quoteTablePath, compileQuery) {
81
+ // Set isPartialQuery so CTEs aren't used (they can't be nested in subqueries)
82
+ const sql = compileQuery(query, { ...opts, isPartialQuery: true });
83
+ return `(${sql})`;
84
+ }
85
+ /**
86
+ * Get the SQL for a PersistableSourceDef.
87
+ *
88
+ * @param source The persistable source to compile
89
+ * @param quoteTablePath Dialect function to quote table paths
90
+ * @param compileQuery Callback to compile a Query to SQL
91
+ * @param opts Optional - if provided with manifest, nested sources may be substituted.
92
+ * Omit for "full SQL" (e.g., when computing BuildID).
93
+ */
94
+ function getSourceSQL(source, quoteTablePath, compileQuery, opts) {
95
+ if (source.type === 'sql_select') {
96
+ // Recursive call for nested sql_select
97
+ return getCompiledSQL(source, opts !== null && opts !== void 0 ? opts : {}, quoteTablePath, compileQuery);
98
+ }
99
+ // query_source - compile the inner query
100
+ return compileQuery(source.query, opts);
101
+ }
102
+ //# sourceMappingURL=sql_compiled.js.map
@@ -1,12 +1,11 @@
1
1
  import type { Dialect } from '../dialect';
2
- import type { QueryToMaterialize, StructDef, Query } from './malloy_types';
2
+ import type { StructDef } from './malloy_types';
3
3
  export declare class StageWriter {
4
4
  parent: StageWriter | undefined;
5
5
  withs: string[];
6
6
  stageNames: string[];
7
7
  udfs: string[];
8
8
  pdts: string[];
9
- dependenciesToMaterialize: Record<string, QueryToMaterialize>;
10
9
  stagePrefix: string;
11
10
  useCTE: boolean;
12
11
  stageNumber: number;
@@ -16,7 +15,6 @@ export declare class StageWriter {
16
15
  root(): StageWriter;
17
16
  addStage(sql: string): string;
18
17
  addUDF(stageWriter: StageWriter, dialect: Dialect, structDef: StructDef): string;
19
- addMaterializedQuery(fieldName: string, query: Query, materializatedTablePrefix?: string): string;
20
18
  addPDT(baseName: string, dialect: Dialect): string;
21
19
  combineStages(includeLastStage: boolean): {
22
20
  sql: string;
@@ -5,8 +5,7 @@
5
5
  */
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
7
  exports.StageWriter = void 0;
8
- const utils_1 = require("./materialization/utils");
9
- const utils_2 = require("./utils");
8
+ const utils_1 = require("./utils");
10
9
  class StageWriter {
11
10
  constructor(useCTE = true, parent) {
12
11
  this.parent = parent;
@@ -14,7 +13,6 @@ class StageWriter {
14
13
  this.stageNames = [];
15
14
  this.udfs = [];
16
15
  this.pdts = [];
17
- this.dependenciesToMaterialize = {};
18
16
  this.stagePrefix = '__stage';
19
17
  this.stageNumber = 0;
20
18
  this.useCTE = useCTE;
@@ -43,7 +41,7 @@ class StageWriter {
43
41
  }
44
42
  else {
45
43
  this.withs[0] = sql;
46
- return (0, utils_2.indent)(`\n(${sql})\n`);
44
+ return (0, utils_1.indent)(`\n(${sql})\n`);
47
45
  }
48
46
  }
49
47
  addUDF(stageWriter, dialect, structDef) {
@@ -53,31 +51,15 @@ class StageWriter {
53
51
  if (lastStageName === undefined) {
54
52
  throw new Error('Internal Error: no stage to combine');
55
53
  }
56
- sql += dialect.sqlCreateFunctionCombineLastStage(lastStageName, (0, utils_2.getDialectFieldList)(structDef), (_a = structDef.resultMetadata) === null || _a === void 0 ? void 0 : _a.orderBy);
54
+ sql += dialect.sqlCreateFunctionCombineLastStage(lastStageName, (0, utils_1.getDialectFieldList)(structDef), (_a = structDef.resultMetadata) === null || _a === void 0 ? void 0 : _a.orderBy);
57
55
  const id = `${dialect.udfPrefix}${this.root().udfs.length}`;
58
56
  sql = dialect.sqlCreateFunction(id, sql);
59
57
  this.root().udfs.push(sql);
60
58
  return id;
61
59
  }
62
- addMaterializedQuery(fieldName, query, materializatedTablePrefix) {
63
- var _a;
64
- const name = query.name;
65
- if (!name) {
66
- throw new Error(`Source ${fieldName} on a unnamed query that is tagged as materialize, only named queries can be materialized.`);
67
- }
68
- const path = (_a = query.location) === null || _a === void 0 ? void 0 : _a.url;
69
- if (!path) {
70
- throw new Error(`Trying to materialize query ${name}, but its path is not set.`);
71
- }
72
- // Creating an object that should uniquely identify a query within a Malloy model repo.
73
- const queryMaterializationSpec = (0, utils_1.buildQueryMaterializationSpec)(path, name, materializatedTablePrefix);
74
- this.root().dependenciesToMaterialize[queryMaterializationSpec.id] =
75
- queryMaterializationSpec;
76
- return queryMaterializationSpec.id;
77
- }
78
60
  addPDT(baseName, dialect) {
79
61
  const sql = this.combineStages(false).sql + this.withs[this.withs.length - 1];
80
- const name = baseName + (0, utils_2.generateHash)(sql);
62
+ const name = baseName + (0, utils_1.generateHash)(sql);
81
63
  const tableName = `scratch.${name}`;
82
64
  this.root().pdts.push(dialect.sqlCreateTableAsSelect(tableName, sql));
83
65
  return tableName;
@@ -97,7 +79,7 @@ class StageWriter {
97
79
  if (sql === undefined) {
98
80
  throw new Error(`Expected sql WITH to be present for stage ${lastStageName}.`);
99
81
  }
100
- w += `${prefix}${lastStageName} AS (\n${(0, utils_2.indent)(sql)})\n`;
82
+ w += `${prefix}${lastStageName} AS (\n${(0, utils_1.indent)(sql)})\n`;
101
83
  prefix = ', ';
102
84
  }
103
85
  return { sql: w, lastStageName };
@@ -116,11 +98,11 @@ class StageWriter {
116
98
  generateCoorelatedSubQuery(dialect, structDef) {
117
99
  var _a, _b;
118
100
  if (!this.useCTE) {
119
- return dialect.sqlCreateFunctionCombineLastStage(`(${this.withs[0]})`, (0, utils_2.getDialectFieldList)(structDef), (_a = structDef.resultMetadata) === null || _a === void 0 ? void 0 : _a.orderBy);
101
+ return dialect.sqlCreateFunctionCombineLastStage(`(${this.withs[0]})`, (0, utils_1.getDialectFieldList)(structDef), (_a = structDef.resultMetadata) === null || _a === void 0 ? void 0 : _a.orderBy);
120
102
  }
121
103
  else {
122
104
  return (this.combineStages(true).sql +
123
- dialect.sqlCreateFunctionCombineLastStage(this.getName(this.withs.length - 1), (0, utils_2.getDialectFieldList)(structDef), (_b = structDef.resultMetadata) === null || _b === void 0 ? void 0 : _b.orderBy));
105
+ dialect.sqlCreateFunctionCombineLastStage(this.getName(this.withs.length - 1), (0, utils_1.getDialectFieldList)(structDef), (_b = structDef.resultMetadata) === null || _b === void 0 ? void 0 : _b.orderBy));
124
106
  }
125
107
  }
126
108
  }
@@ -1,4 +1,4 @@
1
- import type { Expr, GenericSQLExpr, StructDef } from './malloy_types';
1
+ import type { Expr, GenericSQLExpr, ModelDef, StructDef } from './malloy_types';
2
2
  import type { DialectFieldList } from '../dialect';
3
3
  /** simple indent function */
4
4
  export declare function indent(s: string): string;
@@ -22,6 +22,20 @@ export declare class AndChain {
22
22
  sql(whereOrHaving?: 'where' | 'having'): string;
23
23
  }
24
24
  export declare function generateHash(input: string): string;
25
+ /**
26
+ * Compute a digest for lookup/identity purposes (not cryptographic).
27
+ *
28
+ * Uses blueimp-md5 for these reasons:
29
+ * - Works in both Node.js and browsers (no native crypto dependency)
30
+ * - Synchronous API (unlike Web Crypto which is async)
31
+ * - Well-maintained by Sebastian Tschan (blueimp), a known maintainer
32
+ * - High adoption (~1.7M weekly downloads)
33
+ * - MD5 is fast and produces short hex strings - perfect for cache keys
34
+ *
35
+ * Takes variable string arguments and combines them in a collision-resistant
36
+ * way by including the length of each string (similar to pathToKey pattern).
37
+ */
38
+ export declare function makeDigest(...parts: string[]): string;
25
39
  export declare function joinWith<T>(els: T[][], sep: T): T[];
26
40
  export declare function range(start: number, end: number): number[];
27
41
  export declare function exprKids(eNode: Expr): IterableIterator<Expr>;
@@ -49,3 +63,8 @@ export declare class GenerateState {
49
63
  withApply(s: string): GenerateState;
50
64
  withTotal(groupSet: number): GenerateState;
51
65
  }
66
+ /**
67
+ * Create an empty ModelDef with the given name.
68
+ * Use this factory to ensure all required fields are present.
69
+ */
70
+ export declare function mkModelDef(name: string): ModelDef;
@@ -21,11 +21,15 @@
21
21
  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22
22
  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
23
  */
24
+ var __importDefault = (this && this.__importDefault) || function (mod) {
25
+ return (mod && mod.__esModule) ? mod : { "default": mod };
26
+ };
24
27
  Object.defineProperty(exports, "__esModule", { value: true });
25
28
  exports.GenerateState = exports.AndChain = void 0;
26
29
  exports.indent = indent;
27
30
  exports.generateSQLStringLiteral = generateSQLStringLiteral;
28
31
  exports.generateHash = generateHash;
32
+ exports.makeDigest = makeDigest;
29
33
  exports.joinWith = joinWith;
30
34
  exports.range = range;
31
35
  exports.exprKids = exprKids;
@@ -36,7 +40,9 @@ exports.getDialectFieldList = getDialectFieldList;
36
40
  exports.pathToKey = pathToKey;
37
41
  exports.groupingKey = groupingKey;
38
42
  exports.caseGroup = caseGroup;
43
+ exports.mkModelDef = mkModelDef;
39
44
  const uuid_1 = require("uuid");
45
+ const blueimp_md5_1 = __importDefault(require("blueimp-md5"));
40
46
  const malloy_types_1 = require("./malloy_types");
41
47
  /** simple indent function */
42
48
  function indent(s) {
@@ -108,6 +114,26 @@ function generateHash(input) {
108
114
  const MALLOY_UUID = '76c17e9d-f3ce-5f2d-bfde-98ad3d2a37f6';
109
115
  return (0, uuid_1.v5)(input, MALLOY_UUID);
110
116
  }
117
+ /**
118
+ * Compute a digest for lookup/identity purposes (not cryptographic).
119
+ *
120
+ * Uses blueimp-md5 for these reasons:
121
+ * - Works in both Node.js and browsers (no native crypto dependency)
122
+ * - Synchronous API (unlike Web Crypto which is async)
123
+ * - Well-maintained by Sebastian Tschan (blueimp), a known maintainer
124
+ * - High adoption (~1.7M weekly downloads)
125
+ * - MD5 is fast and produces short hex strings - perfect for cache keys
126
+ *
127
+ * Takes variable string arguments and combines them in a collision-resistant
128
+ * way by including the length of each string (similar to pathToKey pattern).
129
+ */
130
+ function makeDigest(...parts) {
131
+ // Combine parts with length prefix to avoid collisions
132
+ // e.g., ("ab", "c") vs ("a", "bc") both concat to "abc"
133
+ // but with lengths: "2:ab/1:c" vs "1:a/2:bc"
134
+ const combined = parts.map(p => `${p.length}:${p}`).join('/');
135
+ return (0, blueimp_md5_1.default)(combined);
136
+ }
111
137
  function joinWith(els, sep) {
112
138
  const result = [];
113
139
  for (let i = 0; i < els.length; i++) {
@@ -260,4 +286,18 @@ class GenerateState {
260
286
  }
261
287
  }
262
288
  exports.GenerateState = GenerateState;
289
+ /**
290
+ * Create an empty ModelDef with the given name.
291
+ * Use this factory to ensure all required fields are present.
292
+ */
293
+ function mkModelDef(name) {
294
+ return {
295
+ name,
296
+ exports: [],
297
+ contents: {},
298
+ sourceRegistry: {},
299
+ queryList: [],
300
+ dependencies: {},
301
+ };
302
+ }
263
303
  //# sourceMappingURL=utils.js.map
@@ -8,7 +8,6 @@ export interface RunSQLOptions {
8
8
  abortSignal?: AbortSignal;
9
9
  modelAnnotation?: Annotation;
10
10
  queryAnnotation?: Annotation;
11
- replaceMaterializedReferences?: boolean;
12
11
  clientMetadata?: {
13
12
  sourceRefWithMetadata?: SourceRefWithMetadata;
14
13
  };
@@ -0,0 +1,10 @@
1
+ import type { TagParseSpec, MalloyTagParse } from './annotation';
2
+ /**
3
+ * Interface for objects that have Malloy tag annotations.
4
+ * This is part of the runtime API - objects returned from the Malloy
5
+ * runtime implement this interface to expose their tag metadata.
6
+ */
7
+ export interface Taggable {
8
+ tagParse: (spec?: TagParseSpec) => MalloyTagParse;
9
+ getTaglines: (prefix?: RegExp) => string[];
10
+ }
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ /*
3
+ * Copyright Contributors to the Malloy project
4
+ * SPDX-License-Identifier: MIT
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ //# sourceMappingURL=taggable.js.map
package/dist/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const MALLOY_VERSION = "0.0.335";
1
+ export declare const MALLOY_VERSION = "0.0.337";
package/dist/version.js CHANGED
@@ -2,5 +2,5 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.MALLOY_VERSION = void 0;
4
4
  // generated with 'generate-version-file' script; do not edit manually
5
- exports.MALLOY_VERSION = '0.0.335';
5
+ exports.MALLOY_VERSION = '0.0.337';
6
6
  //# sourceMappingURL=version.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@malloydata/malloy",
3
- "version": "0.0.335",
3
+ "version": "0.0.337",
4
4
  "license": "MIT",
5
5
  "exports": {
6
6
  ".": "./dist/index.js",
@@ -45,11 +45,12 @@
45
45
  "generate-version-file": "VERSION=$(npm pkg get version --workspaces=false | tr -d \\\")\necho \"// generated with 'generate-version-file' script; do not edit manually\\nexport const MALLOY_VERSION = '$VERSION';\" > src/version.ts"
46
46
  },
47
47
  "dependencies": {
48
- "@malloydata/malloy-filter": "0.0.335",
49
- "@malloydata/malloy-interfaces": "0.0.335",
50
- "@malloydata/malloy-tag": "0.0.335",
48
+ "@malloydata/malloy-filter": "0.0.337",
49
+ "@malloydata/malloy-interfaces": "0.0.337",
50
+ "@malloydata/malloy-tag": "0.0.337",
51
51
  "antlr4ts": "^0.5.0-alpha.4",
52
52
  "assert": "^2.0.0",
53
+ "blueimp-md5": "^2.19.0",
53
54
  "jaro-winkler": "^0.2.8",
54
55
  "jest-diff": "^29.6.2",
55
56
  "lodash": "^4.17.20",
@@ -57,6 +58,7 @@
57
58
  "uuid": "^8.3.2"
58
59
  },
59
60
  "devDependencies": {
61
+ "@types/blueimp-md5": "^2.18.2",
60
62
  "@types/jaro-winkler": "^0.2.3",
61
63
  "@types/lodash": "^4.14.165",
62
64
  "@types/luxon": "^3.5.0",