@malloydata/malloy 0.0.304 → 0.0.306

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.
Files changed (74) hide show
  1. package/dist/dialect/dialect.d.ts +1 -1
  2. package/dist/dialect/duckdb/duckdb.d.ts +1 -1
  3. package/dist/dialect/duckdb/duckdb.js +2 -6
  4. package/dist/dialect/mysql/mysql.d.ts +1 -1
  5. package/dist/dialect/mysql/mysql.js +2 -6
  6. package/dist/dialect/postgres/postgres.d.ts +1 -1
  7. package/dist/dialect/postgres/postgres.js +2 -6
  8. package/dist/dialect/snowflake/snowflake.d.ts +1 -1
  9. package/dist/dialect/snowflake/snowflake.js +2 -5
  10. package/dist/dialect/standardsql/standardsql.d.ts +1 -1
  11. package/dist/dialect/standardsql/standardsql.js +2 -6
  12. package/dist/dialect/trino/trino.d.ts +1 -1
  13. package/dist/dialect/trino/trino.js +2 -6
  14. package/dist/index.d.ts +1 -1
  15. package/dist/index.js +2 -3
  16. package/dist/lang/ast/expressions/expr-aggregate-function.js +12 -2
  17. package/dist/lang/ast/expressions/expr-count.js +3 -1
  18. package/dist/lang/ast/expressions/expr-func.js +34 -10
  19. package/dist/lang/ast/expressions/expr-props.js +1 -1
  20. package/dist/lang/ast/expressions/expr-ungroup.js +7 -3
  21. package/dist/lang/ast/expressions/function-ordering.d.ts +19 -5
  22. package/dist/lang/ast/expressions/function-ordering.js +61 -9
  23. package/dist/lang/ast/field-space/include-utils.js +1 -1
  24. package/dist/lang/ast/field-space/index-field-space.js +3 -1
  25. package/dist/lang/ast/field-space/query-spaces.js +20 -11
  26. package/dist/lang/ast/query-builders/index-builder.js +1 -1
  27. package/dist/lang/ast/query-builders/reduce-builder.js +1 -1
  28. package/dist/lang/ast/query-elements/query-arrow.js +14 -4
  29. package/dist/lang/ast/query-elements/query-base.d.ts +1 -0
  30. package/dist/lang/ast/query-elements/query-base.js +14 -4
  31. package/dist/lang/ast/query-elements/query-refine.js +2 -0
  32. package/dist/lang/ast/query-properties/drill.js +1 -1
  33. package/dist/lang/ast/source-properties/join.js +6 -2
  34. package/dist/lang/ast/statements/define-source.js +1 -1
  35. package/dist/lang/ast/types/expr-value.js +1 -1
  36. package/dist/lang/ast/view-elements/reference-view.js +4 -1
  37. package/dist/lang/ast/view-elements/refine-utils.js +1 -1
  38. package/dist/{model/composite_source_utils.d.ts → lang/composite-source-utils.d.ts} +4 -17
  39. package/dist/{model/composite_source_utils.js → lang/composite-source-utils.js} +274 -44
  40. package/dist/lang/test/parse-expects.d.ts +1 -1
  41. package/dist/lang/test/parse-expects.js +6 -2
  42. package/dist/lang/test/test-translator.js +1 -1
  43. package/dist/malloy.js +1 -1
  44. package/dist/model/expression_compiler.d.ts +26 -0
  45. package/dist/model/expression_compiler.js +774 -0
  46. package/dist/model/field_instance.d.ts +108 -0
  47. package/dist/model/field_instance.js +520 -0
  48. package/dist/model/index.d.ts +5 -1
  49. package/dist/model/index.js +25 -4
  50. package/dist/model/join_instance.d.ts +18 -0
  51. package/dist/model/join_instance.js +71 -0
  52. package/dist/model/malloy_types.d.ts +48 -2
  53. package/dist/model/malloy_types.js +39 -1
  54. package/dist/model/query_model.d.ts +2 -0
  55. package/dist/model/query_model.js +7 -0
  56. package/dist/model/query_model_contract.d.ts +32 -0
  57. package/dist/model/query_model_contract.js +7 -0
  58. package/dist/model/query_model_impl.d.ts +30 -0
  59. package/dist/model/query_model_impl.js +266 -0
  60. package/dist/model/query_node.d.ts +132 -0
  61. package/dist/model/query_node.js +638 -0
  62. package/dist/model/query_query.d.ts +86 -0
  63. package/dist/model/query_query.js +1724 -0
  64. package/dist/model/sql_block.js +2 -2
  65. package/dist/model/stage_writer.d.ts +25 -0
  66. package/dist/model/stage_writer.js +120 -0
  67. package/dist/model/utils.d.ts +18 -1
  68. package/dist/model/utils.js +66 -1
  69. package/dist/to_stable.js +3 -4
  70. package/dist/version.d.ts +1 -1
  71. package/dist/version.js +1 -1
  72. package/package.json +4 -4
  73. package/dist/model/malloy_query.d.ts +0 -391
  74. package/dist/model/malloy_query.js +0 -3926
@@ -70,7 +70,7 @@ export declare abstract class Dialect {
70
70
  abstract quoteTablePath(tablePath: string): string;
71
71
  abstract sqlGroupSetTable(groupSetCount: number): string;
72
72
  abstract sqlAnyValue(groupSet: number, fieldName: string): string;
73
- abstract sqlAggregateTurtle(groupSet: number, fieldList: DialectFieldList, orderBy: string | undefined, limit: number | undefined): string;
73
+ abstract sqlAggregateTurtle(groupSet: number, fieldList: DialectFieldList, orderBy: string | undefined): string;
74
74
  abstract sqlAnyValueTurtle(groupSet: number, fieldList: DialectFieldList): string;
75
75
  abstract sqlAnyValueLastTurtle(name: string, groupSet: number, sqlName: string): string;
76
76
  abstract sqlCoaleseMeasuresInline(groupSet: number, fieldList: DialectFieldList): string;
@@ -28,7 +28,7 @@ export declare class DuckDBDialect extends PostgresBase {
28
28
  sqlAnyValue(groupSet: number, fieldName: string): string;
29
29
  sqlLiteralNumber(literal: string): string;
30
30
  mapFields(fieldList: DialectFieldList): string;
31
- sqlAggregateTurtle(groupSet: number, fieldList: DialectFieldList, orderBy: string | undefined, limit: number | undefined): string;
31
+ sqlAggregateTurtle(groupSet: number, fieldList: DialectFieldList, orderBy: string | undefined): string;
32
32
  sqlAnyValueTurtle(groupSet: number, fieldList: DialectFieldList): string;
33
33
  sqlAnyValueLastTurtle(name: string, groupSet: number, sqlName: string): string;
34
34
  sqlCoaleseMeasuresInline(groupSet: number, fieldList: DialectFieldList): string;
@@ -96,15 +96,11 @@ class DuckDBDialect extends pg_impl_1.PostgresBase {
96
96
  mapFields(fieldList) {
97
97
  return fieldList.join(', ');
98
98
  }
99
- sqlAggregateTurtle(groupSet, fieldList, orderBy, limit) {
100
- let tail = '';
101
- if (limit !== undefined) {
102
- tail += `[1:${limit}]`;
103
- }
99
+ sqlAggregateTurtle(groupSet, fieldList, orderBy) {
104
100
  const fields = fieldList
105
101
  .map(f => `\n ${f.sqlOutputName}: ${f.sqlExpression}`)
106
102
  .join(', ');
107
- return `COALESCE(LIST({${fields}} ${orderBy}) FILTER (WHERE group_set=${groupSet})${tail},[])`;
103
+ return `COALESCE(LIST({${fields}} ${orderBy}) FILTER (WHERE group_set=${groupSet}),[])`;
108
104
  }
109
105
  sqlAnyValueTurtle(groupSet, fieldList) {
110
106
  const fields = fieldList
@@ -37,7 +37,7 @@ export declare class MySQLDialect extends Dialect {
37
37
  sqlGroupSetTable(groupSetCount: number): string;
38
38
  sqlAnyValue(_groupSet: number, fieldName: string): string;
39
39
  private mapFields;
40
- sqlAggregateTurtle(groupSet: number, fieldList: DialectFieldList, orderBy: string | undefined, limit: number | undefined): string;
40
+ sqlAggregateTurtle(groupSet: number, fieldList: DialectFieldList, orderBy: string | undefined): string;
41
41
  sqlAnyValueTurtle(groupSet: number, fieldList: DialectFieldList): string;
42
42
  sqlAnyValueLastTurtle(name: string, groupSet: number, sqlName: string): string;
43
43
  sqlCoaleseMeasuresInline(groupSet: number, fieldList: DialectFieldList): string;
@@ -135,8 +135,8 @@ class MySQLDialect extends dialect_1.Dialect {
135
135
  mapFields(fieldList) {
136
136
  return fieldList.map(f => `"${f.rawName}", ${f.sqlExpression}`).join(', ');
137
137
  }
138
- sqlAggregateTurtle(groupSet, fieldList, orderBy, limit) {
139
- const separator = limit ? ',xrmmex' : ',';
138
+ sqlAggregateTurtle(groupSet, fieldList, orderBy) {
139
+ const separator = ',';
140
140
  let gc = `GROUP_CONCAT(
141
141
  IF(group_set=${groupSet},
142
142
  JSON_OBJECT(${this.mapFields(fieldList)})
@@ -145,10 +145,6 @@ class MySQLDialect extends dialect_1.Dialect {
145
145
  ${orderBy}
146
146
  SEPARATOR '${separator}'
147
147
  )`;
148
- if (limit) {
149
- gc = `SUBSTRING_INDEX(${gc}, '${separator}', ${limit})`;
150
- gc = `REPLACE(${gc},'${separator}',',')`;
151
- }
152
148
  gc = `COALESCE(JSON_EXTRACT(CONCAT('[',${gc},']'),'$'),JSON_ARRAY())`;
153
149
  return gc;
154
150
  }
@@ -30,7 +30,7 @@ export declare class PostgresDialect extends PostgresBase {
30
30
  sqlGroupSetTable(groupSetCount: number): string;
31
31
  sqlAnyValue(groupSet: number, fieldName: string): string;
32
32
  mapFields(fieldList: DialectFieldList): string;
33
- sqlAggregateTurtle(groupSet: number, fieldList: DialectFieldList, orderBy: string | undefined, limit: number | undefined): string;
33
+ sqlAggregateTurtle(groupSet: number, fieldList: DialectFieldList, orderBy: string | undefined): string;
34
34
  sqlAnyValueTurtle(groupSet: number, fieldList: DialectFieldList): string;
35
35
  sqlAnyValueLastTurtle(name: string, groupSet: number, sqlName: string): string;
36
36
  sqlCoaleseMeasuresInline(groupSet: number, fieldList: DialectFieldList): string;
@@ -113,13 +113,9 @@ class PostgresDialect extends pg_impl_1.PostgresBase {
113
113
  .map(f => `\n ${f.sqlExpression}${f.typeDef.type === 'number' ? `::${this.defaultNumberType}` : ''} as ${f.sqlOutputName}`)
114
114
  .join(', ');
115
115
  }
116
- sqlAggregateTurtle(groupSet, fieldList, orderBy, limit) {
117
- let tail = '';
118
- if (limit !== undefined) {
119
- tail += `[1:${limit}]`;
120
- }
116
+ sqlAggregateTurtle(groupSet, fieldList, orderBy) {
121
117
  const fields = this.mapFields(fieldList);
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)`;
118
+ return `COALESCE(TO_JSONB((ARRAY_AGG((SELECT TO_JSONB(__x) FROM (SELECT ${fields}\n ) as __x) ${orderBy} ) FILTER (WHERE group_set=${groupSet}))),'[]'::JSONB)`;
123
119
  }
124
120
  sqlAnyValueTurtle(groupSet, fieldList) {
125
121
  const fields = fieldList
@@ -30,7 +30,7 @@ export declare class SnowflakeDialect extends Dialect {
30
30
  sqlAnyValue(groupSet: number, fieldName: string): string;
31
31
  mapFields(fieldList: DialectFieldList): string;
32
32
  mapFieldsForObjectConstruct(fieldList: DialectFieldList): string;
33
- sqlAggregateTurtle(groupSet: number, fieldList: DialectFieldList, orderBy: string | undefined, limit: number | undefined): string;
33
+ sqlAggregateTurtle(groupSet: number, fieldList: DialectFieldList, orderBy: string | undefined): string;
34
34
  sqlAnyValueTurtle(groupSet: number, fieldList: DialectFieldList): string;
35
35
  sqlAnyValueLastTurtle(name: string, groupSet: number, sqlName: string): string;
36
36
  sqlCoaleseMeasuresInline(groupSet: number, fieldList: DialectFieldList): string;
@@ -119,14 +119,11 @@ class SnowflakeDialect extends dialect_1.Dialect {
119
119
  .map(f => `'${f.rawName}', (${f.sqlExpression})`)
120
120
  .join(', ');
121
121
  }
122
- sqlAggregateTurtle(groupSet, fieldList, orderBy, limit) {
122
+ sqlAggregateTurtle(groupSet, fieldList, orderBy) {
123
123
  const fields = this.mapFieldsForObjectConstruct(fieldList);
124
124
  const orderByClause = orderBy ? ` WITHIN GROUP (${orderBy})` : '';
125
125
  const aggClause = `ARRAY_AGG(CASE WHEN group_set=${groupSet} THEN OBJECT_CONSTRUCT_KEEP_NULL(${fields}) END)${orderByClause}`;
126
- if (limit === undefined) {
127
- return `COALESCE(${aggClause}, [])`;
128
- }
129
- return `COALESCE(ARRAY_SLICE(${aggClause}, 0, ${limit}), [])`;
126
+ return `COALESCE(${aggClause}, [])`;
130
127
  }
131
128
  sqlAnyValueTurtle(groupSet, fieldList) {
132
129
  const fields = this.mapFieldsForObjectConstruct(fieldList);
@@ -31,7 +31,7 @@ export declare class StandardSQLDialect extends Dialect {
31
31
  sqlGroupSetTable(groupSetCount: number): string;
32
32
  sqlAnyValue(groupSet: number, fieldName: string): string;
33
33
  sqlOrderBy(orderTerms: string[], obr?: OrderByRequest): string;
34
- sqlAggregateTurtle(groupSet: number, fieldList: DialectFieldList, orderBy: string | undefined, limit: number | undefined): string;
34
+ sqlAggregateTurtle(groupSet: number, fieldList: DialectFieldList, orderBy: string | undefined): string;
35
35
  sqlAnyValueTurtle(groupSet: number, fieldList: DialectFieldList): string;
36
36
  sqlAnyValueLastTurtle(name: string, groupSet: number, sqlName: string): string;
37
37
  sqlCoaleseMeasuresInline(groupSet: number, fieldList: DialectFieldList): string;
@@ -117,15 +117,11 @@ class StandardSQLDialect extends dialect_1.Dialect {
117
117
  return `ORDER BY ${orderTerms.map(t => `${t} NULLS LAST`).join(',')}`;
118
118
  }
119
119
  // can array agg or any_value a struct...
120
- sqlAggregateTurtle(groupSet, fieldList, orderBy, limit) {
121
- let tail = '';
122
- if (limit !== undefined) {
123
- tail += ` LIMIT ${limit}`;
124
- }
120
+ sqlAggregateTurtle(groupSet, fieldList, orderBy) {
125
121
  const fields = fieldList
126
122
  .map(f => `\n ${f.sqlExpression} as ${f.sqlOutputName}`)
127
123
  .join(', ');
128
- return `ARRAY_AGG(CASE WHEN group_set=${groupSet} THEN STRUCT(${fields}\n ) END IGNORE NULLS ${orderBy} ${tail})`;
124
+ return `ARRAY_AGG(CASE WHEN group_set=${groupSet} THEN STRUCT(${fields}\n ) END IGNORE NULLS ${orderBy})`;
129
125
  }
130
126
  sqlAnyValueTurtle(groupSet, fieldList) {
131
127
  const fields = fieldList
@@ -35,7 +35,7 @@ export declare class TrinoDialect extends PostgresBase {
35
35
  exprToSQL(qi: QueryInfo, df: Expr): string | undefined;
36
36
  sqlAnyValue(groupSet: number, fieldName: string): string;
37
37
  buildTypeExpression(fieldList: DialectFieldList): string;
38
- sqlAggregateTurtle(groupSet: number, fieldList: DialectFieldList, orderBy: string | undefined, limit: number | undefined): string;
38
+ sqlAggregateTurtle(groupSet: number, fieldList: DialectFieldList, orderBy: string | undefined): string;
39
39
  sqlAnyValueTurtle(groupSet: number, fieldList: DialectFieldList): string;
40
40
  sqlAnyValueLastTurtle(name: string, groupSet: number, sqlName: string): string;
41
41
  sqlCoaleseMeasuresInline(groupSet: number, fieldList: DialectFieldList): string;
@@ -227,14 +227,10 @@ class TrinoDialect extends pg_impl_1.PostgresBase {
227
227
  .join(', \n');
228
228
  }
229
229
  // can array agg or any_value a struct...
230
- sqlAggregateTurtle(groupSet, fieldList, orderBy, limit) {
230
+ sqlAggregateTurtle(groupSet, fieldList, orderBy) {
231
231
  const expressions = fieldList.map(f => f.sqlExpression).join(',\n ');
232
232
  const definitions = this.buildTypeExpression(fieldList);
233
- let ret = `ARRAY_AGG(CAST(ROW(${expressions}) AS ROW(${definitions})) ${orderBy}) FILTER (WHERE group_set=${groupSet})`;
234
- if (limit !== undefined) {
235
- ret = `SLICE(${ret}, 1, ${limit})`;
236
- }
237
- return ret;
233
+ return `ARRAY_AGG(CAST(ROW(${expressions}) AS ROW(${definitions})) ${orderBy}) FILTER (WHERE group_set=${groupSet})`;
238
234
  }
239
235
  sqlAnyValueTurtle(groupSet, fieldList) {
240
236
  const expressions = fieldList.map(f => f.sqlExpression).join(',\n ');
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
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, QueryResultDef, QueryRunStats, QueryScalar, 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, StringLiteralNode, ArrayLiteralNode, SourceComponentInfo, } from './model';
4
- export { isSourceDef, Segment, isBasicAtomic, isJoined, isJoinedSource, isSamplingEnable, isSamplingPercent, isSamplingRows, isRepeatedRecord, isBasicArray, mkArrayDef, mkFieldDef, expressionIsAggregate, expressionIsAnalytic, expressionIsCalculation, expressionIsScalar, expressionIsUngroupedAggregate, indent, composeSQLExpr, isTimestampUnit, isDateUnit, } from './model';
4
+ export { isSourceDef, isBasicAtomic, isJoined, isJoinedSource, isSamplingEnable, isSamplingPercent, isSamplingRows, isRepeatedRecord, isBasicArray, mkArrayDef, mkFieldDef, expressionIsAggregate, expressionIsAnalytic, expressionIsCalculation, expressionIsScalar, expressionIsUngroupedAggregate, indent, composeSQLExpr, isTimestampUnit, isDateUnit, } 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
@@ -33,8 +33,8 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.ConnectionRuntime = exports.AtomicFieldType = exports.Runtime = exports.Malloy = exports.Model = exports.MalloyTranslator = exports.malloyToQuery = 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.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;
37
- exports.annotationToTaglines = exports.annotationToTag = exports.sqlKey = exports.API = exports.extractMalloyObjectFromTag = exports.writeMalloyObjectToTag = exports.sourceDefToSourceInfo = 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 = exports.EmptyURLReader = exports.SingleConnectionRuntime = void 0;
36
+ exports.SingleConnectionRuntime = exports.ConnectionRuntime = exports.AtomicFieldType = exports.Runtime = exports.Malloy = exports.Model = exports.MalloyTranslator = exports.malloyToQuery = 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.isBasicAtomic = 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.annotationToTaglines = exports.annotationToTag = exports.sqlKey = exports.API = exports.extractMalloyObjectFromTag = exports.writeMalloyObjectToTag = exports.sourceDefToSourceInfo = 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 = exports.EmptyURLReader = void 0;
38
38
  /*
39
39
  * Copyright 2023 Google LLC
40
40
  *
@@ -83,7 +83,6 @@ 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, "Segment", { enumerable: true, get: function () { return model_1.Segment; } });
87
86
  Object.defineProperty(exports, "isBasicAtomic", { enumerable: true, get: function () { return model_1.isBasicAtomic; } });
88
87
  Object.defineProperty(exports, "isJoined", { enumerable: true, get: function () { return model_1.isJoined; } });
89
88
  Object.defineProperty(exports, "isJoinedSource", { enumerable: true, get: function () { return model_1.isJoinedSource; } });
@@ -106,7 +106,7 @@ class ExprAggregateFunction extends expression_def_1.ExpressionDef {
106
106
  at: this.source.location,
107
107
  },
108
108
  evalSpace: footType.evalSpace,
109
- fieldUsage: footType.fieldUsage,
109
+ fieldUsage: [{ path: this.source.path, at: this.source.location }],
110
110
  };
111
111
  structPath = this.source.path.slice(0, -1);
112
112
  // Here we handle a special case where you write `foo.agg()` and `foo` is a
@@ -176,8 +176,18 @@ class ExprAggregateFunction extends expression_def_1.ExpressionDef {
176
176
  if (structPath && structPath.length > 0) {
177
177
  f.structPath = structPath;
178
178
  }
179
+ const returnExpr = this.returns(exprVal);
180
+ if (!this.isSymmetricFunction()) {
181
+ if (returnExpr.fieldUsage === undefined) {
182
+ returnExpr.fieldUsage = [];
183
+ }
184
+ returnExpr.fieldUsage.push({
185
+ path: structPath || [],
186
+ uniqueKeyRequirement: { isCount: false },
187
+ });
188
+ }
179
189
  return {
180
- ...this.returns(exprVal),
190
+ ...returnExpr,
181
191
  expressionType: 'aggregate',
182
192
  value: f,
183
193
  evalSpace: 'output',
@@ -63,7 +63,9 @@ class ExprCount extends expr_aggregate_function_1.ExprAggregateFunction {
63
63
  expressionType: 'aggregate',
64
64
  value: ret,
65
65
  evalSpace: 'output',
66
- fieldUsage: [],
66
+ fieldUsage: [
67
+ { path: ret.structPath || [], uniqueKeyRequirement: { isCount: true } },
68
+ ],
67
69
  };
68
70
  }
69
71
  }
@@ -64,7 +64,7 @@ const expression_def_1 = require("../types/expression-def");
64
64
  const field_space_1 = require("../types/field-space");
65
65
  const utils_1 = require("../../../model/utils");
66
66
  const TDU = __importStar(require("../typedesc-utils"));
67
- const composite_source_utils_1 = require("../../../model/composite_source_utils");
67
+ const composite_source_utils_1 = require("../../composite-source-utils");
68
68
  class ExprFunc extends expression_def_1.ExpressionDef {
69
69
  constructor(name, args, isRaw, rawType, source) {
70
70
  super({ args: args });
@@ -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, _e;
114
+ var _a, _b, _c, _d;
115
115
  const argExprsWithoutImplicit = this.args.map(arg => arg.getExpression(fs));
116
116
  if (this.isRaw) {
117
117
  const funcCall = [`${this.name}(`];
@@ -156,7 +156,7 @@ class ExprFunc extends expression_def_1.ExpressionDef {
156
156
  at: this.source.location,
157
157
  },
158
158
  evalSpace: footType.evalSpace,
159
- fieldUsage: footType.fieldUsage,
159
+ fieldUsage: [{ path: this.source.path, at: this.source.location }],
160
160
  };
161
161
  structPath = this.source.path.slice(0, -1);
162
162
  }
@@ -232,11 +232,13 @@ class ExprFunc extends expression_def_1.ExpressionDef {
232
232
  structPath,
233
233
  };
234
234
  let funcCall = frag;
235
+ const isAnalytic = (0, malloy_types_1.expressionIsAnalytic)(overload.returnType.expressionType);
236
+ const isAsymmetric = !overload.isSymmetric;
237
+ const orderByUsage = [];
235
238
  // TODO add in an error if you use an asymmetric function in BQ
236
239
  // and the function uses joins
237
240
  // TODO add in an error if you use an illegal join pattern
238
241
  if ((props === null || props === void 0 ? void 0 : props.orderBys) && props.orderBys.length > 0) {
239
- const isAnalytic = (0, malloy_types_1.expressionIsAnalytic)(overload.returnType.expressionType);
240
242
  if (!isAnalytic) {
241
243
  if (!this.inExperiment('aggregate_order_by', true)) {
242
244
  props.orderBys[0].logError('aggregate-order-by-experiment-not-enabled', 'Enable experiment `aggregate_order_by` to use `order_by` with an aggregate function');
@@ -244,10 +246,17 @@ class ExprFunc extends expression_def_1.ExpressionDef {
244
246
  }
245
247
  if (overload.supportsOrderBy || isAnalytic) {
246
248
  const allowExpression = overload.supportsOrderBy !== 'only_default';
247
- const allObs = props.orderBys.flatMap(orderBy => isAnalytic
248
- ? orderBy.getAnalyticOrderBy(fs)
249
- : orderBy.getAggregateOrderBy(fs, allowExpression));
250
- frag.kids.orderBy = allObs;
249
+ const allOrderBy = [];
250
+ for (const ordering of props.orderBys) {
251
+ const { orderBy, fieldUsage } = isAnalytic
252
+ ? ordering.getAnalyticOrderBy(fs)
253
+ : ordering.getAggregateOrderBy(fs, allowExpression);
254
+ if (fieldUsage) {
255
+ orderByUsage.push(...fieldUsage);
256
+ }
257
+ allOrderBy.push(...orderBy);
258
+ }
259
+ frag.kids.orderBy = allOrderBy;
251
260
  }
252
261
  else {
253
262
  props.orderBys[0].logError('function-does-not-support-order-by', `Function \`${this.name}\` does not support \`order_by\``);
@@ -317,11 +326,14 @@ class ExprFunc extends expression_def_1.ExpressionDef {
317
326
  if (typeDesc.type === 'filter expression') {
318
327
  return this.loggedErrorExpr('filter-expression-error', 'Filter expressions cannot be used in sql_ functions');
319
328
  }
320
- sqlFunctionFieldUsage.push(...((_e = typeDesc.fieldUsage) !== null && _e !== void 0 ? _e : []));
321
329
  if (result.found.refType === 'parameter') {
322
330
  expr.push({ node: 'parameter', path: part.path });
323
331
  }
324
332
  else {
333
+ sqlFunctionFieldUsage.push({
334
+ path: part.path,
335
+ at: this.args[0].location,
336
+ });
325
337
  expr.push({
326
338
  node: 'field',
327
339
  // TODO when we have namespaces, this will need to be replaced with the resolved path
@@ -345,6 +357,17 @@ class ExprFunc extends expression_def_1.ExpressionDef {
345
357
  : (0, malloy_types_1.expressionIsScalar)(expressionType)
346
358
  ? maxEvalSpace
347
359
  : 'output';
360
+ const aggregateFunctionUsage = [];
361
+ if (isAsymmetric || isAnalytic) {
362
+ const funcUsage = { path: structPath || [], at: this.location };
363
+ if (isAsymmetric)
364
+ funcUsage.uniqueKeyRequirement = { isCount: false };
365
+ if (isAnalytic)
366
+ funcUsage.analyticFunctionUse = true;
367
+ aggregateFunctionUsage.push(funcUsage);
368
+ }
369
+ const fieldUsage = (0, composite_source_utils_1.mergeFieldUsage)(...argExprs.map(ae => ae.fieldUsage), orderByUsage, sqlFunctionFieldUsage, aggregateFunctionUsage);
370
+ const ungroupings = argExprs.reduce((ug, a) => { var _a; return (_a = a.ungroupings) !== null && _a !== void 0 ? _a : ug; }, []);
348
371
  // TODO consider if I can use `computedExprValue` here...
349
372
  // seems like the rules for the evalSpace is a bit different from normal though
350
373
  return {
@@ -353,7 +376,8 @@ class ExprFunc extends expression_def_1.ExpressionDef {
353
376
  expressionType,
354
377
  value: funcCall,
355
378
  evalSpace,
356
- fieldUsage: (0, composite_source_utils_1.mergeFieldUsage)(...argExprs.map(e => e.fieldUsage), sqlFunctionFieldUsage),
379
+ fieldUsage,
380
+ ungroupings,
357
381
  };
358
382
  }
359
383
  }
@@ -65,7 +65,7 @@ const partition_by_1 = require("./partition_by");
65
65
  const expr_value_1 = require("../types/expr-value");
66
66
  const expression_def_1 = require("../types/expression-def");
67
67
  const expr_func_1 = require("./expr-func");
68
- const composite_source_utils_1 = require("../../../model/composite_source_utils");
68
+ const composite_source_utils_1 = require("../../composite-source-utils");
69
69
  const grouped_by_1 = require("./grouped_by");
70
70
  class ExprProps extends expression_def_1.ExpressionDef {
71
71
  constructor(expr, statements) {
@@ -71,7 +71,7 @@ class ExprUngroup extends expression_def_1.ExpressionDef {
71
71
  this.elementType = 'ungroup';
72
72
  }
73
73
  getExpression(fs) {
74
- var _a, _b;
74
+ var _a;
75
75
  const exprVal = this.expr.getExpression(fs);
76
76
  if (!(0, malloy_types_1.expressionIsAggregate)(exprVal.expressionType)) {
77
77
  return this.expr.loggedErrorExpr('ungroup-of-non-aggregate', `${this.control}() expression must be an aggregate`);
@@ -117,17 +117,21 @@ class ExprUngroup extends expression_def_1.ExpressionDef {
117
117
  }
118
118
  ungroup.fields = dstFields;
119
119
  }
120
+ const fieldUsage = exprVal.fieldUsage;
120
121
  return {
121
122
  ...TDU.atomicDef(exprVal),
122
123
  expressionType: 'ungrouped_aggregate',
123
124
  value: ungroup,
124
125
  evalSpace: 'output',
125
- fieldUsage: exprVal.fieldUsage,
126
+ fieldUsage,
126
127
  ungroupings: [
127
128
  {
128
129
  requiresGroupBy: (_a = exprVal.requiresGroupBy) !== null && _a !== void 0 ? _a : [],
129
- fieldUsage: (_b = exprVal.fieldUsage) !== null && _b !== void 0 ? _b : [],
130
+ fieldUsage: fieldUsage !== null && fieldUsage !== void 0 ? fieldUsage : [],
130
131
  ungroupedFields: isExclude ? ungroupFields !== null && ungroupFields !== void 0 ? ungroupFields : [] : '*',
132
+ path: [],
133
+ exclude: isExclude,
134
+ refFields: ungroup.fields,
131
135
  },
132
136
  ],
133
137
  };
@@ -1,18 +1,32 @@
1
- import type { FunctionOrderBy as ModelFunctionOrderBy } from '../../../model/malloy_types';
1
+ import type { FieldUsage, FunctionOrderBy as ModelFunctionOrderBy } from '../../../model/malloy_types';
2
2
  import type { ExpressionDef } from '../types/expression-def';
3
3
  import type { FieldSpace } from '../types/field-space';
4
4
  import { ListOf, MalloyElement } from '../types/malloy-element';
5
+ type FieldUsageSummary = FieldUsage[] | undefined;
5
6
  export declare class FunctionOrderBy extends MalloyElement {
6
7
  readonly field?: ExpressionDef | undefined;
7
8
  readonly dir?: "asc" | "desc" | undefined;
8
9
  elementType: string;
9
10
  constructor(field?: ExpressionDef | undefined, dir?: "asc" | "desc" | undefined);
10
- getAnalyticOrderBy(fs: FieldSpace): ModelFunctionOrderBy;
11
- getAggregateOrderBy(fs: FieldSpace, allowExpression: boolean): ModelFunctionOrderBy;
11
+ computeAnalyticOrderBy(fs: FieldSpace): {
12
+ modelFunctionOrderBy: ModelFunctionOrderBy;
13
+ fieldUsage: FieldUsageSummary;
14
+ };
15
+ computeAggregateOrderByWithUsage(fs: FieldSpace, allowExpression: boolean): {
16
+ modelFunctionOrderBy: ModelFunctionOrderBy;
17
+ fieldUsage: FieldUsageSummary;
18
+ };
12
19
  }
13
20
  export declare class FunctionOrdering extends ListOf<FunctionOrderBy> {
14
21
  elementType: string;
15
22
  constructor(list: FunctionOrderBy[]);
16
- getAnalyticOrderBy(fs: FieldSpace): ModelFunctionOrderBy[];
17
- getAggregateOrderBy(fs: FieldSpace, allowExpression: boolean): ModelFunctionOrderBy[];
23
+ getAnalyticOrderBy(fs: FieldSpace): {
24
+ orderBy: ModelFunctionOrderBy[];
25
+ fieldUsage: FieldUsageSummary;
26
+ };
27
+ getAggregateOrderBy(fs: FieldSpace, allowExpression: boolean): {
28
+ orderBy: ModelFunctionOrderBy[];
29
+ fieldUsage: FieldUsageSummary;
30
+ };
18
31
  }
32
+ export {};
@@ -26,6 +26,7 @@ exports.FunctionOrdering = exports.FunctionOrderBy = void 0;
26
26
  const malloy_types_1 = require("../../../model/malloy_types");
27
27
  const malloy_element_1 = require("../types/malloy-element");
28
28
  const expr_id_reference_1 = require("./expr-id-reference");
29
+ const composite_source_utils_1 = require("../../composite-source-utils");
29
30
  class FunctionOrderBy extends malloy_element_1.MalloyElement {
30
31
  constructor(field, dir) {
31
32
  super();
@@ -35,12 +36,21 @@ class FunctionOrderBy extends malloy_element_1.MalloyElement {
35
36
  if (field)
36
37
  this.has({ field });
37
38
  }
38
- getAnalyticOrderBy(fs) {
39
+ computeAnalyticOrderBy(fs) {
40
+ let fieldUsage = undefined;
39
41
  if (!this.field) {
40
42
  this.logError('analytic-order-by-missing-field', 'analytic `order_by` must specify an aggregate expression or output field reference');
41
- return { node: 'functionOrderBy', e: { node: 'error' }, dir: this.dir };
43
+ return {
44
+ modelFunctionOrderBy: {
45
+ node: 'functionOrderBy',
46
+ e: { node: 'error' },
47
+ dir: this.dir,
48
+ },
49
+ fieldUsage,
50
+ };
42
51
  }
43
52
  const expr = this.field.getExpression(fs);
53
+ fieldUsage = expr.fieldUsage;
44
54
  if ((0, malloy_types_1.expressionIsAggregate)(expr.expressionType)) {
45
55
  // Aggregates are okay
46
56
  }
@@ -53,26 +63,48 @@ class FunctionOrderBy extends malloy_element_1.MalloyElement {
53
63
  else {
54
64
  this.field.logError('analytic-order-by-not-aggregate-or-output', 'analytic `order_by` must be scalar or aggregate');
55
65
  }
56
- return { node: 'functionOrderBy', e: expr.value, dir: this.dir };
66
+ return {
67
+ modelFunctionOrderBy: {
68
+ node: 'functionOrderBy',
69
+ e: expr.value,
70
+ dir: this.dir,
71
+ },
72
+ fieldUsage,
73
+ };
57
74
  }
58
- getAggregateOrderBy(fs, allowExpression) {
75
+ computeAggregateOrderByWithUsage(fs, allowExpression) {
76
+ let fieldUsage = undefined;
77
+ const dir = this.dir || 'asc';
59
78
  if (this.field) {
60
79
  const expr = this.field.getExpression(fs);
80
+ fieldUsage = expr.fieldUsage;
61
81
  if (!(0, malloy_types_1.expressionIsScalar)(expr.expressionType)) {
62
82
  this.field.logError('aggregate-order-by-not-scalar', 'aggregate `order_by` must be scalar');
63
83
  }
64
84
  if (!allowExpression) {
65
85
  this.field.logError('aggregate-order-by-expression-not-allowed', '`order_by` must be only `asc` or `desc` with no expression');
66
86
  }
67
- return { node: 'functionOrderBy', e: expr.value, dir: this.dir };
87
+ return {
88
+ modelFunctionOrderBy: {
89
+ node: 'functionOrderBy',
90
+ e: expr.value,
91
+ dir,
92
+ },
93
+ fieldUsage,
94
+ };
68
95
  }
69
96
  else {
70
97
  if (this.dir === undefined) {
71
98
  // This error should technically never happen because it can't parse this way
72
99
  this.logError('aggregate-order-by-without-field-or-direction', 'field or order direction must be specified');
73
- return { node: 'functionDefaultOrderBy', dir: 'asc' };
74
100
  }
75
- return { node: 'functionDefaultOrderBy', dir: this.dir };
101
+ return {
102
+ modelFunctionOrderBy: {
103
+ node: 'functionDefaultOrderBy',
104
+ dir,
105
+ },
106
+ fieldUsage,
107
+ };
76
108
  }
77
109
  }
78
110
  }
@@ -83,10 +115,30 @@ class FunctionOrdering extends malloy_element_1.ListOf {
83
115
  this.elementType = 'function-ordering';
84
116
  }
85
117
  getAnalyticOrderBy(fs) {
86
- return this.list.map(el => el.getAnalyticOrderBy(fs));
118
+ const ret = [];
119
+ const fieldUsage = [];
120
+ for (const ob of this.list) {
121
+ const computed = ob.computeAnalyticOrderBy(fs);
122
+ ret.push(computed.modelFunctionOrderBy);
123
+ fieldUsage.push(computed.fieldUsage);
124
+ }
125
+ return {
126
+ orderBy: ret,
127
+ fieldUsage: (0, composite_source_utils_1.mergeFieldUsage)(...fieldUsage),
128
+ };
87
129
  }
88
130
  getAggregateOrderBy(fs, allowExpression) {
89
- return this.list.map(el => el.getAggregateOrderBy(fs, allowExpression));
131
+ const ret = [];
132
+ const fieldUsage = [];
133
+ for (const ob of this.list) {
134
+ const computed = ob.computeAggregateOrderByWithUsage(fs, allowExpression);
135
+ ret.push(computed.modelFunctionOrderBy);
136
+ fieldUsage.push(computed.fieldUsage);
137
+ }
138
+ return {
139
+ orderBy: ret,
140
+ fieldUsage: (0, composite_source_utils_1.mergeFieldUsage)(...fieldUsage),
141
+ };
90
142
  }
91
143
  }
92
144
  exports.FunctionOrdering = FunctionOrdering;
@@ -11,7 +11,7 @@ exports.processIncludeList = processIncludeList;
11
11
  const malloy_types_1 = require("../../../model/malloy_types");
12
12
  const include_item_1 = require("../source-query-elements/include-item");
13
13
  const field_references_1 = require("../query-items/field-references");
14
- const composite_source_utils_1 = require("../../../model/composite_source_utils");
14
+ const composite_source_utils_1 = require("../../composite-source-utils");
15
15
  function getJoinFields(from, joinPath, logTo) {
16
16
  let fields = from.fields;
17
17
  for (const joinName of joinPath) {
@@ -23,7 +23,7 @@
23
23
  */
24
24
  Object.defineProperty(exports, "__esModule", { value: true });
25
25
  exports.IndexFieldSpace = void 0;
26
- const composite_source_utils_1 = require("../../../model/composite_source_utils");
26
+ const composite_source_utils_1 = require("../../composite-source-utils");
27
27
  const malloy_types_1 = require("../../../model/malloy_types");
28
28
  const error_factory_1 = require("../error-factory");
29
29
  const field_references_1 = require("../query-items/field-references");
@@ -79,6 +79,7 @@ class IndexFieldSpace extends query_spaces_1.QueryOperationSpace {
79
79
  const wild = this.expandedWild[name];
80
80
  if (wild) {
81
81
  indexFields.push({ type: 'fieldref', path: wild.path, at: wild.at });
82
+ fieldUsage.push({ path: wild.path });
82
83
  nextFieldUsage = wild.entry.typeDesc().fieldUsage;
83
84
  }
84
85
  else if (field instanceof reference_field_1.ReferenceField) {
@@ -91,6 +92,7 @@ class IndexFieldSpace extends query_spaces_1.QueryOperationSpace {
91
92
  else {
92
93
  indexFields.push(fieldRef.refToField);
93
94
  nextFieldUsage = check.found.typeDesc().fieldUsage;
95
+ fieldUsage.push({ path: fieldRef.path });
94
96
  }
95
97
  }
96
98
  fieldUsage = (_a = (0, composite_source_utils_1.mergeFieldUsage)(fieldUsage, nextFieldUsage)) !== null && _a !== void 0 ? _a : [];