diff --git a/src/platform/packages/shared/kbn-esql-ast/scripts/functions.ts b/src/platform/packages/shared/kbn-esql-ast/scripts/functions.ts index 8291646a98404..3eb7f67f63735 100644 --- a/src/platform/packages/shared/kbn-esql-ast/scripts/functions.ts +++ b/src/platform/packages/shared/kbn-esql-ast/scripts/functions.ts @@ -8,7 +8,6 @@ */ import type { RecursivePartial } from '@kbn/utility-types'; import { FunctionDefinition, FunctionDefinitionTypes } from '../src/definitions/types'; -import { validateLogFunctions } from './validators'; import { defaultScalarFunctionLocations, dateDiffSuggestions, @@ -48,12 +47,6 @@ export const extraFunctions: FunctionDefinition[] = [ * and, hence, won't be present in the JSON file. */ export const functionEnrichments: Record> = { - log10: { - validate: validateLogFunctions, - }, - log: { - validate: validateLogFunctions, - }, date_diff: { signatures: [ { diff --git a/src/platform/packages/shared/kbn-esql-ast/scripts/generate_function_definitions.ts b/src/platform/packages/shared/kbn-esql-ast/scripts/generate_function_definitions.ts index d404c76048cd9..60f0de09db83c 100644 --- a/src/platform/packages/shared/kbn-esql-ast/scripts/generate_function_definitions.ts +++ b/src/platform/packages/shared/kbn-esql-ast/scripts/generate_function_definitions.ts @@ -18,7 +18,6 @@ import { } from '../src/definitions/types'; import { Location } from '../src/commands_registry/types'; import { FULL_TEXT_SEARCH_FUNCTIONS } from '../src/definitions/constants'; -import { mathValidators } from './validators'; import { aliasTable, aliases, @@ -149,7 +148,6 @@ const enrichGrouping = ( const enrichOperators = ( operatorsFunctionDefinitions: FunctionDefinition[] ): FunctionDefinition[] => { - // @ts-expect-error Stringified version of the validator function return operatorsFunctionDefinitions.map((op) => { const isMathOperator = MATH_OPERATORS.includes(op.name); const isComparisonOperator = COMPARISON_OPERATORS.includes(op.name); @@ -231,7 +229,6 @@ const enrichOperators = ( // so we are overriding to add proper support locationsAvailable, type: FunctionDefinitionTypes.OPERATOR, - validate: mathValidators[op.name], }; }); }; @@ -315,7 +312,6 @@ const ${getDefinitionName(name)}: FunctionDefinition = { signatures: ${JSON.stringify(signatures, null, 2)}, locationsAvailable: [${locationsAvailable.join(', ')}], ${licenseField} - validate: ${functionDefinition.validate || 'undefined'}, examples: ${JSON.stringify(functionDefinition.examples || [])},${ customParametersSnippet ? `\ncustomParametersSnippet: ${JSON.stringify(customParametersSnippet)},` @@ -346,17 +342,6 @@ const ${getDefinitionName(name)}: FunctionDefinition = { import { i18n } from '@kbn/i18n'; import { Location } from '../../commands_registry/types'; import { type FunctionDefinition, FunctionDefinitionTypes } from '../types'; -${ - functionsType === FunctionDefinitionTypes.SCALAR - ? `import type { ESQLFunction } from '../../types'; -import { isLiteral } from '../../ast/is';;` - : '' -} -${ - functionsType === FunctionDefinitionTypes.OPERATOR - ? `import { isNumericType } from '../types';` - : '' -} diff --git a/src/platform/packages/shared/kbn-esql-ast/scripts/validators.ts b/src/platform/packages/shared/kbn-esql-ast/scripts/validators.ts deleted file mode 100644 index 2c46ddd910ba4..0000000000000 --- a/src/platform/packages/shared/kbn-esql-ast/scripts/validators.ts +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the "Elastic License - * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side - * Public License v 1"; you may not use this file except in compliance with, at - * your election, the "Elastic License 2.0", the "GNU Affero General Public - * License v3.0 only", or the "Server Side Public License, v 1". - */ - -export const validateLogFunctions = `(fnDef: ESQLFunction) => { - const messages = []; - // do not really care here about the base and field - // just need to check both values are not negative - for (const arg of fnDef.args) { - if (isLiteral(arg) && Number(arg.value) < 0) { - messages.push({ - type: 'warning' as const, - code: 'logOfNegativeValue', - text: i18n.translate( - 'kbn-esql-ast.esql.divide.warning.logOfNegativeValue', - { - defaultMessage: 'Log of a negative number results in null: {value}', - values: { - value: arg.value, - }, - } - ), - location: arg.location, - }); - } - } - return messages; -}`; - -export const mathValidators: Record = { - div: `(fnDef) => { - const [left, right] = fnDef.args; - const messages = []; - if (!Array.isArray(left) && !Array.isArray(right)) { - if (right.type === 'literal' && isNumericType(right.literalType)) { - if (right.value === 0) { - messages.push({ - type: 'warning' as const, - code: 'divideByZero', - text: i18n.translate( - 'kbn-esql-ast.esql.divide.warning.divideByZero', - { - defaultMessage: 'Cannot divide by zero: {left}/{right}', - values: { - left: left.text, - right: right.value, - }, - } - ), - location: fnDef.location, - }); - } - } - } - return messages; - }`, - mod: `(fnDef) => { - const [left, right] = fnDef.args; - const messages = []; - if (!Array.isArray(left) && !Array.isArray(right)) { - if (right.type === 'literal' && isNumericType(right.literalType)) { - if (right.value === 0) { - messages.push({ - type: 'warning' as const, - code: 'moduleByZero', - text: i18n.translate( - 'kbn-esql-ast.esql.divide.warning.zeroModule', - { - defaultMessage: 'Module by zero can return null value: {left}%{right}', - values: { - left: left.text, - right: right.value, - }, - } - ), - location: fnDef.location, - }); - } - } - } - return messages; - }`, -}; diff --git a/src/platform/packages/shared/kbn-esql-ast/src/commands_registry/commands/enrich/validate.test.ts b/src/platform/packages/shared/kbn-esql-ast/src/commands_registry/commands/enrich/validate.test.ts index d1a3d51c5bfed..8fbf4dbf06961 100644 --- a/src/platform/packages/shared/kbn-esql-ast/src/commands_registry/commands/enrich/validate.test.ts +++ b/src/platform/packages/shared/kbn-esql-ast/src/commands_registry/commands/enrich/validate.test.ts @@ -67,9 +67,6 @@ describe('ENRICH Validation', () => { enrichExpectErrors('from a_index | enrich `this``is fine`', ['Unknown policy [`this``is]']); enrichExpectErrors('from a_index | enrich this is fine', ['Unknown policy [this]']); enrichExpectErrors(`from a_index |enrich missing-policy `, ['Unknown policy [missing-policy]']); - enrichExpectErrors('from a_index | enrich my-pol*', [ - 'Using wildcards (*) in ENRICH is not allowed [my-pol*]', - ]); }); test('validates the columns', () => { diff --git a/src/platform/packages/shared/kbn-esql-ast/src/commands_registry/commands/enrich/validate.ts b/src/platform/packages/shared/kbn-esql-ast/src/commands_registry/commands/enrich/validate.ts index 89c65d4355ac4..2fc375fe8bdb1 100644 --- a/src/platform/packages/shared/kbn-esql-ast/src/commands_registry/commands/enrich/validate.ts +++ b/src/platform/packages/shared/kbn-esql-ast/src/commands_registry/commands/enrich/validate.ts @@ -12,10 +12,6 @@ import { ENRICH_MODES } from './util'; import type { ESQLPolicy, ICommandContext, ICommandCallbacks } from '../../types'; import { validateCommandArguments } from '../../../definitions/utils/validation'; -function hasWildcard(name: string) { - return /\*/.test(name); -} - export const validate = ( command: ESQLCommand, ast: ESQLAst, @@ -28,24 +24,14 @@ export const validate = ( const index = source.index; const policies = context?.policies || new Map(); - if (index) { - if (hasWildcard(index.valueUnquoted)) { - messages.push( - getMessageFromId({ - messageId: 'wildcardNotSupportedForCommand', - values: { command: 'ENRICH', value: index.valueUnquoted }, - locations: index.location, - }) - ); - } else if (!policies.has(index.valueUnquoted)) { - messages.push( - getMessageFromId({ - messageId: 'unknownPolicy', - values: { name: index.valueUnquoted }, - locations: index.location, - }) - ); - } + if (index && !policies.has(index.valueUnquoted)) { + messages.push( + getMessageFromId({ + messageId: 'unknownPolicy', + values: { name: index.valueUnquoted }, + locations: index.location, + }) + ); } if (cluster) { diff --git a/src/platform/packages/shared/kbn-esql-ast/src/commands_registry/commands/eval/validate.test.ts b/src/platform/packages/shared/kbn-esql-ast/src/commands_registry/commands/eval/validate.test.ts index dd58042cdaede..8aecf610ae3cc 100644 --- a/src/platform/packages/shared/kbn-esql-ast/src/commands_registry/commands/eval/validate.test.ts +++ b/src/platform/packages/shared/kbn-esql-ast/src/commands_registry/commands/eval/validate.test.ts @@ -118,201 +118,6 @@ describe('EVAL Validation', () => { } }); - test('warnings when log is used', () => { - evalExpectErrors('from a_index | eval log10(-1)', [ - 'Log of a negative number results in null: -1', - ]); - evalExpectErrors('from a_index | eval log(-1)', [ - 'Log of a negative number results in null: -1', - ]); - evalExpectErrors('from a_index | eval log(-1, 20)', [ - 'Log of a negative number results in null: -1', - ]); - evalExpectErrors('from a_index | eval log(-1, -20)', [ - 'Log of a negative number results in null: -1', - 'Log of a negative number results in null: -20', - ]); - evalExpectErrors('from a_index | eval col0 = log(-1, -20)', [ - 'Log of a negative number results in null: -1', - 'Log of a negative number results in null: -20', - ]); - }); - - test('validates operators', () => { - for (const op of ['>', '>=', '<', '<=', '==', '!=']) { - evalExpectErrors(`from a_index | eval doubleField ${op} 0`, []); - evalExpectErrors(`from a_index | eval NOT doubleField ${op} 0`, []); - evalExpectErrors(`from a_index | eval (doubleField ${op} 0)`, []); - evalExpectErrors(`from a_index | eval (NOT (doubleField ${op} 0))`, []); - evalExpectErrors(`from a_index | eval 1 ${op} 0`, []); - for (const type of ['text', 'double', 'date', 'boolean', 'ip']) { - if (type === 'boolean') { - evalExpectErrors( - `from a_index | eval ${type}Field ${op} ${type}Field`, - type !== 'boolean' || ['==', '!='].includes(op) - ? [] - : [ - `Argument of [${op}] must be [date], found value [${type}Field] type [${type}]`, - `Argument of [${op}] must be [date], found value [${type}Field] type [${type}]`, - ] - ); - } else { - evalExpectErrors( - `from a_index | eval ${type}Field ${op} ${type}Field`, - type !== 'boolean' || ['==', '!='].includes(op) - ? [] - : [ - `Argument of [${op}] must be [double], found value [${type}Field] type [${type}]`, - `Argument of [${op}] must be [double], found value [${type}Field] type [${type}]`, - ] - ); - } - } - // Implicit casting of literal values tests - evalExpectErrors(`from a_index | eval doubleField ${op} textField`, [ - `Argument of [${op}] must be [double], found value [textField] type [text]`, - ]); - evalExpectErrors(`from a_index | eval keywordField ${op} doubleField`, [ - `Argument of [${op}] must be [double], found value [keywordField] type [keyword]`, - ]); - evalExpectErrors(`from a_index | eval doubleField ${op} "2022"`, [ - op === '==' || op === '!=' - ? `Argument of [${op}] must be [boolean], found value [doubleField] type [double]` - : `Argument of [${op}] must be [date], found value [doubleField] type [double]`, - ]); - - evalExpectErrors(`from a_index | eval dateField ${op} keywordField`, [ - `Argument of [${op}] must be [date], found value [keywordField] type [keyword]`, - ]); - evalExpectErrors(`from a_index | eval keywordField ${op} dateField`, [ - `Argument of [${op}] must be [date], found value [keywordField] type [keyword]`, - ]); - - // Check that the implicit cast doesn't apply for fields - evalExpectErrors(`from a_index | eval textField ${op} 0`, [ - `Argument of [${op}] must be [double], found value [textField] type [text]`, - ]); - evalExpectErrors(`from a_index | eval textField ${op} now()`, [ - `Argument of [${op}] must be [date], found value [textField] type [text]`, - ]); - - evalExpectErrors(`from a_index | eval dateField ${op} "2022"`, []); - evalExpectErrors(`from a_index | eval "2022" ${op} dateField`, []); - - evalExpectErrors(`from a_index | eval versionField ${op} "1.2.3"`, []); - evalExpectErrors(`from a_index | eval "1.2.3" ${op} versionField`, []); - - evalExpectErrors( - `from a_index | eval booleanField ${op} "true"`, - ['==', '!='].includes(op) - ? [] - : [`Argument of [${op}] must be [date], found value [booleanField] type [boolean]`] - ); - evalExpectErrors( - `from a_index | eval "true" ${op} booleanField`, - ['==', '!='].includes(op) - ? [] - : [`Argument of [${op}] must be [date], found value [booleanField] type [boolean]`] - ); - - evalExpectErrors(`from a_index | eval ipField ${op} "136.36.3.205"`, []); - evalExpectErrors(`from a_index | eval "136.36.3.205" ${op} ipField`, []); - } - // casting for IN for version, date, boolean, ip - evalExpectErrors( - 'from a_index | eval versionField in ("1.2.3", "4.5.6", to_version("2.3.2"))', - [] - ); - evalExpectErrors( - 'from a_index | eval dateField in ("2023-12-12", "2024-12-12", date_parse("yyyy-MM-dd", "2025-12-12"))', - [] - ); - evalExpectErrors('from a_index | eval booleanField in ("true", "false", false)', []); - evalExpectErrors( - 'from a_index | eval ipField in ("136.36.3.205", "136.36.3.206", to_ip("136.36.3.207"))', - [] - ); - - for (const op of ['+', '-', '*', '/', '%']) { - evalExpectErrors(`from a_index | eval doubleField ${op} 1`, []); - evalExpectErrors(`from a_index | eval (doubleField ${op} 1)`, []); - evalExpectErrors(`from a_index | eval 1 ${op} 1`, []); - evalExpectErrors( - `from a_index | eval now() ${op} now()`, - ['+', '-'].includes(op) - ? [`Argument of [${op}] must be [date_period], found value [now()] type [date]`] - : [ - `Argument of [${op}] must be [double], found value [now()] type [date]`, - `Argument of [${op}] must be [double], found value [now()] type [date]`, - ] - ); - - evalExpectErrors( - `from a_index | eval 1 ${op} "1"`, - ['+', '-'].includes(op) - ? [`Argument of [${op}] must be [date], found value [1] type [integer]`] - : [`Argument of [${op}] must be [double], found value [\"1\"] type [keyword]`] - ); - evalExpectErrors( - `from a_index | eval "1" ${op} 1`, - ['+', '-'].includes(op) - ? [`Argument of [${op}] must be [date_period], found value [1] type [integer]`] - : [`Argument of [${op}] must be [double], found value [\"1\"] type [keyword]`] - ); - // TODO: enable when https://github.com/elastic/elasticsearch/issues/108432 is complete - // evalExpectErrors(`from a_index | eval "2022" ${op} 1 day`, []); - } - for (const divideByZeroExpr of ['1/0', 'col0 = 1/0', '1 + 1/0']) { - evalExpectErrors(`from a_index | eval ${divideByZeroExpr}`, ['Cannot divide by zero: 1/0']); - } - for (const divideByZeroExpr of ['1%0', 'col0 = 1%0', '1 + 1%0']) { - evalExpectErrors(`from a_index | eval ${divideByZeroExpr}`, [ - 'Module by zero can return null value: 1%0', - ]); - } - for (const op of ['like', 'rlike']) { - evalExpectErrors(`from a_index | eval textField ${op} "?a"`, []); - evalExpectErrors(`from a_index | eval textField NOT ${op} "?a"`, []); - evalExpectErrors(`from a_index | eval NOT textField ${op} "?a"`, []); - evalExpectErrors(`from a_index | eval NOT textField NOT ${op} "?a"`, []); - evalExpectErrors(`from a_index | eval doubleField ${op} "?a"`, [ - `Argument of [${op}] must be [keyword], found value [doubleField] type [double]`, - ]); - evalExpectErrors(`from a_index | eval doubleField NOT ${op} "?a"`, [ - `Argument of [not ${op}] must be [keyword], found value [doubleField] type [double]`, - ]); - evalExpectErrors(`from a_index | eval NOT doubleField ${op} "?a"`, [ - `Argument of [${op}] must be [keyword], found value [doubleField] type [double]`, - ]); - evalExpectErrors(`from a_index | eval NOT doubleField NOT ${op} "?a"`, [ - `Argument of [not ${op}] must be [keyword], found value [doubleField] type [double]`, - ]); - } - - // test lists - evalExpectErrors('from a_index | eval 1 in (1, 2, 3)', []); - evalExpectErrors('from a_index | eval doubleField in (1, 2, 3)', []); - evalExpectErrors('from a_index | eval doubleField not in (1, 2, 3)', []); - evalExpectErrors('from a_index | eval doubleField not in (1, 2, 3, doubleField)', []); - evalExpectErrors('from a_index | eval 1 in (1, 2, 3, round(doubleField))', []); - evalExpectErrors('from a_index | eval "a" in ("a", "b", "c")', []); - evalExpectErrors('from a_index | eval textField in ("a", "b", "c")', []); - evalExpectErrors('from a_index | eval textField not in ("a", "b", "c")', []); - evalExpectErrors('from a_index | eval textField not in ("a", "b", "c", textField)', []); - evalExpectErrors('from a_index | eval 1 in ("a", "b", "c")', [ - 'Argument of [in] must be [integer[]], found value [("a", "b", "c")] type [(keyword, keyword, keyword)]', - ]); - evalExpectErrors('from a_index | eval doubleField in ("a", "b", "c")', [ - // 'Argument of [in] must be [number[]], found value [("a", "b", "c")] type [(string, string, string)]', - ]); - evalExpectErrors('from a_index | eval doubleField not in ("a", "b", "c")', [ - // 'Argument of [not_in] must be [number[]], found value [("a", "b", "c")] type [(string, string, string)]', - ]); - evalExpectErrors('from a_index | eval doubleField not in (1, 2, 3, textField)', [ - // 'Argument of [not_in] must be [number[]], found value [(1, 2, 3, textField)] type [(number, number, number, string)]', - ]); - }); - test('rest validations', () => { const newUserDefinedColumns = new Map(mockContext.userDefinedColumns); newUserDefinedColumns.set('avg(doubleField)', [ diff --git a/src/platform/packages/shared/kbn-esql-ast/src/commands_registry/commands/stats/validate.test.ts b/src/platform/packages/shared/kbn-esql-ast/src/commands_registry/commands/stats/validate.test.ts index 1b1475d282839..ba5d764d9e923 100644 --- a/src/platform/packages/shared/kbn-esql-ast/src/commands_registry/commands/stats/validate.test.ts +++ b/src/platform/packages/shared/kbn-esql-ast/src/commands_registry/commands/stats/validate.test.ts @@ -84,43 +84,6 @@ describe('STATS Validation', () => { } }); - test('errors on agg and non-agg mix', () => { - statsExpectErrors('from a_index | STATS sum( doubleField ) + abs( doubleField ) ', [ - 'Cannot combine aggregation and non-aggregation values in [STATS], found [sum(doubleField)+abs(doubleField)]', - ]); - statsExpectErrors('from a_index | STATS abs( doubleField + sum( doubleField )) ', [ - 'Cannot combine aggregation and non-aggregation values in [STATS], found [abs(doubleField+sum(doubleField))]', - ]); - // This is a valid expression as it is an operation on two aggregation functions - statsExpectErrors( - 'from a_index | STATS sum(doubleField) / (min(doubleField) + max(doubleField)) ', - [] - ); - }); - - test('errors on each aggregation field, which does not contain at least one agg function', () => { - statsExpectErrors('from a_index | stats doubleField + 1', [ - 'At least one aggregation function required in [STATS], found [doubleField+1]', - ]); - statsExpectErrors('from a_index | stats doubleField + 1, textField', [ - 'At least one aggregation function required in [STATS], found [doubleField+1]', - 'Expected an aggregate function or group but got [textField] of type [FieldAttribute]', - ]); - statsExpectErrors('from a_index | stats doubleField + 1, doubleField + 2, count()', [ - 'At least one aggregation function required in [STATS], found [doubleField+1]', - 'At least one aggregation function required in [STATS], found [doubleField+2]', - ]); - statsExpectErrors('from a_index | stats doubleField + 1, doubleField + count(), count()', [ - 'At least one aggregation function required in [STATS], found [doubleField+1]', - ]); - statsExpectErrors('from a_index | stats 5 + doubleField + 1', [ - 'At least one aggregation function required in [STATS], found [5+doubleField+1]', - ]); - statsExpectErrors('from a_index | stats doubleField + 1 by ipField', [ - 'At least one aggregation function required in [STATS], found [doubleField+1]', - ]); - }); - test('errors when input is not an aggregate function', () => { statsExpectErrors('from a_index | stats doubleField ', [ 'Expected an aggregate function or group but got [doubleField] of type [FieldAttribute]', @@ -142,15 +105,6 @@ describe('STATS Validation', () => { ]); }); - test('semantic errors', () => { - statsExpectErrors('from a_index | stats count(round(*))', [ - 'Using wildcards (*) in round is not allowed', - ]); - statsExpectErrors('from a_index | stats count(count(*))', [ - `Aggregate function's parameters must be an attribute, literal or a non-aggregation function; found [count(*)] of type [long]`, - ]); - }); - test('allows WHERE clause', () => { statsExpectErrors('FROM a_index | STATS col0 = avg(doubleField) WHERE 123', []); }); @@ -179,15 +133,6 @@ describe('STATS Validation', () => { } }); - test('semantic errors in ', () => { - statsExpectErrors('from a_index | stats count(round(*)) BY ipField', [ - 'Using wildcards (*) in round is not allowed', - ]); - statsExpectErrors('from a_index | stats count(count(*)) BY ipField', [ - `Aggregate function's parameters must be an attribute, literal or a non-aggregation function; found [count(*)] of type [long]`, - ]); - }); - test('various errors', () => { statsExpectErrors('from a_index | stats avg(doubleField) by percentile(doubleField)', [ 'STATS BY does not support function percentile', @@ -252,21 +197,6 @@ describe('STATS Validation', () => { [] ); }); - - test('errors', () => { - statsExpectErrors(`from a_index | stats 5 ${operatorsWrapping} + doubleField`, [ - `At least one aggregation function required in [STATS], found [5${operatorsWrapping}+doubleField]`, - ]); - statsExpectErrors(`from a_index | stats 5 + doubleField ${operatorsWrapping}`, [ - `At least one aggregation function required in [STATS], found [5+doubleField${operatorsWrapping}]`, - ]); - statsExpectErrors( - `from a_index | stats 5 + doubleField ${operatorsWrapping}, col0 = sum(doubleField)`, - [ - `At least one aggregation function required in [STATS], found [5+doubleField${operatorsWrapping}]`, - ] - ); - }); }); describe('EVAL', () => { @@ -303,27 +233,6 @@ describe('STATS Validation', () => { [] ); }); - - test('errors', () => { - statsExpectErrors( - `from a_index | stats ${evalWrapping} doubleField + sum(doubleField) ${closingWrapping}`, - [ - `Cannot combine aggregation and non-aggregation values in [STATS], found [${evalWrapping}doubleField+sum(doubleField)${closingWrapping}]`, - ] - ); - statsExpectErrors( - `from a_index | stats ${evalWrapping} doubleField + sum(doubleField) ${closingWrapping}, col0 = sum(doubleField)`, - [ - `Cannot combine aggregation and non-aggregation values in [STATS], found [${evalWrapping}doubleField+sum(doubleField)${closingWrapping}]`, - ] - ); - statsExpectErrors( - `from a_index | stats col0 = ${evalWrapping} doubleField + sum(doubleField) ${closingWrapping}, var0 = sum(doubleField)`, - [ - `Cannot combine aggregation and non-aggregation values in [STATS], found [${evalWrapping}doubleField+sum(doubleField)${closingWrapping}]`, - ] - ); - }); }); }); } diff --git a/src/platform/packages/shared/kbn-esql-ast/src/commands_registry/commands/stats/validate.ts b/src/platform/packages/shared/kbn-esql-ast/src/commands_registry/commands/stats/validate.ts index e38fc7dae9991..1de05826d7850 100644 --- a/src/platform/packages/shared/kbn-esql-ast/src/commands_registry/commands/stats/validate.ts +++ b/src/platform/packages/shared/kbn-esql-ast/src/commands_registry/commands/stats/validate.ts @@ -6,12 +6,9 @@ * your election, the "Elastic License 2.0", the "GNU Affero General Public * License v3.0 only", or the "Server Side Public License, v 1". */ -import { i18n } from '@kbn/i18n'; -import type { ESQLCommand, ESQLMessage, ESQLFunction, ESQLAst } from '../../../types'; +import type { ESQLCommand, ESQLMessage, ESQLAst } from '../../../types'; import { validateCommandArguments } from '../../../definitions/utils/validation'; import { ICommandContext, ICommandCallbacks } from '../../types'; -import { isFunctionExpression, isWhereExpression, isAssignment } from '../../../ast/is'; -import { checkAggExistence, checkFunctionContent } from './utils'; export const validate = ( command: ESQLCommand, @@ -20,80 +17,6 @@ export const validate = ( callbacks?: ICommandCallbacks ): ESQLMessage[] => { const messages: ESQLMessage[] = []; - const commandName = command.name.toUpperCase(); - if (!command.args.length) { - messages.push({ - location: command.location, - text: i18n.translate('kbn-esql-ast.esql.validation.statsNoArguments', { - defaultMessage: - 'At least one aggregation or grouping expression required in [{commandName}]', - values: { commandName }, - }), - type: 'error', - code: 'statsNoArguments', - }); - } - - // now that all functions are supported, there's a specific check to perform - // unfortunately the logic here is a bit complex as it needs to dig deeper into the args - // until an agg function is detected - // in the long run this might be integrated into the validation function - const statsArg = command.args - .flatMap((arg) => { - if (isWhereExpression(arg) && isFunctionExpression(arg.args[0])) { - arg = arg.args[0] as ESQLFunction; - } - - return isAssignment(arg) ? arg.args[1] : arg; - }) - .filter(isFunctionExpression); - - if (statsArg.length) { - // first check: is there an agg function somewhere? - const noAggsExpressions = statsArg.filter((arg) => !checkAggExistence(arg)); - - if (noAggsExpressions.length) { - messages.push( - ...noAggsExpressions.map((fn) => ({ - location: fn.location, - text: i18n.translate('kbn-esql-ast.esql.validation.statsNoAggFunction', { - defaultMessage: - 'At least one aggregation function required in [{commandName}], found [{expression}]', - values: { - expression: fn.text, - commandName, - }, - }), - type: 'error' as const, - code: 'statsNoAggFunction', - })) - ); - } else { - // @TODO: improve here the check to get the last instance of the invalidExpression - // to provide a better location for the error message - // i.e. STATS round(round(round( a + sum(b) ))) - // should return the location of the + node, just before the agg one - const invalidExpressions = statsArg.filter((arg) => !checkFunctionContent(arg)); - - if (invalidExpressions.length) { - messages.push( - ...invalidExpressions.map((fn) => ({ - location: fn.location, - text: i18n.translate('kbn-esql-ast.esql.validation.noCombinationOfAggAndNonAggValues', { - defaultMessage: - 'Cannot combine aggregation and non-aggregation values in [{commandName}], found [{expression}]', - values: { - expression: fn.text, - commandName, - }, - }), - type: 'error' as const, - code: 'statsNoCombinationOfAggAndNonAggValues', - })) - ); - } - } - } messages.push(...validateCommandArguments(command, ast, context, callbacks)); diff --git a/src/platform/packages/shared/kbn-esql-ast/src/definitions/constants.ts b/src/platform/packages/shared/kbn-esql-ast/src/definitions/constants.ts index 2a32f806dace1..2de19c0406fc1 100644 --- a/src/platform/packages/shared/kbn-esql-ast/src/definitions/constants.ts +++ b/src/platform/packages/shared/kbn-esql-ast/src/definitions/constants.ts @@ -144,17 +144,3 @@ export const timeUnits: string[] = [ ]; export const FULL_TEXT_SEARCH_FUNCTIONS = ['match', 'match_operator', 'qstr', 'kql']; -export const UNSUPPORTED_COMMANDS_BEFORE_QSTR = new Set([ - 'show', - 'row', - 'dissect', - 'enrich', - 'eval', - 'grok', - 'keep', - 'mv_expand', - 'rename', - 'stats', - 'limit', -]); -export const UNSUPPORTED_COMMANDS_BEFORE_MATCH = new Set(['limit']); diff --git a/src/platform/packages/shared/kbn-esql-ast/src/definitions/generated/aggregation_functions.ts b/src/platform/packages/shared/kbn-esql-ast/src/definitions/generated/aggregation_functions.ts index c5d462aa6677e..718fea84f0a22 100644 --- a/src/platform/packages/shared/kbn-esql-ast/src/definitions/generated/aggregation_functions.ts +++ b/src/platform/packages/shared/kbn-esql-ast/src/definitions/generated/aggregation_functions.ts @@ -72,7 +72,6 @@ const avgDefinition: FunctionDefinition = { }, ], locationsAvailable: [Location.STATS], - validate: undefined, examples: [ 'FROM employees\n| STATS AVG(height)', 'FROM employees\n| STATS avg_salary_change = ROUND(AVG(MV_AVG(salary_change)), 10)', @@ -242,7 +241,6 @@ const countDefinition: FunctionDefinition = { }, ], locationsAvailable: [Location.STATS], - validate: undefined, examples: [ 'FROM employees\n| STATS COUNT(height)', 'FROM employees\n| STATS count = COUNT(*) BY languages\n| SORT languages DESC', @@ -814,7 +812,6 @@ const countDistinctDefinition: FunctionDefinition = { }, ], locationsAvailable: [Location.STATS], - validate: undefined, examples: [ 'FROM hosts\n| STATS COUNT_DISTINCT(ip0), COUNT_DISTINCT(ip1)', 'FROM hosts\n| STATS COUNT_DISTINCT(ip0, 80000), COUNT_DISTINCT(ip1, 5)', @@ -944,7 +941,6 @@ const maxDefinition: FunctionDefinition = { }, ], locationsAvailable: [Location.STATS], - validate: undefined, examples: [ 'FROM employees\n| STATS MAX(languages)', 'FROM employees\n| STATS max_avg_salary_change = MAX(MV_AVG(salary_change))', @@ -994,7 +990,6 @@ const medianDefinition: FunctionDefinition = { }, ], locationsAvailable: [Location.STATS], - validate: undefined, examples: [ 'FROM employees\n| STATS MEDIAN(salary), PERCENTILE(salary, 50)', 'FROM employees\n| STATS median_max_salary_change = MEDIAN(MV_MAX(salary_change))', @@ -1044,7 +1039,6 @@ const medianAbsoluteDeviationDefinition: FunctionDefinition = { }, ], locationsAvailable: [Location.STATS], - validate: undefined, examples: [ 'FROM employees\n| STATS MEDIAN(salary), MEDIAN_ABSOLUTE_DEVIATION(salary)', 'FROM employees\n| STATS m_a_d_max_salary_change = MEDIAN_ABSOLUTE_DEVIATION(MV_MAX(salary_change))', @@ -1173,7 +1167,6 @@ const minDefinition: FunctionDefinition = { }, ], locationsAvailable: [Location.STATS], - validate: undefined, examples: [ 'FROM employees\n| STATS MIN(languages)', 'FROM employees\n| STATS min_avg_salary_change = MIN(MV_AVG(salary_change))', @@ -1337,7 +1330,6 @@ const percentileDefinition: FunctionDefinition = { }, ], locationsAvailable: [Location.STATS], - validate: undefined, examples: [ 'FROM employees\n| STATS p0 = PERCENTILE(salary, 0)\n , p50 = PERCENTILE(salary, 50)\n , p99 = PERCENTILE(salary, 99)', 'FROM employees\n| STATS p80_max_salary_change = PERCENTILE(MV_MAX(salary_change), 80)', @@ -1581,7 +1573,6 @@ const sampleDefinition: FunctionDefinition = { }, ], locationsAvailable: [Location.STATS], - validate: undefined, examples: ['FROM employees\n| STATS sample = SAMPLE(gender, 5)'], }; @@ -1617,7 +1608,6 @@ const stCentroidAggDefinition: FunctionDefinition = { }, ], locationsAvailable: [Location.STATS], - validate: undefined, examples: ['FROM airports\n| STATS centroid=ST_CENTROID_AGG(location)'], }; @@ -1676,7 +1666,6 @@ const stExtentAggDefinition: FunctionDefinition = { }, ], locationsAvailable: [Location.STATS], - validate: undefined, examples: ['FROM airports\n| WHERE country == "India"\n| STATS extent = ST_EXTENT_AGG(location)'], }; @@ -1722,7 +1711,6 @@ const stdDevDefinition: FunctionDefinition = { }, ], locationsAvailable: [Location.STATS], - validate: undefined, examples: [ 'FROM employees\n| STATS STD_DEV(height)', 'FROM employees\n| STATS stddev_salary_change = STD_DEV(MV_MAX(salary_change))', @@ -1771,7 +1759,6 @@ const sumDefinition: FunctionDefinition = { }, ], locationsAvailable: [Location.STATS], - validate: undefined, examples: [ 'FROM employees\n| STATS SUM(languages)', 'FROM employees\n| STATS total_salary_changes = SUM(MV_MAX(salary_change))', @@ -1968,7 +1955,6 @@ const topDefinition: FunctionDefinition = { }, ], locationsAvailable: [Location.STATS], - validate: undefined, examples: [ 'FROM employees\n| STATS top_salaries = TOP(salary, 3, "desc"), top_salary = MAX(salary)', ], @@ -2137,7 +2123,6 @@ const valuesDefinition: FunctionDefinition = { }, ], locationsAvailable: [Location.STATS], - validate: undefined, examples: [ 'FROM employees\n| EVAL first_letter = SUBSTRING(first_name, 0, 1)\n| STATS first_name = MV_SORT(VALUES(first_name)) BY first_letter\n| SORT first_letter', ], @@ -2290,7 +2275,6 @@ const weightedAvgDefinition: FunctionDefinition = { }, ], locationsAvailable: [Location.STATS], - validate: undefined, examples: [ 'FROM employees\n| STATS w_avg = WEIGHTED_AVG(salary, height) BY languages\n| EVAL w_avg = ROUND(w_avg)\n| KEEP w_avg, languages\n| SORT languages', ], diff --git a/src/platform/packages/shared/kbn-esql-ast/src/definitions/generated/function_names.ts b/src/platform/packages/shared/kbn-esql-ast/src/definitions/generated/function_names.ts index 853912a8f988c..6755238f008ee 100644 --- a/src/platform/packages/shared/kbn-esql-ast/src/definitions/generated/function_names.ts +++ b/src/platform/packages/shared/kbn-esql-ast/src/definitions/generated/function_names.ts @@ -184,6 +184,7 @@ export const esqlFunctionNames = [ 'V_COSINE', 'V_DOT_PRODUCT', 'V_L1_NORM', + 'V_L2_NORM', 'VALUES', 'WEIGHTED_AVG', 'ADD', diff --git a/src/platform/packages/shared/kbn-esql-ast/src/definitions/generated/grouping_functions.ts b/src/platform/packages/shared/kbn-esql-ast/src/definitions/generated/grouping_functions.ts index a190ecf95e82c..d1bf97857ab76 100644 --- a/src/platform/packages/shared/kbn-esql-ast/src/definitions/generated/grouping_functions.ts +++ b/src/platform/packages/shared/kbn-esql-ast/src/definitions/generated/grouping_functions.ts @@ -1511,7 +1511,6 @@ const bucketDefinition: FunctionDefinition = { }, ], locationsAvailable: [Location.STATS, Location.STATS_BY], - validate: undefined, examples: [ 'FROM employees\n| WHERE hire_date >= "1985-01-01T00:00:00Z" AND hire_date < "1986-01-01T00:00:00Z"\n| STATS hire_date = MV_SORT(VALUES(hire_date)) BY month = BUCKET(hire_date, 20, "1985-01-01T00:00:00Z", "1986-01-01T00:00:00Z")', 'FROM employees\n| WHERE hire_date >= "1985-01-01T00:00:00Z" AND hire_date < "1986-01-01T00:00:00Z"\n| STATS hires_per_month = COUNT(*) BY month = BUCKET(hire_date, 20, "1985-01-01T00:00:00Z", "1986-01-01T00:00:00Z")\n| SORT month', @@ -1561,7 +1560,6 @@ const categorizeDefinition: FunctionDefinition = { ], locationsAvailable: [Location.STATS, Location.STATS_BY], license: 'PLATINUM', - validate: undefined, examples: ['FROM sample_data\n| STATS count=COUNT() BY category=CATEGORIZE(message)'], }; export const groupingFunctionDefinitions = [bucketDefinition, categorizeDefinition]; diff --git a/src/platform/packages/shared/kbn-esql-ast/src/definitions/generated/operators.ts b/src/platform/packages/shared/kbn-esql-ast/src/definitions/generated/operators.ts index 7c3809ed4ef44..3006bae98783d 100644 --- a/src/platform/packages/shared/kbn-esql-ast/src/definitions/generated/operators.ts +++ b/src/platform/packages/shared/kbn-esql-ast/src/definitions/generated/operators.ts @@ -30,8 +30,6 @@ import { i18n } from '@kbn/i18n'; import { Location } from '../../commands_registry/types'; import { type FunctionDefinition, FunctionDefinitionTypes } from '../types'; -import { isNumericType } from '../types'; - // Do not edit this manually... generated by scripts/generate_function_definitions.ts const addDefinition: FunctionDefinition = { type: FunctionDefinitionTypes.OPERATOR, @@ -380,7 +378,6 @@ const addDefinition: FunctionDefinition = { Location.STATS_BY, Location.COMPLETION, ], - validate: undefined, examples: [], }; @@ -556,29 +553,6 @@ const divDefinition: FunctionDefinition = { Location.STATS_BY, Location.COMPLETION, ], - validate: (fnDef) => { - const [left, right] = fnDef.args; - const messages = []; - if (!Array.isArray(left) && !Array.isArray(right)) { - if (right.type === 'literal' && isNumericType(right.literalType)) { - if (right.value === 0) { - messages.push({ - type: 'warning' as const, - code: 'divideByZero', - text: i18n.translate('kbn-esql-ast.esql.divide.warning.divideByZero', { - defaultMessage: 'Cannot divide by zero: {left}/{right}', - values: { - left: left.text, - right: right.value, - }, - }), - location: fnDef.location, - }); - } - } - } - return messages; - }, examples: [], }; @@ -1035,7 +1009,6 @@ const equalsDefinition: FunctionDefinition = { Location.STATS_BY, Location.COMPLETION, ], - validate: undefined, examples: [], }; @@ -1417,7 +1390,6 @@ const greaterThanDefinition: FunctionDefinition = { Location.STATS_BY, Location.COMPLETION, ], - validate: undefined, examples: [], }; @@ -1799,7 +1771,6 @@ const greaterThanOrEqualDefinition: FunctionDefinition = { Location.STATS_BY, Location.COMPLETION, ], - validate: undefined, examples: [], }; @@ -2047,7 +2018,6 @@ const inDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: ['ROW a = 1, b = 4, c = 3\n| WHERE c-a IN (3, b / 2, a)'], }; @@ -2250,7 +2220,6 @@ const isNotNullDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: ['FROM employees\n| WHERE is_rehired IS NOT NULL\n| STATS COUNT(emp_no)'], }; @@ -2453,7 +2422,6 @@ const isNullDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: ['FROM employees\n| WHERE birth_date IS NULL'], }; @@ -2835,7 +2803,6 @@ const lessThanDefinition: FunctionDefinition = { Location.STATS_BY, Location.COMPLETION, ], - validate: undefined, examples: [], }; @@ -3217,7 +3184,6 @@ const lessThanOrEqualDefinition: FunctionDefinition = { Location.STATS_BY, Location.COMPLETION, ], - validate: undefined, examples: [], }; @@ -3273,7 +3239,6 @@ const likeDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: ['FROM employees\n| WHERE first_name LIKE """?b*"""\n| KEEP first_name, last_name'], }; @@ -3783,7 +3748,6 @@ const matchOperatorDefinition: FunctionDefinition = { }, ], locationsAvailable: [Location.WHERE, Location.STATS_WHERE], - validate: undefined, examples: ['FROM books\n| WHERE author:"Faulkner"'], }; @@ -3959,29 +3923,6 @@ const modDefinition: FunctionDefinition = { Location.STATS_BY, Location.COMPLETION, ], - validate: (fnDef) => { - const [left, right] = fnDef.args; - const messages = []; - if (!Array.isArray(left) && !Array.isArray(right)) { - if (right.type === 'literal' && isNumericType(right.literalType)) { - if (right.value === 0) { - messages.push({ - type: 'warning' as const, - code: 'moduleByZero', - text: i18n.translate('kbn-esql-ast.esql.divide.warning.zeroModule', { - defaultMessage: 'Module by zero can return null value: {left}%{right}', - values: { - left: left.text, - right: right.value, - }, - }), - location: fnDef.location, - }); - } - } - } - return messages; - }, examples: [], }; @@ -4157,7 +4098,6 @@ const mulDefinition: FunctionDefinition = { Location.STATS_BY, Location.COMPLETION, ], - validate: undefined, examples: [], }; @@ -4223,7 +4163,6 @@ const negDefinition: FunctionDefinition = { }, ], locationsAvailable: [Location.STATS], - validate: undefined, examples: [], }; @@ -4471,7 +4410,6 @@ const notInDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: [], }; @@ -4527,7 +4465,6 @@ const notLikeDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: [], }; @@ -4583,7 +4520,6 @@ const notRlikeDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: [], }; @@ -5040,7 +4976,6 @@ const notEqualsDefinition: FunctionDefinition = { Location.STATS_BY, Location.COMPLETION, ], - validate: undefined, examples: [], }; @@ -5096,7 +5031,6 @@ const rlikeDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: [ 'FROM employees\n| WHERE first_name RLIKE """.leja.*"""\n| KEEP first_name, last_name', ], @@ -5420,7 +5354,6 @@ const subDefinition: FunctionDefinition = { Location.STATS_BY, Location.COMPLETION, ], - validate: undefined, examples: [], }; export const operatorFunctionDefinitions = [ diff --git a/src/platform/packages/shared/kbn-esql-ast/src/definitions/generated/scalar_functions.ts b/src/platform/packages/shared/kbn-esql-ast/src/definitions/generated/scalar_functions.ts index fd29ae7c4bac7..277c8f0112b8c 100644 --- a/src/platform/packages/shared/kbn-esql-ast/src/definitions/generated/scalar_functions.ts +++ b/src/platform/packages/shared/kbn-esql-ast/src/definitions/generated/scalar_functions.ts @@ -29,8 +29,6 @@ import { i18n } from '@kbn/i18n'; import { Location } from '../../commands_registry/types'; import { type FunctionDefinition, FunctionDefinitionTypes } from '../types'; -import type { ESQLFunction } from '../../types'; -import { isLiteral } from '../../ast/is'; // Do not edit this manually... generated by scripts/generate_function_definitions.ts const absDefinition: FunctionDefinition = { @@ -93,7 +91,6 @@ const absDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: [ 'ROW number = -1.0\n| EVAL abs_number = ABS(number)', 'FROM employees\n| KEEP first_name, last_name, height\n| EVAL abs_height = ABS(0.0 - height)', @@ -161,7 +158,6 @@ const acosDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: ['ROW a=.9\n| EVAL acos=ACOS(a)'], }; @@ -227,7 +223,6 @@ const asinDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: ['ROW a=.9\n| EVAL asin=ASIN(a)'], }; @@ -293,7 +288,6 @@ const atanDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: ['ROW a=12.9\n| EVAL atan=ATAN(a)'], }; @@ -559,7 +553,6 @@ const atan2Definition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: ['ROW y=12.9, x=.6\n| EVAL atan2=ATAN2(y, x)'], }; @@ -604,7 +597,6 @@ const bitLengthDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: [ 'FROM airports\n| WHERE country == "India"\n| KEEP city\n| EVAL fn_length = LENGTH(city), fn_bit_length = BIT_LENGTH(city)', ], @@ -651,7 +643,6 @@ const byteLengthDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: [ 'FROM airports\n| WHERE country == "India"\n| KEEP city\n| EVAL fn_length = LENGTH(city), fn_byte_length = BYTE_LENGTH(city)', ], @@ -719,7 +710,6 @@ const cbrtDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: ['ROW d = 1000.0\n| EVAL c = CBRT(d)'], }; @@ -784,7 +774,6 @@ const ceilDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: ['ROW a=1.8\n| EVAL a=CEIL(a)'], }; @@ -842,7 +831,6 @@ const cidrMatchDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: [ 'FROM hosts\n| WHERE CIDR_MATCH(ip1, "127.0.0.2/32", "127.0.0.3/32")\n| KEEP card, host, ip0, ip1', ], @@ -1133,7 +1121,6 @@ const coalesceDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: ['ROW a=null, b="b"\n| EVAL COALESCE(a, b)'], }; @@ -1222,7 +1209,6 @@ const concatDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: [ 'FROM employees\n| KEEP first_name, last_name\n| EVAL fullname = CONCAT(first_name, " ", last_name)', ], @@ -1289,7 +1275,6 @@ const cosDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: ['ROW a=1.8\n| EVAL cos=COS(a)'], }; @@ -1354,7 +1339,6 @@ const coshDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: ['ROW a=1.8\n| EVAL cosh=COSH(a)'], }; @@ -1601,7 +1585,6 @@ const dateDiffDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: [ 'ROW date1 = TO_DATETIME("2023-12-02T11:00:00.000Z"),\n date2 = TO_DATETIME("2023-12-02T11:00:00.001Z")\n| EVAL dd_ms = DATE_DIFF("microseconds", date1, date2)', 'ROW end_23 = TO_DATETIME("2023-12-31T23:59:59.999Z"),\n start_24 = TO_DATETIME("2024-01-01T00:00:00.000Z"),\n end_24 = TO_DATETIME("2024-12-31T23:59:59.999")\n| EVAL end23_to_start24 = DATE_DIFF("year", end_23, start_24)\n| EVAL end23_to_end24 = DATE_DIFF("year", end_23, end_24)\n| EVAL start_to_end_24 = DATE_DIFF("year", start_24, end_24)', @@ -1721,7 +1704,6 @@ const dateExtractDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: [ 'ROW date = DATE_PARSE("yyyy-MM-dd", "2022-05-06")\n| EVAL year = DATE_EXTRACT("year", date)', 'FROM sample_data\n| WHERE DATE_EXTRACT("hour_of_day", @timestamp) < 9\n AND DATE_EXTRACT("hour_of_day", @timestamp) >= 17', @@ -1829,7 +1811,6 @@ const dateFormatDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: [ 'FROM employees\n| KEEP first_name, last_name, hire_date\n| EVAL hired = DATE_FORMAT("yyyy-MM-dd", hire_date)', ], @@ -1917,7 +1898,6 @@ const dateParseDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: ['ROW date_string = "2022-05-06"\n| EVAL date = DATE_PARSE("yyyy-MM-dd", date_string)'], }; @@ -2003,7 +1983,6 @@ const dateTruncDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: [ 'FROM employees\n| KEEP first_name, last_name, hire_date\n| EVAL year_hired = DATE_TRUNC(1 year, hire_date)', 'FROM employees\n| EVAL year = DATE_TRUNC(1 year, hire_date)\n| STATS hires = COUNT(emp_no) BY year\n| SORT year', @@ -2036,7 +2015,6 @@ const eDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: ['ROW E()'], }; @@ -2122,7 +2100,6 @@ const endsWithDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: ['FROM employees\n| KEEP last_name\n| EVAL ln_E = ENDS_WITH(last_name, "d")'], }; @@ -2187,7 +2164,6 @@ const expDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: ['ROW d = 5.0\n| EVAL s = EXP(d)'], }; @@ -2252,7 +2228,6 @@ const floorDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: ['ROW a=1.8\n| EVAL a=FLOOR(a)'], }; @@ -2297,7 +2272,6 @@ const fromBase64Definition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: ['ROW a = "ZWxhc3RpYw=="\n| EVAL d = FROM_BASE64(a)'], }; @@ -2538,7 +2512,6 @@ const greatestDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: ['ROW a = 10, b = 20\n| EVAL g = GREATEST(a, b)'], }; @@ -2624,7 +2597,6 @@ const hashDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: [ 'FROM sample_data\n| WHERE message != "Connection error"\n| EVAL md5 = hash("md5", message), sha256 = hash("sha256", message)\n| KEEP message, md5, sha256', ], @@ -2892,7 +2864,6 @@ const hypotDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: ['ROW a = 3.0, b = 4.0\n| EVAL c = HYPOT(a, b)'], }; @@ -2937,7 +2908,6 @@ const ipPrefixDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: [ 'ROW ip4 = to_ip("1.2.3.4"), ip6 = TO_IP("fe80::cae2:65ff:fece:feb9")\n| EVAL ip4_prefix = IP_PREFIX(ip4, 24, 0), ip6_prefix = IP_PREFIX(ip6, 0, 112);', ], @@ -2965,7 +2935,6 @@ const knnDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: [ 'from colors metadata _score\n| where knn(rgb_vector, [0, 120, 0], 10)\n| sort _score desc, color asc', ], @@ -3006,7 +2975,6 @@ const kqlDefinition: FunctionDefinition = { }, ], locationsAvailable: [Location.WHERE, Location.STATS_WHERE], - validate: undefined, examples: ['FROM books\n| WHERE KQL("author: Faulkner")'], customParametersSnippet: '"""$0"""', }; @@ -3248,7 +3216,6 @@ const leastDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: ['ROW a = 10, b = 20\n| EVAL l = LEAST(a, b)'], }; @@ -3304,7 +3271,6 @@ const leftDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: ['FROM employees\n| KEEP last_name\n| EVAL left = LEFT(last_name, 3)'], }; @@ -3349,7 +3315,6 @@ const lengthDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: [ 'FROM airports\n| WHERE country == "India"\n| KEEP city\n| EVAL fn_length = LENGTH(city)', ], @@ -3517,7 +3482,6 @@ const locateDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: ['ROW a = "hello"\n| EVAL a_ll = LOCATE(a, "ll")'], }; @@ -3823,27 +3787,6 @@ const logDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: (fnDef: ESQLFunction) => { - const messages = []; - // do not really care here about the base and field - // just need to check both values are not negative - for (const arg of fnDef.args) { - if (isLiteral(arg) && Number(arg.value) < 0) { - messages.push({ - type: 'warning' as const, - code: 'logOfNegativeValue', - text: i18n.translate('kbn-esql-ast.esql.divide.warning.logOfNegativeValue', { - defaultMessage: 'Log of a negative number results in null: {value}', - values: { - value: arg.value, - }, - }), - location: arg.location, - }); - } - } - return messages; - }, examples: [ 'ROW base = 2.0, value = 8.0\n| EVAL s = LOG(base, value)', 'ROW value = 100\n| EVAL s = LOG(value);', @@ -3912,27 +3855,6 @@ const log10Definition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: (fnDef: ESQLFunction) => { - const messages = []; - // do not really care here about the base and field - // just need to check both values are not negative - for (const arg of fnDef.args) { - if (isLiteral(arg) && Number(arg.value) < 0) { - messages.push({ - type: 'warning' as const, - code: 'logOfNegativeValue', - text: i18n.translate('kbn-esql-ast.esql.divide.warning.logOfNegativeValue', { - defaultMessage: 'Log of a negative number results in null: {value}', - values: { - value: arg.value, - }, - }), - location: arg.location, - }); - } - } - return messages; - }, examples: ['ROW d = 1000.0\n| EVAL s = LOG10(d)'], }; @@ -3977,7 +3899,6 @@ const ltrimDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: [ 'ROW message = " some text ", color = " red "\n| EVAL message = LTRIM(message)\n| EVAL color = LTRIM(color)\n| EVAL message = CONCAT("\'", message, "\'")\n| EVAL color = CONCAT("\'", color, "\'")', ], @@ -4721,7 +4642,6 @@ const matchDefinition: FunctionDefinition = { }, ], locationsAvailable: [Location.WHERE, Location.STATS_WHERE], - validate: undefined, examples: [ 'FROM books\n| WHERE MATCH(author, "Faulkner")', 'FROM books\n| WHERE MATCH(title, "Hobbit Back Again", {"operator": "AND"})\n| KEEP title;', @@ -4794,7 +4714,6 @@ const matchPhraseDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: ['FROM books\n| WHERE MATCH_PHRASE(author, "William Faulkner")'], }; @@ -4839,7 +4758,6 @@ const md5Definition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: [ 'FROM sample_data\n| WHERE message != "Connection error"\n| EVAL md5 = md5(message)\n| KEEP message, md5', ], @@ -5534,7 +5452,6 @@ const multiMatchDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: [ 'FROM books\n| WHERE MULTI_MATCH("Faulkner", author, description)\n| KEEP book_no, author\n| SORT book_no\n| LIMIT 5', 'FROM books\n| WHERE MULTI_MATCH("Hobbit Back Again", title, description, {"operator": "AND"})\n| KEEP title;', @@ -5817,7 +5734,6 @@ const mvAppendDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: [ 'FROM employees\n| WHERE emp_no == 10039 OR emp_no == 10040\n| SORT emp_no\n| EVAL dates = MV_APPEND(birth_date, hire_date)\n| KEEP emp_no, birth_date, hire_date, dates', ], @@ -5885,7 +5801,6 @@ const mvAvgDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: ['ROW a=[3, 5, 1, 6]\n| EVAL avg_a = MV_AVG(a)'], }; @@ -5971,7 +5886,6 @@ const mvConcatDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: [ 'ROW a=["foo", "zoo", "bar"]\n| EVAL j = MV_CONCAT(a, ", ")', 'ROW a=[10, 9, 8]\n| EVAL j = MV_CONCAT(TO_STRING(a), ", ")', @@ -6150,7 +6064,6 @@ const mvCountDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: ['ROW a=["foo", "zoo", "bar"]\n| EVAL count_a = MV_COUNT(a)'], }; @@ -6325,7 +6238,6 @@ const mvDedupeDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: ['ROW a=["foo", "foo", "bar", "foo"]\n| EVAL dedupe_a = MV_DEDUPE(a)'], }; @@ -6501,7 +6413,6 @@ const mvFirstDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: ['ROW a="foo;bar;baz"\n| EVAL first_a = MV_FIRST(SPLIT(a, ";"))'], }; @@ -6677,7 +6588,6 @@ const mvLastDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: ['ROW a="foo;bar;baz"\n| EVAL last_a = MV_LAST(SPLIT(a, ";"))'], }; @@ -6813,7 +6723,6 @@ const mvMaxDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: [ 'ROW a=[3, 5, 1]\n| EVAL max_a = MV_MAX(a)', 'ROW a=["foo", "zoo", "bar"]\n| EVAL max_a = MV_MAX(a)', @@ -6882,7 +6791,6 @@ const mvMedianDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: [ 'ROW a=[3, 5, 1]\n| EVAL median_a = MV_MEDIAN(a)', 'ROW a=[3, 7, 1, 6]\n| EVAL median_a = MV_MEDIAN(a)', @@ -6951,7 +6859,6 @@ const mvMedianAbsoluteDeviationDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: [ 'ROW values = [0, 2, 5, 6]\n| EVAL median_absolute_deviation = MV_MEDIAN_ABSOLUTE_DEVIATION(values), median = MV_MEDIAN(values)', ], @@ -7089,7 +6996,6 @@ const mvMinDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: [ 'ROW a=[2, 1]\n| EVAL min_a = MV_MIN(a)', 'ROW a=["foo", "bar"]\n| EVAL min_a = MV_MIN(a)', @@ -7253,7 +7159,6 @@ const mvPercentileDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: [ 'ROW values = [5, 5, 10, 12, 5000]\n| EVAL p50 = MV_PERCENTILE(values, 50), median = MV_MEDIAN(values)', ], @@ -7296,7 +7201,6 @@ const mvPseriesWeightedSumDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: [ 'ROW a = [70.0, 45.0, 21.0, 21.0, 21.0]\n| EVAL sum = MV_PSERIES_WEIGHTED_SUM(a, 1.5)\n| KEEP sum', ], @@ -7624,7 +7528,6 @@ const mvSliceDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: [ 'row a = [1, 2, 2, 3]\n| eval a1 = mv_slice(a, 1), a2 = mv_slice(a, 2, 3)', 'row a = [1, 2, 2, 3]\n| eval a1 = mv_slice(a, -2), a2 = mv_slice(a, -3, -1)', @@ -7812,7 +7715,6 @@ const mvSortDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: ['ROW a = [4, 2, -3, 2]\n| EVAL sa = mv_sort(a), sd = mv_sort(a, "DESC")'], }; @@ -7878,7 +7780,6 @@ const mvSumDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: ['ROW a=[3, 5, 6]\n| EVAL sum_a = MV_SUM(a)'], }; @@ -8124,7 +8025,6 @@ const mvZipDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: [ 'ROW a = ["x", "y", "z"], b = ["1", "2"]\n| EVAL c = mv_zip(a, b, "-")\n| KEEP a, b, c', ], @@ -8155,7 +8055,6 @@ const nowDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: ['ROW current_date = NOW()', 'FROM sample_data\n| WHERE @timestamp > NOW() - 1 hour'], }; @@ -8184,7 +8083,6 @@ const piDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: ['ROW PI()'], }; @@ -8449,7 +8347,6 @@ const powDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: [ 'ROW base = 2.0, exponent = 2\n| EVAL result = POW(base, exponent)', 'ROW base = 4, exponent = 0.5\n| EVAL s = POW(base, exponent)', @@ -8507,7 +8404,6 @@ const qstrDefinition: FunctionDefinition = { }, ], locationsAvailable: [Location.WHERE, Location.STATS_WHERE], - validate: undefined, examples: [ 'FROM books\n| WHERE QSTR("author: Faulkner")', 'FROM books\n| WHERE QSTR("title: Hobbjt~", {"fuzziness": 2})', @@ -8567,7 +8463,6 @@ const repeatDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: ['ROW a = "Hello!"\n| EVAL triple_a = REPEAT(a, 3)'], }; @@ -8753,7 +8648,6 @@ const replaceDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: ['ROW str = "Hello World"\n| EVAL str = REPLACE(str, "World", "Universe")\n| KEEP str'], }; @@ -8798,7 +8692,6 @@ const reverseDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: [ 'ROW message = "Some Text" | EVAL message_reversed = REVERSE(message);', 'ROW bending_arts = "💧🪨🔥💨" | EVAL bending_arts_reversed = REVERSE(bending_arts);', @@ -8857,7 +8750,6 @@ const rightDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: ['FROM employees\n| KEEP last_name\n| EVAL right = RIGHT(last_name, 3)'], }; @@ -9043,7 +8935,6 @@ const roundDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: [ 'FROM employees\n| KEEP first_name, last_name, height\n| EVAL height_ft = ROUND(height * 3.281, 1)', ], @@ -9246,7 +9137,6 @@ const roundToDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: [ 'FROM employees\n| STATS COUNT(*) BY birth_window=ROUND_TO(\n birth_date,\n "1900-01-01T00:00:00Z"::DATETIME,\n "1950-01-01T00:00:00Z"::DATETIME,\n "1955-01-01T00:00:00Z"::DATETIME,\n "1960-01-01T00:00:00Z"::DATETIME,\n "1965-01-01T00:00:00Z"::DATETIME,\n "1970-01-01T00:00:00Z"::DATETIME,\n "1975-01-01T00:00:00Z"::DATETIME\n)\n| SORT birth_window ASC', ], @@ -9293,7 +9183,6 @@ const rtrimDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: [ 'ROW message = " some text ", color = " red "\n| EVAL message = RTRIM(message)\n| EVAL color = RTRIM(color)\n| EVAL message = CONCAT("\'", message, "\'")\n| EVAL color = CONCAT("\'", color, "\'")', ], @@ -9441,7 +9330,6 @@ const scalbDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: ['row x = 3.0, y = 10 | eval z = scalb(x, y)'], }; @@ -9478,7 +9366,6 @@ const scoreDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: [ 'FROM books METADATA _score\n| WHERE match(title, "Return") AND match(author, "Tolkien")\n| EVAL first_score = score(match(title, "Return"))', ], @@ -9525,7 +9412,6 @@ const sha1Definition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: [ 'FROM sample_data\n| WHERE message != "Connection error"\n| EVAL sha1 = sha1(message)\n| KEEP message, sha1', ], @@ -9572,7 +9458,6 @@ const sha256Definition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: [ 'FROM sample_data\n| WHERE message != "Connection error"\n| EVAL sha256 = sha256(message)\n| KEEP message, sha256', ], @@ -9640,7 +9525,6 @@ const signumDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: ['ROW d = 100.0\n| EVAL s = SIGNUM(d)'], }; @@ -9705,7 +9589,6 @@ const sinDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: ['ROW a=1.8\n| EVAL sin=SIN(a)'], }; @@ -9770,7 +9653,6 @@ const sinhDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: ['ROW a=1.8\n| EVAL sinh=SINH(a)'], }; @@ -9805,7 +9687,6 @@ const spaceDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: ['ROW message = CONCAT("Hello", SPACE(1), "World!");'], }; @@ -9890,7 +9771,6 @@ const splitDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: ['ROW words="foo;bar;baz;qux;quux;corge"\n| EVAL word = SPLIT(words, ";")'], }; @@ -9956,7 +9836,6 @@ const sqrtDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: ['ROW d = 100.0\n| EVAL s = SQRT(d)'], }; @@ -10102,7 +9981,6 @@ const stContainsDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: [ 'FROM airport_city_boundaries\n| WHERE ST_CONTAINS(city_boundary, TO_GEOSHAPE("POLYGON((109.35 18.3, 109.45 18.3, 109.45 18.4, 109.35 18.4, 109.35 18.3))"))\n| KEEP abbrev, airport, region, city, city_location', ], @@ -10250,7 +10128,6 @@ const stDisjointDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: [ 'FROM airport_city_boundaries\n| WHERE ST_DISJOINT(city_boundary, TO_GEOSHAPE("POLYGON((-10 -60, 120 -60, 120 60, -10 60, -10 -60))"))\n| KEEP abbrev, airport, region, city, city_location', ], @@ -10308,7 +10185,6 @@ const stDistanceDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: [ 'FROM airports\n| WHERE abbrev == "CPH"\n| EVAL distance = ST_DISTANCE(location, city_location)\n| KEEP abbrev, name, location, city_location, distance', ], @@ -10375,7 +10251,6 @@ const stEnvelopeDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: [ 'FROM airport_city_boundaries\n| WHERE abbrev == "CPH"\n| EVAL envelope = ST_ENVELOPE(city_boundary)\n| KEEP abbrev, airport, envelope', ], @@ -10439,7 +10314,6 @@ const stGeohashDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: [ 'FROM airports\n| EVAL geohash = ST_GEOHASH(location, 1)\n| STATS\n count = COUNT(*),\n centroid = ST_CENTROID_AGG(location)\n BY geohash\n| WHERE count >= 10\n| EVAL geohashString = ST_GEOHASH_TO_STRING(geohash)\n| KEEP count, centroid, geohashString\n| SORT count DESC, geohashString ASC', ], @@ -10488,7 +10362,6 @@ const stGeohashToLongDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: ['ROW geohash = "u3bu"\n| EVAL geohashLong = ST_GEOHASH_TO_LONG(geohash)'], }; @@ -10535,7 +10408,6 @@ const stGeohashToStringDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: [ 'ROW geohash = TO_LONG(13686180)\n| EVAL geohashString = ST_GEOHASH_TO_STRING(geohash)', ], @@ -10602,7 +10474,6 @@ const stGeohexDefinition: FunctionDefinition = { Location.COMPLETION, ], license: 'PLATINUM', - validate: undefined, examples: [ 'FROM airports\n| EVAL geohex = ST_GEOHEX(location, 1)\n| STATS\n count = COUNT(*),\n centroid = ST_CENTROID_AGG(location)\n BY geohex\n| WHERE count >= 10\n| EVAL geohexString = ST_GEOHEX_TO_STRING(geohex)\n| KEEP count, centroid, geohexString\n| SORT count DESC, geohexString ASC', ], @@ -10651,7 +10522,6 @@ const stGeohexToLongDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: ['ROW geohex = "841f059ffffffff"\n| EVAL geohexLong = ST_GEOHEX_TO_LONG(geohex)'], }; @@ -10698,7 +10568,6 @@ const stGeohexToStringDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: ['ROW geohex = 595020895127339007\n| EVAL geohexString = ST_GEOHEX_TO_STRING(geohex)'], }; @@ -10760,7 +10629,6 @@ const stGeotileDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: [ 'FROM airports\n| EVAL geotile = ST_GEOTILE(location, 2)\n| STATS\n count = COUNT(*),\n centroid = ST_CENTROID_AGG(location)\n BY geotile\n| EVAL geotileString = ST_GEOTILE_TO_STRING(geotile)\n| SORT count DESC, geotileString ASC\n| KEEP count, centroid, geotileString', ], @@ -10809,7 +10677,6 @@ const stGeotileToLongDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: ['ROW geotile = "4/8/5"\n| EVAL geotileLong = ST_GEOTILE_TO_LONG(geotile)'], }; @@ -10856,7 +10723,6 @@ const stGeotileToStringDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: [ 'ROW geotile = 1152921508901814277\n| EVAL geotileString = ST_GEOTILE_TO_STRING(geotile)', ], @@ -11004,7 +10870,6 @@ const stIntersectsDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: [ 'FROM airports\n| WHERE ST_INTERSECTS(location, TO_GEOSHAPE("POLYGON((42 14, 43 14, 43 15, 42 15, 42 14))"))', ], @@ -11152,7 +11017,6 @@ const stWithinDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: [ 'FROM airport_city_boundaries\n| WHERE ST_WITHIN(city_boundary, TO_GEOSHAPE("POLYGON((109.1 18.15, 109.6 18.15, 109.6 18.65, 109.1 18.65, 109.1 18.15))"))\n| KEEP abbrev, airport, region, city, city_location', ], @@ -11200,7 +11064,6 @@ const stXDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: [ 'ROW point = TO_GEOPOINT("POINT(42.97109629958868 14.7552534006536)")\n| EVAL x = ST_X(point), y = ST_Y(point)', ], @@ -11268,7 +11131,6 @@ const stXmaxDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: [ 'FROM airport_city_boundaries\n| WHERE abbrev == "CPH"\n| EVAL envelope = ST_ENVELOPE(city_boundary)\n| EVAL xmin = ST_XMIN(envelope), xmax = ST_XMAX(envelope), ymin = ST_YMIN(envelope), ymax = ST_YMAX(envelope)\n| KEEP abbrev, airport, xmin, xmax, ymin, ymax', ], @@ -11336,7 +11198,6 @@ const stXminDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: [ 'FROM airport_city_boundaries\n| WHERE abbrev == "CPH"\n| EVAL envelope = ST_ENVELOPE(city_boundary)\n| EVAL xmin = ST_XMIN(envelope), xmax = ST_XMAX(envelope), ymin = ST_YMIN(envelope), ymax = ST_YMAX(envelope)\n| KEEP abbrev, airport, xmin, xmax, ymin, ymax', ], @@ -11384,7 +11245,6 @@ const stYDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: [ 'ROW point = TO_GEOPOINT("POINT(42.97109629958868 14.7552534006536)")\n| EVAL x = ST_X(point), y = ST_Y(point)', ], @@ -11452,7 +11312,6 @@ const stYmaxDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: [ 'FROM airport_city_boundaries\n| WHERE abbrev == "CPH"\n| EVAL envelope = ST_ENVELOPE(city_boundary)\n| EVAL xmin = ST_XMIN(envelope), xmax = ST_XMAX(envelope), ymin = ST_YMIN(envelope), ymax = ST_YMAX(envelope)\n| KEEP abbrev, airport, xmin, xmax, ymin, ymax', ], @@ -11520,7 +11379,6 @@ const stYminDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: [ 'FROM airport_city_boundaries\n| WHERE abbrev == "CPH"\n| EVAL envelope = ST_ENVELOPE(city_boundary)\n| EVAL xmin = ST_XMIN(envelope), xmax = ST_XMAX(envelope), ymin = ST_YMIN(envelope), ymax = ST_YMAX(envelope)\n| KEEP abbrev, airport, xmin, xmax, ymin, ymax', ], @@ -11608,7 +11466,6 @@ const startsWithDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: ['FROM employees\n| KEEP last_name\n| EVAL ln_S = STARTS_WITH(last_name, "B")'], }; @@ -11674,7 +11531,6 @@ const substringDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: [ 'FROM employees\n| KEEP last_name\n| EVAL ln_sub = SUBSTRING(last_name, 1, 3)', 'FROM employees\n| KEEP last_name\n| EVAL ln_sub = SUBSTRING(last_name, -3, 3)', @@ -11743,7 +11599,6 @@ const tanDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: ['ROW a=1.8\n| EVAL tan=TAN(a)'], }; @@ -11808,7 +11663,6 @@ const tanhDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: ['ROW a=1.8\n| EVAL tanh=TANH(a)'], }; @@ -11837,7 +11691,6 @@ const tauDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: ['ROW TAU()'], }; @@ -11924,7 +11777,6 @@ const termDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: ['FROM books\n| WHERE TERM(author, "gabriel")'], }; @@ -11948,7 +11800,6 @@ const toAggregateMetricDoubleDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: [ 'ROW x = 3892095203\n| EVAL agg_metric = TO_AGGREGATE_METRIC_DOUBLE(x)', 'ROW x = [5032, 11111, 40814]\n| EVAL agg_metric = TO_AGGREGATE_METRIC_DOUBLE(x)', @@ -11996,7 +11847,6 @@ const toBase64Definition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: ['ROW a = "elastic"\n| EVAL e = TO_BASE64(a)'], }; @@ -12092,7 +11942,6 @@ const toBooleanDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: ['ROW str = ["true", "TRuE", "false", "", "yes", "1"]\n| EVAL bool = TO_BOOLEAN(str)'], }; @@ -12148,7 +11997,6 @@ const toCartesianpointDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: [ 'ROW wkt = ["POINT(4297.11 -1475.53)", "POINT(7580.93 2272.77)"]\n| MV_EXPAND wkt\n| EVAL pt = TO_CARTESIANPOINT(wkt)', ], @@ -12216,7 +12064,6 @@ const toCartesianshapeDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: [ 'ROW wkt = ["POINT(4297.11 -1475.53)", "POLYGON ((3339584.72 1118889.97, 4452779.63 4865942.27, 2226389.81 4865942.27, 1113194.90 2273030.92, 3339584.72 1118889.97))"]\n| MV_EXPAND wkt\n| EVAL geom = TO_CARTESIANSHAPE(wkt)', ], @@ -12313,7 +12160,6 @@ const toDateNanosDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: [ 'FROM date_nanos\n| WHERE MV_MIN(nanos) < TO_DATE_NANOS("2023-10-23T12:27:28.948Z")\n AND millis > "2000-01-01"\n| SORT nanos DESC', ], @@ -12370,7 +12216,6 @@ const toDateperiodDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: [ 'ROW x = "2024-01-01"::datetime\n| EVAL y = x + "3 DAYS"::date_period, z = x - TO_DATEPERIOD("3 days");', ], @@ -12478,7 +12323,6 @@ const toDatetimeDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: [ 'ROW string = ["1953-09-02T00:00:00.000Z", "1964-06-02T00:00:00.000Z", "1964-06-02 00:00:00"]\n| EVAL datetime = TO_DATETIME(string)', 'ROW int = [0, 1]\n| EVAL dt = TO_DATETIME(int)', @@ -12546,7 +12390,6 @@ const toDegreesDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: ['ROW rad = [1.57, 3.14, 4.71]\n| EVAL deg = TO_DEGREES(rad)'], }; @@ -12682,7 +12525,6 @@ const toDoubleDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: [ 'ROW str1 = "5.20128E11", str2 = "foo"\n| EVAL dbl = TO_DOUBLE("520128000000"), dbl1 = TO_DOUBLE(str1), dbl2 = TO_DOUBLE(str2)', ], @@ -12740,7 +12582,6 @@ const toGeopointDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: ['ROW wkt = "POINT(42.97109630194 14.7552534413725)"\n| EVAL pt = TO_GEOPOINT(wkt)'], }; @@ -12806,7 +12647,6 @@ const toGeoshapeDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: [ 'ROW wkt = "POLYGON ((30 10, 40 40, 20 40, 10 20, 30 10))"\n| EVAL geom = TO_GEOSHAPE(wkt)', ], @@ -12924,7 +12764,6 @@ const toIntegerDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: ['ROW long = [5013792, 2147483647, 501379200000]\n| EVAL int = TO_INTEGER(long)'], }; @@ -12979,7 +12818,6 @@ const toIpDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: [ 'ROW str1 = "1.1.1.1", str2 = "foo"\n| EVAL ip1 = TO_IP(str1), ip2 = TO_IP(str2)\n| WHERE CIDR_MATCH(ip1, "1.0.0.0/8")', 'ROW s = "1.1.010.1" | EVAL ip = TO_IP(s, {"leading_zeros":"octal"})', @@ -13119,7 +12957,6 @@ const toLongDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: [ 'ROW str1 = "2147483648", str2 = "2147483648.2", str3 = "foo"\n| EVAL long1 = TO_LONG(str1), long2 = TO_LONG(str2), long3 = TO_LONG(str3)', ], @@ -13166,7 +13003,6 @@ const toLowerDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: [ 'ROW message = "Some Text"\n| EVAL message_lower = TO_LOWER(message)', 'ROW v = TO_LOWER(["Some", "Text"])', @@ -13234,7 +13070,6 @@ const toRadiansDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: ['ROW deg = [90.0, 180.0, 270.0]\n| EVAL rad = TO_RADIANS(deg)'], }; @@ -13409,7 +13244,6 @@ const toStringDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: ['ROW a=10\n| EVAL j = TO_STRING(a)', 'ROW a=[10, 9, 8]\n| EVAL j = TO_STRING(a)'], }; @@ -13464,7 +13298,6 @@ const toTimedurationDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: [ 'ROW x = "2024-01-01"::datetime\n| EVAL y = x + "3 hours"::time_duration, z = x - TO_TIMEDURATION("3 hours");', ], @@ -13572,7 +13405,6 @@ const toUnsignedLongDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: [ 'ROW str1 = "2147483648", str2 = "2147483648.2", str3 = "foo"\n| EVAL long1 = TO_UNSIGNED_LONG(str1), long2 = TO_ULONG(str2), long3 = TO_UL(str3)', ], @@ -13619,7 +13451,6 @@ const toUpperDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: ['ROW message = "Some Text"\n| EVAL message_upper = TO_UPPER(message)'], }; @@ -13674,7 +13505,6 @@ const toVersionDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: ['ROW v = TO_VERSION("1.2.3")'], }; @@ -13719,7 +13549,6 @@ const trimDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: [ 'ROW message = " some text ", color = " red "\n| EVAL message = TRIM(message)\n| EVAL color = TRIM(color)', ], @@ -13746,7 +13575,6 @@ const vCosineDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: [ ' from colors\n | where color != "black"\n | eval similarity = v_cosine(rgb_vector, [0, 255, 255])\n | sort similarity desc, color asc', ], @@ -13773,7 +13601,6 @@ const vDotProductDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: [ ' from colors\n | eval similarity = v_dot_product(rgb_vector, [0, 255, 255])\n | sort similarity desc, color asc', ], @@ -13800,12 +13627,37 @@ const vL1NormDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: [ ' from colors\n | eval similarity = v_l1_norm(rgb_vector, [0, 255, 255])\n | sort similarity desc, color asc', ], }; +// Do not edit this manually... generated by scripts/generate_function_definitions.ts +const vL2NormDefinition: FunctionDefinition = { + type: FunctionDefinitionTypes.SCALAR, + name: 'v_l2_norm', + description: i18n.translate('kbn-esql-ast.esql.definitions.v_l2_norm', { + defaultMessage: 'Calculates the l2 norm between two dense_vectors.', + }), + ignoreAsSuggestion: true, + preview: true, + alias: undefined, + signatures: [], + locationsAvailable: [ + Location.EVAL, + Location.ROW, + Location.SORT, + Location.WHERE, + Location.STATS, + Location.STATS_BY, + Location.STATS_WHERE, + Location.COMPLETION, + ], + examples: [ + ' from colors\n | eval similarity = v_l2_norm(rgb_vector, [0, 255, 255])\n | sort similarity desc, color asc', + ], +}; + // Do not edit this manually... generated by scripts/generate_function_definitions.ts const caseDefinition: FunctionDefinition = { type: FunctionDefinitionTypes.SCALAR, @@ -13842,7 +13694,6 @@ const caseDefinition: FunctionDefinition = { Location.STATS_WHERE, Location.COMPLETION, ], - validate: undefined, examples: [ 'from index | eval type = case(languages <= 1, "monolingual", languages <= 2, "bilingual", "polyglot")', ], @@ -13980,5 +13831,6 @@ export const scalarFunctionDefinitions = [ vCosineDefinition, vDotProductDefinition, vL1NormDefinition, + vL2NormDefinition, caseDefinition, ]; diff --git a/src/platform/packages/shared/kbn-esql-ast/src/definitions/generated/time_series_agg_functions.ts b/src/platform/packages/shared/kbn-esql-ast/src/definitions/generated/time_series_agg_functions.ts index ae6c60ea08b63..7ef5319383644 100644 --- a/src/platform/packages/shared/kbn-esql-ast/src/definitions/generated/time_series_agg_functions.ts +++ b/src/platform/packages/shared/kbn-esql-ast/src/definitions/generated/time_series_agg_functions.ts @@ -73,7 +73,6 @@ const avgOverTimeDefinition: FunctionDefinition = { }, ], locationsAvailable: [Location.STATS_TIMESERIES], - validate: undefined, examples: [ 'TS k8s\n| STATS max_cost=max(avg_over_time(network.cost)) BY cluster, time_bucket = bucket(@timestamp,1minute)', ], @@ -642,7 +641,6 @@ const countDistinctOverTimeDefinition: FunctionDefinition = { }, ], locationsAvailable: [Location.STATS_TIMESERIES], - validate: undefined, examples: [ 'TS k8s\n| STATS distincts=count_distinct(count_distinct_over_time(network.cost)),\n distincts_imprecise=count_distinct(count_distinct_over_time(network.cost, 100))\n BY cluster, time_bucket = bucket(@timestamp,1minute)', ], @@ -811,7 +809,6 @@ const countOverTimeDefinition: FunctionDefinition = { }, ], locationsAvailable: [Location.STATS_TIMESERIES], - validate: undefined, examples: [ 'TS k8s\n| STATS count=count(count_over_time(network.cost))\n BY cluster, time_bucket = bucket(@timestamp,1minute)', ], @@ -861,7 +858,6 @@ const firstOverTimeDefinition: FunctionDefinition = { }, ], locationsAvailable: [Location.STATS_TIMESERIES], - validate: undefined, examples: [ 'TS k8s\n| STATS max_cost=max(first_over_time(network.cost)) BY cluster, time_bucket = bucket(@timestamp,1minute)', ], @@ -911,7 +907,6 @@ const lastOverTimeDefinition: FunctionDefinition = { }, ], locationsAvailable: [Location.STATS_TIMESERIES], - validate: undefined, examples: [ 'TS k8s\n| STATS max_cost=max(last_over_time(network.cost)) BY cluster, time_bucket = bucket(@timestamp,1minute)', ], @@ -1040,7 +1035,6 @@ const maxOverTimeDefinition: FunctionDefinition = { }, ], locationsAvailable: [Location.STATS_TIMESERIES], - validate: undefined, examples: [ 'TS k8s\n| STATS cost=sum(max_over_time(network.cost)) BY cluster, time_bucket = bucket(@timestamp,1minute)', ], @@ -1169,7 +1163,6 @@ const minOverTimeDefinition: FunctionDefinition = { }, ], locationsAvailable: [Location.STATS_TIMESERIES], - validate: undefined, examples: [ 'TS k8s\n| STATS cost=sum(min_over_time(network.cost)) BY cluster, time_bucket = bucket(@timestamp,1minute)', ], @@ -1218,7 +1211,6 @@ const rateDefinition: FunctionDefinition = { }, ], locationsAvailable: [Location.STATS_TIMESERIES], - validate: undefined, examples: [ 'TS k8s\n| STATS max(rate(network.total_bytes_in)) BY time_bucket = bucket(@timestamp,5minute)', ], diff --git a/src/platform/packages/shared/kbn-esql-ast/src/definitions/types.ts b/src/platform/packages/shared/kbn-esql-ast/src/definitions/types.ts index 9597b627eb49e..0c51715b16864 100644 --- a/src/platform/packages/shared/kbn-esql-ast/src/definitions/types.ts +++ b/src/platform/packages/shared/kbn-esql-ast/src/definitions/types.ts @@ -7,7 +7,7 @@ * License v3.0 only", or the "Server Side Public License, v 1". */ import type { ESQLSignatureLicenseType } from '@kbn/esql-types'; -import type { ESQLFunction, ESQLMessage, ESQLNumericLiteralType } from '../types'; +import type { ESQLNumericLiteralType } from '../types'; import { Location } from '../commands_registry/types'; /** @@ -218,7 +218,6 @@ export interface FunctionDefinition { locationsAvailable: Location[]; signatures: Signature[]; examples?: string[]; - validate?: (fnDef: ESQLFunction) => ESQLMessage[]; operator?: string; customParametersSnippet?: string; license?: ESQLSignatureLicenseType; @@ -299,10 +298,6 @@ export interface ValidationErrors { message: string; type: { name: string; value: string; supportedOptions: string }; }; - shadowFieldType: { - message: string; - type: { field: string; fieldType: string; newType: string }; - }; unsupportedColumnTypeForCommand: { message: string; type: { command: string; type: string; givenType: string; column: string }; @@ -331,14 +326,6 @@ export interface ValidationErrors { message: string; type: { type: string; value: string }; }; - wildcardNotSupportedForCommand: { - message: string; - type: { command: string; value: string }; - }; - noWildcardSupportAsArg: { - message: string; - type: { name: string }; - }; unsupportedFieldType: { message: string; type: { field: string }; diff --git a/src/platform/packages/shared/kbn-esql-ast/src/definitions/utils/errors.ts b/src/platform/packages/shared/kbn-esql-ast/src/definitions/utils/errors.ts index 7699703268f46..678ce4608450a 100644 --- a/src/platform/packages/shared/kbn-esql-ast/src/definitions/utils/errors.ts +++ b/src/platform/packages/shared/kbn-esql-ast/src/definitions/utils/errors.ts @@ -110,15 +110,6 @@ function getMessageAndTypeFromId({ values: { name: out.name, argType: out.argType }, }), }; - case 'shadowFieldType': - return { - message: i18n.translate('kbn-esql-ast.esql.validation.typeOverwrite', { - defaultMessage: - 'Column [{field}] of type {fieldType} has been overwritten as new type: {newType}', - values: { field: out.field, fieldType: out.fieldType, newType: out.newType }, - }), - type: 'warning', - }; case 'unsupportedColumnTypeForCommand': return { message: i18n.translate('kbn-esql-ast.esql.validation.unsupportedColumnTypeForCommand', { @@ -217,25 +208,6 @@ function getMessageAndTypeFromId({ }, }), }; - case 'wildcardNotSupportedForCommand': - return { - message: i18n.translate('kbn-esql-ast.esql.validation.wildcardNotSupportedForCommand', { - defaultMessage: 'Using wildcards (*) in {command} is not allowed [{value}]', - values: { - command: out.command, - value: out.value, - }, - }), - }; - case 'noWildcardSupportAsArg': - return { - message: i18n.translate('kbn-esql-ast.esql.validation.wildcardNotSupportedForFunction', { - defaultMessage: 'Using wildcards (*) in {name} is not allowed', - values: { - name: out.name, - }, - }), - }; case 'unsupportedFieldType': return { message: i18n.translate('kbn-esql-ast.esql.validation.unsupportedFieldType', { diff --git a/src/platform/packages/shared/kbn-esql-ast/src/definitions/utils/validation/commands.ts b/src/platform/packages/shared/kbn-esql-ast/src/definitions/utils/validation/commands.ts index f534c793e37e2..ccf3d9d0f2c20 100644 --- a/src/platform/packages/shared/kbn-esql-ast/src/definitions/utils/validation/commands.ts +++ b/src/platform/packages/shared/kbn-esql-ast/src/definitions/utils/validation/commands.ts @@ -6,7 +6,6 @@ * your election, the "Elastic License 2.0", the "GNU Affero General Public * License v3.0 only", or the "Server Side Public License, v 1". */ -import { isEqual } from 'lodash'; import { isFunctionExpression, isOptionNode, @@ -31,7 +30,6 @@ export const validateCommandArguments = ( }, callbacks: ICommandCallbacks = {} ) => { - const currentCommandIndex = ast.findIndex((astCommand) => isEqual(astCommand, command)); const messages: ESQLMessage[] = []; for (const arg of command.args) { if (!Array.isArray(arg)) { @@ -44,7 +42,6 @@ export const validateCommandArguments = ( context, callbacks, parentAst: ast, - currentCommandIndex, }) ); } else if (isOptionNode(arg)) { diff --git a/src/platform/packages/shared/kbn-esql-ast/src/definitions/utils/validation/function.ts b/src/platform/packages/shared/kbn-esql-ast/src/definitions/utils/validation/function.ts index 184c6dd52db32..d3e2d30d09141 100644 --- a/src/platform/packages/shared/kbn-esql-ast/src/definitions/utils/validation/function.ts +++ b/src/platform/packages/shared/kbn-esql-ast/src/definitions/utils/validation/function.ts @@ -18,10 +18,6 @@ import { ESQLParamLiteral, } from '../../../types'; import { isAssignment, isInlineCast } from '../../../ast/is'; -import { - UNSUPPORTED_COMMANDS_BEFORE_MATCH, - UNSUPPORTED_COMMANDS_BEFORE_QSTR, -} from '../../constants'; import { getMessageFromId, errors, getFunctionDefinition, getColumnForASTNode } from '..'; import { FunctionParameter, @@ -319,8 +315,6 @@ function unwrapArrayOneLevel(type: FunctionParameterType): FunctionParameterType return isArrayType(type) ? (type.slice(0, -2) as FunctionParameterType) : type; } -const NO_MESSAGE: ESQLMessage[] = []; - /** * Performs validation on a function */ @@ -333,7 +327,6 @@ export function validateFunction({ forceConstantOnly = false, isNested, parentAst, - currentCommandIndex, }: { fn: ESQLFunction; parentCommand: string; @@ -343,7 +336,6 @@ export function validateFunction({ forceConstantOnly?: boolean; isNested?: boolean; parentAst?: ESQLCommand[]; - currentCommandIndex?: number; }): ESQLMessage[] { const messages: ESQLMessage[] = []; @@ -357,20 +349,6 @@ export function validateFunction({ const isFnSupported = isSupportedFunction(fn.name, parentCommand, parentOption); - if (typeof textSearchFunctionsValidators[fn.name] === 'function') { - const validator = textSearchFunctionsValidators[fn.name]; - messages.push( - ...validator({ - fn, - parentCommand, - parentOption, - context, - isNested, - parentAst, - currentCommandIndex, - }) - ); - } if (!isFnSupported.supported) { if (isFnSupported.reason === 'unknownFunction') { messages.push(errors.unknownFunction(fn)); @@ -537,13 +515,7 @@ export function validateFunction({ } } } - // check if the definition has some specific validation to apply: - if (fnDefinition.validate) { - const payloads = fnDefinition.validate(fn); - if (payloads.length) { - messages.push(...payloads); - } - } + // at this point we're sure that at least one signature is matching const failingSignatures: ESQLMessage[][] = []; let relevantFuncSignatures = matchingSignatures; @@ -836,19 +808,7 @@ function validateFunctionColumnArg( } if (actualArg.name === '*') { - // if function does not support wildcards return a specific error - if (!('supportsWildcard' in parameterDefinition) || !parameterDefinition.supportsWildcard) { - messages.push( - getMessageFromId({ - messageId: 'noWildcardSupportAsArg', - values: { - name: astFunction.name, - }, - locations: actualArg.location, - }) - ); - } - + // special case for COUNT(*) return messages; } @@ -888,88 +848,6 @@ function removeInlineCasts(arg: ESQLAstItem): ESQLAstItem { // #region Specific functions -function validateIfHasUnsupportedCommandPrior( - fn: ESQLFunction, - parentAst: ESQLCommand[] = [], - unsupportedCommands: Set, - currentCommandIndex?: number -) { - if (currentCommandIndex === undefined) { - return NO_MESSAGE; - } - const unsupportedCommandsPrior = parentAst.filter( - (cmd, idx) => idx <= currentCommandIndex && unsupportedCommands.has(cmd.name) - ); - - if (unsupportedCommandsPrior.length > 0) { - return [ - getMessageFromId({ - messageId: 'fnUnsupportedAfterCommand', - values: { - function: fn.name.toUpperCase(), - command: unsupportedCommandsPrior[0].name.toUpperCase(), - }, - locations: fn.location, - }), - ]; - } - return NO_MESSAGE; -} - -const validateMatchFunction: FunctionValidator = ({ - fn, - parentCommand, - parentAst, - currentCommandIndex, -}) => { - if (fn.name === 'match') { - if (parentCommand !== 'where') { - return [ - getMessageFromId({ - messageId: 'onlyWhereCommandSupported', - values: { fn: fn.name }, - locations: fn.location, - }), - ]; - } - return validateIfHasUnsupportedCommandPrior( - fn, - parentAst, - UNSUPPORTED_COMMANDS_BEFORE_MATCH, - currentCommandIndex - ); - } - return NO_MESSAGE; -}; - -type FunctionValidator = (args: { - fn: ESQLFunction; - parentCommand: string; - parentOption?: string; - context: ICommandContext; - forceConstantOnly?: boolean; - isNested?: boolean; - parentAst?: ESQLCommand[]; - currentCommandIndex?: number; -}) => ESQLMessage[]; - -const validateQSTRFunction: FunctionValidator = ({ fn, parentAst, currentCommandIndex }) => { - if (fn.name === 'qstr') { - return validateIfHasUnsupportedCommandPrior( - fn, - parentAst, - UNSUPPORTED_COMMANDS_BEFORE_QSTR, - currentCommandIndex - ); - } - return NO_MESSAGE; -}; - -const textSearchFunctionsValidators: Record = { - match: validateMatchFunction, - qstr: validateQSTRFunction, -}; - export function isSupportedFunction( name: string, parentCommand?: string, diff --git a/src/platform/packages/shared/kbn-esql-validation-autocomplete/src/validation/__tests__/functions.test.ts b/src/platform/packages/shared/kbn-esql-validation-autocomplete/src/validation/__tests__/functions.test.ts index bc7f7d7bdc052..89b79228a49d4 100644 --- a/src/platform/packages/shared/kbn-esql-validation-autocomplete/src/validation/__tests__/functions.test.ts +++ b/src/platform/packages/shared/kbn-esql-validation-autocomplete/src/validation/__tests__/functions.test.ts @@ -351,49 +351,6 @@ describe('function validation', () => { await expectErrors('FROM a_index | EVAL TEST("", "")', []); }); - it('validates "all" parameter (wildcard)', async () => { - setTestFunctions([ - { - name: 'supports_all', - type: FunctionDefinitionTypes.SCALAR, - description: '', - locationsAvailable: [Location.EVAL], - signatures: [ - { - params: [{ name: 'arg1', type: 'keyword', supportsWildcard: true }], - returnType: 'keyword', - }, - ], - }, - { - name: 'does_not_support_all', - type: FunctionDefinitionTypes.SCALAR, - description: '', - locationsAvailable: [Location.EVAL], - signatures: [ - { - params: [{ name: 'arg1', type: 'keyword', supportsWildcard: false }], - returnType: 'keyword', - }, - ], - }, - ]); - - const { expectErrors } = await setup(); - - await expectErrors('FROM a_index | EVAL SUPPORTS_ALL(*)', []); - await expectErrors('FROM a_index | EVAL SUPPORTS_ALL(*, "")', [ - // It may seem strange that these are syntax errors, but the grammar actually doesn't allow - // for a function to support the asterisk and have additional arguments. Testing it here so we'll - // be notified if that changes. - `SyntaxError: extraneous input ')' expecting `, - `SyntaxError: no viable alternative at input 'SUPPORTS_ALL(*,'`, - ]); - await expectErrors('FROM a_index | EVAL DOES_NOT_SUPPORT_ALL(*)', [ - 'Using wildcards (*) in does_not_support_all is not allowed', - ]); - }); - it('casts string arguments to dates', async () => { setTestFunctions([ { @@ -691,7 +648,6 @@ describe('function validation', () => { 'SORT does not support function stats_fn', ]); await expectErrors('FROM a_index | STATS ROW_FN()', [ - 'At least one aggregation function required in [STATS], found [ROW_FN()]', 'STATS does not support function row_fn', ]); await expectErrors('ROW WHERE_FN()', ['ROW does not support function where_fn']); diff --git a/src/platform/packages/shared/kbn-esql-validation-autocomplete/src/validation/__tests__/validation.functions.full_text.test.ts b/src/platform/packages/shared/kbn-esql-validation-autocomplete/src/validation/__tests__/validation.functions.full_text.test.ts deleted file mode 100644 index e8d378d7c8935..0000000000000 --- a/src/platform/packages/shared/kbn-esql-validation-autocomplete/src/validation/__tests__/validation.functions.full_text.test.ts +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the "Elastic License - * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side - * Public License v 1"; you may not use this file except in compliance with, at - * your election, the "Elastic License 2.0", the "GNU Affero General Public - * License v3.0 only", or the "Server Side Public License, v 1". - */ - -import { setup } from './helpers'; - -describe('validation', () => { - describe('MATCH function', () => { - it('no error if valid', async () => { - const { expectErrors } = await setup(); - await expectErrors('FROM index | WHERE MATCH(keywordField, "value") | LIMIT 10 ', []); - await expectErrors( - 'FROM index | EVAL a=CONCAT(keywordField, "_") | WHERE MATCH(a, "value") | LIMIT 10 ', - [] - ); - }); - - it('shows errors if after incompatible commands ', async () => { - const { expectErrors } = await setup(); - await expectErrors('FROM index | LIMIT 10 | WHERE MATCH(keywordField, "value")', [ - '[MATCH] function cannot be used after LIMIT', - ]); - - await expectErrors(`FROM index | EVAL MATCH(a, "value")`, [ - 'EVAL does not support function match', - '[MATCH] function is only supported in WHERE commands', - ]); - }); - }); - describe('QSRT function', () => { - it('no error if valid', async () => { - const { expectErrors } = await setup(); - await expectErrors('FROM index | WHERE QSTR("keywordField:value") | LIMIT 10 ', []); - }); - - it('shows errors if comes after incompatible functions or commands ', async () => { - const { expectErrors } = await setup(); - await expectErrors('ROW a = 1, b = "two", c = null | WHERE QSTR("keywordField:value")', [ - '[QSTR] function cannot be used after ROW', - ]); - for (const clause of [ - { command: 'LIMIT', clause: 'LIMIT 10' }, - { command: 'EVAL', clause: 'EVAL a=CONCAT(keywordField, "_")' }, - { command: 'KEEP', clause: 'KEEP keywordField' }, - { command: 'RENAME', clause: 'RENAME keywordField as a' }, - { command: 'STATS', clause: 'STATS avg(doubleField) by keywordField' }, - ]) { - await expectErrors(`FROM index | ${clause.clause} | WHERE QSTR("keywordField:value")`, [ - `[QSTR] function cannot be used after ${clause.command}`, - ]); - } - await expectErrors(`FROM index | EVAL QSTR("keywordField:value")`, [ - `EVAL does not support function qstr`, - '[QSTR] function cannot be used after EVAL', - ]); - - await expectErrors(`FROM index | STATS avg(doubleField) by QSTR("keywordField:value")`, [ - `STATS BY does not support function qstr`, - ]); - }); - }); -}); diff --git a/src/platform/packages/shared/kbn-esql-validation-autocomplete/src/validation/esql_validation_meta_tests.json b/src/platform/packages/shared/kbn-esql-validation-autocomplete/src/validation/esql_validation_meta_tests.json index 3c66e1e984e01..676e4eeb0dd56 100644 --- a/src/platform/packages/shared/kbn-esql-validation-autocomplete/src/validation/esql_validation_meta_tests.json +++ b/src/platform/packages/shared/kbn-esql-validation-autocomplete/src/validation/esql_validation_meta_tests.json @@ -608,20 +608,6 @@ ], "warning": [] }, - { - "query": "from a_index | eval textField = 5", - "error": [], - "warning": [ - "Column [textField] of type text has been overwritten as new type: integer" - ] - }, - { - "query": "from a_index | eval doubleField = \"5\"", - "error": [], - "warning": [ - "Column [doubleField] of type double has been overwritten as new type: keyword" - ] - }, { "query": "from a_index | eval round(doubleField) + 1 | eval `round(doubleField) + 1` + 1 | keep ```round(doubleField) + 1`` + 1`", "error": [], diff --git a/src/platform/packages/shared/kbn-esql-validation-autocomplete/src/validation/validation.test.ts b/src/platform/packages/shared/kbn-esql-validation-autocomplete/src/validation/validation.test.ts index d7e3ee6d01f00..88f4a9a2a3560 100644 --- a/src/platform/packages/shared/kbn-esql-validation-autocomplete/src/validation/validation.test.ts +++ b/src/platform/packages/shared/kbn-esql-validation-autocomplete/src/validation/validation.test.ts @@ -541,16 +541,7 @@ describe('validation logic', () => { }); describe('shadowing', () => { - testErrorsAndWarnings( - 'from a_index | eval textField = 5', - [], - ['Column [textField] of type text has been overwritten as new type: integer'] - ); - testErrorsAndWarnings( - 'from a_index | eval doubleField = "5"', - [], - ['Column [doubleField] of type double has been overwritten as new type: keyword'] - ); + // fields shadowing validation removed }); describe('quoting and escaping expressions', () => { diff --git a/src/platform/packages/shared/kbn-esql-validation-autocomplete/src/validation/validation.ts b/src/platform/packages/shared/kbn-esql-validation-autocomplete/src/validation/validation.ts index 61f0454360e33..e3a3571b123d2 100644 --- a/src/platform/packages/shared/kbn-esql-validation-autocomplete/src/validation/validation.ts +++ b/src/platform/packages/shared/kbn-esql-validation-autocomplete/src/validation/validation.ts @@ -19,11 +19,10 @@ import { import { getMessageFromId } from '@kbn/esql-ast/src/definitions/utils'; import type { ESQLFieldWithMetadata, - ESQLUserDefinedColumn, ICommandCallbacks, } from '@kbn/esql-ast/src/commands_registry/types'; import { ESQLLicenseType } from '@kbn/esql-types'; -import { areFieldAndUserDefinedColumnTypesCompatible } from '../shared/helpers'; + import type { ESQLCallbacks } from '../shared/types'; import { collectUserDefinedColumns } from '../shared/user_defined_columns'; import { @@ -153,8 +152,6 @@ async function validateAst( } const userDefinedColumns = collectUserDefinedColumns(rootCommands, availableFields, queryString); - // notify if the user is rewriting a column as userDefinedColumn with another type - messages.push(...validateFieldsShadowing(availableFields, userDefinedColumns)); messages.push(...validateUnsupportedTypeFields(availableFields, rootCommands)); const references: ReferenceMaps = { @@ -249,42 +246,6 @@ function validateCommand( return messages; } -function validateFieldsShadowing( - fields: Map, - userDefinedColumns: Map -) { - const messages: ESQLMessage[] = []; - for (const userDefinedColumn of userDefinedColumns.keys()) { - if (fields.has(userDefinedColumn)) { - const userDefinedColumnHits = userDefinedColumns.get(userDefinedColumn)!; - if ( - !areFieldAndUserDefinedColumnTypesCompatible( - fields.get(userDefinedColumn)?.type, - userDefinedColumnHits[0].type - ) - ) { - const fieldType = fields.get(userDefinedColumn)!.type; - const userDefinedColumnType = userDefinedColumnHits[0].type; - const flatFieldType = fieldType; - const flatUserDefinedColumnType = userDefinedColumnType; - messages.push( - getMessageFromId({ - messageId: 'shadowFieldType', - values: { - field: userDefinedColumn, - fieldType: flatFieldType, - newType: flatUserDefinedColumnType, - }, - locations: userDefinedColumnHits[0].location, - }) - ); - } - } - } - - return messages; -} - function validateUnsupportedTypeFields(fields: Map, ast: ESQLAst) { const usedColumnsInQuery: string[] = [];