KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2
3    Derby - Class org.apache.derby.impl.sql.compile.IndexToBaseRowNode
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.context.ContextManager;
25
26 import org.apache.derby.iapi.sql.compile.AccessPath;
27 import org.apache.derby.iapi.sql.compile.CostEstimate;
28 import org.apache.derby.iapi.sql.compile.Optimizable;
29
30 import org.apache.derby.iapi.sql.dictionary.ConglomerateDescriptor;
31
32 import org.apache.derby.impl.sql.compile.ActivationClassBuilder;
33
34 import org.apache.derby.iapi.error.StandardException;
35
36 import org.apache.derby.iapi.services.compiler.MethodBuilder;
37
38 import org.apache.derby.iapi.sql.execute.NoPutResultSet;
39
40 import org.apache.derby.iapi.sql.Activation;
41 import org.apache.derby.iapi.sql.ResultSet;
42
43 import org.apache.derby.iapi.services.loader.GeneratedMethod;
44
45 import org.apache.derby.iapi.store.access.StaticCompiledOpenConglomInfo;
46
47 import org.apache.derby.iapi.services.io.FormatableBitSet;
48
49 import org.apache.derby.catalog.types.ReferencedColumnsDescriptorImpl;
50 import org.apache.derby.iapi.reference.ClassName;
51 import org.apache.derby.iapi.services.classfile.VMOpcode;
52
53 import java.util.Properties JavaDoc;
54 import java.util.Vector JavaDoc;
55
56 /**
57  * This node type translates an index row to a base row. It takes a
58  * FromBaseTable as its source ResultSetNode, and generates an
59  * IndexRowToBaseRowResultSet that takes a TableScanResultSet on an
60  * index conglomerate as its source.
61  */

62 public class IndexToBaseRowNode extends FromTable
63 {
64     protected FromBaseTable source;
65     protected ConglomerateDescriptor baseCD;
66     protected boolean cursorTargetTable;
67     protected PredicateList restrictionList;
68     protected boolean forUpdate;
69     private FormatableBitSet heapReferencedCols;
70     private FormatableBitSet indexReferencedCols;
71
72     public void init(
73             Object JavaDoc source,
74             Object JavaDoc baseCD,
75             Object JavaDoc resultColumns,
76             Object JavaDoc cursorTargetTable,
77             Object JavaDoc heapReferencedCols,
78             Object JavaDoc indexReferencedCols,
79             Object JavaDoc restrictionList,
80             Object JavaDoc forUpdate,
81             Object JavaDoc tableProperties)
82     {
83         super.init(null, tableProperties);
84         this.source = (FromBaseTable) source;
85         this.baseCD = (ConglomerateDescriptor) baseCD;
86         this.resultColumns = (ResultColumnList) resultColumns;
87         this.cursorTargetTable = ((Boolean JavaDoc) cursorTargetTable).booleanValue();
88         this.restrictionList = (PredicateList) restrictionList;
89         this.forUpdate = ((Boolean JavaDoc) forUpdate).booleanValue();
90         this.heapReferencedCols = (FormatableBitSet) heapReferencedCols;
91         this.indexReferencedCols = (FormatableBitSet) indexReferencedCols;
92     }
93
94     /** @see Optimizable#forUpdate */
95     public boolean forUpdate()
96     {
97         return source.forUpdate();
98     }
99
100     /** @see Optimizable#getTrulyTheBestAccessPath */
101     public AccessPath getTrulyTheBestAccessPath()
102     {
103         // Get AccessPath comes from base table.
104
return ((Optimizable) source).getTrulyTheBestAccessPath();
105     }
106
107     public CostEstimate getCostEstimate()
108     {
109         return source.getTrulyTheBestAccessPath().getCostEstimate();
110     }
111
112     public CostEstimate getFinalCostEstimate()
113     {
114         return source.getFinalCostEstimate();
115     }
116
117     /**
118      * Return whether or not the underlying ResultSet tree
119      * is ordered on the specified columns.
120      * RESOLVE - This method currently only considers the outermost table
121      * of the query block.
122      *
123      * @param crs The specified ColumnReference[]
124      * @param permuteOrdering Whether or not the order of the CRs in the array can be permuted
125      * @param fbtVector Vector that is to be filled with the FromBaseTable
126      *
127      * @return Whether the underlying ResultSet tree
128      * is ordered on the specified column.
129      *
130      * @exception StandardException Thrown on error
131      */

132     boolean isOrderedOn(ColumnReference[] crs, boolean permuteOrdering, Vector JavaDoc fbtVector)
133                 throws StandardException
134     {
135         return source.isOrderedOn(crs, permuteOrdering, fbtVector);
136     }
137
138     /**
139      * Generation of an IndexToBaseRowNode creates an
140      * IndexRowToBaseRowResultSet, which uses the RowLocation in the last
141      * column of an index row to get the row from the base conglomerate (heap).
142      *
143      * @param acb The ActivationClassBuilder for the class being built
144      * @param mb the method for the method to be built
145      *
146      * @exception StandardException Thrown on error
147      */

148     public void generate(ActivationClassBuilder acb,
149                                 MethodBuilder mb)
150                             throws StandardException
151     {
152         ValueNode restriction = null;
153
154         /*
155         ** Get the next ResultSet #, so that we can number this ResultSetNode,
156         ** its ResultColumnList and ResultSet.
157         */

158         assignResultSetNumber();
159
160         // Get the CostEstimate info for the underlying scan
161
costEstimate = getFinalCostEstimate();
162
163         /* Put the predicates back into the tree */
164         if (restrictionList != null)
165         {
166             restriction = restrictionList.restorePredicates();
167             /* Allow the restrictionList to get garbage collected now
168              * that we're done with it.
169              */

170             restrictionList = null;
171         }
172
173         // for the restriction, we generate an exprFun
174
// that evaluates the expression of the clause
175
// against the current row of the child's result.
176
// if the restriction is empty, simply pass null
177
// to optimize for run time performance.
178

179         // generate the function and initializer:
180
// Note: Boolean lets us return nulls (boolean would not)
181
// private Boolean exprN()
182
// {
183
// return <<restriction.generate(ps)>>;
184
// }
185
// static Method exprN = method pointer to exprN;
186

187
188
189         int heapColRefItem = -1;
190         int indexColRefItem = -1;
191         if (heapReferencedCols != null)
192         {
193             heapColRefItem = acb.addItem(heapReferencedCols);
194         }
195         if (indexReferencedCols != null)
196         {
197             indexColRefItem = acb.addItem(indexReferencedCols);
198         }
199
200         /* Create the ReferencedColumnsDescriptorImpl which tells which columns
201          * come from the index.
202          */

203         int indexColMapItem = acb.addItem(new ReferencedColumnsDescriptorImpl(getIndexColMapping()));
204         long heapConglomNumber = baseCD.getConglomerateNumber();
205         StaticCompiledOpenConglomInfo scoci = getLanguageConnectionContext().
206                                                 getTransactionCompile().
207                                                     getStaticCompiledConglomInfo(heapConglomNumber);
208
209         acb.pushGetResultSetFactoryExpression(mb);
210
211         mb.push(heapConglomNumber);
212         mb.push(acb.addItem(scoci));
213         source.generate(acb, mb);
214         
215         mb.upCast(ClassName.NoPutResultSet);
216
217         resultColumns.generateHolder(acb, mb, heapReferencedCols, indexReferencedCols);
218         mb.push(resultSetNumber);
219         mb.push(source.getBaseTableName());
220         mb.push(heapColRefItem);
221         mb.push(indexColRefItem);
222         mb.push(indexColMapItem);
223
224         // if there is no restriction, we just want to pass null.
225
if (restriction == null)
226         {
227             mb.pushNull(ClassName.GeneratedMethod);
228         }
229         else
230         {
231             // this sets up the method and the static field.
232
// generates:
233
// Object userExprFun { }
234
MethodBuilder userExprFun = acb.newUserExprFun();
235
236             // restriction knows it is returning its value;
237

238             /* generates:
239              * return <restriction.generate(acb)>;
240              * and adds it to userExprFun
241              * NOTE: The explicit cast to DataValueDescriptor is required
242              * since the restriction may simply be a boolean column or subquery
243              * which returns a boolean. For example:
244              * where booleanColumn
245              */

246             restriction.generate(acb, userExprFun);
247             userExprFun.methodReturn();
248
249             // we are done modifying userExprFun, complete it.
250
userExprFun.complete();
251
252             // restriction is used in the final result set as an access of the new static
253
// field holding a reference to this new method.
254
// generates:
255
// ActivationClass.userExprFun
256
// which is the static field that "points" to the userExprFun
257
// that evaluates the where clause.
258
acb.pushMethodReference(mb, userExprFun);
259         }
260
261         mb.push(forUpdate);
262         mb.push(costEstimate.rowCount());
263         mb.push(costEstimate.getEstimatedCost());
264
265         mb.callMethod(VMOpcode.INVOKEINTERFACE, (String JavaDoc) null, "getIndexRowToBaseRowResultSet",
266                         ClassName.NoPutResultSet, 13);
267
268         /* The IndexRowToBaseRowResultSet generator is what we return */
269
270         /*
271         ** Remember if this result set is the cursor target table, so we
272         ** can know which table to use when doing positioned update and delete.
273         */

274         if (cursorTargetTable)
275         {
276             acb.rememberCursorTarget(mb);
277         }
278     }
279
280     /**
281      * Return whether or not the underlying ResultSet tree will return
282      * a single row, at most.
283      * This is important for join nodes where we can save the extra next
284      * on the right side if we know that it will return at most 1 row.
285      *
286      * @return Whether or not the underlying ResultSet tree will return a single row.
287      * @exception StandardException Thrown on error
288      */

289     public boolean isOneRowResultSet() throws StandardException
290     {
291         // Default is false
292
return source.isOneRowResultSet();
293     }
294
295     /**
296      * Return whether or not the underlying FBT is for NOT EXISTS.
297      *
298      * @return Whether or not the underlying FBT is for NOT EXISTS.
299      */

300     public boolean isNotExists()
301     {
302         return source.isNotExists();
303     }
304
305     /**
306      * Decrement (query block) level (0-based) for this FromTable.
307      * This is useful when flattening a subquery.
308      *
309      * @param decrement The amount to decrement by.
310      */

311     void decrementLevel(int decrement)
312     {
313         source.decrementLevel(decrement);
314     }
315
316     /**
317      * Get the lock mode for the target of an update statement
318      * (a delete or update). The update mode will always be row for
319      * CurrentOfNodes. It will be table if there is no where clause.
320      *
321      * @return The lock mode
322      */

323     public int updateTargetLockMode()
324     {
325         return source.updateTargetLockMode();
326     }
327
328     /**
329      * Notify the underlying result set tree that the result is
330      * ordering dependent. (For example, no bulk fetch on an index
331      * if under an IndexRowToBaseRow.)
332      */

333     void markOrderingDependent()
334     {
335         /* NOTE: We use a different method to tell a FBT that
336          * it cannot do a bulk fetch as the ordering issues are
337          * specific to a FBT being under an IRTBR as opposed to a
338          * FBT being under a PRN, etc.
339          */

340         source.disableBulkFetch();
341     }
342
343     /**
344      * Fill in the column mapping for those columns coming from the index.
345      *
346      * @return The int[] with the mapping.
347      */

348     private int[] getIndexColMapping()
349     {
350         int rclSize = resultColumns.size();
351         int[] indexColMapping = new int[rclSize];
352
353         for (int index = 0; index < rclSize; index++)
354         {
355             ResultColumn rc = (ResultColumn) resultColumns.elementAt(index);
356             if (indexReferencedCols != null && rc.getExpression() instanceof VirtualColumnNode)
357             {
358                 // Column is coming from index
359
VirtualColumnNode vcn = (VirtualColumnNode) rc.getExpression();
360                 indexColMapping[index] =
361                     vcn.getSourceColumn().getVirtualColumnId() - 1;
362             }
363             else
364             {
365                 // Column is not coming from index
366
indexColMapping[index] = -1;
367             }
368         }
369
370         return indexColMapping;
371     }
372
373 }
374
Popular Tags