Source Code Cross Referenced for FromSubquery.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.FromSubquery
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.reference.SQLState;
025:
026:        import org.apache.derby.iapi.services.context.ContextManager;
027:
028:        import org.apache.derby.iapi.error.StandardException;
029:        import org.apache.derby.iapi.sql.compile.CompilerContext;
030:        import org.apache.derby.iapi.sql.compile.C_NodeTypes;
031:        import org.apache.derby.iapi.sql.dictionary.DataDictionary;
032:
033:        import org.apache.derby.iapi.services.sanity.SanityManager;
034:
035:        import org.apache.derby.iapi.util.JBitSet;
036:
037:        import java.util.Properties;
038:
039:        /**
040:         * A FromSubquery represents a subquery in the FROM list of a DML statement.
041:         *
042:         * The current implementation of this class is only
043:         * sufficient for Insert's need to push a new
044:         * select on top of the one the user specified,
045:         * to make the selected structure match that
046:         * of the insert target table.
047:         *
048:         * @author Jeff Lichtman
049:         */
050:        public class FromSubquery extends FromTable {
051:            boolean generatedForGroupByClause;
052:            boolean generatedForHavingClause;
053:            ResultSetNode subquery;
054:
055:            /**
056:             * Intializer for a table in a FROM list.
057:             *
058:             * @param subquery		The subquery
059:             * @param correlationName	The correlation name
060:             * @param derivedRCL		The derived column list
061:             * @param tableProperties	Properties list associated with the table
062:             */
063:            public void init(Object subquery, Object correlationName,
064:                    Object derivedRCL, Object tableProperties) {
065:                super .init(correlationName, tableProperties);
066:                this .subquery = (ResultSetNode) subquery;
067:                resultColumns = (ResultColumnList) derivedRCL;
068:            }
069:
070:            /**
071:             * Convert this object to a String.  See comments in QueryTreeNode.java
072:             * for how this should be done for tree printing.
073:             *
074:             * @return	This object as a String
075:             */
076:
077:            public String toString() {
078:                if (SanityManager.DEBUG) {
079:                    return "generatedForGroupByClause: "
080:                            + generatedForGroupByClause + "\n"
081:                            + "generatedForHavingClause: "
082:                            + generatedForHavingClause + "\n"
083:                            + super .toString();
084:                } else {
085:                    return "";
086:                }
087:            }
088:
089:            /**
090:             * Prints the sub-nodes of this object.  See QueryTreeNode.java for
091:             * how tree printing is supposed to work.
092:             *
093:             * @param depth		The depth of this node in the tree
094:             */
095:
096:            public void printSubNodes(int depth) {
097:                if (SanityManager.DEBUG) {
098:                    super .printSubNodes(depth);
099:
100:                    if (subquery != null) {
101:                        printLabel(depth, "subquery: ");
102:                        subquery.treePrint(depth + 1);
103:                    }
104:                }
105:            }
106:
107:            /** 
108:             * Return the "subquery" from this node.
109:             *
110:             * @return ResultSetNode	The "subquery" from this node.
111:             */
112:            public ResultSetNode getSubquery() {
113:                return subquery;
114:            }
115:
116:            /**
117:             * Mark this FromSubquery as being generated for a GROUP BY clause.
118:             * (This node represents the SELECT thru GROUP BY clauses.  We
119:             * appear in the FromList of a SelectNode generated to represent
120:             * the result of the GROUP BY.  This allows us to add ResultColumns
121:             * to the SelectNode for the user's query.
122:             */
123:            public void markAsForGroupByClause() {
124:                generatedForGroupByClause = true;
125:            }
126:
127:            /**
128:             * Mark this FromSubquery as being generated for a HAVING clause.
129:             * (This node represents the SELECT thru GROUP BY clauses.  We
130:             * appear in the FromList of a SelectNode generated to represent
131:             * the actual HAVING clause.
132:             */
133:            public void markAsForHavingClause() {
134:                generatedForHavingClause = true;
135:            }
136:
137:            /** 
138:             * Determine whether or not the specified name is an exposed name in
139:             * the current query block.
140:             *
141:             * @param name	The specified name to search for as an exposed name.
142:             * @param schemaName	Schema name, if non-null.
143:             * @param exactMatch	Whether or not we need an exact match on specified schema and table
144:             *						names or match on table id.
145:             *
146:             * @return The FromTable, if any, with the exposed name.
147:             *
148:             * @exception StandardException		Thrown on error
149:             */
150:            protected FromTable getFromTableByName(String name,
151:                    String schemaName, boolean exactMatch)
152:                    throws StandardException {
153:                if (generatedForGroupByClause || generatedForHavingClause) {
154:                    return subquery.getFromTableByName(name, schemaName,
155:                            exactMatch);
156:                } else {
157:                    return super .getFromTableByName(name, schemaName,
158:                            exactMatch);
159:                }
160:            }
161:
162:            /**
163:             * Bind this subquery that appears in the FROM list.
164:             *
165:             * @param dataDictionary	The DataDictionary to use for binding
166:             * @param fromListParam		FromList to use/append to.
167:             *
168:             * @return	ResultSetNode		The bound FromSubquery.
169:             *
170:             * @exception StandardException		Thrown on error
171:             */
172:
173:            public ResultSetNode bindNonVTITables(
174:                    DataDictionary dataDictionary, FromList fromListParam)
175:                    throws StandardException {
176:                /* Assign the tableNumber */
177:                if (tableNumber == -1) // allow re-bind, in which case use old number
178:                    tableNumber = getCompilerContext().getNextTableNumber();
179:
180:                subquery = subquery.bindNonVTITables(dataDictionary,
181:                        fromListParam);
182:
183:                return this ;
184:            }
185:
186:            /**
187:             * Bind this subquery that appears in the FROM list.
188:             *
189:             * @param fromListParam		FromList to use/append to.
190:             *
191:             * @return	ResultSetNode		The bound FromSubquery.
192:             *
193:             * @exception StandardException		Thrown on error
194:             */
195:
196:            public ResultSetNode bindVTITables(FromList fromListParam)
197:                    throws StandardException {
198:                subquery = subquery.bindVTITables(fromListParam);
199:
200:                return this ;
201:            }
202:
203:            /**
204:             * Check for (and reject) ? parameters directly under the ResultColumns.
205:             * This is done for SELECT statements.  For FromSubquery, we
206:             * simply pass the check through to the subquery.
207:             *
208:             * @exception StandardException		Thrown if a ? parameter found
209:             *									directly under a ResultColumn
210:             */
211:
212:            public void rejectParameters() throws StandardException {
213:                subquery.rejectParameters();
214:            }
215:
216:            /**
217:             * Bind the expressions in this FromSubquery.  This means 
218:             * binding the sub-expressions, as well as figuring out what the return 
219:             * type is for each expression.
220:             *
221:             * @exception StandardException		Thrown on error
222:             */
223:
224:            public void bindExpressions(FromList fromListParam)
225:                    throws StandardException {
226:                FromList emptyFromList = (FromList) getNodeFactory().getNode(
227:                        C_NodeTypes.FROM_LIST,
228:                        getNodeFactory().doJoinOrderOptimization(),
229:                        getContextManager());
230:                ResultColumnList derivedRCL = resultColumns;
231:                ResultColumnList subqueryRCL;
232:                FromList nestedFromList;
233:
234:                /* From subqueries cannot be correlated, so we pass an empty FromList
235:                 * to subquery.bindExpressions() and .bindResultColumns(). However,
236:                 * the parser rewrites queries which have GROUP BY and HAVING clauses.
237:                 * For these rewritten pseudo-subqueries, we need to pass in the outer FromList
238:                 * which contains correlated tables.
239:                 */
240:                if (generatedForGroupByClause || generatedForHavingClause) {
241:                    nestedFromList = fromListParam;
242:                } else {
243:                    nestedFromList = emptyFromList;
244:                }
245:
246:                subquery.bindExpressions(nestedFromList);
247:                subquery.bindResultColumns(nestedFromList);
248:
249:                /* Now that we've bound the expressions in the subquery, we 
250:                 * can propagate the subquery's RCL up to the FromSubquery.
251:                 * Get the subquery's RCL, assign shallow copy back to
252:                 * it and create new VirtualColumnNodes for the original's
253:                 * ResultColumn.expressions.
254:                 * NOTE: If the size of the derived column list is less than
255:                 * the size of the subquery's RCL and the derived column list is marked
256:                 * for allowing a size mismatch, then we have a select * view
257:                 * on top of a table that has had columns added to it via alter table.
258:                 * In this case, we trim out the columns that have been added to
259:                 * the table since the view was created.
260:                 */
261:                subqueryRCL = subquery.getResultColumns();
262:                if (resultColumns != null
263:                        && resultColumns.getCountMismatchAllowed()
264:                        && resultColumns.size() < subqueryRCL.size()) {
265:                    for (int index = subqueryRCL.size() - 1; index >= resultColumns
266:                            .size(); index--) {
267:                        subqueryRCL.removeElementAt(index);
268:                    }
269:                }
270:
271:                subquery.setResultColumns(subqueryRCL.copyListAndObjects());
272:                subqueryRCL.genVirtualColumnNodes(subquery, subquery
273:                        .getResultColumns());
274:                resultColumns = subqueryRCL;
275:
276:                /* Propagate the name info from the derived column list */
277:                if (derivedRCL != null) {
278:                    resultColumns.propagateDCLInfo(derivedRCL, correlationName);
279:                }
280:            }
281:
282:            /**
283:             * Try to find a ResultColumn in the table represented by this FromBaseTable
284:             * that matches the name in the given ColumnReference.
285:             *
286:             * @param columnReference	The columnReference whose name we're looking
287:             *				for in the given table.
288:             *
289:             * @return	A ResultColumn whose expression is the ColumnNode
290:             *			that matches the ColumnReference.
291:             *		Returns null if there is no match.
292:             *
293:             * @exception StandardException		Thrown on error
294:             */
295:
296:            public ResultColumn getMatchingColumn(
297:                    ColumnReference columnReference) throws StandardException {
298:                ResultColumn resultColumn = null;
299:                String columnsTableName;
300:
301:                /*
302:                 ** RESOLVE: When we add support for schemas, check to see if
303:                 ** the column name specifies a schema, and if so, if this
304:                 ** table is in that schema.
305:                 */
306:
307:                columnsTableName = columnReference.getTableName();
308:
309:                /* We have 5 cases here:
310:                 *  1.  ColumnReference was generated to replace an aggregate.
311:                 *		(We are the wrapper for a HAVING clause and the ColumnReference
312:                 *		was generated to reference the aggregate which was pushed down into
313:                 *		the SELECT list in the user's query.)  
314:                 *		Just do what you would expect.  Try to resolve the
315:                 *		ColumnReference against our RCL if the ColumnReference is unqualified
316:                 *		or if it is qualified with our exposed name.
317:                 *	2.	We are the wrapper for a GROUP BY and a HAVING clause and
318:                 *		either the ColumnReference is qualified or it is in
319:                 *		the HAVING clause.  For example:
320:                 *			select a from t1 group by a having t1.a = 1
321:                 *			select a as asdf from t1 group by a having a = 1
322:                 *		We need to match against the underlying FromList and then find
323:                 *		the grandparent ResultColumn in our RCL so that we return a
324:                 *		ResultColumn from the correct ResultSetNode.  It is okay not to
325:                 *		find a matching grandparent node.  In fact, this is how we ensure
326:                 *		the correct semantics for ColumnReferences in the HAVING clause
327:                 *		(which must be bound against the GROUP BY list.)
328:                 *  3.	We are the wrapper for a HAVING clause without a GROUP BY and
329:                 *		the ColumnReference is from the HAVING clause.  ColumnReferences
330:                 *		are invalid in this case, so we return null.
331:                 *  4.  We are the wrapper for a GROUP BY with no HAVING.  This has
332:                 *		to be a separate case because of #5 and the following query:
333:                 *			select * from (select c1 from t1) t, (select c1 from t1) tt
334:                 *			group by t1.c1, tt.c1
335:                 *		(The correlation names are lost in the generated FromSuquery.)
336:                 *  5.  Everything else - do what you would expect.  Try to resolve the
337:                 *		ColumnReference against our RCL if the ColumnReference is unqualified
338:                 *		or if it is qualified with our exposed name.
339:                 */
340:                if (columnReference.getGeneratedToReplaceAggregate()) // 1
341:                {
342:                    resultColumn = resultColumns
343:                            .getResultColumn(columnReference.getColumnName());
344:                } else if (generatedForGroupByClause
345:                        && generatedForHavingClause
346:                        && (columnsTableName != null || columnReference
347:                                .getClause() != ValueNode.IN_SELECT_LIST)) // 2
348:                {
349:                    if (SanityManager.DEBUG) {
350:                        SanityManager.ASSERT(correlationName == null,
351:                                "correlationName expected to be null");
352:                        SanityManager.ASSERT(subquery instanceof  SelectNode,
353:                                "subquery expected to be instanceof SelectNode, not "
354:                                        + subquery.getClass().getName());
355:                    }
356:
357:                    SelectNode select = (SelectNode) subquery;
358:
359:                    resultColumn = select.getFromList().bindColumnReference(
360:                            columnReference);
361:
362:                    /* Find and return the matching RC from our RCL.
363:                     * (Not an error if no match found.  Let ColumnReference deal with it.
364:                     */
365:                    if (resultColumn != null) {
366:                        /* Is there a matching resultColumn in the subquery's RCL? */
367:                        resultColumn = subquery.getResultColumns()
368:                                .findParentResultColumn(resultColumn);
369:                        if (resultColumn != null) {
370:                            /* Is there a matching resultColumn in our RCL? */
371:                            resultColumn = resultColumns
372:                                    .findParentResultColumn(resultColumn);
373:                        }
374:                    }
375:                } else if ((generatedForHavingClause && !generatedForGroupByClause) // 3
376:                        && (columnReference.getClause() != ValueNode.IN_SELECT_LIST)) {
377:                    resultColumn = null;
378:                } else if (generatedForGroupByClause) // 4
379:                {
380:                    resultColumn = resultColumns.getResultColumn(
381:                            columnsTableName, columnReference.getColumnName());
382:                } else if (columnsTableName == null
383:                        || columnsTableName.equals(correlationName)) // 5?
384:                {
385:                    resultColumn = resultColumns.getAtMostOneResultColumn(
386:                            columnReference, correlationName);
387:                }
388:
389:                if (resultColumn != null) {
390:                    columnReference.setTableNumber(tableNumber);
391:                }
392:
393:                return resultColumn;
394:            }
395:
396:            /**
397:             * Preprocess a ResultSetNode - this currently means:
398:             *	o  Generating a referenced table map for each ResultSetNode.
399:             *  o  Putting the WHERE and HAVING clauses in conjunctive normal form (CNF).
400:             *  o  Converting the WHERE and HAVING clauses into PredicateLists and
401:             *	   classifying them.
402:             *  o  Ensuring that a ProjectRestrictNode is generated on top of every 
403:             *     FromBaseTable and generated in place of every FromSubquery.  
404:             *  o  Pushing single table predicates down to the new ProjectRestrictNodes.
405:             *
406:             * @param numTables			The number of tables in the DML Statement
407:             * @param gbl				The group by list, if any
408:             * @param fromList			The from list, if any
409:             *
410:             * @return ResultSetNode at top of preprocessed tree.
411:             *
412:             * @exception StandardException		Thrown on error
413:             */
414:
415:            public ResultSetNode preprocess(int numTables, GroupByList gbl,
416:                    FromList fromList) throws StandardException {
417:                /* We want to chop out the FromSubquery from the tree and replace it 
418:                 * with a ProjectRestrictNode.  One complication is that there may be 
419:                 * ColumnReferences above us which point to the FromSubquery's RCL.
420:                 * What we want to return is a tree with a PRN with the
421:                 * FromSubquery's RCL on top.  (In addition, we don't want to be
422:                 * introducing any redundant ProjectRestrictNodes.)
423:                 * Another complication is that we want to be able to only only push
424:                 * projections and restrictions down to this ProjectRestrict, but
425:                 * we want to be able to push them through as well.
426:                 * So, we:
427:                 *		o call subquery.preprocess() which returns a tree with
428:                 *		  a SelectNode or a RowResultSetNode on top.  
429:                 *		o If the FSqry is flattenable(), then we return (so that the
430:                 *		  caller can then call flatten()), otherwise we:
431:                 *		o generate a PRN, whose RCL is the FSqry's RCL, on top of the result.
432:                 *		o create a referencedTableMap for the PRN which represents 
433:                 *		  the FSqry's tableNumber, since ColumnReferences in the outer
434:                 *		  query block would be referring to that one.  
435:                 *		  (This will allow us to push restrictions down to the PRN.)
436:                 */
437:
438:                subquery = subquery.preprocess(numTables, gbl, fromList);
439:
440:                /* Return if the FSqry is flattenable() 
441:                 * NOTE: We can't flatten a FromSubquery if there is a group by list
442:                 * because the group by list must be ColumnReferences.  For:
443:                 *	select c1 from v1 group by c1,
444:                 *	where v1 is select 1 from t1
445:                 * The expression under the last redundant ResultColumn is an IntConstantNode,
446:                 * not a ColumnReference.
447:                 * We also do not flatten a subquery if tableProperties is non-null,
448:                 * as the user is specifying 1 or more properties for the derived table,
449:                 * which could potentially be lost on the flattening.
450:                 * RESOLVE - this is too restrictive.
451:                 */
452:                if ((gbl == null || gbl.size() == 0) && tableProperties == null
453:                        && subquery.flattenableInFromSubquery(fromList)) {
454:                    /* Set our table map to the subquery's table map. */
455:                    setReferencedTableMap(subquery.getReferencedTableMap());
456:                    return this ;
457:                }
458:
459:                return extractSubquery(numTables);
460:            }
461:
462:            /**
463:             * Extract out and return the subquery, with a PRN on top.
464:             * (See FromSubquery.preprocess() for more details.)
465:             *
466:             * @param numTables			The number of tables in the DML Statement
467:             *
468:             * @return ResultSetNode at top of extracted tree.
469:             *
470:             * @exception StandardException		Thrown on error
471:             */
472:
473:            public ResultSetNode extractSubquery(int numTables)
474:                    throws StandardException {
475:                JBitSet newJBS;
476:                ResultSetNode newPRN;
477:
478:                newPRN = (ResultSetNode) getNodeFactory().getNode(
479:                        C_NodeTypes.PROJECT_RESTRICT_NODE, subquery, /* Child ResultSet */
480:                        resultColumns, /* Projection */
481:                        null, /* Restriction */
482:                        null, /* Restriction as PredicateList */
483:                        null, /* Subquerys in Projection */
484:                        null, /* Subquerys in Restriction */
485:                        tableProperties, getContextManager());
486:
487:                /* Set up the PRN's referencedTableMap */
488:                newJBS = new JBitSet(numTables);
489:                newJBS.set(tableNumber);
490:                newPRN.setReferencedTableMap(newJBS);
491:                ((FromTable) newPRN).setTableNumber(tableNumber);
492:
493:                return newPRN;
494:            }
495:
496:            /**
497:             * Flatten this FSqry into the outer query block. The steps in
498:             * flattening are:
499:             *	o  Mark all ResultColumns as redundant, so that they are "skipped over"
500:             *	   at generate().
501:             *	o  Append the wherePredicates to the outer list.
502:             *	o  Return the fromList so that the caller will merge the 2 lists 
503:             *  RESOLVE - FSqrys with subqueries are currently not flattenable.  Some of
504:             *  them can be flattened, however.  We need to merge the subquery list when
505:             *  we relax this restriction.
506:             *
507:             * NOTE: This method returns NULL when flattening RowResultSetNodes
508:             * (the node for a VALUES clause).  The reason is that no reference
509:             * is left to the RowResultSetNode after flattening is done - the
510:             * expressions point directly to the ValueNodes in the RowResultSetNode's
511:             * ResultColumnList.
512:             *
513:             * @param rcl				The RCL from the outer query
514:             * @param outerPList	PredicateList to append wherePredicates to.
515:             * @param sql				The SubqueryList from the outer query
516:             * @param gbl				The group by list, if any
517:             *
518:             * @return FromList		The fromList from the underlying SelectNode.
519:             *
520:             * @exception StandardException		Thrown on error
521:             */
522:            public FromList flatten(ResultColumnList rcl,
523:                    PredicateList outerPList, SubqueryList sql, GroupByList gbl)
524:
525:            throws StandardException {
526:                FromList fromList = null;
527:                SelectNode selectNode;
528:
529:                resultColumns.setRedundant();
530:
531:                subquery.getResultColumns().setRedundant();
532:
533:                /*
534:                 ** RESOLVE: Each type of result set should know how to remap itself.
535:                 */
536:                if (subquery instanceof  SelectNode) {
537:                    selectNode = (SelectNode) subquery;
538:                    fromList = selectNode.getFromList();
539:
540:                    // selectNode.getResultColumns().setRedundant();
541:
542:                    if (selectNode.getWherePredicates().size() > 0) {
543:                        outerPList.destructiveAppend(selectNode
544:                                .getWherePredicates());
545:                    }
546:
547:                    if (selectNode.getWhereSubquerys().size() > 0) {
548:                        sql.destructiveAppend(selectNode.getWhereSubquerys());
549:                    }
550:                } else if (!(subquery instanceof  RowResultSetNode)) {
551:                    if (SanityManager.DEBUG) {
552:                        SanityManager
553:                                .THROWASSERT("subquery expected to be either a SelectNode or a RowResultSetNode, but is a "
554:                                        + subquery.getClass().getName());
555:                    }
556:                }
557:
558:                /* Remap all ColumnReferences from the outer query to this node.
559:                 * (We replace those ColumnReferences with clones of the matching
560:                 * expression in the SELECT's RCL.
561:                 */
562:                rcl.remapColumnReferencesToExpressions();
563:                outerPList.remapColumnReferencesToExpressions();
564:                if (gbl != null) {
565:                    gbl.remapColumnReferencesToExpressions();
566:                }
567:
568:                return fromList;
569:            }
570:
571:            /**
572:             * Get the exposed name for this table, which is the name that can
573:             * be used to refer to it in the rest of the query.
574:             *
575:             * @return	The exposed name for this table.
576:             */
577:
578:            public String getExposedName() {
579:                return correlationName;
580:            }
581:
582:            /**
583:             * Expand a "*" into a ResultColumnList with all of the
584:             * result columns from the subquery.
585:             * @exception StandardException		Thrown on error
586:             */
587:            public ResultColumnList getAllResultColumns(TableName allTableName)
588:                    throws StandardException {
589:                ResultColumnList rcList = null;
590:                TableName exposedName;
591:                TableName toCompare;
592:
593:                if (allTableName != null)
594:                    toCompare = makeTableName(allTableName.getSchemaName(),
595:                            correlationName);
596:                else
597:                    toCompare = makeTableName(null, correlationName);
598:
599:                if (allTableName != null && !allTableName.equals(toCompare)) {
600:                    return null;
601:                }
602:
603:                /* Cache exposed name for this table.
604:                 * The exposed name becomes the qualifier for each column
605:                 * in the expanded list.
606:                 */
607:                exposedName = makeTableName(null, correlationName);
608:
609:                rcList = (ResultColumnList) getNodeFactory().getNode(
610:                        C_NodeTypes.RESULT_COLUMN_LIST, getContextManager());
611:
612:                /* Build a new result column list based off of resultColumns.
613:                 * NOTE: This method will capture any column renaming due to 
614:                 * a derived column list.
615:                 */
616:                int rclSize = resultColumns.size();
617:                for (int index = 0; index < rclSize; index++) {
618:                    ResultColumn resultColumn = (ResultColumn) resultColumns
619:                            .elementAt(index);
620:                    ValueNode valueNode;
621:                    String columnName;
622:
623:                    if (resultColumn.isGenerated()) {
624:                        continue;
625:                    }
626:
627:                    // Build a ResultColumn/ColumnReference pair for the column //
628:                    columnName = resultColumn.getName();
629:                    boolean isNameGenerated = resultColumn.isNameGenerated();
630:
631:                    /* If this node was generated for a GROUP BY, then tablename for the CR, if any,
632:                     * comes from the source RC.
633:                     */
634:                    TableName tableName;
635:
636:                    if (correlationName == null && generatedForGroupByClause) {
637:                        tableName = makeTableName(null, resultColumn
638:                                .getTableName());
639:                    } else {
640:                        tableName = exposedName;
641:                    }
642:                    valueNode = (ValueNode) getNodeFactory().getNode(
643:                            C_NodeTypes.COLUMN_REFERENCE, columnName,
644:                            tableName, getContextManager());
645:                    resultColumn = (ResultColumn) getNodeFactory().getNode(
646:                            C_NodeTypes.RESULT_COLUMN, columnName, valueNode,
647:                            getContextManager());
648:
649:                    resultColumn.setNameGenerated(isNameGenerated);
650:                    // Build the ResultColumnList to return //
651:                    rcList.addResultColumn(resultColumn);
652:                }
653:                return rcList;
654:            }
655:
656:            /** 
657:             * @see QueryTreeNode#disablePrivilegeCollection
658:             */
659:            public void disablePrivilegeCollection() {
660:                super .disablePrivilegeCollection();
661:                subquery.disablePrivilegeCollection();
662:            }
663:
664:            /**
665:             * Search to see if a query references the specifed table name.
666:             *
667:             * @param name		Table name (String) to search for.
668:             * @param baseTable	Whether or not name is for a base table
669:             *
670:             * @return	true if found, else false
671:             *
672:             * @exception StandardException		Thrown on error
673:             */
674:            public boolean referencesTarget(String name, boolean baseTable)
675:                    throws StandardException {
676:                return subquery.referencesTarget(name, baseTable);
677:            }
678:
679:            /**
680:             * Return true if the node references SESSION schema tables (temporary or permanent)
681:             *
682:             * @return	true if references SESSION schema tables, else false
683:             *
684:             * @exception StandardException		Thrown on error
685:             */
686:            public boolean referencesSessionSchema() throws StandardException {
687:                return subquery.referencesSessionSchema();
688:            }
689:
690:            /**
691:             * Bind any untyped null nodes to the types in the given ResultColumnList.
692:             *
693:             * @param bindingRCL	The ResultColumnList with the types to bind to.
694:             *
695:             * @exception StandardException		Thrown on error
696:             */
697:            public void bindUntypedNullsToResultColumns(
698:                    ResultColumnList bindingRCL) throws StandardException {
699:                subquery.bindUntypedNullsToResultColumns(bindingRCL);
700:            }
701:
702:            /**
703:             * Decrement (query block) level (0-based) for this FromTable.
704:             * This is useful when flattening a subquery.
705:             *
706:             * @param decrement	The amount to decrement by.
707:             */
708:            void decrementLevel(int decrement) {
709:                super.decrementLevel(decrement);
710:                subquery.decrementLevel(decrement);
711:            }
712:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.