|
33 | 33 | import io.trino.sql.tree.Expression;
|
34 | 34 | import io.trino.sql.tree.FunctionSpecification;
|
35 | 35 | import io.trino.sql.tree.Node;
|
| 36 | +import io.trino.sql.tree.NodeRef; |
| 37 | +import io.trino.sql.tree.Parameter; |
| 38 | +import io.trino.sql.tree.PropertiesCharacteristic; |
| 39 | +import io.trino.sql.tree.Property; |
36 | 40 | import io.trino.sql.tree.QualifiedName;
|
37 | 41 |
|
38 | 42 | import java.util.List;
|
| 43 | +import java.util.Map; |
39 | 44 | import java.util.Optional;
|
40 | 45 | import java.util.function.BiFunction;
|
41 | 46 |
|
| 47 | +import static com.google.common.collect.ImmutableList.toImmutableList; |
42 | 48 | import static com.google.common.util.concurrent.Futures.immediateVoidFuture;
|
| 49 | +import static io.trino.execution.ParameterExtractor.bindParameters; |
43 | 50 | import static io.trino.spi.StandardErrorCode.ALREADY_EXISTS;
|
44 | 51 | import static io.trino.spi.StandardErrorCode.GENERIC_INTERNAL_ERROR;
|
45 | 52 | import static io.trino.spi.StandardErrorCode.NOT_SUPPORTED;
|
46 | 53 | import static io.trino.spi.StandardErrorCode.SYNTAX_ERROR;
|
47 | 54 | import static io.trino.sql.SqlFormatter.formatSql;
|
48 | 55 | import static io.trino.sql.analyzer.SemanticExceptions.semanticException;
|
| 56 | +import static io.trino.sql.routine.SqlRoutineAnalyzer.getProperties; |
49 | 57 | import static io.trino.sql.routine.SqlRoutineAnalyzer.isRunAsInvoker;
|
50 | 58 | import static java.util.Objects.requireNonNull;
|
51 | 59 |
|
@@ -94,6 +102,8 @@ public ListenableFuture<Void> execute(CreateFunction statement, QueryStateMachin
|
94 | 102 |
|
95 | 103 | languageFunctionManager.verifyForCreate(session, function, functionManager, accessControl);
|
96 | 104 |
|
| 105 | + function = materializeFunctionProperties(session, function, bindParameters(statement, parameters)); |
| 106 | + |
97 | 107 | String signatureToken = languageFunctionManager.getSignatureToken(function.getParameters());
|
98 | 108 |
|
99 | 109 | String sql = functionToSql(function);
|
@@ -121,6 +131,32 @@ public ListenableFuture<Void> execute(CreateFunction statement, QueryStateMachin
|
121 | 131 | return immediateVoidFuture();
|
122 | 132 | }
|
123 | 133 |
|
| 134 | + private FunctionSpecification materializeFunctionProperties(Session session, FunctionSpecification function, Map<NodeRef<Parameter>, Expression> parameters) |
| 135 | + { |
| 136 | + List<Property> originalProperties = getProperties(function); |
| 137 | + if (originalProperties.isEmpty()) { |
| 138 | + return function; |
| 139 | + } |
| 140 | + |
| 141 | + List<Property> sqlProperties = languageFunctionManager.materializeFunctionProperties(session, function, parameters, accessControl); |
| 142 | + |
| 143 | + return new FunctionSpecification( |
| 144 | + function.getLocation().orElseThrow(), |
| 145 | + function.getName(), |
| 146 | + function.getParameters(), |
| 147 | + function.getReturnsClause(), |
| 148 | + function.getRoutineCharacteristics().stream() |
| 149 | + .map(characteristic -> { |
| 150 | + if (characteristic instanceof PropertiesCharacteristic) { |
| 151 | + return new PropertiesCharacteristic(characteristic.getLocation().orElseThrow(), sqlProperties); |
| 152 | + } |
| 153 | + return characteristic; |
| 154 | + }) |
| 155 | + .collect(toImmutableList()), |
| 156 | + function.getStatement(), |
| 157 | + function.getDefinition()); |
| 158 | + } |
| 159 | + |
124 | 160 | private String functionToSql(FunctionSpecification function)
|
125 | 161 | {
|
126 | 162 | String sql = formatSql(function);
|
|
0 commit comments