@malloydata/malloy 0.0.2 → 0.0.3
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/README.md +12 -11
- package/dist/dialect/duckdb.d.ts +1 -1
- package/dist/dialect/duckdb.js +35 -37
- package/dist/dialect/postgres.d.ts +1 -1
- package/dist/dialect/postgres.js +15 -8
- package/dist/dialect/standardsql.js +1 -0
- package/dist/index.d.ts +4 -4
- package/dist/index.js +2 -2
- package/dist/lang/ast/apply-expr.js +2 -2
- package/dist/lang/ast/ast-expr.js +2 -12
- package/dist/lang/ast/ast-main.d.ts +2 -2
- package/dist/lang/ast/ast-main.js +2 -1
- package/dist/lang/field-space.d.ts +9 -7
- package/dist/lang/field-space.js +10 -8
- package/dist/lang/lib/Malloy/MalloyLexer.d.ts +108 -106
- package/dist/lang/lib/Malloy/MalloyLexer.js +1019 -1006
- package/dist/lang/lib/Malloy/MalloyParser.d.ts +581 -590
- package/dist/lang/lib/Malloy/MalloyParser.js +1141 -1202
- package/dist/lang/lib/Malloy/MalloyParserListener.d.ts +2015 -0
- package/dist/lang/lib/Malloy/MalloyParserListener.js +4 -0
- package/dist/lang/lib/Malloy/MalloyParserVisitor.d.ts +1269 -0
- package/dist/lang/lib/Malloy/MalloyParserVisitor.js +4 -0
- package/dist/lang/parse-to-ast.d.ts +3 -4
- package/dist/lang/parse-to-ast.js +1 -1
- package/dist/lang/parse-tree-walkers/document-completion-walker.js +2 -0
- package/dist/lang/parse-tree-walkers/explore-query-walker.d.ts +2 -2
- package/dist/lang/test/field-symbols.spec.js +2 -2
- package/dist/lang/test/parse.spec.js +15 -0
- package/dist/lang/test/test-translator.js +1 -1
- package/dist/malloy.d.ts +1 -1
- package/dist/malloy.js +11 -5
- package/dist/md5.d.ts +1 -0
- package/dist/md5.js +30 -0
- package/dist/model/malloy_query.js +4 -6
- package/dist/model/malloy_types.d.ts +3 -1
- package/package.json +9 -14
- package/dist/dialect/dialect-map.d.ts +0 -3
- package/dist/dialect/dialect-map.js +0 -33
- package/dist/model/malloy-query.d.ts +0 -313
- package/dist/model/malloy-query.js +0 -2603
- package/dist/model/malloy-types.d.ts +0 -404
- package/dist/model/malloy-types.js +0 -242
- package/dist/model/sql-block.d.ts +0 -11
- package/dist/model/sql-block.js +0 -38
- package/dist/runtime-types.d.ts +0 -116
- package/dist/runtime-types.js +0 -40
package/README.md
CHANGED
|
@@ -9,17 +9,16 @@ This package facilitates building the Malloy language - or the usage of data mod
|
|
|
9
9
|
## Show me an example!
|
|
10
10
|
|
|
11
11
|
```
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
const connection = new
|
|
16
|
-
const runtime = new
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
12
|
+
const malloy = require("@malloydata/malloy")
|
|
13
|
+
const bigquery = require("@malloydata/db-bigquery")
|
|
14
|
+
|
|
15
|
+
const connection = new bigquery.BigQueryConnection("bigquery");
|
|
16
|
+
const runtime = new malloy.SingleConnectionRuntime(connection);
|
|
17
|
+
const model = runtime.loadModel("source: airports is table('malloytest.airports')")
|
|
18
|
+
const runner = model.loadQuery("query: airports->{aggregate: airport_count is count()}")
|
|
19
|
+
runner.run().then((result) => {
|
|
20
|
+
console.log(result.data.value) // [ { airport_count: 19793 } ]
|
|
21
|
+
})
|
|
23
22
|
```
|
|
24
23
|
|
|
25
24
|
Note: These APIs are still in beta and subject to change.
|
|
@@ -37,3 +36,5 @@ In practice, much of this loop is handled by various database plugins:
|
|
|
37
36
|
## Do you have any examples?
|
|
38
37
|
|
|
39
38
|
You can find a (very) simple example of writing a CLI for executing Malloy queries [here](https://github.com/looker-open-source/malloy/tree/main/demo/malloy-demo-bq-cli)
|
|
39
|
+
|
|
40
|
+
A more realistic and complex use case - we use these libraries to power our VSCode Extension. Some examples can be found [here](https://github.com/looker-open-source/malloy/tree/main/vscode-extension/src/extension/commands)
|
package/dist/dialect/duckdb.d.ts
CHANGED
|
@@ -34,7 +34,7 @@ export declare class DuckDBDialect extends Dialect {
|
|
|
34
34
|
sqlSelectAliasAsStruct(alias: string, physicalFieldNames: string[]): string;
|
|
35
35
|
sqlMaybeQuoteIdentifier(identifier: string): string;
|
|
36
36
|
sqlCreateTableAsSelect(_tableName: string, _sql: string): string;
|
|
37
|
-
getFunctionInfo(
|
|
37
|
+
getFunctionInfo(functionName: string): FunctionInfo | undefined;
|
|
38
38
|
sqlMeasureTime(from: TimeValue, to: TimeValue, units: string): Expr;
|
|
39
39
|
sqlNow(): Expr;
|
|
40
40
|
sqlTrunc(sqlTime: TimeValue, units: TimestampUnit): Expr;
|
package/dist/dialect/duckdb.js
CHANGED
|
@@ -109,8 +109,6 @@ const inSeconds = {
|
|
|
109
109
|
second: 1,
|
|
110
110
|
minute: 60,
|
|
111
111
|
hour: 3600,
|
|
112
|
-
day: 86400,
|
|
113
|
-
week: 604800,
|
|
114
112
|
};
|
|
115
113
|
class DuckDBDialect extends dialect_1.Dialect {
|
|
116
114
|
constructor() {
|
|
@@ -125,7 +123,9 @@ class DuckDBDialect extends dialect_1.Dialect {
|
|
|
125
123
|
this.defaultSampling = { rows: 50000 };
|
|
126
124
|
this.supportUnnestArrayAgg = true;
|
|
127
125
|
this.supportsCTEinCoorelatedSubQueries = true;
|
|
128
|
-
this.functionInfo = {
|
|
126
|
+
this.functionInfo = {
|
|
127
|
+
concat: { returnType: "string" },
|
|
128
|
+
};
|
|
129
129
|
}
|
|
130
130
|
// hack until they support temporary macros.
|
|
131
131
|
get udfPrefix() {
|
|
@@ -230,8 +230,8 @@ class DuckDBDialect extends dialect_1.Dialect {
|
|
|
230
230
|
sqlCreateTableAsSelect(_tableName, _sql) {
|
|
231
231
|
throw new Error("Not implemented Yet");
|
|
232
232
|
}
|
|
233
|
-
getFunctionInfo(
|
|
234
|
-
return
|
|
233
|
+
getFunctionInfo(functionName) {
|
|
234
|
+
return this.functionInfo[functionName];
|
|
235
235
|
}
|
|
236
236
|
sqlMeasureTime(from, to, units) {
|
|
237
237
|
let lVal = from.value;
|
|
@@ -242,21 +242,20 @@ class DuckDBDialect extends dialect_1.Dialect {
|
|
|
242
242
|
const duration = (0, model_1.mkExpr) `(${rVal} - ${lVal})`;
|
|
243
243
|
return units == "second"
|
|
244
244
|
? duration
|
|
245
|
-
: (0, model_1.mkExpr) `
|
|
245
|
+
: (0, model_1.mkExpr) `FLOOR(${duration}/${inSeconds[units].toString()})`;
|
|
246
246
|
}
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
return yearDiff;
|
|
247
|
+
if (from.valueType != "date") {
|
|
248
|
+
lVal = (0, model_1.mkExpr) `CAST((${lVal}) AS DATE)`;
|
|
250
249
|
}
|
|
251
|
-
if (
|
|
252
|
-
|
|
253
|
-
return (0, model_1.mkExpr) `${yearDiff} * 12 + ${monthDiff}`;
|
|
250
|
+
if (to.valueType != "date") {
|
|
251
|
+
rVal = (0, model_1.mkExpr) `CAST((${rVal}) AS DATE)`;
|
|
254
252
|
}
|
|
255
|
-
if (units == "
|
|
256
|
-
|
|
257
|
-
|
|
253
|
+
if (units == "week") {
|
|
254
|
+
// DuckDB's weeks start on Monday, but Malloy's weeks start on Sunday
|
|
255
|
+
lVal = (0, model_1.mkExpr) `(${lVal} + INTERVAL 1 DAY)`;
|
|
256
|
+
rVal = (0, model_1.mkExpr) `(${rVal} + INTERVAL 1 DAY)`;
|
|
258
257
|
}
|
|
259
|
-
|
|
258
|
+
return (0, model_1.mkExpr) `DATE_DIFF('${units}', ${lVal}, ${rVal})`;
|
|
260
259
|
}
|
|
261
260
|
sqlNow() {
|
|
262
261
|
return (0, model_1.mkExpr) `CURRENT_TIMESTAMP`;
|
|
@@ -265,10 +264,10 @@ class DuckDBDialect extends dialect_1.Dialect {
|
|
|
265
264
|
// adjusting for monday/sunday weeks
|
|
266
265
|
const week = units == "week";
|
|
267
266
|
const truncThis = week
|
|
268
|
-
? (0, model_1.mkExpr) `${sqlTime.value}+
|
|
267
|
+
? (0, model_1.mkExpr) `${sqlTime.value} + INTERVAL 1 DAY`
|
|
269
268
|
: sqlTime.value;
|
|
270
269
|
const trunced = (0, model_1.mkExpr) `DATE_TRUNC('${units}', ${truncThis})`;
|
|
271
|
-
return week ? (0, model_1.mkExpr) `(${trunced}-
|
|
270
|
+
return week ? (0, model_1.mkExpr) `(${trunced} - INTERVAL 1 DAY)` : trunced;
|
|
272
271
|
}
|
|
273
272
|
sqlExtract(from, units) {
|
|
274
273
|
const pgUnits = pgExtractionMap[units] || units;
|
|
@@ -284,8 +283,8 @@ class DuckDBDialect extends dialect_1.Dialect {
|
|
|
284
283
|
timeframe = "day";
|
|
285
284
|
n = (0, model_1.mkExpr) `${n}*7`;
|
|
286
285
|
}
|
|
287
|
-
const interval = (0, model_1.mkExpr) `INTERVAL ${n} ${timeframe}`;
|
|
288
|
-
return (0, model_1.mkExpr) `((${expr.value})${op}${interval}
|
|
286
|
+
const interval = (0, model_1.mkExpr) `INTERVAL (${n}) ${timeframe}`;
|
|
287
|
+
return (0, model_1.mkExpr) `((${expr.value})) ${op} ${interval}`;
|
|
289
288
|
}
|
|
290
289
|
sqlCast(cast) {
|
|
291
290
|
if (cast.dstType !== cast.srcType) {
|
|
@@ -299,7 +298,7 @@ class DuckDBDialect extends dialect_1.Dialect {
|
|
|
299
298
|
}
|
|
300
299
|
sqlLiteralTime(timeString, type, _timezone) {
|
|
301
300
|
if (type == "date") {
|
|
302
|
-
return `DATE
|
|
301
|
+
return `DATE '${timeString}'`;
|
|
303
302
|
}
|
|
304
303
|
else if (type == "timestamp") {
|
|
305
304
|
return `TIMESTAMP '${timeString}'`;
|
|
@@ -308,24 +307,23 @@ class DuckDBDialect extends dialect_1.Dialect {
|
|
|
308
307
|
throw new Error(`Unknown Literal time format ${type}`);
|
|
309
308
|
}
|
|
310
309
|
}
|
|
311
|
-
// sqlSumDistinct(key: string, value: string): string {
|
|
312
|
-
// // return `sum_distinct(list({key:${key}, val: ${value}}))`;
|
|
313
|
-
// return `(
|
|
314
|
-
// fail -- force the query for fail until the bug is fixed.
|
|
315
|
-
// SELECT sum(a.val) as value
|
|
316
|
-
// FROM (
|
|
317
|
-
// SELECT UNNEST(list(distinct {key:${key}, val: ${value}})) a
|
|
318
|
-
// )
|
|
319
|
-
// )`;
|
|
320
|
-
// }
|
|
321
310
|
sqlSumDistinct(key, value) {
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
311
|
+
// return `sum_distinct(list({key:${key}, val: ${value}}))`;
|
|
312
|
+
return `(
|
|
313
|
+
SELECT sum(a.val) as value
|
|
314
|
+
FROM (
|
|
315
|
+
SELECT UNNEST(list(distinct {key:${key}, val: ${value}})) a
|
|
316
|
+
)
|
|
317
|
+
)`;
|
|
328
318
|
}
|
|
319
|
+
// sqlSumDistinct(key: string, value: string): string {
|
|
320
|
+
// const _factor = 32;
|
|
321
|
+
// const precision = 0.000001;
|
|
322
|
+
// const keySQL = `md5_number_lower(${key}::varchar)::int128`;
|
|
323
|
+
// return `
|
|
324
|
+
// (SUM(DISTINCT ${keySQL} + FLOOR(IFNULL(${value},0)/${precision})::int128) - SUM(DISTINCT ${keySQL}))*${precision}
|
|
325
|
+
// `;
|
|
326
|
+
// }
|
|
329
327
|
// default duckdb to sampling 50K rows.
|
|
330
328
|
sqlSampleTable(tableSQL, sample) {
|
|
331
329
|
if (sample !== undefined) {
|
|
@@ -41,7 +41,7 @@ export declare class PostgresDialect extends Dialect {
|
|
|
41
41
|
sqlCast(cast: TypecastFragment): Expr;
|
|
42
42
|
sqlRegexpMatch(expr: Expr, regexp: string): Expr;
|
|
43
43
|
sqlLiteralTime(timeString: string, type: TimeFieldType, _timezone: string): string;
|
|
44
|
-
getFunctionInfo(
|
|
44
|
+
getFunctionInfo(functionName: string): FunctionInfo | undefined;
|
|
45
45
|
sqlMeasureTime(from: TimeValue, to: TimeValue, units: string): Expr;
|
|
46
46
|
sqlSumDistinct(key: string, value: string): string;
|
|
47
47
|
sqlSampleTable(tableSQL: string, sample: Sampling | undefined): string;
|
package/dist/dialect/postgres.js
CHANGED
|
@@ -37,8 +37,6 @@ const inSeconds = {
|
|
|
37
37
|
second: 1,
|
|
38
38
|
minute: 60,
|
|
39
39
|
hour: 3600,
|
|
40
|
-
day: 86400,
|
|
41
|
-
week: 604800,
|
|
42
40
|
};
|
|
43
41
|
class PostgresDialect extends dialect_1.Dialect {
|
|
44
42
|
constructor() {
|
|
@@ -54,7 +52,9 @@ class PostgresDialect extends dialect_1.Dialect {
|
|
|
54
52
|
this.defaultSampling = { rows: 50000 };
|
|
55
53
|
this.supportUnnestArrayAgg = true;
|
|
56
54
|
this.supportsCTEinCoorelatedSubQueries = true;
|
|
57
|
-
this.functionInfo = {
|
|
55
|
+
this.functionInfo = {
|
|
56
|
+
concat: { returnType: "string" },
|
|
57
|
+
};
|
|
58
58
|
}
|
|
59
59
|
quoteTablePath(tablePath) {
|
|
60
60
|
return tablePath
|
|
@@ -249,8 +249,8 @@ class PostgresDialect extends dialect_1.Dialect {
|
|
|
249
249
|
throw new Error(`Unknown Literal time format ${type}`);
|
|
250
250
|
}
|
|
251
251
|
}
|
|
252
|
-
getFunctionInfo(
|
|
253
|
-
return
|
|
252
|
+
getFunctionInfo(functionName) {
|
|
253
|
+
return this.functionInfo[functionName];
|
|
254
254
|
}
|
|
255
255
|
sqlMeasureTime(from, to, units) {
|
|
256
256
|
let lVal = from.value;
|
|
@@ -263,16 +263,23 @@ class PostgresDialect extends dialect_1.Dialect {
|
|
|
263
263
|
? duration
|
|
264
264
|
: (0, model_1.mkExpr) `TRUNC(${duration}/${inSeconds[units].toString()})`;
|
|
265
265
|
}
|
|
266
|
-
|
|
266
|
+
if (units === "day") {
|
|
267
|
+
return (0, model_1.mkExpr) `${rVal}::date - ${lVal}::date`;
|
|
268
|
+
}
|
|
269
|
+
const yearDiff = (0, model_1.mkExpr) `(DATE_PART('year', ${rVal}) - DATE_PART('year', ${lVal}))`;
|
|
267
270
|
if (units == "year") {
|
|
268
271
|
return yearDiff;
|
|
269
272
|
}
|
|
273
|
+
if (units == "week") {
|
|
274
|
+
const dayDiffForWeekStart = (0, model_1.mkExpr) `(DATE_TRUNC('week', ${rVal} + '1 day'::interval)::date - DATE_TRUNC('week', ${lVal} + '1 day'::interval)::date)`;
|
|
275
|
+
return (0, model_1.mkExpr) `${dayDiffForWeekStart} / 7`;
|
|
276
|
+
}
|
|
270
277
|
if (units == "month") {
|
|
271
|
-
const monthDiff = (0, model_1.mkExpr) `
|
|
278
|
+
const monthDiff = (0, model_1.mkExpr) `DATE_PART('month', ${rVal}) - DATE_PART('month', ${lVal})`;
|
|
272
279
|
return (0, model_1.mkExpr) `${yearDiff} * 12 + ${monthDiff}`;
|
|
273
280
|
}
|
|
274
281
|
if (units == "quarter") {
|
|
275
|
-
const qDiff = (0, model_1.mkExpr) `
|
|
282
|
+
const qDiff = (0, model_1.mkExpr) `DATE_PART('quarter', ${rVal}) - DATE_PART('quarter', ${lVal})`;
|
|
276
283
|
return (0, model_1.mkExpr) `${yearDiff} * 4 + ${qDiff}`;
|
|
277
284
|
}
|
|
278
285
|
throw new Error(`Unknown or unhandled postgres time unit: ${units}`);
|
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
export type { QueryDataRow, ModelDef, Fragment, Query, StructDef, NamedStructDefs, MalloyQueryData, AtomicFieldType as AtomicFieldTypeInner, DateUnit, ExtractUnit, TimestampUnit, TimeFieldType, QueryData, FieldTypeDef, Expr, DialectFragment, TimeValue, FilterExpression, SQLBlock, FieldDef, PipeSegment, QueryFieldDef, TurtleDef, SearchValueMapResult, SearchIndexResult, } from "./model";
|
|
1
|
+
export type { QueryDataRow, ModelDef, Fragment, Query, StructDef, StructRelationship, NamedStructDefs, MalloyQueryData, AtomicFieldType as AtomicFieldTypeInner, DateUnit, ExtractUnit, TimestampUnit, TimeFieldType, QueryData, FieldTypeDef, Expr, DialectFragment, TimeValue, FilterExpression, SQLBlock, FieldDef, FilteredAliasedName, PipeSegment, QueryFieldDef, TurtleDef, SearchValueMapResult, SearchIndexResult, } from "./model";
|
|
2
2
|
export { Segment, isFilteredAliasedName, } from "./model";
|
|
3
3
|
export { HighlightType, MalloyTranslator, } from "./lang";
|
|
4
4
|
export type { LogMessage, TranslateResponse } from "./lang";
|
|
5
|
-
export { Malloy, Runtime, AtomicFieldType, ConnectionRuntime, SingleConnectionRuntime, EmptyURLReader, InMemoryURLReader, FixedConnectionMap, MalloyError, JoinRelationship, SourceRelationship, DateTimeframe, TimestampTimeframe, Result,
|
|
6
|
-
export type { Explore, Model, PreparedQuery, PreparedResult, Field, AtomicField, ExploreField, QueryField, DataArray, DataRecord, DataColumn, DataArrayOrRecord, ModelMaterializer, DocumentSymbol, DocumentHighlight, ResultJSON, PreparedResultMaterializer, SQLBlockMaterializer, ExploreMaterializer, WriteStream, } from "./malloy";
|
|
7
|
-
export type { URLReader, InfoConnection, LookupConnection, Connection, QueryString, ModelString, QueryURL, ModelURL, PooledConnection, TestableConnection, PersistSQLResults, } from "./runtime_types";
|
|
5
|
+
export { Malloy, Runtime, AtomicFieldType, ConnectionRuntime, SingleConnectionRuntime, EmptyURLReader, InMemoryURLReader, FixedConnectionMap, MalloyError, JoinRelationship, SourceRelationship, DateTimeframe, TimestampTimeframe, Result, parseTableURI, QueryMaterializer, CSVWriter, JSONWriter, DataWriter, } from "./malloy";
|
|
6
|
+
export type { Explore, Model, PreparedQuery, PreparedResult, Field, AtomicField, ExploreField, QueryField, DataArray, DataRecord, DataColumn, DataArrayOrRecord, ModelMaterializer, DocumentSymbol, DocumentHighlight, ResultJSON, RunSQLOptions, PreparedResultMaterializer, SQLBlockMaterializer, ExploreMaterializer, WriteStream, } from "./malloy";
|
|
7
|
+
export type { URLReader, InfoConnection, LookupConnection, Connection, QueryString, ModelString, QueryURL, ModelURL, PooledConnection, TestableConnection, PersistSQLResults, FetchSchemaAndRunSimultaneously, StreamingConnection, FetchSchemaAndRunStreamSimultaneously, } from "./runtime_types";
|
|
8
8
|
export type { Loggable } from "./malloy";
|
|
9
9
|
export { toAsyncGenerator } from "./connection_utils";
|
package/dist/index.js
CHANGED
|
@@ -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.toAsyncGenerator = exports.DataWriter = exports.JSONWriter = exports.CSVWriter = exports.QueryMaterializer = exports.
|
|
15
|
+
exports.toAsyncGenerator = exports.DataWriter = exports.JSONWriter = exports.CSVWriter = exports.QueryMaterializer = exports.parseTableURI = exports.Result = exports.TimestampTimeframe = exports.DateTimeframe = exports.SourceRelationship = exports.JoinRelationship = exports.MalloyError = exports.FixedConnectionMap = exports.InMemoryURLReader = exports.EmptyURLReader = exports.SingleConnectionRuntime = exports.ConnectionRuntime = exports.AtomicFieldType = exports.Runtime = exports.Malloy = exports.MalloyTranslator = exports.HighlightType = exports.isFilteredAliasedName = exports.Segment = void 0;
|
|
16
16
|
var model_1 = require("./model");
|
|
17
17
|
// Used in Composer Demo
|
|
18
18
|
Object.defineProperty(exports, "Segment", { enumerable: true, get: function () { return model_1.Segment; } });
|
|
@@ -37,7 +37,7 @@ Object.defineProperty(exports, "SourceRelationship", { enumerable: true, get: fu
|
|
|
37
37
|
Object.defineProperty(exports, "DateTimeframe", { enumerable: true, get: function () { return malloy_1.DateTimeframe; } });
|
|
38
38
|
Object.defineProperty(exports, "TimestampTimeframe", { enumerable: true, get: function () { return malloy_1.TimestampTimeframe; } });
|
|
39
39
|
Object.defineProperty(exports, "Result", { enumerable: true, get: function () { return malloy_1.Result; } });
|
|
40
|
-
Object.defineProperty(exports, "
|
|
40
|
+
Object.defineProperty(exports, "parseTableURI", { enumerable: true, get: function () { return malloy_1.parseTableURI; } });
|
|
41
41
|
Object.defineProperty(exports, "QueryMaterializer", { enumerable: true, get: function () { return malloy_1.QueryMaterializer; } });
|
|
42
42
|
Object.defineProperty(exports, "CSVWriter", { enumerable: true, get: function () { return malloy_1.CSVWriter; } });
|
|
43
43
|
Object.defineProperty(exports, "JSONWriter", { enumerable: true, get: function () { return malloy_1.JSONWriter; } });
|
|
@@ -43,10 +43,10 @@ function applyBinary(fs, left, op, right) {
|
|
|
43
43
|
const num = left.getExpression(fs);
|
|
44
44
|
const denom = right.getExpression(fs);
|
|
45
45
|
if (num.dataType != "number") {
|
|
46
|
-
left.log("Numerator for division
|
|
46
|
+
left.log("Numerator for division must be a number");
|
|
47
47
|
}
|
|
48
48
|
else if (denom.dataType != "number") {
|
|
49
|
-
right.log("Denominator for division
|
|
49
|
+
right.log("Denominator for division must be a number");
|
|
50
50
|
}
|
|
51
51
|
else {
|
|
52
52
|
const div = {
|
|
@@ -96,20 +96,10 @@ class ConstantFieldSpace {
|
|
|
96
96
|
this.type = "fieldSpace";
|
|
97
97
|
}
|
|
98
98
|
structDef() {
|
|
99
|
-
|
|
100
|
-
type: "struct",
|
|
101
|
-
name: "empty structdef",
|
|
102
|
-
structSource: { type: "table" },
|
|
103
|
-
structRelationship: {
|
|
104
|
-
type: "basetable",
|
|
105
|
-
connectionName: "noConnection",
|
|
106
|
-
},
|
|
107
|
-
fields: [],
|
|
108
|
-
dialect: "noDialect",
|
|
109
|
-
};
|
|
99
|
+
throw new Error("ConstantFieldSpace cannot generate a structDef");
|
|
110
100
|
}
|
|
111
101
|
emptyStructDef() {
|
|
112
|
-
|
|
102
|
+
throw new Error("ConstantFieldSpace cannot generate a structDef");
|
|
113
103
|
}
|
|
114
104
|
lookup(_name) {
|
|
115
105
|
return {
|
|
@@ -303,9 +303,9 @@ export declare class WildcardFieldReference extends MalloyElement {
|
|
|
303
303
|
}
|
|
304
304
|
export declare class OrderBy extends MalloyElement {
|
|
305
305
|
readonly field: number | FieldName;
|
|
306
|
-
readonly dir?: "
|
|
306
|
+
readonly dir?: "desc" | "asc" | undefined;
|
|
307
307
|
elementType: string;
|
|
308
|
-
constructor(field: number | FieldName, dir?: "
|
|
308
|
+
constructor(field: number | FieldName, dir?: "desc" | "asc" | undefined);
|
|
309
309
|
get modelField(): string | number;
|
|
310
310
|
getOrderBy(_fs: FieldSpace): model.OrderBy;
|
|
311
311
|
}
|
|
@@ -55,7 +55,7 @@ const theErrorStruct = {
|
|
|
55
55
|
type: "struct",
|
|
56
56
|
name: "~malformed~",
|
|
57
57
|
dialect: "~malformed~",
|
|
58
|
-
structSource: { type: "table" },
|
|
58
|
+
structSource: { type: "table", tablePath: "//undefined_error_table_path" },
|
|
59
59
|
structRelationship: {
|
|
60
60
|
type: "basetable",
|
|
61
61
|
connectionName: "//undefined_error_connection",
|
|
@@ -867,6 +867,7 @@ class ExpressionJoin extends Join {
|
|
|
867
867
|
if (sourceDef.structSource.type === "query") {
|
|
868
868
|
// the name from query does not need to be preserved
|
|
869
869
|
joinStruct.name = this.name.refString;
|
|
870
|
+
delete joinStruct.as;
|
|
870
871
|
}
|
|
871
872
|
else {
|
|
872
873
|
joinStruct.as = this.name.refString;
|
|
@@ -48,10 +48,10 @@ export declare type SourceSpec = model.StructDef | FieldSpace;
|
|
|
48
48
|
/**
|
|
49
49
|
* Based on how things are constructed, the starting field space
|
|
50
50
|
* can either be another field space or an existing structdef.
|
|
51
|
-
* Using a
|
|
51
|
+
* Using a SpaceSeed allows a class to accept either one
|
|
52
52
|
* and use either version at some future time.
|
|
53
53
|
*/
|
|
54
|
-
declare class
|
|
54
|
+
declare class SpaceSeed {
|
|
55
55
|
readonly sourceSpec: SourceSpec;
|
|
56
56
|
private spaceSpec;
|
|
57
57
|
private asFS?;
|
|
@@ -65,7 +65,7 @@ declare class SourceSpace {
|
|
|
65
65
|
*/
|
|
66
66
|
export declare class DynamicSpace extends StaticSpace {
|
|
67
67
|
protected final: model.StructDef | undefined;
|
|
68
|
-
protected source:
|
|
68
|
+
protected source: SpaceSeed;
|
|
69
69
|
outputFS?: QuerySpace;
|
|
70
70
|
completions: (() => void)[];
|
|
71
71
|
private complete;
|
|
@@ -86,11 +86,13 @@ export declare class DynamicSpace extends StaticSpace {
|
|
|
86
86
|
structDef(): model.StructDef;
|
|
87
87
|
}
|
|
88
88
|
/**
|
|
89
|
-
*
|
|
90
|
-
*
|
|
91
|
-
* which
|
|
92
|
-
* space is
|
|
89
|
+
* Unlike a source, which is a refinement of a namespace, a query
|
|
90
|
+
* is creating a new unrelated namespace. The query starts with a
|
|
91
|
+
* source, which it might modify. This set of fields used to resolve
|
|
92
|
+
* expressions in the query is called the "input space". There is a
|
|
93
|
+
* specialized QuerySpace for each type of query operation.
|
|
93
94
|
*
|
|
95
|
+
* The query output is managed by an instance of ResultSpace.
|
|
94
96
|
*/
|
|
95
97
|
export declare class QuerySpace extends DynamicSpace {
|
|
96
98
|
readonly result: ResultSpace;
|
package/dist/lang/field-space.js
CHANGED
|
@@ -167,10 +167,10 @@ function isFieldSpace(x) {
|
|
|
167
167
|
/**
|
|
168
168
|
* Based on how things are constructed, the starting field space
|
|
169
169
|
* can either be another field space or an existing structdef.
|
|
170
|
-
* Using a
|
|
170
|
+
* Using a SpaceSeed allows a class to accept either one
|
|
171
171
|
* and use either version at some future time.
|
|
172
172
|
*/
|
|
173
|
-
class
|
|
173
|
+
class SpaceSeed {
|
|
174
174
|
constructor(sourceSpec) {
|
|
175
175
|
this.sourceSpec = sourceSpec;
|
|
176
176
|
this.spaceSpec = sourceSpec;
|
|
@@ -199,7 +199,7 @@ class SourceSpace {
|
|
|
199
199
|
*/
|
|
200
200
|
class DynamicSpace extends StaticSpace {
|
|
201
201
|
constructor(extending) {
|
|
202
|
-
const source = new
|
|
202
|
+
const source = new SpaceSeed(extending);
|
|
203
203
|
super((0, lodash_1.cloneDeep)(source.structDef));
|
|
204
204
|
this.completions = [];
|
|
205
205
|
this.complete = false;
|
|
@@ -365,15 +365,17 @@ class DynamicSpace extends StaticSpace {
|
|
|
365
365
|
}
|
|
366
366
|
exports.DynamicSpace = DynamicSpace;
|
|
367
367
|
/**
|
|
368
|
-
*
|
|
369
|
-
*
|
|
370
|
-
* which
|
|
371
|
-
* space is
|
|
368
|
+
* Unlike a source, which is a refinement of a namespace, a query
|
|
369
|
+
* is creating a new unrelated namespace. The query starts with a
|
|
370
|
+
* source, which it might modify. This set of fields used to resolve
|
|
371
|
+
* expressions in the query is called the "input space". There is a
|
|
372
|
+
* specialized QuerySpace for each type of query operation.
|
|
372
373
|
*
|
|
374
|
+
* The query output is managed by an instance of ResultSpace.
|
|
373
375
|
*/
|
|
374
376
|
class QuerySpace extends DynamicSpace {
|
|
375
377
|
constructor(input, result) {
|
|
376
|
-
const inputSpace = new
|
|
378
|
+
const inputSpace = new SpaceSeed(input);
|
|
377
379
|
super(inputSpace.structDef);
|
|
378
380
|
this.result = result;
|
|
379
381
|
this.extendList = [];
|