diff --git a/packages/kbn-esql-validation-autocomplete/src/autocomplete/autocomplete.test.ts b/packages/kbn-esql-validation-autocomplete/src/autocomplete/autocomplete.test.ts index dcaa898b15a5d..7af0871fd59ef 100644 --- a/packages/kbn-esql-validation-autocomplete/src/autocomplete/autocomplete.test.ts +++ b/packages/kbn-esql-validation-autocomplete/src/autocomplete/autocomplete.test.ts @@ -1104,7 +1104,7 @@ describe('autocomplete', () => { ...getFieldNamesByType('string').map((v) => `${v},`), ...getFunctionSignaturesByReturnType('eval', 'string', { evalMath: true }, undefined, [ 'concat', - ]).map((v) => `${v},`), + ]).map((v) => ({ ...v, text: `${v.text},` })), ]); testSuggestions('from a | eval a=concat(stringField, ', [ ...getFieldNamesByType('string'), @@ -1124,7 +1124,7 @@ describe('autocomplete', () => { ...getFieldNamesByType('ip').map((v) => `${v},`), ...getFunctionSignaturesByReturnType('eval', 'ip', { evalMath: true }, undefined, [ 'cidr_match', - ]).map((v) => `${v},`), + ]).map((v) => ({ ...v, text: `${v.text},` })), ]); testSuggestions('from a | eval a=cidr_match(ipField, ', [ ...getFieldNamesByType('string'), @@ -1289,7 +1289,7 @@ describe('autocomplete', () => { ...getLiteralsByType('time_literal').map((t) => `${t},`), ...getFunctionSignaturesByReturnType('eval', 'date', { evalMath: true }, undefined, [ 'date_trunc', - ]).map((t) => `${t},`), + ]).map((t) => ({ ...t, text: `${t.text},` })), ...getFieldNamesByType('date').map((t) => `${t},`), ], '(' diff --git a/packages/kbn-esql-validation-autocomplete/src/autocomplete/factories.ts b/packages/kbn-esql-validation-autocomplete/src/autocomplete/factories.ts index ad49303c55def..5820118d0013a 100644 --- a/packages/kbn-esql-validation-autocomplete/src/autocomplete/factories.ts +++ b/packages/kbn-esql-validation-autocomplete/src/autocomplete/factories.ts @@ -46,7 +46,7 @@ function getSafeInsertSourceText(text: string) { } export function getSuggestionFunctionDefinition(fn: FunctionDefinition): SuggestionRawDefinition { - const fullSignatures = getFunctionSignatures(fn); + const fullSignatures = getFunctionSignatures(fn, { capitalize: true, withTypes: true }); return { label: fullSignatures[0].declaration, text: `${fn.name.toUpperCase()}($0)`, @@ -66,7 +66,7 @@ export function getSuggestionFunctionDefinition(fn: FunctionDefinition): Suggest export function getSuggestionBuiltinDefinition(fn: FunctionDefinition): SuggestionRawDefinition { const hasArgs = fn.signatures.some(({ params }) => params.length > 1); return { - label: fn.name, + label: fn.name.toUpperCase(), text: hasArgs ? `${fn.name.toUpperCase()} $0` : fn.name.toUpperCase(), asSnippet: hasArgs, kind: 'Operator', diff --git a/packages/kbn-esql-validation-autocomplete/src/definitions/helpers.ts b/packages/kbn-esql-validation-autocomplete/src/definitions/helpers.ts index 0ccb7855b284b..a44db712ab230 100644 --- a/packages/kbn-esql-validation-autocomplete/src/definitions/helpers.ts +++ b/packages/kbn-esql-validation-autocomplete/src/definitions/helpers.ts @@ -17,7 +17,10 @@ import type { CommandDefinition, FunctionDefinition } from './types'; */ export function getFunctionSignatures( { name, signatures }: FunctionDefinition, - { withTypes }: { withTypes: boolean } = { withTypes: true } + { withTypes, capitalize }: { withTypes: boolean; capitalize?: boolean } = { + withTypes: true, + capitalize: false, + } ) { return signatures.map(({ params, returnType, minParams }) => { // for functions with a minimum number of args, repeat the last arg multiple times @@ -25,7 +28,7 @@ export function getFunctionSignatures( const minParamsToAdd = Math.max((minParams || 0) - params.length, 0); const extraArg = Array(minParamsToAdd || 1).fill(params[Math.max(params.length - 1, 0)]); return { - declaration: `${name}(${params + declaration: `${capitalize ? name.toUpperCase() : name}(${params .map((arg) => printArguments(arg, withTypes)) .join(', ')}${handleAdditionalArgs(minParamsToAdd > 0, extraArg, withTypes)})${ withTypes ? `: ${returnType}` : '' diff --git a/packages/kbn-esql-validation-autocomplete/src/shared/helpers.ts b/packages/kbn-esql-validation-autocomplete/src/shared/helpers.ts index 94aae4194d367..6cedf378c35aa 100644 --- a/packages/kbn-esql-validation-autocomplete/src/shared/helpers.ts +++ b/packages/kbn-esql-validation-autocomplete/src/shared/helpers.ts @@ -290,13 +290,12 @@ export function areFieldAndVariableTypesCompatible( return fieldType === variableType; } -export function printFunctionSignature(arg: ESQLFunction, useCaps = true): string { +export function printFunctionSignature(arg: ESQLFunction): string { const fnDef = getFunctionDefinition(arg.name); if (fnDef) { const signature = getFunctionSignatures( { ...fnDef, - name: useCaps ? fnDef.name.toUpperCase() : fnDef.name, signatures: [ { ...fnDef?.signatures[0], @@ -313,7 +312,7 @@ export function printFunctionSignature(arg: ESQLFunction, useCaps = true): strin }, ], }, - { withTypes: false } + { withTypes: false, capitalize: true } ); return signature[0].declaration; } diff --git a/packages/kbn-esql-validation-autocomplete/src/validation/esql_validation_meta_tests.json b/packages/kbn-esql-validation-autocomplete/src/validation/esql_validation_meta_tests.json index c49f5c7af82df..98bcf3468348e 100644 --- a/packages/kbn-esql-validation-autocomplete/src/validation/esql_validation_meta_tests.json +++ b/packages/kbn-esql-validation-autocomplete/src/validation/esql_validation_meta_tests.json @@ -9187,8 +9187,8 @@ { "query": "from a_index | eval date_diff(\"year\", concat(\"20\", \"22\"), concat(\"20\", \"22\"))", "error": [ - "Argument of [date_diff] must be [date], found value [concat(\"20\", \"22\")] type [string]", - "Argument of [date_diff] must be [date], found value [concat(\"20\", \"22\")] type [string]" + "Argument of [date_diff] must be [date], found value [concat(\"20\",\"22\")] type [string]", + "Argument of [date_diff] must be [date], found value [concat(\"20\",\"22\")] type [string]" ], "warning": [] }, @@ -11080,7 +11080,7 @@ { "query": "from a_index | eval date_extract(\"ALIGNED_DAY_OF_WEEK_IN_MONTH\", concat(\"20\", \"22\"))", "error": [ - "Argument of [date_extract] must be [date], found value [concat(\"20\", \"22\")] type [string]" + "Argument of [date_extract] must be [date], found value [concat(\"20\",\"22\")] type [string]" ], "warning": [] }, @@ -11167,7 +11167,7 @@ { "query": "from a_index | eval date_format(stringField, concat(\"20\", \"22\"))", "error": [ - "Argument of [date_format] must be [date], found value [concat(\"20\", \"22\")] type [string]" + "Argument of [date_format] must be [date], found value [concat(\"20\",\"22\")] type [string]" ], "warning": [] }, @@ -11384,7 +11384,7 @@ { "query": "from a_index | eval date_trunc(1 year, concat(\"20\", \"22\"))", "error": [ - "Argument of [date_trunc] must be [date], found value [concat(\"20\", \"22\")] type [string]" + "Argument of [date_trunc] must be [date], found value [concat(\"20\",\"22\")] type [string]" ], "warning": [] }, @@ -11396,8 +11396,8 @@ { "query": "from a_index | eval date_trunc(concat(\"20\", \"22\"), concat(\"20\", \"22\"))", "error": [ - "Argument of [date_trunc] must be [time_literal], found value [concat(\"20\", \"22\")] type [string]", - "Argument of [date_trunc] must be [date], found value [concat(\"20\", \"22\")] type [string]" + "Argument of [date_trunc] must be [time_literal], found value [concat(\"20\",\"22\")] type [string]", + "Argument of [date_trunc] must be [date], found value [concat(\"20\",\"22\")] type [string]" ], "warning": [] }, @@ -24139,7 +24139,7 @@ { "query": "from a_index | stats max(concat(\"20\", \"22\"))", "error": [ - "Argument of [max] must be [number], found value [concat(\"20\", \"22\")] type [string]" + "Argument of [max] must be [number], found value [concat(\"20\",\"22\")] type [string]" ], "warning": [] }, @@ -24412,7 +24412,7 @@ { "query": "from a_index | stats min(concat(\"20\", \"22\"))", "error": [ - "Argument of [min] must be [number], found value [concat(\"20\", \"22\")] type [string]" + "Argument of [min] must be [number], found value [concat(\"20\",\"22\")] type [string]" ], "warning": [] }, @@ -24970,14 +24970,14 @@ { "query": "from a_index | stats bucket(concat(\"20\", \"22\"), 1 year)", "error": [ - "Argument of [bucket] must be [date], found value [concat(\"20\", \"22\")] type [string]" + "Argument of [bucket] must be [date], found value [concat(\"20\",\"22\")] type [string]" ], "warning": [] }, { "query": "from a_index | stats by bucket(concat(\"20\", \"22\"), 1 year)", "error": [ - "Argument of [bucket] must be [date], found value [concat(\"20\", \"22\")] type [string]" + "Argument of [bucket] must be [date], found value [concat(\"20\",\"22\")] type [string]" ], "warning": [] }, @@ -24989,7 +24989,7 @@ { "query": "from a_index | stats bucket(concat(\"20\", \"22\"), 5, \"a\", \"a\")", "error": [ - "Argument of [bucket] must be [date], found value [concat(\"20\", \"22\")] type [string]" + "Argument of [bucket] must be [date], found value [concat(\"20\",\"22\")] type [string]" ], "warning": [] }, @@ -25001,7 +25001,7 @@ { "query": "from a_index | stats bucket(concat(\"20\", \"22\"), 5, concat(\"20\", \"22\"), concat(\"20\", \"22\"))", "error": [ - "Argument of [bucket] must be [date], found value [concat(\"20\", \"22\")] type [string]" + "Argument of [bucket] must be [date], found value [concat(\"20\",\"22\")] type [string]" ], "warning": [] }, @@ -25013,7 +25013,7 @@ { "query": "from a_index | stats bucket(concat(\"20\", \"22\"), 5, \"a\", concat(\"20\", \"22\"))", "error": [ - "Argument of [bucket] must be [date], found value [concat(\"20\", \"22\")] type [string]" + "Argument of [bucket] must be [date], found value [concat(\"20\",\"22\")] type [string]" ], "warning": [] }, @@ -25025,7 +25025,7 @@ { "query": "from a_index | stats bucket(concat(\"20\", \"22\"), 5, concat(\"20\", \"22\"), \"a\")", "error": [ - "Argument of [bucket] must be [date], found value [concat(\"20\", \"22\")] type [string]" + "Argument of [bucket] must be [date], found value [concat(\"20\",\"22\")] type [string]" ], "warning": [] }, @@ -26368,6 +26368,91 @@ "error": [], "warning": [] }, + { + "query": "row var = exp(5)", + "error": [], + "warning": [] + }, + { + "query": "row exp(5)", + "error": [], + "warning": [] + }, + { + "query": "row var = exp(to_integer(true))", + "error": [], + "warning": [] + }, + { + "query": "row var = exp(true)", + "error": [ + "Argument of [exp] must be [number], found value [true] type [boolean]" + ], + "warning": [] + }, + { + "query": "from a_index | where exp(numberField) > 0", + "error": [], + "warning": [] + }, + { + "query": "from a_index | where exp(booleanField) > 0", + "error": [ + "Argument of [exp] must be [number], found value [booleanField] type [boolean]" + ], + "warning": [] + }, + { + "query": "from a_index | eval var = exp(numberField)", + "error": [], + "warning": [] + }, + { + "query": "from a_index | eval exp(numberField)", + "error": [], + "warning": [] + }, + { + "query": "from a_index | eval var = exp(to_integer(booleanField))", + "error": [], + "warning": [] + }, + { + "query": "from a_index | eval exp(booleanField)", + "error": [ + "Argument of [exp] must be [number], found value [booleanField] type [boolean]" + ], + "warning": [] + }, + { + "query": "from a_index | eval var = exp(*)", + "error": [ + "Using wildcards (*) in exp is not allowed" + ], + "warning": [] + }, + { + "query": "from a_index | eval exp(numberField, extraArg)", + "error": [ + "Error: [exp] function expects exactly one argument, got 2." + ], + "warning": [] + }, + { + "query": "from a_index | sort exp(numberField)", + "error": [], + "warning": [] + }, + { + "query": "from a_index | eval exp(null)", + "error": [], + "warning": [] + }, + { + "query": "row nullVar = null | eval exp(nullVar)", + "error": [], + "warning": [] + }, { "query": "f", "error": [ diff --git a/packages/kbn-esql-validation-autocomplete/src/validation/validation.test.ts b/packages/kbn-esql-validation-autocomplete/src/validation/validation.test.ts index 14d9c50d5c88c..7421621fd941d 100644 --- a/packages/kbn-esql-validation-autocomplete/src/validation/validation.test.ts +++ b/packages/kbn-esql-validation-autocomplete/src/validation/validation.test.ts @@ -103,7 +103,7 @@ function prepareNestedFunction(fnSignature: FunctionDefinition): string { }, ], }, - { withTypes: false } + { withTypes: false, capitalize: false } )[0].declaration; } function getFieldMapping( @@ -1784,8 +1784,8 @@ describe('validation logic', () => { testErrorsAndWarnings( 'from a_index | eval date_diff("year", concat("20", "22"), concat("20", "22"))', [ - 'Argument of [date_diff] must be [date], found value [concat("20", "22")] type [string]', - 'Argument of [date_diff] must be [date], found value [concat("20", "22")] type [string]', + 'Argument of [date_diff] must be [date], found value [concat("20","22")] type [string]', + 'Argument of [date_diff] must be [date], found value [concat("20","22")] type [string]', ] ); }); @@ -2666,7 +2666,7 @@ describe('validation logic', () => { testErrorsAndWarnings( 'from a_index | eval date_extract("ALIGNED_DAY_OF_WEEK_IN_MONTH", concat("20", "22"))', [ - 'Argument of [date_extract] must be [date], found value [concat("20", "22")] type [string]', + 'Argument of [date_extract] must be [date], found value [concat("20","22")] type [string]', ] ); }); @@ -2710,7 +2710,7 @@ describe('validation logic', () => { testErrorsAndWarnings('row nullVar = null | eval date_format(nullVar, nullVar)', []); testErrorsAndWarnings('from a_index | eval date_format(stringField, "2022")', []); testErrorsAndWarnings('from a_index | eval date_format(stringField, concat("20", "22"))', [ - 'Argument of [date_format] must be [date], found value [concat("20", "22")] type [string]', + 'Argument of [date_format] must be [date], found value [concat("20","22")] type [string]', ]); }); @@ -2815,15 +2815,15 @@ describe('validation logic', () => { testErrorsAndWarnings('row nullVar = null | eval date_trunc(nullVar, nullVar)', []); testErrorsAndWarnings('from a_index | eval date_trunc(1 year, "2022")', []); testErrorsAndWarnings('from a_index | eval date_trunc(1 year, concat("20", "22"))', [ - 'Argument of [date_trunc] must be [date], found value [concat("20", "22")] type [string]', + 'Argument of [date_trunc] must be [date], found value [concat("20","22")] type [string]', ]); testErrorsAndWarnings('from a_index | eval date_trunc("2022", "2022")', []); testErrorsAndWarnings( 'from a_index | eval date_trunc(concat("20", "22"), concat("20", "22"))', [ - 'Argument of [date_trunc] must be [time_literal], found value [concat("20", "22")] type [string]', - 'Argument of [date_trunc] must be [date], found value [concat("20", "22")] type [string]', + 'Argument of [date_trunc] must be [time_literal], found value [concat("20","22")] type [string]', + 'Argument of [date_trunc] must be [date], found value [concat("20","22")] type [string]', ] ); }); @@ -9170,7 +9170,7 @@ describe('validation logic', () => { testErrorsAndWarnings('row nullVar = null | stats max(nullVar)', []); testErrorsAndWarnings('from a_index | stats max("2022")', []); testErrorsAndWarnings('from a_index | stats max(concat("20", "22"))', [ - 'Argument of [max] must be [number], found value [concat("20", "22")] type [string]', + 'Argument of [max] must be [number], found value [concat("20","22")] type [string]', ]); }); @@ -9314,7 +9314,7 @@ describe('validation logic', () => { testErrorsAndWarnings('row nullVar = null | stats min(nullVar)', []); testErrorsAndWarnings('from a_index | stats min("2022")', []); testErrorsAndWarnings('from a_index | stats min(concat("20", "22"))', [ - 'Argument of [min] must be [number], found value [concat("20", "22")] type [string]', + 'Argument of [min] must be [number], found value [concat("20","22")] type [string]', ]); }); @@ -9632,34 +9632,34 @@ describe('validation logic', () => { ); testErrorsAndWarnings('from a_index | stats bucket("2022", 1 year)', []); testErrorsAndWarnings('from a_index | stats bucket(concat("20", "22"), 1 year)', [ - 'Argument of [bucket] must be [date], found value [concat("20", "22")] type [string]', + 'Argument of [bucket] must be [date], found value [concat("20","22")] type [string]', ]); testErrorsAndWarnings('from a_index | stats by bucket(concat("20", "22"), 1 year)', [ - 'Argument of [bucket] must be [date], found value [concat("20", "22")] type [string]', + 'Argument of [bucket] must be [date], found value [concat("20","22")] type [string]', ]); testErrorsAndWarnings('from a_index | stats bucket("2022", 5, "a", "a")', []); testErrorsAndWarnings('from a_index | stats bucket(concat("20", "22"), 5, "a", "a")', [ - 'Argument of [bucket] must be [date], found value [concat("20", "22")] type [string]', + 'Argument of [bucket] must be [date], found value [concat("20","22")] type [string]', ]); testErrorsAndWarnings('from a_index | stats bucket("2022", 5, "2022", "2022")', []); testErrorsAndWarnings( 'from a_index | stats bucket(concat("20", "22"), 5, concat("20", "22"), concat("20", "22"))', - ['Argument of [bucket] must be [date], found value [concat("20", "22")] type [string]'] + ['Argument of [bucket] must be [date], found value [concat("20","22")] type [string]'] ); testErrorsAndWarnings('from a_index | stats bucket("2022", 5, "a", "2022")', []); testErrorsAndWarnings( 'from a_index | stats bucket(concat("20", "22"), 5, "a", concat("20", "22"))', - ['Argument of [bucket] must be [date], found value [concat("20", "22")] type [string]'] + ['Argument of [bucket] must be [date], found value [concat("20","22")] type [string]'] ); testErrorsAndWarnings('from a_index | stats bucket("2022", 5, "2022", "a")', []); testErrorsAndWarnings( 'from a_index | stats bucket(concat("20", "22"), 5, concat("20", "22"), "a")', - ['Argument of [bucket] must be [date], found value [concat("20", "22")] type [string]'] + ['Argument of [bucket] must be [date], found value [concat("20","22")] type [string]'] ); }); diff --git a/packages/kbn-esql-validation-autocomplete/src/validation/validation.ts b/packages/kbn-esql-validation-autocomplete/src/validation/validation.ts index e3c94aee3f482..cea9dccbd8d97 100644 --- a/packages/kbn-esql-validation-autocomplete/src/validation/validation.ts +++ b/packages/kbn-esql-validation-autocomplete/src/validation/validation.ts @@ -43,7 +43,6 @@ import { isSupportedFunction, isTimeIntervalItem, inKnownTimeInterval, - printFunctionSignature, sourceExists, getColumnExists, hasWildcard, @@ -220,7 +219,7 @@ function validateNestedFunctionArg( values: { name: astFunction.name, argType: parameterDefinition.type, - value: printFunctionSignature(actualArg, false) || actualArg.name, + value: actualArg.text, givenType: argFn.signatures[0].returnType, }, locations: actualArg.location,