@cloudcare/codemirror-dql 0.0.57 → 0.0.61

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,12 +85,150 @@ 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',
92
226
  QueryExpr: 'DQL query',
227
+ StudioQuery: 'STUDIOQL query',
228
+ StudioModule: 'STUDIOQL module',
229
+ StudioFunction: 'STUDIOQL function',
230
+ StudioCallBody: 'function arguments',
231
+ StudioArgument: 'named function argument',
93
232
  ShowExpr: 'SHOW expression',
94
233
  QueryFragment: 'query fragment',
95
234
  QueryFragmentClause: 'query fragment clause',
@@ -121,8 +260,15 @@ exports.dqlSyntaxContexts = {
121
260
  OuterArgItem: 'outer function argument',
122
261
  Queted: 'quoted query delimiter',
123
262
  EvalCallBody: 'eval function arguments',
263
+ EvalArgItem: 'eval expression argument',
264
+ EvalExpression: 'eval expression',
265
+ EvalAtom: 'eval expression value',
266
+ EvalFunctionCall: 'eval function call',
267
+ EvalFunctionCallBody: 'eval function arguments',
268
+ EvalFunctionArg: 'eval function argument',
124
269
  FunctionCallBody: 'function arguments',
125
270
  ArgItem: 'function argument',
271
+ EvalFieldReference: 'eval field reference',
126
272
  InValue: 'argument value list',
127
273
  SingleExpr: 'expression value',
128
274
  Expr: 'expression',
@@ -139,6 +285,8 @@ exports.dqlSyntaxContexts = {
139
285
  ProjectionFieldFragment: 'projection field fragment',
140
286
  ProjectionField: 'projection field',
141
287
  SingleFieldExpr: 'projection expression value',
288
+ ShiftExpr: 'SHIFT expression',
289
+ ShiftOperand: 'SHIFT operand',
142
290
  ProjectionExpr: 'projection expression',
143
291
  AsExpr: 'alias',
144
292
  FilterClause: 'filter clause',
@@ -152,10 +300,10 @@ exports.dqlSyntaxContexts = {
152
300
  CaseCondition: 'CASE condition',
153
301
  CaseFilterExpr: 'CASE filter expression',
154
302
  CasePredicate: 'CASE predicate',
303
+ CaseComparableValue: 'CASE comparison value',
155
304
  CaseValue: 'CASE value',
156
- CaseFunctionCall: 'CASE function call',
157
- CaseFunctionIdentifier: 'CASE function name',
158
- CaseFunctionCallBody: 'CASE function arguments',
305
+ CaseArithmeticAtom: 'CASE arithmetic value',
306
+ CaseArithmeticExpr: 'CASE arithmetic expression',
159
307
  FilterFragmentExpr: 'filter fragment',
160
308
  ComparisonExpr: 'comparison expression',
161
309
  LogicalFragmentExpr: 'logical filter expression',
@@ -166,6 +314,7 @@ exports.dqlSyntaxContexts = {
166
314
  FilterExpr: 'filter expression',
167
315
  BinaryExpr: 'binary expression',
168
316
  TimeClause: 'time range clause',
317
+ ShiftClause: 'SHIFT clause',
169
318
  TimeRange: 'time range',
170
319
  TimeExpr: 'time range value',
171
320
  ByClause: 'BY clause',
@@ -184,7 +333,9 @@ exports.dqlSyntaxContexts = {
184
333
  NestedByMathExpr: 'nested grouping expression',
185
334
  };
186
335
  var functionCallBodyParents = new Set([
336
+ 'StudioCallBody',
187
337
  'FunctionCallBody',
338
+ 'EvalFunctionCallBody',
188
339
  'EvalCallBody',
189
340
  'OuterFunctionCallBody',
190
341
  'RawOuterFunctionCallBody',
@@ -193,7 +344,6 @@ var functionCallBodyParents = new Set([
193
344
  'FillOuterFunctionCallBody',
194
345
  'VariadicOuterFunctionCallBody',
195
346
  'RollupFunctionCallBody',
196
- 'CaseFunctionCallBody',
197
347
  ]);
198
348
  var Parser = /** @class */ (function () {
199
349
  function Parser(state, deadline) {
@@ -211,6 +361,7 @@ var Parser = /** @class */ (function () {
211
361
  this.quotedQueryDelimiterInfo = undefined;
212
362
  this.caseResultDiagnostics = undefined;
213
363
  this.caseResultRecoveryErrors = new Set();
364
+ this.caseShiftPresence = new Map();
214
365
  }
215
366
  Parser.prototype.getDiagnostics = function () {
216
367
  var seen = new Set();
@@ -599,7 +750,7 @@ var Parser = /** @class */ (function () {
599
750
  this.appendDiagnostics(diagnostics);
600
751
  };
601
752
  Parser.prototype.describeError = function (node) {
602
- var _a;
753
+ var _a, _b, _c;
603
754
  var delimiterIssue = this.getDelimiterIssue();
604
755
  if (delimiterIssue && delimiterIssue.kind !== 'unclosed' && this.isRelatedDelimiterError(node, delimiterIssue)) {
605
756
  return null;
@@ -681,6 +832,26 @@ var Parser = /** @class */ (function () {
681
832
  }
682
833
  return this.makeDiagnostic(node, 'expected "AS" before projection alias', group);
683
834
  }
835
+ var projectionField = (_a = this.findAncestor(parent, 'ProjectionField')) !== null && _a !== void 0 ? _a : this.findAncestor(parent, 'ProjectionFieldFragment');
836
+ if (projectionField) {
837
+ var shiftError = this.errorDescendantsWithText(projectionField, 'shift').find(function (error) { return error.from <= node.from; });
838
+ if (shiftError && this.containsNode(projectionField, 'ShiftExpr')) {
839
+ return this.makeDiagnosticAt(shiftError.from, shiftError.to, 'SHIFT expressions cannot be nested', "shift-nested-syntax:".concat(projectionField.from));
840
+ }
841
+ if (shiftError) {
842
+ var rawOperand = this.state.sliceDoc(projectionField.from, shiftError.from);
843
+ var leading = rawOperand.length - rawOperand.trimStart().length;
844
+ var trailing = rawOperand.length - rawOperand.trimEnd().length;
845
+ 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));
846
+ }
847
+ }
848
+ var invalidShiftContext = (_b = this.findAncestor(parent, 'FilterClause')) !== null && _b !== void 0 ? _b : this.findAncestor(parent, 'HavingClause');
849
+ if (invalidShiftContext) {
850
+ var shiftError = this.errorDescendantsWithText(invalidShiftContext, 'shift').find(function (error) { return error.from <= node.from; });
851
+ if (shiftError) {
852
+ return this.makeDiagnosticAt(shiftError.from, shiftError.to, 'expression-level SHIFT is only allowed in the projection', "shift-context-syntax:".concat(invalidShiftContext.from));
853
+ }
854
+ }
684
855
  if (parentName === 'OuterFunctionCall') {
685
856
  return this.makeUnexpectedTokenDiagnostic(node, exports.dqlSyntaxContexts.OuterFunctionCall, group);
686
857
  }
@@ -705,7 +876,7 @@ var Parser = /** @class */ (function () {
705
876
  }
706
877
  return this.makeUnexpectedTokenDiagnostic(node, 'function call', group);
707
878
  }
708
- if (parentName === 'ArgItem' && node.from === node.to) {
879
+ if ((parentName === 'ArgItem' || parentName === 'EvalFunctionArg') && node.from === node.to) {
709
880
  if ((previous === null || previous === void 0 ? void 0 : previous.name) === 'EqlSingle') {
710
881
  return this.makeDiagnostic(node, 'function argument value expected after "="', group);
711
882
  }
@@ -751,20 +922,52 @@ var Parser = /** @class */ (function () {
751
922
  if (parentName === 'ByExpr' && errorText === ',') {
752
923
  return this.makeDiagnostic(node, 'grouping field expected before ","', group);
753
924
  }
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
925
  var caseWhenClause = this.findAncestor(parent, 'CaseWhenClause');
761
926
  if (caseWhenClause) {
927
+ var firstCaseError = this.firstErrorFrom(caseWhenClause);
762
928
  var missingCondition = /^\s*when\s+(then)\b/i.exec(this.maskLineComments(this.nodeText(caseWhenClause)));
763
929
  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));
930
+ if (node.from === firstCaseError) {
931
+ var thenOffset = missingCondition.index + missingCondition[0].toLowerCase().lastIndexOf('then');
932
+ return this.makeDiagnosticAt(caseWhenClause.from + thenOffset, caseWhenClause.from + thenOffset + 4, 'CASE condition expected after "WHEN"', this.caseGroup(caseWhenClause));
933
+ }
934
+ return null;
935
+ }
936
+ if (!caseWhenClause.getChild('Then')) {
937
+ if (node.from === firstCaseError) {
938
+ return this.makeDiagnostic(node, 'expected "THEN" after CASE condition', this.caseGroup(caseWhenClause));
939
+ }
940
+ return null;
941
+ }
942
+ var missingResult = /\bthen\s+(else)\b/i.exec(this.maskLineComments(this.nodeText(caseWhenClause)));
943
+ if (missingResult) {
944
+ if (node.from === firstCaseError) {
945
+ var keyword = missingResult[1];
946
+ var keywordOffset = missingResult.index + missingResult[0].toLowerCase().lastIndexOf(keyword.toLowerCase());
947
+ return this.makeDiagnosticAt(caseWhenClause.from + keywordOffset, caseWhenClause.from + keywordOffset + keyword.length, 'CASE result expected after "THEN"', this.caseGroup(caseWhenClause));
948
+ }
949
+ return errorText ? this.makeUnexpectedTokenDiagnostic(node, exports.dqlSyntaxContexts.CaseExpr, group) : null;
766
950
  }
767
951
  }
952
+ if (parentName === 'EvalAtom' && errorText === '=' && (previous === null || previous === void 0 ? void 0 : previous.name) === 'Identifier') {
953
+ return this.makeDiagnostic(node, 'function argument value expected after "="', group);
954
+ }
955
+ 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') {
956
+ return this.makeDiagnostic(node, 'expected "," between function arguments', group);
957
+ }
958
+ if (parentName === 'CaseArithmeticExpr' && errorText && !(previous === null || previous === void 0 ? void 0 : previous.type.isError)) {
959
+ return this.makeUnexpectedTokenDiagnostic(node, exports.dqlSyntaxContexts.CaseExpr, group);
960
+ }
961
+ if (parentName === 'ShiftExpr' || parentName === 'ShiftClause') {
962
+ var message = errorText ? 'SHIFT duration must be a positive fixed duration' : 'duration expected after "SHIFT"';
963
+ return this.makeDiagnostic(node, message, "shift-duration:".concat(parent.from));
964
+ }
965
+ if (expressionParents.has(parentName)) {
966
+ if (previous && this.isOperator(previous)) {
967
+ return this.makeDiagnostic(node, "right-hand expression expected after \"".concat(previousText, "\""), group);
968
+ }
969
+ return this.makeUnexpectedTokenDiagnostic(node, 'expression', group);
970
+ }
768
971
  if (parentName === 'CaseCondition') {
769
972
  return this.makeDiagnostic(node, 'expected "THEN" after CASE condition', this.caseGroup(parent));
770
973
  }
@@ -812,7 +1015,7 @@ var Parser = /** @class */ (function () {
812
1015
  }
813
1016
  if (parentName === 'RollupIdentifier') {
814
1017
  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;
1018
+ var child = (_c = timeClause_1 === null || timeClause_1 === void 0 ? void 0 : timeClause_1.firstChild) !== null && _c !== void 0 ? _c : null;
816
1019
  while (child) {
817
1020
  if (child.type.isError)
818
1021
  return null;
@@ -1381,7 +1584,9 @@ var Parser = /** @class */ (function () {
1381
1584
  Parser.prototype.describeConsecutiveCommaError = function (node, parent) {
1382
1585
  var contexts = {
1383
1586
  Projection: 'projection item',
1587
+ StudioCallBody: 'function argument',
1384
1588
  FunctionCallBody: 'function argument',
1589
+ EvalFunctionCallBody: 'function argument',
1385
1590
  EvalCallBody: 'function argument',
1386
1591
  OuterFunctionCallBody: 'function argument',
1387
1592
  RawOuterFunctionCallBody: 'function argument',
@@ -1390,7 +1595,6 @@ var Parser = /** @class */ (function () {
1390
1595
  FillOuterFunctionCallBody: 'function argument',
1391
1596
  VariadicOuterFunctionCallBody: 'function argument',
1392
1597
  RollupFunctionCallBody: 'function argument',
1393
- CaseFunctionCallBody: 'function argument',
1394
1598
  InValue: 'argument value',
1395
1599
  InFieldValue: 'filter value',
1396
1600
  IndexExpr: 'namespace index',
@@ -1575,6 +1779,20 @@ var Parser = /** @class */ (function () {
1575
1779
  }
1576
1780
  return false;
1577
1781
  };
1782
+ Parser.prototype.firstErrorFrom = function (node) {
1783
+ var first = null;
1784
+ var visit = function (current) {
1785
+ var child = current.firstChild;
1786
+ while (child) {
1787
+ if (child.type.isError && (first === null || child.from < first))
1788
+ first = child.from;
1789
+ visit(child);
1790
+ child = child.nextSibling;
1791
+ }
1792
+ };
1793
+ visit(node);
1794
+ return first;
1795
+ };
1578
1796
  Parser.prototype.looksLikeProjectionAfterMissingColon = function (node) {
1579
1797
  var querySource = node.getChild('QuerySource');
1580
1798
  return Boolean(querySource && this.containsError(querySource) && !this.containsNode(querySource, 'DColon'));
@@ -2648,6 +2866,8 @@ var Parser = /** @class */ (function () {
2648
2866
  case 'Query':
2649
2867
  case 'QueryFragment':
2650
2868
  this.checkDuplicateQueryClauses(node);
2869
+ this.checkQueryShiftPlacement(node);
2870
+ this.checkExpressionShiftOffsets(node);
2651
2871
  break;
2652
2872
  case 'ShowExpr':
2653
2873
  this.checkDuplicateShowClauses(node);
@@ -2656,6 +2876,19 @@ var Parser = /** @class */ (function () {
2656
2876
  case 'TimeRange':
2657
2877
  this.checkTimeRangeShape(node);
2658
2878
  break;
2879
+ case 'ShiftClause':
2880
+ this.checkShiftDuration(node);
2881
+ break;
2882
+ case 'ShiftExpr':
2883
+ this.checkShiftDuration(node);
2884
+ this.checkShiftExpression(node);
2885
+ break;
2886
+ case 'EvalExpr':
2887
+ this.checkEvalReferences(node);
2888
+ break;
2889
+ case 'EvalFieldReference':
2890
+ this.checkEvalFieldReferenceContext(node);
2891
+ break;
2659
2892
  case 'RollupIdentifier':
2660
2893
  this.checkBareRollup(node);
2661
2894
  break;
@@ -2663,7 +2896,10 @@ var Parser = /** @class */ (function () {
2663
2896
  this.checkRollupFunctionCall(node);
2664
2897
  break;
2665
2898
  case 'FunctionCall':
2899
+ case 'EvalFunctionCall':
2666
2900
  this.checkFunctionCall(node);
2901
+ if (node.name === 'FunctionCall')
2902
+ this.checkCaseFunction(node);
2667
2903
  break;
2668
2904
  case 'OuterFunctionCall':
2669
2905
  this.checkOuterFunctionCall(node);
@@ -2683,9 +2919,6 @@ var Parser = /** @class */ (function () {
2683
2919
  case 'FieldName':
2684
2920
  this.checkFieldName(node);
2685
2921
  break;
2686
- case 'CaseFunctionIdentifier':
2687
- this.checkCaseFunction(node);
2688
- break;
2689
2922
  case 'CaseExpr':
2690
2923
  this.checkCaseResults(node);
2691
2924
  break;
@@ -2718,6 +2951,203 @@ var Parser = /** @class */ (function () {
2718
2951
  child = child.nextSibling;
2719
2952
  }
2720
2953
  };
2954
+ Parser.prototype.checkQueryShiftPlacement = function (query) {
2955
+ var _a;
2956
+ var clauses = [];
2957
+ var child = query.firstChild;
2958
+ while (child) {
2959
+ if (child.name === 'QueryClause' || child.name === 'QueryFragmentClause') {
2960
+ var clause = child.firstChild;
2961
+ if (clause)
2962
+ clauses.push(clause);
2963
+ }
2964
+ child = child.nextSibling;
2965
+ }
2966
+ var shifts = clauses.filter(function (clause) { return clause.name === 'ShiftClause'; });
2967
+ var timeRanges = clauses.filter(function (clause) { return clause.name === 'TimeClause'; });
2968
+ if (shifts.length !== 1 || timeRanges.length > 1)
2969
+ return;
2970
+ var shift = shifts[0];
2971
+ var shiftIndex = clauses.indexOf(shift);
2972
+ var laterTarget = clauses.slice(shiftIndex + 1).find(function (clause) { return clause.name === 'TargetClause'; });
2973
+ if (laterTarget) {
2974
+ this.pushSemanticDiagnostic(shift, '"SHIFT" must appear after the projection', "shift-placement:".concat(shift.from));
2975
+ return;
2976
+ }
2977
+ var laterFilter = clauses.slice(shiftIndex + 1).find(function (clause) { return clause.name === 'FilterClause'; });
2978
+ if (laterFilter) {
2979
+ this.pushSemanticDiagnostic(shift, '"SHIFT" must appear after "WHERE"', "shift-placement:".concat(shift.from));
2980
+ return;
2981
+ }
2982
+ if (timeRanges.length === 1) {
2983
+ var timeIndex = clauses.indexOf(timeRanges[0]);
2984
+ if (shiftIndex !== timeIndex + 1) {
2985
+ this.pushSemanticDiagnostic(shift, '"SHIFT" must immediately follow the time range', "shift-placement:".concat(shift.from));
2986
+ }
2987
+ return;
2988
+ }
2989
+ var outputClause = clauses
2990
+ .slice(0, shiftIndex)
2991
+ .reverse()
2992
+ .find(function (clause) {
2993
+ return ['ByClause', 'HavingClause', 'OrderClause', 'SOrderClause', 'LimitClause', 'OffsetClause', 'SLimitClause', 'SOffsetClause'].includes(clause.name);
2994
+ });
2995
+ if (outputClause) {
2996
+ var label = (_a = queryClauseLabels.get(outputClause.name)) !== null && _a !== void 0 ? _a : outputClause.name;
2997
+ this.pushSemanticDiagnostic(shift, "\"SHIFT\" must appear before \"".concat(label, "\""), "shift-placement:".concat(shift.from));
2998
+ }
2999
+ };
3000
+ Parser.prototype.checkExpressionShiftOffsets = function (query) {
3001
+ var _this = this;
3002
+ var offsets = new Set();
3003
+ var overflowReported = false;
3004
+ var visit = function (node) {
3005
+ if (overflowReported || Date.now() >= _this.deadline)
3006
+ return;
3007
+ if (node !== query && node.name === 'Query')
3008
+ return;
3009
+ if (node.name === 'ShiftExpr') {
3010
+ var duration = node.getChild('Duration');
3011
+ if (duration) {
3012
+ var rawOffset = _this.nodeText(duration).toLowerCase();
3013
+ var milliseconds = _this.fixedDurationMilliseconds(rawOffset);
3014
+ var offset = milliseconds !== null && Number.isSafeInteger(milliseconds) ? "".concat(milliseconds, "ms") : rawOffset;
3015
+ if (!offsets.has(offset)) {
3016
+ offsets.add(offset);
3017
+ if (offsets.size > 16) {
3018
+ _this.pushSemanticDiagnostic(duration, 'a SELECT can use at most 16 distinct SHIFT offsets', "shift-offsets:".concat(query.from));
3019
+ overflowReported = true;
3020
+ return;
3021
+ }
3022
+ }
3023
+ }
3024
+ }
3025
+ var child = node.firstChild;
3026
+ while (child) {
3027
+ visit(child);
3028
+ child = child.nextSibling;
3029
+ }
3030
+ };
3031
+ visit(query);
3032
+ };
3033
+ Parser.prototype.checkShiftDuration = function (shift) {
3034
+ var duration = shift.getChild('Duration');
3035
+ if (!duration || this.isPositiveFixedDuration(this.nodeText(duration)))
3036
+ return;
3037
+ this.pushSemanticDiagnostic(duration, 'SHIFT duration must be a positive fixed duration', "shift-duration:".concat(shift.from));
3038
+ };
3039
+ Parser.prototype.checkShiftExpression = function (shift) {
3040
+ var _this = this;
3041
+ var _a, _b;
3042
+ var nested = this.findAncestor(shift.parent, 'ShiftExpr');
3043
+ if (nested) {
3044
+ this.pushSemanticDiagnostic(shift, 'SHIFT expressions cannot be nested', "shift-nested:".concat(shift.from));
3045
+ return;
3046
+ }
3047
+ if (!this.findAncestor(shift.parent, 'TargetClause') && !this.findAncestor(shift.parent, 'ProjectionFragment')) {
3048
+ this.pushSemanticDiagnostic(shift, 'expression-level SHIFT is only allowed in the projection', "shift-context:".concat(shift.from));
3049
+ return;
3050
+ }
3051
+ var operand = shift.getChild('ShiftOperand');
3052
+ if (!operand)
3053
+ return;
3054
+ var calls = this.shiftOperandFunctionCalls(operand);
3055
+ var unstable = calls.find(function (call) {
3056
+ var name = _this.functionCallName(call);
3057
+ return name !== null && unstableShiftAggregateFunctions.has(name);
3058
+ });
3059
+ if (unstable) {
3060
+ var name_1 = (_a = this.functionCallName(unstable)) !== null && _a !== void 0 ? _a : 'function';
3061
+ var identifier = (_b = unstable.getChild('FunctionIdentifier')) !== null && _b !== void 0 ? _b : unstable;
3062
+ this.pushSemanticDiagnostic(identifier, "function \"".concat(name_1, "\" cannot be used as a SHIFT operand"), "shift-operand:".concat(shift.from));
3063
+ return;
3064
+ }
3065
+ var hasStableAggregate = calls.some(function (call) {
3066
+ var name = _this.functionCallName(call);
3067
+ return name !== null && stableShiftAggregateFunctions.has(name);
3068
+ });
3069
+ if (!hasStableAggregate) {
3070
+ this.pushSemanticDiagnostic(operand, 'SHIFT operand must be a stable aggregate or subquery measure', "shift-operand:".concat(shift.from));
3071
+ }
3072
+ };
3073
+ Parser.prototype.checkEvalFieldReferenceContext = function (reference) {
3074
+ if (this.findAncestor(reference.parent, 'EvalExpr'))
3075
+ return;
3076
+ this.pushSemanticDiagnostic(reference, 'qualified field references are only supported inside eval', "eval-field-context:".concat(reference.from));
3077
+ };
3078
+ Parser.prototype.checkEvalReferences = function (evalExpr) {
3079
+ var e_24, _a, e_25, _b, e_26, _c;
3080
+ var body = evalExpr.getChild('EvalCallBody');
3081
+ if (!body)
3082
+ return;
3083
+ var aliases = new Set();
3084
+ try {
3085
+ for (var _d = __values(this.directChildren(body, 'OuterArgItem')), _e = _d.next(); !_e.done; _e = _d.next()) {
3086
+ var argument = _e.value;
3087
+ var identifier = argument.getChild('Identifier');
3088
+ if (!identifier || !argument.getChild('EqlSingle'))
3089
+ continue;
3090
+ if (!argument.getChild('Query') && !argument.getChild('OuterFunctionCall'))
3091
+ continue;
3092
+ var name_2 = this.nodeText(identifier).toLowerCase();
3093
+ if (aliases.has(name_2)) {
3094
+ this.pushSemanticDiagnostic(identifier, "duplicate eval subquery \"".concat(name_2, "\""), "eval-alias-duplicate:".concat(identifier.from));
3095
+ continue;
3096
+ }
3097
+ aliases.add(name_2);
3098
+ }
3099
+ }
3100
+ catch (e_24_1) { e_24 = { error: e_24_1 }; }
3101
+ finally {
3102
+ try {
3103
+ if (_e && !_e.done && (_a = _d.return)) _a.call(_d);
3104
+ }
3105
+ finally { if (e_24) throw e_24.error; }
3106
+ }
3107
+ var expression = body.getChild('EvalArgItem');
3108
+ if (!expression)
3109
+ return;
3110
+ try {
3111
+ for (var _f = __values(this.descendantsNamed(expression, 'EvalFieldReference')), _g = _f.next(); !_g.done; _g = _f.next()) {
3112
+ var reference = _g.value;
3113
+ var alias = reference.getChild('Identifier');
3114
+ if (!alias)
3115
+ continue;
3116
+ var name_3 = this.nodeText(alias).toLowerCase();
3117
+ if (!aliases.has(name_3)) {
3118
+ this.pushSemanticDiagnostic(alias, "unknown eval subquery \"".concat(name_3, "\" in field reference"), "eval-field:".concat(reference.from));
3119
+ }
3120
+ }
3121
+ }
3122
+ catch (e_25_1) { e_25 = { error: e_25_1 }; }
3123
+ finally {
3124
+ try {
3125
+ if (_g && !_g.done && (_b = _f.return)) _b.call(_f);
3126
+ }
3127
+ finally { if (e_25) throw e_25.error; }
3128
+ }
3129
+ if (aliases.size > 1) {
3130
+ try {
3131
+ for (var _h = __values(this.descendantsNamed(expression, 'EvalAtom')), _j = _h.next(); !_j.done; _j = _h.next()) {
3132
+ var atom = _j.value;
3133
+ var identifier = atom.getChild('Identifier');
3134
+ if (!identifier)
3135
+ continue;
3136
+ var name_4 = this.nodeText(identifier).toLowerCase();
3137
+ if (!aliases.has(name_4)) {
3138
+ this.pushSemanticDiagnostic(identifier, "unknown eval subquery \"".concat(name_4, "\" in expression"), "eval-alias:".concat(identifier.from));
3139
+ }
3140
+ }
3141
+ }
3142
+ catch (e_26_1) { e_26 = { error: e_26_1 }; }
3143
+ finally {
3144
+ try {
3145
+ if (_j && !_j.done && (_c = _h.return)) _c.call(_h);
3146
+ }
3147
+ finally { if (e_26) throw e_26.error; }
3148
+ }
3149
+ }
3150
+ };
2721
3151
  Parser.prototype.checkDuplicateShowClauses = function (show) {
2722
3152
  var seen = new Set();
2723
3153
  var child = show.firstChild;
@@ -2839,12 +3269,44 @@ var Parser = /** @class */ (function () {
2839
3269
  }
2840
3270
  };
2841
3271
  Parser.prototype.checkFunctionCall = function (call) {
3272
+ var _a;
2842
3273
  var identifier = call.getChild('FunctionIdentifier');
2843
- var body = call.getChild('FunctionCallBody');
3274
+ var body = (_a = call.getChild('FunctionCallBody')) !== null && _a !== void 0 ? _a : call.getChild('EvalFunctionCallBody');
2844
3275
  if (!identifier || !body)
2845
3276
  return;
2846
3277
  var name = this.nodeText(identifier).toLowerCase();
2847
- var args = this.directChildren(body, 'ArgItem');
3278
+ var argumentName = body.name === 'EvalFunctionCallBody' ? 'EvalFunctionArg' : 'ArgItem';
3279
+ var args = this.directChildren(body, argumentName);
3280
+ var arity = documentedFunctionArities.get(name);
3281
+ if (arity && (args.length < arity.min || args.length > arity.max)) {
3282
+ this.pushSemanticDiagnostic(body, this.functionArityMessage(name, arity), "function-arity:".concat(call.from));
3283
+ return;
3284
+ }
3285
+ if ((name === 'count_filter' || name === 'distinct_by_collapse') && args.length === 2 && !args[1].getChild('InValue')) {
3286
+ this.pushSemanticDiagnostic(args[1], "function \"".concat(name, "\" expects a value list as its second argument"), "function:".concat(call.from));
3287
+ return;
3288
+ }
3289
+ if (name === 'histogram_quantile' && args.length === 2) {
3290
+ var quantile = this.numericValue(args[1]);
3291
+ if (quantile === null || quantile < 0 || quantile > 1) {
3292
+ this.pushSemanticDiagnostic(args[1], 'function "histogram_quantile" expects a quantile in range [0, 1]', "function:".concat(call.from));
3293
+ return;
3294
+ }
3295
+ }
3296
+ if (name === 'drain' && args.length >= 2) {
3297
+ var threshold = this.numericValue(args[1]);
3298
+ if (threshold === null || threshold <= 0 || threshold > 1) {
3299
+ this.pushSemanticDiagnostic(args[1], 'function "drain" expects a similarity threshold in range (0, 1]', "function:".concat(call.from));
3300
+ return;
3301
+ }
3302
+ if (args.length === 3) {
3303
+ var maxClusters = this.numericValue(args[2]);
3304
+ if (maxClusters === null || !Number.isInteger(maxClusters) || maxClusters < 1 || maxClusters > 10000) {
3305
+ this.pushSemanticDiagnostic(args[2], 'function "drain" expects max_clusters to be an integer in range [1, 10000]', "function:".concat(call.from));
3306
+ return;
3307
+ }
3308
+ }
3309
+ }
2848
3310
  if (name === 'ewma') {
2849
3311
  var alpha = args.length === 2 ? this.numericValue(args[1]) : null;
2850
3312
  if (alpha === null || alpha <= 0 || alpha > 1) {
@@ -2873,6 +3335,17 @@ var Parser = /** @class */ (function () {
2873
3335
  this.pushSemanticDiagnostic(body, "function \"".concat(name, "\" expects exactly one input field"), "function:".concat(call.from));
2874
3336
  }
2875
3337
  };
3338
+ Parser.prototype.functionArityMessage = function (name, arity) {
3339
+ if (arity.min === arity.max) {
3340
+ if (arity.min === 0)
3341
+ return "function \"".concat(name, "\" does not accept arguments");
3342
+ return "function \"".concat(name, "\" expects exactly ").concat(arity.min, " ").concat(arity.min === 1 ? 'argument' : 'arguments');
3343
+ }
3344
+ if (!Number.isFinite(arity.max)) {
3345
+ return "function \"".concat(name, "\" expects at least ").concat(arity.min, " ").concat(arity.min === 1 ? 'argument' : 'arguments');
3346
+ }
3347
+ return "function \"".concat(name, "\" expects between ").concat(arity.min, " and ").concat(arity.max, " arguments");
3348
+ };
2876
3349
  Parser.prototype.checkOuterFunctionCall = function (call) {
2877
3350
  var identifier = call.firstChild;
2878
3351
  if (!identifier || identifier.name === 'FunctionIdentifier')
@@ -2971,11 +3444,36 @@ var Parser = /** @class */ (function () {
2971
3444
  this.pushSemanticDiagnostic(field, 'field names containing "-" must be enclosed in backticks', "field-name:".concat(field.from));
2972
3445
  }
2973
3446
  };
2974
- Parser.prototype.checkCaseFunction = function (identifier) {
3447
+ Parser.prototype.checkCaseFunction = function (call) {
3448
+ var caseExpr = this.findAncestor(call.parent, 'CaseExpr');
3449
+ if (!caseExpr)
3450
+ return;
3451
+ var shiftExpr = this.findAncestor(call.parent, 'ShiftExpr');
3452
+ if (shiftExpr && shiftExpr.from >= caseExpr.from && shiftExpr.to <= caseExpr.to)
3453
+ return;
3454
+ var identifier = call.getChild('FunctionIdentifier');
3455
+ var body = call.getChild('FunctionCallBody');
3456
+ if (!identifier || !body)
3457
+ return;
2975
3458
  var name = this.nodeText(identifier).toLowerCase();
2976
- if (name === 'uint' || name === 'bool' || name === 'substr') {
2977
- this.pushSemanticDiagnostic(identifier, "function \"".concat(name, "\" is not supported inside CASE"), "case-function:".concat(identifier.from));
2978
- }
3459
+ var args = this.directChildren(body, 'ArgItem');
3460
+ var arity = documentedFunctionArities.get(name);
3461
+ if (arity && (args.length < arity.min || args.length > arity.max))
3462
+ return;
3463
+ if (caseScalarFunctions.has(name))
3464
+ return;
3465
+ if (stableShiftAggregateFunctions.has(name) && this.caseContainsShift(caseExpr))
3466
+ return;
3467
+ this.pushSemanticDiagnostic(identifier, "function \"".concat(name, "\" is not supported inside CASE"), "case-function:".concat(identifier.from));
3468
+ };
3469
+ Parser.prototype.caseContainsShift = function (caseExpr) {
3470
+ var key = this.nodeRangeKey(caseExpr);
3471
+ var cached = this.caseShiftPresence.get(key);
3472
+ if (cached !== undefined)
3473
+ return cached;
3474
+ var containsShift = this.containsNode(caseExpr, 'ShiftExpr');
3475
+ this.caseShiftPresence.set(key, containsShift);
3476
+ return containsShift;
2979
3477
  };
2980
3478
  Parser.prototype.checkCaseResults = function (caseExpr) {
2981
3479
  var clause = caseExpr.firstChild;
@@ -3002,6 +3500,10 @@ var Parser = /** @class */ (function () {
3002
3500
  var hasFrom = /\bfrom\s*=/.test(bodyText.toLowerCase());
3003
3501
  var filter = show.getChild('FilterClause');
3004
3502
  var hasSourceFilter = Boolean(filter && /@__source__/.test(this.maskStringsAndLineComments(this.nodeText(filter))));
3503
+ if (/^show_[a-z0-9]+_index$/.test(name)) {
3504
+ this.pushSemanticDiagnostic(identifier, "\"".concat(name, "\" is not supported by the DQL parser"), "show:".concat(show.from, ":unsupported"));
3505
+ return;
3506
+ }
3005
3507
  if ((name === 'show_tag_value' || name === 'show_tag_value_cardinality' || name === 'show_series_count_by_tag_value') && !hasKeyin) {
3006
3508
  this.pushSemanticDiagnostic(identifier, "\"".concat(name, "\" requires the named argument \"keyin\""), "show:".concat(show.from, ":keyin"));
3007
3509
  }
@@ -3028,13 +3530,106 @@ var Parser = /** @class */ (function () {
3028
3530
  }
3029
3531
  return children;
3030
3532
  };
3533
+ Parser.prototype.descendantsNamed = function (node, name) {
3534
+ var descendants = [];
3535
+ var visit = function (current) {
3536
+ var child = current.firstChild;
3537
+ while (child) {
3538
+ if (child.name === name)
3539
+ descendants.push(child);
3540
+ visit(child);
3541
+ child = child.nextSibling;
3542
+ }
3543
+ };
3544
+ visit(node);
3545
+ return descendants;
3546
+ };
3547
+ Parser.prototype.shiftOperandFunctionCalls = function (operand) {
3548
+ var querySource = operand.getChild('QuerySource');
3549
+ if (!querySource)
3550
+ return this.descendantsNamed(operand, 'FunctionCall');
3551
+ var query = querySource.getChild('Query');
3552
+ if (!query)
3553
+ return [];
3554
+ var calls = [];
3555
+ var clause = query.firstChild;
3556
+ while (clause) {
3557
+ if (clause.name === 'QueryClause') {
3558
+ var target = clause.getChild('TargetClause');
3559
+ if (target)
3560
+ calls.push.apply(calls, __spreadArray([], __read(this.descendantsNamed(target, 'FunctionCall')), false));
3561
+ }
3562
+ clause = clause.nextSibling;
3563
+ }
3564
+ return calls;
3565
+ };
3566
+ Parser.prototype.errorDescendantsWithText = function (node, text) {
3567
+ var _this = this;
3568
+ var errors = [];
3569
+ var expected = text.toLowerCase();
3570
+ var visit = function (current) {
3571
+ var child = current.firstChild;
3572
+ while (child) {
3573
+ if (child.type.isError && _this.nodeText(child).toLowerCase() === expected)
3574
+ errors.push(child);
3575
+ visit(child);
3576
+ child = child.nextSibling;
3577
+ }
3578
+ };
3579
+ visit(node);
3580
+ return errors;
3581
+ };
3582
+ Parser.prototype.functionCallName = function (call) {
3583
+ var identifier = call.getChild('FunctionIdentifier');
3584
+ return identifier ? this.nodeText(identifier).toLowerCase() : null;
3585
+ };
3586
+ Parser.prototype.isPositiveFixedDuration = function (text) {
3587
+ var milliseconds = this.fixedDurationMilliseconds(text);
3588
+ return milliseconds !== null && milliseconds > 0;
3589
+ };
3590
+ Parser.prototype.fixedDurationMilliseconds = function (text) {
3591
+ var multipliers = {
3592
+ y: 365 * 24 * 60 * 60 * 1000,
3593
+ w: 7 * 24 * 60 * 60 * 1000,
3594
+ d: 24 * 60 * 60 * 1000,
3595
+ h: 60 * 60 * 1000,
3596
+ m: 60 * 1000,
3597
+ s: 1000,
3598
+ ms: 1,
3599
+ };
3600
+ var normalized = text.toLowerCase();
3601
+ var pattern = /(\d+)(ms|[ywdhms])/g;
3602
+ var total = 0;
3603
+ var consumed = 0;
3604
+ var part = pattern.exec(normalized);
3605
+ while (part) {
3606
+ if (part.index !== consumed)
3607
+ return null;
3608
+ var amount = Number(part[1]);
3609
+ var component = amount * multipliers[part[2]];
3610
+ if (!Number.isSafeInteger(amount) || !Number.isSafeInteger(component) || !Number.isSafeInteger(total + component))
3611
+ return null;
3612
+ total += component;
3613
+ consumed = pattern.lastIndex;
3614
+ part = pattern.exec(normalized);
3615
+ }
3616
+ return consumed === normalized.length ? total : null;
3617
+ };
3031
3618
  Parser.prototype.numericValue = function (node) {
3032
3619
  if (!node)
3033
3620
  return null;
3034
- var number = node.name === 'Number' ? node : node.getChild('Number');
3621
+ var valueNode = node;
3622
+ if (node.name === 'EvalFunctionArg') {
3623
+ var expression = node.getChild('EvalExpression');
3624
+ var atom = expression === null || expression === void 0 ? void 0 : expression.firstChild;
3625
+ if (!expression || (atom === null || atom === void 0 ? void 0 : atom.name) !== 'EvalAtom' || atom.nextSibling)
3626
+ return null;
3627
+ valueNode = atom;
3628
+ }
3629
+ var number = valueNode.name === 'Number' ? valueNode : valueNode.getChild('Number');
3035
3630
  if (!number)
3036
3631
  return null;
3037
- var sign = node.name !== 'Number' && node.getChild('Sub') ? -1 : 1;
3632
+ var sign = valueNode.name !== 'Number' && valueNode.getChild('Sub') ? -1 : 1;
3038
3633
  var value = sign * Number(this.nodeText(number).replace(/_/g, ''));
3039
3634
  return Number.isFinite(value) ? value : null;
3040
3635
  };
@@ -3083,10 +3678,10 @@ var Parser = /** @class */ (function () {
3083
3678
  var functionPattern = /\b([A-Za-z_][A-Za-z0-9_-]*)\s*\(/g;
3084
3679
  var match = functionPattern.exec(text);
3085
3680
  while (match) {
3086
- var name_1 = match[1];
3681
+ var name_5 = match[1];
3087
3682
  var nameFrom = context.from + match.index;
3088
3683
  if (!this.containsFunctionCallStartingAt(context, nameFrom)) {
3089
- return this.makeDiagnosticAt(nameFrom, nameFrom + name_1.length, "unknown function \"".concat(name_1, "\""), "unknown-function:".concat(context.from, ":").concat(nameFrom));
3684
+ return this.makeDiagnosticAt(nameFrom, nameFrom + name_5.length, "unknown function \"".concat(name_5, "\""), "unknown-function:".concat(context.from, ":").concat(nameFrom));
3090
3685
  }
3091
3686
  match = functionPattern.exec(text);
3092
3687
  }