Skip to content

Commit f0a416b

Browse files
committed
fix
1 parent 2987c8e commit f0a416b

6 files changed

Lines changed: 103 additions & 11 deletions

File tree

fe/fe-core/src/main/java/org/apache/doris/catalog/FunctionToSqlConverter.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,14 +77,18 @@ public static String toSql(ScalarFunction fn, boolean ifNotExists) {
7777
.append("\"" + (fn.getLocation() == null ? "" : fn.getLocation().toString()) + "\"");
7878
boolean isReturnNull = fn.getNullableMode() == NullableMode.ALWAYS_NULLABLE;
7979
sb.append(",\n \"ALWAYS_NULLABLE\"=").append("\"" + isReturnNull + "\"");
80-
sb.append(",\n \"VOLATILITY\"=").append("\"" + fn.getVolatility().toSql() + "\"");
80+
if (!fn.isUDTFunction()) {
81+
sb.append(",\n \"VOLATILITY\"=").append("\"" + fn.getVolatility().toSql() + "\"");
82+
}
8183
} else if (fn.getBinaryType() == Function.BinaryType.PYTHON_UDF) {
8284
sb.append(",\n \"FILE\"=")
8385
.append("\"" + (fn.getLocation() == null ? "" : fn.getLocation().toString()) + "\"");
8486
boolean isReturnNull = fn.getNullableMode() == NullableMode.ALWAYS_NULLABLE;
8587
sb.append(",\n \"ALWAYS_NULLABLE\"=").append("\"" + isReturnNull + "\"");
8688
sb.append(",\n \"RUNTIME_VERSION\"=").append("\"" + Strings.nullToEmpty(fn.getRuntimeVersion()) + "\"");
87-
sb.append(",\n \"VOLATILITY\"=").append("\"" + fn.getVolatility().toSql() + "\"");
89+
if (!fn.isUDTFunction()) {
90+
sb.append(",\n \"VOLATILITY\"=").append("\"" + fn.getVolatility().toSql() + "\"");
91+
}
8892
} else {
8993
sb.append(",\n \"OBJECT_FILE\"=")
9094
.append("\"" + (fn.getLocation() == null ? "" : fn.getLocation().toString()) + "\"");

fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/AddProjectForUniqueFunction.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import org.apache.doris.nereids.trees.expressions.StatementScopeIdGenerator;
2929
import org.apache.doris.nereids.trees.expressions.VolatileExpression;
3030
import org.apache.doris.nereids.trees.expressions.functions.Function;
31+
import org.apache.doris.nereids.trees.expressions.functions.scalar.UniqueFunction;
3132
import org.apache.doris.nereids.trees.plans.JoinType;
3233
import org.apache.doris.nereids.trees.plans.Plan;
3334
import org.apache.doris.nereids.trees.plans.logical.LogicalAggregate;
@@ -278,8 +279,8 @@ public List<NamedExpression> tryGenUniqueFunctionAlias(Collection<? extends Expr
278279
for (Expression target : targets) {
279280
target.foreach(e -> {
280281
Expression expr = (Expression) e;
281-
if (expr instanceof VolatileExpression && ((VolatileExpression) expr).isVolatile()) {
282-
unqiueFunctionCounter.merge(expr, 1, Integer::sum);
282+
if (expr instanceof UniqueFunction) {
283+
unqiueFunctionCounter.merge((UniqueFunction) expr, 1, Integer::sum);
283284
}
284285
});
285286
}

fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/VolatileIdentity.java

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -70,15 +70,14 @@ public VolatileIdentity withIgnoreUniqueId(boolean ignoreUniqueId) {
7070

7171
/** Compare volatile expressions by identity unless either side temporarily ignores it. */
7272
public boolean equalsByIdentity(VolatileIdentity other, boolean fallbackEquals) {
73-
if (!isVolatile() && !other.isVolatile()) {
73+
if ((!isVolatile() && !other.isVolatile())
74+
|| (ignoreUniqueId && other.ignoreUniqueId())) {
7475
return fallbackEquals;
7576
}
76-
if (!isVolatile() || !other.isVolatile()) {
77+
if ((!isVolatile() || !other.isVolatile())
78+
|| (ignoreUniqueId || other.ignoreUniqueId())) {
7779
return false;
7880
}
79-
if (ignoreUniqueId || other.ignoreUniqueId()) {
80-
return fallbackEquals;
81-
}
8281
return uniqueId.equals(other.getUniqueIdOptional());
8382
}
8483

fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/ShowFunctionsCommand.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -295,8 +295,9 @@ private String buildProperties(Function function) {
295295
}
296296
if (function instanceof ScalarFunction) {
297297
ScalarFunction scalarFunction = (ScalarFunction) function;
298-
if (function.getBinaryType() == Function.BinaryType.JAVA_UDF
299-
|| function.getBinaryType() == Function.BinaryType.PYTHON_UDF) {
298+
if (!scalarFunction.isUDTFunction()
299+
&& (function.getBinaryType() == Function.BinaryType.JAVA_UDF
300+
|| function.getBinaryType() == Function.BinaryType.PYTHON_UDF)) {
300301
properties.put("VOLATILITY", function.getVolatility().toSql());
301302
}
302303
properties.put("SYMBOL", Strings.nullToEmpty(scalarFunction.getSymbolName()));
@@ -351,4 +352,9 @@ private String buildProperties(Function function) {
351352
.collect(Collectors.joining(", "));
352353
}
353354

355+
@VisibleForTesting
356+
String buildPropertiesForTest(Function function) {
357+
return buildProperties(function);
358+
}
359+
354360
}

fe/fe-core/src/test/java/org/apache/doris/catalog/FunctionToSqlConverterTest.java

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,38 @@ void testScalarFunction_pythonUdf_moduleReplaySql() throws AnalysisException {
143143
Assertions.assertFalse(sql.contains("AS $$"));
144144
}
145145

146+
@Test
147+
void testScalarFunction_javaUdtfDoesNotEmitVolatility() {
148+
FunctionName name = new FunctionName("testDb", "java_table_fn");
149+
Type[] argTypes = {Type.INT};
150+
ScalarFunction fn = ScalarFunction.createUdf(BinaryType.JAVA_UDF, name, argTypes,
151+
Type.INT, false, null, "com.example.TableFn", null, null);
152+
fn.setUDTFunction(true);
153+
fn.setVolatility(FunctionVolatility.IMMUTABLE);
154+
155+
String sql = FunctionToSqlConverter.toSql(fn, false);
156+
157+
Assertions.assertTrue(sql.contains("\"TYPE\"=\"JAVA_UDF\""));
158+
Assertions.assertFalse(sql.contains("VOLATILITY"));
159+
}
160+
161+
@Test
162+
void testScalarFunction_pythonUdtfDoesNotEmitVolatility() {
163+
FunctionName name = new FunctionName("testDb", "py_table_fn");
164+
Type[] argTypes = {Type.INT};
165+
ScalarFunction fn = ScalarFunction.createUdf(BinaryType.PYTHON_UDF, name, argTypes,
166+
Type.INT, false, null, "evaluate", null, null);
167+
fn.setUDTFunction(true);
168+
fn.setRuntimeVersion("3.10.2");
169+
fn.setVolatility(FunctionVolatility.IMMUTABLE);
170+
171+
String sql = FunctionToSqlConverter.toSql(fn, false);
172+
173+
Assertions.assertTrue(sql.contains("\"RUNTIME_VERSION\"=\"3.10.2\""));
174+
Assertions.assertTrue(sql.contains("\"TYPE\"=\"PYTHON_UDF\""));
175+
Assertions.assertFalse(sql.contains("VOLATILITY"));
176+
}
177+
146178
// ======================== ScalarFunction — IF NOT EXISTS ========================
147179

148180
@Test

fe/fe-core/src/test/java/org/apache/doris/nereids/trees/plans/commands/ShowFunctionsCommandTest.java

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@
2424
import org.apache.doris.catalog.AccessPrivilegeWithCols;
2525
import org.apache.doris.catalog.Env;
2626
import org.apache.doris.catalog.Function;
27+
import org.apache.doris.catalog.FunctionName;
28+
import org.apache.doris.catalog.FunctionVolatility;
29+
import org.apache.doris.catalog.ScalarFunction;
30+
import org.apache.doris.catalog.Type;
2731
import org.apache.doris.common.AnalysisException;
2832
import org.apache.doris.common.UserException;
2933
import org.apache.doris.mysql.privilege.Auth;
@@ -111,6 +115,52 @@ void testLike() {
111115
Assertions.assertTrue(sf.like("test_for_create_function", "test_for_create_function%"));
112116
}
113117

118+
@Test
119+
void testBuildProperties_scalarUdfEmitsVolatility() {
120+
ShowFunctionsCommand sf = new ShowFunctionsCommand("test", true, null);
121+
ScalarFunction fn = ScalarFunction.createUdf(Function.BinaryType.JAVA_UDF,
122+
new FunctionName("test", "java_scalar_fn"), new Type[] {Type.INT},
123+
Type.INT, false, null, "com.example.ScalarFn", null, null);
124+
fn.setVolatility(FunctionVolatility.IMMUTABLE);
125+
126+
String properties = sf.buildPropertiesForTest(fn);
127+
128+
Assertions.assertTrue(properties.contains("SYMBOL=com.example.ScalarFn"));
129+
Assertions.assertTrue(properties.contains("VOLATILITY=immutable"));
130+
}
131+
132+
@Test
133+
void testBuildProperties_javaUdtfDoesNotEmitVolatility() {
134+
ShowFunctionsCommand sf = new ShowFunctionsCommand("test", true, null);
135+
ScalarFunction fn = ScalarFunction.createUdf(Function.BinaryType.JAVA_UDF,
136+
new FunctionName("test", "java_table_fn"), new Type[] {Type.INT},
137+
Type.INT, false, null, "com.example.TableFn", null, null);
138+
fn.setUDTFunction(true);
139+
fn.setVolatility(FunctionVolatility.IMMUTABLE);
140+
141+
String properties = sf.buildPropertiesForTest(fn);
142+
143+
Assertions.assertTrue(properties.contains("SYMBOL=com.example.TableFn"));
144+
Assertions.assertFalse(properties.contains("VOLATILITY"));
145+
}
146+
147+
@Test
148+
void testBuildProperties_pythonUdtfDoesNotEmitVolatility() {
149+
ShowFunctionsCommand sf = new ShowFunctionsCommand("test", true, null);
150+
ScalarFunction fn = ScalarFunction.createUdf(Function.BinaryType.PYTHON_UDF,
151+
new FunctionName("test", "py_table_fn"), new Type[] {Type.INT},
152+
Type.INT, false, null, "evaluate", null, null);
153+
fn.setUDTFunction(true);
154+
fn.setRuntimeVersion("3.10.2");
155+
fn.setVolatility(FunctionVolatility.IMMUTABLE);
156+
157+
String properties = sf.buildPropertiesForTest(fn);
158+
159+
Assertions.assertTrue(properties.contains("RUNTIME_VERSION=3.10.2"));
160+
Assertions.assertTrue(properties.contains("SYMBOL=evaluate"));
161+
Assertions.assertFalse(properties.contains("VOLATILITY"));
162+
}
163+
114164
@Test
115165
void testAuth() throws Exception {
116166
auth = Env.getCurrentEnv().getAuth();

0 commit comments

Comments
 (0)