You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
A column compared with a function of itself collapses onto one Painless parameter — silent wrong answer #370
A predicate that compares a column with a FUNCTION OF THAT SAME COLUMN answers with the wrong rows,
silently, on every Elasticsearch major.
Measured on real Elasticsearch 8.18.3
Two documents, d = 2025-01-06 and d = 2024-01-06:
WHERE DATE_TRUNC(d, MONTH) < d rows: [] truth: both documents
WHERE DATE_ADD(d, INTERVAL 1 DAY) = d rows: [a, b] truth: neither
HTTP 200 both times. The first is always false, the second always true, whatever the data.
Cause
PainlessParam identity is the doc-value STRING (Identifier.param = paramName), while the
function's methods are attached to the parameter OBJECT by addPainlessMethod. So when the same
column appears on both sides and the left-hand function folds into the parameter as a method, both
sides resolve to that ONE parameter — and the emitted script compares the transformed value with
itself:
param1 carries the truncation, so left1.isBefore(param1) is x < x.
Population
Exactly the functions whose Painless folds into the parameter as a suffix method — DATE_TRUNC, DATE_ADD / DATE_SUB and the interval family, YEAR, MONTH, DAY, EPOCHDAY, the whole
extraction family — compared against their own column.
A function that renders as an EXPRESSION is unaffected, because it never folds: WHERE UPPER(name) = name emits left1 == param1 with left1 = param1.toUpperCase() and is correct (measured: returns
the right row).
Not a regression
Present before and after the fix for #367, verbatim the same rows. #367 removed the shortcut that
dropped the transform; it does not touch parameter identity.
The repair is to parameter IDENTITY — two uses of one column with different transforms must be two
parameters — and every emission that reuses a parameter goes through that code (YEAR(d) = 2025
included). That is its own change with its own evidence, not a rider on a predicate fix.
Guard that exists today
PredicateFunctionResultSpec (added with #367) executes DATE_TRUNC(d, MONTH) < d on all four
majors and asserts the WRONG answer, with this issue's number in the comment, so the day it is fixed
that assertion turns red and says why.
Activity
docs(sql): record the Elasticsearch 6.8 limit of DATE_FORMAT / DATETI…
Merge pull request #374 from SOFTNETWORK-APP/fix/370-parameter-identi…