13
13
*/
14
14
package com .facebook .presto .sql .relational ;
15
15
16
+ import com .facebook .presto .common .CatalogSchemaName ;
17
+ import com .facebook .presto .common .QualifiedObjectName ;
16
18
import com .facebook .presto .metadata .FunctionAndTypeManager ;
17
19
import com .facebook .presto .metadata .Metadata ;
18
20
import com .facebook .presto .spi .ConnectorSession ;
21
+ import com .facebook .presto .spi .relation .CallExpression ;
19
22
import com .facebook .presto .spi .relation .ExpressionOptimizer ;
20
23
import com .facebook .presto .spi .relation .RowExpression ;
24
+ import com .facebook .presto .spi .relation .RowExpressionVisitor ;
21
25
import com .facebook .presto .spi .relation .VariableReferenceExpression ;
26
+ import com .facebook .presto .sql .analyzer .TypeSignatureProvider ;
22
27
import com .facebook .presto .sql .planner .RowExpressionInterpreter ;
23
28
24
29
import java .util .function .Function ;
25
30
31
+ import static com .facebook .presto .metadata .BuiltInTypeAndFunctionNamespaceManager .JAVA_BUILTIN_NAMESPACE ;
26
32
import static com .facebook .presto .spi .relation .ExpressionOptimizer .Level .OPTIMIZED ;
27
33
import static com .facebook .presto .sql .planner .LiteralEncoder .toRowExpression ;
34
+ import static com .google .common .collect .ImmutableList .toImmutableList ;
28
35
import static java .util .Objects .requireNonNull ;
36
+ import static java .util .function .UnaryOperator .identity ;
29
37
30
38
public final class RowExpressionOptimizer
31
39
implements ExpressionOptimizer
32
40
{
33
41
private final FunctionAndTypeManager functionAndTypeManager ;
42
+ private final CatalogSchemaName defaultNamespace ;
43
+ private final Function <RowExpression , RowExpression > normalizeRowExpression ;
34
44
35
45
public RowExpressionOptimizer (Metadata metadata )
36
46
{
@@ -39,22 +49,73 @@ public RowExpressionOptimizer(Metadata metadata)
39
49
40
50
public RowExpressionOptimizer (FunctionAndTypeManager functionAndTypeManager )
41
51
{
52
+ this .defaultNamespace = requireNonNull (functionAndTypeManager , "functionMetadataManager is null" ).getDefaultNamespace ();
42
53
this .functionAndTypeManager = requireNonNull (functionAndTypeManager , "functionMetadataManager is null" );
54
+ if (!defaultNamespace .equals (JAVA_BUILTIN_NAMESPACE )) {
55
+ this .normalizeRowExpression = rowExpression -> rowExpression .accept (new BuiltInFunctionNamespaceOverride (), null );
56
+ }
57
+ else {
58
+ this .normalizeRowExpression = identity ();
59
+ }
43
60
}
44
61
45
62
@ Override
46
63
public RowExpression optimize (RowExpression rowExpression , Level level , ConnectorSession session )
47
64
{
48
65
if (level .ordinal () <= OPTIMIZED .ordinal ()) {
49
- return toRowExpression (rowExpression .getSourceLocation (), new RowExpressionInterpreter (rowExpression , functionAndTypeManager , session , level ).optimize (), rowExpression .getType ());
66
+ RowExpressionInterpreter rowExpressionInterpreter = new RowExpressionInterpreter (
67
+ normalizeRowExpression .apply (rowExpression ),
68
+ functionAndTypeManager ,
69
+ session ,
70
+ level );
71
+ return toRowExpression (rowExpression .getSourceLocation (), rowExpressionInterpreter .optimize (), rowExpression .getType ());
50
72
}
51
73
throw new IllegalArgumentException ("Not supported optimization level: " + level );
52
74
}
53
75
54
76
@ Override
55
77
public RowExpression optimize (RowExpression expression , Level level , ConnectorSession session , Function <VariableReferenceExpression , Object > variableResolver )
56
78
{
57
- RowExpressionInterpreter interpreter = new RowExpressionInterpreter (expression , functionAndTypeManager , session , level );
79
+ RowExpressionInterpreter interpreter = new RowExpressionInterpreter (
80
+ normalizeRowExpression .apply (expression ),
81
+ functionAndTypeManager ,
82
+ session ,
83
+ level );
58
84
return toRowExpression (expression .getSourceLocation (), interpreter .optimize (variableResolver ::apply ), expression .getType ());
59
85
}
86
+
87
+ /**
88
+ * TODO: GIANT HACK
89
+ * This class is a hack and should eventually be removed. It is used to ensure consistent constant folding behavior when the built-in
90
+ * function namespace has been switched (for example, to native.default. in the case of native functions). This will no longer be needed
91
+ * when the native sidecar is capable of providing its own expression optimizer.
92
+ */
93
+ private class BuiltInFunctionNamespaceOverride
94
+ implements RowExpressionVisitor <RowExpression , Void >
95
+ {
96
+ @ Override
97
+ public RowExpression visitExpression (RowExpression expression , Void context )
98
+ {
99
+ return expression ;
100
+ }
101
+
102
+ @ Override
103
+ public RowExpression visitCall (CallExpression call , Void context )
104
+ {
105
+ if (call .getFunctionHandle ().getCatalogSchemaName ().equals (defaultNamespace )) {
106
+ call = new CallExpression (
107
+ call .getSourceLocation (),
108
+ call .getDisplayName (),
109
+ functionAndTypeManager .lookupFunction (
110
+ QualifiedObjectName .valueOf (JAVA_BUILTIN_NAMESPACE , call .getDisplayName ()),
111
+ call .getArguments ().stream ()
112
+ .map (RowExpression ::getType )
113
+ .map (x -> new TypeSignatureProvider (x .getTypeSignature ()))
114
+ .collect (toImmutableList ())),
115
+ call .getType (),
116
+ call .getArguments ());
117
+ }
118
+ return call ;
119
+ }
120
+ }
60
121
}
0 commit comments