KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > derby > impl > sql > compile > VirtualColumnNode


1 /*
2
3    Derby - Class org.apache.derby.impl.sql.compile.VirtualColumnNode
4
5    Licensed to the Apache Software Foundation (ASF) under one or more
6    contributor license agreements. See the NOTICE file distributed with
7    this work for additional information regarding copyright ownership.
8    The ASF licenses this file to you under the Apache License, Version 2.0
9    (the "License"); you may not use this file except in compliance with
10    the License. You may obtain a copy of the License at
11
12       http://www.apache.org/licenses/LICENSE-2.0
13
14    Unless required by applicable law or agreed to in writing, software
15    distributed under the License is distributed on an "AS IS" BASIS,
16    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17    See the License for the specific language governing permissions and
18    limitations under the License.
19
20  */

21
22 package org.apache.derby.impl.sql.compile;
23
24 import org.apache.derby.iapi.services.compiler.MethodBuilder;
25
26 import org.apache.derby.iapi.services.sanity.SanityManager;
27
28 import org.apache.derby.iapi.types.DataTypeDescriptor;
29 import org.apache.derby.iapi.error.StandardException;
30
31 import org.apache.derby.impl.sql.compile.ExpressionClassBuilder;
32
33 /**
34  * A VirtualColumnNode represents a virtual column reference to a column in
35  * a row returned by an underlying ResultSetNode. The underlying column could
36  * be in a base table, view (which could expand into a complex
37  * expression), subquery in the FROM clause, temp table, expression result, etc.
38  * By the time we get to code generation, all VirtualColumnNodes should stand only
39  * for references to columns in a base table within a FromBaseTable.
40  *
41  * @author Jeff Lichtman
42  */

43
44 public class VirtualColumnNode extends ValueNode
45 {
46     /* A VirtualColumnNode contains a pointer to the immediate child result
47      * that is materializing the virtual column and the ResultColumn
48      * that represents that materialization.
49      */

50     ResultSetNode sourceResultSet;
51     ResultColumn sourceColumn;
52
53     /* columnId is redundant since a ResultColumn also has one, but
54      * we need it here for generate()
55      */

56     int columnId;
57
58     boolean correlated = false;
59
60
61     /**
62      * Initializer for a VirtualColumnNode.
63      *
64      * @param sourceResultSet The ResultSetNode where the value is originating
65      * @param sourceColumn The ResultColumn where the value is originating
66      * @param columnId The columnId within the current Row
67      */

68
69     public void init(
70                         Object JavaDoc sourceResultSet,
71                         Object JavaDoc sourceColumn,
72                         Object JavaDoc columnId) throws StandardException
73     {
74         ResultColumn source = (ResultColumn) sourceColumn;
75
76         this.sourceResultSet = (ResultSetNode) sourceResultSet;
77         this.sourceColumn = source;
78         this.columnId = ((Integer JavaDoc) columnId).intValue();
79         setType(source.getTypeServices());
80     }
81
82
83     /**
84      * Prints the sub-nodes of this object. See QueryTreeNode.java for
85      * how tree printing is supposed to work.
86      *
87      * @param depth The depth of this node in the tree
88      */

89
90     public void printSubNodes(int depth)
91     {
92         if (SanityManager.DEBUG)
93         {
94             super.printSubNodes(depth);
95
96             if (sourceColumn != null)
97             {
98                 printLabel(depth, "sourceColumn: ");
99                 sourceColumn.treePrint(depth + 1);
100             }
101         }
102     }
103
104     /**
105      * Return the ResultSetNode that is the source of this VirtualColumnNode.
106      *
107      * @return ResultSetNode
108      */

109     public ResultSetNode getSourceResultSet()
110     {
111         return sourceResultSet;
112     }
113
114     /**
115      * Return the ResultColumn that is the source of this VirtualColumnNode.
116      *
117      * @return ResultSetNode
118      */

119     public ResultColumn getSourceColumn()
120     {
121         return sourceColumn;
122     }
123
124     /**
125      * Get the name of the table the ResultColumn is in, if any. This will be null
126      * if the user did not supply a name (for example, select a from t).
127      * The method will return B for this example, select b.a from t as b
128      * The method will return T for this example, select t.a from t
129      *
130      * @return A String containing the name of the table the Column
131      * is in. If the column is not in a table (i.e. is a
132      * derived column), it returns NULL.
133      */

134     public String JavaDoc getTableName()
135     {
136         return ( ( sourceColumn != null) ? sourceColumn.getTableName() : null );
137     }
138
139     /**
140      * Get the name of the schema the ResultColumn's table is in, if any.
141      * The return value will be null if the user did not supply a schema name
142      * (for example, select t.a from t).
143      * Another example for null return value (for example, select b.a from t as b).
144      * But for following query select app.t.a from t, this will return APP
145      *
146      * @return A String containing the name of the schema for the Column's table.
147      * If the column is not in a schema (i.e. derived column), it returns NULL.
148      */

149     public String JavaDoc getSchemaName() throws StandardException
150     {
151         return ( ( sourceColumn != null) ? sourceColumn.getSchemaName() : null );
152     }
153
154     /**
155      * Return whether or not the ResultColumn is wirtable by a positioned update.
156      *
157      * @return TRUE, if the column is a base column of a table and is
158      * writable by a positioned update.
159      */

160     public boolean updatableByCursor()
161     {
162         return ((sourceColumn != null) ? sourceColumn.updatableByCursor() : false);
163     }
164
165     /**
166      * Return the ResultColumn that is the source of this VirtualColumnNode.
167      *
168      * @return ResultSetNode
169      */

170     public ResultColumn getSourceResultColumn()
171     {
172         return sourceColumn;
173     }
174
175     /**
176      * Mark this VCN as a reference to a correlated column.
177      * (It's source resultSet is an outer ResultSet.
178      */

179     void setCorrelated()
180     {
181         correlated = true;
182     }
183
184     /**
185      * Return whether or not this VCN is a correlated reference.
186      *
187      * @return Whether or not this VCN is a correlated reference.
188      */

189     boolean getCorrelated()
190     {
191         return correlated;
192     }
193
194     /**
195      * Return whether or not this expression tree is cloneable.
196      *
197      * @return boolean Whether or not this expression tree is cloneable.
198      */

199     public boolean isCloneable()
200     {
201         return true;
202     }
203
204     /**
205      * ColumnNode's are against the current row in the system.
206      * This lets us generate
207      * a faster get that simply returns the column from the
208      * current row, rather than getting the value out and
209      * returning that, only to have the caller (in the situations
210      * needed) stuffing it back into a new column holder object.
211      * We will assume the general generate() path is for getting
212      * the value out, and use generateColumn() when we want to
213      * keep the column wrapped.
214      *
215      * @exception StandardException Thrown on error
216      */

217     public void generateExpression(ExpressionClassBuilder acb,
218                                             MethodBuilder mb)
219                                     throws StandardException
220     {
221         int sourceResultSetNumber = sourceColumn.getResultSetNumber();
222
223         /* If the source is marked as redundant, then continue down
224          * the RC/VirtualColumnNode chain.
225          */

226         if (sourceColumn.isRedundant())
227         {
228             sourceColumn.getExpression().generateExpression(acb, mb);
229             return;
230         }
231
232         if (SanityManager.DEBUG)
233         SanityManager.ASSERT(sourceResultSetNumber >= 0,
234             "sourceResultSetNumber expected to be >= 0 for virtual column "+sourceColumn.getName());
235
236         /* The ColumnReference is from an immediately underlying ResultSet.
237          * The Row for that ResultSet is Activation.row[sourceResultSetNumber],
238          * where sourceResultSetNumber is the resultSetNumber for that ResultSet.
239          *
240          * The generated java is the expression:
241          * (<Datatype interface>) this.row[sourceResultSetNumber].
242          * getColumn(#columnId);
243          * where <Datatype interface> is the appropriate interface for the
244          * column from the Datatype protocol.
245          */

246         acb.pushColumnReference(mb,
247                                     sourceResultSetNumber,
248                                     sourceColumn.getVirtualColumnId());
249
250         mb.cast(sourceColumn.getTypeCompiler().interfaceName());
251     }
252
253     /**
254      * Return the variant type for the underlying expression.
255      * The variant type can be:
256      * VARIANT - variant within a scan
257      * (method calls and non-static field access)
258      * SCAN_INVARIANT - invariant within a scan
259      * (column references from outer tables)
260      * QUERY_INVARIANT - invariant within the life of a query
261      * (constant expressions)
262      *
263      * @return The variant type for the underlying expression.
264      * @exception StandardException thrown on error
265      */

266     protected int getOrderableVariantType() throws StandardException
267     {
268         /*
269         ** Delegate to the source column
270         */

271         return sourceColumn.getOrderableVariantType();
272     }
273
274     /**
275      * Get the DataTypeServices from this Node.
276      *
277      * @return The DataTypeServices from this Node. This
278      * may be null if the node isn't bound yet.
279      */

280     public DataTypeDescriptor getTypeServices() throws StandardException
281     {
282         DataTypeDescriptor dtd = super.getTypeServices();
283         if( dtd == null && sourceColumn != null)
284         {
285             dtd = sourceColumn.getTypeServices();
286             if( dtd != null)
287                 setType( dtd);
288         }
289         return dtd;
290     } // end of getTypeServices
291

292     protected boolean isEquivalent(ValueNode o) throws StandardException
293     {
294         if (isSameNodeType(o)) {
295             VirtualColumnNode other = (VirtualColumnNode)o;
296             return sourceColumn.isEquivalent(other.sourceColumn);
297         }
298         return false;
299     }
300 }
301
Popular Tags