@malloydata/malloy 0.0.253-dev250330190957 → 0.0.253-dev250401001016

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.
@@ -1,18 +1,11 @@
1
- import type { Expr, Sampling, AtomicTypeDef, MeasureTimeExpr, TimeTruncExpr, TimeExtractExpr, TimeDeltaExpr, TypecastExpr, RegexMatchExpr, TimeLiteralNode, RecordLiteralNode, ArrayLiteralNode, LeafAtomicTypeDef, OrderBy } from '../model/malloy_types';
1
+ import type { Expr, Sampling, AtomicTypeDef, MeasureTimeExpr, TimeTruncExpr, TimeExtractExpr, TimeDeltaExpr, TypecastExpr, RegexMatchExpr, TimeLiteralNode, RecordLiteralNode, ArrayLiteralNode, BasicAtomicTypeDef, OrderBy } from '../model/malloy_types';
2
2
  import type { DialectFunctionOverloadDef } from './functions';
3
- type DialectFieldTypes = string | 'struct';
4
3
  interface DialectField {
5
- type: DialectFieldTypes;
4
+ typeDef: AtomicTypeDef;
6
5
  sqlExpression: string;
7
6
  rawName: string;
8
7
  sqlOutputName: string;
9
8
  }
10
- export interface DialectFieldTypeStruct extends DialectField {
11
- type: 'struct';
12
- nestedStruct: DialectFieldList;
13
- isArray: boolean;
14
- }
15
- export declare function isDialectFieldStruct(d: DialectField): d is DialectFieldTypeStruct;
16
9
  export type DialectFieldList = DialectField[];
17
10
  /**
18
11
  * Data which dialect methods need in order to correctly generate SQL.
@@ -131,7 +124,7 @@ export declare abstract class Dialect {
131
124
  sqlTzStr(qi: QueryInfo): string;
132
125
  sqlMakeUnnestKey(key: string, rowKey: string): string;
133
126
  sqlStringAggDistinct(distinctKey: string, valueSQL: string, separatorSQL: string): string;
134
- abstract sqlTypeToMalloyType(sqlType: string): LeafAtomicTypeDef;
127
+ abstract sqlTypeToMalloyType(sqlType: string): BasicAtomicTypeDef;
135
128
  abstract malloyTypeToSQLType(malloyType: AtomicTypeDef): string;
136
129
  abstract validateTypeName(sqlType: string): boolean;
137
130
  /**
@@ -141,8 +134,8 @@ export declare abstract class Dialect {
141
134
  */
142
135
  sqlCastPrep(cast: TypecastExpr): {
143
136
  op: string;
144
- srcTypeDef: LeafAtomicTypeDef | undefined;
145
- dstTypeDef: LeafAtomicTypeDef | undefined;
137
+ srcTypeDef: BasicAtomicTypeDef | undefined;
138
+ dstTypeDef: BasicAtomicTypeDef | undefined;
146
139
  dstSQLType: string;
147
140
  };
148
141
  /**
@@ -22,12 +22,8 @@
22
22
  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
23
  */
24
24
  Object.defineProperty(exports, "__esModule", { value: true });
25
- exports.Dialect = exports.qtz = exports.inDays = exports.dayIndex = exports.isDialectFieldStruct = void 0;
25
+ exports.Dialect = exports.qtz = exports.inDays = exports.dayIndex = void 0;
26
26
  const malloy_types_1 = require("../model/malloy_types");
27
- function isDialectFieldStruct(d) {
28
- return d.type === 'struct';
29
- }
30
- exports.isDialectFieldStruct = isDialectFieldStruct;
31
27
  const allUnits = [
32
28
  'microsecond',
33
29
  'millisecond',
@@ -212,7 +208,7 @@ class Dialect {
212
208
  sqlCastPrep(cast) {
213
209
  let srcTypeDef = cast.srcType || cast.e.typeDef;
214
210
  const src = (srcTypeDef === null || srcTypeDef === void 0 ? void 0 : srcTypeDef.type) || 'unknown';
215
- if (srcTypeDef && !(0, malloy_types_1.isLeafAtomic)(srcTypeDef)) {
211
+ if (srcTypeDef && !(0, malloy_types_1.isBasicAtomic)(srcTypeDef)) {
216
212
  srcTypeDef = undefined;
217
213
  }
218
214
  if ((0, malloy_types_1.isRawCast)(cast)) {
@@ -1,4 +1,4 @@
1
- import type { Sampling, AtomicTypeDef, TimeDeltaExpr, RegexMatchExpr, MeasureTimeExpr, LeafAtomicTypeDef, RecordLiteralNode, OrderBy } from '../../model/malloy_types';
1
+ import type { Sampling, AtomicTypeDef, TimeDeltaExpr, RegexMatchExpr, MeasureTimeExpr, BasicAtomicTypeDef, RecordLiteralNode, OrderBy } from '../../model/malloy_types';
2
2
  import type { DialectFunctionOverloadDef } from '../functions';
3
3
  import type { DialectFieldList, FieldReferenceType } from '../dialect';
4
4
  import { PostgresBase } from '../pg_impl';
@@ -56,7 +56,7 @@ export declare class DuckDBDialect extends PostgresBase {
56
56
  };
57
57
  malloyTypeToSQLType(malloyType: AtomicTypeDef): string;
58
58
  parseDuckDBType(sqlType: string): AtomicTypeDef;
59
- sqlTypeToMalloyType(sqlType: string): LeafAtomicTypeDef;
59
+ sqlTypeToMalloyType(sqlType: string): BasicAtomicTypeDef;
60
60
  castToString(expression: string): string;
61
61
  concat(...values: string[]): string;
62
62
  validateTypeName(sqlType: string): boolean;
@@ -108,9 +108,9 @@ class DuckDBDialect extends pg_impl_1.PostgresBase {
108
108
  }
109
109
  sqlAnyValueTurtle(groupSet, fieldList) {
110
110
  const fields = fieldList
111
- .map(f => `${f.sqlExpression} as ${f.sqlOutputName}`)
111
+ .map(f => `${f.sqlOutputName}:=${f.sqlExpression}`)
112
112
  .join(', ');
113
- return `ANY_VALUE(CASE WHEN group_set=${groupSet} THEN STRUCT_PACK(${fields}))`;
113
+ return `ANY_VALUE(CASE WHEN group_set=${groupSet} THEN STRUCT_PACK(${fields}) END)`;
114
114
  }
115
115
  sqlAnyValueLastTurtle(name, groupSet, sqlName) {
116
116
  return `MAX(CASE WHEN group_set=${groupSet} THEN ${name} END) as ${sqlName}`;
@@ -1,4 +1,4 @@
1
- import type { FunctionParameterDef, TypeDesc, Expr, FunctionParamTypeDesc, LeafExpressionType, FunctionReturnTypeDesc, FunctionParameterTypeDef, ExpressionType, EvalSpace, FunctionGenericTypeDef } from '../../model/malloy_types';
1
+ import type { FunctionParameterDef, TypeDesc, Expr, FunctionParamTypeDesc, BasicExpressionType, FunctionReturnTypeDesc, FunctionParameterTypeDef, ExpressionType, EvalSpace, FunctionGenericTypeDef } from '../../model/malloy_types';
2
2
  import type { SQLExprElement } from '../../model/utils';
3
3
  export interface DialectFunctionOverloadDef {
4
4
  returnType: FunctionReturnTypeDesc;
@@ -72,7 +72,7 @@ export interface RecordBlueprint {
72
72
  export interface SQLNativeTypeBlueprint {
73
73
  sql_native: string;
74
74
  }
75
- export type LeafPlusType = LeafExpressionType | 'any';
75
+ export type LeafPlusType = BasicExpressionType | 'any';
76
76
  export type TypeDescElementBlueprint = LeafPlusType | ArrayBlueprint | RecordBlueprint | SQLNativeTypeBlueprint;
77
77
  export type NamedGeneric = {
78
78
  generic: string;
@@ -1,4 +1,4 @@
1
- import type { Sampling, MeasureTimeExpr, TimeLiteralNode, RegexMatchExpr, TimeDeltaExpr, TimeTruncExpr, TimeExtractExpr, TypecastExpr, LeafAtomicTypeDef, AtomicTypeDef, ArrayLiteralNode, RecordLiteralNode } from '../../model/malloy_types';
1
+ import type { Sampling, MeasureTimeExpr, TimeLiteralNode, RegexMatchExpr, TimeDeltaExpr, TimeTruncExpr, TimeExtractExpr, TypecastExpr, BasicAtomicTypeDef, AtomicTypeDef, ArrayLiteralNode, RecordLiteralNode } from '../../model/malloy_types';
2
2
  import type { DialectFieldList, FieldReferenceType, OrderByClauseType, QueryInfo } from '../dialect';
3
3
  import { Dialect } from '../dialect';
4
4
  import type { DialectFunctionOverloadDef } from '../functions';
@@ -32,7 +32,7 @@ export declare class MySQLDialect extends Dialect {
32
32
  booleanAsNumbers: boolean;
33
33
  orderByClause: OrderByClauseType;
34
34
  malloyTypeToSQLType(malloyType: AtomicTypeDef): string;
35
- sqlTypeToMalloyType(sqlType: string): LeafAtomicTypeDef;
35
+ sqlTypeToMalloyType(sqlType: string): BasicAtomicTypeDef;
36
36
  quoteTablePath(tablePath: string): string;
37
37
  sqlGroupSetTable(groupSetCount: number): string;
38
38
  sqlAnyValue(_groupSet: number, fieldName: string): string;
@@ -101,7 +101,10 @@ class MySQLDialect extends dialect_1.Dialect {
101
101
  case 'number':
102
102
  return malloyType.numberType === 'integer' ? 'BIGINT' : 'DOUBLE';
103
103
  case 'string':
104
- return 'CHAR';
104
+ return 'TEXT';
105
+ case 'record':
106
+ case 'array':
107
+ return 'JSON';
105
108
  case 'date':
106
109
  case 'timestamp':
107
110
  default:
@@ -175,9 +178,16 @@ class MySQLDialect extends dialect_1.Dialect {
175
178
  return t;
176
179
  }
177
180
  unnestColumns(fieldList) {
181
+ var _a;
178
182
  const fields = [];
179
183
  for (const f of fieldList) {
180
- fields.push(`${this.sqlMaybeQuoteIdentifier(f.sqlOutputName)} ${this.malloyToSQL(f.type)} PATH "$.${f.rawName}"`);
184
+ let fType = this.malloyTypeToSQLType(f.typeDef);
185
+ if (f.typeDef.type === 'sql native' &&
186
+ f.typeDef.rawType &&
187
+ ((_a = f.typeDef.rawType) === null || _a === void 0 ? void 0 : _a.match(/json/))) {
188
+ fType = f.typeDef.rawType.toUpperCase();
189
+ }
190
+ fields.push(`${this.sqlMaybeQuoteIdentifier(f.sqlOutputName)} ${fType} PATH "$.${f.rawName}"`);
181
191
  }
182
192
  return fields.join(',\n');
183
193
  }
@@ -1,4 +1,4 @@
1
- import type { Sampling, AtomicTypeDef, TimeDeltaExpr, TypecastExpr, MeasureTimeExpr, LeafAtomicTypeDef, RecordLiteralNode, ArrayLiteralNode } from '../../model/malloy_types';
1
+ import type { Sampling, AtomicTypeDef, TimeDeltaExpr, TypecastExpr, MeasureTimeExpr, BasicAtomicTypeDef, RecordLiteralNode, ArrayLiteralNode } from '../../model/malloy_types';
2
2
  import type { DialectFunctionOverloadDef } from '../functions';
3
3
  import type { DialectFieldList, FieldReferenceType, QueryInfo } from '../dialect';
4
4
  import { PostgresBase } from '../pg_impl';
@@ -60,7 +60,7 @@ export declare class PostgresDialect extends PostgresBase {
60
60
  [name: string]: DialectFunctionOverloadDef[];
61
61
  };
62
62
  malloyTypeToSQLType(malloyType: AtomicTypeDef): string;
63
- sqlTypeToMalloyType(sqlType: string): LeafAtomicTypeDef;
63
+ sqlTypeToMalloyType(sqlType: string): BasicAtomicTypeDef;
64
64
  castToString(expression: string): string;
65
65
  concat(...values: string[]): string;
66
66
  validateTypeName(sqlType: string): boolean;
@@ -110,9 +110,7 @@ class PostgresDialect extends pg_impl_1.PostgresBase {
110
110
  }
111
111
  mapFields(fieldList) {
112
112
  return fieldList
113
- .map(f => `\n ${f.sqlExpression}${f.type === 'number' ? `::${this.defaultNumberType}` : ''} as ${f.sqlOutputName}`
114
- //`${f.sqlExpression} ${f.type} as ${f.sqlOutputName}`
115
- )
113
+ .map(f => `\n ${f.sqlExpression}${f.typeDef.type === 'number' ? `::${this.defaultNumberType}` : ''} as ${f.sqlOutputName}`)
116
114
  .join(', ');
117
115
  }
118
116
  sqlAggregateTurtle(groupSet, fieldList, orderBy, limit) {
@@ -121,7 +119,6 @@ class PostgresDialect extends pg_impl_1.PostgresBase {
121
119
  tail += `[1:${limit}]`;
122
120
  }
123
121
  const fields = this.mapFields(fieldList);
124
- // return `(ARRAY_AGG((SELECT __x FROM (SELECT ${fields}) as __x) ${orderBy} ) FILTER (WHERE group_set=${groupSet}))${tail}`;
125
122
  return `COALESCE(TO_JSONB((ARRAY_AGG((SELECT TO_JSONB(__x) FROM (SELECT ${fields}\n ) as __x) ${orderBy} ) FILTER (WHERE group_set=${groupSet}))${tail}),'[]'::JSONB)`;
126
123
  }
127
124
  sqlAnyValueTurtle(groupSet, fieldList) {
@@ -137,39 +134,6 @@ class PostgresDialect extends pg_impl_1.PostgresBase {
137
134
  const fields = this.mapFields(fieldList);
138
135
  return `TO_JSONB((ARRAY_AGG((SELECT __x FROM (SELECT ${fields}) as __x)) FILTER (WHERE group_set=${groupSet}))[1])`;
139
136
  }
140
- // UNNEST((select ARRAY((SELECT ROW(gen_random_uuid()::text, state, airport_count) FROM UNNEST(base.by_state) as by_state(state text, airport_count numeric, by_fac_type record[]))))) as by_state(__distinct_key text, state text, airport_count numeric)
141
- // sqlUnnestAlias(
142
- // source: string,
143
- // alias: string,
144
- // fieldList: DialectFieldList,
145
- // needDistinctKey: boolean
146
- // ): string {
147
- // const fields = [];
148
- // for (const f of fieldList) {
149
- // let t = undefined;
150
- // switch (f.type) {
151
- // case "string":
152
- // t = "text";
153
- // break;
154
- // case "number":
155
- // t = this.defaultNumberType;
156
- // break;
157
- // case "struct":
158
- // t = "record[]";
159
- // break;
160
- // }
161
- // fields.push(`${f.sqlOutputName} ${t || f.type}`);
162
- // }
163
- // if (needDistinctKey) {
164
- // return `UNNEST((select ARRAY((SELECT ROW(gen_random_uuid()::text, ${fieldList
165
- // .map((f) => f.sqlOutputName)
166
- // .join(", ")}) FROM UNNEST(${source}) as ${alias}(${fields.join(
167
- // ", "
168
- // )}))))) as ${alias}(__distinct_key text, ${fields.join(", ")})`;
169
- // } else {
170
- // return `UNNEST(${source}) as ${alias}(${fields.join(", ")})`;
171
- // }
172
- // }
173
137
  sqlUnnestAlias(source, alias, fieldList, needDistinctKey, isArray, _isInNestedPipeline) {
174
138
  if (isArray) {
175
139
  if (needDistinctKey) {
@@ -210,6 +174,7 @@ class PostgresDialect extends pg_impl_1.PostgresBase {
210
174
  case 'array':
211
175
  case 'record':
212
176
  case 'array[record]':
177
+ case 'sql native':
213
178
  ret = `JSONB_EXTRACT_PATH(${parentAlias},'${childName}')`;
214
179
  break;
215
180
  }
@@ -1,4 +1,4 @@
1
- import type { Sampling, AtomicTypeDef, TimeTruncExpr, TimeExtractExpr, TimeDeltaExpr, TypecastExpr, TimeLiteralNode, MeasureTimeExpr, RegexMatchExpr, LeafAtomicTypeDef, ArrayLiteralNode, RecordLiteralNode } from '../../model/malloy_types';
1
+ import type { Sampling, AtomicTypeDef, TimeTruncExpr, TimeExtractExpr, TimeDeltaExpr, TypecastExpr, TimeLiteralNode, MeasureTimeExpr, RegexMatchExpr, BasicAtomicTypeDef, ArrayLiteralNode, RecordLiteralNode } from '../../model/malloy_types';
2
2
  import type { DialectFunctionOverloadDef } from '../functions';
3
3
  import type { DialectFieldList, FieldReferenceType, QueryInfo } from '../dialect';
4
4
  import { Dialect } from '../dialect';
@@ -65,7 +65,7 @@ export declare class SnowflakeDialect extends Dialect {
65
65
  [name: string]: DialectFunctionOverloadDef[];
66
66
  };
67
67
  malloyTypeToSQLType(malloyType: AtomicTypeDef): string;
68
- sqlTypeToMalloyType(sqlType: string): LeafAtomicTypeDef;
68
+ sqlTypeToMalloyType(sqlType: string): BasicAtomicTypeDef;
69
69
  castToString(expression: string): string;
70
70
  concat(...values: string[]): string;
71
71
  validateTypeName(sqlType: string): boolean;
@@ -412,7 +412,7 @@ ${(0, utils_1.indent)(sql)}
412
412
  ? recordScehma
413
413
  : `ARRAY(${recordScehma})`;
414
414
  }
415
- else if ((0, malloy_types_1.isScalarArray)(malloyType)) {
415
+ else if ((0, malloy_types_1.isBasicArray)(malloyType)) {
416
416
  return `ARRAY(${this.malloyTypeToSQLType(malloyType.elementTypeDef)})`;
417
417
  }
418
418
  return malloyType.type;
@@ -1,4 +1,4 @@
1
- import type { Sampling, AtomicTypeDef, TimeTruncExpr, TimeExtractExpr, TimeDeltaExpr, TypecastExpr, RegexMatchExpr, TimeLiteralNode, MeasureTimeExpr, LeafAtomicTypeDef, RecordLiteralNode, ArrayLiteralNode } from '../../model/malloy_types';
1
+ import type { Sampling, AtomicTypeDef, TimeTruncExpr, TimeExtractExpr, TimeDeltaExpr, TypecastExpr, RegexMatchExpr, TimeLiteralNode, MeasureTimeExpr, BasicAtomicTypeDef, RecordLiteralNode, ArrayLiteralNode } from '../../model/malloy_types';
2
2
  import type { DialectFunctionOverloadDef } from '../functions';
3
3
  import type { DialectFieldList, OrderByRequest, QueryInfo } from '../dialect';
4
4
  import { Dialect } from '../dialect';
@@ -64,7 +64,7 @@ export declare class StandardSQLDialect extends Dialect {
64
64
  [name: string]: DialectFunctionOverloadDef[];
65
65
  };
66
66
  malloyTypeToSQLType(malloyType: AtomicTypeDef): string;
67
- sqlTypeToMalloyType(sqlType: string): LeafAtomicTypeDef;
67
+ sqlTypeToMalloyType(sqlType: string): BasicAtomicTypeDef;
68
68
  castToString(expression: string): string;
69
69
  concat(...values: string[]): string;
70
70
  validateTypeName(sqlType: string): boolean;
@@ -131,7 +131,7 @@ class StandardSQLDialect extends dialect_1.Dialect {
131
131
  const fields = fieldList
132
132
  .map(f => `${f.sqlExpression} as ${f.sqlOutputName}`)
133
133
  .join(', ');
134
- return `ANY_VALUE(CASE WHEN group_set=${groupSet} THEN STRUCT(${fields}))`;
134
+ return `ANY_VALUE(CASE WHEN group_set=${groupSet} THEN STRUCT(${fields}) END)`;
135
135
  }
136
136
  sqlAnyValueLastTurtle(name, groupSet, sqlName) {
137
137
  return `ANY_VALUE(CASE WHEN group_set=${groupSet} THEN ${name} END) as ${sqlName}`;
@@ -1,4 +1,4 @@
1
- import type { Expr, Sampling, AtomicTypeDef, TimeDeltaExpr, TypecastExpr, RegexMatchExpr, MeasureTimeExpr, TimeLiteralNode, TimeExtractExpr, LeafAtomicTypeDef, RecordLiteralNode } from '../../model/malloy_types';
1
+ import type { Expr, Sampling, AtomicTypeDef, TimeDeltaExpr, TypecastExpr, RegexMatchExpr, MeasureTimeExpr, TimeLiteralNode, TimeExtractExpr, BasicAtomicTypeDef, RecordLiteralNode } from '../../model/malloy_types';
2
2
  import type { DialectFunctionOverloadDef } from '../functions';
3
3
  import type { DialectFieldList, OrderByClauseType, QueryInfo } from '../dialect';
4
4
  import { PostgresBase } from '../pg_impl';
@@ -65,7 +65,7 @@ export declare class TrinoDialect extends PostgresBase {
65
65
  [name: string]: DialectFunctionOverloadDef[];
66
66
  };
67
67
  malloyTypeToSQLType(malloyType: AtomicTypeDef): string;
68
- sqlTypeToMalloyType(sqlType: string): LeafAtomicTypeDef;
68
+ sqlTypeToMalloyType(sqlType: string): BasicAtomicTypeDef;
69
69
  castToString(expression: string): string;
70
70
  concat(...values: string[]): string;
71
71
  sqlMakeUnnestKey(key: string, rowKey: string): string;
@@ -26,7 +26,6 @@ exports.PrestoDialect = exports.TrinoDialect = void 0;
26
26
  const utils_1 = require("../../model/utils");
27
27
  const malloy_types_1 = require("../../model/malloy_types");
28
28
  const functions_1 = require("../functions");
29
- const dialect_1 = require("../dialect");
30
29
  const pg_impl_1 = require("../pg_impl");
31
30
  const dialect_functions_1 = require("./dialect_functions");
32
31
  const function_overrides_1 = require("./function_overrides");
@@ -50,10 +49,6 @@ function qtz(qi) {
50
49
  return tz;
51
50
  }
52
51
  }
53
- const trinoTypeMap = {
54
- 'string': 'VARCHAR',
55
- 'number': 'DOUBLE',
56
- };
57
52
  const trinoToMalloyTypes = {
58
53
  'varchar': { type: 'string' },
59
54
  'integer': { type: 'number', numberType: 'integer' },
@@ -227,20 +222,9 @@ class TrinoDialect extends pg_impl_1.PostgresBase {
227
222
  return `ANY_VALUE(CASE WHEN group_set=${groupSet} THEN ${fieldName} END)`;
228
223
  }
229
224
  buildTypeExpression(fieldList) {
230
- const fields = [];
231
- for (const f of fieldList) {
232
- if ((0, dialect_1.isDialectFieldStruct)(f)) {
233
- let s = `ROW(${this.buildTypeExpression(f.nestedStruct)})`;
234
- if (f.isArray) {
235
- s = `array(${s})`;
236
- }
237
- fields.push(`${f.sqlOutputName} ${s}`);
238
- }
239
- else {
240
- fields.push(`${f.sqlOutputName} ${trinoTypeMap[f.type] || f.type}`);
241
- }
242
- }
243
- return fields.join(', \n');
225
+ return fieldList
226
+ .map(dlf => `${dlf.sqlOutputName} ${this.malloyTypeToSQLType(dlf.typeDef)}`)
227
+ .join(', \n');
244
228
  }
245
229
  // can array agg or any_value a struct...
246
230
  sqlAggregateTurtle(groupSet, fieldList, orderBy, limit) {
@@ -253,10 +237,9 @@ class TrinoDialect extends pg_impl_1.PostgresBase {
253
237
  return ret;
254
238
  }
255
239
  sqlAnyValueTurtle(groupSet, fieldList) {
256
- const fields = fieldList
257
- .map(f => `\n '${f.sqlOutputName}' VALUE ${f.sqlExpression}`)
258
- .join(', ');
259
- return `ANY_VALUE(CASE WHEN group_set=${groupSet} THEN JSON_OBJECT(${fields}))`;
240
+ const expressions = fieldList.map(f => f.sqlExpression).join(',\n ');
241
+ const definitions = this.buildTypeExpression(fieldList);
242
+ return `ANY_VALUE(CASE WHEN group_set=${groupSet} THEN CAST(ROW(${expressions}) AS ROW(${definitions})) END)`;
260
243
  }
261
244
  sqlAnyValueLastTurtle(name, groupSet, sqlName) {
262
245
  return `ANY_VALUE(CASE WHEN group_set=${groupSet} THEN ${name} END) as ${sqlName}`;
@@ -465,10 +448,16 @@ ${(0, utils_1.indent)(sql)}
465
448
  case 'sql native':
466
449
  return malloyType.rawType || 'UNKNOWN-NATIVE';
467
450
  case 'array': {
468
- if (malloyType.elementTypeDef.type !== 'record_element') {
469
- return `ARRAY<${this.malloyTypeToSQLType(malloyType.elementTypeDef)}>`;
451
+ if ((0, malloy_types_1.isRepeatedRecord)(malloyType)) {
452
+ const typeSpec = [];
453
+ for (const f of malloyType.fields) {
454
+ if ((0, malloy_types_1.isAtomic)(f)) {
455
+ typeSpec.push(`${f.name} ${this.malloyTypeToSQLType(f)}`);
456
+ }
457
+ }
458
+ return `ARRAY<ROW(${typeSpec.join(',')})>`;
470
459
  }
471
- return malloyType.type.toUpperCase();
460
+ return `ARRAY<${this.malloyTypeToSQLType(malloyType.elementTypeDef)}>`;
472
461
  }
473
462
  default:
474
463
  return malloyType.type.toUpperCase();
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 { QueryDataRow, 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, QueryRunStats, NamedQuery, NamedModelObject, ExpressionType, FunctionDef, FunctionOverloadDef, FunctionParameterDef, ExpressionValueType, TypeDesc, FunctionParamTypeDesc, DocumentLocation, DocumentRange, DocumentPosition, Sampling, Annotation, LeafAtomicTypeDef, LeafAtomicDef, AtomicTypeDef, AtomicFieldDef, ArrayDef, ArrayTypeDef, RecordTypeDef, RepeatedRecordTypeDef, RecordDef, RepeatedRecordDef, RecordLiteralNode, ArrayLiteralNode, } from './model';
4
- export { isSourceDef, Segment, isLeafAtomic, isJoined, isJoinedSource, isSamplingEnable, isSamplingPercent, isSamplingRows, isRepeatedRecord, isScalarArray, mkArrayDef, mkFieldDef, expressionIsAggregate, expressionIsAnalytic, expressionIsCalculation, expressionIsScalar, expressionIsUngroupedAggregate, indent, composeSQLExpr, } from './model';
3
+ export type { QueryDataRow, 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, QueryRunStats, NamedQuery, NamedModelObject, ExpressionType, FunctionDef, FunctionOverloadDef, FunctionParameterDef, ExpressionValueType, TypeDesc, FunctionParamTypeDesc, DocumentLocation, DocumentRange, DocumentPosition, Sampling, Annotation, BasicAtomicTypeDef, BasicAtomicDef, AtomicTypeDef, AtomicFieldDef, ArrayDef, ArrayTypeDef, RecordTypeDef, RepeatedRecordTypeDef, RecordDef, RepeatedRecordDef, RecordLiteralNode, ArrayLiteralNode, } from './model';
4
+ export { isSourceDef, Segment, isBasicAtomic, isJoined, isJoinedSource, isSamplingEnable, isSamplingPercent, isSamplingRows, isRepeatedRecord, isBasicArray, mkArrayDef, mkFieldDef, expressionIsAggregate, expressionIsAnalytic, expressionIsCalculation, expressionIsScalar, expressionIsUngroupedAggregate, indent, composeSQLExpr, } 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 './malloy';
package/dist/index.js CHANGED
@@ -23,7 +23,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
23
23
  return result;
24
24
  };
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.EmptyURLReader = exports.SingleConnectionRuntime = exports.ConnectionRuntime = exports.AtomicFieldType = exports.Runtime = exports.Malloy = exports.Model = exports.MalloyTranslator = exports.malloyToQuery = exports.composeSQLExpr = exports.indent = exports.expressionIsUngroupedAggregate = exports.expressionIsScalar = exports.expressionIsCalculation = exports.expressionIsAnalytic = exports.expressionIsAggregate = exports.mkFieldDef = exports.mkArrayDef = exports.isScalarArray = exports.isRepeatedRecord = exports.isSamplingRows = exports.isSamplingPercent = exports.isSamplingEnable = exports.isJoinedSource = exports.isJoined = exports.isLeafAtomic = exports.Segment = 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;
26
+ exports.EmptyURLReader = exports.SingleConnectionRuntime = exports.ConnectionRuntime = exports.AtomicFieldType = exports.Runtime = exports.Malloy = exports.Model = exports.MalloyTranslator = exports.malloyToQuery = 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.isBasicAtomic = exports.Segment = 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;
27
27
  exports.annotationToTaglines = exports.annotationToTag = exports.sqlKey = exports.API = exports.modelDefToModelInfo = exports.toAsyncGenerator = 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 = void 0;
28
28
  /*
29
29
  * Copyright 2023 Google LLC
@@ -74,14 +74,14 @@ var model_1 = require("./model");
74
74
  Object.defineProperty(exports, "isSourceDef", { enumerable: true, get: function () { return model_1.isSourceDef; } });
75
75
  // Used in Composer Demo
76
76
  Object.defineProperty(exports, "Segment", { enumerable: true, get: function () { return model_1.Segment; } });
77
- Object.defineProperty(exports, "isLeafAtomic", { enumerable: true, get: function () { return model_1.isLeafAtomic; } });
77
+ Object.defineProperty(exports, "isBasicAtomic", { enumerable: true, get: function () { return model_1.isBasicAtomic; } });
78
78
  Object.defineProperty(exports, "isJoined", { enumerable: true, get: function () { return model_1.isJoined; } });
79
79
  Object.defineProperty(exports, "isJoinedSource", { enumerable: true, get: function () { return model_1.isJoinedSource; } });
80
80
  Object.defineProperty(exports, "isSamplingEnable", { enumerable: true, get: function () { return model_1.isSamplingEnable; } });
81
81
  Object.defineProperty(exports, "isSamplingPercent", { enumerable: true, get: function () { return model_1.isSamplingPercent; } });
82
82
  Object.defineProperty(exports, "isSamplingRows", { enumerable: true, get: function () { return model_1.isSamplingRows; } });
83
83
  Object.defineProperty(exports, "isRepeatedRecord", { enumerable: true, get: function () { return model_1.isRepeatedRecord; } });
84
- Object.defineProperty(exports, "isScalarArray", { enumerable: true, get: function () { return model_1.isScalarArray; } });
84
+ Object.defineProperty(exports, "isBasicArray", { enumerable: true, get: function () { return model_1.isBasicArray; } });
85
85
  Object.defineProperty(exports, "mkArrayDef", { enumerable: true, get: function () { return model_1.mkArrayDef; } });
86
86
  Object.defineProperty(exports, "mkFieldDef", { enumerable: true, get: function () { return model_1.mkFieldDef; } });
87
87
  Object.defineProperty(exports, "expressionIsAggregate", { enumerable: true, get: function () { return model_1.expressionIsAggregate; } });
@@ -480,7 +480,7 @@ function isDataTypeMatch(genericsAlreadySelected, genericTypes, arg, paramT) {
480
480
  return { dataTypeMatch: true, genericsSet: [] };
481
481
  }
482
482
  if (paramT.type === 'array' && arg.type === 'array') {
483
- if ((0, malloy_types_1.isScalarArray)(arg)) {
483
+ if ((0, malloy_types_1.isBasicArray)(arg)) {
484
484
  if (!(0, malloy_types_1.isRepeatedRecordFunctionParam)(paramT)) {
485
485
  return isDataTypeMatch(genericsAlreadySelected, genericTypes, arg.elementTypeDef, paramT.elementTypeDef);
486
486
  }
@@ -135,7 +135,7 @@ class IndexFieldSpace extends query_spaces_1.QueryOperationSpace {
135
135
  else {
136
136
  const eTypeDesc = entry.typeDesc();
137
137
  // Don't index arrays and records
138
- if (malloy_types_1.TD.isLeafAtomic(eTypeDesc) &&
138
+ if (malloy_types_1.TD.isBasicAtomic(eTypeDesc) &&
139
139
  (0, malloy_types_1.expressionIsScalar)(eTypeDesc.expressionType) &&
140
140
  (dialect === undefined || !dialect.ignoreInProject(name))) {
141
141
  expandEntries.push({ name: indexName, entry });
@@ -55,7 +55,7 @@ export declare abstract class ViewField extends SpaceField {
55
55
  } | {
56
56
  compositeFieldUsage: import("../../../model/malloy_types").CompositeFieldUsage;
57
57
  type: "array";
58
- elementTypeDef: import("../../../model/malloy_types").LeafAtomicTypeDef | import("../../../model/malloy_types").ScalarArrayTypeDef | import("../../../model/malloy_types").RepeatedRecordTypeDef;
58
+ elementTypeDef: import("../../../model/malloy_types").BasicAtomicTypeDef | import("../../../model/malloy_types").BasicArrayTypeDef | import("../../../model/malloy_types").RepeatedRecordTypeDef;
59
59
  expressionType: import("../../../model/malloy_types").ExpressionType;
60
60
  evalSpace: import("../../../model/malloy_types").EvalSpace;
61
61
  } | {
@@ -1,8 +1,7 @@
1
- import type { Dialect, DialectFieldList } from '../dialect';
2
- import type { AggregateFunctionType, Annotation, CompiledQuery, Expr, FieldDef, Filtered, FunctionOverloadDef, FunctionParameterDef, JoinRelationship, ModelDef, OrderBy, OutputFieldNode, ParameterNode, PipeSegment, Query, QueryFieldDef, QuerySegment, ResultMetadataDef, ResultStructMetadataDef, SearchIndexResult, SegmentFieldDef, StructDef, StructRef, TurtleDef, FunctionOrderBy, Argument, AggregateExpr, FilterCondition, GenericSQLExpr, FieldnameNode, FunctionCallNode, UngroupNode, SourceReferenceNode, SpreadExpr, FilteredExpr, SourceDef, BooleanFieldDef, QueryResultDef, QueryToMaterialize, PrepareResultOptions, CaseExpr, LeafAtomicDef } from './malloy_types';
1
+ import type { QueryInfo, Dialect, DialectFieldList } from '../dialect';
2
+ import type { AggregateFunctionType, Annotation, CompiledQuery, Expr, FieldDef, Filtered, FunctionOverloadDef, FunctionParameterDef, JoinRelationship, ModelDef, OrderBy, OutputFieldNode, ParameterNode, PipeSegment, Query, QueryFieldDef, QuerySegment, ResultMetadataDef, ResultStructMetadataDef, SearchIndexResult, SegmentFieldDef, StructDef, StructRef, TurtleDef, FunctionOrderBy, Argument, AggregateExpr, FilterCondition, GenericSQLExpr, FieldnameNode, FunctionCallNode, UngroupNode, SourceReferenceNode, SpreadExpr, FilteredExpr, SourceDef, BooleanFieldDef, QueryResultDef, QueryToMaterialize, PrepareResultOptions, CaseExpr, BasicAtomicDef, AtomicFieldDef } from './malloy_types';
3
3
  import type { Connection } from '../connection/types';
4
4
  import { AndChain } from './utils';
5
- import type { QueryInfo } from '../dialect/dialect';
6
5
  import type { EventStream } from '../runtime_types';
7
6
  import type { Tag } from '@malloydata/malloy-tag';
8
7
  interface TurtleDefPlus extends TurtleDef, Filtered {
@@ -98,19 +97,16 @@ declare class QueryField extends QueryNode {
98
97
  isNestedInParent(parentDef: FieldDef): boolean;
99
98
  isArrayElement(parentDef: FieldDef): boolean;
100
99
  generateExpression(resultSet: FieldInstanceResult): string;
100
+ includeInWildcard(): boolean;
101
101
  }
102
- type QueryFieldAtomic = AbstractQueryAtomic<LeafAtomicDef>;
103
- declare class AbstractQueryAtomic<T extends LeafAtomicDef> extends QueryField {
102
+ type QueryBasicField = QueryAtomicField<BasicAtomicDef>;
103
+ declare abstract class QueryAtomicField<T extends AtomicFieldDef> extends QueryField {
104
104
  fieldDef: T;
105
105
  constructor(fieldDef: T, parent: QueryStruct, refId?: string);
106
106
  includeInWildcard(): boolean;
107
- isCalculated(): boolean;
108
- isAggregate(): boolean;
109
107
  getFilterList(): FilterCondition[];
110
- hasExpression(): boolean;
111
- isAtomic(): boolean;
112
108
  }
113
- declare class QueryFieldBoolean extends AbstractQueryAtomic<BooleanFieldDef> {
109
+ declare class QueryFieldBoolean extends QueryAtomicField<BooleanFieldDef> {
114
110
  }
115
111
  type FieldUsage = {
116
112
  type: 'result';
@@ -333,7 +329,7 @@ declare class QueryStruct {
333
329
  getJoinableParent(): QueryStruct;
334
330
  addFieldToNameMap(as: string, n: QueryField): void;
335
331
  /** the the primary key or throw an error. */
336
- getPrimaryKeyField(fieldDef: FieldDef): QueryFieldAtomic;
332
+ getPrimaryKeyField(fieldDef: FieldDef): QueryBasicField;
337
333
  /**
338
334
  * called after all structure has been loaded. Examine this structure to see
339
335
  * if if it is based on a query and if it is, add the output fields (unless
@@ -347,7 +343,7 @@ declare class QueryStruct {
347
343
  makeQueryField(field: FieldDef, referenceId?: string): QueryField;
348
344
  structSourceSQL(stageWriter: StageWriter): string;
349
345
  root(): QueryStruct;
350
- primaryKey(): QueryFieldAtomic | undefined;
346
+ primaryKey(): QueryBasicField | undefined;
351
347
  getChildByName(name: string): QueryField | undefined;
352
348
  /** convert a path into a field reference */
353
349
  getFieldByName(path: string[]): QueryField;
@@ -355,10 +351,10 @@ declare class QueryStruct {
355
351
  getQueryFieldReference(path: string[], annotation: Annotation | undefined): QueryField;
356
352
  getDimensionOrMeasureByName(name: string[]): QueryField;
357
353
  /** returns a query object for the given name */
358
- getDimensionByName(name: string[]): QueryFieldAtomic;
354
+ getDimensionByName(name: string[]): QueryBasicField;
359
355
  /** returns a query object for the given name */
360
356
  getStructByName(name: string[]): QueryStruct;
361
- getDistinctKey(): QueryFieldAtomic;
357
+ getDistinctKey(): QueryBasicField;
362
358
  applyStructFiltersToTurtleDef(turtleDef: TurtleDef | TurtleDefPlus): TurtleDef;
363
359
  }
364
360
  /** the resulting SQL and the shape of the data at each stage of the pipeline */
@@ -46,7 +46,7 @@ function getDialectFieldList(structDef) {
46
46
  const dialectFieldList = [];
47
47
  for (const f of structDef.fields.filter(malloy_types_1.fieldIsIntrinsic)) {
48
48
  dialectFieldList.push({
49
- type: f.type,
49
+ typeDef: f,
50
50
  sqlExpression: (0, malloy_types_1.getIdentifier)(f),
51
51
  rawName: (0, malloy_types_1.getIdentifier)(f),
52
52
  sqlOutputName: (0, malloy_types_1.getIdentifier)(f),
@@ -54,6 +54,12 @@ function getDialectFieldList(structDef) {
54
54
  }
55
55
  return dialectFieldList;
56
56
  }
57
+ function pushDialectField(dl, f) {
58
+ const { sqlExpression, sqlOutputName, rawName } = f;
59
+ if ((0, malloy_types_1.isAtomic)(f.fieldDef)) {
60
+ dl.push({ typeDef: f.fieldDef, sqlExpression, sqlOutputName, rawName });
61
+ }
62
+ }
57
63
  class UniqueKeyUse extends Set {
58
64
  add_use(k) {
59
65
  if (k !== undefined) {
@@ -622,7 +628,7 @@ class QueryField extends QueryNode {
622
628
  const ret = [];
623
629
  let p = resultStruct.parent;
624
630
  while (p !== undefined) {
625
- const scalars = p.fields(fi => isScalarField(fi.f) && fi.fieldUsage.type === 'result');
631
+ const scalars = p.fields(fi => isBasicScalar(fi.f) && fi.fieldUsage.type === 'result');
626
632
  const partitionSQLs = scalars.map(fi => fi.getAnalyticalSQL(true));
627
633
  ret.push(...partitionSQLs);
628
634
  p = p.parent;
@@ -942,17 +948,44 @@ class QueryField extends QueryNode {
942
948
  }
943
949
  : undefined);
944
950
  }
951
+ includeInWildcard() {
952
+ return false;
953
+ }
945
954
  }
946
- function isCalculatedField(f) {
947
- return f instanceof AbstractQueryAtomic && f.isCalculated();
955
+ function isBasicCalculation(f) {
956
+ return f instanceof QueryAtomicField && isCalculatedField(f);
948
957
  }
949
- function isAggregateField(f) {
950
- return f instanceof AbstractQueryAtomic && f.isAggregate();
958
+ function isBasicAggregate(f) {
959
+ return f instanceof QueryAtomicField && isAggregateField(f);
960
+ }
961
+ function isBasicScalar(f) {
962
+ return f instanceof QueryAtomicField && isScalarField(f);
951
963
  }
952
964
  function isScalarField(f) {
953
- return (f instanceof AbstractQueryAtomic && !f.isCalculated() && !f.isAggregate());
965
+ if (f.isAtomic()) {
966
+ if ((0, malloy_types_1.hasExpression)(f.fieldDef)) {
967
+ const et = f.fieldDef.expressionType;
968
+ if ((0, malloy_types_1.expressionIsCalculation)(et) || (0, malloy_types_1.expressionIsAggregate)(et)) {
969
+ return false;
970
+ }
971
+ }
972
+ return true;
973
+ }
974
+ return false;
954
975
  }
955
- class AbstractQueryAtomic extends QueryField {
976
+ function isCalculatedField(f) {
977
+ if (f.isAtomic() && (0, malloy_types_1.hasExpression)(f.fieldDef)) {
978
+ return (0, malloy_types_1.expressionIsCalculation)(f.fieldDef.expressionType);
979
+ }
980
+ return false;
981
+ }
982
+ function isAggregateField(f) {
983
+ if (f.isAtomic() && (0, malloy_types_1.hasExpression)(f.fieldDef)) {
984
+ return (0, malloy_types_1.expressionIsAggregate)(f.fieldDef.expressionType);
985
+ }
986
+ return false;
987
+ }
988
+ class QueryAtomicField extends QueryField {
956
989
  constructor(fieldDef, parent, refId) {
957
990
  super(fieldDef, parent, refId);
958
991
  this.fieldDef = fieldDef; // wish I didn't have to do this
@@ -960,36 +993,22 @@ class AbstractQueryAtomic extends QueryField {
960
993
  includeInWildcard() {
961
994
  return true;
962
995
  }
963
- isCalculated() {
964
- return ((0, malloy_types_1.hasExpression)(this.fieldDef) &&
965
- (0, malloy_types_1.expressionIsCalculation)(this.fieldDef.expressionType));
966
- }
967
- isAggregate() {
968
- return ((0, malloy_types_1.hasExpression)(this.fieldDef) &&
969
- (0, malloy_types_1.expressionIsAggregate)(this.fieldDef.expressionType));
970
- }
971
996
  getFilterList() {
972
997
  return [];
973
998
  }
974
- hasExpression() {
975
- return (0, malloy_types_1.hasExpression)(this.fieldDef);
976
- }
977
- isAtomic() {
978
- return true;
979
- }
980
999
  }
981
1000
  // class QueryMeasure extends QueryField {}
982
- class QueryFieldString extends AbstractQueryAtomic {
1001
+ class QueryFieldString extends QueryAtomicField {
983
1002
  }
984
- class QueryFieldNumber extends AbstractQueryAtomic {
1003
+ class QueryFieldNumber extends QueryAtomicField {
985
1004
  }
986
- class QueryFieldBoolean extends AbstractQueryAtomic {
1005
+ class QueryFieldBoolean extends QueryAtomicField {
987
1006
  }
988
- class QueryFieldJSON extends AbstractQueryAtomic {
1007
+ class QueryFieldJSON extends QueryAtomicField {
989
1008
  }
990
- class QueryFieldUnsupported extends AbstractQueryAtomic {
1009
+ class QueryFieldUnsupported extends QueryAtomicField {
991
1010
  }
992
- class QueryFieldDate extends AbstractQueryAtomic {
1011
+ class QueryFieldDate extends QueryAtomicField {
993
1012
  generateExpression(resultSet) {
994
1013
  const fd = this.fieldDef;
995
1014
  const superExpr = super.generateExpression(resultSet);
@@ -1015,7 +1034,7 @@ class QueryFieldDate extends AbstractQueryAtomic {
1015
1034
  return new QueryFieldDate(fieldDef, this.parent);
1016
1035
  }
1017
1036
  }
1018
- class QueryFieldTimestamp extends AbstractQueryAtomic {
1037
+ class QueryFieldTimestamp extends QueryAtomicField {
1019
1038
  // clone ourselves on demand as a timeframe.
1020
1039
  getChildByName(name) {
1021
1040
  const fieldDef = {
@@ -1026,7 +1045,7 @@ class QueryFieldTimestamp extends AbstractQueryAtomic {
1026
1045
  return new QueryFieldTimestamp(fieldDef, this.parent);
1027
1046
  }
1028
1047
  }
1029
- class QueryFieldDistinctKey extends AbstractQueryAtomic {
1048
+ class QueryFieldDistinctKey extends QueryAtomicField {
1030
1049
  generateExpression(resultSet) {
1031
1050
  var _a;
1032
1051
  if (this.parent.primaryKey()) {
@@ -1246,7 +1265,7 @@ class FieldInstanceResult {
1246
1265
  let ret = 'inline_all_numbers';
1247
1266
  for (const f of this.fields()) {
1248
1267
  if (f.fieldUsage.type === 'result') {
1249
- if (isScalarField(f.f)) {
1268
+ if (isBasicScalar(f.f)) {
1250
1269
  return 'nested';
1251
1270
  }
1252
1271
  if (f.f instanceof QueryFieldStruct) {
@@ -1293,7 +1312,7 @@ class FieldInstanceResult {
1293
1312
  if (['date', 'timestamp'].indexOf(fi.f.fieldDef.type) > -1) {
1294
1313
  return [{ dir: 'desc', field: fi.fieldUsage.resultIndex }];
1295
1314
  }
1296
- else if (isAggregateField(fi.f)) {
1315
+ else if (isBasicAggregate(fi.f)) {
1297
1316
  return [{ dir: 'desc', field: fi.fieldUsage.resultIndex }];
1298
1317
  }
1299
1318
  }
@@ -1367,7 +1386,7 @@ class FieldInstanceResult {
1367
1386
  // fields specified an an all, convert it to an exclude set.
1368
1387
  const allFields = (ungroupSet === null || ungroupSet === void 0 ? void 0 : ungroupSet.fields) || [];
1369
1388
  // convert an All into the equivalent exclude
1370
- excludeFields = this.fields(fi => isScalarField(fi.f) &&
1389
+ excludeFields = this.fields(fi => isBasicScalar(fi.f) &&
1371
1390
  fi.fieldUsage.type === 'result' &&
1372
1391
  allFields.indexOf(fi.f.getIdentifier()) === -1).map(fi => fi.f.getIdentifier());
1373
1392
  }
@@ -1783,13 +1802,13 @@ class QueryQuery extends QueryField {
1783
1802
  this.expandFields(fir);
1784
1803
  resultStruct.add(as, fir);
1785
1804
  }
1786
- else if (field instanceof AbstractQueryAtomic) {
1805
+ else if (field instanceof QueryAtomicField) {
1787
1806
  resultStruct.addField(as, field, {
1788
1807
  resultIndex,
1789
1808
  type: 'result',
1790
1809
  });
1791
1810
  this.addDependancies(resultStruct, field);
1792
- if (isAggregateField(field)) {
1811
+ if (isBasicAggregate(field)) {
1793
1812
  if (this.firstSegment.type === 'project') {
1794
1813
  throw new Error(`Aggregate Fields cannot be used in select - '${field.fieldDef.name}'`);
1795
1814
  }
@@ -1896,7 +1915,7 @@ class QueryQuery extends QueryField {
1896
1915
  sourceClasses,
1897
1916
  referenceId,
1898
1917
  };
1899
- if (isCalculatedField(fi.f)) {
1918
+ if (isBasicCalculation(fi.f)) {
1900
1919
  filterList = fi.f.getFilterList();
1901
1920
  return {
1902
1921
  ...base,
@@ -1904,7 +1923,7 @@ class QueryQuery extends QueryField {
1904
1923
  fieldKind: 'measure',
1905
1924
  };
1906
1925
  }
1907
- if (isScalarField(fi.f)) {
1926
+ if (isBasicScalar(fi.f)) {
1908
1927
  return {
1909
1928
  ...base,
1910
1929
  filterList,
@@ -1976,7 +1995,7 @@ class QueryQuery extends QueryField {
1976
1995
  if (fi.fieldUsage.type === 'result') {
1977
1996
  // if there is only one dimension, it is the primaryKey
1978
1997
  // if there are more, primaryKey is undefined.
1979
- if (isScalarField(fi.f)) {
1998
+ if (isBasicScalar(fi.f)) {
1980
1999
  if (dimCount === 0 && isRoot) {
1981
2000
  primaryKey = name;
1982
2001
  }
@@ -2155,7 +2174,7 @@ class QueryQuery extends QueryField {
2155
2174
  }
2156
2175
  // we need to generate primary key. If parent has a primary key combine
2157
2176
  // console.log(ji.alias, fieldExpression, this.inNestedPipeline());
2158
- s += `${this.parent.dialect.sqlUnnestAlias(arrayExpression, ji.alias, ji.getDialectFieldList(), ji.makeUniqueKey, (0, malloy_types_1.isScalarArray)(qsDef), this.inNestedPipeline())}\n`;
2177
+ s += `${this.parent.dialect.sqlUnnestAlias(arrayExpression, ji.alias, ji.getDialectFieldList(), ji.makeUniqueKey, (0, malloy_types_1.isBasicArray)(qsDef), this.inNestedPipeline())}\n`;
2159
2178
  }
2160
2179
  else if (qsDef.type === 'record') {
2161
2180
  throw new Error('Internal Error: records should never appear in join trees');
@@ -2382,7 +2401,7 @@ class QueryQuery extends QueryField {
2382
2401
  }
2383
2402
  output.dimensionIndexes.push(output.fieldIndex++);
2384
2403
  }
2385
- else if (isCalculatedField(fi.f)) {
2404
+ else if (isBasicCalculation(fi.f)) {
2386
2405
  output.sql.push(`${exp} as ${outputName}`);
2387
2406
  output.fieldIndex++;
2388
2407
  }
@@ -2519,7 +2538,7 @@ class QueryQuery extends QueryField {
2519
2538
  output.sql.push(`${exp} as ${sqlFieldName}`);
2520
2539
  output.dimensionIndexes.push(output.fieldIndex++);
2521
2540
  }
2522
- else if (isCalculatedField(fi.f)) {
2541
+ else if (isBasicCalculation(fi.f)) {
2523
2542
  const exp = this.parent.dialect.sqlAnyValue(resultSet.groupSet, sqlFieldName);
2524
2543
  output.sql.push(`${exp} as ${sqlFieldName}`);
2525
2544
  output.fieldIndex++;
@@ -2591,7 +2610,7 @@ class QueryQuery extends QueryField {
2591
2610
  fieldsSQL.push(this.parent.dialect.sqlMaybeQuoteIdentifier(`${name}__${this.rootResult.groupSet}`) + ` as ${sqlName}`);
2592
2611
  dimensionIndexes.push(fieldIndex++);
2593
2612
  }
2594
- else if (isCalculatedField(fi.f)) {
2613
+ else if (isBasicCalculation(fi.f)) {
2595
2614
  fieldsSQL.push(this.parent.dialect.sqlAnyValueLastTurtle(this.parent.dialect.sqlMaybeQuoteIdentifier(`${name}__${this.rootResult.groupSet}`), this.rootResult.groupSet, sqlName));
2596
2615
  fieldIndex++;
2597
2616
  }
@@ -2634,21 +2653,42 @@ class QueryQuery extends QueryField {
2634
2653
  //
2635
2654
  if (resultStruct.firstSegment.type === 'reduce' &&
2636
2655
  field instanceof FieldInstanceResult) {
2637
- const d = {
2638
- type: 'struct',
2639
- sqlExpression: this.parent.dialect.sqlMaybeQuoteIdentifier(`${name}__${resultStruct.groupSet}`),
2640
- rawName: name,
2641
- sqlOutputName: sqlName,
2642
- isArray: field.getRepeatedResultType() === 'nested',
2643
- nestedStruct: this.buildDialectFieldList(field),
2644
- };
2645
- dialectFieldList.push(d);
2656
+ const { structDef, repeatedResultType } = this.generateTurtlePipelineSQL(field, new StageWriter(true, undefined), '<nosource>');
2657
+ if (repeatedResultType === 'nested') {
2658
+ const multiLineNest = {
2659
+ ...structDef,
2660
+ type: 'array',
2661
+ elementTypeDef: { type: 'record_element' },
2662
+ join: 'many',
2663
+ name,
2664
+ };
2665
+ dialectFieldList.push({
2666
+ typeDef: multiLineNest,
2667
+ sqlExpression: this.parent.dialect.sqlMaybeQuoteIdentifier(`${name}__${resultStruct.groupSet}`),
2668
+ rawName: name,
2669
+ sqlOutputName: sqlName,
2670
+ });
2671
+ }
2672
+ else {
2673
+ const oneLineNest = {
2674
+ ...structDef,
2675
+ type: 'record',
2676
+ join: 'one',
2677
+ name,
2678
+ };
2679
+ dialectFieldList.push({
2680
+ typeDef: oneLineNest,
2681
+ sqlExpression: this.parent.dialect.sqlMaybeQuoteIdentifier(`${name}__${resultStruct.groupSet}`),
2682
+ rawName: name,
2683
+ sqlOutputName: sqlName,
2684
+ });
2685
+ }
2646
2686
  }
2647
2687
  else if (resultStruct.firstSegment.type === 'reduce' &&
2648
2688
  field instanceof FieldInstanceField &&
2649
2689
  field.fieldUsage.type === 'result') {
2650
- dialectFieldList.push({
2651
- type: field.f.fieldDef.type,
2690
+ pushDialectField(dialectFieldList, {
2691
+ fieldDef: field.f.fieldDef,
2652
2692
  sqlExpression: this.parent.dialect.sqlMaybeQuoteIdentifier(`${name}__${resultStruct.groupSet}`),
2653
2693
  rawName: name,
2654
2694
  sqlOutputName: sqlName,
@@ -2657,8 +2697,8 @@ class QueryQuery extends QueryField {
2657
2697
  else if (resultStruct.firstSegment.type === 'project' &&
2658
2698
  field instanceof FieldInstanceField &&
2659
2699
  field.fieldUsage.type === 'result') {
2660
- dialectFieldList.push({
2661
- type: field.f.fieldDef.type,
2700
+ pushDialectField(dialectFieldList, {
2701
+ fieldDef: field.f.fieldDef,
2662
2702
  sqlExpression: field.f.generateExpression(resultStruct),
2663
2703
  rawName: name,
2664
2704
  sqlOutputName: sqlName,
@@ -2857,7 +2897,7 @@ class QueryQueryIndexStage extends QueryQuery {
2857
2897
  resultIndex,
2858
2898
  type: 'result',
2859
2899
  });
2860
- if (field instanceof AbstractQueryAtomic) {
2900
+ if (field instanceof QueryAtomicField) {
2861
2901
  this.addDependancies(resultStruct, field);
2862
2902
  }
2863
2903
  resultIndex++;
@@ -3091,17 +3131,15 @@ class QueryFieldStruct extends QueryField {
3091
3131
  * those probably should be in here ... I thought this would be important
3092
3132
  * but maybe it isn't, it doesn't fix the problem I am working on ...
3093
3133
  */
3094
- // mtoy todo review with lloyd if any of these are needed, had to NOT
3095
- // do getIdentifier to pass a test, didn't stop to think why.
3096
- // getIdentifier() {
3097
- // return this.queryStruct.getIdentifier();
3098
- // }
3099
3134
  getJoinableParent() {
3100
3135
  return this.queryStruct.getJoinableParent();
3101
3136
  }
3102
3137
  getFullOutputName() {
3103
3138
  return this.queryStruct.getFullOutputName();
3104
3139
  }
3140
+ includeInWildcard() {
3141
+ return this.isAtomic();
3142
+ }
3105
3143
  }
3106
3144
  /** Structure object as it is used to build a query */
3107
3145
  class QueryStruct {
@@ -3551,7 +3589,7 @@ class QueryStruct {
3551
3589
  /** returns a query object for the given name */
3552
3590
  getDimensionByName(name) {
3553
3591
  const field = this.getFieldByName(name);
3554
- if (field.isAtomic() && isScalarField(field)) {
3592
+ if (isBasicScalar(field)) {
3555
3593
  return field;
3556
3594
  }
3557
3595
  throw new Error(`${name} is not an atomic scalar field? Inconceivable!`);
@@ -3744,10 +3782,8 @@ class QueryModel {
3744
3782
  const struct = this.getStructByName(explore);
3745
3783
  let indexStar = [];
3746
3784
  for (const [fn, fv] of struct.nameMap) {
3747
- if (!(fv instanceof QueryFieldStruct)) {
3748
- if (isScalarField(fv) && fv.includeInWildcard()) {
3749
- indexStar.push({ type: 'fieldref', path: [fn] });
3750
- }
3785
+ if (isScalarField(fv) && fv.includeInWildcard()) {
3786
+ indexStar.push({ type: 'fieldref', path: [fn] });
3751
3787
  }
3752
3788
  }
3753
3789
  indexStar = indexStar.sort((a, b) => a.path[0].localeCompare(b.path[0]));
@@ -154,15 +154,15 @@ export interface MalloyTypecastExpr extends ExprE {
154
154
  node: 'cast';
155
155
  safe: boolean;
156
156
  e: Expr;
157
- dstType: LeafAtomicTypeDef;
158
- srcType?: LeafAtomicTypeDef;
157
+ dstType: BasicAtomicTypeDef;
158
+ srcType?: BasicAtomicTypeDef;
159
159
  }
160
160
  interface RawTypeCastExpr extends ExprE {
161
161
  node: 'cast';
162
162
  safe: boolean;
163
163
  e: Expr;
164
164
  dstSQLType: string;
165
- srcType?: LeafAtomicTypeDef;
165
+ srcType?: BasicAtomicTypeDef;
166
166
  }
167
167
  export type TypecastExpr = MalloyTypecastExpr | RawTypeCastExpr;
168
168
  export declare function isRawCast(te: TypecastExpr): te is RawTypeCastExpr;
@@ -371,7 +371,7 @@ export interface FieldBase extends NamedObject, Expression, ResultMetadata {
371
371
  annotation?: Annotation;
372
372
  accessModifier?: NonDefaultAccessModifierLabel | undefined;
373
373
  }
374
- export declare function fieldIsIntrinsic(f: FieldDef): boolean;
374
+ export declare function fieldIsIntrinsic(f: FieldDef): f is AtomicFieldDef;
375
375
  export interface StringTypeDef {
376
376
  type: 'string';
377
377
  bucketFilter?: string;
@@ -396,11 +396,11 @@ export interface NativeUnsupportedTypeDef {
396
396
  rawType?: string;
397
397
  }
398
398
  export type NativeUnsupportedFieldDef = NativeUnsupportedTypeDef & AtomicFieldDef;
399
- export interface ScalarArrayTypeDef {
399
+ export interface BasicArrayTypeDef {
400
400
  type: 'array';
401
401
  elementTypeDef: Exclude<AtomicTypeDef, RecordTypeDef>;
402
402
  }
403
- export interface ScalarArrayDef extends ScalarArrayTypeDef, StructDefBase, JoinBase, FieldBase {
403
+ export interface BasicArrayDef extends BasicArrayTypeDef, StructDefBase, JoinBase, FieldBase {
404
404
  type: 'array';
405
405
  join: 'many';
406
406
  }
@@ -426,11 +426,11 @@ export interface RepeatedRecordDef extends RepeatedRecordTypeDef, StructDefBase,
426
426
  type: 'array';
427
427
  join: 'many';
428
428
  }
429
- export type ArrayTypeDef = ScalarArrayTypeDef | RepeatedRecordTypeDef;
430
- export type ArrayDef = ScalarArrayDef | RepeatedRecordDef;
429
+ export type ArrayTypeDef = BasicArrayTypeDef | RepeatedRecordTypeDef;
430
+ export type ArrayDef = BasicArrayDef | RepeatedRecordDef;
431
431
  export declare function isRepeatedRecordFunctionParam(paramT: FunctionParameterTypeDef): paramT is RepeatedRecordFunctionParameterTypeDef;
432
432
  export declare function isRepeatedRecord(fd: FieldDef | QueryFieldDef | StructDef | AtomicTypeDef): fd is RepeatedRecordTypeDef;
433
- export declare function isScalarArray(td: AtomicTypeDef | FieldDef | QueryFieldDef | StructDef): td is ScalarArrayTypeDef;
433
+ export declare function isBasicArray(td: AtomicTypeDef | FieldDef | QueryFieldDef | StructDef): td is BasicArrayTypeDef;
434
434
  export interface ErrorTypeDef {
435
435
  type: 'error';
436
436
  }
@@ -646,7 +646,7 @@ export interface NonAtomicTypeDef {
646
646
  }
647
647
  export type ExpressionValueType = AtomicFieldType | NonAtomicType;
648
648
  export type ExpressionValueTypeDef = AtomicTypeDef | NonAtomicTypeDef;
649
- export type LeafExpressionType = Exclude<ExpressionValueType, JoinElementType | 'turtle'>;
649
+ export type BasicExpressionType = Exclude<ExpressionValueType, JoinElementType | 'turtle'>;
650
650
  export type TypeInfo = {
651
651
  expressionType: ExpressionType;
652
652
  evalSpace: EvalSpace;
@@ -658,11 +658,11 @@ export type FunctionParamTypeDesc = FunctionParameterTypeDef & {
658
658
  expressionType: ExpressionType | undefined;
659
659
  evalSpace: EvalSpace;
660
660
  };
661
- interface ScalarArrayExtTypeDef<TypeExtensions> {
661
+ interface BasicArrayExtTypeDef<TypeExtensions> {
662
662
  type: 'array';
663
663
  elementTypeDef: Exclude<ExpressionValueExtTypeDef<TypeExtensions>, RecordExtTypeDef<TypeExtensions>>;
664
664
  }
665
- type ExpressionValueExtTypeDef<TypeExtensions> = AtomicTypeDef | NonAtomicTypeDef | ScalarArrayExtTypeDef<TypeExtensions> | RecordExtTypeDef<TypeExtensions> | RepeatedRecordExtTypeDef<TypeExtensions> | TypeExtensions;
665
+ type ExpressionValueExtTypeDef<TypeExtensions> = AtomicTypeDef | NonAtomicTypeDef | BasicArrayExtTypeDef<TypeExtensions> | RecordExtTypeDef<TypeExtensions> | RepeatedRecordExtTypeDef<TypeExtensions> | TypeExtensions;
666
666
  interface RecordExtTypeDef<TypeExtensions> {
667
667
  type: 'record';
668
668
  fields: ExtFieldDef<TypeExtensions>[];
@@ -674,17 +674,17 @@ interface RepeatedRecordExtTypeDef<TypeExtensions> {
674
674
  fields: ExtFieldDef<TypeExtensions>[];
675
675
  }
676
676
  type FunctionReturnTypeExtensions = GenericTypeDef;
677
- export type ScalarArrayFunctionReturnTypeDef = ScalarArrayExtTypeDef<FunctionReturnTypeExtensions>;
677
+ export type BasicArrayFunctionReturnTypeDef = BasicArrayExtTypeDef<FunctionReturnTypeExtensions>;
678
678
  export type FunctionReturnFieldDef = ExtFieldDef<FunctionReturnTypeExtensions>;
679
679
  export type RecordFunctionReturnTypeDef = RecordExtTypeDef<FunctionReturnTypeExtensions>;
680
680
  export type RepeatedRecordFunctionReturnTypeDef = RepeatedRecordExtTypeDef<FunctionReturnTypeExtensions>;
681
681
  type FunctionParameterTypeExtensions = GenericTypeDef | AnyTypeDef;
682
- export type ScalarArrayFunctionParameterTypeDef = ScalarArrayExtTypeDef<FunctionParameterTypeExtensions>;
682
+ export type BasicArrayFunctionParameterTypeDef = BasicArrayExtTypeDef<FunctionParameterTypeExtensions>;
683
683
  export type FunctionParameterFieldDef = ExtFieldDef<FunctionParameterTypeExtensions>;
684
684
  export type RecordFunctionParameterTypeDef = RecordExtTypeDef<FunctionParameterTypeExtensions>;
685
685
  export type RepeatedRecordFunctionParameterTypeDef = RepeatedRecordExtTypeDef<FunctionParameterTypeExtensions>;
686
686
  type FunctionGenericTypeExtensions = AnyTypeDef;
687
- export type ScalarArrayFunctionGenericTypeDef = ScalarArrayExtTypeDef<FunctionGenericTypeExtensions>;
687
+ export type BasicArrayFunctionGenericTypeDef = BasicArrayExtTypeDef<FunctionGenericTypeExtensions>;
688
688
  export type FunctionGenericFieldDef = ExtFieldDef<FunctionGenericTypeExtensions>;
689
689
  export type RecordFunctionGenericTypeDef = RecordExtTypeDef<FunctionGenericTypeExtensions>;
690
690
  export type RepeatedRecordFunctionGenericTypeDef = RepeatedRecordExtTypeDef<FunctionGenericTypeExtensions>;
@@ -740,12 +740,12 @@ export interface ConnectionDef extends NamedObject {
740
740
  type: 'connection';
741
741
  }
742
742
  export type TemporalTypeDef = DateTypeDef | TimestampTypeDef;
743
- export type LeafAtomicTypeDef = StringTypeDef | TemporalTypeDef | NumberTypeDef | BooleanTypeDef | JSONTypeDef | NativeUnsupportedTypeDef | ErrorTypeDef;
744
- export type LeafAtomicDef = LeafAtomicTypeDef & FieldBase;
745
- export type AtomicTypeDef = LeafAtomicTypeDef | ScalarArrayTypeDef | RecordTypeDef | RepeatedRecordTypeDef;
746
- export type AtomicFieldDef = LeafAtomicDef | ScalarArrayDef | RecordDef | RepeatedRecordDef;
747
- export declare function isLeafAtomic(fd: FieldDef | QueryFieldDef | AtomicTypeDef): fd is LeafAtomicDef;
748
- export type FieldDef = LeafAtomicDef | JoinFieldDef | TurtleDef;
743
+ export type BasicAtomicTypeDef = StringTypeDef | TemporalTypeDef | NumberTypeDef | BooleanTypeDef | JSONTypeDef | NativeUnsupportedTypeDef | ErrorTypeDef;
744
+ export type BasicAtomicDef = BasicAtomicTypeDef & FieldBase;
745
+ export type AtomicTypeDef = BasicAtomicTypeDef | BasicArrayTypeDef | RecordTypeDef | RepeatedRecordTypeDef;
746
+ export type AtomicFieldDef = BasicAtomicDef | BasicArrayDef | RecordDef | RepeatedRecordDef;
747
+ export declare function isBasicAtomic(fd: FieldDef | QueryFieldDef | AtomicTypeDef): fd is BasicAtomicDef;
748
+ export type FieldDef = BasicAtomicDef | JoinFieldDef | TurtleDef;
749
749
  export type FieldDefType = AtomicFieldType | 'turtle' | JoinElementType;
750
750
  export interface RefToField {
751
751
  type: 'fieldref';
@@ -879,7 +879,7 @@ type UTD = AtomicTypeDef | TypedDef | FunctionParameterTypeDef | FunctionReturnT
879
879
  */
880
880
  export declare const TD: {
881
881
  isAtomic(td: UTD): td is AtomicTypeDef;
882
- isLeafAtomic(td: UTD): td is LeafAtomicTypeDef;
882
+ isBasicAtomic(td: UTD): td is BasicAtomicTypeDef;
883
883
  isString: (td: UTD) => td is StringTypeDef;
884
884
  isNumber: (td: UTD) => td is NumberTypeDef;
885
885
  isBoolean: (td: UTD) => td is BooleanTypeDef;
@@ -23,8 +23,8 @@
23
23
  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24
24
  */
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.sourceBase = exports.isSegmentSQL = exports.isIndexSegment = exports.isRawSegment = exports.isSamplingEnable = exports.isSamplingPercent = exports.isSamplingRows = exports.isQuerySegment = exports.isProjectSegment = exports.isPartialSegment = exports.isReduceSegment = exports.structHasErrors = exports.segmentHasErrors = exports.refIsStructDef = exports.ValueType = exports.isExtractUnit = exports.isTimestampUnit = exports.isDateUnit = exports.isJoinedSource = exports.isJoined = exports.isJoinable = exports.isMatrixOperation = exports.isScalarArray = exports.isRepeatedRecord = exports.isRepeatedRecordFunctionParam = exports.mkArrayDef = exports.mkFieldDef = exports.fieldIsIntrinsic = exports.isCastType = exports.canOrderBy = exports.isAtomicFieldType = exports.isTemporalType = exports.hasExpression = exports.maxOfExpressionTypes = exports.maxExpressionType = exports.isExpressionTypeLEQ = exports.expressionIsAnalytic = exports.expressionIsCalculation = exports.expressionInvolvesAggregate = exports.expressionIsUngroupedAggregate = exports.expressionIsAggregate = exports.expressionIsScalar = exports.paramHasValue = exports.isFilterExprType = exports.isRawCast = exports.mkTemporal = exports.isAsymmetricExpr = exports.exprIsLeaf = exports.exprHasE = exports.exprHasKids = void 0;
27
- exports.TD = exports.isValueDate = exports.isValueTimestamp = exports.isValueBoolean = exports.isValueNumber = exports.isValueString = exports.isAtomic = exports.isTurtle = exports.getIdentifier = exports.isLeafAtomic = exports.mergeEvalSpaces = exports.isLiteral = exports.isBaseTable = exports.isSourceDef = void 0;
26
+ exports.sourceBase = exports.isSegmentSQL = exports.isIndexSegment = exports.isRawSegment = exports.isSamplingEnable = exports.isSamplingPercent = exports.isSamplingRows = exports.isQuerySegment = exports.isProjectSegment = exports.isPartialSegment = exports.isReduceSegment = exports.structHasErrors = exports.segmentHasErrors = exports.refIsStructDef = exports.ValueType = exports.isExtractUnit = exports.isTimestampUnit = exports.isDateUnit = exports.isJoinedSource = exports.isJoined = exports.isJoinable = exports.isMatrixOperation = exports.isBasicArray = exports.isRepeatedRecord = exports.isRepeatedRecordFunctionParam = exports.mkArrayDef = exports.mkFieldDef = exports.fieldIsIntrinsic = exports.isCastType = exports.canOrderBy = exports.isAtomicFieldType = exports.isTemporalType = exports.hasExpression = exports.maxOfExpressionTypes = exports.maxExpressionType = exports.isExpressionTypeLEQ = exports.expressionIsAnalytic = exports.expressionIsCalculation = exports.expressionInvolvesAggregate = exports.expressionIsUngroupedAggregate = exports.expressionIsAggregate = exports.expressionIsScalar = exports.paramHasValue = exports.isFilterExprType = exports.isRawCast = exports.mkTemporal = exports.isAsymmetricExpr = exports.exprIsLeaf = exports.exprHasE = exports.exprHasKids = void 0;
27
+ exports.TD = exports.isValueDate = exports.isValueTimestamp = exports.isValueBoolean = exports.isValueNumber = exports.isValueString = exports.isAtomic = exports.isTurtle = exports.getIdentifier = exports.isBasicAtomic = exports.mergeEvalSpaces = exports.isLiteral = exports.isBaseTable = exports.isSourceDef = void 0;
28
28
  function exprHasKids(e) {
29
29
  return 'kids' in e;
30
30
  }
@@ -187,7 +187,7 @@ function fieldIsIntrinsic(f) {
187
187
  }
188
188
  exports.fieldIsIntrinsic = fieldIsIntrinsic;
189
189
  function mkFieldDef(atd, name) {
190
- if (isScalarArray(atd)) {
190
+ if (isBasicArray(atd)) {
191
191
  return mkArrayDef(atd.elementTypeDef, name);
192
192
  }
193
193
  if (isRepeatedRecord(atd)) {
@@ -232,10 +232,10 @@ function isRepeatedRecord(fd) {
232
232
  return fd.type === 'array' && fd.elementTypeDef.type === 'record_element';
233
233
  }
234
234
  exports.isRepeatedRecord = isRepeatedRecord;
235
- function isScalarArray(td) {
235
+ function isBasicArray(td) {
236
236
  return td.type === 'array' && td.elementTypeDef.type !== 'record_element';
237
237
  }
238
- exports.isScalarArray = isScalarArray;
238
+ exports.isBasicArray = isBasicArray;
239
239
  function isMatrixOperation(x) {
240
240
  return ['left', 'right', 'full', 'inner'].includes(x);
241
241
  }
@@ -388,7 +388,7 @@ function mergeEvalSpaces(...evalSpaces) {
388
388
  return 'input';
389
389
  }
390
390
  exports.mergeEvalSpaces = mergeEvalSpaces;
391
- function isLeafAtomic(fd) {
391
+ function isBasicAtomic(fd) {
392
392
  return (fd.type === 'string' ||
393
393
  isTemporalType(fd.type) ||
394
394
  fd.type === 'number' ||
@@ -397,7 +397,7 @@ function isLeafAtomic(fd) {
397
397
  fd.type === 'sql native' ||
398
398
  fd.type === 'error');
399
399
  }
400
- exports.isLeafAtomic = isLeafAtomic;
400
+ exports.isBasicAtomic = isBasicAtomic;
401
401
  /** Get the output name for a NamedObject */
402
402
  function getIdentifier(n) {
403
403
  if (n.as !== undefined) {
@@ -442,8 +442,8 @@ exports.TD = {
442
442
  isAtomic(td) {
443
443
  return td !== undefined && isAtomicFieldType(td.type);
444
444
  },
445
- isLeafAtomic(td) {
446
- return td !== undefined && isLeafAtomic({ type: td.type });
445
+ isBasicAtomic(td) {
446
+ return td !== undefined && isBasicAtomic({ type: td.type });
447
447
  },
448
448
  isString: (td) => (td === null || td === void 0 ? void 0 : td.type) === 'string',
449
449
  isNumber: (td) => (td === null || td === void 0 ? void 0 : td.type) === 'number',
package/dist/to_stable.js CHANGED
@@ -220,7 +220,7 @@ function getResultStructMetadataAnnotation(field, resultMetadata) {
220
220
  }
221
221
  exports.getResultStructMetadataAnnotation = getResultStructMetadataAnnotation;
222
222
  function typeDefToType(field) {
223
- if ((0, model_1.isLeafAtomic)(field)) {
223
+ if ((0, model_1.isBasicAtomic)(field)) {
224
224
  switch (field.type) {
225
225
  case 'string':
226
226
  return { kind: 'string_type' };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@malloydata/malloy",
3
- "version": "0.0.253-dev250330190957",
3
+ "version": "0.0.253-dev250401001016",
4
4
  "license": "MIT",
5
5
  "exports": {
6
6
  ".": "./dist/index.js",
@@ -41,9 +41,9 @@
41
41
  "generate-version-file": "VERSION=$(npm pkg get version --workspaces=false | tr -d \\\")\necho \"// generated with 'generate-version-file' script; do not edit manually\\nexport const MALLOY_VERSION = '$VERSION';\" > src/version.ts"
42
42
  },
43
43
  "dependencies": {
44
- "@malloydata/malloy-filter": "^0.0.253-dev250330190957",
45
- "@malloydata/malloy-interfaces": "^0.0.253-dev250330190957",
46
- "@malloydata/malloy-tag": "^0.0.253-dev250330190957",
44
+ "@malloydata/malloy-filter": "^0.0.253-dev250401001016",
45
+ "@malloydata/malloy-interfaces": "^0.0.253-dev250401001016",
46
+ "@malloydata/malloy-tag": "^0.0.253-dev250401001016",
47
47
  "antlr4ts": "^0.5.0-alpha.4",
48
48
  "assert": "^2.0.0",
49
49
  "jest-diff": "^29.6.2",