@cloudcare/codemirror-dql 0.0.56 → 0.0.58

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.
@@ -75,6 +75,7 @@ var queryClauseLabels = new Map([
75
75
  ['TargetClause', 'projection'],
76
76
  ['FilterClause', 'WHERE'],
77
77
  ['TimeClause', 'time range'],
78
+ ['ShiftClause', 'SHIFT'],
78
79
  ['ByClause', 'BY'],
79
80
  ['HavingClause', 'HAVING'],
80
81
  ['OrderClause', 'ORDER BY'],
@@ -84,8 +85,141 @@ var queryClauseLabels = new Map([
84
85
  ['SLimitClause', 'SLIMIT'],
85
86
  ['SOffsetClause', 'SOFFSET'],
86
87
  ]);
87
- var expressionParents = new Set(['BinaryExpr', 'Expr', 'HavingExpr', 'ProjectionExpr']);
88
+ var expressionParents = new Set(['BinaryExpr', 'Expr', 'HavingExpr', 'ProjectionExpr', 'CaseArithmeticExpr']);
88
89
  var commaContextBoundaries = new Set(['CaseExpr', 'Query']);
90
+ var documentedFunctionArities = new Map(__spreadArray(__spreadArray([], __read([
91
+ 'abs',
92
+ 'any',
93
+ 'avg',
94
+ 'bool',
95
+ 'ceil',
96
+ 'count',
97
+ 'count_distinct',
98
+ 'count_series',
99
+ 'deriv',
100
+ 'derivative',
101
+ 'difference',
102
+ 'distinct',
103
+ 'field_values',
104
+ 'first',
105
+ 'float',
106
+ 'floor',
107
+ 'histogram_auto',
108
+ 'increase',
109
+ 'int',
110
+ 'irate',
111
+ 'last',
112
+ 'last_row',
113
+ 'length',
114
+ 'log',
115
+ 'log2',
116
+ 'log10',
117
+ 'lower',
118
+ 'ltrim',
119
+ 'max',
120
+ 'md5',
121
+ 'median',
122
+ 'min',
123
+ 'mode',
124
+ 'non_negative_derivative',
125
+ 'non_negative_difference',
126
+ 'rate',
127
+ 'rate_over_count',
128
+ 'rate_over_sum',
129
+ 'rtrim',
130
+ 'set',
131
+ 'spread',
132
+ 'stddev',
133
+ 'string',
134
+ 'sum',
135
+ 'trim',
136
+ 'uint',
137
+ 'unwrap',
138
+ 'upper',
139
+ ].map(function (name) { return [name, { min: 1, max: 1 }]; })), false), [
140
+ ['bottom', { min: 2, max: 2 }],
141
+ ['cidr', { min: 1, max: 2 }],
142
+ ['collect', { min: 1, max: 2 }],
143
+ ['collect_distinct', { min: 1, max: 2 }],
144
+ ['concat', { min: 1, max: Number.POSITIVE_INFINITY }],
145
+ ['count_filter', { min: 2, max: 2 }],
146
+ ['default', { min: 2, max: 2 }],
147
+ ['distinct_by_collapse', { min: 1, max: 2 }],
148
+ ['drain', { min: 2, max: 3 }],
149
+ ['exists', { min: 0, max: 0 }],
150
+ ['fill', { min: 2, max: 2 }],
151
+ ['histogram', { min: 4, max: 5 }],
152
+ ['histogram_quantile', { min: 2, max: 2 }],
153
+ ['match', { min: 1, max: 2 }],
154
+ ['now', { min: 0, max: 0 }],
155
+ ['query_string', { min: 1, max: 2 }],
156
+ ['querystring', { min: 1, max: 2 }],
157
+ ['re', { min: 1, max: 2 }],
158
+ ['regexp', { min: 1, max: 2 }],
159
+ ['regex', { min: 1, max: 2 }],
160
+ ['regexp_extract', { min: 2, max: 3 }],
161
+ ['regexp_extract_all', { min: 2, max: 3 }],
162
+ ['regexp_replace', { min: 3, max: 3 }],
163
+ ['round', { min: 1, max: 2 }],
164
+ ['search', { min: 1, max: 2 }],
165
+ ['substr', { min: 2, max: 3 }],
166
+ ['top', { min: 2, max: 2 }],
167
+ ['wildcard', { min: 1, max: 2 }],
168
+ ], false));
169
+ var stableShiftAggregateFunctions = new Set([
170
+ 'any',
171
+ 'avg',
172
+ 'change_score',
173
+ 'collect',
174
+ 'collect_distinct',
175
+ 'corr',
176
+ 'count',
177
+ 'count_distinct',
178
+ 'count_filter',
179
+ 'count_series',
180
+ 'deriv',
181
+ 'derivative',
182
+ 'difference',
183
+ 'ewma',
184
+ 'first',
185
+ 'histogram_quantile',
186
+ 'increase',
187
+ 'irate',
188
+ 'last',
189
+ 'last_row',
190
+ 'mad_score',
191
+ 'max',
192
+ 'median',
193
+ 'min',
194
+ 'mode',
195
+ 'moving_average',
196
+ 'non_negative_derivative',
197
+ 'non_negative_difference',
198
+ 'p50',
199
+ 'p75',
200
+ 'p90',
201
+ 'p95',
202
+ 'p99',
203
+ 'percentile',
204
+ 'rate',
205
+ 'rate_over_count',
206
+ 'rate_over_sum',
207
+ 'slope',
208
+ 'spread',
209
+ 'stddev',
210
+ 'sum',
211
+ 'zscore',
212
+ ]);
213
+ var unstableShiftAggregateFunctions = new Set([
214
+ 'distinct',
215
+ 'distinct_by_collapse',
216
+ 'drain',
217
+ 'field_values',
218
+ 'histogram',
219
+ 'histogram_auto',
220
+ 'schema',
221
+ ]);
222
+ var caseScalarFunctions = new Set(['int', 'float', 'string', 'md5', 'lower', 'upper', 'trim', 'ltrim', 'rtrim', 'regexp_replace', 'length']);
89
223
  exports.dqlSyntaxContexts = {
90
224
  DQL: 'DQL query',
91
225
  DQLConditions: 'DQL condition',
@@ -121,8 +255,15 @@ exports.dqlSyntaxContexts = {
121
255
  OuterArgItem: 'outer function argument',
122
256
  Queted: 'quoted query delimiter',
123
257
  EvalCallBody: 'eval function arguments',
258
+ EvalArgItem: 'eval expression argument',
259
+ EvalExpression: 'eval expression',
260
+ EvalAtom: 'eval expression value',
261
+ EvalFunctionCall: 'eval function call',
262
+ EvalFunctionCallBody: 'eval function arguments',
263
+ EvalFunctionArg: 'eval function argument',
124
264
  FunctionCallBody: 'function arguments',
125
265
  ArgItem: 'function argument',
266
+ EvalFieldReference: 'eval field reference',
126
267
  InValue: 'argument value list',
127
268
  SingleExpr: 'expression value',
128
269
  Expr: 'expression',
@@ -139,6 +280,8 @@ exports.dqlSyntaxContexts = {
139
280
  ProjectionFieldFragment: 'projection field fragment',
140
281
  ProjectionField: 'projection field',
141
282
  SingleFieldExpr: 'projection expression value',
283
+ ShiftExpr: 'SHIFT expression',
284
+ ShiftOperand: 'SHIFT operand',
142
285
  ProjectionExpr: 'projection expression',
143
286
  AsExpr: 'alias',
144
287
  FilterClause: 'filter clause',
@@ -152,10 +295,10 @@ exports.dqlSyntaxContexts = {
152
295
  CaseCondition: 'CASE condition',
153
296
  CaseFilterExpr: 'CASE filter expression',
154
297
  CasePredicate: 'CASE predicate',
298
+ CaseComparableValue: 'CASE comparison value',
155
299
  CaseValue: 'CASE value',
156
- CaseFunctionCall: 'CASE function call',
157
- CaseFunctionIdentifier: 'CASE function name',
158
- CaseFunctionCallBody: 'CASE function arguments',
300
+ CaseArithmeticAtom: 'CASE arithmetic value',
301
+ CaseArithmeticExpr: 'CASE arithmetic expression',
159
302
  FilterFragmentExpr: 'filter fragment',
160
303
  ComparisonExpr: 'comparison expression',
161
304
  LogicalFragmentExpr: 'logical filter expression',
@@ -166,6 +309,7 @@ exports.dqlSyntaxContexts = {
166
309
  FilterExpr: 'filter expression',
167
310
  BinaryExpr: 'binary expression',
168
311
  TimeClause: 'time range clause',
312
+ ShiftClause: 'SHIFT clause',
169
313
  TimeRange: 'time range',
170
314
  TimeExpr: 'time range value',
171
315
  ByClause: 'BY clause',
@@ -185,6 +329,7 @@ exports.dqlSyntaxContexts = {
185
329
  };
186
330
  var functionCallBodyParents = new Set([
187
331
  'FunctionCallBody',
332
+ 'EvalFunctionCallBody',
188
333
  'EvalCallBody',
189
334
  'OuterFunctionCallBody',
190
335
  'RawOuterFunctionCallBody',
@@ -193,7 +338,6 @@ var functionCallBodyParents = new Set([
193
338
  'FillOuterFunctionCallBody',
194
339
  'VariadicOuterFunctionCallBody',
195
340
  'RollupFunctionCallBody',
196
- 'CaseFunctionCallBody',
197
341
  ]);
198
342
  var Parser = /** @class */ (function () {
199
343
  function Parser(state, deadline) {
@@ -211,6 +355,7 @@ var Parser = /** @class */ (function () {
211
355
  this.quotedQueryDelimiterInfo = undefined;
212
356
  this.caseResultDiagnostics = undefined;
213
357
  this.caseResultRecoveryErrors = new Set();
358
+ this.caseShiftPresence = new Map();
214
359
  }
215
360
  Parser.prototype.getDiagnostics = function () {
216
361
  var seen = new Set();
@@ -599,7 +744,7 @@ var Parser = /** @class */ (function () {
599
744
  this.appendDiagnostics(diagnostics);
600
745
  };
601
746
  Parser.prototype.describeError = function (node) {
602
- var _a;
747
+ var _a, _b, _c;
603
748
  var delimiterIssue = this.getDelimiterIssue();
604
749
  if (delimiterIssue && delimiterIssue.kind !== 'unclosed' && this.isRelatedDelimiterError(node, delimiterIssue)) {
605
750
  return null;
@@ -681,6 +826,26 @@ var Parser = /** @class */ (function () {
681
826
  }
682
827
  return this.makeDiagnostic(node, 'expected "AS" before projection alias', group);
683
828
  }
829
+ var projectionField = (_a = this.findAncestor(parent, 'ProjectionField')) !== null && _a !== void 0 ? _a : this.findAncestor(parent, 'ProjectionFieldFragment');
830
+ if (projectionField) {
831
+ var shiftError = this.errorDescendantsWithText(projectionField, 'shift').find(function (error) { return error.from <= node.from; });
832
+ if (shiftError && this.containsNode(projectionField, 'ShiftExpr')) {
833
+ return this.makeDiagnosticAt(shiftError.from, shiftError.to, 'SHIFT expressions cannot be nested', "shift-nested-syntax:".concat(projectionField.from));
834
+ }
835
+ if (shiftError) {
836
+ var rawOperand = this.state.sliceDoc(projectionField.from, shiftError.from);
837
+ var leading = rawOperand.length - rawOperand.trimStart().length;
838
+ var trailing = rawOperand.length - rawOperand.trimEnd().length;
839
+ return this.makeDiagnosticAt(projectionField.from + leading, Math.max(projectionField.from + leading + 1, projectionField.from + rawOperand.length - trailing), 'SHIFT operand must be a stable aggregate or subquery measure', "shift-operand-syntax:".concat(projectionField.from));
840
+ }
841
+ }
842
+ var invalidShiftContext = (_b = this.findAncestor(parent, 'FilterClause')) !== null && _b !== void 0 ? _b : this.findAncestor(parent, 'HavingClause');
843
+ if (invalidShiftContext) {
844
+ var shiftError = this.errorDescendantsWithText(invalidShiftContext, 'shift').find(function (error) { return error.from <= node.from; });
845
+ if (shiftError) {
846
+ return this.makeDiagnosticAt(shiftError.from, shiftError.to, 'expression-level SHIFT is only allowed in the projection', "shift-context-syntax:".concat(invalidShiftContext.from));
847
+ }
848
+ }
684
849
  if (parentName === 'OuterFunctionCall') {
685
850
  return this.makeUnexpectedTokenDiagnostic(node, exports.dqlSyntaxContexts.OuterFunctionCall, group);
686
851
  }
@@ -705,7 +870,7 @@ var Parser = /** @class */ (function () {
705
870
  }
706
871
  return this.makeUnexpectedTokenDiagnostic(node, 'function call', group);
707
872
  }
708
- if (parentName === 'ArgItem' && node.from === node.to) {
873
+ if ((parentName === 'ArgItem' || parentName === 'EvalFunctionArg') && node.from === node.to) {
709
874
  if ((previous === null || previous === void 0 ? void 0 : previous.name) === 'EqlSingle') {
710
875
  return this.makeDiagnostic(node, 'function argument value expected after "="', group);
711
876
  }
@@ -751,20 +916,52 @@ var Parser = /** @class */ (function () {
751
916
  if (parentName === 'ByExpr' && errorText === ',') {
752
917
  return this.makeDiagnostic(node, 'grouping field expected before ","', group);
753
918
  }
754
- if (expressionParents.has(parentName)) {
755
- if (previous && this.isOperator(previous)) {
756
- return this.makeDiagnostic(node, "right-hand expression expected after \"".concat(previousText, "\""), group);
757
- }
758
- return this.makeUnexpectedTokenDiagnostic(node, 'expression', group);
759
- }
760
919
  var caseWhenClause = this.findAncestor(parent, 'CaseWhenClause');
761
920
  if (caseWhenClause) {
921
+ var firstCaseError = this.firstErrorFrom(caseWhenClause);
762
922
  var missingCondition = /^\s*when\s+(then)\b/i.exec(this.maskLineComments(this.nodeText(caseWhenClause)));
763
923
  if (missingCondition) {
764
- var thenOffset = missingCondition.index + missingCondition[0].toLowerCase().lastIndexOf('then');
765
- return this.makeDiagnosticAt(caseWhenClause.from + thenOffset, caseWhenClause.from + thenOffset + 4, 'CASE condition expected after "WHEN"', this.caseGroup(caseWhenClause));
924
+ if (node.from === firstCaseError) {
925
+ var thenOffset = missingCondition.index + missingCondition[0].toLowerCase().lastIndexOf('then');
926
+ return this.makeDiagnosticAt(caseWhenClause.from + thenOffset, caseWhenClause.from + thenOffset + 4, 'CASE condition expected after "WHEN"', this.caseGroup(caseWhenClause));
927
+ }
928
+ return null;
929
+ }
930
+ if (!caseWhenClause.getChild('Then')) {
931
+ if (node.from === firstCaseError) {
932
+ return this.makeDiagnostic(node, 'expected "THEN" after CASE condition', this.caseGroup(caseWhenClause));
933
+ }
934
+ return null;
935
+ }
936
+ var missingResult = /\bthen\s+(else)\b/i.exec(this.maskLineComments(this.nodeText(caseWhenClause)));
937
+ if (missingResult) {
938
+ if (node.from === firstCaseError) {
939
+ var keyword = missingResult[1];
940
+ var keywordOffset = missingResult.index + missingResult[0].toLowerCase().lastIndexOf(keyword.toLowerCase());
941
+ return this.makeDiagnosticAt(caseWhenClause.from + keywordOffset, caseWhenClause.from + keywordOffset + keyword.length, 'CASE result expected after "THEN"', this.caseGroup(caseWhenClause));
942
+ }
943
+ return errorText ? this.makeUnexpectedTokenDiagnostic(node, exports.dqlSyntaxContexts.CaseExpr, group) : null;
766
944
  }
767
945
  }
946
+ if (parentName === 'EvalAtom' && errorText === '=' && (previous === null || previous === void 0 ? void 0 : previous.name) === 'Identifier') {
947
+ return this.makeDiagnostic(node, 'function argument value expected after "="', group);
948
+ }
949
+ if (parentName === 'EvalExpression' && node.from === node.to && (previous === null || previous === void 0 ? void 0 : previous.name) === 'EvalAtom' && (next === null || next === void 0 ? void 0 : next.name) === 'EvalAtom') {
950
+ return this.makeDiagnostic(node, 'expected "," between function arguments', group);
951
+ }
952
+ if (parentName === 'CaseArithmeticExpr' && errorText && !(previous === null || previous === void 0 ? void 0 : previous.type.isError)) {
953
+ return this.makeUnexpectedTokenDiagnostic(node, exports.dqlSyntaxContexts.CaseExpr, group);
954
+ }
955
+ if (parentName === 'ShiftExpr' || parentName === 'ShiftClause') {
956
+ var message = errorText ? 'SHIFT duration must be a positive fixed duration' : 'duration expected after "SHIFT"';
957
+ return this.makeDiagnostic(node, message, "shift-duration:".concat(parent.from));
958
+ }
959
+ if (expressionParents.has(parentName)) {
960
+ if (previous && this.isOperator(previous)) {
961
+ return this.makeDiagnostic(node, "right-hand expression expected after \"".concat(previousText, "\""), group);
962
+ }
963
+ return this.makeUnexpectedTokenDiagnostic(node, 'expression', group);
964
+ }
768
965
  if (parentName === 'CaseCondition') {
769
966
  return this.makeDiagnostic(node, 'expected "THEN" after CASE condition', this.caseGroup(parent));
770
967
  }
@@ -812,7 +1009,7 @@ var Parser = /** @class */ (function () {
812
1009
  }
813
1010
  if (parentName === 'RollupIdentifier') {
814
1011
  var timeClause_1 = this.findAncestor(parent, 'TimeClause');
815
- var child = (_a = timeClause_1 === null || timeClause_1 === void 0 ? void 0 : timeClause_1.firstChild) !== null && _a !== void 0 ? _a : null;
1012
+ var child = (_c = timeClause_1 === null || timeClause_1 === void 0 ? void 0 : timeClause_1.firstChild) !== null && _c !== void 0 ? _c : null;
816
1013
  while (child) {
817
1014
  if (child.type.isError)
818
1015
  return null;
@@ -1382,6 +1579,7 @@ var Parser = /** @class */ (function () {
1382
1579
  var contexts = {
1383
1580
  Projection: 'projection item',
1384
1581
  FunctionCallBody: 'function argument',
1582
+ EvalFunctionCallBody: 'function argument',
1385
1583
  EvalCallBody: 'function argument',
1386
1584
  OuterFunctionCallBody: 'function argument',
1387
1585
  RawOuterFunctionCallBody: 'function argument',
@@ -1390,7 +1588,6 @@ var Parser = /** @class */ (function () {
1390
1588
  FillOuterFunctionCallBody: 'function argument',
1391
1589
  VariadicOuterFunctionCallBody: 'function argument',
1392
1590
  RollupFunctionCallBody: 'function argument',
1393
- CaseFunctionCallBody: 'function argument',
1394
1591
  InValue: 'argument value',
1395
1592
  InFieldValue: 'filter value',
1396
1593
  IndexExpr: 'namespace index',
@@ -1575,6 +1772,20 @@ var Parser = /** @class */ (function () {
1575
1772
  }
1576
1773
  return false;
1577
1774
  };
1775
+ Parser.prototype.firstErrorFrom = function (node) {
1776
+ var first = null;
1777
+ var visit = function (current) {
1778
+ var child = current.firstChild;
1779
+ while (child) {
1780
+ if (child.type.isError && (first === null || child.from < first))
1781
+ first = child.from;
1782
+ visit(child);
1783
+ child = child.nextSibling;
1784
+ }
1785
+ };
1786
+ visit(node);
1787
+ return first;
1788
+ };
1578
1789
  Parser.prototype.looksLikeProjectionAfterMissingColon = function (node) {
1579
1790
  var querySource = node.getChild('QuerySource');
1580
1791
  return Boolean(querySource && this.containsError(querySource) && !this.containsNode(querySource, 'DColon'));
@@ -2646,7 +2857,10 @@ var Parser = /** @class */ (function () {
2646
2857
  if (!node.type.isError && !this.containsError(node)) {
2647
2858
  switch (node.name) {
2648
2859
  case 'Query':
2860
+ case 'QueryFragment':
2649
2861
  this.checkDuplicateQueryClauses(node);
2862
+ this.checkQueryShiftPlacement(node);
2863
+ this.checkExpressionShiftOffsets(node);
2650
2864
  break;
2651
2865
  case 'ShowExpr':
2652
2866
  this.checkDuplicateShowClauses(node);
@@ -2655,6 +2869,19 @@ var Parser = /** @class */ (function () {
2655
2869
  case 'TimeRange':
2656
2870
  this.checkTimeRangeShape(node);
2657
2871
  break;
2872
+ case 'ShiftClause':
2873
+ this.checkShiftDuration(node);
2874
+ break;
2875
+ case 'ShiftExpr':
2876
+ this.checkShiftDuration(node);
2877
+ this.checkShiftExpression(node);
2878
+ break;
2879
+ case 'EvalExpr':
2880
+ this.checkEvalReferences(node);
2881
+ break;
2882
+ case 'EvalFieldReference':
2883
+ this.checkEvalFieldReferenceContext(node);
2884
+ break;
2658
2885
  case 'RollupIdentifier':
2659
2886
  this.checkBareRollup(node);
2660
2887
  break;
@@ -2662,7 +2889,10 @@ var Parser = /** @class */ (function () {
2662
2889
  this.checkRollupFunctionCall(node);
2663
2890
  break;
2664
2891
  case 'FunctionCall':
2892
+ case 'EvalFunctionCall':
2665
2893
  this.checkFunctionCall(node);
2894
+ if (node.name === 'FunctionCall')
2895
+ this.checkCaseFunction(node);
2666
2896
  break;
2667
2897
  case 'OuterFunctionCall':
2668
2898
  this.checkOuterFunctionCall(node);
@@ -2682,9 +2912,6 @@ var Parser = /** @class */ (function () {
2682
2912
  case 'FieldName':
2683
2913
  this.checkFieldName(node);
2684
2914
  break;
2685
- case 'CaseFunctionIdentifier':
2686
- this.checkCaseFunction(node);
2687
- break;
2688
2915
  case 'CaseExpr':
2689
2916
  this.checkCaseResults(node);
2690
2917
  break;
@@ -2700,7 +2927,7 @@ var Parser = /** @class */ (function () {
2700
2927
  var seen = new Set();
2701
2928
  var child = query.firstChild;
2702
2929
  while (child) {
2703
- if (child.name === 'QueryClause') {
2930
+ if (child.name === 'QueryClause' || child.name === 'QueryFragmentClause') {
2704
2931
  var clause = child.firstChild;
2705
2932
  if (clause) {
2706
2933
  var label = queryClauseLabels.get(clause.name);
@@ -2717,6 +2944,203 @@ var Parser = /** @class */ (function () {
2717
2944
  child = child.nextSibling;
2718
2945
  }
2719
2946
  };
2947
+ Parser.prototype.checkQueryShiftPlacement = function (query) {
2948
+ var _a;
2949
+ var clauses = [];
2950
+ var child = query.firstChild;
2951
+ while (child) {
2952
+ if (child.name === 'QueryClause' || child.name === 'QueryFragmentClause') {
2953
+ var clause = child.firstChild;
2954
+ if (clause)
2955
+ clauses.push(clause);
2956
+ }
2957
+ child = child.nextSibling;
2958
+ }
2959
+ var shifts = clauses.filter(function (clause) { return clause.name === 'ShiftClause'; });
2960
+ var timeRanges = clauses.filter(function (clause) { return clause.name === 'TimeClause'; });
2961
+ if (shifts.length !== 1 || timeRanges.length > 1)
2962
+ return;
2963
+ var shift = shifts[0];
2964
+ var shiftIndex = clauses.indexOf(shift);
2965
+ var laterTarget = clauses.slice(shiftIndex + 1).find(function (clause) { return clause.name === 'TargetClause'; });
2966
+ if (laterTarget) {
2967
+ this.pushSemanticDiagnostic(shift, '"SHIFT" must appear after the projection', "shift-placement:".concat(shift.from));
2968
+ return;
2969
+ }
2970
+ var laterFilter = clauses.slice(shiftIndex + 1).find(function (clause) { return clause.name === 'FilterClause'; });
2971
+ if (laterFilter) {
2972
+ this.pushSemanticDiagnostic(shift, '"SHIFT" must appear after "WHERE"', "shift-placement:".concat(shift.from));
2973
+ return;
2974
+ }
2975
+ if (timeRanges.length === 1) {
2976
+ var timeIndex = clauses.indexOf(timeRanges[0]);
2977
+ if (shiftIndex !== timeIndex + 1) {
2978
+ this.pushSemanticDiagnostic(shift, '"SHIFT" must immediately follow the time range', "shift-placement:".concat(shift.from));
2979
+ }
2980
+ return;
2981
+ }
2982
+ var outputClause = clauses
2983
+ .slice(0, shiftIndex)
2984
+ .reverse()
2985
+ .find(function (clause) {
2986
+ return ['ByClause', 'HavingClause', 'OrderClause', 'SOrderClause', 'LimitClause', 'OffsetClause', 'SLimitClause', 'SOffsetClause'].includes(clause.name);
2987
+ });
2988
+ if (outputClause) {
2989
+ var label = (_a = queryClauseLabels.get(outputClause.name)) !== null && _a !== void 0 ? _a : outputClause.name;
2990
+ this.pushSemanticDiagnostic(shift, "\"SHIFT\" must appear before \"".concat(label, "\""), "shift-placement:".concat(shift.from));
2991
+ }
2992
+ };
2993
+ Parser.prototype.checkExpressionShiftOffsets = function (query) {
2994
+ var _this = this;
2995
+ var offsets = new Set();
2996
+ var overflowReported = false;
2997
+ var visit = function (node) {
2998
+ if (overflowReported || Date.now() >= _this.deadline)
2999
+ return;
3000
+ if (node !== query && node.name === 'Query')
3001
+ return;
3002
+ if (node.name === 'ShiftExpr') {
3003
+ var duration = node.getChild('Duration');
3004
+ if (duration) {
3005
+ var rawOffset = _this.nodeText(duration).toLowerCase();
3006
+ var milliseconds = _this.fixedDurationMilliseconds(rawOffset);
3007
+ var offset = milliseconds !== null && Number.isSafeInteger(milliseconds) ? "".concat(milliseconds, "ms") : rawOffset;
3008
+ if (!offsets.has(offset)) {
3009
+ offsets.add(offset);
3010
+ if (offsets.size > 16) {
3011
+ _this.pushSemanticDiagnostic(duration, 'a SELECT can use at most 16 distinct SHIFT offsets', "shift-offsets:".concat(query.from));
3012
+ overflowReported = true;
3013
+ return;
3014
+ }
3015
+ }
3016
+ }
3017
+ }
3018
+ var child = node.firstChild;
3019
+ while (child) {
3020
+ visit(child);
3021
+ child = child.nextSibling;
3022
+ }
3023
+ };
3024
+ visit(query);
3025
+ };
3026
+ Parser.prototype.checkShiftDuration = function (shift) {
3027
+ var duration = shift.getChild('Duration');
3028
+ if (!duration || this.isPositiveFixedDuration(this.nodeText(duration)))
3029
+ return;
3030
+ this.pushSemanticDiagnostic(duration, 'SHIFT duration must be a positive fixed duration', "shift-duration:".concat(shift.from));
3031
+ };
3032
+ Parser.prototype.checkShiftExpression = function (shift) {
3033
+ var _this = this;
3034
+ var _a, _b;
3035
+ var nested = this.findAncestor(shift.parent, 'ShiftExpr');
3036
+ if (nested) {
3037
+ this.pushSemanticDiagnostic(shift, 'SHIFT expressions cannot be nested', "shift-nested:".concat(shift.from));
3038
+ return;
3039
+ }
3040
+ if (!this.findAncestor(shift.parent, 'TargetClause') && !this.findAncestor(shift.parent, 'ProjectionFragment')) {
3041
+ this.pushSemanticDiagnostic(shift, 'expression-level SHIFT is only allowed in the projection', "shift-context:".concat(shift.from));
3042
+ return;
3043
+ }
3044
+ var operand = shift.getChild('ShiftOperand');
3045
+ if (!operand)
3046
+ return;
3047
+ var calls = this.shiftOperandFunctionCalls(operand);
3048
+ var unstable = calls.find(function (call) {
3049
+ var name = _this.functionCallName(call);
3050
+ return name !== null && unstableShiftAggregateFunctions.has(name);
3051
+ });
3052
+ if (unstable) {
3053
+ var name_1 = (_a = this.functionCallName(unstable)) !== null && _a !== void 0 ? _a : 'function';
3054
+ var identifier = (_b = unstable.getChild('FunctionIdentifier')) !== null && _b !== void 0 ? _b : unstable;
3055
+ this.pushSemanticDiagnostic(identifier, "function \"".concat(name_1, "\" cannot be used as a SHIFT operand"), "shift-operand:".concat(shift.from));
3056
+ return;
3057
+ }
3058
+ var hasStableAggregate = calls.some(function (call) {
3059
+ var name = _this.functionCallName(call);
3060
+ return name !== null && stableShiftAggregateFunctions.has(name);
3061
+ });
3062
+ if (!hasStableAggregate) {
3063
+ this.pushSemanticDiagnostic(operand, 'SHIFT operand must be a stable aggregate or subquery measure', "shift-operand:".concat(shift.from));
3064
+ }
3065
+ };
3066
+ Parser.prototype.checkEvalFieldReferenceContext = function (reference) {
3067
+ if (this.findAncestor(reference.parent, 'EvalExpr'))
3068
+ return;
3069
+ this.pushSemanticDiagnostic(reference, 'qualified field references are only supported inside eval', "eval-field-context:".concat(reference.from));
3070
+ };
3071
+ Parser.prototype.checkEvalReferences = function (evalExpr) {
3072
+ var e_24, _a, e_25, _b, e_26, _c;
3073
+ var body = evalExpr.getChild('EvalCallBody');
3074
+ if (!body)
3075
+ return;
3076
+ var aliases = new Set();
3077
+ try {
3078
+ for (var _d = __values(this.directChildren(body, 'OuterArgItem')), _e = _d.next(); !_e.done; _e = _d.next()) {
3079
+ var argument = _e.value;
3080
+ var identifier = argument.getChild('Identifier');
3081
+ if (!identifier || !argument.getChild('EqlSingle'))
3082
+ continue;
3083
+ if (!argument.getChild('Query') && !argument.getChild('OuterFunctionCall'))
3084
+ continue;
3085
+ var name_2 = this.nodeText(identifier).toLowerCase();
3086
+ if (aliases.has(name_2)) {
3087
+ this.pushSemanticDiagnostic(identifier, "duplicate eval subquery \"".concat(name_2, "\""), "eval-alias-duplicate:".concat(identifier.from));
3088
+ continue;
3089
+ }
3090
+ aliases.add(name_2);
3091
+ }
3092
+ }
3093
+ catch (e_24_1) { e_24 = { error: e_24_1 }; }
3094
+ finally {
3095
+ try {
3096
+ if (_e && !_e.done && (_a = _d.return)) _a.call(_d);
3097
+ }
3098
+ finally { if (e_24) throw e_24.error; }
3099
+ }
3100
+ var expression = body.getChild('EvalArgItem');
3101
+ if (!expression)
3102
+ return;
3103
+ try {
3104
+ for (var _f = __values(this.descendantsNamed(expression, 'EvalFieldReference')), _g = _f.next(); !_g.done; _g = _f.next()) {
3105
+ var reference = _g.value;
3106
+ var alias = reference.getChild('Identifier');
3107
+ if (!alias)
3108
+ continue;
3109
+ var name_3 = this.nodeText(alias).toLowerCase();
3110
+ if (!aliases.has(name_3)) {
3111
+ this.pushSemanticDiagnostic(alias, "unknown eval subquery \"".concat(name_3, "\" in field reference"), "eval-field:".concat(reference.from));
3112
+ }
3113
+ }
3114
+ }
3115
+ catch (e_25_1) { e_25 = { error: e_25_1 }; }
3116
+ finally {
3117
+ try {
3118
+ if (_g && !_g.done && (_b = _f.return)) _b.call(_f);
3119
+ }
3120
+ finally { if (e_25) throw e_25.error; }
3121
+ }
3122
+ if (aliases.size > 1) {
3123
+ try {
3124
+ for (var _h = __values(this.descendantsNamed(expression, 'EvalAtom')), _j = _h.next(); !_j.done; _j = _h.next()) {
3125
+ var atom = _j.value;
3126
+ var identifier = atom.getChild('Identifier');
3127
+ if (!identifier)
3128
+ continue;
3129
+ var name_4 = this.nodeText(identifier).toLowerCase();
3130
+ if (!aliases.has(name_4)) {
3131
+ this.pushSemanticDiagnostic(identifier, "unknown eval subquery \"".concat(name_4, "\" in expression"), "eval-alias:".concat(identifier.from));
3132
+ }
3133
+ }
3134
+ }
3135
+ catch (e_26_1) { e_26 = { error: e_26_1 }; }
3136
+ finally {
3137
+ try {
3138
+ if (_j && !_j.done && (_c = _h.return)) _c.call(_h);
3139
+ }
3140
+ finally { if (e_26) throw e_26.error; }
3141
+ }
3142
+ }
3143
+ };
2720
3144
  Parser.prototype.checkDuplicateShowClauses = function (show) {
2721
3145
  var seen = new Set();
2722
3146
  var child = show.firstChild;
@@ -2838,12 +3262,44 @@ var Parser = /** @class */ (function () {
2838
3262
  }
2839
3263
  };
2840
3264
  Parser.prototype.checkFunctionCall = function (call) {
3265
+ var _a;
2841
3266
  var identifier = call.getChild('FunctionIdentifier');
2842
- var body = call.getChild('FunctionCallBody');
3267
+ var body = (_a = call.getChild('FunctionCallBody')) !== null && _a !== void 0 ? _a : call.getChild('EvalFunctionCallBody');
2843
3268
  if (!identifier || !body)
2844
3269
  return;
2845
3270
  var name = this.nodeText(identifier).toLowerCase();
2846
- var args = this.directChildren(body, 'ArgItem');
3271
+ var argumentName = body.name === 'EvalFunctionCallBody' ? 'EvalFunctionArg' : 'ArgItem';
3272
+ var args = this.directChildren(body, argumentName);
3273
+ var arity = documentedFunctionArities.get(name);
3274
+ if (arity && (args.length < arity.min || args.length > arity.max)) {
3275
+ this.pushSemanticDiagnostic(body, this.functionArityMessage(name, arity), "function-arity:".concat(call.from));
3276
+ return;
3277
+ }
3278
+ if ((name === 'count_filter' || name === 'distinct_by_collapse') && args.length === 2 && !args[1].getChild('InValue')) {
3279
+ this.pushSemanticDiagnostic(args[1], "function \"".concat(name, "\" expects a value list as its second argument"), "function:".concat(call.from));
3280
+ return;
3281
+ }
3282
+ if (name === 'histogram_quantile' && args.length === 2) {
3283
+ var quantile = this.numericValue(args[1]);
3284
+ if (quantile === null || quantile < 0 || quantile > 1) {
3285
+ this.pushSemanticDiagnostic(args[1], 'function "histogram_quantile" expects a quantile in range [0, 1]', "function:".concat(call.from));
3286
+ return;
3287
+ }
3288
+ }
3289
+ if (name === 'drain' && args.length >= 2) {
3290
+ var threshold = this.numericValue(args[1]);
3291
+ if (threshold === null || threshold <= 0 || threshold > 1) {
3292
+ this.pushSemanticDiagnostic(args[1], 'function "drain" expects a similarity threshold in range (0, 1]', "function:".concat(call.from));
3293
+ return;
3294
+ }
3295
+ if (args.length === 3) {
3296
+ var maxClusters = this.numericValue(args[2]);
3297
+ if (maxClusters === null || !Number.isInteger(maxClusters) || maxClusters < 1 || maxClusters > 10000) {
3298
+ this.pushSemanticDiagnostic(args[2], 'function "drain" expects max_clusters to be an integer in range [1, 10000]', "function:".concat(call.from));
3299
+ return;
3300
+ }
3301
+ }
3302
+ }
2847
3303
  if (name === 'ewma') {
2848
3304
  var alpha = args.length === 2 ? this.numericValue(args[1]) : null;
2849
3305
  if (alpha === null || alpha <= 0 || alpha > 1) {
@@ -2872,6 +3328,17 @@ var Parser = /** @class */ (function () {
2872
3328
  this.pushSemanticDiagnostic(body, "function \"".concat(name, "\" expects exactly one input field"), "function:".concat(call.from));
2873
3329
  }
2874
3330
  };
3331
+ Parser.prototype.functionArityMessage = function (name, arity) {
3332
+ if (arity.min === arity.max) {
3333
+ if (arity.min === 0)
3334
+ return "function \"".concat(name, "\" does not accept arguments");
3335
+ return "function \"".concat(name, "\" expects exactly ").concat(arity.min, " ").concat(arity.min === 1 ? 'argument' : 'arguments');
3336
+ }
3337
+ if (!Number.isFinite(arity.max)) {
3338
+ return "function \"".concat(name, "\" expects at least ").concat(arity.min, " ").concat(arity.min === 1 ? 'argument' : 'arguments');
3339
+ }
3340
+ return "function \"".concat(name, "\" expects between ").concat(arity.min, " and ").concat(arity.max, " arguments");
3341
+ };
2875
3342
  Parser.prototype.checkOuterFunctionCall = function (call) {
2876
3343
  var identifier = call.firstChild;
2877
3344
  if (!identifier || identifier.name === 'FunctionIdentifier')
@@ -2970,10 +3437,36 @@ var Parser = /** @class */ (function () {
2970
3437
  this.pushSemanticDiagnostic(field, 'field names containing "-" must be enclosed in backticks', "field-name:".concat(field.from));
2971
3438
  }
2972
3439
  };
2973
- Parser.prototype.checkCaseFunction = function (identifier) {
2974
- if (this.nodeText(identifier).toLowerCase() === 'substr') {
2975
- this.pushSemanticDiagnostic(identifier, 'function "substr" is not supported inside CASE', "case-function:".concat(identifier.from));
2976
- }
3440
+ Parser.prototype.checkCaseFunction = function (call) {
3441
+ var caseExpr = this.findAncestor(call.parent, 'CaseExpr');
3442
+ if (!caseExpr)
3443
+ return;
3444
+ var shiftExpr = this.findAncestor(call.parent, 'ShiftExpr');
3445
+ if (shiftExpr && shiftExpr.from >= caseExpr.from && shiftExpr.to <= caseExpr.to)
3446
+ return;
3447
+ var identifier = call.getChild('FunctionIdentifier');
3448
+ var body = call.getChild('FunctionCallBody');
3449
+ if (!identifier || !body)
3450
+ return;
3451
+ var name = this.nodeText(identifier).toLowerCase();
3452
+ var args = this.directChildren(body, 'ArgItem');
3453
+ var arity = documentedFunctionArities.get(name);
3454
+ if (arity && (args.length < arity.min || args.length > arity.max))
3455
+ return;
3456
+ if (caseScalarFunctions.has(name))
3457
+ return;
3458
+ if (stableShiftAggregateFunctions.has(name) && this.caseContainsShift(caseExpr))
3459
+ return;
3460
+ this.pushSemanticDiagnostic(identifier, "function \"".concat(name, "\" is not supported inside CASE"), "case-function:".concat(identifier.from));
3461
+ };
3462
+ Parser.prototype.caseContainsShift = function (caseExpr) {
3463
+ var key = this.nodeRangeKey(caseExpr);
3464
+ var cached = this.caseShiftPresence.get(key);
3465
+ if (cached !== undefined)
3466
+ return cached;
3467
+ var containsShift = this.containsNode(caseExpr, 'ShiftExpr');
3468
+ this.caseShiftPresence.set(key, containsShift);
3469
+ return containsShift;
2977
3470
  };
2978
3471
  Parser.prototype.checkCaseResults = function (caseExpr) {
2979
3472
  var clause = caseExpr.firstChild;
@@ -3000,6 +3493,10 @@ var Parser = /** @class */ (function () {
3000
3493
  var hasFrom = /\bfrom\s*=/.test(bodyText.toLowerCase());
3001
3494
  var filter = show.getChild('FilterClause');
3002
3495
  var hasSourceFilter = Boolean(filter && /@__source__/.test(this.maskStringsAndLineComments(this.nodeText(filter))));
3496
+ if (/^show_[a-z0-9]+_index$/.test(name)) {
3497
+ this.pushSemanticDiagnostic(identifier, "\"".concat(name, "\" is not supported by the DQL parser"), "show:".concat(show.from, ":unsupported"));
3498
+ return;
3499
+ }
3003
3500
  if ((name === 'show_tag_value' || name === 'show_tag_value_cardinality' || name === 'show_series_count_by_tag_value') && !hasKeyin) {
3004
3501
  this.pushSemanticDiagnostic(identifier, "\"".concat(name, "\" requires the named argument \"keyin\""), "show:".concat(show.from, ":keyin"));
3005
3502
  }
@@ -3026,13 +3523,106 @@ var Parser = /** @class */ (function () {
3026
3523
  }
3027
3524
  return children;
3028
3525
  };
3526
+ Parser.prototype.descendantsNamed = function (node, name) {
3527
+ var descendants = [];
3528
+ var visit = function (current) {
3529
+ var child = current.firstChild;
3530
+ while (child) {
3531
+ if (child.name === name)
3532
+ descendants.push(child);
3533
+ visit(child);
3534
+ child = child.nextSibling;
3535
+ }
3536
+ };
3537
+ visit(node);
3538
+ return descendants;
3539
+ };
3540
+ Parser.prototype.shiftOperandFunctionCalls = function (operand) {
3541
+ var querySource = operand.getChild('QuerySource');
3542
+ if (!querySource)
3543
+ return this.descendantsNamed(operand, 'FunctionCall');
3544
+ var query = querySource.getChild('Query');
3545
+ if (!query)
3546
+ return [];
3547
+ var calls = [];
3548
+ var clause = query.firstChild;
3549
+ while (clause) {
3550
+ if (clause.name === 'QueryClause') {
3551
+ var target = clause.getChild('TargetClause');
3552
+ if (target)
3553
+ calls.push.apply(calls, __spreadArray([], __read(this.descendantsNamed(target, 'FunctionCall')), false));
3554
+ }
3555
+ clause = clause.nextSibling;
3556
+ }
3557
+ return calls;
3558
+ };
3559
+ Parser.prototype.errorDescendantsWithText = function (node, text) {
3560
+ var _this = this;
3561
+ var errors = [];
3562
+ var expected = text.toLowerCase();
3563
+ var visit = function (current) {
3564
+ var child = current.firstChild;
3565
+ while (child) {
3566
+ if (child.type.isError && _this.nodeText(child).toLowerCase() === expected)
3567
+ errors.push(child);
3568
+ visit(child);
3569
+ child = child.nextSibling;
3570
+ }
3571
+ };
3572
+ visit(node);
3573
+ return errors;
3574
+ };
3575
+ Parser.prototype.functionCallName = function (call) {
3576
+ var identifier = call.getChild('FunctionIdentifier');
3577
+ return identifier ? this.nodeText(identifier).toLowerCase() : null;
3578
+ };
3579
+ Parser.prototype.isPositiveFixedDuration = function (text) {
3580
+ var milliseconds = this.fixedDurationMilliseconds(text);
3581
+ return milliseconds !== null && milliseconds > 0;
3582
+ };
3583
+ Parser.prototype.fixedDurationMilliseconds = function (text) {
3584
+ var multipliers = {
3585
+ y: 365 * 24 * 60 * 60 * 1000,
3586
+ w: 7 * 24 * 60 * 60 * 1000,
3587
+ d: 24 * 60 * 60 * 1000,
3588
+ h: 60 * 60 * 1000,
3589
+ m: 60 * 1000,
3590
+ s: 1000,
3591
+ ms: 1,
3592
+ };
3593
+ var normalized = text.toLowerCase();
3594
+ var pattern = /(\d+)(ms|[ywdhms])/g;
3595
+ var total = 0;
3596
+ var consumed = 0;
3597
+ var part = pattern.exec(normalized);
3598
+ while (part) {
3599
+ if (part.index !== consumed)
3600
+ return null;
3601
+ var amount = Number(part[1]);
3602
+ var component = amount * multipliers[part[2]];
3603
+ if (!Number.isSafeInteger(amount) || !Number.isSafeInteger(component) || !Number.isSafeInteger(total + component))
3604
+ return null;
3605
+ total += component;
3606
+ consumed = pattern.lastIndex;
3607
+ part = pattern.exec(normalized);
3608
+ }
3609
+ return consumed === normalized.length ? total : null;
3610
+ };
3029
3611
  Parser.prototype.numericValue = function (node) {
3030
3612
  if (!node)
3031
3613
  return null;
3032
- var number = node.name === 'Number' ? node : node.getChild('Number');
3614
+ var valueNode = node;
3615
+ if (node.name === 'EvalFunctionArg') {
3616
+ var expression = node.getChild('EvalExpression');
3617
+ var atom = expression === null || expression === void 0 ? void 0 : expression.firstChild;
3618
+ if (!expression || (atom === null || atom === void 0 ? void 0 : atom.name) !== 'EvalAtom' || atom.nextSibling)
3619
+ return null;
3620
+ valueNode = atom;
3621
+ }
3622
+ var number = valueNode.name === 'Number' ? valueNode : valueNode.getChild('Number');
3033
3623
  if (!number)
3034
3624
  return null;
3035
- var sign = node.name !== 'Number' && node.getChild('Sub') ? -1 : 1;
3625
+ var sign = valueNode.name !== 'Number' && valueNode.getChild('Sub') ? -1 : 1;
3036
3626
  var value = sign * Number(this.nodeText(number).replace(/_/g, ''));
3037
3627
  return Number.isFinite(value) ? value : null;
3038
3628
  };
@@ -3081,10 +3671,10 @@ var Parser = /** @class */ (function () {
3081
3671
  var functionPattern = /\b([A-Za-z_][A-Za-z0-9_-]*)\s*\(/g;
3082
3672
  var match = functionPattern.exec(text);
3083
3673
  while (match) {
3084
- var name_1 = match[1];
3674
+ var name_5 = match[1];
3085
3675
  var nameFrom = context.from + match.index;
3086
3676
  if (!this.containsFunctionCallStartingAt(context, nameFrom)) {
3087
- return this.makeDiagnosticAt(nameFrom, nameFrom + name_1.length, "unknown function \"".concat(name_1, "\""), "unknown-function:".concat(context.from, ":").concat(nameFrom));
3677
+ return this.makeDiagnosticAt(nameFrom, nameFrom + name_5.length, "unknown function \"".concat(name_5, "\""), "unknown-function:".concat(context.from, ":").concat(nameFrom));
3088
3678
  }
3089
3679
  match = functionPattern.exec(text);
3090
3680
  }