@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/index.d.ts +1 -1
- package/dist/lang/ast/ast-main.d.ts +61 -21
- package/dist/lang/ast/ast-main.js +170 -92
- package/dist/lang/index.d.ts +1 -1
- package/dist/lang/lib/Malloy/MalloyLexer.d.ts +135 -128
- package/dist/lang/lib/Malloy/MalloyLexer.js +1124 -1069
- package/dist/lang/lib/Malloy/MalloyListener.d.ts +2026 -0
- package/dist/lang/lib/Malloy/MalloyListener.js +4 -0
- package/dist/lang/lib/Malloy/MalloyParser.d.ts +276 -232
- package/dist/lang/lib/Malloy/MalloyParser.js +1719 -1456
- package/dist/lang/lib/Malloy/MalloyParserListener.d.ts +48 -15
- package/dist/lang/lib/Malloy/MalloyParserVisitor.d.ts +30 -9
- package/dist/lang/lib/Malloy/MalloyVisitor.d.ts +1276 -0
- package/dist/lang/lib/Malloy/MalloyVisitor.js +4 -0
- package/dist/lang/parse-malloy.d.ts +14 -23
- package/dist/lang/parse-malloy.js +37 -51
- package/dist/lang/parse-to-ast.d.ts +3 -2
- package/dist/lang/parse-to-ast.js +45 -13
- package/dist/lang/parse-tree-walkers/document-symbol-walker.js +2 -2
- package/dist/lang/test/parse.spec.d.ts +5 -3
- package/dist/lang/test/parse.spec.js +267 -181
- package/dist/malloy.d.ts +20 -20
- package/dist/malloy.js +73 -75
- package/dist/md5.d.ts +1 -0
- package/dist/md5.js +30 -0
- package/dist/model/malloy_query.js +1 -1
- package/dist/model/malloy_types.d.ts +19 -9
- package/dist/model/malloy_types.js +10 -1
- package/dist/model/sql_block.d.ts +5 -9
- package/dist/model/sql_block.js +21 -13
- package/dist/runtime_types.d.ts +8 -23
- package/package.json +1 -1
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
|
|
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
|
-
|
|
79
|
+
sqlStruct: SQLBlockStructDef;
|
|
80
80
|
options?: RunSQLOptions;
|
|
81
81
|
}): Promise<Result>;
|
|
82
82
|
static run(params: {
|
|
83
83
|
connections: LookupConnection<Connection>;
|
|
84
|
-
|
|
84
|
+
sqlStruct: SQLBlockStructDef;
|
|
85
85
|
options?: RunSQLOptions;
|
|
86
86
|
}): Promise<Result>;
|
|
87
87
|
static run(params: {
|
|
88
88
|
connection: Connection;
|
|
89
|
-
|
|
89
|
+
sqlStruct: SQLBlockStructDef;
|
|
90
90
|
options?: RunSQLOptions;
|
|
91
91
|
}): Promise<Result>;
|
|
92
92
|
static run(params: {
|
|
93
93
|
connections: LookupConnection<Connection>;
|
|
94
|
-
|
|
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
|
-
|
|
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
|
-
|
|
119
|
+
sqlStruct: SQLBlockStructDef;
|
|
120
120
|
options?: RunSQLOptions;
|
|
121
121
|
}): AsyncIterableIterator<DataRecord>;
|
|
122
122
|
static runStream(params: {
|
|
123
123
|
connections: LookupConnection<Connection>;
|
|
124
|
-
|
|
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:
|
|
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):
|
|
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):
|
|
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 `
|
|
711
|
+
* @returns A promise of a `CompiledSQLBlock`.
|
|
712
712
|
*/
|
|
713
|
-
getSQLBlockByName(model: ModelURL | ModelString, name: string): Promise<
|
|
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<
|
|
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<
|
|
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<
|
|
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<
|
|
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<
|
|
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<
|
|
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.
|
|
135
|
-
//
|
|
136
|
-
const
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
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
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
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
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
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,
|
|
189
|
-
|
|
190
|
-
|
|
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 (
|
|
200
|
-
|
|
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: [
|
|
206
|
-
sql: sqlBlock.
|
|
204
|
+
structs: [sqlStruct],
|
|
205
|
+
sql: sqlBlock.selectStr,
|
|
207
206
|
result: data.rows,
|
|
208
207
|
totalRows: data.totalRows,
|
|
209
|
-
lastStageName:
|
|
208
|
+
lastStageName: sqlBlock.name,
|
|
210
209
|
// TODO feature-sql-block There is no malloy code...
|
|
211
210
|
malloy: "",
|
|
212
|
-
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
|
|
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:
|
|
230
|
+
throw new Error("Internal error: sqlStruct or preparedResult must be provided.");
|
|
232
231
|
}
|
|
233
232
|
}
|
|
234
|
-
static async *runStream({ connections, preparedResult,
|
|
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 (
|
|
252
|
-
|
|
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(
|
|
258
|
-
sql = sqlBlock.
|
|
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:
|
|
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 `
|
|
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
|
|
1853
|
+
const sqlStruct = await this.getSQLBlock();
|
|
1856
1854
|
const connections = this.runtime.connections;
|
|
1857
|
-
const stream = Malloy.runStream({ connections,
|
|
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
|
|
1877
|
-
return sqlBlock.
|
|
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.
|
|
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:
|
|
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
|
|
375
|
-
|
|
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
|
-
*
|
|
381
|
-
*
|
|
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
|
|
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 {
|
|
1
|
+
import { SQLBlockSource, SQLPhrase } from "./malloy_types";
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
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
|
|
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;
|
package/dist/model/sql_block.js
CHANGED
|
@@ -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(
|
|
26
|
+
function makeSQLBlock(select, connection) {
|
|
24
27
|
const theBlock = {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
select: from.select,
|
|
28
|
+
name: `md5:/${connection || "$default"}//${nameFor(select)}`,
|
|
29
|
+
select,
|
|
28
30
|
};
|
|
29
|
-
if (
|
|
30
|
-
theBlock.
|
|
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
|
package/dist/runtime_types.d.ts
CHANGED
|
@@ -43,14 +43,17 @@ export interface InfoConnection {
|
|
|
43
43
|
errors: Record<string, string>;
|
|
44
44
|
}>;
|
|
45
45
|
/**
|
|
46
|
-
* Fetch schemas
|
|
46
|
+
* Fetch schemas an SQL blocks
|
|
47
47
|
*
|
|
48
|
-
* @param
|
|
48
|
+
* @param block The SQL blocks to fetch schemas for.
|
|
49
49
|
* @returns A mapping of SQL block names to schemas.
|
|
50
50
|
*/
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
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
|
*/
|