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