Make SQL function work for input parameters with lambda
@@ -36,6 +36,7 @@ import com.google.common.base.VerifyException;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
+import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
@@ -121,12 +122,14 @@ public class RowExpressionCompiler
RowExpression function = getSqlFunctionRowExpression(functionMetadata, functionImplementation, metadata, sqlFunctionProperties, call.getArguments());
// Pre-compile lambda bytecode
- ImmutableMap.Builder<LambdaDefinitionExpression, LambdaBytecodeGenerator.CompiledLambda> newCompiledLambdaMap = ImmutableMap.builder();
- newCompiledLambdaMap.putAll(compiledLambdaMap);
- newCompiledLambdaMap.putAll(generateMethodsForLambda(classDefinition, callSiteBinder, cachedInstanceBinder, function, metadata, sqlFunctionProperties, "sql"));
+ // When we inline the input parameters, if the parameter contains lambda, that lambda has already been pre-compiled and exist in compiledLambdaMap. When we pre-compile the function
+ // it would be compiled again. Do not put these in the new map in this case.
+ Map<LambdaDefinitionExpression, LambdaBytecodeGenerator.CompiledLambda> newCompiledLambdaMap = new HashMap<>(compiledLambdaMap);
+ generateMethodsForLambda(classDefinition, callSiteBinder, cachedInstanceBinder, function, metadata, sqlFunctionProperties, "sql")
+ .forEach(newCompiledLambdaMap::putIfAbsent);
// generate bytecode for SQL function
- RowExpressionCompiler newRowExpressionCompiler = new RowExpressionCompiler(classDefinition, callSiteBinder, cachedInstanceBinder, fieldReferenceCompiler, metadata, sqlFunctionProperties, newCompiledLambdaMap.build());
+ RowExpressionCompiler newRowExpressionCompiler = new RowExpressionCompiler(classDefinition, callSiteBinder, cachedInstanceBinder, fieldReferenceCompiler, metadata, sqlFunctionProperties, ImmutableMap.copyOf(newCompiledLambdaMap));
// If called on null input, directly use the generated bytecode
if (functionMetadata.isCalledOnNullInput() || call.getArguments().isEmpty()) {
return newRowExpressionCompiler.compile(
