Source Code Cross Referenced for ResultSetNode.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) 


0001:        /*
0002:
0003:           Derby - Class org.apache.derby.impl.sql.compile.ResultSetNode
0004:
0005:           Licensed to the Apache Software Foundation (ASF) under one or more
0006:           contributor license agreements.  See the NOTICE file distributed with
0007:           this work for additional information regarding copyright ownership.
0008:           The ASF licenses this file to you under the Apache License, Version 2.0
0009:           (the "License"); you may not use this file except in compliance with
0010:           the License.  You may obtain a copy of the License at
0011:
0012:              http://www.apache.org/licenses/LICENSE-2.0
0013:
0014:           Unless required by applicable law or agreed to in writing, software
0015:           distributed under the License is distributed on an "AS IS" BASIS,
0016:           WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0017:           See the License for the specific language governing permissions and
0018:           limitations under the License.
0019:
0020:         */
0021:
0022:        package org.apache.derby.impl.sql.compile;
0023:
0024:        import org.apache.derby.iapi.services.context.ContextManager;
0025:
0026:        import org.apache.derby.iapi.error.StandardException;
0027:        import org.apache.derby.iapi.sql.compile.CompilerContext;
0028:        import org.apache.derby.iapi.sql.compile.CostEstimate;
0029:        import org.apache.derby.iapi.sql.compile.OptimizerFactory;
0030:        import org.apache.derby.iapi.sql.compile.Optimizer;
0031:        import org.apache.derby.iapi.sql.compile.OptimizableList;
0032:        import org.apache.derby.iapi.sql.compile.OptimizablePredicateList;
0033:        import org.apache.derby.iapi.sql.compile.Parser;
0034:        import org.apache.derby.iapi.sql.compile.Visitable;
0035:        import org.apache.derby.iapi.sql.compile.Visitor;
0036:        import org.apache.derby.iapi.sql.compile.RequiredRowOrdering;
0037:        import org.apache.derby.iapi.sql.compile.RowOrdering;
0038:        import org.apache.derby.iapi.sql.compile.C_NodeTypes;
0039:
0040:        import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
0041:
0042:        import org.apache.derby.iapi.sql.dictionary.ColumnDescriptor;
0043:        import org.apache.derby.iapi.sql.dictionary.DataDictionary;
0044:        import org.apache.derby.iapi.sql.dictionary.DefaultDescriptor;
0045:        import org.apache.derby.iapi.sql.dictionary.TableDescriptor;
0046:
0047:        import org.apache.derby.iapi.sql.execute.ExecutionContext;
0048:
0049:        import org.apache.derby.iapi.sql.Activation;
0050:        import org.apache.derby.iapi.types.DataTypeDescriptor;
0051:        import org.apache.derby.iapi.sql.ResultColumnDescriptor;
0052:        import org.apache.derby.iapi.sql.ResultDescription;
0053:        import org.apache.derby.iapi.sql.ResultSet;
0054:
0055:        import org.apache.derby.iapi.types.TypeId;
0056:
0057:        import org.apache.derby.iapi.store.access.TransactionController;
0058:
0059:        import org.apache.derby.iapi.services.loader.GeneratedMethod;
0060:
0061:        import org.apache.derby.iapi.services.sanity.SanityManager;
0062:        import org.apache.derby.iapi.reference.ClassName;
0063:
0064:        import org.apache.derby.iapi.services.compiler.MethodBuilder;
0065:
0066:        import org.apache.derby.impl.sql.compile.ActivationClassBuilder;
0067:        import org.apache.derby.impl.sql.compile.ExpressionClassBuilder;
0068:
0069:        import org.apache.derby.iapi.util.JBitSet;
0070:        import org.apache.derby.iapi.services.classfile.VMOpcode;
0071:
0072:        import org.apache.derby.catalog.types.DefaultInfoImpl;
0073:
0074:        import java.util.Properties;
0075:        import java.util.Vector;
0076:        import java.util.Set;
0077:
0078:        /**
0079:         * A ResultSetNode represents a result set, that is, a set of rows.  It is
0080:         * analogous to a ResultSet in the LanguageModuleExternalInterface.  In fact,
0081:         * code generation for a a ResultSetNode will create a "new" call to a
0082:         * constructor for a ResultSet.
0083:         *
0084:         * @author Jeff Lichtman
0085:         */
0086:
0087:        public abstract class ResultSetNode extends QueryTreeNode {
0088:            int resultSetNumber;
0089:            /* Bit map of referenced tables under this ResultSetNode */
0090:            JBitSet referencedTableMap;
0091:            ResultColumnList resultColumns;
0092:            boolean statementResultSet;
0093:            boolean cursorTargetTable;
0094:            boolean insertSource;
0095:
0096:            CostEstimate costEstimate;
0097:            CostEstimate scratchCostEstimate;
0098:            Optimizer optimizer;
0099:
0100:            // Final cost estimate for this result set node, which is the estimate
0101:            // for this node with respect to the best join order for the top-level
0102:            // query. Subclasses will set this value where appropriate.
0103:            CostEstimate finalCostEstimate;
0104:
0105:            /**
0106:             * Convert this object to a String.  See comments in QueryTreeNode.java
0107:             * for how this should be done for tree printing.
0108:             *
0109:             * @return	This object as a String
0110:             */
0111:
0112:            public String toString() {
0113:                if (SanityManager.DEBUG) {
0114:                    return "resultSetNumber: "
0115:                            + resultSetNumber
0116:                            + "\n"
0117:                            + "referencedTableMap: "
0118:                            + (referencedTableMap != null ? referencedTableMap
0119:                                    .toString() : "null") + "\n"
0120:                            + "statementResultSet: " + statementResultSet
0121:                            + "\n" + super .toString();
0122:                } else {
0123:                    return "";
0124:                }
0125:            }
0126:
0127:            /**
0128:             * Prints the sub-nodes of this object.  See QueryTreeNode.java for
0129:             * how tree printing is supposed to work.
0130:             *
0131:             * @param depth		The depth of this node in the tree
0132:             */
0133:
0134:            public void printSubNodes(int depth) {
0135:                if (SanityManager.DEBUG) {
0136:                    super .printSubNodes(depth);
0137:
0138:                    if (resultColumns != null) {
0139:                        printLabel(depth, "resultColumns: ");
0140:                        resultColumns.treePrint(depth);
0141:                    }
0142:                }
0143:            }
0144:
0145:            /**
0146:             * Get the resultSetNumber in this ResultSetNode. Expected to be set during
0147:             * generate().
0148:             *
0149:             * @return int 	The resultSetNumber.
0150:             */
0151:
0152:            public int getResultSetNumber() {
0153:                return resultSetNumber;
0154:            }
0155:
0156:            /**
0157:             * Get the CostEstimate for this ResultSetNode.
0158:             *
0159:             * @return	The CostEstimate for this ResultSetNode.
0160:             */
0161:            public CostEstimate getCostEstimate() {
0162:                if (SanityManager.DEBUG) {
0163:                    if (costEstimate == null) {
0164:                        SanityManager
0165:                                .THROWASSERT("costEstimate is not expected to be null for "
0166:                                        + getClass().getName());
0167:                    }
0168:                }
0169:                return costEstimate;
0170:            }
0171:
0172:            /**
0173:             * Get the final CostEstimate for this ResultSetNode.
0174:             *
0175:             * @return	The final CostEstimate for this ResultSetNode.
0176:             */
0177:            public CostEstimate getFinalCostEstimate() throws StandardException {
0178:                if (SanityManager.DEBUG) {
0179:                    if (finalCostEstimate == null) {
0180:                        SanityManager
0181:                                .THROWASSERT("finalCostEstimate is not expected to be null for "
0182:                                        + getClass().getName());
0183:                    }
0184:                }
0185:                return finalCostEstimate;
0186:            }
0187:
0188:            /**
0189:             * Assign the next resultSetNumber to the resultSetNumber in this ResultSetNode. 
0190:             * Expected to be done during generate().
0191:             *
0192:             * @exception StandardException		Thrown on error
0193:             */
0194:
0195:            public void assignResultSetNumber() throws StandardException {
0196:                resultSetNumber = getCompilerContext().getNextResultSetNumber();
0197:                resultColumns.setResultSetNumber(resultSetNumber);
0198:            }
0199:
0200:            /**
0201:             * Bind the non VTI tables in this ResultSetNode.  This includes getting their
0202:             * descriptors from the data dictionary and numbering them.
0203:             *
0204:             * @param dataDictionary	The DataDictionary to use for binding
0205:             * @param fromListParam		FromList to use/append to.
0206:             *
0207:             * @return	ResultSetNode
0208:             *
0209:             * @exception StandardException		Thrown on error
0210:             */
0211:
0212:            public ResultSetNode bindNonVTITables(
0213:                    DataDictionary dataDictionary, FromList fromListParam)
0214:                    throws StandardException {
0215:                return this ;
0216:            }
0217:
0218:            /**
0219:             * Bind the VTI tables in this ResultSetNode.  This includes getting their
0220:             * descriptors from the data dictionary and numbering them.
0221:             *
0222:             * @param fromListParam		FromList to use/append to.
0223:             *
0224:             * @return	ResultSetNode
0225:             *
0226:             * @exception StandardException		Thrown on error
0227:             */
0228:
0229:            public ResultSetNode bindVTITables(FromList fromListParam)
0230:                    throws StandardException {
0231:                return this ;
0232:            }
0233:
0234:            /**
0235:             * Bind the expressions in this ResultSetNode.  This means binding the
0236:             * sub-expressions, as well as figuring out what the return type is for
0237:             * each expression.
0238:             *
0239:             * @param fromListParam		FromList to use/append to.
0240:             *
0241:             * @exception StandardException		Thrown on error
0242:             */
0243:            public void bindExpressions(FromList fromListParam)
0244:                    throws StandardException {
0245:                if (SanityManager.DEBUG)
0246:                    SanityManager.ASSERT(false,
0247:                            "bindExpressions() is not expected to be called for "
0248:                                    + this .getClass().toString());
0249:            }
0250:
0251:            /**
0252:             * Bind the expressions in this ResultSetNode if it has tables.  This means binding the
0253:             * sub-expressions, as well as figuring out what the return type is for
0254:             * each expression.
0255:             *
0256:             * @param fromListParam		FromList to use/append to.
0257:             *
0258:             * @exception StandardException		Thrown on error
0259:             */
0260:            public void bindExpressionsWithTables(FromList fromListParam)
0261:                    throws StandardException {
0262:                if (SanityManager.DEBUG)
0263:                    SanityManager.ASSERT(false,
0264:                            "bindExpressionsWithTables() is not expected to be called for "
0265:                                    + this .getClass().toString());
0266:            }
0267:
0268:            /**
0269:             * Bind the expressions in the target list.  This means binding the
0270:             * sub-expressions, as well as figuring out what the return type is
0271:             * for each expression.  This is useful for EXISTS subqueries, where we
0272:             * need to validate the target list before blowing it away and replacing
0273:             * it with a SELECT true.
0274:             *
0275:             * @exception StandardException		Thrown on error
0276:             */
0277:
0278:            public void bindTargetExpressions(FromList fromListParam)
0279:                    throws StandardException {
0280:                if (SanityManager.DEBUG)
0281:                    SanityManager.ASSERT(false,
0282:                            "bindTargetExpressions() is not expected to be called for "
0283:                                    + this .getClass().toString());
0284:            }
0285:
0286:            /**
0287:             * Set the type of each parameter in the result column list for this table constructor.
0288:             *
0289:             * @param typeColumns	The ResultColumnList containing the desired result
0290:             *						types.
0291:             *
0292:             * @exception StandardException		Thrown on error
0293:             */
0294:            void setTableConstructorTypes(ResultColumnList typeColumns)
0295:                    throws StandardException {
0296:                if (SanityManager.DEBUG)
0297:                    SanityManager
0298:                            .ASSERT(resultColumns.size() <= typeColumns.size(),
0299:                                    "More columns in ResultColumnList than in base table");
0300:
0301:                /* Look for ? parameters in the result column list */
0302:                int rclSize = resultColumns.size();
0303:                for (int index = 0; index < rclSize; index++) {
0304:                    ResultColumn rc = (ResultColumn) resultColumns
0305:                            .elementAt(index);
0306:
0307:                    ValueNode re = rc.getExpression();
0308:
0309:                    if (re.requiresTypeFromContext()) {
0310:                        ResultColumn typeCol = (ResultColumn) typeColumns
0311:                                .elementAt(index);
0312:
0313:                        /*
0314:                         ** We found a ? - set its type to the type of the
0315:                         ** corresponding column of the target table.
0316:                         */
0317:                        re.setType(typeCol.getTypeServices());
0318:                    } else if (re instanceof  CharConstantNode) {
0319:                        // Character constants are of type CHAR (fixed length string).
0320:                        // This causes a problem (beetle 5160) when multiple row values are provided
0321:                        // as constants for insertion into a variable length string column.
0322:                        //
0323:                        // This issue is the query expression
0324:                        // VALUES 'abc', 'defghi'
0325:                        // has type of CHAR(6), ie. the length of largest row value for that column.
0326:                        // This is from the UNION defined behaviour.
0327:                        // This causes strings with less than the maximum length to be blank padded
0328:                        // to that length (CHAR semantics). Thus if this VALUES clause is used to
0329:                        // insert into a variable length string column, then these blank padded values
0330:                        // are inserted, which is not what is required ...
0331:                        // 
0332:                        // BECAUSE, when the VALUES is used as a table constructor SQL standard says the
0333:                        // types of the table constructor's columns are set by the table's column types.
0334:                        // Thus, in this case, each of those string constants should be of type VARCHAR
0335:                        // (or the matching string type for the table).
0336:                        //
0337:                        //
0338:                        // This is only an issue for fixed length character (CHAR, BIT) string or
0339:                        // binary consraints being inserted into variable length types.
0340:                        // This is because any other type's fundemental literal value is not affected
0341:                        // by its data type. E.g. Numeric types such as INT, REAL, BIGINT, DECIMAL etc.
0342:                        // do not have their value modifed by the union since even if the type is promoted
0343:                        // to a higher type, its fundemental value remains unchanged. 
0344:                        // values (1.2, 34.4567, 234.47) will be promoted to
0345:                        // values (1.2000, 34.4567, 234.4700)
0346:                        // but their numeric value remains the same.
0347:                        //
0348:                        //
0349:                        //
0350:                        // The fix is to change the base type of the table constructor's value to
0351:                        // match the column type. Its length can be left as-is, because there is
0352:                        // still a normailzation step when the value is inserted into the table.
0353:                        // That will set the correct length and perform truncation checks etc.
0354:
0355:                        ResultColumn typeCol = (ResultColumn) typeColumns
0356:                                .elementAt(index);
0357:
0358:                        TypeId colTypeId = typeCol.getTypeId();
0359:
0360:                        if (colTypeId.isStringTypeId()) {
0361:
0362:                            if (colTypeId.getJDBCTypeId() != java.sql.Types.CHAR) {
0363:
0364:                                int maxWidth = re.getTypeServices()
0365:                                        .getMaximumWidth();
0366:
0367:                                re.setType(new DataTypeDescriptor(colTypeId,
0368:                                        true, maxWidth));
0369:                            }
0370:                        } else if (colTypeId.isBitTypeId()) {
0371:                            if (colTypeId.getJDBCTypeId() == java.sql.Types.VARBINARY) {
0372:                                // then we're trying to cast a char literal into a
0373:                                // variable bit column.  We can't change the base
0374:                                // type of the table constructor's value from char
0375:                                // to bit, so instead, we just change the base type
0376:                                // of that value from char to varchar--that way,
0377:                                // no padding will be added when we convert to
0378:                                // bits later on (Beetle 5306).
0379:                                TypeId tId = TypeId
0380:                                        .getBuiltInTypeId(java.sql.Types.VARCHAR);
0381:                                re.setType(new DataTypeDescriptor(tId, true));
0382:                                typeColumns.setElementAt(typeCol, index);
0383:                            } else if (colTypeId.getJDBCTypeId() == java.sql.Types.LONGVARBINARY) {
0384:                                TypeId tId = TypeId
0385:                                        .getBuiltInTypeId(java.sql.Types.LONGVARCHAR);
0386:                                re.setType(new DataTypeDescriptor(tId, true));
0387:                                typeColumns.setElementAt(typeCol, index);
0388:                            }
0389:                        }
0390:
0391:                    } else if (re instanceof  BitConstantNode) {
0392:                        ResultColumn typeCol = (ResultColumn) typeColumns
0393:                                .elementAt(index);
0394:
0395:                        TypeId colTypeId = typeCol.getTypeId();
0396:
0397:                        if (colTypeId.isBitTypeId()) {
0398:
0399:                            // NOTE: Don't bother doing this if the column type is BLOB,
0400:                            // as we don't allow bit literals to be inserted into BLOB
0401:                            // columns (they have to be explicitly casted first); beetle 5266.
0402:                            if ((colTypeId.getJDBCTypeId() != java.sql.Types.BINARY)
0403:                                    && (colTypeId.getJDBCTypeId() != java.sql.Types.BLOB)) {
0404:
0405:                                int maxWidth = re.getTypeServices()
0406:                                        .getMaximumWidth();
0407:
0408:                                re.setType(new DataTypeDescriptor(colTypeId,
0409:                                        true, maxWidth));
0410:                            }
0411:                        } else if (colTypeId.isStringTypeId()) {
0412:                            if (colTypeId.getJDBCTypeId() == java.sql.Types.VARCHAR) {
0413:                                // then we're trying to cast a bit literal into a
0414:                                // variable char column.  We can't change the base
0415:                                // type of the table constructor's value from bit
0416:                                // to char, so instead, we just change the base
0417:                                // type of that value from bit to varbit--that way,
0418:                                // no padding will be added when we convert to
0419:                                // char later on.
0420:                                TypeId tId = TypeId
0421:                                        .getBuiltInTypeId(java.sql.Types.VARBINARY);
0422:                                re.setType(new DataTypeDescriptor(tId, true));
0423:                                typeColumns.setElementAt(typeCol, index);
0424:                            } else if (colTypeId.getJDBCTypeId() == java.sql.Types.LONGVARCHAR) {
0425:                                TypeId tId = TypeId
0426:                                        .getBuiltInTypeId(java.sql.Types.LONGVARBINARY);
0427:                                re.setType(new DataTypeDescriptor(tId, true));
0428:                                typeColumns.setElementAt(typeCol, index);
0429:                            }
0430:                        }
0431:                    }
0432:                }
0433:            }
0434:
0435:            /**
0436:             * Remember that this node is the source result set for an INSERT.
0437:             */
0438:            public void setInsertSource() {
0439:                insertSource = true;
0440:            }
0441:
0442:            /**
0443:             * Verify that a SELECT * is valid for this type of subquery.
0444:             *
0445:             * @param outerFromList	The FromList from the outer query block(s)
0446:             * @param subqueryType	The subquery type
0447:             *
0448:             * @exception StandardException		Thrown on error
0449:             */
0450:            public void verifySelectStarSubquery(FromList outerFromList,
0451:                    int subqueryType) throws StandardException {
0452:                if (SanityManager.DEBUG)
0453:                    SanityManager.ASSERT(false,
0454:                            "verifySelectStarSubquery() is not expected to be called for "
0455:                                    + this .getClass().toString());
0456:            }
0457:
0458:            /**
0459:             * Expand "*" into a ResultColumnList with all of the columns
0460:             * in the table's result list.
0461:             *
0462:             * @param allTableName		The qualifier on the "*"
0463:             *
0464:             * @return ResultColumnList The expanded list
0465:             *
0466:             * @exception StandardException		Thrown on error
0467:             */
0468:            public ResultColumnList getAllResultColumns(TableName allTableName)
0469:                    throws StandardException {
0470:                if (SanityManager.DEBUG)
0471:                    SanityManager
0472:                            .THROWASSERT("getAllResultColumns() not expected to be called for "
0473:                                    + this .getClass().getName() + this );
0474:                return null;
0475:            }
0476:
0477:            /**
0478:             * Try to find a ResultColumn in the table represented by this FromTable
0479:             * that matches the name in the given ColumnReference.
0480:             *
0481:             * @param columnReference	The columnReference whose name we're looking
0482:             *				for in the given table.
0483:             *
0484:             * @return	A ResultColumn whose expression is the ColumnNode
0485:             *			that matches the ColumnReference.
0486:             *		Returns null if there is no match.
0487:             *
0488:             * @exception StandardException		Thrown on error
0489:             */
0490:
0491:            public ResultColumn getMatchingColumn(
0492:                    ColumnReference columnReference) throws StandardException {
0493:                if (SanityManager.DEBUG)
0494:                    SanityManager
0495:                            .THROWASSERT("getMatchingColumn() not expected to be called for "
0496:                                    + this );
0497:                return null;
0498:            }
0499:
0500:            /**
0501:             * Set the result column for the subquery to a boolean true,
0502:             * Useful for transformations such as
0503:             * changing:
0504:             *		where exists (select ... from ...) 
0505:             * to:
0506:             *		where (select true from ...)
0507:             *
0508:             * NOTE: No transformation is performed if the ResultColumn.expression is
0509:             * already the correct boolean constant.
0510:             * 
0511:             * @param onlyConvertAlls	Boolean, whether or not to just convert *'s
0512:             *
0513:             * @exception StandardException		Thrown on error
0514:             */
0515:            public void setResultToBooleanTrueNode(boolean onlyConvertAlls)
0516:                    throws StandardException {
0517:                BooleanConstantNode booleanNode;
0518:                ResultColumn resultColumn;
0519:
0520:                /* We need to be able to handle both ResultColumn and AllResultColumn
0521:                 * since they are peers.
0522:                 */
0523:                if (resultColumns.elementAt(0) instanceof  AllResultColumn) {
0524:                    resultColumn = (ResultColumn) getNodeFactory().getNode(
0525:                            C_NodeTypes.RESULT_COLUMN, "", null,
0526:                            getContextManager());
0527:                } else if (onlyConvertAlls) {
0528:                    return;
0529:                } else {
0530:                    resultColumn = (ResultColumn) resultColumns.elementAt(0);
0531:
0532:                    /* Nothing to do if query is already select TRUE ... */
0533:                    if (resultColumn.getExpression().isBooleanTrue()) {
0534:                        return;
0535:                    }
0536:                }
0537:
0538:                booleanNode = (BooleanConstantNode) getNodeFactory().getNode(
0539:                        C_NodeTypes.BOOLEAN_CONSTANT_NODE, Boolean.TRUE,
0540:                        getContextManager());
0541:
0542:                resultColumn.setExpression(booleanNode);
0543:                resultColumn.setType(booleanNode.getTypeServices());
0544:                /* VirtualColumnIds are 1-based, RCLs are 0-based */
0545:                resultColumn.setVirtualColumnId(1);
0546:                resultColumns.setElementAt(resultColumn, 0);
0547:            }
0548:
0549:            /**
0550:             * Get the FromList.  Create and return an empty FromList.  (Subclasses
0551:             * which actuall have FromLists will override this.)  This is useful because
0552:             * there is a FromList parameter to bindExpressions() which is used as
0553:             * the common FromList to bind against, allowing us to support
0554:             * correlation columns under unions in subqueries.
0555:             *
0556:             * @return FromList
0557:             * @exception StandardException		Thrown on error
0558:             */
0559:            public FromList getFromList() throws StandardException {
0560:                return (FromList) getNodeFactory().getNode(
0561:                        C_NodeTypes.FROM_LIST,
0562:                        getNodeFactory().doJoinOrderOptimization(),
0563:                        getContextManager());
0564:            }
0565:
0566:            /** 
0567:             * @see QueryTreeNode#disablePrivilegeCollection
0568:             */
0569:            public void disablePrivilegeCollection() {
0570:                super .disablePrivilegeCollection();
0571:                if (resultColumns != null)
0572:                    resultColumns.disablePrivilegeCollection();
0573:            }
0574:
0575:            /**
0576:             * Bind the result columns of this ResultSetNode when there is no
0577:             * base table to bind them to.  This is useful for SELECT statements,
0578:             * where the result columns get their types from the expressions that
0579:             * live under them.
0580:             *
0581:             * @param fromListParam		FromList to use/append to.
0582:             *
0583:             * @exception StandardException		Thrown on error
0584:             */
0585:
0586:            public void bindResultColumns(FromList fromListParam)
0587:                    throws StandardException {
0588:                resultColumns.bindResultColumnsToExpressions();
0589:            }
0590:
0591:            /**
0592:             * Bind the result columns for this ResultSetNode to a base table.
0593:             * This is useful for INSERT and UPDATE statements, where the
0594:             * result columns get their types from the table being updated or
0595:             * inserted into.
0596:             * If a result column list is specified, then the verification that the 
0597:             * result column list does not contain any duplicates will be done when
0598:             * binding them by name.
0599:             *
0600:             * @param targetTableDescriptor	The TableDescriptor for the table being
0601:             *				updated or inserted into
0602:             * @param targetColumnList	For INSERT statements, the user
0603:             *					does not have to supply column
0604:             *					names (for example, "insert into t
0605:             *					values (1,2,3)".  When this
0606:             *					parameter is null, it means that
0607:             *					the user did not supply column
0608:             *					names, and so the binding should
0609:             *					be done based on order.  When it
0610:             *					is not null, it means do the binding
0611:             *					by name, not position.
0612:             * @param statement			Calling DMLStatementNode (Insert or Update)
0613:             * @param fromListParam		FromList to use/append to.
0614:             *
0615:             * @exception StandardException		Thrown on error
0616:             */
0617:
0618:            public void bindResultColumns(
0619:                    TableDescriptor targetTableDescriptor, FromVTI targetVTI,
0620:                    ResultColumnList targetColumnList,
0621:                    DMLStatementNode statement, FromList fromListParam)
0622:                    throws StandardException {
0623:                /* For insert select, we need to expand any *'s in the
0624:                 * select before binding the result columns
0625:                 */
0626:                if (this  instanceof  SelectNode) {
0627:                    resultColumns
0628:                            .expandAllsAndNameColumns(((SelectNode) this ).fromList);
0629:                }
0630:
0631:                /* If specified, copy the result column names down to the 
0632:                 * source's target list.
0633:                 */
0634:                if (targetColumnList != null) {
0635:                    resultColumns.copyResultColumnNames(targetColumnList);
0636:                }
0637:
0638:                if (targetColumnList != null) {
0639:                    if (targetTableDescriptor != null) {
0640:                        resultColumns.bindResultColumnsByName(
0641:                                targetTableDescriptor,
0642:                                (DMLStatementNode) statement);
0643:                    } else {
0644:                        resultColumns.bindResultColumnsByName(targetVTI
0645:                                .getResultColumns(), targetVTI, statement);
0646:                    }
0647:                } else
0648:                    resultColumns
0649:                            .bindResultColumnsByPosition(targetTableDescriptor);
0650:            }
0651:
0652:            /**
0653:             * Bind untyped nulls to the types in the given ResultColumnList.
0654:             * This is used for binding the nulls in row constructors and
0655:             * table constructors.  In all other cases (as of the time of
0656:             * this writing), we do nothing.
0657:             *
0658:             * @param rcl	The ResultColumnList with the types to bind nulls to
0659:             *
0660:             * @exception StandardException		Thrown on error
0661:             */
0662:            public void bindUntypedNullsToResultColumns(ResultColumnList rcl)
0663:                    throws StandardException {
0664:                return;
0665:            }
0666:
0667:            /**
0668:             * Preprocess a ResultSetNode - this currently means:
0669:             *	o  Generating a referenced table map for each ResultSetNode.
0670:             *  o  Putting the WHERE and HAVING clauses in conjunctive normal form (CNF).
0671:             *  o  Converting the WHERE and HAVING clauses into PredicateLists and
0672:             *	   classifying them.
0673:             *  o  Ensuring that a ProjectRestrictNode is generated on top of every 
0674:             *     FromBaseTable and generated in place of every FromSubquery.  
0675:             *  o  Pushing single table predicates down to the new ProjectRestrictNodes.
0676:             *
0677:             * @param numTables			The number of tables in the DML Statement
0678:             * @param gbl				The group by list, if any
0679:             * @param fromList			The from list, if any
0680:             *
0681:             * @return ResultSetNode at top of preprocessed tree.
0682:             *
0683:             * @exception StandardException		Thrown on error
0684:             */
0685:
0686:            public ResultSetNode preprocess(int numTables, GroupByList gbl,
0687:                    FromList fromList) throws StandardException {
0688:                if (SanityManager.DEBUG)
0689:                    SanityManager
0690:                            .THROWASSERT("preprocess() not expected to be called for "
0691:                                    + getClass().toString());
0692:                return null;
0693:            }
0694:
0695:            /**
0696:             * Find the unreferenced result columns and project them out.
0697:             */
0698:            void projectResultColumns() throws StandardException {
0699:                // It is only necessary for joins
0700:            }
0701:
0702:            /**
0703:             * Ensure that the top of the RSN tree has a PredicateList.
0704:             *
0705:             * @param numTables			The number of tables in the query.
0706:             * @return ResultSetNode	A RSN tree with a node which has a PredicateList on top.
0707:             *
0708:             * @exception StandardException		Thrown on error
0709:             */
0710:            public ResultSetNode ensurePredicateList(int numTables)
0711:                    throws StandardException {
0712:                if (SanityManager.DEBUG)
0713:                    SanityManager
0714:                            .THROWASSERT("ensurePredicateList() not expected to be called for "
0715:                                    + getClass().toString());
0716:                return null;
0717:            }
0718:
0719:            /**
0720:             * Add a new predicate to the list.  This is useful when doing subquery
0721:             * transformations, when we build a new predicate with the left side of
0722:             * the subquery operator and the subquery's result column.
0723:             *
0724:             * @param predicate		The predicate to add
0725:             *
0726:             * @return ResultSetNode	The new top of the tree.
0727:             *
0728:             * @exception StandardException		Thrown on error
0729:             */
0730:            public ResultSetNode addNewPredicate(Predicate predicate)
0731:                    throws StandardException {
0732:                if (SanityManager.DEBUG)
0733:                    SanityManager
0734:                            .THROWASSERT("addNewPredicate() not expected to be called for "
0735:                                    + getClass().toString());
0736:                return null;
0737:            }
0738:
0739:            /**
0740:             * Evaluate whether or not the subquery in a FromSubquery is flattenable.  
0741:             * Currently, a FSqry is flattenable if all of the following are true:
0742:             *		o  Subquery is a SelectNode. (ie, not a RowResultSetNode or a UnionNode)
0743:             *		o  It contains no top level subqueries.  (RESOLVE - we can relax this)
0744:             *		o  It does not contain a group by or having clause
0745:             *		o  It does not contain aggregates.
0746:             *
0747:             * @param fromList	The outer from list
0748:             *
0749:             * @return boolean	Whether or not the FromSubquery is flattenable.
0750:             */
0751:            public boolean flattenableInFromSubquery(FromList fromList) {
0752:                if (SanityManager.DEBUG)
0753:                    SanityManager
0754:                            .THROWASSERT("flattenableInFromSubquery() not expected to be called for "
0755:                                    + getClass().toString());
0756:                return false;
0757:            }
0758:
0759:            /**
0760:             * Get a parent ProjectRestrictNode above us.
0761:             * This is useful when we need to preserve the
0762:             * user specified column order when reordering the
0763:             * columns in the distinct when we combine
0764:             * an order by with a distinct.
0765:             *
0766:             * @return A parent ProjectRestrictNode to do column reordering
0767:             *
0768:             * @exception StandardException		Thrown on error
0769:             */
0770:            ResultSetNode genProjectRestrictForReordering()
0771:                    throws StandardException {
0772:                ResultColumnList prRCList;
0773:
0774:                /* We get a shallow copy of the ResultColumnList and its 
0775:                 * ResultColumns.  (Copy maintains ResultColumn.expression for now.)
0776:                 */
0777:                prRCList = resultColumns;
0778:                resultColumns = resultColumns.copyListAndObjects();
0779:
0780:                /* Replace ResultColumn.expression with new VirtualColumnNodes
0781:                 * in the ProjectRestrictNode's ResultColumnList.  (VirtualColumnNodes include
0782:                 * pointers to source ResultSetNode, this, and source ResultColumn.)
0783:                 * NOTE: We don't want to mark the underlying RCs as referenced, otherwise
0784:                 * we won't be able to project out any of them.
0785:                 */
0786:                prRCList.genVirtualColumnNodes(this , resultColumns, false);
0787:
0788:                /* Finally, we create the new ProjectRestrictNode */
0789:                return (ResultSetNode) getNodeFactory().getNode(
0790:                        C_NodeTypes.PROJECT_RESTRICT_NODE, this , prRCList,
0791:                        null, /* Restriction */
0792:                        null, /* Restriction as PredicateList */
0793:                        null, /* Project subquery list */
0794:                        null, /* Restrict subquery list */
0795:                        null, getContextManager());
0796:            }
0797:
0798:            /**
0799:             * Optimize a ResultSetNode. This means choosing the best access
0800:             * path for each table under the ResultSetNode, among other things.
0801:             * 
0802:             * The only RSNs that need to implement their own optimize() are a 
0803:             * SelectNode and those RSNs that can appear above a SelectNode in the 
0804:             * query tree.  Currently, a ProjectRestrictNode is the only RSN that 
0805:             * can appear above a SelectNode.
0806:             *
0807:             * @param dataDictionary	The DataDictionary to use for optimization
0808:             * @param predicates		The PredicateList to apply.
0809:             * @param outerRows			The number of outer joining rows
0810:             *
0811:             * @return	ResultSetNode	The top of the optimized query tree
0812:             *
0813:             * @exception StandardException		Thrown on error
0814:             */
0815:
0816:            public ResultSetNode optimize(DataDictionary dataDictionary,
0817:                    PredicateList predicates, double outerRows)
0818:                    throws StandardException {
0819:                if (SanityManager.DEBUG)
0820:                    SanityManager.ASSERT(false,
0821:                            "optimize() is not expected to be called for "
0822:                                    + this .getClass().toString());
0823:                return null;
0824:            }
0825:
0826:            /**
0827:             * Modify the access paths according to the decisions the optimizer
0828:             * made.  This can include adding project/restrict nodes,
0829:             * index-to-base-row nodes, etc.
0830:             *
0831:             * @return	The modified query tree
0832:             *
0833:             * @exception StandardException		Thrown on error
0834:             */
0835:            public ResultSetNode modifyAccessPaths() throws StandardException {
0836:                /* Default behavior is to do nothing */
0837:                return this ;
0838:            }
0839:
0840:            /**
0841:             * Modify the access paths according to the decisions the optimizer
0842:             * made.  This can include adding project/restrict nodes,
0843:             * index-to-base-row nodes, etc.
0844:             *
0845:             * @param predList A list of optimizable predicates that should
0846:             *  be pushed to this ResultSetNode, as determined by optimizer.
0847:             * @return The modified query tree
0848:             * @exception StandardException        Thrown on error
0849:             */
0850:            public ResultSetNode modifyAccessPaths(PredicateList predList)
0851:                    throws StandardException {
0852:                // Default behavior is to call the no-arg version of this method.
0853:                return modifyAccessPaths();
0854:            }
0855:
0856:            ResultColumnDescriptor[] makeResultDescriptors(ExecutionContext ec) {
0857:                return resultColumns.makeResultDescriptors(ec);
0858:            }
0859:
0860:            /*
0861:             ** Check whether the column lengths and types of the result columns
0862:             ** match the expressions under those columns.  This is useful for
0863:             ** INSERT and UPDATE statements.  For SELECT statements this method
0864:             ** should always return true.  There is no need to call this for a
0865:             ** DELETE statement.
0866:             **
0867:             ** @return	true means all the columns match their expressions,
0868:             **		false means at least one column does not match its
0869:             **		expression
0870:             */
0871:
0872:            boolean columnTypesAndLengthsMatch() throws StandardException {
0873:                return resultColumns.columnTypesAndLengthsMatch();
0874:            }
0875:
0876:            /**
0877:             * Set the resultColumns in this ResultSetNode
0878:             *
0879:             * @param newRCL		The new ResultColumnList for this ResultSetNode
0880:             */
0881:            public void setResultColumns(ResultColumnList newRCL) {
0882:                resultColumns = newRCL;
0883:            }
0884:
0885:            /**
0886:             * Get the resultColumns for this ResultSetNode
0887:             *
0888:             * @return ResultColumnList for this ResultSetNode
0889:             */
0890:            public ResultColumnList getResultColumns() {
0891:                return resultColumns;
0892:            }
0893:
0894:            /**
0895:             * Set the referencedTableMap in this ResultSetNode
0896:             *
0897:             * @param newRTM	The new referencedTableMap for this ResultSetNode
0898:             */
0899:            public void setReferencedTableMap(JBitSet newRTM) {
0900:                referencedTableMap = newRTM;
0901:            }
0902:
0903:            /**
0904:             * Get the referencedTableMap for this ResultSetNode
0905:             *
0906:             * @return JBitSet	Referenced table map for this ResultSetNode
0907:             */
0908:            public JBitSet getReferencedTableMap() {
0909:                return referencedTableMap;
0910:            }
0911:
0912:            /**
0913:             * Fill the referencedTableMap with this ResultSetNode.
0914:             *
0915:             * @param passedMap	The table map to fill in.
0916:             */
0917:            public void fillInReferencedTableMap(JBitSet passedMap) {
0918:            }
0919:
0920:            /**
0921:             * Check for (and reject) ? parameters directly under the ResultColumns.
0922:             * This is done for SELECT statements.
0923:             *
0924:             * @exception StandardException		Thrown if a ? parameter found
0925:             *									directly under a ResultColumn
0926:             */
0927:
0928:            public void rejectParameters() throws StandardException {
0929:                /* Okay if no resultColumns yet - means no parameters there */
0930:                if (resultColumns != null) {
0931:                    resultColumns.rejectParameters();
0932:                }
0933:            }
0934:
0935:            /**
0936:             * Check for (and reject) XML values directly under the ResultColumns.
0937:             * This is done for SELECT/VALUES statements.  We reject values
0938:             * in this case because JDBC does not define an XML type/binding
0939:             * and thus there's no standard way to pass such a type back
0940:             * to a JDBC application.
0941:             *
0942:             * @exception StandardException		Thrown if an XML value found
0943:             *									directly under a ResultColumn
0944:             */
0945:            public void rejectXMLValues() throws StandardException {
0946:                if (resultColumns != null) {
0947:                    resultColumns.rejectXMLValues();
0948:                }
0949:            }
0950:
0951:            /**
0952:             * Rename generated result column names as '1', '2' etc... These will be the result
0953:             * column names seen by JDBC clients.
0954:             */
0955:            public void renameGeneratedResultNames() throws StandardException {
0956:                for (int i = 0; i < resultColumns.size(); i++) {
0957:                    ResultColumn rc = (ResultColumn) resultColumns.elementAt(i);
0958:                    if (rc.isNameGenerated())
0959:                        rc.setName(Integer.toString(i + 1));
0960:                }
0961:            }
0962:
0963:            /**
0964:            	This method is overridden to allow a resultset node to know
0965:            	if it is the one controlling the statement -- i.e., it is
0966:            	the outermost result set node for the statement.
0967:             */
0968:            public void markStatementResultSet() {
0969:                statementResultSet = true;
0970:            }
0971:
0972:            /**
0973:             * This ResultSet is the source for an Insert.  The target RCL
0974:             * is in a different order and/or a superset of this RCL.  In most cases
0975:             * we will reorder and/or add defaults to the current RCL so that is
0976:             * matches the target RCL.  Those RSNs whose generate() method does
0977:             * not handle projects will insert a PRN, with a new RCL which matches
0978:             * the target RCL, above the current RSN.
0979:             * NOTE - The new or enhanced RCL will be fully bound.
0980:             *
0981:             * @param numTargetColumns	# of columns in target RCL
0982:             * @param colMap			int array representation of correspondence between
0983:             *							RCLs - colmap[i] = -1 -> missing in current RCL
0984:             *								   colmap[i] = j -> targetRCL(i) <-> thisRCL(j+1)
0985:             * @param dataDictionary	DataDictionary to use
0986:             * @param targetTD			TableDescriptor for target if the target is not a VTI, null if a VTI
0987:             * @param targetVTI         Target description if it is a VTI, null if not a VTI
0988:             *
0989:             * @return ResultSetNode	The new top of the tree
0990:             *
0991:             * @exception StandardException		Thrown on error
0992:             */
0993:            public ResultSetNode enhanceRCLForInsert(int numTargetColumns,
0994:                    int[] colMap, DataDictionary dataDictionary,
0995:                    TableDescriptor targetTD, FromVTI targetVTI)
0996:                    throws StandardException {
0997:                // our newResultCols are put into the bound form straight away.
0998:                ResultColumnList newResultCols = (ResultColumnList) getNodeFactory()
0999:                        .getNode(C_NodeTypes.RESULT_COLUMN_LIST,
1000:                                getContextManager());
1001:                int numResultSetColumns = resultColumns.size();
1002:
1003:                /* Create a massaged version of the source RCL.
1004:                 * (Much simpler to build new list and then assign to source,
1005:                 * rather than massage the source list in place.)
1006:                 */
1007:                for (int index = 0; index < numTargetColumns; index++) {
1008:                    ResultColumn newResultColumn = null;
1009:                    ColumnReference newColumnReference;
1010:
1011:                    if (colMap[index] != -1) {
1012:                        // getResultColumn uses 1-based positioning, so offset the colMap entry appropriately
1013:                        newResultColumn = resultColumns
1014:                                .getResultColumn(colMap[index] + 1);
1015:                    } else {
1016:                        newResultColumn = genNewRCForInsert(targetTD,
1017:                                targetVTI, index + 1, dataDictionary);
1018:                    }
1019:
1020:                    newResultCols.addResultColumn(newResultColumn);
1021:                }
1022:
1023:                /* Set the source RCL to the massaged version */
1024:                resultColumns = newResultCols;
1025:
1026:                return this ;
1027:            }
1028:
1029:            /**
1030:             * Generate the RC/expression for an unspecified column in an insert.
1031:             * Use the default if one exists.
1032:             *
1033:             * @param targetTD			Target TableDescriptor if the target is not a VTI, null if a VTI.
1034:             * @param targetVTI         Target description if it is a VTI, null if not a VTI
1035:             * @param columnNumber		The column number
1036:             * @param dataDictionary	The DataDictionary
1037:             * @return	The RC/expression for the unspecified column.
1038:             *
1039:             * @exception StandardException		Thrown on error
1040:             */
1041:            ResultColumn genNewRCForInsert(TableDescriptor targetTD,
1042:                    FromVTI targetVTI, int columnNumber,
1043:                    DataDictionary dataDictionary) throws StandardException {
1044:                ResultColumn newResultColumn = null;
1045:
1046:                // the i-th column's value was not specified, so create an
1047:                // expression containing its default value (null for now)
1048:                // REVISIT: will we store trailing nulls?
1049:
1050:                if (targetVTI != null) {
1051:                    newResultColumn = targetVTI.getResultColumns()
1052:                            .getResultColumn(columnNumber);
1053:                    newResultColumn = newResultColumn.cloneMe();
1054:                    newResultColumn.setExpressionToNullNode();
1055:                } else {
1056:                    // column position is 1-based, index is 0-based.
1057:                    ColumnDescriptor colDesc = targetTD
1058:                            .getColumnDescriptor(columnNumber);
1059:                    DataTypeDescriptor colType = colDesc.getType();
1060:
1061:                    // Check for defaults
1062:                    DefaultInfoImpl defaultInfo = (DefaultInfoImpl) colDesc
1063:                            .getDefaultInfo();
1064:
1065:                    //Column has constant default value , 
1066:                    //if it have defaultInfo and not be autoincrement.
1067:                    if (defaultInfo != null && !colDesc.isAutoincrement()) {
1068:                        //RESOLVEPARAMETER - skip the tree if we have the value
1069:                        /*
1070:                          if (defaultInfo.getDefaultValue() != null)
1071:                          {
1072:                          }
1073:                          else
1074:                         */
1075:                        {
1076:                            // Generate the tree for the default
1077:                            String defaultText = defaultInfo.getDefaultText();
1078:                            ValueNode defaultTree = parseDefault(defaultText);
1079:                            defaultTree = defaultTree.bindExpression(
1080:                                    getFromList(), (SubqueryList) null,
1081:                                    (Vector) null);
1082:                            newResultColumn = (ResultColumn) getNodeFactory()
1083:                                    .getNode(C_NodeTypes.RESULT_COLUMN,
1084:                                            defaultTree.getTypeServices(),
1085:                                            defaultTree, getContextManager());
1086:
1087:                            DefaultDescriptor defaultDescriptor = colDesc
1088:                                    .getDefaultDescriptor(dataDictionary);
1089:                            if (SanityManager.DEBUG) {
1090:                                SanityManager
1091:                                        .ASSERT(defaultDescriptor != null,
1092:                                                "defaultDescriptor expected to be non-null");
1093:                            }
1094:                            getCompilerContext().createDependency(
1095:                                    defaultDescriptor);
1096:                        }
1097:                    } else if (colDesc.isAutoincrement()) {
1098:                        newResultColumn = (ResultColumn) getNodeFactory()
1099:                                .getNode(C_NodeTypes.RESULT_COLUMN, colDesc,
1100:                                        null, getContextManager());
1101:                        newResultColumn.setAutoincrementGenerated();
1102:                    } else {
1103:                        newResultColumn = (ResultColumn) getNodeFactory()
1104:                                .getNode(
1105:                                        C_NodeTypes.RESULT_COLUMN,
1106:                                        colType,
1107:                                        getNullNode(colType.getTypeId(),
1108:                                                getContextManager()),
1109:                                        getContextManager());
1110:                    }
1111:                }
1112:
1113:                // Mark the new RC as generated for an unmatched column in an insert
1114:                newResultColumn.markGeneratedForUnmatchedColumnInInsert();
1115:
1116:                return newResultColumn;
1117:            }
1118:
1119:            /**
1120:             *	Parse a default and turn it into a query tree.
1121:             *
1122:             *	@param	defaultText			Text of Default.
1123:             *
1124:             * @return	The parsed default as a query tree.
1125:             *
1126:             * @exception StandardException		Thrown on failure
1127:             */
1128:            public ValueNode parseDefault(String defaultText)
1129:                    throws StandardException {
1130:                Parser p;
1131:                ValueNode defaultTree;
1132:                LanguageConnectionContext lcc = getLanguageConnectionContext();
1133:                CompilerContext compilerContext = getCompilerContext();
1134:
1135:                /* Get a Statement to pass to the parser */
1136:
1137:                /* We're all set up to parse. We have to build a compilable SQL statement
1138:                 * before we can parse -  So, we goober up a VALUES defaultText.
1139:                 */
1140:                String values = "VALUES " + defaultText;
1141:
1142:                /*
1143:                 ** Get a new compiler context, so the parsing of the select statement
1144:                 ** doesn't mess up anything in the current context (it could clobber
1145:                 ** the ParameterValueSet, for example).
1146:                 */
1147:                CompilerContext newCC = lcc.pushCompilerContext();
1148:
1149:                p = newCC.getParser();
1150:
1151:                /* Finally, we can call the parser */
1152:                // Since this is always nested inside another SQL statement, so topLevel flag
1153:                // should be false
1154:                QueryTreeNode qt = p.parseStatement(values);
1155:                if (SanityManager.DEBUG) {
1156:                    if (!(qt instanceof  CursorNode)) {
1157:                        SanityManager
1158:                                .THROWASSERT("qt expected to be instanceof CursorNode, not "
1159:                                        + qt.getClass().getName());
1160:                    }
1161:                    CursorNode cn = (CursorNode) qt;
1162:                    if (!(cn.getResultSetNode() instanceof  RowResultSetNode)) {
1163:                        SanityManager
1164:                                .THROWASSERT("cn.getResultSetNode() expected to be instanceof RowResultSetNode, not "
1165:                                        + cn.getResultSetNode().getClass()
1166:                                                .getName());
1167:                    }
1168:                }
1169:
1170:                defaultTree = ((ResultColumn) ((CursorNode) qt)
1171:                        .getResultSetNode().getResultColumns().elementAt(0))
1172:                        .getExpression();
1173:
1174:                lcc.popCompilerContext(newCC);
1175:
1176:                return defaultTree;
1177:            }
1178:
1179:            /**
1180:             * Make a ResultDescription for use in a ResultSet.
1181:             * This is useful when generating/executing a NormalizeResultSet, since
1182:             * it can appear anywhere in the tree.
1183:             *
1184:             * @return	A ResultDescription for this ResultSetNode.
1185:             */
1186:
1187:            public ResultDescription makeResultDescription() {
1188:                ExecutionContext ec = (ExecutionContext) getContextManager()
1189:                        .getContext(ExecutionContext.CONTEXT_ID);
1190:                ResultColumnDescriptor[] colDescs = makeResultDescriptors(ec);
1191:
1192:                return ec.getExecutionFactory().getResultDescription(colDescs,
1193:                        null);
1194:            }
1195:
1196:            /**
1197:            	Determine if this result set is updatable or not, for a cursor
1198:            	(i.e., is it a cursor-updatable select).  This returns false
1199:            	and we expect selectnode to refine it for further checking.
1200:             *
1201:             * @exception StandardException		Thrown on error
1202:             */
1203:            boolean isUpdatableCursor(DataDictionary dd)
1204:                    throws StandardException {
1205:                if (SanityManager.DEBUG)
1206:                    SanityManager.DEBUG("DumpUpdateCheck",
1207:                            "cursor is not a select result set");
1208:                return false;
1209:            }
1210:
1211:            /**
1212:            	return the target table of an updatable cursor result set.
1213:            	since this is not updatable, just return null.
1214:             */
1215:            FromTable getCursorTargetTable() {
1216:                return null;
1217:            }
1218:
1219:            /**
1220:            	Mark this ResultSetNode as the target table of an updatable
1221:            	cursor.  Most types of ResultSetNode can't be target tables.
1222:            	@return true if the target table supports positioned updates.
1223:             */
1224:            public boolean markAsCursorTargetTable() {
1225:                return false;
1226:            }
1227:
1228:            /**
1229:            	Mark this ResultSetNode as *not* the target table of an updatable
1230:            	cursor.
1231:             */
1232:            void notCursorTargetTable() {
1233:                cursorTargetTable = false;
1234:            }
1235:
1236:            /** 
1237:             * Put a ProjectRestrictNode on top of this ResultSetNode.
1238:             * ColumnReferences must continue to point to the same ResultColumn, so
1239:             * that ResultColumn must percolate up to the new PRN.  However,
1240:             * that ResultColumn will point to a new expression, a VirtualColumnNode, 
1241:             * which points to the FromTable and the ResultColumn that is the source for
1242:             * the ColumnReference.  
1243:             * (The new PRN will have the original of the ResultColumnList and
1244:             * the ResultColumns from that list.  The FromTable will get shallow copies
1245:             * of the ResultColumnList and its ResultColumns.  ResultColumn.expression
1246:             * will remain at the FromTable, with the PRN getting a new 
1247:             * VirtualColumnNode for each ResultColumn.expression.)
1248:             *
1249:             * This is useful for UNIONs, where we want to generate a DistinctNode above
1250:             * the UnionNode to eliminate the duplicates, because DistinctNodes expect
1251:             * their immediate child to be a PRN.
1252:             *
1253:             * @return The generated ProjectRestrictNode atop the original ResultSetNode.
1254:             *
1255:             * @exception StandardException		Thrown on error
1256:             */
1257:
1258:            public ResultSetNode genProjectRestrict() throws StandardException {
1259:                ResultColumnList prRCList;
1260:
1261:                /* We get a shallow copy of the ResultColumnList and its 
1262:                 * ResultColumns.  (Copy maintains ResultColumn.expression for now.)
1263:                 */
1264:                prRCList = resultColumns;
1265:                resultColumns = resultColumns.copyListAndObjects();
1266:
1267:                /* Replace ResultColumn.expression with new VirtualColumnNodes
1268:                 * in the ProjectRestrictNode's ResultColumnList.  (VirtualColumnNodes include
1269:                 * pointers to source ResultSetNode, this, and source ResultColumn.)
1270:                 */
1271:                prRCList.genVirtualColumnNodes(this , resultColumns);
1272:
1273:                /* Finally, we create the new ProjectRestrictNode */
1274:                return (ResultSetNode) getNodeFactory().getNode(
1275:                        C_NodeTypes.PROJECT_RESTRICT_NODE, this , prRCList,
1276:                        null, /* Restriction */
1277:                        null, /* Restriction as PredicateList */
1278:                        null, /* Project subquery list */
1279:                        null, /* Restrict subquery list */
1280:                        null, getContextManager());
1281:            }
1282:
1283:            /** 
1284:             * Put a ProjectRestrictNode on top of each FromTable in the FromList.
1285:             * ColumnReferences must continue to point to the same ResultColumn, so
1286:             * that ResultColumn must percolate up to the new PRN.  However,
1287:             * that ResultColumn will point to a new expression, a VirtualColumnNode, 
1288:             * which points to the FromTable and the ResultColumn that is the source for
1289:             * the ColumnReference.  
1290:             * (The new PRN will have the original of the ResultColumnList and
1291:             * the ResultColumns from that list.  The FromTable will get shallow copies
1292:             * of the ResultColumnList and its ResultColumns.  ResultColumn.expression
1293:             * will remain at the FromTable, with the PRN getting a new 
1294:             * VirtualColumnNode for each ResultColumn.expression.)
1295:             * We then project out the non-referenced columns.  If there are no referenced
1296:             * columns, then the PRN's ResultColumnList will consist of a single ResultColumn
1297:             * whose expression is 1.
1298:             *
1299:             * @param numTables			Number of tables in the DML Statement
1300:             *
1301:             * @return The generated ProjectRestrictNode atop the original FromTable.
1302:             *
1303:             * @exception StandardException		Thrown on error
1304:             */
1305:
1306:            protected ResultSetNode genProjectRestrict(int numTables)
1307:                    throws StandardException {
1308:                return genProjectRestrict();
1309:            }
1310:
1311:            /** 
1312:             * Put a NormalizeResultSetNode on top of the specified ResultSetNode.
1313:             * ColumnReferences must continue to point to the same ResultColumn, so
1314:             * that ResultColumn must percolate up to the new PRN.  However,
1315:             * that ResultColumn will point to a new expression, a VirtualColumnNode, 
1316:             * which points to the FromTable and the ResultColumn that is the source for
1317:             * the ColumnReference.  
1318:             * (The new NRSN will have the original of the ResultColumnList and
1319:             * the ResultColumns from that list.  The FromTable will get shallow copies
1320:             * of the ResultColumnList and its ResultColumns.  ResultColumn.expression
1321:             * will remain at the FromTable, with the PRN getting a new 
1322:             * VirtualColumnNode for each ResultColumn.expression.)
1323:             *
1324:             * This is useful for UNIONs, where we want to generate a DistinctNode above
1325:             * the UnionNode to eliminate the duplicates, because the type going into the
1326:             * sort has to agree with what the sort expects.
1327:             * (insert into t1 (smallintcol) values 1 union all values 2;
1328:             *
1329:             * @param normalizeChild	Child result set for new NRSN.
1330:             * @param forUpdate			If the normalize result set is being used as a
1331:             * child for an update statement, then this is true. 
1332:             *
1333:             * @return The generated NormalizeResultSetNode atop the original UnionNode.
1334:             *
1335:             * @exception StandardException		Thrown on error
1336:             * @see NormalizeResultSetNode#init
1337:             */
1338:
1339:            public NormalizeResultSetNode genNormalizeResultSetNode(
1340:                    ResultSetNode normalizeChild, boolean forUpdate)
1341:                    throws StandardException {
1342:                NormalizeResultSetNode nrsn;
1343:                ResultColumnList prRCList;
1344:
1345:                /* We get a shallow copy of the ResultColumnList and its 
1346:                 * ResultColumns.  (Copy maintains ResultColumn.expression for now.)
1347:                 */
1348:                prRCList = resultColumns;
1349:                resultColumns = resultColumns.copyListAndObjects();
1350:
1351:                /* Replace ResultColumn.expression with new VirtualColumnNodes
1352:                 * in the NormalizeResultSetNode's ResultColumnList.  (VirtualColumnNodes include
1353:                 * pointers to source ResultSetNode, this, and source ResultColumn.)
1354:                 */
1355:                prRCList.genVirtualColumnNodes(this , resultColumns);
1356:
1357:                /* Finally, we create the new NormalizeResultSetNode */
1358:                nrsn = (NormalizeResultSetNode) getNodeFactory().getNode(
1359:                        C_NodeTypes.NORMALIZE_RESULT_SET_NODE, normalizeChild,
1360:                        prRCList, null, new Boolean(forUpdate),
1361:                        getContextManager());
1362:                // Propagate the referenced table map if it's already been created
1363:                if (normalizeChild.getReferencedTableMap() != null) {
1364:                    nrsn.setReferencedTableMap((JBitSet) normalizeChild
1365:                            .getReferencedTableMap().clone());
1366:                }
1367:                return nrsn;
1368:            }
1369:
1370:            /**
1371:             * Generate the code for a NormalizeResultSet.
1372:               The call must push two items before calling this method
1373:               <OL>
1374:               <LI> pushGetResultSetFactoryExpression
1375:               <LI> the expression to normalize
1376:               </OL>
1377:             *
1378:             * @param acb				The ActivationClassBuilder
1379:             * @param mb				The method to put the generated code in
1380:             * @param resultSetNumber	The result set number for the NRS
1381:             * @param resultDescription	The ERD for the ResultSet
1382:             *
1383:             *
1384:             * @exception StandardException		Thrown on error
1385:             */
1386:            public void generateNormalizationResultSet(
1387:                    ActivationClassBuilder acb, MethodBuilder mb,
1388:                    int resultSetNumber, ResultDescription resultDescription)
1389:                    throws StandardException {
1390:                int erdNumber = acb.addItem(resultDescription);
1391:
1392:                // instance and first arg are pushed by caller
1393:
1394:                mb.push(resultSetNumber);
1395:                mb.push(erdNumber);
1396:                mb.push(getCostEstimate().rowCount());
1397:                mb.push(getCostEstimate().getEstimatedCost());
1398:                mb.push(false);
1399:
1400:                mb.callMethod(VMOpcode.INVOKEINTERFACE, (String) null,
1401:                        "getNormalizeResultSet", ClassName.NoPutResultSet, 6);
1402:            }
1403:
1404:            /**
1405:             * The optimizer's decision on the access path for a result set
1406:             * may require the generation of extra result sets.  For example,
1407:             * if it chooses an index for a FromBaseTable, we need an IndexToBaseRowNode
1408:             * above the FromBaseTable (and the FromBaseTable has to change its
1409:             * column list to match the index.
1410:             *
1411:             * This method in the parent class does not generate any extra result sets.
1412:             * It may be overridden in child classes.
1413:             *
1414:             * @return	A ResultSetNode tree modified to do any extra processing for
1415:             *			the chosen access path
1416:             *
1417:             * @exception StandardException		Thrown on error
1418:             */
1419:            public ResultSetNode changeAccessPath() throws StandardException {
1420:                return this ;
1421:            }
1422:
1423:            /**
1424:             * Search to see if a query references the specifed table name.
1425:             *
1426:             * @param name		Table name (String) to search for.
1427:             * @param baseTable	Whether or not name is for a base table
1428:             *
1429:             * @return	true if found, else false
1430:             *
1431:             * @exception StandardException		Thrown on error
1432:             */
1433:            public boolean referencesTarget(String name, boolean baseTable)
1434:                    throws StandardException {
1435:                return false;
1436:            }
1437:
1438:            /**
1439:             * Return whether or not this ResultSetNode contains a subquery with a
1440:             * reference to the specified target.
1441:             * 
1442:             * @param name	The table name.
1443:             *
1444:             * @return boolean	Whether or not a reference to the table was found.
1445:             *
1446:             * @exception StandardException		Thrown on error
1447:             */
1448:            boolean subqueryReferencesTarget(String name, boolean baseTable)
1449:                    throws StandardException {
1450:                return false;
1451:            }
1452:
1453:            /**
1454:             * Return whether or not the underlying ResultSet tree will return
1455:             * a single row, at most.
1456:             * This is important for join nodes where we can save the extra next
1457:             * on the right side if we know that it will return at most 1 row.
1458:             *
1459:             * @return Whether or not the underlying ResultSet tree will return a single row.
1460:             * @exception StandardException		Thrown on error
1461:             */
1462:            public boolean isOneRowResultSet() throws StandardException {
1463:                // Default is false
1464:                return false;
1465:            }
1466:
1467:            /**
1468:             * Return whether or not the underlying ResultSet tree is for a NOT EXISTS
1469:             * join.
1470:             *
1471:             * @return Whether or not the underlying ResultSet tree if for NOT EXISTS.
1472:             */
1473:            public boolean isNotExists() {
1474:                // Default is false
1475:                return false;
1476:            }
1477:
1478:            /**
1479:             * Get an optimizer to use for this ResultSetNode.  Only get it once -
1480:             * subsequent calls return the same optimizer.
1481:             *
1482:             * @exception StandardException		Thrown on error
1483:             */
1484:            protected Optimizer getOptimizer(OptimizableList optList,
1485:                    OptimizablePredicateList predList,
1486:                    DataDictionary dataDictionary,
1487:                    RequiredRowOrdering requiredRowOrdering)
1488:                    throws StandardException {
1489:                if (optimizer == null) {
1490:                    /* Get an optimizer. */
1491:                    OptimizerFactory optimizerFactory = getLanguageConnectionContext()
1492:                            .getOptimizerFactory();
1493:
1494:                    optimizer = optimizerFactory.getOptimizer(optList,
1495:                            predList, dataDictionary, requiredRowOrdering,
1496:                            getCompilerContext().getNumTables(),
1497:                            getLanguageConnectionContext());
1498:                }
1499:
1500:                optimizer.prepForNextRound();
1501:                return optimizer;
1502:            }
1503:
1504:            /**
1505:             * Get the optimizer for this result set.
1506:             * 
1507:             * @return If this.optimizer has has already been created by the
1508:             *  getOptimizer() method above, then return it; otherwise,
1509:             *  return null.
1510:             */
1511:            protected OptimizerImpl getOptimizerImpl() {
1512:                // Note that the optimizer might be null because it's possible that
1513:                // we'll get here before any calls to getOptimizer() were made, which
1514:                // can happen if we're trying to save a "best path" but we haven't
1515:                // actually found one yet.  In that case we just return the "null"
1516:                // value; the caller must check for it and behave appropriately.
1517:                // Ex. see TableOperatorNode.addOrLoadBestPlanMapping().
1518:                return (OptimizerImpl) optimizer;
1519:            }
1520:
1521:            /**
1522:             * Get a cost estimate to use for this ResultSetNode.
1523:             *
1524:             * @exception StandardException		Thrown on error
1525:             */
1526:            protected CostEstimate getNewCostEstimate()
1527:                    throws StandardException {
1528:                OptimizerFactory optimizerFactory = getLanguageConnectionContext()
1529:                        .getOptimizerFactory();
1530:                return optimizerFactory.getCostEstimate();
1531:            }
1532:
1533:            /**
1534:             * Accept a visitor, and call v.visit()
1535:             * on child nodes as necessary.  
1536:             * 
1537:             * @param v the visitor
1538:             *
1539:             * @exception StandardException on error
1540:             */
1541:            public Visitable accept(Visitor v) throws StandardException {
1542:                Visitable returnNode = v.visit(this );
1543:
1544:                if (v.skipChildren(this )) {
1545:                    return returnNode;
1546:                }
1547:
1548:                if (resultColumns != null && !v.stopTraversal()) {
1549:                    resultColumns = (ResultColumnList) resultColumns.accept(v);
1550:                }
1551:                return returnNode;
1552:            }
1553:
1554:            /**
1555:             * Consider materialization for this ResultSet tree if it is valid and cost effective
1556:             * (It is not valid if incorrect results would be returned.)
1557:             *
1558:             * @return Top of the new/same ResultSet tree.
1559:             *
1560:             * @exception StandardException		Thrown on error
1561:             */
1562:            public ResultSetNode considerMaterialization(JBitSet outerTables)
1563:                    throws StandardException {
1564:                return this ;
1565:            }
1566:
1567:            /**
1568:             * Return whether or not to materialize this ResultSet tree.
1569:             *
1570:             * @return Whether or not to materialize this ResultSet tree.
1571:             *			would return valid results.
1572:             *
1573:             * @exception StandardException		Thrown on error
1574:             */
1575:            public boolean performMaterialization(JBitSet outerTables)
1576:                    throws StandardException {
1577:                return false;
1578:            }
1579:
1580:            /** 
1581:             * Determine whether or not the specified name is an exposed name in
1582:             * the current query block.
1583:             *
1584:             * @param name	The specified name to search for as an exposed name.
1585:             * @param schemaName	Schema name, if non-null.
1586:             * @param exactMatch	Whether or not we need an exact match on specified schema and table
1587:             *						names or match on table id.
1588:             *
1589:             * @return The FromTable, if any, with the exposed name.
1590:             *
1591:             * @exception StandardException		Thrown on error
1592:             */
1593:            protected FromTable getFromTableByName(String name,
1594:                    String schemaName, boolean exactMatch)
1595:                    throws StandardException {
1596:                if (SanityManager.DEBUG) {
1597:                    SanityManager
1598:                            .THROWASSERT("getFromTableByName() not expected to be called for "
1599:                                    + getClass().getName());
1600:                }
1601:                return null;
1602:            }
1603:
1604:            /**
1605:             * Decrement (query block) level (0-based) for 
1606:             * all of the tables in this ResultSet tree.
1607:             * This is useful when flattening a subquery.
1608:             *
1609:             * @param decrement	The amount to decrement by.
1610:             */
1611:            abstract void decrementLevel(int decrement);
1612:
1613:            /**
1614:             * Push the order by list down from the cursor node
1615:             * into its child result set so that the optimizer
1616:             * has all of the information that it needs to 
1617:             * consider sort avoidance.
1618:             *
1619:             * @param orderByList	The order by list
1620:             */
1621:            void pushOrderByList(OrderByList orderByList) {
1622:                if (SanityManager.DEBUG) {
1623:                    SanityManager
1624:                            .THROWASSERT("pushOrderByList() not expected to be called for "
1625:                                    + getClass().getName());
1626:                }
1627:            }
1628:
1629:            /**
1630:             * General logic shared by Core compilation and by the Replication Filter
1631:             * compiler. A couple ResultSets (the ones used by PREPARE SELECT FILTER)
1632:             * implement this method.
1633:             *
1634:             * @param acb	The ExpressionClassBuilder for the class being built
1635:             * @param mb	The method the expression will go into
1636:             *
1637:             *
1638:             * @exception StandardException		Thrown on error
1639:             */
1640:
1641:            public void generateResultSet(ExpressionClassBuilder acb,
1642:                    MethodBuilder mb) throws StandardException {
1643:                System.out.println("I am a " + getClass());
1644:                if (SanityManager.DEBUG)
1645:                    SanityManager.NOTREACHED();
1646:                return;
1647:            }
1648:
1649:            /**
1650:             * Get the lock mode for the target of an update statement
1651:             * (a delete or update).  The update mode will always be row for
1652:             * CurrentOfNodes.  It will be table if there is no where clause.
1653:             *
1654:             * @see TransactionController
1655:             *
1656:             * @return	The lock mode
1657:             */
1658:            public int updateTargetLockMode() {
1659:                return TransactionController.MODE_TABLE;
1660:            }
1661:
1662:            /**
1663:             * Mark this node and its children as not being a flattenable join.
1664:             */
1665:            void notFlattenableJoin() {
1666:            }
1667:
1668:            /**
1669:             * Return whether or not the underlying ResultSet tree
1670:             * is ordered on the specified columns.
1671:             * RESOLVE - This method currently only considers the outermost table 
1672:             * of the query block.
1673:             *
1674:             * @param	crs					The specified ColumnReference[]
1675:             * @param	permuteOrdering		Whether or not the order of the CRs in the array can be permuted
1676:             * @param	fbtVector			Vector that is to be filled with the FromBaseTable	
1677:             *
1678:             * @return	Whether the underlying ResultSet tree
1679:             * is ordered on the specified column.
1680:             *
1681:             * @exception StandardException		Thrown on error
1682:             */
1683:            boolean isOrderedOn(ColumnReference[] crs, boolean permuteOrdering,
1684:                    Vector fbtVector) throws StandardException {
1685:                return false;
1686:            }
1687:
1688:            /**
1689:             * Return whether or not this ResultSet tree is guaranteed to return
1690:             * at most 1 row based on heuristics.  (A RowResultSetNode and a
1691:             * SELECT with a non-grouped aggregate will return at most 1 row.)
1692:             *
1693:             * @return Whether or not this ResultSet tree is guaranteed to return
1694:             * at most 1 row based on heuristics.
1695:             */
1696:            boolean returnsAtMostOneRow() {
1697:                return false;
1698:            }
1699:
1700:            /**
1701:             * Replace any DEFAULTs with the associated tree for the default.
1702:             *
1703:             * @param ttd	The TableDescriptor for the target table.
1704:             * @param tcl	The RCL for the target table.
1705:             *
1706:             * @exception StandardException		Thrown on error
1707:             */
1708:            void replaceDefaults(TableDescriptor ttd, ResultColumnList tcl)
1709:                    throws StandardException {
1710:                // Only subclasses with something to do override this.
1711:            }
1712:
1713:            /**
1714:             * Is it possible to do a distinct scan on this ResultSet tree.
1715:             * (See SelectNode for the criteria.)
1716:             *
1717:             * @param distinctColumns the set of distinct columns
1718:             * @return Whether or not it is possible to do a distinct scan on this ResultSet tree.
1719:             */
1720:            boolean isPossibleDistinctScan(Set distinctColumns) {
1721:                return false;
1722:            }
1723:
1724:            /**
1725:             * Mark the underlying scan as a distinct scan.
1726:             */
1727:            void markForDistinctScan() {
1728:                if (SanityManager.DEBUG) {
1729:                    SanityManager
1730:                            .THROWASSERT("markForDistinctScan() not expected to be called for "
1731:                                    + getClass().getName());
1732:                }
1733:            }
1734:
1735:            /**
1736:             * Notify the underlying result set tree that the result is
1737:             * ordering dependent.  (For example, no bulk fetch on an index
1738:             * if under an IndexRowToBaseRow.)
1739:             */
1740:            void markOrderingDependent() {
1741:                if (SanityManager.DEBUG) {
1742:                    SanityManager
1743:                            .THROWASSERT("markOrderingDependent() not expected to be called for "
1744:                                    + getClass().getName());
1745:                }
1746:            }
1747:
1748:            /**
1749:             * Count the number of distinct aggregates in the list.
1750:             * By 'distinct' we mean aggregates of the form:
1751:             *	<UL><I>SELECT MAX(DISTINCT x) FROM T<\I><\UL>
1752:             *
1753:             * @return number of aggregates
1754:             */
1755:            protected static final int numDistinctAggregates(
1756:                    Vector aggregateVector) {
1757:                int count = 0;
1758:                int size = aggregateVector.size();
1759:
1760:                for (int index = 0; index < size; index++) {
1761:                    count += (((AggregateNode) aggregateVector.elementAt(index))
1762:                            .isDistinct() == true) ? 1 : 0;
1763:                }
1764:
1765:                return count;
1766:            }
1767:
1768:            // It may be we have a SELECT view underneath a LOJ.
1769:            // Return null for now.. we don't do any optimization.
1770:            public JBitSet LOJgetReferencedTables(int numTables)
1771:                    throws StandardException {
1772:                if (this  instanceof  FromTable) {
1773:                    if (((FromTable) this ).tableNumber != -1) {
1774:                        JBitSet map = new JBitSet(numTables);
1775:                        map.set(((FromTable) this).tableNumber);
1776:                        return map;
1777:                    }
1778:                }
1779:
1780:                return null;
1781:            }
1782:
1783:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.