@malloydata/malloy 0.0.337 → 0.0.339
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/api/foundation/result.d.ts +4 -4
- package/dist/api/foundation/result.js +9 -9
- package/dist/api/foundation/writers.d.ts +1 -1
- package/dist/api/foundation/writers.js +9 -8
- package/dist/connection/registry.d.ts +1 -1
- package/dist/connection/types.d.ts +2 -2
- package/dist/dialect/dialect.d.ts +2 -1
- package/dist/dialect/dialect.js +3 -0
- package/dist/dialect/duckdb/duckdb.js +22 -1
- package/dist/dialect/mysql/mysql.d.ts +1 -0
- package/dist/dialect/mysql/mysql.js +1 -0
- package/dist/dialect/postgres/postgres.d.ts +1 -0
- package/dist/dialect/postgres/postgres.js +10 -0
- package/dist/dialect/standardsql/standardsql.js +21 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +4 -2
- package/dist/lang/ast/expressions/expr-cast.d.ts +3 -3
- package/dist/lang/ast/expressions/expr-cast.js +4 -2
- package/dist/lang/ast/expressions/expr-func.d.ts +3 -3
- package/dist/lang/ast/expressions/expr-func.js +7 -9
- package/dist/lang/ast/expressions/for-range.js +1 -1
- package/dist/lang/ast/source-elements/named-source.js +4 -2
- package/dist/lang/ast/time-utils.d.ts +2 -2
- package/dist/lang/ast/time-utils.js +4 -5
- package/dist/lang/lib/Malloy/MalloyParser.d.ts +88 -45
- package/dist/lang/lib/Malloy/MalloyParser.js +2193 -1862
- package/dist/lang/lib/Malloy/MalloyParserListener.d.ts +33 -0
- package/dist/lang/lib/Malloy/MalloyParserVisitor.d.ts +21 -0
- package/dist/lang/malloy-to-ast.d.ts +4 -4
- package/dist/lang/malloy-to-ast.js +38 -22
- package/dist/model/malloy_types.d.ts +11 -8
- package/dist/model/malloy_types.js +23 -15
- package/dist/model/utils.d.ts +4 -6
- package/dist/model/utils.js +10 -11
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +5 -6
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { QueryData,
|
|
1
|
+
import type { QueryData, QueryRecord, QueryResult, QueryRunStats, ModelDef } from '../../model';
|
|
2
2
|
import type { Explore, Field, AtomicField, StringField, NumberField, BooleanField, DateField, TimestampField, JSONField, UnsupportedField } from './core';
|
|
3
3
|
import { PreparedResult } from './core';
|
|
4
4
|
export type ResultJSON = {
|
|
@@ -163,17 +163,17 @@ export declare class DataRecord extends Data<{
|
|
|
163
163
|
protected _field: Explore;
|
|
164
164
|
readonly index: number | undefined;
|
|
165
165
|
private cellCache;
|
|
166
|
-
constructor(queryDataRow:
|
|
166
|
+
constructor(queryDataRow: QueryRecord, index: number | undefined, field: Explore, parent: DataArrayOrRecord | undefined, parentRecord: DataRecord | undefined);
|
|
167
167
|
/**
|
|
168
168
|
* @return Normalized data with JS native types (number | bigint, Date).
|
|
169
169
|
* Use this for CSV output, tests, and general programmatic access.
|
|
170
170
|
*/
|
|
171
|
-
toObject():
|
|
171
|
+
toObject(): QueryRecord;
|
|
172
172
|
/**
|
|
173
173
|
* @return Normalized data with JSON-safe types (numbers as number | string, dates as ISO strings).
|
|
174
174
|
* Use this for JSON serialization.
|
|
175
175
|
*/
|
|
176
|
-
toJSON():
|
|
176
|
+
toJSON(): QueryRecord;
|
|
177
177
|
path(...path: (number | string)[]): DataColumn;
|
|
178
178
|
cell(fieldOrName: string | Field): DataColumn;
|
|
179
179
|
get value(): {
|
|
@@ -406,12 +406,12 @@ const JSON_NORMALIZERS = {
|
|
|
406
406
|
* Walk a QueryData array and normalize values according to the given normalizers.
|
|
407
407
|
*/
|
|
408
408
|
function walkQueryData(data, structDef, normalizers) {
|
|
409
|
-
return data.map(row =>
|
|
409
|
+
return data.map(row => walkQueryRecord(row, structDef, normalizers));
|
|
410
410
|
}
|
|
411
411
|
/**
|
|
412
|
-
* Walk a
|
|
412
|
+
* Walk a QueryRecord and normalize values according to the given normalizers.
|
|
413
413
|
*/
|
|
414
|
-
function
|
|
414
|
+
function walkQueryRecord(row, structDef, normalizers) {
|
|
415
415
|
var _a;
|
|
416
416
|
const result = {};
|
|
417
417
|
for (const fieldDef of structDef.fields) {
|
|
@@ -458,7 +458,7 @@ function walkValue(value, fieldDef, normalizers) {
|
|
|
458
458
|
}
|
|
459
459
|
if ((0, model_1.isRepeatedRecord)(fieldDef)) {
|
|
460
460
|
// Array of records - recurse into each record
|
|
461
|
-
return value.map(item =>
|
|
461
|
+
return value.map(item => walkQueryRecord(item, fieldDef, normalizers));
|
|
462
462
|
}
|
|
463
463
|
else if ((0, model_1.isBasicArray)(fieldDef)) {
|
|
464
464
|
// Scalar array - normalize each element based on elementTypeDef
|
|
@@ -470,7 +470,7 @@ function walkValue(value, fieldDef, normalizers) {
|
|
|
470
470
|
// Handle records (non-array)
|
|
471
471
|
if (fieldDef.type === 'record') {
|
|
472
472
|
if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
|
|
473
|
-
return
|
|
473
|
+
return walkQueryRecord(value, fieldDef, normalizers);
|
|
474
474
|
}
|
|
475
475
|
}
|
|
476
476
|
// Fallback - pass through
|
|
@@ -505,7 +505,7 @@ function walkScalarValue(value, typeDef, normalizers) {
|
|
|
505
505
|
return value.map(item => walkScalarValue(item, elementType, normalizers));
|
|
506
506
|
}
|
|
507
507
|
else if ((0, model_1.isRepeatedRecord)(typeDef)) {
|
|
508
|
-
return value.map(item =>
|
|
508
|
+
return value.map(item => walkQueryRecord(item, typeDef, normalizers));
|
|
509
509
|
}
|
|
510
510
|
}
|
|
511
511
|
// Pass through other types
|
|
@@ -612,14 +612,14 @@ class DataRecord extends Data {
|
|
|
612
612
|
* Use this for CSV output, tests, and general programmatic access.
|
|
613
613
|
*/
|
|
614
614
|
toObject() {
|
|
615
|
-
return
|
|
615
|
+
return walkQueryRecord(this.queryDataRow, this._field.structDef, OBJECT_NORMALIZERS);
|
|
616
616
|
}
|
|
617
617
|
/**
|
|
618
618
|
* @return Normalized data with JSON-safe types (numbers as number | string, dates as ISO strings).
|
|
619
619
|
* Use this for JSON serialization.
|
|
620
620
|
*/
|
|
621
621
|
toJSON() {
|
|
622
|
-
return
|
|
622
|
+
return walkQueryRecord(this.queryDataRow, this._field.structDef, JSON_NORMALIZERS);
|
|
623
623
|
}
|
|
624
624
|
path(...path) {
|
|
625
625
|
return getPath(this, path);
|
|
@@ -657,7 +657,7 @@ class DataRecord extends Data {
|
|
|
657
657
|
}
|
|
658
658
|
}
|
|
659
659
|
else if (field.isExploreField()) {
|
|
660
|
-
if (
|
|
660
|
+
if ((0, model_1.isCompoundArrayData)(value)) {
|
|
661
661
|
column = new DataArray(value, field, this, this);
|
|
662
662
|
}
|
|
663
663
|
else {
|
|
@@ -15,7 +15,7 @@ export declare class JSONWriter extends DataWriter {
|
|
|
15
15
|
* CSV writer class that handles nested data.
|
|
16
16
|
* This writer creates CSV using a DFS traversal of the result dataset.
|
|
17
17
|
* Each trivial column value is converted to a CSV of 1x1 matrix and all the
|
|
18
|
-
* columns are merged together to create a CSV that represents 1
|
|
18
|
+
* columns are merged together to create a CSV that represents 1 QueryRecord.
|
|
19
19
|
* Since this follows DFS, each non trivial data is rendered into a NxM matrix
|
|
20
20
|
* where N is the number of rows in the nested data and M is the number of
|
|
21
21
|
* columns it has.
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
7
|
exports.CSVWriter = exports.JSONWriter = exports.DataWriter = void 0;
|
|
8
|
+
const model_1 = require("../../model");
|
|
8
9
|
// =============================================================================
|
|
9
10
|
// DataWriter Base Class
|
|
10
11
|
// =============================================================================
|
|
@@ -47,7 +48,7 @@ exports.JSONWriter = JSONWriter;
|
|
|
47
48
|
* CSV writer class that handles nested data.
|
|
48
49
|
* This writer creates CSV using a DFS traversal of the result dataset.
|
|
49
50
|
* Each trivial column value is converted to a CSV of 1x1 matrix and all the
|
|
50
|
-
* columns are merged together to create a CSV that represents 1
|
|
51
|
+
* columns are merged together to create a CSV that represents 1 QueryRecord.
|
|
51
52
|
* Since this follows DFS, each non trivial data is rendered into a NxM matrix
|
|
52
53
|
* where N is the number of rows in the nested data and M is the number of
|
|
53
54
|
* columns it has.
|
|
@@ -108,7 +109,7 @@ class CSVWriter extends DataWriter {
|
|
|
108
109
|
for (const key in firstVal) {
|
|
109
110
|
numKeys = numKeys + 1;
|
|
110
111
|
const val = firstVal[key];
|
|
111
|
-
if (
|
|
112
|
+
if ((0, model_1.isCompoundArrayData)(val)) {
|
|
112
113
|
const weight = this.getColWeight(val) - 1;
|
|
113
114
|
numKeys = numKeys + weight;
|
|
114
115
|
}
|
|
@@ -123,7 +124,7 @@ class CSVWriter extends DataWriter {
|
|
|
123
124
|
csv.push(this.escape(key));
|
|
124
125
|
const val = row[key];
|
|
125
126
|
width++;
|
|
126
|
-
if (
|
|
127
|
+
if ((0, model_1.isCompoundArrayData)(val)) {
|
|
127
128
|
const numKeys = this.getColWeight(val) - 1;
|
|
128
129
|
width = width + numKeys;
|
|
129
130
|
for (let i = 0; i < numKeys; i++) {
|
|
@@ -193,7 +194,11 @@ class CSVWriter extends DataWriter {
|
|
|
193
194
|
const matrices = [];
|
|
194
195
|
for (const key in row) {
|
|
195
196
|
const val = row[key];
|
|
196
|
-
if (
|
|
197
|
+
if ((0, model_1.isCompoundArrayData)(val)) {
|
|
198
|
+
const cell = this.getChildMatrix(val);
|
|
199
|
+
matrices.push(cell);
|
|
200
|
+
}
|
|
201
|
+
else {
|
|
197
202
|
const cell = {
|
|
198
203
|
rows: [this.stringify(val)],
|
|
199
204
|
length: 1,
|
|
@@ -201,10 +206,6 @@ class CSVWriter extends DataWriter {
|
|
|
201
206
|
};
|
|
202
207
|
matrices.push(cell);
|
|
203
208
|
}
|
|
204
|
-
else {
|
|
205
|
-
const cell = this.getChildMatrix(val);
|
|
206
|
-
matrices.push(cell);
|
|
207
|
-
}
|
|
208
209
|
}
|
|
209
210
|
return this.mergeMatrices(matrices);
|
|
210
211
|
}
|
|
@@ -6,7 +6,7 @@ export type ConnectionTypeFactory = (config: ConnectionConfig) => Connection;
|
|
|
6
6
|
/**
|
|
7
7
|
* The type of a connection property value.
|
|
8
8
|
*/
|
|
9
|
-
export type ConnectionPropertyType = 'string' | 'number' | 'boolean' | 'password' | 'file';
|
|
9
|
+
export type ConnectionPropertyType = 'string' | 'number' | 'boolean' | 'password' | 'file' | 'text';
|
|
10
10
|
/**
|
|
11
11
|
* Describes a single configuration property for a connection type.
|
|
12
12
|
*/
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { RunSQLOptions } from '../run_sql_options';
|
|
2
|
-
import type { Annotation, MalloyQueryData,
|
|
2
|
+
import type { Annotation, MalloyQueryData, QueryRecord, QueryRunStats, SQLSourceDef, TableSourceDef } from '../model/malloy_types';
|
|
3
3
|
import type { SQLSourceRequest } from '../lang/translate-response';
|
|
4
4
|
/**
|
|
5
5
|
* Options passed to fetchSchema methods.
|
|
@@ -90,7 +90,7 @@ export interface PersistSQLResults extends Connection {
|
|
|
90
90
|
manifestTemporaryTable(sqlCommand: string): Promise<string>;
|
|
91
91
|
}
|
|
92
92
|
export interface StreamingConnection extends Connection {
|
|
93
|
-
runSQLStream(sqlCommand: string, options?: RunSQLOptions): AsyncIterableIterator<
|
|
93
|
+
runSQLStream(sqlCommand: string, options?: RunSQLOptions): AsyncIterableIterator<QueryRecord>;
|
|
94
94
|
}
|
|
95
95
|
/**
|
|
96
96
|
* A mapping of connection names to connections.
|
|
@@ -74,6 +74,7 @@ export declare abstract class Dialect {
|
|
|
74
74
|
supportsBigIntPrecision: boolean;
|
|
75
75
|
supportsComplexFilteredSources: boolean;
|
|
76
76
|
supportsTempTables: boolean;
|
|
77
|
+
maxIdentifierLength: number;
|
|
77
78
|
hasModOperator: boolean;
|
|
78
79
|
supportsLeftJoinUnnest: boolean;
|
|
79
80
|
requiresExplicitUnnestOrdering: boolean;
|
|
@@ -368,7 +369,7 @@ export declare abstract class Dialect {
|
|
|
368
369
|
sqlCastPrep(cast: TypecastExpr): {
|
|
369
370
|
op: string;
|
|
370
371
|
srcTypeDef: BasicAtomicTypeDef | undefined;
|
|
371
|
-
dstTypeDef:
|
|
372
|
+
dstTypeDef: AtomicTypeDef | undefined;
|
|
372
373
|
dstSQLType: string;
|
|
373
374
|
};
|
|
374
375
|
/**
|
package/dist/dialect/dialect.js
CHANGED
|
@@ -95,6 +95,9 @@ class Dialect {
|
|
|
95
95
|
this.supportsComplexFilteredSources = true;
|
|
96
96
|
// can create temp tables
|
|
97
97
|
this.supportsTempTables = true;
|
|
98
|
+
// Maximum length of a table/view identifier. Used to truncate
|
|
99
|
+
// generated temp table names. 128 is a safe default for most databases.
|
|
100
|
+
this.maxIdentifierLength = 128;
|
|
98
101
|
this.hasModOperator = true;
|
|
99
102
|
// can LEFT JOIN UNNEST
|
|
100
103
|
this.supportsLeftJoinUnnest = true;
|
|
@@ -289,9 +289,30 @@ class DuckDBDialect extends pg_impl_1.PostgresBase {
|
|
|
289
289
|
else if (malloyType.type === 'string') {
|
|
290
290
|
return 'varchar';
|
|
291
291
|
}
|
|
292
|
-
if (malloyType.type === 'timestamptz') {
|
|
292
|
+
else if (malloyType.type === 'timestamptz') {
|
|
293
293
|
return 'timestamp with time zone';
|
|
294
294
|
}
|
|
295
|
+
else if (malloyType.type === 'record') {
|
|
296
|
+
const typeSpec = [];
|
|
297
|
+
for (const f of malloyType.fields) {
|
|
298
|
+
if ((0, malloy_types_1.isAtomic)(f)) {
|
|
299
|
+
typeSpec.push(`${this.sqlMaybeQuoteIdentifier(f.name)} ${this.malloyTypeToSQLType(f)}`);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
return `STRUCT(${typeSpec.join(', ')})`;
|
|
303
|
+
}
|
|
304
|
+
else if (malloyType.type === 'array') {
|
|
305
|
+
if ((0, malloy_types_1.isRepeatedRecord)(malloyType)) {
|
|
306
|
+
const typeSpec = [];
|
|
307
|
+
for (const f of malloyType.fields) {
|
|
308
|
+
if ((0, malloy_types_1.isAtomic)(f)) {
|
|
309
|
+
typeSpec.push(`${this.sqlMaybeQuoteIdentifier(f.name)} ${this.malloyTypeToSQLType(f)}`);
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
return `STRUCT(${typeSpec.join(', ')})[]`;
|
|
313
|
+
}
|
|
314
|
+
return `${this.malloyTypeToSQLType(malloyType.elementTypeDef)}[]`;
|
|
315
|
+
}
|
|
295
316
|
return malloyType.type;
|
|
296
317
|
}
|
|
297
318
|
parseDuckDBType(sqlType) {
|
|
@@ -31,6 +31,7 @@ export declare class MySQLDialect extends Dialect {
|
|
|
31
31
|
compoundObjectInSchema: boolean;
|
|
32
32
|
booleanType: BooleanTypeSupport;
|
|
33
33
|
orderByClause: OrderByClauseType;
|
|
34
|
+
maxIdentifierLength: number;
|
|
34
35
|
malloyTypeToSQLType(malloyType: AtomicTypeDef): string;
|
|
35
36
|
sqlTypeToMalloyType(sqlType: string): BasicAtomicTypeDef;
|
|
36
37
|
quoteTablePath(tablePath: string): string;
|
|
@@ -120,6 +120,7 @@ class MySQLDialect extends dialect_1.Dialect {
|
|
|
120
120
|
this.compoundObjectInSchema = false;
|
|
121
121
|
this.booleanType = 'simulated';
|
|
122
122
|
this.orderByClause = 'ordinal';
|
|
123
|
+
this.maxIdentifierLength = 64;
|
|
123
124
|
}
|
|
124
125
|
malloyTypeToSQLType(malloyType) {
|
|
125
126
|
switch (malloyType.type) {
|
|
@@ -26,6 +26,7 @@ export declare class PostgresDialect extends PostgresBase {
|
|
|
26
26
|
supportsComplexFilteredSources: boolean;
|
|
27
27
|
compoundObjectInSchema: boolean;
|
|
28
28
|
likeEscape: boolean;
|
|
29
|
+
maxIdentifierLength: number;
|
|
29
30
|
quoteTablePath(tablePath: string): string;
|
|
30
31
|
sqlGroupSetTable(groupSetCount: number): string;
|
|
31
32
|
sqlAnyValue(groupSet: number, fieldName: string): string;
|
|
@@ -97,6 +97,7 @@ class PostgresDialect extends pg_impl_1.PostgresBase {
|
|
|
97
97
|
this.supportsComplexFilteredSources = false;
|
|
98
98
|
this.compoundObjectInSchema = false;
|
|
99
99
|
this.likeEscape = false;
|
|
100
|
+
this.maxIdentifierLength = 63;
|
|
100
101
|
}
|
|
101
102
|
quoteTablePath(tablePath) {
|
|
102
103
|
return tablePath
|
|
@@ -331,6 +332,15 @@ class PostgresDialect extends pg_impl_1.PostgresBase {
|
|
|
331
332
|
else if (malloyType.type === 'string') {
|
|
332
333
|
return 'varchar';
|
|
333
334
|
}
|
|
335
|
+
else if (malloyType.type === 'record') {
|
|
336
|
+
throw new Error('PostgreSQL does not support CAST to record type');
|
|
337
|
+
}
|
|
338
|
+
else if (malloyType.type === 'array') {
|
|
339
|
+
if ((0, malloy_types_1.isRepeatedRecord)(malloyType)) {
|
|
340
|
+
throw new Error('PostgreSQL does not support CAST to array of records');
|
|
341
|
+
}
|
|
342
|
+
return `${this.malloyTypeToSQLType(malloyType.elementTypeDef)}[]`;
|
|
343
|
+
}
|
|
334
344
|
return malloyType.type;
|
|
335
345
|
}
|
|
336
346
|
sqlTypeToMalloyType(rawSqlType) {
|
|
@@ -377,6 +377,27 @@ ${(0, utils_1.indent)(sql)}
|
|
|
377
377
|
return 'FLOAT64';
|
|
378
378
|
}
|
|
379
379
|
}
|
|
380
|
+
else if (malloyType.type === 'record') {
|
|
381
|
+
const typeSpec = [];
|
|
382
|
+
for (const f of malloyType.fields) {
|
|
383
|
+
if ((0, malloy_types_1.isAtomic)(f)) {
|
|
384
|
+
typeSpec.push(`${f.name} ${this.malloyTypeToSQLType(f)}`);
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
return `STRUCT<${typeSpec.join(', ')}>`;
|
|
388
|
+
}
|
|
389
|
+
else if (malloyType.type === 'array') {
|
|
390
|
+
if ((0, malloy_types_1.isRepeatedRecord)(malloyType)) {
|
|
391
|
+
const typeSpec = [];
|
|
392
|
+
for (const f of malloyType.fields) {
|
|
393
|
+
if ((0, malloy_types_1.isAtomic)(f)) {
|
|
394
|
+
typeSpec.push(`${f.name} ${this.malloyTypeToSQLType(f)}`);
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
return `ARRAY<STRUCT<${typeSpec.join(', ')}>>`;
|
|
398
|
+
}
|
|
399
|
+
return `ARRAY<${this.malloyTypeToSQLType(malloyType.elementTypeDef)}>`;
|
|
400
|
+
}
|
|
380
401
|
return malloyType.type;
|
|
381
402
|
}
|
|
382
403
|
sqlTypeToMalloyType(sqlType) {
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export { DuckDBDialect, StandardSQLDialect, TrinoDialect, PostgresDialect, SnowflakeDialect, MySQLDialect, registerDialect, arg, qtz, overload, minScalar, anyExprType, minAggregate, maxScalar, sql, makeParam, param, variadicParam, literal, spread, Dialect, TinyParser, } from './dialect';
|
|
2
2
|
export type { DialectFieldList, DialectFunctionOverloadDef, QueryInfo, MalloyStandardFunctionImplementations, DefinitionBlueprint, DefinitionBlueprintMap, OverloadedDefinitionBlueprint, TinyToken, } from './dialect';
|
|
3
|
-
export type {
|
|
4
|
-
export { isSourceDef, isBasicAtomic, isJoined, isJoinedSource, isSamplingEnable, isSamplingPercent, isSamplingRows, isRepeatedRecord, isBasicArray, mkArrayDef, mkFieldDef, expressionIsAggregate, expressionIsAnalytic, expressionIsCalculation, expressionIsScalar, expressionIsUngroupedAggregate, indent, composeSQLExpr, isTimestampUnit, isDateUnit, constantExprToSQL, } from './model';
|
|
3
|
+
export type { QueryRecord, StructDef, TableSourceDef, SQLSourceDef, SourceDef, JoinFieldDef, NamedSourceDefs, MalloyQueryData, DateUnit, ExtractUnit, TimestampUnit, TemporalFieldType, QueryData, QueryValue, Expr, FilterCondition, Argument, Parameter, FieldDef, PipeSegment, QueryFieldDef, IndexFieldDef, TurtleDef, SearchValueMapResult, SearchIndexResult, ModelDef, Query, QueryResult, QueryResultDef, QueryRunStats, QueryScalar, NamedQueryDef, NamedModelObject, ExpressionType, FunctionDef, FunctionOverloadDef, FunctionParameterDef, ExpressionValueType, TypeDesc, FunctionParamTypeDesc, DocumentLocation, DocumentRange, DocumentPosition, Sampling, Annotation, BasicAtomicTypeDef, BasicAtomicDef, AtomicTypeDef, AtomicFieldDef, ArrayDef, ArrayTypeDef, RecordTypeDef, RepeatedRecordTypeDef, RecordDef, RepeatedRecordDef, RecordLiteralNode, StringLiteralNode, ArrayLiteralNode, SourceComponentInfo, DateLiteralNode, TimestampLiteralNode, TimestamptzLiteralNode, TimeLiteralExpr, TypecastExpr, BuildManifest, BuildManifestEntry, } from './model';
|
|
4
|
+
export { isSourceDef, isAtomic, isBasicAtomic, isCompoundArrayData, isJoined, isJoinedSource, isSamplingEnable, isSamplingPercent, isSamplingRows, isRepeatedRecord, isBasicArray, mkArrayDef, mkFieldDef, expressionIsAggregate, expressionIsAnalytic, expressionIsCalculation, expressionIsScalar, expressionIsUngroupedAggregate, indent, composeSQLExpr, isTimestampUnit, isDateUnit, constantExprToSQL, } from './model';
|
|
5
5
|
export { malloyToQuery, MalloyTranslator, } from './lang';
|
|
6
6
|
export type { LogMessage, TranslateResponse } from './lang';
|
|
7
7
|
export { Model, Malloy, Runtime, AtomicFieldType, ConnectionRuntime, SingleConnectionRuntime, EmptyURLReader, InMemoryURLReader, FixedConnectionMap, MalloyError, JoinRelationship, SourceRelationship, DateTimeframe, TimestampTimeframe, PreparedResult, Result, QueryMaterializer, CSVWriter, JSONWriter, Parse, DataWriter, Explore, InMemoryModelCache, CacheManager, } from './api/foundation';
|
package/dist/index.js
CHANGED
|
@@ -33,8 +33,8 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.
|
|
37
|
-
exports.makeDigest = exports.PersistSource = exports.annotationToTaglines = exports.annotationToTag = exports.sqlKey = exports.API = exports.extractMalloyObjectFromTag = exports.writeMalloyObjectToTag = exports.sourceDefToSourceInfo = exports.modelDefToModelInfo = exports.toAsyncGenerator = exports.createConnectionsFromConfig = exports.writeConnectionsConfig = exports.readConnectionsConfig = exports.getRegisteredConnectionTypes = exports.getConnectionProperties = exports.registerConnectionType = exports.CacheManager = exports.InMemoryModelCache = exports.Explore = exports.DataWriter = exports.Parse = exports.JSONWriter = exports.CSVWriter = exports.QueryMaterializer = exports.Result = exports.PreparedResult = exports.TimestampTimeframe = exports.DateTimeframe = exports.SourceRelationship = exports.JoinRelationship = exports.MalloyError = exports.FixedConnectionMap = exports.InMemoryURLReader = exports.EmptyURLReader = exports.SingleConnectionRuntime = void 0;
|
|
36
|
+
exports.Runtime = exports.Malloy = exports.Model = exports.MalloyTranslator = exports.malloyToQuery = exports.constantExprToSQL = exports.isDateUnit = exports.isTimestampUnit = exports.composeSQLExpr = exports.indent = exports.expressionIsUngroupedAggregate = exports.expressionIsScalar = exports.expressionIsCalculation = exports.expressionIsAnalytic = exports.expressionIsAggregate = exports.mkFieldDef = exports.mkArrayDef = exports.isBasicArray = exports.isRepeatedRecord = exports.isSamplingRows = exports.isSamplingPercent = exports.isSamplingEnable = exports.isJoinedSource = exports.isJoined = exports.isCompoundArrayData = exports.isBasicAtomic = exports.isAtomic = exports.isSourceDef = exports.TinyParser = exports.Dialect = exports.spread = exports.literal = exports.variadicParam = exports.param = exports.makeParam = exports.sql = exports.maxScalar = exports.minAggregate = exports.anyExprType = exports.minScalar = exports.overload = exports.qtz = exports.arg = exports.registerDialect = exports.MySQLDialect = exports.SnowflakeDialect = exports.PostgresDialect = exports.TrinoDialect = exports.StandardSQLDialect = exports.DuckDBDialect = void 0;
|
|
37
|
+
exports.makeDigest = exports.PersistSource = exports.annotationToTaglines = exports.annotationToTag = exports.sqlKey = exports.API = exports.extractMalloyObjectFromTag = exports.writeMalloyObjectToTag = exports.sourceDefToSourceInfo = exports.modelDefToModelInfo = exports.toAsyncGenerator = exports.createConnectionsFromConfig = exports.writeConnectionsConfig = exports.readConnectionsConfig = exports.getRegisteredConnectionTypes = exports.getConnectionProperties = exports.registerConnectionType = exports.CacheManager = exports.InMemoryModelCache = exports.Explore = exports.DataWriter = exports.Parse = exports.JSONWriter = exports.CSVWriter = exports.QueryMaterializer = exports.Result = exports.PreparedResult = exports.TimestampTimeframe = exports.DateTimeframe = exports.SourceRelationship = exports.JoinRelationship = exports.MalloyError = exports.FixedConnectionMap = exports.InMemoryURLReader = exports.EmptyURLReader = exports.SingleConnectionRuntime = exports.ConnectionRuntime = exports.AtomicFieldType = void 0;
|
|
38
38
|
/*
|
|
39
39
|
* Copyright 2023 Google LLC
|
|
40
40
|
*
|
|
@@ -83,7 +83,9 @@ Object.defineProperty(exports, "TinyParser", { enumerable: true, get: function (
|
|
|
83
83
|
var model_1 = require("./model");
|
|
84
84
|
Object.defineProperty(exports, "isSourceDef", { enumerable: true, get: function () { return model_1.isSourceDef; } });
|
|
85
85
|
// Used in Composer Demo
|
|
86
|
+
Object.defineProperty(exports, "isAtomic", { enumerable: true, get: function () { return model_1.isAtomic; } });
|
|
86
87
|
Object.defineProperty(exports, "isBasicAtomic", { enumerable: true, get: function () { return model_1.isBasicAtomic; } });
|
|
88
|
+
Object.defineProperty(exports, "isCompoundArrayData", { enumerable: true, get: function () { return model_1.isCompoundArrayData; } });
|
|
87
89
|
Object.defineProperty(exports, "isJoined", { enumerable: true, get: function () { return model_1.isJoined; } });
|
|
88
90
|
Object.defineProperty(exports, "isJoinedSource", { enumerable: true, get: function () { return model_1.isJoinedSource; } });
|
|
89
91
|
Object.defineProperty(exports, "isSamplingEnable", { enumerable: true, get: function () { return model_1.isSamplingEnable; } });
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { AtomicTypeDef } from '../../../model/malloy_types';
|
|
2
2
|
import type { ExprValue } from '../types/expr-value';
|
|
3
3
|
import { ExpressionDef } from '../types/expression-def';
|
|
4
4
|
import type { FieldSpace } from '../types/field-space';
|
|
5
5
|
export declare class ExprCast extends ExpressionDef {
|
|
6
6
|
readonly expr: ExpressionDef;
|
|
7
|
-
readonly castType:
|
|
7
|
+
readonly castType: AtomicTypeDef | {
|
|
8
8
|
raw: string;
|
|
9
9
|
};
|
|
10
10
|
readonly safe: boolean;
|
|
11
11
|
elementType: string;
|
|
12
|
-
constructor(expr: ExpressionDef, castType:
|
|
12
|
+
constructor(expr: ExpressionDef, castType: AtomicTypeDef | {
|
|
13
13
|
raw: string;
|
|
14
14
|
}, safe?: boolean);
|
|
15
15
|
getExpression(fs: FieldSpace): ExprValue;
|
|
@@ -34,11 +34,13 @@ class ExprCast extends expression_def_1.ExpressionDef {
|
|
|
34
34
|
this.safe = safe;
|
|
35
35
|
this.elementType = 'cast';
|
|
36
36
|
}
|
|
37
|
+
// TODO: Validate senseless casts (e.g. scalar to record) at translate time
|
|
38
|
+
// for better error messages than what the dialect/database produces.
|
|
37
39
|
getExpression(fs) {
|
|
38
40
|
const expr = this.expr.getExpression(fs);
|
|
39
41
|
let dataType = { type: 'error' };
|
|
40
|
-
if (
|
|
41
|
-
dataType =
|
|
42
|
+
if ('type' in this.castType) {
|
|
43
|
+
dataType = this.castType;
|
|
42
44
|
}
|
|
43
45
|
else {
|
|
44
46
|
const dialect = fs.dialectObj();
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { AtomicTypeDef } from '../../../model/malloy_types';
|
|
2
2
|
import type { FieldReference } from '../query-items/field-references';
|
|
3
3
|
import type { FunctionOrdering } from './function-ordering';
|
|
4
4
|
import type { Limit } from '../query-properties/limit';
|
|
@@ -10,10 +10,10 @@ export declare class ExprFunc extends ExpressionDef {
|
|
|
10
10
|
readonly name: string;
|
|
11
11
|
readonly args: ExpressionDef[];
|
|
12
12
|
readonly isRaw: boolean;
|
|
13
|
-
readonly
|
|
13
|
+
readonly explicitType: AtomicTypeDef | undefined;
|
|
14
14
|
readonly source?: FieldReference | undefined;
|
|
15
15
|
elementType: string;
|
|
16
|
-
constructor(name: string, args: ExpressionDef[], isRaw: boolean,
|
|
16
|
+
constructor(name: string, args: ExpressionDef[], isRaw: boolean, explicitType: AtomicTypeDef | undefined, source?: FieldReference | undefined);
|
|
17
17
|
canSupportPartitionBy(): boolean;
|
|
18
18
|
canSupportOrderBy(): boolean;
|
|
19
19
|
canSupportLimit(): boolean;
|
|
@@ -66,12 +66,12 @@ const utils_1 = require("../../../model/utils");
|
|
|
66
66
|
const TDU = __importStar(require("../typedesc-utils"));
|
|
67
67
|
const composite_source_utils_1 = require("../../composite-source-utils");
|
|
68
68
|
class ExprFunc extends expression_def_1.ExpressionDef {
|
|
69
|
-
constructor(name, args, isRaw,
|
|
69
|
+
constructor(name, args, isRaw, explicitType, source) {
|
|
70
70
|
super({ args: args });
|
|
71
71
|
this.name = name;
|
|
72
72
|
this.args = args;
|
|
73
73
|
this.isRaw = isRaw;
|
|
74
|
-
this.
|
|
74
|
+
this.explicitType = explicitType;
|
|
75
75
|
this.source = source;
|
|
76
76
|
this.elementType = 'function call()';
|
|
77
77
|
this.has({ source: source });
|
|
@@ -111,7 +111,7 @@ class ExprFunc extends expression_def_1.ExpressionDef {
|
|
|
111
111
|
return { found: func, error: undefined };
|
|
112
112
|
}
|
|
113
113
|
getPropsExpression(fs, props) {
|
|
114
|
-
var _a, _b, _c, _d;
|
|
114
|
+
var _a, _b, _c, _d, _e;
|
|
115
115
|
const argExprsWithoutImplicit = this.args.map(arg => arg.getExpression(fs));
|
|
116
116
|
if (this.isRaw) {
|
|
117
117
|
const funcCall = [`${this.name}(`];
|
|
@@ -123,16 +123,14 @@ class ExprFunc extends expression_def_1.ExpressionDef {
|
|
|
123
123
|
});
|
|
124
124
|
funcCall.push(')');
|
|
125
125
|
const inferredType = (_a = argExprsWithoutImplicit[0]) !== null && _a !== void 0 ? _a : { type: 'number' };
|
|
126
|
-
const dataType = this.
|
|
127
|
-
? { type: this.rawType }
|
|
128
|
-
: inferredType;
|
|
126
|
+
const dataType = (_b = this.explicitType) !== null && _b !== void 0 ? _b : inferredType;
|
|
129
127
|
return (0, expr_value_1.computedExprValue)({
|
|
130
128
|
dataType,
|
|
131
129
|
value: (0, utils_1.composeSQLExpr)(funcCall),
|
|
132
130
|
from: argExprsWithoutImplicit,
|
|
133
131
|
});
|
|
134
132
|
}
|
|
135
|
-
const dialect = (
|
|
133
|
+
const dialect = (_c = fs.dialectObj()) === null || _c === void 0 ? void 0 : _c.name;
|
|
136
134
|
const { found: func, error } = this.findFunctionDef(dialect);
|
|
137
135
|
if (func === undefined) {
|
|
138
136
|
return (0, ast_utils_1.errorFor)(error);
|
|
@@ -140,7 +138,7 @@ class ExprFunc extends expression_def_1.ExpressionDef {
|
|
|
140
138
|
// Find the 'implicit argument' for aggregate functions called like `some_join.some_field.agg(...args)`
|
|
141
139
|
// where the full arg list is `(some_field, ...args)`.
|
|
142
140
|
let implicitExpr = undefined;
|
|
143
|
-
let structPath = (
|
|
141
|
+
let structPath = (_d = this.source) === null || _d === void 0 ? void 0 : _d.path;
|
|
144
142
|
if (this.source) {
|
|
145
143
|
const lookup = this.source.getField(fs);
|
|
146
144
|
const sourceFoot = lookup.found;
|
|
@@ -214,7 +212,7 @@ class ExprFunc extends expression_def_1.ExpressionDef {
|
|
|
214
212
|
}
|
|
215
213
|
const type = overload.returnType;
|
|
216
214
|
const expressionType = (0, malloy_types_1.maxOfExpressionTypes)([
|
|
217
|
-
(
|
|
215
|
+
(_e = type.expressionType) !== null && _e !== void 0 ? _e : 'scalar',
|
|
218
216
|
...argExprs.map(e => e.expressionType),
|
|
219
217
|
]);
|
|
220
218
|
if (!(0, malloy_types_1.expressionIsAggregate)(overload.returnType.expressionType) &&
|
|
@@ -117,7 +117,7 @@ class ForRange extends expression_def_1.ExpressionDef {
|
|
|
117
117
|
from = tsVersion;
|
|
118
118
|
}
|
|
119
119
|
else {
|
|
120
|
-
from = (0, time_utils_1.castTo)('timestamp', from, 'date');
|
|
120
|
+
from = (0, time_utils_1.castTo)({ type: 'timestamp' }, from, 'date');
|
|
121
121
|
}
|
|
122
122
|
rangeStart = new expr_time_1.ExprTime('timestamp', from, [startV]);
|
|
123
123
|
}
|
|
@@ -154,8 +154,10 @@ class NamedSource extends source_1.Source {
|
|
|
154
154
|
(0, expression_def_1.checkFilterExpression)(argument.value, parameter.filterType, value);
|
|
155
155
|
}
|
|
156
156
|
}
|
|
157
|
-
|
|
158
|
-
|
|
157
|
+
// NOTE: isBasicAtomicType guard here excludes compound types from auto-casting.
|
|
158
|
+
// Revisit if parameters can ever have compound types.
|
|
159
|
+
if (pVal.type !== parameter.type && (0, malloy_types_1.isBasicAtomicType)(parameter.type)) {
|
|
160
|
+
value = (0, time_utils_1.castTo)({ type: parameter.type }, pVal.value, pVal.type, true);
|
|
159
161
|
}
|
|
160
162
|
outArguments[name] = {
|
|
161
163
|
...parameter,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type { Expr, TemporalFieldType, TimestampUnit,
|
|
1
|
+
import type { AtomicTypeDef, Expr, TemporalFieldType, TimestampUnit, TypecastExpr, TimeDeltaExpr, ExpressionValueType } from '../../model/malloy_types';
|
|
2
2
|
import type { TimeResult } from './types/time-result';
|
|
3
3
|
export declare function timeOffset(timeType: TemporalFieldType, from: Expr, op: '+' | '-', n: Expr, timeframe: TimestampUnit): TimeDeltaExpr;
|
|
4
|
-
export declare function castTo(castType:
|
|
4
|
+
export declare function castTo(castType: AtomicTypeDef | {
|
|
5
5
|
raw: string;
|
|
6
6
|
}, from: Expr, fromType: ExpressionValueType, safe?: boolean): TypecastExpr;
|
|
7
7
|
export declare function resolution(timeframe: string): TemporalFieldType;
|
|
@@ -40,24 +40,23 @@ function timeOffset(timeType, from, op, n, timeframe) {
|
|
|
40
40
|
}
|
|
41
41
|
function castTo(castType, from, fromType, safe = false) {
|
|
42
42
|
let cast;
|
|
43
|
-
if (
|
|
43
|
+
if ('type' in castType) {
|
|
44
44
|
cast = {
|
|
45
45
|
node: 'cast',
|
|
46
|
-
|
|
46
|
+
dstType: castType,
|
|
47
47
|
e: from,
|
|
48
48
|
safe,
|
|
49
49
|
};
|
|
50
50
|
}
|
|
51
51
|
else {
|
|
52
|
-
const dstType = { type: castType };
|
|
53
52
|
cast = {
|
|
54
53
|
node: 'cast',
|
|
55
|
-
|
|
54
|
+
dstSQLType: castType.raw,
|
|
56
55
|
e: from,
|
|
57
56
|
safe,
|
|
58
57
|
};
|
|
59
58
|
}
|
|
60
|
-
if ((0, malloy_types_1.
|
|
59
|
+
if ((0, malloy_types_1.isBasicAtomicType)(fromType)) {
|
|
61
60
|
cast.srcType = { type: fromType };
|
|
62
61
|
}
|
|
63
62
|
return cast;
|