@malloydata/malloy 0.0.11-dev221202152346 → 0.0.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/malloy.d.ts CHANGED
@@ -2,7 +2,7 @@
2
2
  import { InfoConnection } from ".";
3
3
  import { DocumentHighlight as DocumentHighlightDefinition, DocumentSymbol as DocumentSymbolDefinition, DocumentCompletion as DocumentCompletionDefinition, LogMessage, MalloyTranslator } from "./lang";
4
4
  import { DocumentHelpContext } from "./lang/parse-tree-walkers/document-help-context-walker";
5
- import { CompiledQuery, FieldBooleanDef, FieldDateDef, FieldNumberDef, FieldStringDef, FieldTimestampDef, FieldTypeDef, FilterExpression, ModelDef, Query as InternalQuery, QueryData, QueryDataRow, QueryResult, StructDef, TurtleDef, SQLBlock, DocumentReference, DocumentPosition as ModelDocumentPosition, SearchIndexResult, SearchValueMapResult, NamedQuery } from "./model";
5
+ import { CompiledQuery, FieldBooleanDef, FieldDateDef, FieldNumberDef, FieldStringDef, FieldTimestampDef, FieldTypeDef, FilterExpression, ModelDef, Query as InternalQuery, QueryData, QueryDataRow, QueryResult, StructDef, TurtleDef, SQLBlock, DocumentReference, DocumentPosition as ModelDocumentPosition, SearchIndexResult, SearchValueMapResult, NamedQuery, SQLBlockStructDef } from "./model";
6
6
  import { LookupConnection, ModelString, ModelURL, QueryString, QueryURL, URLReader, Connection } from "./runtime_types";
7
7
  export interface Loggable {
8
8
  debug: (message?: any, ...optionalParams: any[]) => void;
@@ -56,7 +56,7 @@ export declare class Malloy {
56
56
  parse: Parse;
57
57
  model?: Model;
58
58
  }): Promise<Model>;
59
- private static runSQLBlockAndFetchResultSchema;
59
+ private static compileSQLBlock;
60
60
  /**
61
61
  * Run a fully-prepared query.
62
62
  *
@@ -76,22 +76,22 @@ export declare class Malloy {
76
76
  }): Promise<Result>;
77
77
  static run(params: {
78
78
  connection: Connection;
79
- sqlBlock: SQLBlock;
79
+ sqlStruct: SQLBlockStructDef;
80
80
  options?: RunSQLOptions;
81
81
  }): Promise<Result>;
82
82
  static run(params: {
83
83
  connections: LookupConnection<Connection>;
84
- sqlBlock: SQLBlock;
84
+ sqlStruct: SQLBlockStructDef;
85
85
  options?: RunSQLOptions;
86
86
  }): Promise<Result>;
87
87
  static run(params: {
88
88
  connection: Connection;
89
- sqlBlock: SQLBlock;
89
+ sqlStruct: SQLBlockStructDef;
90
90
  options?: RunSQLOptions;
91
91
  }): Promise<Result>;
92
92
  static run(params: {
93
93
  connections: LookupConnection<Connection>;
94
- sqlBlock: SQLBlock;
94
+ sqlStruct: SQLBlockStructDef;
95
95
  options?: RunSQLOptions;
96
96
  }): Promise<Result>;
97
97
  static runStream(params: {
@@ -106,7 +106,7 @@ export declare class Malloy {
106
106
  }): AsyncIterableIterator<DataRecord>;
107
107
  static runStream(params: {
108
108
  connection: Connection;
109
- sqlBlock: SQLBlock;
109
+ sqlStruct: SQLBlockStructDef;
110
110
  options?: RunSQLOptions;
111
111
  }): AsyncIterableIterator<DataRecord>;
112
112
  static runStream(params: {
@@ -116,12 +116,12 @@ export declare class Malloy {
116
116
  }): AsyncIterableIterator<DataRecord>;
117
117
  static runStream(params: {
118
118
  connection: Connection;
119
- sqlBlock: SQLBlock;
119
+ sqlStruct: SQLBlockStructDef;
120
120
  options?: RunSQLOptions;
121
121
  }): AsyncIterableIterator<DataRecord>;
122
122
  static runStream(params: {
123
123
  connections: LookupConnection<Connection>;
124
- sqlBlock: SQLBlock;
124
+ sqlStruct: SQLBlockStructDef;
125
125
  options?: RunSQLOptions;
126
126
  }): AsyncIterableIterator<DataRecord>;
127
127
  }
@@ -143,7 +143,7 @@ export declare class Model {
143
143
  private queryList;
144
144
  private sqlBlocks;
145
145
  _referenceAt: (location: ModelDocumentPosition) => DocumentReference | undefined;
146
- constructor(modelDef: ModelDef, queryList: InternalQuery[], sqlBlocks: SQLBlock[], referenceAt?: (location: ModelDocumentPosition) => DocumentReference | undefined);
146
+ constructor(modelDef: ModelDef, queryList: InternalQuery[], sqlBlocks: SQLBlockStructDef[], referenceAt?: (location: ModelDocumentPosition) => DocumentReference | undefined);
147
147
  /**
148
148
  * Retrieve a document reference for the token at the given position within
149
149
  * the document that produced this model.
@@ -172,14 +172,14 @@ export declare class Model {
172
172
  * @param queryName Name of the query to retrieve.
173
173
  * @returns A prepared query.
174
174
  */
175
- getSQLBlockByName(sqlBlockName: string): SQLBlock;
175
+ getSQLBlockByName(sqlBlockName: string): SQLBlockStructDef;
176
176
  /**
177
177
  * Retrieve a prepared query by the name of a query at the top level of the model.
178
178
  *
179
179
  * @param index Index of the SQL Block to retrieve.
180
180
  * @returns A prepared query.
181
181
  */
182
- getSQLBlockByIndex(index: number): SQLBlock;
182
+ getSQLBlockByIndex(index: number): SQLBlockStructDef;
183
183
  /**
184
184
  * Retrieve a prepared query for the final unnamed query at the top level of a model.
185
185
  *
@@ -708,9 +708,9 @@ export declare class Runtime {
708
708
  *
709
709
  * @param model The model URL or contents to load and (eventually) compile to retrieve the requested query.
710
710
  * @param name The name of the sql block to use within the model.
711
- * @returns A promise of a `SQLBlock`.
711
+ * @returns A promise of a `CompiledSQLBlock`.
712
712
  */
713
- getSQLBlockByName(model: ModelURL | ModelString, name: string): Promise<SQLBlock>;
713
+ getSQLBlockByName(model: ModelURL | ModelString, name: string): Promise<SQLBlockStructDef>;
714
714
  /**
715
715
  * Get a SQL block by the URL or contents of a Malloy model document
716
716
  * and the name of a query contained in the model.
@@ -719,7 +719,7 @@ export declare class Runtime {
719
719
  * @param index The index of the SQL block to use within the model. Note: named blocks are indexable, too.
720
720
  * @returns A promise of a `SQLBlock`.
721
721
  */
722
- getSQLBlockByIndex(model: ModelURL | ModelString, index: number): Promise<SQLBlock>;
722
+ getSQLBlockByIndex(model: ModelURL | ModelString, index: number): Promise<SQLBlockStructDef>;
723
723
  }
724
724
  export declare class ConnectionRuntime extends Runtime {
725
725
  readonly rawConnections: Connection[];
@@ -741,7 +741,7 @@ declare class FluentState<T> {
741
741
  protected makeQueryMaterializer(materialize: () => Promise<PreparedQuery>): QueryMaterializer;
742
742
  protected makeExploreMaterializer(materialize: () => Promise<Explore>): ExploreMaterializer;
743
743
  protected makePreparedResultMaterializer(materialize: () => Promise<PreparedResult>): PreparedResultMaterializer;
744
- protected makeSQLBlockMaterializer(materialize: () => Promise<SQLBlock>): SQLBlockMaterializer;
744
+ protected makeSQLBlockMaterializer(materialize: () => Promise<SQLBlockStructDef>): SQLBlockMaterializer;
745
745
  }
746
746
  /**
747
747
  * An object representing the task of loading a `Model`, capable of
@@ -833,7 +833,7 @@ export declare class ModelMaterializer extends FluentState<Model> {
833
833
  * @param name The name of the SQL Block to load.
834
834
  * @returns A promise of a `SQLBlock`.
835
835
  */
836
- getSQLBlockByName(name: string): Promise<SQLBlock>;
836
+ getSQLBlockByName(name: string): Promise<SQLBlockStructDef>;
837
837
  /**
838
838
  * Get a SQL Block by index.
839
839
  *
@@ -842,7 +842,7 @@ export declare class ModelMaterializer extends FluentState<Model> {
842
842
  *
843
843
  * TODO feature-sql-block Should named SQL blocks be indexable? This is not the way unnamed queries work.
844
844
  */
845
- getSQLBlockByIndex(index: number): Promise<SQLBlock>;
845
+ getSQLBlockByIndex(index: number): Promise<SQLBlockStructDef>;
846
846
  _loadQueryFromQueryDef(query: InternalQuery): QueryMaterializer;
847
847
  /**
848
848
  * Load an explore contained within this loaded `Model` by name.
@@ -940,7 +940,7 @@ export declare class PreparedResultMaterializer extends FluentState<PreparedResu
940
940
  * materializing the SQLBlock (via `getSQLBlock()`) or extending the task run
941
941
  * the query.
942
942
  */
943
- export declare class SQLBlockMaterializer extends FluentState<SQLBlock> {
943
+ export declare class SQLBlockMaterializer extends FluentState<SQLBlockStructDef> {
944
944
  /**
945
945
  * Run this SQL block.
946
946
  *
@@ -955,7 +955,7 @@ export declare class SQLBlockMaterializer extends FluentState<SQLBlock> {
955
955
  *
956
956
  * @returns A promise of a SQL block.
957
957
  */
958
- getSQLBlock(): Promise<SQLBlock>;
958
+ getSQLBlock(): Promise<SQLBlockStructDef>;
959
959
  /**
960
960
  * Materialize the SQL of this loaded SQL block.
961
961
  *
package/dist/malloy.js CHANGED
@@ -131,85 +131,84 @@ class Malloy {
131
131
  }
132
132
  }
133
133
  }
134
- if (result.sqlStructs) {
135
- // collect sql refs by connection name since there may be multiple connections
136
- const sqlRefsByConnection = new Map();
137
- for (const missingSQLSchemaRef of result.sqlStructs) {
138
- const connectionName = missingSQLSchemaRef.connection;
139
- // if (connectionName === undefined) {
140
- // throw new Error("Oops have not made it required here yet...");
141
- // }
142
- let connectionToSQLReferencesMap = sqlRefsByConnection.get(connectionName);
143
- if (!connectionToSQLReferencesMap) {
144
- connectionToSQLReferencesMap = [missingSQLSchemaRef];
145
- }
146
- else {
147
- connectionToSQLReferencesMap.push(missingSQLSchemaRef);
148
- }
149
- sqlRefsByConnection.set(connectionName, connectionToSQLReferencesMap);
150
- }
151
- for (const [connectionName, connectionToSQLReferencesMap,] of sqlRefsByConnection) {
152
- try {
153
- const connection = await connections.lookupConnection(connectionName);
154
- // TODO detect if the union of `Object.keys(sqlStructs)` and `Object.keys(errors)` is not the same
155
- // as `Object.keys(connectionToSQLReferencesMap)`, i.e. that all tables are accounted for. Otherwise
156
- // the translator runs into an infinite loop fetching SQL structs.
157
- const { schemas: sqlStructs, errors } = await connection.fetchSchemaForSQLBlocks(connectionToSQLReferencesMap);
158
- translator.update({ sqlStructs });
159
- translator.update({ sqlStructs, errors: { sqlStructs: errors } });
134
+ if (result.compileSQL) {
135
+ // Unlike other requests, these do not come in batches
136
+ const toCompile = result.compileSQL;
137
+ const connectionName = toCompile.connection;
138
+ try {
139
+ const conn = await connections.lookupConnection(connectionName);
140
+ const expanded = Malloy.compileSQLBlock(result.partialModel, toCompile);
141
+ const resolved = await conn.fetchSchemaForSQLBlock(expanded);
142
+ if (resolved.error) {
143
+ translator.update({
144
+ errors: { compileSQL: { [expanded.name]: resolved.error } },
145
+ });
160
146
  }
161
- catch (error) {
162
- // There was an exception getting the connection, associate that error
163
- // with all its schemas
164
- const sqlStructs = {};
165
- const errors = {};
166
- for (const sqlRef of connectionToSQLReferencesMap) {
167
- errors[sqlRef.name] = error.toString();
147
+ if (resolved.structDef) {
148
+ if ((0, model_1.isSQLBlock)(resolved.structDef)) {
149
+ translator.update({
150
+ compileSQL: { [expanded.name]: resolved.structDef },
151
+ });
168
152
  }
169
- translator.update({ sqlStructs, errors: { sqlStructs: errors } });
170
153
  }
171
154
  }
155
+ catch (error) {
156
+ const errors = {};
157
+ errors[toCompile.name] = error.toString();
158
+ translator.update({ errors: { compileSQL: errors } });
159
+ }
172
160
  }
173
161
  }
174
162
  }
175
163
  }
176
- static async runSQLBlockAndFetchResultSchema(connection, sqlBlock, options) {
177
- if (connection.canFetchSchemaAndRunSimultaneously()) {
178
- return connection.runSQLBlockAndFetchResultSchema(sqlBlock, options);
179
- }
180
- const [schema, data] = await Promise.all([
181
- connection
182
- .fetchSchemaForSQLBlocks([sqlBlock])
183
- .then((result) => result.schemas[sqlBlock.name]),
184
- connection.runSQL(sqlBlock.select),
185
- ]);
186
- return { schema, data };
164
+ static compileSQLBlock(partialModel, toCompile) {
165
+ let queryModel;
166
+ const sqlStrings = toCompile.select.map((segment) => {
167
+ if ((0, model_1.isSQLFragment)(segment)) {
168
+ return segment.sql;
169
+ }
170
+ else {
171
+ // TODO catch exceptions and throw errors ...
172
+ if (!queryModel) {
173
+ if (!partialModel) {
174
+ throw new Error("Internal error: Partial model missing when compiling SQL block");
175
+ }
176
+ queryModel = new model_1.QueryModel(partialModel);
177
+ }
178
+ return queryModel.compileQuery(segment).sql;
179
+ }
180
+ });
181
+ const { name, connection } = toCompile;
182
+ return {
183
+ type: "sqlBlock",
184
+ name,
185
+ connection,
186
+ selectStr: sqlStrings.join(""),
187
+ };
187
188
  }
188
- static async run({ connections, preparedResult, sqlBlock, connection, options, }) {
189
- if (sqlBlock === undefined && preparedResult === undefined) {
190
- throw new Error("Internal error: sqlBlock or preparedResult must be provided.");
191
- }
192
- const connectionName = (sqlBlock === null || sqlBlock === void 0 ? void 0 : sqlBlock.connection) || (preparedResult === null || preparedResult === void 0 ? void 0 : preparedResult.connectionName);
193
- if (connection === undefined) {
194
- if (connections === undefined) {
189
+ static async run({ connections, preparedResult, sqlStruct, connection, options, }) {
190
+ const sqlBlock = sqlStruct === null || sqlStruct === void 0 ? void 0 : sqlStruct.structSource.sqlBlock;
191
+ if (!connection) {
192
+ if (!connections) {
195
193
  throw new Error("Internal Error: Connection or LookupConnection<Connection> must be provided.");
196
194
  }
195
+ const connectionName = (sqlBlock === null || sqlBlock === void 0 ? void 0 : sqlBlock.connection) || (preparedResult === null || preparedResult === void 0 ? void 0 : preparedResult.connectionName);
197
196
  connection = await connections.lookupConnection(connectionName);
198
197
  }
199
- if (sqlBlock !== undefined) {
200
- const { schema, data } = await this.runSQLBlockAndFetchResultSchema(connection, sqlBlock, options);
201
- if (schema.structRelationship.type !== "basetable") {
198
+ if (sqlStruct && sqlBlock) {
199
+ if (sqlStruct.structRelationship.type !== "basetable") {
202
200
  throw new Error("Expected schema's structRelationship type to be 'basetable'.");
203
201
  }
202
+ const data = await connection.runSQL(sqlBlock.selectStr);
204
203
  return new Result({
205
- structs: [schema],
206
- sql: sqlBlock.select,
204
+ structs: [sqlStruct],
205
+ sql: sqlBlock.selectStr,
207
206
  result: data.rows,
208
207
  totalRows: data.totalRows,
209
- lastStageName: schema.name,
208
+ lastStageName: sqlBlock.name,
210
209
  // TODO feature-sql-block There is no malloy code...
211
210
  malloy: "",
212
- connectionName: schema.structRelationship.connectionName,
211
+ connectionName: sqlStruct.structRelationship.connectionName,
213
212
  // TODO feature-sql-block There is no source explore...
214
213
  sourceExplore: "",
215
214
  sourceFilters: [],
@@ -219,7 +218,7 @@ class Malloy {
219
218
  contents: {},
220
219
  });
221
220
  }
222
- else if (preparedResult !== undefined) {
221
+ else if (preparedResult) {
223
222
  const result = await connection.runSQL(preparedResult.sql, options);
224
223
  return new Result({
225
224
  ...preparedResult._rawQuery,
@@ -228,10 +227,11 @@ class Malloy {
228
227
  }, preparedResult._modelDef);
229
228
  }
230
229
  else {
231
- throw new Error("Internal error: sqlBlock or preparedResult must be provided.");
230
+ throw new Error("Internal error: sqlStruct or preparedResult must be provided.");
232
231
  }
233
232
  }
234
- static async *runStream({ connections, preparedResult, sqlBlock, connection, options, }) {
233
+ static async *runStream({ connections, preparedResult, sqlStruct, connection, options, }) {
234
+ const sqlBlock = sqlStruct === null || sqlStruct === void 0 ? void 0 : sqlStruct.structSource.sqlBlock;
235
235
  if (sqlBlock === undefined && preparedResult === undefined) {
236
236
  throw new Error("Internal error: sqlBlock or preparedResult must be provided.");
237
237
  }
@@ -248,21 +248,19 @@ class Malloy {
248
248
  }
249
249
  let sql;
250
250
  let resultExplore;
251
- if (sqlBlock !== undefined) {
252
- const schema = (await connection.fetchSchemaForSQLBlocks([sqlBlock]))
253
- .schemas[sqlBlock.name];
254
- if (schema.structRelationship.type !== "basetable") {
251
+ if (sqlStruct) {
252
+ if (sqlStruct.structRelationship.type !== "basetable") {
255
253
  throw new Error("Expected schema's structRelationship type to be 'basetable'.");
256
254
  }
257
- resultExplore = new Explore(schema);
258
- sql = sqlBlock.select;
255
+ resultExplore = new Explore(sqlStruct);
256
+ sql = sqlStruct.structSource.sqlBlock.selectStr;
259
257
  }
260
258
  else if (preparedResult !== undefined) {
261
259
  resultExplore = preparedResult.resultExplore;
262
260
  sql = preparedResult.sql;
263
261
  }
264
262
  else {
265
- throw new Error("Internal error: sqlBlock or preparedResult must be provided.");
263
+ throw new Error("Internal error: sqlStruct or preparedResult must be provided.");
266
264
  }
267
265
  let index = 0;
268
266
  for await (const row of connection.runSQLStream(sql, options)) {
@@ -1419,7 +1417,7 @@ class Runtime {
1419
1417
  *
1420
1418
  * @param model The model URL or contents to load and (eventually) compile to retrieve the requested query.
1421
1419
  * @param name The name of the sql block to use within the model.
1422
- * @returns A promise of a `SQLBlock`.
1420
+ * @returns A promise of a `CompiledSQLBlock`.
1423
1421
  */
1424
1422
  getSQLBlockByName(model, name) {
1425
1423
  return this.loadSQLBlockByName(model, name).getSQLBlock();
@@ -1847,14 +1845,14 @@ class SQLBlockMaterializer extends FluentState {
1847
1845
  const connections = this.runtime.connections;
1848
1846
  return Malloy.run({
1849
1847
  connections,
1850
- sqlBlock,
1848
+ sqlStruct: sqlBlock,
1851
1849
  options,
1852
1850
  });
1853
1851
  }
1854
1852
  async *runStream(options) {
1855
- const sqlBlock = await this.getSQLBlock();
1853
+ const sqlStruct = await this.getSQLBlock();
1856
1854
  const connections = this.runtime.connections;
1857
- const stream = Malloy.runStream({ connections, sqlBlock, options });
1855
+ const stream = Malloy.runStream({ connections, sqlStruct, options });
1858
1856
  for await (const row of stream) {
1859
1857
  yield row;
1860
1858
  }
@@ -1873,8 +1871,8 @@ class SQLBlockMaterializer extends FluentState {
1873
1871
  * @returns A promise to the SQL string.
1874
1872
  */
1875
1873
  async getSQL() {
1876
- const sqlBlock = await this.getSQLBlock();
1877
- return sqlBlock.select;
1874
+ const sqlStruct = await this.getSQLBlock();
1875
+ return sqlStruct.structSource.sqlBlock.selectStr;
1878
1876
  }
1879
1877
  }
1880
1878
  exports.SQLBlockMaterializer = SQLBlockMaterializer;
package/dist/md5.d.ts ADDED
@@ -0,0 +1 @@
1
+ export declare const md5: (val: string) => string;
package/dist/md5.js ADDED
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.md5 = void 0;
27
+ const crypto = __importStar(require("crypto"));
28
+ const md5 = (val) => crypto.createHash("md5").update(val).digest("hex");
29
+ exports.md5 = md5;
30
+ //# sourceMappingURL=md5.js.map
@@ -2663,7 +2663,7 @@ class QueryStruct extends QueryNode {
2663
2663
  return this.fieldDef.name;
2664
2664
  }
2665
2665
  else if (this.fieldDef.structSource.method === "subquery") {
2666
- return `(${this.fieldDef.structSource.sqlBlock.select})`;
2666
+ return `(${this.fieldDef.structSource.sqlBlock.selectStr})`;
2667
2667
  }
2668
2668
  throw new Error("Internal Error: Unknown structSource type 'sql' method");
2669
2669
  case "nested":
@@ -43,7 +43,7 @@ export interface DocumentJoinReference extends DocumentReferenceBase {
43
43
  }
44
44
  export interface DocumentSQLBlockReference extends DocumentReferenceBase {
45
45
  type: "sqlBlockReference";
46
- definition: SQLBlock;
46
+ definition: SQLBlockStructDef;
47
47
  }
48
48
  export interface DocumentQueryReference extends DocumentReferenceBase {
49
49
  type: "queryReference";
@@ -371,19 +371,25 @@ export declare type StructRelationship = {
371
371
  field: FieldRef;
372
372
  isArray: boolean;
373
373
  };
374
- export interface SQLSelectStatements {
375
- before?: string[];
376
- select: string;
377
- after?: string[];
374
+ export interface SQLFragment {
375
+ sql: string;
378
376
  }
377
+ export declare type SQLPhrase = Query | SQLFragment;
378
+ export declare function isSQLFragment(f: SQLPhrase): f is SQLFragment;
379
379
  /**
380
- * Use factory makeSQLBlock to create one of these, it will compute the
381
- * name: property and fill it in.
380
+ * A source reference to an SQL block. The compiler uses these to request
381
+ * an SQLBlock with it's schema and structdef defined. Use the factory
382
+ * makeSQLBlock to construct these.
382
383
  */
383
- export interface SQLBlock extends NamedObject, SQLSelectStatements {
384
- type: "sqlBlock";
384
+ export interface SQLBlockSource {
385
385
  name: string;
386
386
  connection?: string;
387
+ select: SQLPhrase[];
388
+ }
389
+ export interface SQLBlock extends NamedObject {
390
+ type: "sqlBlock";
391
+ connection?: string;
392
+ selectStr: string;
387
393
  }
388
394
  interface SubquerySource {
389
395
  type: "sql";
@@ -417,6 +423,10 @@ export interface StructDef extends NamedObject, ResultStructMetadata, Filtered {
417
423
  parameters?: Record<string, Parameter>;
418
424
  dialect: string;
419
425
  }
426
+ export interface SQLBlockStructDef extends StructDef {
427
+ structSource: SubquerySource;
428
+ }
429
+ export declare function isSQLBlock(sd: StructDef): sd is SQLBlockStructDef;
420
430
  /** any of the different field types */
421
431
  export declare type FieldTypeDef = FieldStringDef | FieldDateDef | FieldTimestampDef | FieldNumberDef | FieldBooleanDef;
422
432
  export declare function isFieldTypeDef(f: FieldDef): f is FieldTypeDef;
@@ -12,7 +12,7 @@
12
12
  * GNU General Public License for more details.
13
13
  */
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
- exports.isValueDate = exports.isValueTimestamp = exports.isValueBoolean = exports.isValueNumber = exports.isValueString = exports.isMeasureLike = exports.getPhysicalFields = exports.getDimensions = exports.isPhysical = exports.isDimensional = exports.isTurtleDef = exports.getIdentifier = exports.isFieldStructDef = exports.isFieldTimeBased = exports.isFieldTypeDef = exports.isJoinOn = exports.isIndexSegment = exports.isSamplingEnable = exports.isSamplingPercent = exports.isSamplingRows = exports.isQuerySegment = exports.isProjectSegment = exports.isReduceSegment = exports.refIsStructDef = exports.isByExpression = exports.isByName = exports.ValueType = exports.isExtractUnit = exports.isTimestampUnit = exports.isDateUnit = exports.FieldIsIntrinsic = exports.isAtomicFieldType = exports.isTimeFieldType = exports.hasExpression = exports.mkExpr = exports.isApplyFragment = exports.isApplyValue = exports.isParameterFragment = exports.isFieldFragment = exports.isUngroupFragment = exports.isAsymmetricFragment = exports.isAggregateFragment = exports.isDialectFragment = exports.isFilterFragment = exports.isFilteredAliasedName = exports.paramHasValue = exports.isConditionParameter = exports.isValueParameter = void 0;
15
+ exports.isValueDate = exports.isValueTimestamp = exports.isValueBoolean = exports.isValueNumber = exports.isValueString = exports.isMeasureLike = exports.getPhysicalFields = exports.getDimensions = exports.isPhysical = exports.isDimensional = exports.isTurtleDef = exports.getIdentifier = exports.isFieldStructDef = exports.isFieldTimeBased = exports.isFieldTypeDef = exports.isSQLBlock = exports.isSQLFragment = exports.isJoinOn = exports.isIndexSegment = exports.isSamplingEnable = exports.isSamplingPercent = exports.isSamplingRows = exports.isQuerySegment = exports.isProjectSegment = exports.isReduceSegment = exports.refIsStructDef = exports.isByExpression = exports.isByName = exports.ValueType = exports.isExtractUnit = exports.isTimestampUnit = exports.isDateUnit = exports.FieldIsIntrinsic = exports.isAtomicFieldType = exports.isTimeFieldType = exports.hasExpression = exports.mkExpr = exports.isApplyFragment = exports.isApplyValue = exports.isParameterFragment = exports.isFieldFragment = exports.isUngroupFragment = exports.isAsymmetricFragment = exports.isAggregateFragment = exports.isDialectFragment = exports.isFilterFragment = exports.isFilteredAliasedName = exports.paramHasValue = exports.isConditionParameter = exports.isValueParameter = void 0;
16
16
  function isValueParameter(p) {
17
17
  return p.value !== undefined;
18
18
  }
@@ -199,6 +199,15 @@ function isJoinOn(sr) {
199
199
  return ["one", "many", "cross"].includes(sr.type);
200
200
  }
201
201
  exports.isJoinOn = isJoinOn;
202
+ function isSQLFragment(f) {
203
+ return f.sql !== undefined;
204
+ }
205
+ exports.isSQLFragment = isSQLFragment;
206
+ function isSQLBlock(sd) {
207
+ const src = sd.structSource;
208
+ return src.type == "sql" && src.method == "subquery";
209
+ }
210
+ exports.isSQLBlock = isSQLBlock;
202
211
  function isFieldTypeDef(f) {
203
212
  return (f.type === "string" ||
204
213
  f.type === "date" ||
@@ -1,11 +1,7 @@
1
- import { SQLBlock } from "./malloy_types";
1
+ import { SQLBlockSource, SQLPhrase } from "./malloy_types";
2
2
  /**
3
- * SQLBlockRequest does not have a digest in it
3
+ * The factory for SQLBlocks. Exists because the name is computed
4
+ * from the components of the block and that name needs to be
5
+ * unique, but predictable.
4
6
  */
5
- export interface SQLBlockRequest extends Partial<SQLBlock> {
6
- select: string;
7
- }
8
- /**
9
- * The factory for SQLBlocks.
10
- */
11
- export declare function makeSQLBlock(from: SQLBlockRequest): SQLBlock;
7
+ export declare function makeSQLBlock(select: SQLPhrase[], connection?: string): SQLBlockSource;
@@ -16,26 +16,34 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
16
16
  };
17
17
  Object.defineProperty(exports, "__esModule", { value: true });
18
18
  exports.makeSQLBlock = void 0;
19
+ const malloy_types_1 = require("./malloy_types");
19
20
  const md5_1 = __importDefault(require("md5"));
20
21
  /**
21
- * The factory for SQLBlocks.
22
+ * The factory for SQLBlocks. Exists because the name is computed
23
+ * from the components of the block and that name needs to be
24
+ * unique, but predictable.
22
25
  */
23
- function makeSQLBlock(from) {
26
+ function makeSQLBlock(select, connection) {
24
27
  const theBlock = {
25
- type: "sqlBlock",
26
- name: `md5:/${from.connection || "$default"}//${(0, md5_1.default)(from.select)}`,
27
- select: from.select,
28
+ name: `md5:/${connection || "$default"}//${nameFor(select)}`,
29
+ select,
28
30
  };
29
- if (from.before) {
30
- theBlock.before = from.before;
31
- }
32
- if (from.after) {
33
- theBlock.after = from.after;
34
- }
35
- if (from.connection) {
36
- theBlock.connection = from.connection;
31
+ if (connection) {
32
+ theBlock.connection = connection;
37
33
  }
38
34
  return theBlock;
39
35
  }
40
36
  exports.makeSQLBlock = makeSQLBlock;
37
+ // This feels like wrongness on toast, before SQL contained a query we
38
+ // could compute a stable hash from the select property to use to
39
+ // indentify this piece of SQL. Now the actual SQL isn't known until
40
+ // runtime and I am not certain what the right thing to do is, and
41
+ // at this moment when I am still trying to imagine how this is all
42
+ // going to work, I am using stringify(), but I suspect I will be back
43
+ // here for later, and that the whole "how to determine the name of a query"
44
+ // algorithm needs to change
45
+ function nameFor(select) {
46
+ const phrases = select.map((el) => (0, malloy_types_1.isSQLFragment)(el) ? el.sql : JSON.stringify(el));
47
+ return (0, md5_1.default)(phrases.join(";"));
48
+ }
41
49
  //# sourceMappingURL=sql_block.js.map
@@ -43,14 +43,17 @@ export interface InfoConnection {
43
43
  errors: Record<string, string>;
44
44
  }>;
45
45
  /**
46
- * Fetch schemas for multiple SQL blocks.
46
+ * Fetch schemas an SQL blocks
47
47
  *
48
- * @param tables The SQL blocks to fetch schemas for.
48
+ * @param block The SQL blocks to fetch schemas for.
49
49
  * @returns A mapping of SQL block names to schemas.
50
50
  */
51
- fetchSchemaForSQLBlocks(sqlStructs: SQLBlock[]): Promise<{
52
- schemas: Record<string, StructDef>;
53
- errors: Record<string, string>;
51
+ fetchSchemaForSQLBlock(block: SQLBlock): Promise<{
52
+ structDef: StructDef;
53
+ error?: undefined;
54
+ } | {
55
+ error: string;
56
+ structDef?: undefined;
54
57
  }>;
55
58
  /**
56
59
  * The name of the connection.
@@ -72,9 +75,7 @@ export interface Connection extends InfoConnection {
72
75
  runSQL(sql: string, options?: RunSQLOptions): Promise<MalloyQueryData>;
73
76
  isPool(): this is PooledConnection;
74
77
  canPersist(): this is PersistSQLResults;
75
- canFetchSchemaAndRunSimultaneously(): this is FetchSchemaAndRunSimultaneously;
76
78
  canStream(): this is StreamingConnection;
77
- canFetchSchemaAndRunStreamSimultaneously(): this is FetchSchemaAndRunStreamSimultaneously;
78
79
  }
79
80
  export interface TestableConnection extends Connection {
80
81
  test(): Promise<void>;
@@ -86,27 +87,11 @@ export interface PooledConnection extends Connection {
86
87
  export interface PersistSQLResults extends Connection {
87
88
  manifestTemporaryTable(sqlCommand: string): Promise<string>;
88
89
  }
89
- export interface FetchSchemaAndRunSimultaneously extends Connection {
90
- runSQLBlockAndFetchResultSchema(sqlBlock: SQLBlock, options?: {
91
- rowLimit?: number;
92
- }): Promise<{
93
- data: MalloyQueryData;
94
- schema: StructDef;
95
- }>;
96
- }
97
90
  export interface StreamingConnection extends Connection {
98
91
  runSQLStream(sqlCommand: string, options?: {
99
92
  rowLimit?: number;
100
93
  }): AsyncIterableIterator<QueryDataRow>;
101
94
  }
102
- export interface FetchSchemaAndRunStreamSimultaneously extends StreamingConnection, FetchSchemaAndRunSimultaneously {
103
- runSQLBlockStreamAndFetchResultSchema(sqlCommand: string, options?: {
104
- rowLimit?: number;
105
- }): Promise<{
106
- stream: AsyncIterableIterator<QueryDataRow>;
107
- schema: StructDef;
108
- }>;
109
- }
110
95
  /**
111
96
  * A mapping of connection names to connections.
112
97
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@malloydata/malloy",
3
- "version": "0.0.11-dev221202152346",
3
+ "version": "0.0.11",
4
4
  "license": "GPL-2.0",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",