001: /*
002:
003: Derby - Class org.apache.derby.impl.sql.compile.ConstantNode
004:
005: Licensed to the Apache Software Foundation (ASF) under one or more
006: contributor license agreements. See the NOTICE file distributed with
007: this work for additional information regarding copyright ownership.
008: The ASF licenses this file to you under the Apache License, Version 2.0
009: (the "License"); you may not use this file except in compliance with
010: the License. You may obtain a copy of the License at
011:
012: http://www.apache.org/licenses/LICENSE-2.0
013:
014: Unless required by applicable law or agreed to in writing, software
015: distributed under the License is distributed on an "AS IS" BASIS,
016: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: See the License for the specific language governing permissions and
018: limitations under the License.
019:
020: */
021:
022: package org.apache.derby.impl.sql.compile;
023:
024: import org.apache.derby.iapi.types.DataValueDescriptor;
025: import org.apache.derby.iapi.types.TypeId;
026: import org.apache.derby.iapi.sql.dictionary.DataDictionary;
027:
028: import org.apache.derby.iapi.error.StandardException;
029:
030: import org.apache.derby.iapi.services.compiler.MethodBuilder;
031: import org.apache.derby.iapi.services.compiler.LocalField;
032:
033: import org.apache.derby.impl.sql.compile.ExpressionClassBuilder;
034:
035: import java.lang.reflect.Modifier;
036:
037: import org.apache.derby.iapi.services.sanity.SanityManager;
038:
039: import org.apache.derby.iapi.store.access.Qualifier;
040:
041: import org.apache.derby.iapi.util.ReuseFactory;
042:
043: import java.sql.Date;
044: import java.sql.Time;
045: import java.sql.Timestamp;
046:
047: import java.util.Vector;
048:
049: /**
050: * ConstantNode holds literal constants as well as nulls.
051: * <p>
052: * A NULL from the parser may not yet know its type; that
053: * must be set during binding, as it is for parameters.
054: * <p>
055: * the DataValueDescriptor methods want to throw exceptions
056: * when they are of the wrong type, but to do that they
057: * must check typeId when the value is null, rather than
058: * the instanceof check they do for returning a valid value.
059: * <p>
060: * For code generation, we generate a static field. Then we set the
061: * field be the proper constant expression (something like <code>
062: * getDatavalueFactory().getCharDataValue("hello", ...)) </code>)
063: * in the constructor of the generated method. Ideally
064: * we would have just
065: */
066: abstract class ConstantNode extends ValueNode {
067: protected DataValueDescriptor value;
068:
069: /*
070: ** In case generateExpression() is called twice (something
071: ** that probably wont happen but might), we will cache
072: ** our generated expression and just return a reference
073: ** to the field that holds our value (instead of having
074: ** two fields holding the same constant).
075: */
076:
077: /**
078: * Initializer for non-numeric types
079: *
080: * @param typeId The Type ID of the datatype
081: * @param nullable True means the constant is nullable
082: * @param maximumWidth The maximum number of bytes in the data value
083: *
084: * @exception StandardException
085: */
086: public void init(Object typeId, Object nullable, Object maximumWidth)
087: throws StandardException {
088: /* Fill in the type information in the parent ValueNode */
089: init(typeId, ReuseFactory.getInteger(0), ReuseFactory
090: .getInteger(0), nullable, maximumWidth);
091: }
092:
093: /**
094: * Constructor for untyped nodes, which contain little information
095: *
096: */
097: ConstantNode() {
098: super ();
099: }
100:
101: /**
102: * Set the value in this ConstantNode.
103: */
104: void setValue(DataValueDescriptor value) {
105: this .value = value;
106: }
107:
108: /**
109: * Get the value in this ConstantNode
110: */
111: public DataValueDescriptor getValue() {
112: return value;
113: }
114:
115: /**
116: * Convert this object to a String. See comments in QueryTreeNode.java
117: * for how this should be done for tree printing.
118: *
119: * @return This object as a String
120: */
121:
122: public String toString() {
123: if (SanityManager.DEBUG) {
124: return "value: " + value + "\n" + super .toString();
125: } else {
126: return "";
127: }
128: }
129:
130: /**
131: * Return whether or not this expression tree is cloneable.
132: *
133: * @return boolean Whether or not this expression tree is cloneable.
134: */
135: public boolean isCloneable() {
136: return true;
137: }
138:
139: /**
140: * Return a clone of this node.
141: *
142: * @return ValueNode A clone of this node.
143: *
144: */
145: public ValueNode getClone() {
146: /* All constants can simply be reused */
147: return this ;
148: }
149:
150: /**
151: * Bind this expression. This means binding the sub-expressions,
152: * as well as figuring out what the return type is for this expression.
153: * In this case, there are no sub-expressions, and the return type
154: * is already known, so this is just a stub.
155: *
156: * @param fromList The FROM list for the query this
157: * expression is in, for binding columns.
158: * @param subqueryList The subquery list being built as we find SubqueryNodes
159: * @param aggregateVector The aggregate vector being built as we find AggregateNodes
160: *
161: * @return The new top of the expression tree.
162: */
163: public ValueNode bindExpression(FromList fromList,
164: SubqueryList subqueryList, Vector aggregateVector) {
165: /*
166: ** This has to be here for binding to work, but it doesn't
167: ** have to do anything, because the datatypes of constant nodes
168: ** are pre-generated by the parser.
169: */
170: return this ;
171: }
172:
173: /**
174: * Return whether or not this expression tree represents a constant expression.
175: *
176: * @return Whether or not this expression tree represents a constant expression.
177: */
178: public boolean isConstantExpression() {
179: return true;
180: }
181:
182: /** @see ValueNode#constantExpression */
183: public boolean constantExpression(PredicateList whereClause) {
184: return true;
185: }
186:
187: /**
188: * For a ConstantNode, we generate the equivalent literal value.
189: * A null is generated as a Null value cast to the type of
190: * the constant node.
191: * The subtypes of ConstantNode generate literal expressions
192: * for non-null values.
193: *
194: * @param acb The ExpressionClassBuilder for the class being built
195: * @param mb The method the code to place the code
196: *
197: * @exception StandardException Thrown on error
198: */
199: public void generateExpression(ExpressionClassBuilder acb,
200: MethodBuilder mb) throws StandardException {
201: /* Are we generating a SQL null value? */
202: if (isNull()) {
203: acb.generateNull(mb, getTypeCompiler());
204: } else {
205: generateConstant(acb, mb); // ask sub type to give a constant,
206: // usually a literal like 'hello'
207:
208: acb.generateDataValue(mb, getTypeCompiler(),
209: (LocalField) null);
210: }
211: }
212:
213: /**
214: * This generates the proper constant. It is implemented
215: * by every specific constant node (e.g. IntConstantNode).
216: *
217: * @param acb The ExpressionClassBuilder for the class being built
218: * @param mb The method the code to place the code
219: *
220: * @exception StandardException Thrown on error
221: */
222: abstract void generateConstant(ExpressionClassBuilder acb,
223: MethodBuilder mb) throws StandardException;
224:
225: /**
226: * Return whether or not this node represents a typed null constant.
227: *
228: */
229: public boolean isNull() {
230: return (value == null || value.isNull());
231: }
232:
233: /**
234: * Return the variant type for the underlying expression.
235: * The variant type can be:
236: * VARIANT - variant within a scan
237: * (method calls and non-static field access)
238: * SCAN_INVARIANT - invariant within a scan
239: * (column references from outer tables)
240: * QUERY_INVARIANT - invariant within the life of a query
241: * VARIANT - immutable
242: *
243: * @return The variant type for the underlying expression.
244: */
245: protected int getOrderableVariantType() {
246: // Constants are constant for the life of the query
247: return Qualifier.CONSTANT;
248: }
249:
250: protected boolean isEquivalent(ValueNode o)
251: throws StandardException {
252: if (isSameNodeType(o)) {
253: ConstantNode other = (ConstantNode) o;
254:
255: // value can be null which represents a SQL NULL value.
256: return ((other.getValue() == null && getValue() == null) || (other
257: .getValue() != null && other.getValue().compare(
258: getValue()) == 0));
259: }
260: return false;
261: }
262: }
|