Source Code Cross Referenced for FromVTI.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.FromVTI
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.loader.ClassInspector;
0025:        import org.apache.derby.iapi.services.loader.GeneratedMethod;
0026:
0027:        import org.apache.derby.iapi.services.context.ContextManager;
0028:
0029:        import org.apache.derby.iapi.services.compiler.MethodBuilder;
0030:        import org.apache.derby.iapi.services.compiler.LocalField;
0031:
0032:        import org.apache.derby.iapi.services.sanity.SanityManager;
0033:
0034:        import org.apache.derby.iapi.error.StandardException;
0035:
0036:        import org.apache.derby.iapi.sql.compile.CompilerContext;
0037:        import org.apache.derby.iapi.sql.compile.OptimizablePredicateList;
0038:        import org.apache.derby.iapi.sql.compile.Optimizer;
0039:        import org.apache.derby.iapi.sql.compile.OptimizablePredicate;
0040:        import org.apache.derby.iapi.sql.compile.Optimizable;
0041:        import org.apache.derby.iapi.sql.compile.CostEstimate;
0042:        import org.apache.derby.iapi.sql.compile.Visitable;
0043:        import org.apache.derby.iapi.sql.compile.Visitor;
0044:        import org.apache.derby.iapi.sql.compile.RowOrdering;
0045:        import org.apache.derby.iapi.sql.compile.C_NodeTypes;
0046:
0047:        import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
0048:
0049:        import org.apache.derby.iapi.sql.dictionary.DataDictionary;
0050:        import org.apache.derby.iapi.sql.dictionary.ColumnDescriptor;
0051:        import org.apache.derby.iapi.sql.dictionary.ColumnDescriptorList;
0052:        import org.apache.derby.iapi.sql.dictionary.ConglomerateDescriptor;
0053:        import org.apache.derby.iapi.sql.dictionary.TableDescriptor;
0054:
0055:        import org.apache.derby.iapi.reference.ClassName;
0056:        import org.apache.derby.iapi.reference.JDBC20Translation;
0057:        import org.apache.derby.iapi.reference.SQLState;
0058:
0059:        import org.apache.derby.iapi.sql.Activation;
0060:
0061:        import org.apache.derby.catalog.UUID;
0062:
0063:        import org.apache.derby.vti.DeferModification;
0064:        import org.apache.derby.vti.VTICosting;
0065:        import org.apache.derby.vti.VTIEnvironment;
0066:
0067:        import org.apache.derby.iapi.util.JBitSet;
0068:        import org.apache.derby.iapi.services.io.FormatableBitSet;
0069:        import org.apache.derby.iapi.services.classfile.VMOpcode;
0070:        import org.apache.derby.iapi.services.info.JVMInfo;
0071:
0072:        import org.apache.derby.impl.sql.compile.ActivationClassBuilder;
0073:        import org.apache.derby.iapi.sql.execute.ExecutionContext;
0074:
0075:        import java.lang.reflect.Constructor;
0076:        import java.lang.reflect.InvocationTargetException;
0077:
0078:        import java.sql.PreparedStatement;
0079:        import java.sql.ResultSet;
0080:        import java.sql.ResultSetMetaData;
0081:        import java.sql.SQLException;
0082:        import java.sql.Types;
0083:
0084:        import java.util.Enumeration;
0085:        import java.util.Properties;
0086:        import java.util.Vector;
0087:        import org.apache.derby.iapi.services.io.FormatableHashtable;
0088:
0089:        import java.lang.reflect.Modifier;
0090:
0091:        /**
0092:         * A FromVTI represents a VTI in the FROM list of a DML statement.
0093:         *
0094:         * @author Jerry Brenner
0095:         */
0096:        public class FromVTI extends FromTable implements  VTIEnvironment {
0097:
0098:            JBitSet correlationMap;
0099:            JBitSet dependencyMap;
0100:            NewInvocationNode newInvocation;
0101:            TableName exposedName;
0102:            SubqueryList subqueryList;
0103:            boolean implements VTICosting;
0104:            boolean optimized;
0105:            boolean materializable;
0106:            boolean isTarget;
0107:            ResultSet rs;
0108:
0109:            private FormatableHashtable compileTimeConstants;
0110:
0111:            // Number of columns returned by the VTI
0112:            protected int numVTICols;
0113:
0114:            private PredicateList restrictionList;
0115:
0116:            /**
0117:            	Was a FOR UPDATE clause specified in a SELECT statement.
0118:             */
0119:            private boolean forUpdatePresent;
0120:
0121:            /**
0122:            	Was the FOR UPDATE clause empty (no columns specified).
0123:             */
0124:            private boolean emptyForUpdate;
0125:
0126:            /*
0127:             ** We don't know how expensive a virtual table will be.
0128:             ** Let's say it has 10000 rows with a cost of 100000.
0129:             */
0130:            double estimatedCost = VTICosting.defaultEstimatedCost;
0131:            double estimatedRowCount = VTICosting.defaultEstimatedRowCount;
0132:            boolean supportsMultipleInstantiations = true;
0133:            boolean vtiCosted;
0134:
0135:            /* Version 1 or 2 VTI*/
0136:            protected boolean version2;
0137:            private boolean implements Pushable;
0138:            private PreparedStatement ps;
0139:
0140:            private JavaValueNode[] methodParms;
0141:
0142:            private boolean controlsDeferral;
0143:            private boolean isInsensitive;
0144:            private int resultSetType = ResultSet.TYPE_FORWARD_ONLY;
0145:
0146:            /**
0147:             * @param newInvocation		The constructor for the VTI
0148:             * @param correlationName	The correlation name
0149:             * @param derivedRCL		The derived column list
0150:             * @param tableProperties	Properties list associated with the table
0151:             *
0152:             * @exception StandardException		Thrown on error
0153:             */
0154:            public void init(Object newInvocation, Object correlationName,
0155:                    Object derivedRCL, Object tableProperties)
0156:                    throws StandardException {
0157:                init(newInvocation, correlationName, derivedRCL,
0158:                        tableProperties, makeTableName(null,
0159:                                (String) correlationName));
0160:            }
0161:
0162:            /**
0163:             * @param newInvocation		The constructor for the VTI
0164:             * @param correlationName	The correlation name
0165:             * @param derivedRCL		The derived column list
0166:             * @param tableProperties	Properties list associated with the table
0167:             * @param exposedTableName  The table name (TableName class)
0168:             *
0169:             * @exception StandardException		Thrown on error
0170:             */
0171:            public void init(Object newInvocation, Object correlationName,
0172:                    Object derivedRCL, Object tableProperties,
0173:                    Object exposedTableName) throws StandardException {
0174:                super .init(correlationName, tableProperties);
0175:                this .newInvocation = (NewInvocationNode) newInvocation;
0176:                resultColumns = (ResultColumnList) derivedRCL;
0177:                subqueryList = (SubqueryList) getNodeFactory().getNode(
0178:                        C_NodeTypes.SUBQUERY_LIST, getContextManager());
0179:
0180:                /* Cache exposed name for this table.
0181:                 * The exposed name becomes the qualifier for each column
0182:                 * in the expanded list.
0183:                 */
0184:                this .exposedName = (TableName) exposedTableName;
0185:            }
0186:
0187:            // Optimizable interface
0188:
0189:            /**
0190:             * @see Optimizable#estimateCost
0191:             *
0192:             * @exception StandardException		Thrown on error
0193:             */
0194:            public CostEstimate estimateCost(OptimizablePredicateList predList,
0195:                    ConglomerateDescriptor cd, CostEstimate outerCost,
0196:                    Optimizer optimizer, RowOrdering rowOrdering)
0197:                    throws StandardException {
0198:                costEstimate = getCostEstimate(optimizer);
0199:
0200:                /* Cost the VTI if it implements VTICosting.
0201:                 * Otherwise we use the defaults.
0202:                 * NOTE: We only cost the VTI once.
0203:                 */
0204:                if (implements VTICosting && !vtiCosted) {
0205:                    try {
0206:                        VTICosting vtic = (version2) ? (VTICosting) ps
0207:                                : (VTICosting) rs;
0208:                        estimatedCost = vtic
0209:                                .getEstimatedCostPerInstantiation(this );
0210:                        estimatedRowCount = vtic.getEstimatedRowCount(this );
0211:                        supportsMultipleInstantiations = vtic
0212:                                .supportsMultipleInstantiations(this );
0213:
0214:                        if (ps != null) {
0215:                            ps.close();
0216:                            ps = null;
0217:                        }
0218:                        if (rs != null) {
0219:                            rs.close();
0220:                            rs = null;
0221:                        }
0222:                    } catch (SQLException sqle) {
0223:                        throw StandardException.unexpectedUserException(sqle);
0224:                    }
0225:                    vtiCosted = true;
0226:                }
0227:
0228:                costEstimate.setCost(estimatedCost, estimatedRowCount,
0229:                        estimatedRowCount);
0230:
0231:                /*
0232:                 ** Let the join strategy decide whether the cost of the base
0233:                 ** scan is a single scan, or a scan per outer row.
0234:                 ** NOTE: The multiplication should only be done against the
0235:                 ** total row count, not the singleScanRowCount.
0236:                 ** RESOLVE - If the join strategy does not do materialization,
0237:                 ** the VTI does not support multiple instantiations and the
0238:                 ** outer row count is not exactly 1 row, then we need to change
0239:                 ** the costing formula to take into account the cost of creating
0240:                 ** the temp conglomerate, writing to it and reading from it
0241:                 ** outerCost.rowCount() - 1 times.
0242:                 */
0243:                if (getCurrentAccessPath().getJoinStrategy()
0244:                        .multiplyBaseCostByOuterRows()) {
0245:                    costEstimate.multiply(outerCost.rowCount(), costEstimate);
0246:                }
0247:
0248:                if (!optimized) {
0249:                    subqueryList.optimize(optimizer.getDataDictionary(),
0250:                            costEstimate.rowCount());
0251:                    subqueryList.modifyAccessPaths();
0252:                }
0253:
0254:                optimized = true;
0255:
0256:                return costEstimate;
0257:            }
0258:
0259:            /**
0260:             * @see Optimizable#legalJoinOrder
0261:             */
0262:            public boolean legalJoinOrder(JBitSet assignedTableMap) {
0263:                /* In order to tell if this is a legal join order, we
0264:                 * need to see if the assignedTableMap, ORed with the
0265:                 * outer tables that we are correlated with, contains
0266:                 * our dependency map.
0267:                 */
0268:                JBitSet tempBitSet = (JBitSet) assignedTableMap;
0269:                tempBitSet.or(correlationMap);
0270:
0271:                /* Have all of our dependencies been satisified? */
0272:                return tempBitSet.contains(dependencyMap);
0273:            }
0274:
0275:            /** @see Optimizable#isMaterializable 
0276:             *
0277:             */
0278:            public boolean isMaterializable() {
0279:                return materializable;
0280:            }
0281:
0282:            /** @see Optimizable#supportsMultipleInstantiations */
0283:            public boolean supportsMultipleInstantiations() {
0284:                return supportsMultipleInstantiations;
0285:            }
0286:
0287:            /**
0288:             * @see Optimizable#modifyAccessPath
0289:             *
0290:             * @exception StandardException		Thrown on error
0291:             */
0292:            public Optimizable modifyAccessPath(JBitSet outerTables)
0293:                    throws StandardException {
0294:                /* Close the rs if one was instantiated */
0295:                if (rs != null) {
0296:                    try {
0297:                        rs.close();
0298:                        rs = null;
0299:                    } catch (Throwable t) {
0300:                        throw StandardException.unexpectedUserException(t);
0301:                    }
0302:                }
0303:
0304:                return super .modifyAccessPath(outerTables);
0305:            }
0306:
0307:            public boolean pushOptPredicate(
0308:                    OptimizablePredicate optimizablePredicate)
0309:                    throws StandardException {
0310:                if (!implements Pushable)
0311:                    return false;
0312:
0313:                // Do not push down join predicates: those referencing more than one table.
0314:                if (!optimizablePredicate.getReferencedMap().hasSingleBitSet())
0315:                    return false;
0316:
0317:                if (restrictionList == null) {
0318:                    restrictionList = (PredicateList) getNodeFactory().getNode(
0319:                            C_NodeTypes.PREDICATE_LIST, getContextManager());
0320:                }
0321:
0322:                restrictionList.addPredicate((Predicate) optimizablePredicate);
0323:                return true;
0324:            }
0325:
0326:            /**
0327:             * Convert this object to a String.  See comments in QueryTreeNode.java
0328:             * for how this should be done for tree printing.
0329:             *
0330:             * @return	This object as a String
0331:             */
0332:
0333:            public String toString() {
0334:                if (SanityManager.DEBUG) {
0335:                    return "materializable: " + materializable + "\n"
0336:                            + super .toString();
0337:                } else {
0338:                    return "";
0339:                }
0340:            }
0341:
0342:            /**
0343:             * Prints the sub-nodes of this object.  See QueryTreeNode.java for
0344:             * how tree printing is supposed to work.
0345:             *
0346:             * @param depth		The depth of this node in the tree
0347:             */
0348:
0349:            public void printSubNodes(int depth) {
0350:                if (SanityManager.DEBUG) {
0351:                    super .printSubNodes(depth);
0352:
0353:                    if (newInvocation != null) {
0354:                        printLabel(depth, "newInvocation: ");
0355:                        newInvocation.treePrint(depth + 1);
0356:                    }
0357:
0358:                    if (exposedName != null) {
0359:                        printLabel(depth, "exposedName: ");
0360:                        exposedName.treePrint(depth + 1);
0361:                    }
0362:
0363:                    if (subqueryList != null) {
0364:                        printLabel(depth, "subqueryList: ");
0365:                        subqueryList.treePrint(depth + 1);
0366:                    }
0367:                }
0368:            }
0369:
0370:            /** 
0371:             * Return the new invocation from this node.
0372:             *
0373:             * @return ResultSetNode	The new invocation from this node.
0374:             */
0375:            public NewInvocationNode getNewInvocation() {
0376:                return newInvocation;
0377:            }
0378:
0379:            /**
0380:             * Get the exposed name for this table, which is the name that can
0381:             * be used to refer to it in the rest of the query.
0382:             *
0383:             * @return	The exposed name for this table.
0384:             */
0385:
0386:            public String getExposedName() {
0387:                return correlationName;
0388:            }
0389:
0390:            /**
0391:             * @return the table name used for matching with column references.
0392:             *
0393:             */
0394:            public TableName getExposedTableName() {
0395:                return exposedName;
0396:            }
0397:
0398:            /**
0399:             * Mark this VTI as the target of a delete or update.
0400:             */
0401:            void setTarget() {
0402:                isTarget = true;
0403:                version2 = true;
0404:            }
0405:
0406:            /**
0407:             * Bind the non VTI tables in this ResultSetNode.  This includes getting their
0408:             * descriptors from the data dictionary and numbering them.
0409:             *
0410:             * @param dataDictionary	The DataDictionary to use for binding
0411:             * @param fromListParam		FromList to use/append to.
0412:             *
0413:             * @return	ResultSetNode
0414:             *
0415:             * @exception StandardException		Thrown on error
0416:             */
0417:
0418:            public ResultSetNode bindNonVTITables(
0419:                    DataDictionary dataDictionary, FromList fromListParam)
0420:                    throws StandardException {
0421:
0422:                /* Assign the tableNumber.  (All other work done in bindVTITables() */
0423:                if (tableNumber == -1) // allow re-bind, in which case use old number
0424:                    tableNumber = getCompilerContext().getNextTableNumber();
0425:                return this ;
0426:            }
0427:
0428:            /**
0429:             * @return The name of the VTI, mainly for debugging and error messages.
0430:             */
0431:            String getVTIName() {
0432:                return newInvocation.getJavaClassName();
0433:            } // end of getVTIName
0434:
0435:            /**
0436:             * Bind this VTI that appears in the FROM list.
0437:             *
0438:             * @param fromListParam		FromList to use/append to.
0439:             *
0440:             * @return	ResultSetNode		The bound FromVTI.
0441:             *
0442:             * @exception StandardException		Thrown on error
0443:             */
0444:
0445:            public ResultSetNode bindVTITables(FromList fromListParam)
0446:                    throws StandardException {
0447:                ResultColumnList derivedRCL = resultColumns;
0448:
0449:                LanguageConnectionContext lcc = getLanguageConnectionContext();
0450:
0451:                /* NOTE - setting of table number moved to FromList.bindTables()
0452:                 * in order to avoid an ordering problem with join columns in
0453:                 * parameters.
0454:                 */
0455:
0456:                /* Bind the constructor - does basic error checking.
0457:                 * Correlated subqueries are not allowed as parameters to
0458:                 * a VTI, so pass an empty FromList.
0459:                 */
0460:                Vector aggregateVector = new Vector();
0461:                newInvocation.bindExpression(fromListParam, subqueryList,
0462:                        aggregateVector);
0463:
0464:                /* We have a valid constructor.  Does class implement the correct interface? 
0465:                 * If version2 is true, then it must implement PreparedStatement, otherwise
0466:                 * it can implement either PreparedStatement or ResultSet.  (We check for
0467:                 * PreparedStatement first.)
0468:                 */
0469:
0470:                if (!newInvocation.assignableTo("java.sql.PreparedStatement")) {
0471:                    if (version2) {
0472:                        throw StandardException.newException(
0473:                                SQLState.LANG_DOES_NOT_IMPLEMENT, getVTIName(),
0474:                                "java.sql.PreparedStatement");
0475:                    } else if (!newInvocation
0476:                            .assignableTo("java.sql.ResultSet")) {
0477:                        throw StandardException.newException(
0478:                                SQLState.LANG_DOES_NOT_IMPLEMENT, getVTIName(),
0479:                                "java.sql.ResultSet");
0480:                    }
0481:                } else {
0482:                    version2 = true;
0483:                }
0484:
0485:                /* If this is a version 2 VTI */
0486:                if (version2) {
0487:                    // Does it support predicates
0488:                    implements Pushable = newInvocation
0489:                            .assignableTo("org.apache.derby.vti.IQualifyable");
0490:                }
0491:
0492:                // Remember whether or not the VTI implements the VTICosting interface
0493:                implements VTICosting = newInvocation
0494:                        .assignableTo(ClassName.VTICosting);
0495:
0496:                // Is the parameter list to the constructor valid for a VTI?
0497:                methodParms = newInvocation.getMethodParms();
0498:
0499:                /* Build the RCL for this VTI.  We instantiate an object in order
0500:                 * to get the ResultSetMetaData.
0501:                 * 
0502:                 * If we have a special trigger vti, then we branch off and get
0503:                 * its rcl from the trigger table that is waiting for us in
0504:                 * the compiler context.
0505:                 */
0506:                UUID triggerTableId;
0507:                if ((triggerTableId = getSpecialTriggerVTITableName(lcc,
0508:                        newInvocation.getJavaClassName())) != null) {
0509:                    TableDescriptor td = getDataDictionary()
0510:                            .getTableDescriptor(triggerTableId);
0511:                    resultColumns = genResultColList(td);
0512:
0513:                    // costing info
0514:                    vtiCosted = true;
0515:                    estimatedCost = 50d;
0516:                    estimatedRowCount = 5d;
0517:                    supportsMultipleInstantiations = true;
0518:                } else {
0519:                    ResultSetMetaData rsmd = getResultSetMetaData();
0520:
0521:                    /* Wouldn't it be nice if we knew that the class/object would never
0522:                     * return a null ResultSetMetaData.
0523:                     */
0524:                    if (rsmd == null) {
0525:                        throw StandardException.newException(
0526:                                SQLState.LANG_NULL_RESULT_SET_META_DATA,
0527:                                getVTIName());
0528:                    }
0529:
0530:                    // Remember how many columns VTI returns for partial row calculation
0531:                    try {
0532:                        numVTICols = rsmd.getColumnCount();
0533:                    } catch (SQLException sqle) {
0534:                        numVTICols = 0;
0535:                    }
0536:
0537:                    try {
0538:                        for (int i = 1; i <= numVTICols; i++) {
0539:                            int columnType = rsmd.getColumnType(i);
0540:                            if (columnType == Types.BLOB
0541:                                    || columnType == Types.CLOB)
0542:                                throw StandardException
0543:                                        .newException(
0544:                                                SQLState.LANG_VTI_BLOB_CLOB_UNSUPPORTED,
0545:                                                getVTIName(), rsmd
0546:                                                        .getColumnName(i));
0547:                        }
0548:                    } catch (SQLException sqle) {
0549:                        throw StandardException.unexpectedUserException(sqle);
0550:                    }
0551:
0552:                    resultColumns = (ResultColumnList) getNodeFactory()
0553:                            .getNode(C_NodeTypes.RESULT_COLUMN_LIST,
0554:                                    getContextManager());
0555:                    resultColumns.createListFromResultSetMetaData(rsmd,
0556:                            exposedName, newInvocation.getJavaClassName());
0557:                }
0558:                numVTICols = resultColumns.size();
0559:
0560:                /* Propagate the name info from the derived column list */
0561:                if (derivedRCL != null) {
0562:                    resultColumns.propagateDCLInfo(derivedRCL, correlationName);
0563:                }
0564:
0565:                return this ;
0566:            }
0567:
0568:            /**
0569:             * Get the ResultSetMetaData for the class/object.  We first look for 
0570:             * the optional static method which has the same signature as the constructor.
0571:             * If it doesn't exist, then we instantiate an object and get the ResultSetMetaData
0572:             * from that object.
0573:             *
0574:             * @return The ResultSetMetaData from the class/object.
0575:             *
0576:             * @exception StandardException		Thrown on error
0577:             */
0578:            public ResultSetMetaData getResultSetMetaData()
0579:                    throws StandardException {
0580:                // Get the actual 
0581:                ResultSetMetaData rsmd = null;
0582:
0583:                try {
0584:                    if (version2) {
0585:                        ps = (PreparedStatement) getNewInstance();
0586:
0587:                        if (ps.getResultSetConcurrency() != JDBC20Translation.CONCUR_UPDATABLE) {
0588:                            throw StandardException
0589:                                    .newException(
0590:                                            SQLState.LANG_UPDATABLE_VTI_NON_UPDATABLE_RS,
0591:                                            getVTIName());
0592:                        }
0593:
0594:                        rsmd = ps.getMetaData();
0595:
0596:                        controlsDeferral = (ps instanceof  DeferModification);
0597:
0598:                        /* See if the result set is known to be insensitive or not.
0599:                         *
0600:                         * Some older VTI implementations do not implement getResultSetType(). UpdatableVTITemplate
0601:                         * does not implement it at all. UpdatableVTITemplate.getResultSetType throws an
0602:                         * exception. In either of these cases make the conservative assumption that the result set is sensitive.
0603:                         */
0604:                        try {
0605:                            resultSetType = ps.getResultSetType();
0606:                        } catch (SQLException sqle) {
0607:                        } catch (java.lang.AbstractMethodError ame) {
0608:                        } catch (java.lang.NoSuchMethodError nsme) {
0609:                        }
0610:                        isInsensitive = (resultSetType == ResultSet.TYPE_SCROLL_INSENSITIVE);
0611:
0612:                        if (!implements VTICosting) {
0613:                            ps.close();
0614:                            ps = null;
0615:                        }
0616:
0617:                    } else {
0618:                        rs = (ResultSet) getNewInstance();
0619:
0620:                        rsmd = rs.getMetaData();
0621:
0622:                        if (!implements VTICosting) {
0623:                            rs.close();
0624:                            rs = null;
0625:                        }
0626:                    }
0627:                } catch (Throwable t) {
0628:                    throw StandardException.unexpectedUserException(t);
0629:                }
0630:
0631:                return rsmd;
0632:            }
0633:
0634:            private Object getNewInstance() throws StandardException {
0635:                Class[] paramTypeClasses = newInvocation
0636:                        .getMethodParameterClasses();
0637:                Object[] paramObjects = null;
0638:
0639:                if (paramTypeClasses != null) {
0640:                    paramObjects = new Object[paramTypeClasses.length];
0641:
0642:                    for (int index = 0; index < paramTypeClasses.length; index++) {
0643:                        Class paramClass = paramTypeClasses[index];
0644:
0645:                        paramObjects[index] = methodParms[index]
0646:                                .getConstantValueAsObject();
0647:
0648:                        // As-per the JDBC spec SMALLINT and TINYINT map to java.lang.Integer
0649:                        // as objects. This means if getConstantValueAsObject() has returned an
0650:                        // Integer obejct in these cases, whereas Java method calling requires
0651:                        // Short or Byte object.
0652:                        if ((paramObjects[index] != null)
0653:                                && paramClass.isPrimitive()) {
0654:
0655:                            if (paramClass.equals(Short.TYPE)) {
0656:                                paramObjects[index] = new Short(
0657:                                        ((Integer) paramObjects[index])
0658:                                                .shortValue());
0659:                            } else if (paramClass.equals(Byte.TYPE)) {
0660:                                paramObjects[index] = new Byte(
0661:                                        ((Integer) paramObjects[index])
0662:                                                .byteValue());
0663:                            }
0664:                        }
0665:
0666:                        // Pass defaults for unknown primitive values
0667:                        if (paramObjects[index] == null
0668:                                && paramClass.isPrimitive()) {
0669:                            if (paramClass.equals(Integer.TYPE)) {
0670:                                paramObjects[index] = new Integer(0);
0671:                            } else if (paramClass.equals(Short.TYPE)) {
0672:                                paramObjects[index] = new Short((short) 0);
0673:                            } else if (paramClass.equals(Byte.TYPE)) {
0674:                                paramObjects[index] = new Byte((byte) 0);
0675:                            } else if (paramClass.equals(Long.TYPE)) {
0676:                                paramObjects[index] = new Long((long) 0);
0677:                            } else if (paramClass.equals(Float.TYPE)) {
0678:                                paramObjects[index] = new Float((float) 0);
0679:                            } else if (paramClass.equals(Double.TYPE)) {
0680:                                paramObjects[index] = new Double((double) 0);
0681:                            } else if (paramClass.equals(Boolean.TYPE)) {
0682:                                paramObjects[index] = Boolean.FALSE;
0683:                            } else if (paramClass.equals(Character.TYPE)) {
0684:                                paramObjects[index] = new Character(
0685:                                        Character.MIN_VALUE);
0686:                            }
0687:                        }
0688:                    }
0689:                } else {
0690:                    paramTypeClasses = new Class[0];
0691:                    paramObjects = new Object[0];
0692:                }
0693:
0694:                try {
0695:                    ClassInspector classInspector = getClassFactory()
0696:                            .getClassInspector();
0697:                    String javaClassName = newInvocation.getJavaClassName();
0698:                    Constructor constructor = classInspector.getClass(
0699:                            javaClassName).getConstructor(paramTypeClasses);
0700:
0701:                    return constructor.newInstance(paramObjects);
0702:                } catch (Throwable t) {
0703:                    if (t instanceof  InvocationTargetException) {
0704:                        InvocationTargetException ite = (InvocationTargetException) t;
0705:                        Throwable wrappedThrowable = ite.getTargetException();
0706:                        if (wrappedThrowable instanceof  StandardException)
0707:                            throw (StandardException) wrappedThrowable;
0708:                    }
0709:                    throw StandardException.unexpectedUserException(t);
0710:                }
0711:            } // end of getNewInstance
0712:
0713:            /**
0714:             * Get the DeferModification interface associated with this VTI
0715:             *
0716:             * @return null if the VTI uses the default modification deferral
0717:             */
0718:            public DeferModification getDeferralControl()
0719:                    throws StandardException {
0720:                if (!controlsDeferral)
0721:                    return null;
0722:                try {
0723:                    return (DeferModification) getNewInstance();
0724:                } catch (Throwable t) {
0725:                    throw StandardException.unexpectedUserException(t);
0726:                }
0727:            } // end of getDeferralControl
0728:
0729:            /**
0730:             * @return the ResultSet type of the VTI, TYPE_FORWARD_ONLY if the getResultSetType() method
0731:             *         of the VTI class throws an exception.
0732:             */
0733:            public int getResultSetType() {
0734:                return resultSetType;
0735:            }
0736:
0737:            /**
0738:             * Bind the expressions in this VTI.  This means 
0739:             * binding the sub-expressions, as well as figuring out what the return 
0740:             * type is for each expression.
0741:             *
0742:             *
0743:             * @exception StandardException		Thrown on error
0744:             */
0745:
0746:            public void bindExpressions(FromList fromListParam)
0747:                    throws StandardException {
0748:                ResultColumnList derivedRCL = resultColumns;
0749:
0750:                /* Figure out if the VTIs parameters are QUERY_INVARIANT.  If so,
0751:                 * then the VTI is a candidate for materialization at execution time
0752:                 * if it is the inner table of a join or in a subquery.
0753:                 */
0754:                materializable = newInvocation.areParametersQueryInvariant();
0755:
0756:                /* NOTE: We need to rebind any ColumnReferences that are parameters and are
0757:                 * from other VTIs that appear after this one in the FROM list.
0758:                 * These CRs will have uninitialized column and table numbers.
0759:                 */
0760:                Vector colRefs = getNodesFromParameters(ColumnReference.class);
0761:                Vector aggregateVector = null;
0762:                for (Enumeration e = colRefs.elements(); e.hasMoreElements();) {
0763:                    ColumnReference ref = (ColumnReference) e.nextElement();
0764:
0765:                    // Rebind the CR if the tableNumber is uninitialized
0766:                    if (ref.getTableNumber() == -1) {
0767:                        // we need a fake agg list
0768:                        if (aggregateVector == null) {
0769:                            aggregateVector = new Vector();
0770:                        }
0771:                        ref.bindExpression(fromListParam, subqueryList,
0772:                                aggregateVector);
0773:                    }
0774:                }
0775:            }
0776:
0777:            /**
0778:             * Get all of the nodes of the specified class
0779:             * from the parameters to this VTI.
0780:             *
0781:             * @param nodeClass	The Class of interest.
0782:             *
0783:             * @return A vector containing all of the nodes of interest.
0784:             *
0785:             * @exception StandardException		Thrown on error
0786:             */
0787:            Vector getNodesFromParameters(Class nodeClass)
0788:                    throws StandardException {
0789:                CollectNodesVisitor getCRs = new CollectNodesVisitor(nodeClass);
0790:                newInvocation.accept(getCRs);
0791:                return getCRs.getList();
0792:            }
0793:
0794:            /**
0795:             * Expand a "*" into a ResultColumnList with all of the
0796:             * result columns from the subquery.
0797:             * @exception StandardException		Thrown on error
0798:             */
0799:            public ResultColumnList getAllResultColumns(TableName allTableName)
0800:                    throws StandardException {
0801:                ResultColumnList rcList = null;
0802:                ResultColumn resultColumn;
0803:                ValueNode valueNode;
0804:                String columnName;
0805:                TableName toCompare;
0806:
0807:                if (allTableName != null)
0808:                    toCompare = makeTableName(allTableName.getSchemaName(),
0809:                            correlationName);
0810:                else
0811:                    toCompare = makeTableName(null, correlationName);
0812:
0813:                if (allTableName != null && !allTableName.equals(toCompare)) {
0814:                    return null;
0815:                }
0816:
0817:                rcList = (ResultColumnList) getNodeFactory().getNode(
0818:                        C_NodeTypes.RESULT_COLUMN_LIST, getContextManager());
0819:
0820:                /* Build a new result column list based off of resultColumns.
0821:                 * NOTE: This method will capture any column renaming due to 
0822:                 * a derived column list.
0823:                 */
0824:                int rclSize = resultColumns.size();
0825:                for (int index = 0; index < rclSize; index++) {
0826:                    resultColumn = (ResultColumn) resultColumns
0827:                            .elementAt(index);
0828:
0829:                    if (resultColumn.isGenerated()) {
0830:                        continue;
0831:                    }
0832:
0833:                    // Build a ResultColumn/ColumnReference pair for the column //
0834:                    columnName = resultColumn.getName();
0835:                    valueNode = (ValueNode) getNodeFactory().getNode(
0836:                            C_NodeTypes.COLUMN_REFERENCE, columnName,
0837:                            exposedName, getContextManager());
0838:                    resultColumn = (ResultColumn) getNodeFactory().getNode(
0839:                            C_NodeTypes.RESULT_COLUMN, columnName, valueNode,
0840:                            getContextManager());
0841:
0842:                    // Build the ResultColumnList to return //
0843:                    rcList.addResultColumn(resultColumn);
0844:                }
0845:                return rcList;
0846:            }
0847:
0848:            /**
0849:             * Try to find a ResultColumn in the table represented by this FromBaseTable
0850:             * that matches the name in the given ColumnReference.
0851:             *
0852:             * @param columnReference	The columnReference whose name we're looking
0853:             *				for in the given table.
0854:             *
0855:             * @return	A ResultColumn whose expression is the ColumnNode
0856:             *			that matches the ColumnReference.
0857:             *		Returns null if there is no match.
0858:             *
0859:             * @exception StandardException		Thrown on error
0860:             */
0861:
0862:            public ResultColumn getMatchingColumn(
0863:                    ColumnReference columnReference) throws StandardException {
0864:                /* We could get called before our RCL is built.  That's okay, we'll
0865:                 * just say that we don't match. 
0866:                 */
0867:                if (resultColumns == null) {
0868:                    return null;
0869:                }
0870:
0871:                ResultColumn resultColumn = null;
0872:                TableName columnsTableName;
0873:                TableName exposedTableName;
0874:
0875:                columnsTableName = columnReference.getTableNameNode();
0876:
0877:                /*
0878:                 ** If the column did not specify a name, or the specified name
0879:                 ** matches the table we're looking at, see whether the column
0880:                 ** is in this table.
0881:                 */
0882:                if (columnsTableName == null
0883:                        || columnsTableName.equals(exposedName)) {
0884:                    resultColumn = resultColumns
0885:                            .getResultColumn(columnReference.getColumnName());
0886:                    /* Did we find a match? */
0887:                    if (resultColumn != null) {
0888:                        columnReference.setTableNumber(tableNumber);
0889:                    }
0890:                }
0891:
0892:                return resultColumn;
0893:            }
0894:
0895:            /**
0896:             * Preprocess a ResultSetNode - this currently means:
0897:             *	o  Generating a referenced table map for each ResultSetNode.
0898:             *  o  Putting the WHERE and HAVING clauses in conjunctive normal form (CNF).
0899:             *  o  Converting the WHERE and HAVING clauses into PredicateLists and
0900:             *	   classifying them.
0901:             *  o  Ensuring that a ProjectRestrictNode is generated on top of every 
0902:             *     FromBaseTable and generated in place of every FromSubquery.  
0903:             *  o  Pushing single table predicates down to the new ProjectRestrictNodes.
0904:             *
0905:             * @param numTables			The number of tables in the DML Statement
0906:             * @param gbl				The group by list, if any
0907:             * @param fromList			The from list, if any
0908:             *
0909:             * @return ResultSetNode at top of preprocessed tree.
0910:             *
0911:             * @exception StandardException		Thrown on error
0912:             */
0913:
0914:            public ResultSetNode preprocess(int numTables, GroupByList gbl,
0915:                    FromList fromList) throws StandardException {
0916:                newInvocation
0917:                        .preprocess(numTables, (FromList) getNodeFactory()
0918:                                .getNode(
0919:                                        C_NodeTypes.FROM_LIST,
0920:                                        getNodeFactory()
0921:                                                .doJoinOrderOptimization(),
0922:                                        getContextManager()),
0923:                                (SubqueryList) getNodeFactory().getNode(
0924:                                        C_NodeTypes.SUBQUERY_LIST,
0925:                                        getContextManager()),
0926:                                (PredicateList) getNodeFactory().getNode(
0927:                                        C_NodeTypes.PREDICATE_LIST,
0928:                                        getContextManager()));
0929:                /* Generate the referenced table map */
0930:                referencedTableMap = new JBitSet(numTables);
0931:                referencedTableMap.set(tableNumber);
0932:                newInvocation.categorize(referencedTableMap, false);
0933:
0934:                // Create the dependency map
0935:                dependencyMap = new JBitSet(numTables);
0936:                for (int index = 0; index < numTables; index++) {
0937:                    if ((index != tableNumber) && referencedTableMap.get(index)) {
0938:                        dependencyMap.set(index);
0939:                    }
0940:                }
0941:
0942:                // Get a JBitSet of the outer tables represented in the parameter list
0943:                correlationMap = new JBitSet(numTables);
0944:                newInvocation.getCorrelationTables(correlationMap);
0945:
0946:                return genProjectRestrict(numTables);
0947:            }
0948:
0949:            /** 
0950:             * Put a ProjectRestrictNode on top of each FromTable in the FromList.
0951:             * ColumnReferences must continue to point to the same ResultColumn, so
0952:             * that ResultColumn must percolate up to the new PRN.  However,
0953:             * that ResultColumn will point to a new expression, a VirtualColumnNode, 
0954:             * which points to the FromTable and the ResultColumn that is the source for
0955:             * the ColumnReference.  
0956:             * (The new PRN will have the original of the ResultColumnList and
0957:             * the ResultColumns from that list.  The FromTable will get shallow copies
0958:             * of the ResultColumnList and its ResultColumns.  ResultColumn.expression
0959:             * will remain at the FromTable, with the PRN getting a new 
0960:             * VirtualColumnNode for each ResultColumn.expression.)
0961:             * We then project out the non-referenced columns.  If there are no referenced
0962:             * columns, then the PRN's ResultColumnList will consist of a single ResultColumn
0963:             * whose expression is 1.
0964:             *
0965:             * @param numTables			Number of tables in the DML Statement
0966:             *
0967:             * @return The generated ProjectRestrictNode atop the original FromTable.
0968:             *
0969:             * @exception StandardException		Thrown on error
0970:             */
0971:
0972:            protected ResultSetNode genProjectRestrict(int numTables)
0973:                    throws StandardException {
0974:                ResultColumnList prRCList;
0975:
0976:                /* We get a shallow copy of the ResultColumnList and its 
0977:                 * ResultColumns.  (Copy maintains ResultColumn.expression for now.)
0978:                 */
0979:                prRCList = resultColumns;
0980:                resultColumns = resultColumns.copyListAndObjects();
0981:
0982:                /* Replace ResultColumn.expression with new VirtualColumnNodes
0983:                 * in the ProjectRestrictNode's ResultColumnList.  (VirtualColumnNodes include
0984:                 * pointers to source ResultSetNode, this, and source ResultColumn.)
0985:                 * NOTE: We don't want to mark the underlying RCs as referenced, otherwise
0986:                 * we won't be able to project out any of them.
0987:                 */
0988:                prRCList.genVirtualColumnNodes(this , resultColumns, false);
0989:
0990:                /* Project out any unreferenced columns.  If there are no referenced 
0991:                 * columns, generate and bind a single ResultColumn whose expression is 1.
0992:                 */
0993:                prRCList.doProjection();
0994:
0995:                /* Finally, we create the new ProjectRestrictNode */
0996:                return (ResultSetNode) getNodeFactory().getNode(
0997:                        C_NodeTypes.PROJECT_RESTRICT_NODE, this , prRCList,
0998:                        null, /* Restriction */
0999:                        null, /* Restriction as PredicateList */
1000:                        null, /* Project subquery list */
1001:                        null, /* Restrict subquery list */
1002:                        tableProperties, getContextManager());
1003:            }
1004:
1005:            /**
1006:             * Return whether or not to materialize this ResultSet tree.
1007:             *
1008:             * @return Whether or not to materialize this ResultSet tree.
1009:             *			would return valid results.
1010:             *
1011:             * @exception StandardException		Thrown on error
1012:             */
1013:            public boolean performMaterialization(JBitSet outerTables)
1014:                    throws StandardException {
1015:                /* We need to materialize the VTI iff:
1016:                 *	o  It is an inner table.
1017:                 *	o  The VTI can be materialized.
1018:                 *	o  The VTI cannot be instantiated multiple times.
1019:                 *	o  The join strategy does not do materialization.
1020:                 * RESOLVE - We don't have to materialize if all of the
1021:                 * outer tables are 1 row tables.
1022:                 */
1023:                return (outerTables.getFirstSetBit() != -1
1024:                        && !outerTables.hasSingleBitSet() && // Not the outer table
1025:                        (!getTrulyTheBestAccessPath().getJoinStrategy()
1026:                                .doesMaterialization()) && // Join strategy does not do materialization
1027:                        isMaterializable() && // VTI can be materialized
1028:                !supportsMultipleInstantiations // VTI does not support multiple instantiations
1029:                );
1030:            }
1031:
1032:            /**
1033:             * Generation on a FromVTI creates a wrapper around
1034:             * the user's java.sql.ResultSet
1035:             *
1036:             * @param acb	The ActivationClassBuilder for the class being built
1037:             * @param mb The MethodBuilder for the execute() method to be built
1038:             *
1039:             * @exception StandardException		Thrown on error
1040:             */
1041:            public void generate(ActivationClassBuilder acb, MethodBuilder mb)
1042:                    throws StandardException {
1043:                /* NOTE: We need to remap any CRs within the parameters
1044:                 * so that we get their values from the right source
1045:                 * row.  For example, if a CR is a join column, we need
1046:                 * to get the value from the source table and not the
1047:                 * join row since the join row hasn't been filled in yet.
1048:                 */
1049:                RemapCRsVisitor rcrv = new RemapCRsVisitor(true);
1050:                newInvocation.accept(rcrv);
1051:
1052:                /* Get the next ResultSet #, so that we can number this ResultSetNode, its
1053:                 * ResultColumnList and ResultSet.
1054:                 */
1055:                assignResultSetNumber();
1056:
1057:                acb.pushGetResultSetFactoryExpression(mb);
1058:                int nargs = getScanArguments(acb, mb);
1059:                mb.callMethod(VMOpcode.INVOKEINTERFACE, (String) null,
1060:                        "getVTIResultSet", ClassName.NoPutResultSet, nargs);
1061:            }
1062:
1063:            private int getScanArguments(ActivationClassBuilder acb,
1064:                    MethodBuilder mb) throws StandardException {
1065:                int rclSize = resultColumns.size();
1066:                FormatableBitSet referencedCols = new FormatableBitSet(rclSize);
1067:                int erdNumber = -1;
1068:                int numSet = 0;
1069:
1070:                // Get our final cost estimate.
1071:                costEstimate = getFinalCostEstimate();
1072:
1073:                for (int index = 0; index < rclSize; index++) {
1074:                    ResultColumn rc = (ResultColumn) resultColumns
1075:                            .elementAt(index);
1076:                    if (rc.isReferenced()) {
1077:                        referencedCols.set(index);
1078:                        numSet++;
1079:                    }
1080:                }
1081:
1082:                // Only add referencedCols if not all columns are accessed
1083:                if (numSet != numVTICols) {
1084:                    erdNumber = acb.addItem(referencedCols);
1085:                }
1086:
1087:                // compileTimeConstants can be null
1088:                int ctcNumber = acb.addItem(compileTimeConstants);
1089:
1090:                acb.pushThisAsActivation(mb); // arg 1
1091:
1092:                // get a function to allocate scan rows of the right shape and size
1093:                resultColumns.generateHolder(acb, mb); // arg 2
1094:
1095:                // For a Version 2 VTI we never maintain the java.sql.PreparedStatement
1096:                // from compile time to execute time. This would rquire the PreparedStatement
1097:                // to be shareable across multiple connections, which is not the model for
1098:                // java.sql.PreparedStatement.
1099:
1100:                // For a Version 2 VTI we do pass onto the ResultSet the re-useability
1101:                // of the java.sql.PreparedStatement at runtime. The java.sql.PreparedStatement
1102:                // is re-uesable if
1103:                //
1104:                // o  No ? or ColumnReferences in parameters
1105:
1106:                boolean reuseablePs = version2
1107:                        && (getNodesFromParameters(ParameterNode.class).size() == 0)
1108:                        && (getNodesFromParameters(ColumnReference.class)
1109:                                .size() == 0);
1110:
1111:                mb.push(resultSetNumber); // arg 3
1112:
1113:                // The generated method for the constructor
1114:                generateConstructor(acb, mb, reuseablePs); // arg 4
1115:
1116:                // Pass in the class name
1117:                mb.push(newInvocation.getJavaClassName()); // arg 5
1118:
1119:                if (restrictionList != null) {
1120:                    restrictionList.generateQualifiers(acb, mb, this , true);
1121:                } else
1122:                    mb.pushNull(ClassName.Qualifier + "[][]");
1123:
1124:                // Pass in the erdNumber for the referenced column FormatableBitSet
1125:                mb.push(erdNumber); // arg 6
1126:
1127:                // Whether or not this is a version 2 VTI
1128:                mb.push(version2);
1129:
1130:                mb.push(reuseablePs);
1131:
1132:                mb.push(ctcNumber);
1133:
1134:                // Whether or not this is a target VTI
1135:                mb.push(isTarget);
1136:
1137:                // isolation level of the scan (if specified)
1138:                mb.push(getCompilerContext().getScanIsolationLevel());
1139:
1140:                // estimated row count
1141:                mb.push(costEstimate.rowCount());
1142:
1143:                // estimated cost
1144:                mb.push(costEstimate.getEstimatedCost());
1145:
1146:                return 14;
1147:            }
1148:
1149:            private void generateConstructor(ActivationClassBuilder acb,
1150:                    MethodBuilder mb, boolean reuseablePs)
1151:                    throws StandardException {
1152:
1153:                String vtiType = version2 ? "java.sql.PreparedStatement"
1154:                        : "java.sql.ResultSet";
1155:                // this sets up the method and the static field.
1156:                // generates:
1157:                // 	java.sql.ResultSet userExprFun { }
1158:                MethodBuilder userExprFun = acb.newGeneratedFun(vtiType,
1159:                        Modifier.PUBLIC);
1160:                userExprFun.addThrownException("java.lang.Exception");
1161:
1162:                // If it's a re-useable PreparedStatement then hold onto it.
1163:                LocalField psHolder = reuseablePs ? acb.newFieldDeclaration(
1164:                        Modifier.PRIVATE, "java.sql.PreparedStatement") : null;
1165:
1166:                if (reuseablePs) {
1167:
1168:                    userExprFun.getField(psHolder);
1169:                    userExprFun.conditionalIfNull();
1170:                }
1171:
1172:                newInvocation.generateExpression(acb, userExprFun);
1173:                userExprFun.upCast(vtiType);
1174:
1175:                if (reuseablePs) {
1176:
1177:                    userExprFun.putField(psHolder);
1178:
1179:                    userExprFun.startElseCode();
1180:
1181:                    userExprFun.getField(psHolder);
1182:
1183:                    userExprFun.completeConditional();
1184:                }
1185:
1186:                userExprFun.methodReturn();
1187:
1188:                // newInvocation knows it is returning its value;
1189:
1190:                /* generates:
1191:                 *    return <newInvocation.generate(acb)>;
1192:                 */
1193:                // we are done modifying userExprFun, complete it.
1194:                userExprFun.complete();
1195:
1196:                // constructor is used in the final result set as an access of the new static
1197:                // field holding a reference to this new method.
1198:                // generates:
1199:                //	ActivationClass.userExprFun
1200:                // which is the static field that "points" to the userExprFun
1201:                // that evaluates the where clause.
1202:                acb.pushMethodReference(mb, userExprFun);
1203:
1204:                // now add in code to close the reusable PreparedStatement when
1205:                // the activation is closed.
1206:                if (reuseablePs) {
1207:                    MethodBuilder closeActivationMethod = acb
1208:                            .getCloseActivationMethod();
1209:
1210:                    closeActivationMethod.getField(psHolder);
1211:                    closeActivationMethod.conditionalIfNull();
1212:                    // do nothing
1213:                    closeActivationMethod.push(0); // work around for no support for real if statements
1214:                    closeActivationMethod.startElseCode();
1215:                    closeActivationMethod.getField(psHolder);
1216:                    closeActivationMethod.callMethod(VMOpcode.INVOKEINTERFACE,
1217:                            "java.sql.Statement", "close", "void", 0);
1218:                    closeActivationMethod.push(0);
1219:
1220:                    closeActivationMethod.completeConditional();
1221:                    closeActivationMethod.endStatement();
1222:                }
1223:
1224:            }
1225:
1226:            /**
1227:             * Search to see if a query references the specifed table name.
1228:             *
1229:             * @param name		Table name (String) to search for.
1230:             * @param baseTable	Whether or not name is for a base table
1231:             *
1232:             * @return	true if found, else false
1233:             *
1234:             * @exception StandardException		Thrown on error
1235:             */
1236:            public boolean referencesTarget(String name, boolean baseTable)
1237:                    throws StandardException {
1238:                return (!baseTable)
1239:                        && name.equals(newInvocation.getJavaClassName());
1240:            }
1241:
1242:            /**
1243:             * Accept a visitor, and call v.visit()
1244:             * on child nodes as necessary.  
1245:             * 
1246:             * @param v the visitor
1247:             *
1248:             * @exception StandardException on error
1249:             */
1250:            public Visitable accept(Visitor v) throws StandardException {
1251:                if (v.skipChildren(this )) {
1252:                    return v.visit(this );
1253:                }
1254:
1255:                Visitable returnNode = super .accept(v);
1256:
1257:                if (!v.stopTraversal()) {
1258:                    newInvocation = (NewInvocationNode) newInvocation.accept(v);
1259:                }
1260:
1261:                return returnNode;
1262:            }
1263:
1264:            /**
1265:             * Check and see if we have a special trigger VTI.
1266:             * If it cannot be bound (because we aren't actually 
1267:             * compiling or executing a trigger), then throw 
1268:             * an exception.
1269:             * 
1270:             * @return null if not a special trigger vti, or the table
1271:             * id if it is
1272:             */
1273:            private UUID getSpecialTriggerVTITableName(
1274:                    LanguageConnectionContext lcc, String className)
1275:                    throws StandardException {
1276:                if (className.equals(ClassName.TriggerNewTransitionRows)
1277:                        || className.equals(ClassName.TriggerOldTransitionRows)) {
1278:                    // if there isn't an active trigger being compiled, error
1279:                    if (lcc.getTriggerTable() != null) {
1280:                        return lcc.getTriggerTable().getUUID();
1281:                    } else if (lcc.getTriggerExecutionContext() != null) {
1282:                        return lcc.getTriggerExecutionContext()
1283:                                .getTargetTableId();
1284:                    } else {
1285:                        throw StandardException.newException(
1286:                                SQLState.LANG_CANNOT_BIND_TRIGGER_V_T_I,
1287:                                className);
1288:                    }
1289:                }
1290:                return (UUID) null;
1291:            }
1292:
1293:            private ResultColumnList genResultColList(TableDescriptor td)
1294:                    throws StandardException {
1295:                ResultColumnList rcList = null;
1296:                ResultColumn resultColumn;
1297:                ValueNode valueNode;
1298:                ColumnDescriptor colDesc = null;
1299:
1300:                TableName tableName = makeTableName(td.getSchemaName(), td
1301:                        .getName());
1302:
1303:                /* Add all of the columns in the table */
1304:                rcList = (ResultColumnList) getNodeFactory().getNode(
1305:                        C_NodeTypes.RESULT_COLUMN_LIST, getContextManager());
1306:                ColumnDescriptorList cdl = td.getColumnDescriptorList();
1307:                int cdlSize = cdl.size();
1308:
1309:                for (int index = 0; index < cdlSize; index++) {
1310:                    /* Build a ResultColumn/BaseColumnNode pair for the column */
1311:                    colDesc = (ColumnDescriptor) cdl.elementAt(index);
1312:
1313:                    valueNode = (ValueNode) getNodeFactory().getNode(
1314:                            C_NodeTypes.BASE_COLUMN_NODE,
1315:                            colDesc.getColumnName(), exposedName,
1316:                            colDesc.getType(), getContextManager());
1317:                    resultColumn = (ResultColumn) getNodeFactory().getNode(
1318:                            C_NodeTypes.RESULT_COLUMN, colDesc, valueNode,
1319:                            getContextManager());
1320:
1321:                    /* Build the ResultColumnList to return */
1322:                    rcList.addResultColumn(resultColumn);
1323:                }
1324:
1325:                return rcList;
1326:            }
1327:
1328:            public boolean needsSpecialRCLBinding() {
1329:                return true;
1330:            }
1331:
1332:            boolean isUpdatableCursor() throws StandardException {
1333:                return true;
1334:            }
1335:
1336:            protected void markUpdatableByCursor(Vector updateColumns) {
1337:                super .markUpdatableByCursor(updateColumns);
1338:                forUpdatePresent = true;
1339:                emptyForUpdate = ((updateColumns == null) || (updateColumns
1340:                        .size() == 0));
1341:            }
1342:
1343:            private int[] getForUpdateColumnList() {
1344:
1345:                int[] tempList = new int[getNumColumnsReturned()];
1346:                int offset = 0;
1347:
1348:                for (int col = 0; col < tempList.length; col++) {
1349:                    if (resultColumns.updatableByCursor(col))
1350:                        tempList[offset++] = col + 1; // JDBC id
1351:                }
1352:
1353:                int[] list;
1354:
1355:                if (offset == tempList.length)
1356:                    list = tempList;
1357:                else {
1358:                    list = new int[offset];
1359:                    System.arraycopy(tempList, 0, list, 0, offset);
1360:                }
1361:
1362:                return list;
1363:            }
1364:
1365:            /*
1366:             ** VTIEnvironment
1367:             */
1368:            public final boolean isCompileTime() {
1369:                return true;
1370:            }
1371:
1372:            public String getOriginalSQL() {
1373:                return getCompilerContext().getParser().getSQLtext();
1374:            }
1375:
1376:            public final int getStatementIsolationLevel() {
1377:                return ExecutionContext.CS_TO_JDBC_ISOLATION_LEVEL_MAP[getCompilerContext()
1378:                        .getScanIsolationLevel()];
1379:            }
1380:
1381:            public void setSharedState(String key, java.io.Serializable value) {
1382:
1383:                if (key == null)
1384:                    return;
1385:
1386:                if (compileTimeConstants == null)
1387:                    compileTimeConstants = new FormatableHashtable();
1388:
1389:                compileTimeConstants.put(key, value);
1390:            }
1391:
1392:            public Object getSharedState(String key) {
1393:                if ((key == null) || (compileTimeConstants == null))
1394:                    return null;
1395:
1396:                return compileTimeConstants.get(key);
1397:            }
1398:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.