This is an automated email from the ASF dual-hosted git repository.
michaelsmith pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/impala.git
The following commit(s) were added to refs/heads/master by this push:
new f6ceca2b4 IMPALA-14571: increase planner cost of java functions
f6ceca2b4 is described below
commit f6ceca2b4d37d6a6d6f3881ddb3509165d1deb2a
Author: Csaba Ringhofer <[email protected]>
AuthorDate: Fri Apr 4 16:22:24 2025 +0200
IMPALA-14571: increase planner cost of java functions
The main motivation is to evaluate expensive geospatial
functions (which are Java functions) last in predicates.
Java functions have a major overhead anyway from the JNI
call, so bumping all Java function costs seems beneficial.
Note that currently geospatial functions are the only
built-in Java functions.
Change-Id: I11d1652d76092ec60af18a33502dacc25b284fcc
Reviewed-on: http://gerrit.cloudera.org:8080/22733
Reviewed-by: Impala Public Jenkins <[email protected]>
Tested-by: Impala Public Jenkins <[email protected]>
---
fe/src/main/java/org/apache/impala/analysis/Expr.java | 1 +
.../main/java/org/apache/impala/analysis/FunctionCallExpr.java | 5 ++++-
.../queries/QueryTest/geospatial-esri-planner.test | 10 ++++++++++
tests/query_test/test_geospatial_functions.py | 5 +++++
4 files changed, 20 insertions(+), 1 deletion(-)
diff --git a/fe/src/main/java/org/apache/impala/analysis/Expr.java
b/fe/src/main/java/org/apache/impala/analysis/Expr.java
index 1fd6e4db9..8c69736d9 100644
--- a/fe/src/main/java/org/apache/impala/analysis/Expr.java
+++ b/fe/src/main/java/org/apache/impala/analysis/Expr.java
@@ -89,6 +89,7 @@ abstract public class Expr extends TreeNode<Expr> implements
ParseNode, Cloneabl
public static final float VAR_LEN_BINARY_PREDICATE_COST = 5;
public static final float COMPOUND_PREDICATE_COST = 1;
public static final float FUNCTION_CALL_COST = 10;
+ public static final float JAVA_FUNCTION_CALL_COST = 100;
public static final float IS_NOT_EMPTY_COST = 1;
public static final float IS_NULL_COST = 1;
public static final float LIKE_COST = 10;
diff --git a/fe/src/main/java/org/apache/impala/analysis/FunctionCallExpr.java
b/fe/src/main/java/org/apache/impala/analysis/FunctionCallExpr.java
index 54ea6c513..2933d17b5 100644
--- a/fe/src/main/java/org/apache/impala/analysis/FunctionCallExpr.java
+++ b/fe/src/main/java/org/apache/impala/analysis/FunctionCallExpr.java
@@ -840,8 +840,11 @@ public class FunctionCallExpr extends Expr {
@Override
protected float computeEvalCost() {
+ Preconditions.checkState(fn_ != null);
+ boolean isJava = fn_.getBinaryType() == TFunctionBinaryType.JAVA;
+ float callCost = isJava ? JAVA_FUNCTION_CALL_COST : FUNCTION_CALL_COST;
// TODO(tmarshall): Differentiate based on the specific function.
- return hasChildCosts() ? getChildCosts() + FUNCTION_CALL_COST :
UNKNOWN_COST;
+ return hasChildCosts() ? getChildCosts() + callCost : UNKNOWN_COST;
}
public FunctionCallExpr getMergeAggInputFn() { return mergeAggInputFn_; }
diff --git
a/testdata/workloads/functional-query/queries/QueryTest/geospatial-esri-planner.test
b/testdata/workloads/functional-query/queries/QueryTest/geospatial-esri-planner.test
new file mode 100644
index 000000000..14eb187bc
--- /dev/null
+++
b/testdata/workloads/functional-query/queries/QueryTest/geospatial-esri-planner.test
@@ -0,0 +1,10 @@
+=====
+---- QUERY
+# Check that st_geomfromwkb(), which is a Java function, is moved after the
other
+# expression in the predicate.
+select * from functional.binary_tbl
+where st_geomfromwkb(binary_col) is not null and sqrt(id) = 1;
+---- RUNTIME_PROFILE
+predicates: sqrt(CAST(id AS DOUBLE)) = CAST(1 AS DOUBLE),
st_geomfromwkb(binary_col) IS NOT NULL
+====
+
diff --git a/tests/query_test/test_geospatial_functions.py
b/tests/query_test/test_geospatial_functions.py
index 2ae9ae649..acaad7147 100644
--- a/tests/query_test/test_geospatial_functions.py
+++ b/tests/query_test/test_geospatial_functions.py
@@ -25,3 +25,8 @@ class TestGeospatialFuctions(ImpalaTestSuite):
@SkipIfApacheHive.feature_not_supported
def test_esri_geospatial_functions(self, vector):
self.run_test_case('QueryTest/geospatial-esri', vector)
+
+ def test_esri_geospatial_planner(self, vector):
+ # These tests are not among planner tests because with default flags
+ # geospatial builtin functions are not loaded.
+ self.run_test_case('QueryTest/geospatial-esri-planner', vector)