Source code: org/apache/derby/impl/sql/compile/SpecialFunctionNode.java
1 /*
2
3 Derby - Class org.apache.derby.impl.sql.compile.SpecialFunctionNode
4
5 Copyright 1999, 2005 The Apache Software Foundation or its licensors, as applicable.
6
7 Licensed under the Apache License, Version 2.0 (the "License");
8 you may not use this file except in compliance with the License.
9 You may obtain a copy of the License at
10
11 http://www.apache.org/licenses/LICENSE-2.0
12
13 Unless required by applicable law or agreed to in writing, software
14 distributed under the License is distributed on an "AS IS" BASIS,
15 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 See the License for the specific language governing permissions and
17 limitations under the License.
18
19 */
20
21 package org.apache.derby.impl.sql.compile;
22
23 import org.apache.derby.iapi.sql.compile.CompilerContext;
24
25 import org.apache.derby.iapi.types.DataTypeDescriptor;
26
27 import org.apache.derby.iapi.services.compiler.MethodBuilder;
28 import org.apache.derby.iapi.services.compiler.LocalField;
29
30 import org.apache.derby.iapi.services.sanity.SanityManager;
31
32 import org.apache.derby.iapi.store.access.Qualifier;
33
34 import org.apache.derby.impl.sql.compile.ExpressionClassBuilder;
35
36 import java.lang.reflect.Modifier;
37
38 import org.apache.derby.iapi.error.StandardException;
39 import org.apache.derby.iapi.reference.ClassName;
40 import org.apache.derby.iapi.services.classfile.VMOpcode;
41 import org.apache.derby.iapi.sql.compile.C_NodeTypes;
42
43
44 import java.sql.Types;
45
46 import java.util.Vector;
47
48 /**
49 SpecialFunctionNode handles system SQL functions.
50 A function value is either obtained by a method
51 call off the LanguageConnectionContext or Activation.
52 LanguageConnectionContext functions are state related to the connection.
53 Activation functions are those related to the statement execution.
54
55 Each SQL function takes no arguments and returns a SQLvalue.
56 <P>
57 Functions supported:
58 <UL>
59 <LI> USER
60 <LI> CURRENT_USER
61 <LI> SESSION_USER
62 <LI> SYSTEM_USER
63 <LI> CURRENT SCHEMA
64 <LI> CURRENT ISOLATION
65 <LI> IDENTITY_VAL_LOCAL
66
67 </UL>
68
69
70 <P>
71
72 This node is used rather than some use of MethodCallNode for
73 runtime performance. MethodCallNode does not provide a fast access
74 to the current language connection or activatation, since it is geared
75 towards user defined routines.
76
77
78 */
79 public class SpecialFunctionNode extends ValueNode
80 {
81 /**
82 Name of SQL function
83 */
84 String sqlName;
85
86 /**
87 Java method name
88 */
89 private String methodName;
90
91 /**
92 Return type of Java method.
93 */
94 private String methodType;
95
96 /**
97 */
98 //private boolean isActivationCall;
99
100 /**
101 * Binding this special function means setting the result DataTypeServices.
102 * In this case, the result type is based on the operation requested.
103 *
104 * @param fromList The FROM list for the statement. This parameter
105 * is not used in this case.
106 * @param subqueryList The subquery list being built as we find
107 * SubqueryNodes. Not used in this case.
108 * @param aggregateVector The aggregate vector being built as we find
109 * AggregateNodes. Not used in this case.
110 *
111 * @return The new top of the expression tree.
112 *
113 * @exception StandardException Thrown on error
114 */
115 public ValueNode bindExpression(FromList fromList, SubqueryList subqueryList,
116 Vector aggregateVector)
117 throws StandardException
118 { DataTypeDescriptor dtd;
119 int nodeType = getNodeType();
120 switch (nodeType)
121 {
122 case C_NodeTypes.USER_NODE:
123 case C_NodeTypes.CURRENT_USER_NODE:
124 case C_NodeTypes.SESSION_USER_NODE:
125 case C_NodeTypes.SYSTEM_USER_NODE:
126 switch (nodeType)
127 {
128 case C_NodeTypes.USER_NODE: sqlName = "USER"; break;
129 case C_NodeTypes.CURRENT_USER_NODE: sqlName = "CURRENT_USER"; break;
130 case C_NodeTypes.SESSION_USER_NODE: sqlName = "SESSION_USER"; break;
131 case C_NodeTypes.SYSTEM_USER_NODE: sqlName = "SYSTEM_USER"; break;
132 }
133 methodName = "getAuthorizationId";
134 methodType = "java.lang.String";
135 dtd = DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.VARCHAR, false, 128);
136 break;
137
138 case C_NodeTypes.CURRENT_SCHEMA_NODE:
139 sqlName = "CURRENT SCHEMA";
140 methodName = "getCurrentSchemaName";
141 methodType = "java.lang.String";
142 dtd = DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.VARCHAR, false, 128);
143 break;
144
145 case C_NodeTypes.IDENTITY_VAL_NODE:
146 sqlName = "IDENTITY_VAL_LOCAL";
147 methodName = "getIdentityValue";
148 methodType = "java.lang.Long";
149 dtd = DataTypeDescriptor.getSQLDataTypeDescriptor("java.math.BigDecimal", 31, 0, true, 31);
150 break;
151
152 case C_NodeTypes.CURRENT_ISOLATION_NODE:
153 sqlName = "CURRENT ISOLATION";
154 methodName = "getCurrentIsolationLevelStr";
155 methodType = "java.lang.String";
156 dtd = DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.CHAR, 2);
157 break;
158 default:
159 if (SanityManager.DEBUG)
160 {
161 SanityManager.THROWASSERT("Invalid type for SpecialFunctionNode " + nodeType);
162 }
163 dtd = null;
164 break;
165 }
166
167 checkReliability(sqlName, CompilerContext.USER_ILLEGAL );
168 setType(dtd);
169
170 return this;
171 }
172
173 /**
174 * Return the variant type for the underlying expression.
175 All supported special functions are QUERY_INVARIANT
176
177 *
178 * @return The variant type for the underlying expression.
179 */
180 protected int getOrderableVariantType()
181 {
182 return Qualifier.QUERY_INVARIANT;
183 }
184
185 /**
186 Generate an expression that returns a DataValueDescriptor and
187 calls a method off the language connection or the activation.
188 *
189 * @param acb The ExpressionClassBuilder for the class being built
190 * @param mb The method the code to place the code
191 *
192 *
193 * @exception StandardException Thrown on error
194 */
195 public void generateExpression(ExpressionClassBuilder acb,
196 MethodBuilder mb)
197 throws StandardException
198 {
199 mb.pushThis();
200 mb.callMethod(VMOpcode.INVOKEINTERFACE, ClassName.Activation, "getLanguageConnectionContext",
201 ClassName.LanguageConnectionContext, 0);
202
203 mb.callMethod(VMOpcode.INVOKEINTERFACE, (String) null, methodName, methodType, 0);
204
205 String fieldType = getTypeCompiler().interfaceName();
206 LocalField field = acb.newFieldDeclaration(Modifier.PRIVATE, fieldType);
207
208 acb.generateDataValue(mb, getTypeCompiler(), field);
209 }
210
211 /*
212 print the non-node subfields
213 */
214 public String toString() {
215 if (SanityManager.DEBUG)
216 {
217 return super.toString()+ sqlName;
218 }
219 else
220 {
221 return "";
222 }
223 }
224 }