Source Code Cross Referenced for TableOperatorNode.java in  » Database-DBMS » db-derby-10.2 » org » apache » derby » impl » sql » compile » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Database DBMS » db derby 10.2 » org.apache.derby.impl.sql.compile 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:
003:           Derby - Class org.apache.derby.impl.sql.compile.TableOperatorNode
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.services.context.ContextManager;
025:
026:        import org.apache.derby.iapi.services.sanity.SanityManager;
027:
028:        import org.apache.derby.iapi.error.StandardException;
029:
030:        import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
031:        import org.apache.derby.iapi.sql.compile.CompilerContext;
032:        import org.apache.derby.iapi.sql.compile.Optimizable;
033:        import org.apache.derby.iapi.sql.compile.Visitable;
034:        import org.apache.derby.iapi.sql.compile.Visitor;
035:        import org.apache.derby.iapi.sql.compile.Optimizer;
036:        import org.apache.derby.iapi.sql.compile.OptimizableList;
037:        import org.apache.derby.iapi.sql.compile.CostEstimate;
038:        import org.apache.derby.iapi.sql.compile.OptimizerFactory;
039:        import org.apache.derby.iapi.sql.compile.RequiredRowOrdering;
040:        import org.apache.derby.iapi.sql.compile.C_NodeTypes;
041:
042:        import org.apache.derby.iapi.sql.dictionary.DataDictionary;
043:        import org.apache.derby.iapi.sql.dictionary.TableDescriptor;
044:
045:        import org.apache.derby.iapi.util.JBitSet;
046:
047:        import java.util.Properties;
048:
049:        /**
050:         * A TableOperatorNode represents a relational operator like UNION, INTERSECT,
051:         * JOIN, etc. that takes two tables as parameters and returns a table.  The
052:         * parameters it takes are represented as ResultSetNodes.
053:         *
054:         * Currently, all known table operators are binary operators, so there are no
055:         * subclasses of this node type called "BinaryTableOperatorNode" and
056:         * "UnaryTableOperatorNode".
057:         *
058:         * @author Jeff Lichtman
059:         */
060:
061:        abstract class TableOperatorNode extends FromTable {
062:            ResultSetNode leftResultSet;
063:            ResultSetNode rightResultSet;
064:            Optimizer leftOptimizer;
065:            Optimizer rightOptimizer;
066:            private boolean leftModifyAccessPathsDone;
067:            private boolean rightModifyAccessPathsDone;
068:
069:            /**
070:             * Initializer for a TableOperatorNode.
071:             *
072:             * @param leftResultSet		The ResultSetNode on the left side of this node
073:             * @param rightResultSet	The ResultSetNode on the right side of this node
074:             * @param tableProperties	Properties list associated with the table
075:             *
076:             * @exception StandardException		Thrown on error
077:             */
078:            public void init(Object leftResultSet, Object rightResultSet,
079:                    Object tableProperties) throws StandardException {
080:                /* correlationName is always null */
081:                init(null, tableProperties);
082:                this .leftResultSet = (ResultSetNode) leftResultSet;
083:                this .rightResultSet = (ResultSetNode) rightResultSet;
084:            }
085:
086:            /**
087:             * @see Optimizable#modifyAccessPath
088:             *
089:             * @exception StandardException		Thrown on error
090:             */
091:            public Optimizable modifyAccessPath(JBitSet outerTables)
092:                    throws StandardException {
093:                boolean callModifyAccessPaths = false;
094:
095:                if (leftResultSet instanceof  FromTable) {
096:                    if (leftOptimizer != null)
097:                        leftOptimizer.modifyAccessPaths();
098:                    else {
099:                        leftResultSet = (ResultSetNode) ((FromTable) leftResultSet)
100:                                .modifyAccessPath(outerTables);
101:                    }
102:                    leftModifyAccessPathsDone = true;
103:                } else {
104:                    callModifyAccessPaths = true;
105:                }
106:
107:                if (rightResultSet instanceof  FromTable) {
108:                    if (rightOptimizer != null)
109:                        rightOptimizer.modifyAccessPaths();
110:                    else {
111:                        rightResultSet = (ResultSetNode) ((FromTable) rightResultSet)
112:                                .modifyAccessPath(outerTables);
113:                    }
114:                    rightModifyAccessPathsDone = true;
115:                } else {
116:                    callModifyAccessPaths = true;
117:                }
118:
119:                if (callModifyAccessPaths) {
120:                    return (Optimizable) modifyAccessPaths();
121:                }
122:                return this ;
123:            }
124:
125:            /** @see Optimizable#verifyProperties 
126:             * @exception StandardException		Thrown on error
127:             */
128:            public void verifyProperties(DataDictionary dDictionary)
129:                    throws StandardException {
130:                if (leftResultSet instanceof  Optimizable) {
131:                    ((Optimizable) leftResultSet).verifyProperties(dDictionary);
132:                }
133:                if (rightResultSet instanceof  Optimizable) {
134:                    ((Optimizable) rightResultSet)
135:                            .verifyProperties(dDictionary);
136:                }
137:
138:                super .verifyProperties(dDictionary);
139:            }
140:
141:            /**
142:             * @see Optimizable#updateBestPlanMap
143:             *
144:             * Makes a call to add/load/remove the plan mapping for this node,
145:             * and then makes the necessary call to recurse on this node's
146:             * left and right child, in order to ensure that we've handled
147:             * the full plan all the way down this node's subtree. 
148:             */
149:            public void updateBestPlanMap(short action, Object planKey)
150:                    throws StandardException {
151:                super .updateBestPlanMap(action, planKey);
152:
153:                // Now walk the children.  Note that if either child is not
154:                // an Optimizable and the call to child.getOptimizerImpl()
155:                // returns null, then that means we haven't tried to optimize
156:                // the child yet.  So in that case there's nothing to
157:                // add/load.
158:
159:                if (leftResultSet instanceof  Optimizable) {
160:                    ((Optimizable) leftResultSet).updateBestPlanMap(action,
161:                            planKey);
162:                } else if (leftResultSet.getOptimizerImpl() != null) {
163:                    leftResultSet.getOptimizerImpl().updateBestPlanMaps(action,
164:                            planKey);
165:                }
166:
167:                if (rightResultSet instanceof  Optimizable) {
168:                    ((Optimizable) rightResultSet).updateBestPlanMap(action,
169:                            planKey);
170:                } else if (rightResultSet.getOptimizerImpl() != null) {
171:                    rightResultSet.getOptimizerImpl().updateBestPlanMaps(
172:                            action, planKey);
173:                }
174:            }
175:
176:            /**
177:             * Convert this object to a String.  See comments in QueryTreeNode.java
178:             * for how this should be done for tree printing.
179:             *
180:             * @return	This object as a String
181:             */
182:
183:            public String toString() {
184:                if (SanityManager.DEBUG) {
185:                    return "nestedInParens: " + false + "\n"
186:                            + leftResultSet.toString() + "\n"
187:                            + rightResultSet.toString() + "\n"
188:                            + super .toString();
189:                } else {
190:                    return "";
191:                }
192:            }
193:
194:            /**
195:             * Prints the sub-nodes of this object.  See QueryTreeNode.java for
196:             * how tree printing is supposed to work.
197:             *
198:             * @param depth		The depth of this node in the tree
199:             */
200:
201:            public void printSubNodes(int depth) {
202:                if (SanityManager.DEBUG) {
203:                    super .printSubNodes(depth);
204:
205:                    if (leftResultSet != null) {
206:                        printLabel(depth, "leftResultSet: ");
207:                        leftResultSet.printSubNodes(depth + 1);
208:                    }
209:
210:                    if (rightResultSet != null) {
211:                        printLabel(depth, "rightResultSet: ");
212:                        rightResultSet.printSubNodes(depth + 1);
213:                    }
214:                }
215:            }
216:
217:            /**
218:             * Get the leftResultSet from this node.
219:             *
220:             * @return ResultSetNode	The leftResultSet from this node.
221:             */
222:            public ResultSetNode getLeftResultSet() {
223:                return leftResultSet;
224:            }
225:
226:            /**
227:             * Get the rightResultSet from this node.
228:             *
229:             * @return ResultSetNode	The rightResultSet from this node.
230:             */
231:            public ResultSetNode getRightResultSet() {
232:                return rightResultSet;
233:            }
234:
235:            public ResultSetNode getLeftmostResultSet() {
236:                if (leftResultSet instanceof  TableOperatorNode) {
237:                    return ((TableOperatorNode) leftResultSet)
238:                            .getLeftmostResultSet();
239:                } else {
240:                    return leftResultSet;
241:                }
242:            }
243:
244:            public void setLeftmostResultSet(ResultSetNode newLeftResultSet) {
245:                if (leftResultSet instanceof  TableOperatorNode) {
246:                    ((TableOperatorNode) leftResultSet)
247:                            .setLeftmostResultSet(newLeftResultSet);
248:                } else {
249:                    this .leftResultSet = newLeftResultSet;
250:                }
251:            }
252:
253:            /**
254:             * Set the (query block) level (0-based) for this FromTable.
255:             *
256:             * @param level		The query block level for this FromTable.
257:             */
258:            public void setLevel(int level) {
259:                super .setLevel(level);
260:                if (leftResultSet instanceof  FromTable) {
261:                    ((FromTable) leftResultSet).setLevel(level);
262:                }
263:                if (rightResultSet instanceof  FromTable) {
264:                    ((FromTable) rightResultSet).setLevel(level);
265:                }
266:            }
267:
268:            /**
269:             * Return the exposed name for this table, which is the name that
270:             * can be used to refer to this table in the rest of the query.
271:             *
272:             * @return	The exposed name for this table.
273:             */
274:
275:            public String getExposedName() {
276:                return null;
277:            }
278:
279:            /**
280:             * Mark whether or not this node is nested in parens.  (Useful to parser
281:             * since some trees get created left deep and others right deep.)
282:             * The resulting state of this cal was never used so its
283:             * field was removed to save runtimespace for this node.
284:             * Further cleanup can be done including parser changes
285:             * if this call is really nor required.
286:             *
287:             * @param nestedInParens	Whether or not this node is nested in parens.
288:             */
289:            public void setNestedInParens(boolean nestedInParens) {
290:            }
291:
292:            /**
293:             * Bind the non VTI tables in this TableOperatorNode. This means getting
294:             * their TableDescriptors from the DataDictionary.
295:             * We will build an unbound RCL for this node.  This RCL must be
296:             * "bound by hand" after the underlying left and right RCLs
297:             * are bound.
298:             *
299:             * @param dataDictionary	The DataDictionary to use for binding
300:             * @param fromListParam		FromList to use/append to.
301:             *
302:             * @return	ResultSetNode		Returns this.
303:             *
304:             * @exception StandardException		Thrown on error
305:             */
306:
307:            public ResultSetNode bindNonVTITables(
308:                    DataDictionary dataDictionary, FromList fromListParam)
309:                    throws StandardException {
310:                leftResultSet = leftResultSet.bindNonVTITables(dataDictionary,
311:                        fromListParam);
312:                rightResultSet = rightResultSet.bindNonVTITables(
313:                        dataDictionary, fromListParam);
314:                /* Assign the tableNumber */
315:                if (tableNumber == -1) // allow re-bind, in which case use old number
316:                    tableNumber = getCompilerContext().getNextTableNumber();
317:
318:                return this ;
319:            }
320:
321:            /**
322:             * Bind the VTI tables in this TableOperatorNode. This means getting
323:             * their TableDescriptors from the DataDictionary.
324:             * We will build an unbound RCL for this node.  This RCL must be
325:             * "bound by hand" after the underlying left and right RCLs
326:             * are bound.
327:             *
328:             * @param fromListParam		FromList to use/append to.
329:             *
330:             * @return	ResultSetNode		Returns this.
331:             *
332:             * @exception StandardException		Thrown on error
333:             */
334:
335:            public ResultSetNode bindVTITables(FromList fromListParam)
336:                    throws StandardException {
337:                leftResultSet = leftResultSet.bindVTITables(fromListParam);
338:                rightResultSet = rightResultSet.bindVTITables(fromListParam);
339:
340:                return this ;
341:            }
342:
343:            /**
344:             * Bind the expressions under this TableOperatorNode.  This means
345:             * binding the sub-expressions, as well as figuring out what the
346:             * return type is for each expression.
347:             *
348:             * @exception StandardException		Thrown on error
349:             */
350:
351:            public void bindExpressions(FromList fromListParam)
352:                    throws StandardException {
353:                /*
354:                 ** Parameters not allowed in select list of either side of union,
355:                 ** except when the union is for a table constructor.
356:                 */
357:                if (!(this  instanceof  UnionNode)
358:                        || !((UnionNode) this ).tableConstructor()) {
359:                    leftResultSet.rejectParameters();
360:                    rightResultSet.rejectParameters();
361:                }
362:
363:                leftResultSet.bindExpressions(fromListParam);
364:                rightResultSet.bindExpressions(fromListParam);
365:            }
366:
367:            /**
368:             * Check for (and reject) ? parameters directly under the ResultColumns.
369:             * This is done for SELECT statements.  For TableOperatorNodes, we
370:             * simply pass the check through to the left and right children.
371:             *
372:             * @exception StandardException		Thrown if a ? parameter found
373:             *									directly under a ResultColumn
374:             */
375:
376:            public void rejectParameters() throws StandardException {
377:                leftResultSet.rejectParameters();
378:                rightResultSet.rejectParameters();
379:            }
380:
381:            /**
382:             * Bind the expressions in this ResultSetNode if it has tables.  This means binding the
383:             * sub-expressions, as well as figuring out what the return type is for
384:             * each expression.
385:             *
386:             * @param fromListParam		FromList to use/append to.
387:             *
388:             * @exception StandardException		Thrown on error
389:             */
390:            public void bindExpressionsWithTables(FromList fromListParam)
391:                    throws StandardException {
392:                /*
393:                 ** Parameters not allowed in select list of either side of a set operator,
394:                 ** except when the set operator is for a table constructor.
395:                 */
396:                if (!(this  instanceof  UnionNode)
397:                        || !((UnionNode) this ).tableConstructor()) {
398:                    leftResultSet.rejectParameters();
399:                    rightResultSet.rejectParameters();
400:                }
401:
402:                leftResultSet.bindExpressionsWithTables(fromListParam);
403:                rightResultSet.bindExpressionsWithTables(fromListParam);
404:            }
405:
406:            /**
407:             * Bind the result columns of this ResultSetNode when there is no
408:             * base table to bind them to.  This is useful for SELECT statements,
409:             * where the result columns get their types from the expressions that
410:             * live under them.
411:             *
412:             * @param fromListParam		FromList to use/append to.
413:             *
414:             * @exception StandardException		Thrown on error
415:             */
416:            public void bindResultColumns(FromList fromListParam)
417:                    throws StandardException {
418:                leftResultSet.bindResultColumns(fromListParam);
419:                rightResultSet.bindResultColumns(fromListParam);
420:            }
421:
422:            /**
423:             * Bind the result columns for this ResultSetNode to a base table.
424:             * This is useful for INSERT and UPDATE statements, where the
425:             * result columns get their types from the table being updated or
426:             * inserted into.
427:             * If a result column list is specified, then the verification that the 
428:             * result column list does not contain any duplicates will be done when
429:             * binding them by name.
430:             *
431:             * @param targetTableDescriptor	The TableDescriptor for the table being
432:             *				updated or inserted into
433:             * @param targetColumnList	For INSERT statements, the user
434:             *					does not have to supply column
435:             *					names (for example, "insert into t
436:             *					values (1,2,3)".  When this
437:             *					parameter is null, it means that
438:             *					the user did not supply column
439:             *					names, and so the binding should
440:             *					be done based on order.  When it
441:             *					is not null, it means do the binding
442:             *					by name, not position.
443:             * @param statement			Calling DMLStatementNode (Insert or Update)
444:             * @param fromListParam		FromList to use/append to.
445:             *
446:             * @exception StandardException		Thrown on error
447:             */
448:
449:            public void bindResultColumns(
450:                    TableDescriptor targetTableDescriptor, FromVTI targetVTI,
451:                    ResultColumnList targetColumnList,
452:                    DMLStatementNode statement, FromList fromListParam)
453:                    throws StandardException {
454:                leftResultSet.bindResultColumns(targetTableDescriptor,
455:                        targetVTI, targetColumnList, statement, fromListParam);
456:                rightResultSet.bindResultColumns(targetTableDescriptor,
457:                        targetVTI, targetColumnList, statement, fromListParam);
458:            }
459:
460:            /** 
461:             * Determine whether or not the specified name is an exposed name in
462:             * the current query block.
463:             *
464:             * @param name	The specified name to search for as an exposed name.
465:             * @param schemaName	Schema name, if non-null.
466:             * @param exactMatch	Whether or not we need an exact match on specified schema and table
467:             *						names or match on table id.
468:             *
469:             * @return The FromTable, if any, with the exposed name.
470:             *
471:             * @exception StandardException		Thrown on error
472:             */
473:            protected FromTable getFromTableByName(String name,
474:                    String schemaName, boolean exactMatch)
475:                    throws StandardException {
476:                FromTable result = leftResultSet.getFromTableByName(name,
477:                        schemaName, exactMatch);
478:
479:                /* We search both sides for a TableOperatorNode (join nodes)
480:                 * but only the left side for a UnionNode.
481:                 */
482:                if (result == null) {
483:                    result = rightResultSet.getFromTableByName(name,
484:                            schemaName, exactMatch);
485:                }
486:                return result;
487:            }
488:
489:            /** 
490:             * Put a ProjectRestrictNode on top of each FromTable in the FromList.
491:             * ColumnReferences must continue to point to the same ResultColumn, so
492:             * that ResultColumn must percolate up to the new PRN.  However,
493:             * that ResultColumn will point to a new expression, a VirtualColumnNode, 
494:             * which points to the FromTable and the ResultColumn that is the source for
495:             * the ColumnReference.  
496:             * (The new PRN will have the original of the ResultColumnList and
497:             * the ResultColumns from that list.  The FromTable will get shallow copies
498:             * of the ResultColumnList and its ResultColumns.  ResultColumn.expression
499:             * will remain at the FromTable, with the PRN getting a new 
500:             * VirtualColumnNode for each ResultColumn.expression.)
501:             * We then project out the non-referenced columns.  If there are no referenced
502:             * columns, then the PRN's ResultColumnList will consist of a single ResultColumn
503:             * whose expression is 1.
504:             *
505:             * @param numTables			Number of tables in the DML Statement
506:             * @param gbl				The group by list, if any
507:             * @param fromList			The from list, if any
508:             *
509:             * @return The generated ProjectRestrictNode atop the original FromTable.
510:             *
511:             * @exception StandardException		Thrown on error
512:             */
513:
514:            public ResultSetNode preprocess(int numTables, GroupByList gbl,
515:                    FromList fromList) throws StandardException {
516:                leftResultSet = leftResultSet.preprocess(numTables, gbl,
517:                        fromList);
518:                /* If leftResultSet is a FromSubquery, then we must explicitly extract
519:                 * out the subquery (flatten it).  (SelectNodes have their own
520:                 * method of flattening them.
521:                 */
522:                if (leftResultSet instanceof  FromSubquery) {
523:                    leftResultSet = ((FromSubquery) leftResultSet)
524:                            .extractSubquery(numTables);
525:                }
526:                rightResultSet = rightResultSet.preprocess(numTables, gbl,
527:                        fromList);
528:                /* If rightResultSet is a FromSubquery, then we must explicitly extract
529:                 * out the subquery (flatten it).  (SelectNodes have their own
530:                 * method of flattening them.
531:                 */
532:                if (rightResultSet instanceof  FromSubquery) {
533:                    rightResultSet = ((FromSubquery) rightResultSet)
534:                            .extractSubquery(numTables);
535:                }
536:
537:                /* Build the referenced table map (left || right) */
538:                referencedTableMap = (JBitSet) leftResultSet
539:                        .getReferencedTableMap().clone();
540:                referencedTableMap.or((JBitSet) rightResultSet
541:                        .getReferencedTableMap());
542:                referencedTableMap.set(tableNumber);
543:
544:                /* Only generate a PRN if this node is not a flattenable join node. */
545:                if (isFlattenableJoinNode()) {
546:                    return this ;
547:                } else {
548:                    /* Project out any unreferenced RCs before we generate the PRN.
549:                     * NOTE: We have to do this at the end of preprocess since it has to 
550:                     * be from the bottom up.  We can't do it until the join expression is 
551:                     * bound, since the join expression may contain column references that
552:                     * are not referenced anywhere else above us.
553:                     */
554:                    projectResultColumns();
555:                    return genProjectRestrict(numTables);
556:                }
557:            }
558:
559:            /**
560:             * Find the unreferenced result columns and project them out. This is used in pre-processing joins
561:             * that are not flattened into the where clause.
562:             */
563:            void projectResultColumns() throws StandardException {
564:                resultColumns.doProjection();
565:            }
566:
567:            /**
568:             * Set the referenced columns in the column list if it may not be correct.
569:             */
570:            void setReferencedColumns() {
571:            }
572:
573:            /**
574:             * Optimize a TableOperatorNode. 
575:             *
576:             * @param dataDictionary	The DataDictionary to use for optimization
577:             * @param predicateList		The PredicateList to apply.
578:             *
579:             * @return	ResultSetNode	The top of the optimized query tree
580:             *
581:             * @exception StandardException		Thrown on error
582:             */
583:            public ResultSetNode optimize(DataDictionary dataDictionary,
584:                    PredicateList predicateList, double outerRows)
585:                    throws StandardException {
586:                /* Get an optimizer, so we can get a cost structure */
587:                Optimizer optimizer = getOptimizer((FromList) getNodeFactory()
588:                        .getNode(C_NodeTypes.FROM_LIST,
589:                                getNodeFactory().doJoinOrderOptimization(),
590:                                this , getContextManager()), predicateList,
591:                        dataDictionary, (RequiredRowOrdering) null);
592:
593:                costEstimate = optimizer.newCostEstimate();
594:
595:                /* RESOLVE: This is just a stub for now */
596:                leftResultSet = leftResultSet.optimize(dataDictionary,
597:                        predicateList, outerRows);
598:                rightResultSet = rightResultSet.optimize(dataDictionary,
599:                        predicateList, outerRows);
600:
601:                /* The cost is the sum of the two child costs */
602:                costEstimate
603:                        .setCost(leftResultSet.getCostEstimate()
604:                                .getEstimatedCost(), leftResultSet
605:                                .getCostEstimate().rowCount(), leftResultSet
606:                                .getCostEstimate().singleScanRowCount()
607:                                + rightResultSet.getCostEstimate()
608:                                        .singleScanRowCount());
609:
610:                costEstimate.add(rightResultSet.costEstimate, costEstimate);
611:
612:                return this ;
613:            }
614:
615:            /**
616:             * @see ResultSetNode#modifyAccessPaths
617:             *
618:             * @exception StandardException		Thrown on error
619:             */
620:            public ResultSetNode modifyAccessPaths() throws StandardException {
621:                /* Beetle 4454 - union all with another union all would modify access
622:                 * paths twice causing NullPointerException, make sure we don't
623:                 * do this again, if we have already done it in modifyAccessPaths(outertables)
624:                 */
625:                if (!leftModifyAccessPathsDone) {
626:                    if (leftOptimizer != null)
627:                        leftOptimizer.modifyAccessPaths();
628:                    else {
629:                        // If this is a SetOperatorNode then we may have pushed
630:                        // predicates down to the children.  If that's the case
631:                        // then we need to pass those predicates down as part
632:                        // of the modifyAccessPaths call so that they can be
633:                        // pushed one last time, in prep for generation.
634:                        if (this  instanceof  SetOperatorNode) {
635:                            SetOperatorNode setOp = (SetOperatorNode) this ;
636:                            leftResultSet = leftResultSet
637:                                    .modifyAccessPaths(setOp
638:                                            .getLeftOptPredicateList());
639:                        } else
640:                            leftResultSet = leftResultSet.modifyAccessPaths();
641:                    }
642:                }
643:                if (!rightModifyAccessPathsDone) {
644:                    if (rightOptimizer != null)
645:                        rightOptimizer.modifyAccessPaths();
646:                    else {
647:                        if (this  instanceof  SetOperatorNode) {
648:                            SetOperatorNode setOp = (SetOperatorNode) this ;
649:                            rightResultSet = rightResultSet
650:                                    .modifyAccessPaths(setOp
651:                                            .getRightOptPredicateList());
652:                        } else
653:                            rightResultSet = rightResultSet.modifyAccessPaths();
654:                    }
655:                }
656:                return this ;
657:            }
658:
659:            /**
660:             * Search to see if a query references the specifed table name.
661:             *
662:             * @param name		Table name (String) to search for.
663:             * @param baseTable	Whether or not name is for a base table
664:             *
665:             * @return	true if found, else false
666:             *
667:             * @exception StandardException		Thrown on error
668:             */
669:            public boolean referencesTarget(String name, boolean baseTable)
670:                    throws StandardException {
671:                return leftResultSet.referencesTarget(name, baseTable)
672:                        || rightResultSet.referencesTarget(name, baseTable);
673:            }
674:
675:            /**
676:             * Return true if the node references SESSION schema tables (temporary or permanent)
677:             *
678:             * @return	true if references SESSION schema tables, else false
679:             *
680:             * @exception StandardException		Thrown on error
681:             */
682:            public boolean referencesSessionSchema() throws StandardException {
683:                return leftResultSet.referencesSessionSchema()
684:                        || rightResultSet.referencesSessionSchema();
685:            }
686:
687:            /** 
688:             * Optimize a source result set to this table operator.
689:             *
690:             * @exception StandardException		Thrown on error
691:             */
692:            protected ResultSetNode optimizeSource(Optimizer optimizer,
693:                    ResultSetNode sourceResultSet, PredicateList predList,
694:                    CostEstimate outerCost) throws StandardException {
695:                ResultSetNode retval;
696:
697:                if (sourceResultSet instanceof  FromTable) {
698:                    FromList optList = (FromList) getNodeFactory().getNode(
699:                            C_NodeTypes.FROM_LIST,
700:                            getNodeFactory().doJoinOrderOptimization(),
701:                            sourceResultSet, getContextManager());
702:
703:                    /* If there is no predicate list, create an empty one */
704:                    if (predList == null)
705:                        predList = (PredicateList) getNodeFactory()
706:                                .getNode(C_NodeTypes.PREDICATE_LIST,
707:                                        getContextManager());
708:
709:                    LanguageConnectionContext lcc = getLanguageConnectionContext();
710:                    OptimizerFactory optimizerFactory = lcc
711:                            .getOptimizerFactory();
712:                    optimizer = optimizerFactory.getOptimizer(optList,
713:                            predList, getDataDictionary(),
714:                            (RequiredRowOrdering) null, getCompilerContext()
715:                                    .getNumTables(), lcc);
716:                    optimizer.prepForNextRound();
717:
718:                    if (sourceResultSet == leftResultSet) {
719:                        leftOptimizer = optimizer;
720:                    } else if (sourceResultSet == rightResultSet) {
721:                        rightOptimizer = optimizer;
722:                    } else {
723:                        if (SanityManager.DEBUG)
724:                            SanityManager
725:                                    .THROWASSERT("Result set being optimized is neither left nor right");
726:                    }
727:
728:                    /*
729:                     ** Set the estimated number of outer rows from the outer part of
730:                     ** the plan.
731:                     */
732:                    optimizer.setOuterRows(outerCost.rowCount());
733:
734:                    /* Optimize the underlying result set */
735:                    while (optimizer.getNextPermutation()) {
736:                        while (optimizer.getNextDecoratedPermutation()) {
737:                            optimizer.costPermutation();
738:                        }
739:                    }
740:
741:                    retval = sourceResultSet;
742:                } else {
743:                    retval = sourceResultSet.optimize(optimizer
744:                            .getDataDictionary(), predList, outerCost
745:                            .rowCount());
746:                }
747:
748:                return retval;
749:            }
750:
751:            /**
752:             * Decrement (query block) level (0-based) for 
753:             * all of the tables in this ResultSet tree.
754:             * This is useful when flattening a subquery.
755:             *
756:             * @param decrement	The amount to decrement by.
757:             */
758:            void decrementLevel(int decrement) {
759:                leftResultSet.decrementLevel(decrement);
760:                rightResultSet.decrementLevel(decrement);
761:            }
762:
763:            /**
764:             * Replace any DEFAULTs with the associated tree for the default.
765:             *
766:             * @param ttd	The TableDescriptor for the target table.
767:             * @param tcl	The RCL for the target table.
768:             *
769:             * @exception StandardException		Thrown on error
770:             */
771:            void replaceDefaults(TableDescriptor ttd, ResultColumnList tcl)
772:                    throws StandardException {
773:                leftResultSet.replaceDefaults(ttd, tcl);
774:                rightResultSet.replaceDefaults(ttd, tcl);
775:            }
776:
777:            /**
778:             * Notify the underlying result set tree that the result is
779:             * ordering dependent.  (For example, no bulk fetch on an index
780:             * if under an IndexRowToBaseRow.)
781:             */
782:            void markOrderingDependent() {
783:                leftResultSet.markOrderingDependent();
784:                rightResultSet.markOrderingDependent();
785:            }
786:
787:            /**
788:             * Accept a visitor, and call v.visit()
789:             * on child nodes as necessary.  
790:             * 
791:             * @param v the visitor
792:             *
793:             * @exception StandardException on error
794:             */
795:            public Visitable accept(Visitor v) throws StandardException {
796:                if (v.skipChildren(this )) {
797:                    return v.visit(this );
798:                }
799:
800:                Visitable returnNode = super .accept(v);
801:
802:                if (leftResultSet != null && !v.stopTraversal()) {
803:                    leftResultSet = (ResultSetNode) leftResultSet.accept(v);
804:                }
805:                if (rightResultSet != null && !v.stopTraversal()) {
806:                    rightResultSet = (ResultSetNode) rightResultSet.accept(v);
807:                }
808:                return returnNode;
809:            }
810:
811:            /** 
812:             * apparently something special needs to be done for me....
813:             */
814:            public boolean needsSpecialRCLBinding() {
815:                return true;
816:            }
817:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.