SQL: Fix translation of math functions to painless (#35910)

`SIGN` and `RADIANS` where wrongly overriding `mathFunction()`.
Converted `mathFunction()` to private in `MathFunction` since it
shouldn't be overriden, as it uses the assigned `MathOperation`
to get the funtion name for painless scripts.

Fixes: #35654
This commit is contained in:
Marios Trivyzas 2018-11-27 15:33:43 +01:00 committed by GitHub
parent 8d9e21ffaa
commit 1da9c6faa0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 27 additions and 15 deletions

View File

@ -41,11 +41,8 @@ public abstract class MathFunction extends UnaryScalarFunction {
@Override
public String processScript(String template) {
return super.processScript(format(Locale.ROOT, "{sql}.%s(%s)", mathFunction(), template));
}
protected String mathFunction() {
return getClass().getSimpleName().toLowerCase(Locale.ROOT);
return super.processScript(format(
Locale.ROOT, "{sql}.%s(%s)", getClass().getSimpleName().toLowerCase(Locale.ROOT), template));
}
@Override

View File

@ -29,11 +29,6 @@ public class Radians extends MathFunction {
return new Radians(location(), newChild);
}
@Override
protected String mathFunction() {
return "toRadians";
}
@Override
protected MathOperation operation() {
return MathOperation.RADIANS;

View File

@ -34,11 +34,6 @@ public class Sign extends MathFunction {
return new Sign(location(), newChild);
}
@Override
protected String mathFunction() {
return "signum";
}
@Override
protected MathOperation operation() {
return MathOperation.SIGN;

View File

@ -14,6 +14,7 @@ import org.elasticsearch.xpack.sql.analysis.index.IndexResolution;
import org.elasticsearch.xpack.sql.analysis.index.MappingException;
import org.elasticsearch.xpack.sql.expression.Expression;
import org.elasticsearch.xpack.sql.expression.function.FunctionRegistry;
import org.elasticsearch.xpack.sql.expression.function.scalar.math.MathProcessor.MathOperation;
import org.elasticsearch.xpack.sql.parser.SqlParser;
import org.elasticsearch.xpack.sql.plan.logical.Filter;
import org.elasticsearch.xpack.sql.plan.logical.LogicalPlan;
@ -34,9 +35,13 @@ import org.elasticsearch.xpack.sql.util.DateUtils;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import java.util.Locale;
import java.util.Map;
import java.util.TimeZone;
import java.util.stream.Stream;
import static org.elasticsearch.xpack.sql.expression.function.scalar.math.MathProcessor.MathOperation.E;
import static org.elasticsearch.xpack.sql.expression.function.scalar.math.MathProcessor.MathOperation.PI;
import static org.hamcrest.Matchers.endsWith;
import static org.hamcrest.Matchers.startsWith;
@ -367,4 +372,24 @@ public class QueryTranslatorTests extends ESTestCase {
assertThat(aggFilter.scriptTemplate().params().toString(), startsWith("[{a=MAX(int){a->"));
assertThat(aggFilter.scriptTemplate().params().toString(), endsWith(", {v=[10, null, 20, 30]}]"));
}
public void testTranslateMathFunction_HavingClause_Painless() {
MathOperation operation =
(MathOperation) randomFrom(Stream.of(MathOperation.values()).filter(o -> o != PI && o != E).toArray());
LogicalPlan p = plan("SELECT keyword, max(int) FROM test GROUP BY keyword HAVING " +
operation.name() + "(max(int)) > 10");
assertTrue(p instanceof Project);
assertTrue(p.children().get(0) instanceof Filter);
Expression condition = ((Filter) p.children().get(0)).condition();
assertFalse(condition.foldable());
QueryTranslation translation = QueryTranslator.toQuery(condition, true);
assertNull(translation.query);
AggFilter aggFilter = translation.aggFilter;
assertEquals("InternalSqlScriptUtils.nullSafeFilter(InternalSqlScriptUtils.gt(InternalSqlScriptUtils." +
operation.name().toLowerCase(Locale.ROOT) + "(params.a0),params.v0))",
aggFilter.scriptTemplate().toString());
assertThat(aggFilter.scriptTemplate().params().toString(), startsWith("[{a=MAX(int){a->"));
assertThat(aggFilter.scriptTemplate().params().toString(), endsWith(", {v=10}]"));
}
}