[ES|QL] add tests for implicit date casting (#184612)

## Summary

Relates to https://github.com/elastic/elasticsearch/issues/109265

These test reflect the reality of how date casting is working in
Elasticsearch today. When the above issue is addressed in Elasticsearch,
these tests will fail the error sync check and prompt us to update the
validator.

---------

Co-authored-by: Stratoula Kalafateli <efstratia.kalafateli@elastic.co>
This commit is contained in:
Drew Tate 2024-06-03 08:10:44 -06:00 committed by GitHub
parent 1750ab8676
commit 9abe56f1c6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 306 additions and 0 deletions

View file

@ -53,6 +53,7 @@ function generateTestsForEvalFunction(definition: FunctionDefinition) {
generateEvalCommandTestsForEvalFunction(definition, testCases);
generateSortCommandTestsForEvalFunction(definition, testCases);
generateNullAcceptanceTestsForFunction(definition, testCases);
generateImplicitDateCastingTestsForFunction(definition, testCases);
return testCases;
}
@ -63,6 +64,7 @@ function generateTestsForAggFunction(definition: FunctionDefinition) {
generateWhereCommandTestsForAggFunction(definition, testCases);
generateEvalCommandTestsForAggFunction(definition, testCases);
generateNullAcceptanceTestsForFunction(definition, testCases);
generateImplicitDateCastingTestsForFunction(definition, testCases);
return testCases;
}
@ -71,6 +73,7 @@ function generateTestsForGroupingFunction(definition: FunctionDefinition) {
generateStatsCommandTestsForGroupingFunction(definition, testCases);
generateSortCommandTestsForGroupingFunction(definition, testCases);
generateNullAcceptanceTestsForFunction(definition, testCases);
generateImplicitDateCastingTestsForFunction(definition, testCases);
return testCases;
}
@ -124,6 +127,79 @@ function generateNullAcceptanceTestsForFunction(
);
}
/**
* Tests for strings being casted to dates
*
* @param definition
* @param testCases
* @returns
*/
function generateImplicitDateCastingTestsForFunction(
definition: FunctionDefinition,
testCases: Map<string, string[]>
) {
const allSignaturesWithDateParams = definition.signatures.filter((signature) =>
signature.params.some(
(param, i) =>
param.type === 'date' &&
!definition.signatures.some((def) => def.params[i].type === 'string') // don't count parameters that already accept a string
)
);
if (!allSignaturesWithDateParams.length) {
// no signatures contain date params
return;
}
const commandToTestWith = definition.supportedCommands.includes('eval') ? 'eval' : 'stats';
for (const signature of allSignaturesWithDateParams) {
const mappedParams = getFieldMapping(signature.params);
testCases.set(
`from a_index | ${commandToTestWith} ${
getFunctionSignatures(
{
...definition,
signatures: [
{
...signature,
params: mappedParams.map((param) =>
// overwrite dates with a string
param.type === 'date' ? { ...param, name: '"2022"' } : param
),
},
],
},
{ withTypes: false }
)[0].declaration
}`,
[]
);
testCases.set(
`from a_index | ${commandToTestWith} ${
getFunctionSignatures(
{
...definition,
signatures: [
{
...signature,
params: mappedParams.map((param) =>
// overwrite dates with a string
param.type === 'date' ? { ...param, name: 'concat("20", "22")' } : param
),
},
],
},
{ withTypes: false }
)[0].declaration
}`,
[]
);
}
}
function generateRowCommandTestsForEvalFunction(
{ name, alias, signatures, ...defRest }: FunctionDefinition,
testCases: Map<string, string[]>

View file

@ -9044,6 +9044,19 @@
"error": [],
"warning": []
},
{
"query": "from a_index | eval date_diff(\"year\", \"2022\", \"2022\")",
"error": [],
"warning": []
},
{
"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]"
],
"warning": []
},
{
"query": "row var = abs(5)",
"error": [],
@ -10999,6 +11012,18 @@
"error": [],
"warning": []
},
{
"query": "from a_index | eval date_extract(\"ALIGNED_DAY_OF_WEEK_IN_MONTH\", \"2022\")",
"error": [],
"warning": []
},
{
"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]"
],
"warning": []
},
{
"query": "row var = date_format(\"a\", now())",
"error": [],
@ -11074,6 +11099,18 @@
"error": [],
"warning": []
},
{
"query": "from a_index | eval date_format(stringField, \"2022\")",
"error": [],
"warning": []
},
{
"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]"
],
"warning": []
},
{
"query": "row var = date_parse(\"a\", \"a\")",
"error": [],
@ -11279,6 +11316,31 @@
"error": [],
"warning": []
},
{
"query": "from a_index | eval date_trunc(1 year, \"2022\")",
"error": [],
"warning": []
},
{
"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]"
],
"warning": []
},
{
"query": "from a_index | eval date_trunc(\"2022\", \"2022\")",
"error": [],
"warning": []
},
{
"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]"
],
"warning": []
},
{
"query": "row var = e()",
"error": [],
@ -23968,6 +24030,18 @@
"error": [],
"warning": []
},
{
"query": "from a_index | stats max(\"2022\")",
"error": [],
"warning": []
},
{
"query": "from a_index | stats max(concat(\"20\", \"22\"))",
"error": [
"Argument of [max] must be [number], found value [concat(\"20\", \"22\")] type [string]"
],
"warning": []
},
{
"query": "from a_index | stats var = min(numberField)",
"error": [],
@ -24229,6 +24303,18 @@
"error": [],
"warning": []
},
{
"query": "from a_index | stats min(\"2022\")",
"error": [],
"warning": []
},
{
"query": "from a_index | stats min(concat(\"20\", \"22\"))",
"error": [
"Argument of [min] must be [number], found value [concat(\"20\", \"22\")] type [string]"
],
"warning": []
},
{
"query": "from a_index | stats var = count(stringField)",
"error": [],
@ -24775,6 +24861,73 @@
],
"warning": []
},
{
"query": "from a_index | stats bucket(\"2022\", 1 year)",
"error": [],
"warning": []
},
{
"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]"
],
"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]"
],
"warning": []
},
{
"query": "from a_index | stats bucket(\"2022\", 5, \"a\", \"a\")",
"error": [],
"warning": []
},
{
"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]"
],
"warning": []
},
{
"query": "from a_index | stats bucket(\"2022\", 5, \"2022\", \"2022\")",
"error": [],
"warning": []
},
{
"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]"
],
"warning": []
},
{
"query": "from a_index | stats bucket(\"2022\", 5, \"a\", \"2022\")",
"error": [],
"warning": []
},
{
"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]"
],
"warning": []
},
{
"query": "from a_index | stats bucket(\"2022\", 5, \"2022\", \"a\")",
"error": [],
"warning": []
},
{
"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]"
],
"warning": []
},
{
"query": "row var = cbrt(5)",
"error": [],

View file

@ -2025,6 +2025,15 @@ describe('validation logic', () => {
);
testErrorsAndWarnings('from a_index | eval date_diff(null, null, null)', []);
testErrorsAndWarnings('row nullVar = null | eval date_diff(nullVar, nullVar, nullVar)', []);
testErrorsAndWarnings('from a_index | eval date_diff("year", "2022", "2022")', []);
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]',
]
);
});
describe('abs', () => {
@ -2898,6 +2907,18 @@ describe('validation logic', () => {
]);
testErrorsAndWarnings('from a_index | eval date_extract(null, null)', []);
testErrorsAndWarnings('row nullVar = null | eval date_extract(nullVar, nullVar)', []);
testErrorsAndWarnings(
'from a_index | eval date_extract("ALIGNED_DAY_OF_WEEK_IN_MONTH", "2022")',
[]
);
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]',
]
);
});
describe('date_format', () => {
@ -2937,6 +2958,10 @@ describe('validation logic', () => {
]);
testErrorsAndWarnings('from a_index | eval date_format(null, null)', []);
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]',
]);
});
describe('date_parse', () => {
@ -3038,6 +3063,19 @@ describe('validation logic', () => {
);
testErrorsAndWarnings('from a_index | eval date_trunc(null, null)', []);
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]',
]);
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]',
]
);
});
describe('e', () => {
@ -9353,6 +9391,10 @@ describe('validation logic', () => {
]);
testErrorsAndWarnings('from a_index | stats max(null)', []);
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]',
]);
});
describe('min', () => {
@ -9493,6 +9535,10 @@ describe('validation logic', () => {
]);
testErrorsAndWarnings('from a_index | stats min(null)', []);
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]',
]);
});
describe('count', () => {
@ -9807,6 +9853,37 @@ describe('validation logic', () => {
'Argument of [bucket] must be a constant, received [nullVar]',
]
);
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]',
]);
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]',
]);
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]',
]);
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]']
);
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]']
);
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]']
);
});
describe('cbrt', () => {