@malloydata/malloy 0.0.218-dev241122201503 → 0.0.218-dev241127170002
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/dialect/dialect.d.ts +2 -2
- package/dist/dialect/duckdb/duckdb.d.ts +2 -2
- package/dist/dialect/duckdb/duckdb.js +17 -2
- package/dist/lang/ast/index.d.ts +0 -1
- package/dist/lang/ast/index.js +0 -1
- package/dist/lang/ast/query-builders/reduce-builder.d.ts +1 -2
- package/dist/lang/ast/query-builders/reduce-builder.js +67 -33
- package/dist/lang/ast/view-elements/refine-utils.js +3 -8
- package/dist/lang/lib/Malloy/MalloyParser.d.ts +0 -1
- package/dist/lang/lib/Malloy/MalloyParser.js +977 -992
- package/dist/lang/malloy-to-ast.d.ts +1 -1
- package/dist/lang/malloy-to-ast.js +1 -18
- package/dist/lang/test/query.spec.js +63 -26
- package/dist/model/malloy_query.d.ts +5 -5
- package/dist/model/malloy_query.js +6 -4
- package/dist/model/malloy_types.d.ts +7 -5
- package/dist/model/malloy_types.js +6 -2
- package/package.json +1 -1
- package/dist/lang/ast/query-properties/top.d.ts +0 -16
- package/dist/lang/ast/query-properties/top.js +0 -76
|
@@ -140,7 +140,7 @@ export declare class MalloyToAST extends AbstractParseTreeVisitor<ast.MalloyElem
|
|
|
140
140
|
visitAggregateOrdering(pcx: parse.AggregateOrderingContext): ast.FunctionOrdering;
|
|
141
141
|
visitOrderBySpec(pcx: parse.OrderBySpecContext): ast.OrderBy;
|
|
142
142
|
visitOrdering(pcx: parse.OrderingContext): ast.Ordering;
|
|
143
|
-
visitTopStatement(pcx: parse.TopStatementContext): ast.
|
|
143
|
+
visitTopStatement(pcx: parse.TopStatementContext): ast.Limit;
|
|
144
144
|
visitTopLevelQueryDefs(pcx: parse.TopLevelQueryDefsContext): ast.DefineQueryList;
|
|
145
145
|
visitTopLevelQueryDef(pcx: parse.TopLevelQueryDefContext): ast.DefineQuery;
|
|
146
146
|
visitAnonymousQuery(pcx: parse.AnonymousQueryContext): ast.AnonymousQuery;
|
|
@@ -744,25 +744,8 @@ class MalloyToAST extends AbstractParseTreeVisitor_1.AbstractParseTreeVisitor {
|
|
|
744
744
|
return this.astAt(new ast.Ordering(orderList), pcx);
|
|
745
745
|
}
|
|
746
746
|
visitTopStatement(pcx) {
|
|
747
|
-
const byCx = pcx.bySpec();
|
|
748
747
|
const topN = this.getNumber(pcx.INTEGER_LITERAL());
|
|
749
|
-
|
|
750
|
-
if (byCx) {
|
|
751
|
-
this.m4advisory(byCx, 'top-by', 'by clause of top statement unupported. Use order_by instead');
|
|
752
|
-
const nameCx = byCx.fieldName();
|
|
753
|
-
if (nameCx) {
|
|
754
|
-
const name = this.getFieldName(nameCx);
|
|
755
|
-
top = new ast.Top(topN, name);
|
|
756
|
-
}
|
|
757
|
-
const exprCx = byCx.fieldExpr();
|
|
758
|
-
if (exprCx) {
|
|
759
|
-
top = new ast.Top(topN, this.getFieldExpr(exprCx));
|
|
760
|
-
}
|
|
761
|
-
}
|
|
762
|
-
if (!top) {
|
|
763
|
-
top = new ast.Top(topN, undefined);
|
|
764
|
-
}
|
|
765
|
-
return this.astAt(top, pcx);
|
|
748
|
+
return this.astAt(new ast.Limit(topN), pcx);
|
|
766
749
|
}
|
|
767
750
|
visitTopLevelQueryDefs(pcx) {
|
|
768
751
|
const stmts = pcx
|
|
@@ -784,35 +784,72 @@ describe('query:', () => {
|
|
|
784
784
|
test('top N', () => {
|
|
785
785
|
expect('run: a->{ top: 5; group_by: astr }').toTranslate();
|
|
786
786
|
});
|
|
787
|
-
test('top N by field', () => {
|
|
788
|
-
expect(`##! m4warnings=warn
|
|
789
|
-
run: a->{top: 5 ${'by astr'}; group_by: astr}`).toLog((0, test_translator_1.warningMessage)('by clause of top statement unupported. Use order_by instead'));
|
|
790
|
-
});
|
|
791
|
-
test('top N by expression', () => {
|
|
792
|
-
expect(`##! m4warnings=warn
|
|
793
|
-
run: ab->{top: 5 by ai + 1; group_by: ai}`).toLog((0, test_translator_1.warningMessage)('by clause of top statement unupported. Use order_by instead'));
|
|
794
|
-
});
|
|
795
787
|
test('limit N', () => {
|
|
796
788
|
expect('run: a->{ limit: 5; group_by: astr }').toTranslate();
|
|
797
789
|
});
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
790
|
+
describe('order by variations', () => {
|
|
791
|
+
test('order by', () => {
|
|
792
|
+
expect('run: a->{ order_by: astr; group_by: astr }').toTranslate();
|
|
793
|
+
});
|
|
794
|
+
test('order by preserved over refinement', () => {
|
|
795
|
+
expect(`
|
|
796
|
+
query: a1 is a -> { group_by: astr }
|
|
797
|
+
run: a1 + { order_by: astr }
|
|
798
|
+
`).toTranslate();
|
|
799
|
+
});
|
|
800
|
+
test('order by must be in the output space', () => expect('run: a -> { order_by: af; group_by: astr }').toLog((0, test_translator_1.errorMessage)('Unknown field af in output space')));
|
|
801
|
+
test('order by asc', () => {
|
|
802
|
+
expect('run: a->{ order_by: astr asc; group_by: astr }').toTranslate();
|
|
803
|
+
});
|
|
804
|
+
test('order by desc', () => {
|
|
805
|
+
expect('run: a->{ order_by: astr desc; group_by: astr }').toTranslate();
|
|
806
|
+
});
|
|
807
|
+
test('order by N', () => {
|
|
808
|
+
expect('run: a->{ order_by: 1 asc; group_by: astr }').toTranslate();
|
|
809
|
+
});
|
|
810
|
+
test('first aggregate used for default ordering', () => {
|
|
811
|
+
const m = (0, test_translator_1.model) `run: a->{
|
|
812
|
+
group_by: astr
|
|
813
|
+
aggregate: t is ai.sum()
|
|
814
|
+
}`;
|
|
815
|
+
expect(m).toTranslate();
|
|
816
|
+
const runStmt = m.translator.getQuery(0);
|
|
817
|
+
expect(runStmt).toBeDefined();
|
|
818
|
+
const reduce = runStmt.pipeline[0];
|
|
819
|
+
expect(reduce.type).toEqual('reduce');
|
|
820
|
+
if (reduce.type === 'reduce') {
|
|
821
|
+
expect(reduce.defaultOrderBy).toBeTruthy();
|
|
822
|
+
expect(reduce.orderBy).toEqual([{ field: 't', dir: 'desc' }]);
|
|
823
|
+
}
|
|
824
|
+
});
|
|
825
|
+
test('first temporal used for default ordering', () => {
|
|
826
|
+
const m = (0, test_translator_1.model) `run: a->{
|
|
827
|
+
group_by: astr, ats
|
|
828
|
+
}`;
|
|
829
|
+
expect(m).toTranslate();
|
|
830
|
+
const runStmt = m.translator.getQuery(0);
|
|
831
|
+
expect(runStmt).toBeDefined();
|
|
832
|
+
const reduce = runStmt.pipeline[0];
|
|
833
|
+
expect(reduce.type).toEqual('reduce');
|
|
834
|
+
if (reduce.type === 'reduce') {
|
|
835
|
+
expect(reduce.defaultOrderBy).toBeTruthy();
|
|
836
|
+
expect(reduce.orderBy).toEqual([{ field: 'ats', dir: 'desc' }]);
|
|
837
|
+
}
|
|
838
|
+
});
|
|
839
|
+
test('first used for ordering when appropriate', () => {
|
|
840
|
+
const m = (0, test_translator_1.model) `run: a->{
|
|
841
|
+
group_by: astr, big is upper(astr)
|
|
842
|
+
}`;
|
|
843
|
+
expect(m).toTranslate();
|
|
844
|
+
const runStmt = m.translator.getQuery(0);
|
|
845
|
+
expect(runStmt).toBeDefined();
|
|
846
|
+
const reduce = runStmt.pipeline[0];
|
|
847
|
+
expect(reduce.type).toEqual('reduce');
|
|
848
|
+
if (reduce.type === 'reduce') {
|
|
849
|
+
expect(reduce.defaultOrderBy).toBeTruthy();
|
|
850
|
+
expect(reduce.orderBy).toEqual([{ field: 'astr', dir: 'asc' }]);
|
|
851
|
+
}
|
|
852
|
+
});
|
|
816
853
|
});
|
|
817
854
|
test('order by multiple', () => {
|
|
818
855
|
expect(`
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Dialect, DialectFieldList } from '../dialect';
|
|
2
|
-
import { 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, AtomicFieldDef, BooleanFieldDef, QueryToMaterialize, PrepareResultOptions, CaseExpr } from './malloy_types';
|
|
2
|
+
import { 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, AtomicFieldDef, BooleanFieldDef, QueryResultDef, QueryToMaterialize, PrepareResultOptions, CaseExpr } from './malloy_types';
|
|
3
3
|
import { Connection } from '../connection/types';
|
|
4
4
|
import { AndChain } from './utils';
|
|
5
5
|
import { QueryInfo } from '../dialect/dialect';
|
|
@@ -224,7 +224,7 @@ declare class QueryTurtle extends QueryField {
|
|
|
224
224
|
* half translated to the new world of types ..
|
|
225
225
|
*/
|
|
226
226
|
export declare class Segment {
|
|
227
|
-
static nextStructDef(structDef: SourceDef, segment: PipeSegment):
|
|
227
|
+
static nextStructDef(structDef: SourceDef, segment: PipeSegment): QueryResultDef;
|
|
228
228
|
}
|
|
229
229
|
type StageGroupMaping = {
|
|
230
230
|
fromGroup: number;
|
|
@@ -267,7 +267,7 @@ declare class QueryQuery extends QueryField {
|
|
|
267
267
|
addAlwaysJoins(rootResult: FieldInstanceResultRoot): void;
|
|
268
268
|
getResultMetadata(fi: FieldInstance): ResultStructMetadataDef | ResultMetadataDef | undefined;
|
|
269
269
|
/** returns a fields and primary key of a struct for this query */
|
|
270
|
-
getResultStructDef(resultStruct?: FieldInstanceResult, isRoot?: boolean):
|
|
270
|
+
getResultStructDef(resultStruct?: FieldInstanceResult, isRoot?: boolean): QueryResultDef;
|
|
271
271
|
generateSQLJoinBlock(stageWriter: StageWriter, ji: JoinInstance): string;
|
|
272
272
|
generateSQLPassthroughKeys(qs: QueryStruct): string;
|
|
273
273
|
generateSQLJoins(stageWriter: StageWriter): string;
|
|
@@ -285,14 +285,14 @@ declare class QueryQuery extends QueryField {
|
|
|
285
285
|
buildDialectFieldList(resultStruct: FieldInstanceResult): DialectFieldList;
|
|
286
286
|
generateTurtleSQL(resultStruct: FieldInstanceResult, stageWriter: StageWriter, sqlFieldName: string, outputPipelinedSQL: OutputPipelinedSQL[]): string;
|
|
287
287
|
generateTurtlePipelineSQL(fi: FieldInstanceResult, stageWriter: StageWriter, sourceSQLExpression: string): {
|
|
288
|
-
structDef:
|
|
288
|
+
structDef: QueryResultDef;
|
|
289
289
|
pipeOut: any;
|
|
290
290
|
};
|
|
291
291
|
generateComplexSQL(stageWriter: StageWriter): string;
|
|
292
292
|
generateSQL(stageWriter: StageWriter): string;
|
|
293
293
|
generateSQLFromPipeline(stageWriter: StageWriter): {
|
|
294
294
|
lastStageName: string;
|
|
295
|
-
outputStruct:
|
|
295
|
+
outputStruct: QueryResultDef;
|
|
296
296
|
};
|
|
297
297
|
}
|
|
298
298
|
/** Structure object as it is used to build a query */
|
|
@@ -96,12 +96,13 @@ class StageWriter {
|
|
|
96
96
|
}
|
|
97
97
|
}
|
|
98
98
|
addUDF(stageWriter, dialect, structDef) {
|
|
99
|
+
var _a;
|
|
99
100
|
// eslint-disable-next-line prefer-const
|
|
100
101
|
let { sql, lastStageName } = stageWriter.combineStages(true);
|
|
101
102
|
if (lastStageName === undefined) {
|
|
102
103
|
throw new Error('Internal Error: no stage to combine');
|
|
103
104
|
}
|
|
104
|
-
sql += dialect.sqlCreateFunctionCombineLastStage(lastStageName, getDialectFieldList(structDef));
|
|
105
|
+
sql += dialect.sqlCreateFunctionCombineLastStage(lastStageName, getDialectFieldList(structDef), (_a = structDef.resultMetadata) === null || _a === void 0 ? void 0 : _a.orderBy);
|
|
105
106
|
const id = `${dialect.udfPrefix}${this.root().udfs.length}`;
|
|
106
107
|
sql = dialect.sqlCreateFunction(id, sql);
|
|
107
108
|
this.root().udfs.push(sql);
|
|
@@ -162,12 +163,13 @@ class StageWriter {
|
|
|
162
163
|
return udfs + pdts + sql + this.withs[lastStageNum];
|
|
163
164
|
}
|
|
164
165
|
generateCoorelatedSubQuery(dialect, structDef) {
|
|
166
|
+
var _a, _b;
|
|
165
167
|
if (!this.useCTE) {
|
|
166
|
-
return dialect.sqlCreateFunctionCombineLastStage(`(${this.withs[0]})`, getDialectFieldList(structDef));
|
|
168
|
+
return dialect.sqlCreateFunctionCombineLastStage(`(${this.withs[0]})`, getDialectFieldList(structDef), (_a = structDef.resultMetadata) === null || _a === void 0 ? void 0 : _a.orderBy);
|
|
167
169
|
}
|
|
168
170
|
else {
|
|
169
171
|
return (this.combineStages(true).sql +
|
|
170
|
-
dialect.sqlCreateFunctionCombineLastStage(this.getName(this.withs.length - 1), getDialectFieldList(structDef)));
|
|
172
|
+
dialect.sqlCreateFunctionCombineLastStage(this.getName(this.withs.length - 1), getDialectFieldList(structDef), (_b = structDef.resultMetadata) === null || _b === void 0 ? void 0 : _b.orderBy));
|
|
171
173
|
}
|
|
172
174
|
}
|
|
173
175
|
}
|
|
@@ -2876,7 +2878,7 @@ class QueryQueryRaw extends QueryQuery {
|
|
|
2876
2878
|
if (!(0, malloy_types_1.isSourceDef)(this.parent.structDef)) {
|
|
2877
2879
|
throw new Error(`Result cannot by type ${this.parent.structDef.type}`);
|
|
2878
2880
|
}
|
|
2879
|
-
return this.parent.structDef;
|
|
2881
|
+
return { ...this.parent.structDef, type: 'query_result' };
|
|
2880
2882
|
}
|
|
2881
2883
|
getResultMetadata(_fi) {
|
|
2882
2884
|
return undefined;
|
|
@@ -317,9 +317,12 @@ export interface ResultMetadataDef {
|
|
|
317
317
|
fieldKind: 'measure' | 'dimension' | 'struct';
|
|
318
318
|
referenceId?: string;
|
|
319
319
|
}
|
|
320
|
-
export interface
|
|
321
|
-
limit?: number;
|
|
320
|
+
export interface Ordered {
|
|
322
321
|
orderBy?: OrderBy[];
|
|
322
|
+
defaultOrderBy?: boolean;
|
|
323
|
+
}
|
|
324
|
+
export interface ResultStructMetadataDef extends ResultMetadataDef, Ordered {
|
|
325
|
+
limit?: number;
|
|
323
326
|
}
|
|
324
327
|
export interface ResultMetadata {
|
|
325
328
|
resultMetadata?: ResultMetadataDef;
|
|
@@ -345,6 +348,7 @@ export declare function isTemporalField(s: string): s is TemporalFieldType;
|
|
|
345
348
|
export type CastType = 'string' | 'number' | TemporalFieldType | 'boolean' | 'json';
|
|
346
349
|
export type AtomicFieldType = CastType | 'sql native' | 'record' | 'array' | 'error';
|
|
347
350
|
export declare function isAtomicFieldType(s: string): s is AtomicFieldType;
|
|
351
|
+
export declare function canOrderBy(s: string): boolean;
|
|
348
352
|
export declare function isCastType(s: string): s is CastType;
|
|
349
353
|
/**
|
|
350
354
|
* Fields which contain scalar data all inherit from this. The field
|
|
@@ -550,13 +554,11 @@ export interface CompositeFieldUsage {
|
|
|
550
554
|
fields: string[];
|
|
551
555
|
joinedUsage: Record<string, CompositeFieldUsage>;
|
|
552
556
|
}
|
|
553
|
-
export interface QuerySegment extends Filtered {
|
|
557
|
+
export interface QuerySegment extends Filtered, Ordered {
|
|
554
558
|
type: 'reduce' | 'project' | 'partial';
|
|
555
559
|
queryFields: QueryFieldDef[];
|
|
556
560
|
extendSource?: FieldDef[];
|
|
557
561
|
limit?: number;
|
|
558
|
-
by?: By;
|
|
559
|
-
orderBy?: OrderBy[];
|
|
560
562
|
queryTimezone?: string;
|
|
561
563
|
alwaysJoins?: string[];
|
|
562
564
|
compositeFieldUsage?: CompositeFieldUsage;
|
|
@@ -22,8 +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.
|
|
26
|
-
exports.TD = exports.isValueDate = exports.isValueTimestamp = exports.isValueBoolean = exports.isValueNumber = exports.isValueString = exports.getAtomicFields = exports.isAtomic = exports.isTurtleDef = exports.getIdentifier = exports.isLeafAtomic = exports.mergeEvalSpaces = exports.isLiteral = void 0;
|
|
25
|
+
exports.isBaseTable = exports.isSourceDef = 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.isByExpression = exports.isByName = exports.ValueType = exports.isExtractUnit = exports.isTimestampUnit = exports.isDateUnit = exports.isJoinedSource = exports.isJoined = exports.isJoinable = exports.isMatrixOperation = exports.isRepeatedRecord = exports.arrayEachFields = exports.fieldIsIntrinsic = exports.isCastType = exports.canOrderBy = exports.isAtomicFieldType = exports.isTemporalField = exports.hasExpression = exports.maxOfExpressionTypes = exports.maxExpressionType = exports.isExpressionTypeLEQ = exports.expressionIsAnalytic = exports.expressionIsCalculation = exports.expressionInvolvesAggregate = exports.expressionIsUngroupedAggregate = exports.expressionIsAggregate = exports.expressionIsScalar = exports.paramHasValue = exports.isRawCast = exports.mkTemporal = exports.isAsymmetricExpr = exports.exprIsLeaf = exports.exprHasE = exports.exprHasKids = void 0;
|
|
26
|
+
exports.TD = exports.isValueDate = exports.isValueTimestamp = exports.isValueBoolean = exports.isValueNumber = exports.isValueString = exports.getAtomicFields = exports.isAtomic = exports.isTurtleDef = exports.getIdentifier = exports.isLeafAtomic = exports.mergeEvalSpaces = exports.isLiteral = exports.isScalarArray = void 0;
|
|
27
27
|
function exprHasKids(e) {
|
|
28
28
|
return 'kids' in e;
|
|
29
29
|
}
|
|
@@ -167,6 +167,10 @@ function isAtomicFieldType(s) {
|
|
|
167
167
|
].includes(s);
|
|
168
168
|
}
|
|
169
169
|
exports.isAtomicFieldType = isAtomicFieldType;
|
|
170
|
+
function canOrderBy(s) {
|
|
171
|
+
return ['string', 'number', 'date', 'boolean', 'date', 'timestamp'].includes(s);
|
|
172
|
+
}
|
|
173
|
+
exports.canOrderBy = canOrderBy;
|
|
170
174
|
function isCastType(s) {
|
|
171
175
|
return ['string', 'number', 'date', 'timestamp', 'boolean', 'json'].includes(s);
|
|
172
176
|
}
|
package/package.json
CHANGED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { By as ModelBy } from '../../../model/malloy_types';
|
|
2
|
-
import { ExpressionDef } from '../types/expression-def';
|
|
3
|
-
import { FieldName, FieldSpace } from '../types/field-space';
|
|
4
|
-
import { MalloyElement } from '../types/malloy-element';
|
|
5
|
-
import { LegalRefinementStage, QueryPropertyInterface } from '../types/query-property-interface';
|
|
6
|
-
type TopInit = FieldName | ExpressionDef;
|
|
7
|
-
export declare class Top extends MalloyElement implements QueryPropertyInterface {
|
|
8
|
-
readonly limit: number;
|
|
9
|
-
readonly by?: TopInit | undefined;
|
|
10
|
-
elementType: string;
|
|
11
|
-
queryRefinementStage: LegalRefinementStage;
|
|
12
|
-
forceQueryClass: undefined;
|
|
13
|
-
constructor(limit: number, by?: TopInit | undefined);
|
|
14
|
-
getBy(fs: FieldSpace): ModelBy | undefined;
|
|
15
|
-
}
|
|
16
|
-
export {};
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/*
|
|
3
|
-
* Copyright 2023 Google LLC
|
|
4
|
-
*
|
|
5
|
-
* Permission is hereby granted, free of charge, to any person obtaining
|
|
6
|
-
* a copy of this software and associated documentation files
|
|
7
|
-
* (the "Software"), to deal in the Software without restriction,
|
|
8
|
-
* including without limitation the rights to use, copy, modify, merge,
|
|
9
|
-
* publish, distribute, sublicense, and/or sell copies of the Software,
|
|
10
|
-
* and to permit persons to whom the Software is furnished to do so,
|
|
11
|
-
* subject to the following conditions:
|
|
12
|
-
*
|
|
13
|
-
* The above copyright notice and this permission notice shall be
|
|
14
|
-
* included in all copies or substantial portions of the Software.
|
|
15
|
-
*
|
|
16
|
-
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
17
|
-
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
18
|
-
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
19
|
-
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
20
|
-
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
21
|
-
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
22
|
-
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
23
|
-
*/
|
|
24
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
|
-
exports.Top = void 0;
|
|
26
|
-
const malloy_types_1 = require("../../../model/malloy_types");
|
|
27
|
-
const field_space_1 = require("../types/field-space");
|
|
28
|
-
const malloy_element_1 = require("../types/malloy-element");
|
|
29
|
-
const query_property_interface_1 = require("../types/query-property-interface");
|
|
30
|
-
class Top extends malloy_element_1.MalloyElement {
|
|
31
|
-
constructor(limit, by) {
|
|
32
|
-
super();
|
|
33
|
-
this.limit = limit;
|
|
34
|
-
this.by = by;
|
|
35
|
-
this.elementType = 'top';
|
|
36
|
-
this.queryRefinementStage = query_property_interface_1.LegalRefinementStage.Tail;
|
|
37
|
-
this.forceQueryClass = undefined;
|
|
38
|
-
this.has({ by: by });
|
|
39
|
-
}
|
|
40
|
-
getBy(fs) {
|
|
41
|
-
var _a;
|
|
42
|
-
if (this.by) {
|
|
43
|
-
if (this.by instanceof field_space_1.FieldName) {
|
|
44
|
-
if (fs.isQueryFieldSpace()) {
|
|
45
|
-
// TODO jump-to-definition now that we can lookup fields in the output space,
|
|
46
|
-
// we need to actually add the reference when we do so.
|
|
47
|
-
const output = fs.outputSpace();
|
|
48
|
-
const entry = this.by.getField(output);
|
|
49
|
-
if (entry.error) {
|
|
50
|
-
this.by.logError(entry.error.code, entry.error.message);
|
|
51
|
-
}
|
|
52
|
-
if (!entry.found || !entry.isOutputField) {
|
|
53
|
-
this.by.logError('top-by-not-found-in-output', `Unknown field ${this.by.refString} in output space`);
|
|
54
|
-
}
|
|
55
|
-
if ((0, malloy_types_1.expressionIsAnalytic)((_a = entry.found) === null || _a === void 0 ? void 0 : _a.typeDesc().expressionType)) {
|
|
56
|
-
this.by.logError('top-by-analytic', `Illegal order by of analytic field ${this.by.refString}`);
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
return { by: 'name', name: this.by.refString };
|
|
60
|
-
}
|
|
61
|
-
else {
|
|
62
|
-
const byExpr = this.by.getExpression(fs);
|
|
63
|
-
if ((0, malloy_types_1.expressionIsAggregate)(byExpr.expressionType)) {
|
|
64
|
-
this.by.logError('top-by-aggregate', 'top by expression must not be an aggregate');
|
|
65
|
-
}
|
|
66
|
-
if (byExpr.evalSpace === 'output') {
|
|
67
|
-
this.by.logError('top-by-not-in-output', 'top by expression must be an output expression');
|
|
68
|
-
}
|
|
69
|
-
return { by: 'expression', e: byExpr.value };
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
return undefined;
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
exports.Top = Top;
|
|
76
|
-
//# sourceMappingURL=top.js.map
|