Source Code Cross Referenced for BaseActivation.java in  » Database-DBMS » db-derby-10.2 » org » apache » derby » impl » sql » execute » 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.execute 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:
0003:           Derby - Class org.apache.derby.impl.sql.execute.BaseActivation
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.execute;
0023:
0024:        import org.apache.derby.iapi.services.context.ContextManager;
0025:        import org.apache.derby.iapi.services.context.Context;
0026:
0027:        import org.apache.derby.iapi.jdbc.ConnectionContext;
0028:
0029:        import org.apache.derby.iapi.sql.Activation;
0030:
0031:        import org.apache.derby.iapi.sql.execute.CursorResultSet;
0032:        import org.apache.derby.iapi.sql.execute.ExecPreparedStatement;
0033:        import org.apache.derby.iapi.sql.execute.CursorActivation;
0034:        import org.apache.derby.iapi.sql.ResultSet;
0035:        import org.apache.derby.iapi.sql.execute.ExecRow;
0036:        import org.apache.derby.iapi.sql.execute.NoPutResultSet;
0037:        import org.apache.derby.iapi.sql.ParameterValueSet;
0038:        import org.apache.derby.iapi.sql.ResultDescription;
0039:
0040:        import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
0041:
0042:        import org.apache.derby.iapi.reference.SQLState;
0043:        import org.apache.derby.iapi.error.StandardException;
0044:
0045:        import org.apache.derby.iapi.sql.execute.ExecutionContext;
0046:        import org.apache.derby.iapi.sql.execute.ExecutionFactory;
0047:        import org.apache.derby.iapi.sql.execute.ResultSetFactory;
0048:        import org.apache.derby.iapi.sql.execute.ConstantAction;
0049:
0050:        import org.apache.derby.iapi.types.DataValueFactory;
0051:        import org.apache.derby.iapi.types.DataValueDescriptor;
0052:        import org.apache.derby.iapi.types.NumberDataValue;
0053:        import org.apache.derby.iapi.types.RowLocation;
0054:
0055:        import org.apache.derby.iapi.sql.dictionary.IndexRowGenerator;
0056:        import org.apache.derby.iapi.sql.dictionary.DataDescriptorGenerator;
0057:        import org.apache.derby.iapi.sql.dictionary.DataDictionaryContext;
0058:        import org.apache.derby.iapi.sql.dictionary.TableDescriptor;
0059:
0060:        import org.apache.derby.iapi.sql.depend.DependencyManager;
0061:
0062:        import org.apache.derby.iapi.store.access.Qualifier;
0063:        import org.apache.derby.iapi.store.access.ConglomerateController;
0064:        import org.apache.derby.iapi.store.access.ScanController;
0065:        import org.apache.derby.iapi.store.access.TransactionController;
0066:        import org.apache.derby.iapi.types.DataTypeDescriptor;
0067:
0068:        import org.apache.derby.iapi.services.sanity.SanityManager;
0069:
0070:        import org.apache.derby.iapi.services.context.ContextService;
0071:
0072:        import org.apache.derby.iapi.services.loader.GeneratedClass;
0073:        import org.apache.derby.iapi.services.loader.GeneratedByteCode;
0074:        import org.apache.derby.iapi.services.loader.GeneratedMethod;
0075:
0076:        import org.apache.derby.iapi.services.loader.ClassFactory;
0077:        import org.apache.derby.iapi.services.monitor.Monitor;
0078:
0079:        import org.apache.derby.iapi.services.property.PropertyUtil;
0080:        import org.apache.derby.iapi.sql.compile.Optimizer;
0081:
0082:        import org.apache.derby.iapi.reference.Property;
0083:        import org.apache.derby.iapi.services.io.FormatableBitSet;
0084:
0085:        import org.apache.derby.iapi.sql.execute.RunTimeStatistics;
0086:
0087:        import java.sql.Connection;
0088:        import java.sql.SQLException;
0089:        import java.sql.SQLWarning;
0090:
0091:        import java.util.ArrayList;
0092:        import java.util.Enumeration;
0093:        import java.util.Vector;
0094:        import java.util.Hashtable;
0095:        import java.util.HashSet;
0096:        import org.apache.derby.iapi.util.ReuseFactory;
0097:        import org.apache.derby.iapi.sql.execute.TemporaryRowHolder;
0098:
0099:        /**
0100:         * BaseActivation
0101:         * provides the fundamental support we expect all activations to have.
0102:         * Doesn't actually implement any of the activation interface,
0103:         * expects the subclasses to do that.
0104:         */
0105:        public abstract class BaseActivation implements  CursorActivation,
0106:                GeneratedByteCode
0107:
0108:        {
0109:
0110:            protected ResultSetFactory rsFactory;
0111:            protected ExecutionFactory exFactory;
0112:            protected DataValueFactory dvFactory;
0113:            protected LanguageConnectionContext lcc;
0114:            protected ContextManager cm;
0115:            protected/*private*/ExecutionContext ec;
0116:
0117:            protected ExecPreparedStatement preStmt;
0118:            protected ResultSet resultSet;
0119:            protected ResultDescription resultDescription;
0120:            protected boolean closed;
0121:            private String cursorName;
0122:
0123:            protected int numSubqueries;
0124:
0125:            private boolean singleExecution;
0126:
0127:            // This flag is declared volatile to ensure it is 
0128:            // visible when it has been modified by the finalizer thread.
0129:            private volatile boolean inUse;
0130:
0131:            private java.sql.ResultSet targetVTI;
0132:            private SQLWarning warnings;
0133:
0134:            private GeneratedClass gc; // my Generated class object.
0135:
0136:            private boolean checkRowCounts;
0137:            private HashSet rowCountsCheckedThisExecution = new HashSet(4, 0.9f);
0138:
0139:            private static final long MAX_SQRT = (long) Math
0140:                    .sqrt(Long.MAX_VALUE);
0141:
0142:            // When the row count exceeds this number, we should recompile if
0143:            // the difference in row counts is greater than 10%.  If it's less
0144:            // than this number, we use an entirely different technique to check
0145:            // for recompilation.  See comments below, in informOfRowCount()
0146:            private static final int TEN_PERCENT_THRESHOLD = 400;
0147:
0148:            /* Performance optimization for update/delete - only
0149:             * open heap ConglomerateController once when doing
0150:             * index row to base row on search
0151:             */
0152:            private ConglomerateController updateHeapCC;
0153:            private ScanController indexSC;
0154:            private long indexConglomerateNumber = -1;
0155:
0156:            private TableDescriptor ddlTableDescriptor;
0157:
0158:            private int maxRows = -1;
0159:            private boolean forCreateTable;
0160:
0161:            private boolean scrollable;
0162:
0163:            private boolean resultSetHoldability;
0164:
0165:            //beetle 3865: updateable cursor using index.  A way of communication
0166:            //between cursor activation and update activation.
0167:            private CursorResultSet forUpdateIndexScan;
0168:
0169:            //Following three are used for JDBC3.0 auto-generated keys feature.
0170:            //autoGeneratedKeysResultSetMode will be set true if at the time of statement execution,
0171:            //either Statement.RETURN_GENERATED_KEYS was passed or an array of (column positions or
0172:            //column names) was passed
0173:            private boolean autoGeneratedKeysResultSetMode;
0174:            private int[] autoGeneratedKeysColumnIndexes;
0175:            private String[] autoGeneratedKeysColumnNames;
0176:
0177:            //Following is the position of the session table names list in savedObjects in compiler context
0178:            //This is updated to be the correct value at cursor generate time if the cursor references any session table names.
0179:            //If the cursor does not reference any session table names, this will stay negative
0180:            protected int indexOfSessionTableNamesInSavedObjects = -1;
0181:
0182:            // WARNING: these fields are accessed by code generated in the 
0183:            // ExpressionClassBuilder: don't change them unless you 
0184:            // make the appropriate changes there.
0185:            protected ExecRow[] row;
0186:            protected ParameterValueSet pvs;
0187:
0188:            //
0189:            // constructors
0190:            //
0191:
0192:            protected BaseActivation() {
0193:                super ();
0194:            }
0195:
0196:            public final void initFromContext(Context context)
0197:                    throws StandardException {
0198:
0199:                if (SanityManager.DEBUG) {
0200:                    SanityManager
0201:                            .ASSERT(context != null,
0202:                                    "NULL context passed to BaseActivation.initFromContext");
0203:                }
0204:                this .cm = context.getContextManager();
0205:
0206:                lcc = (LanguageConnectionContext) cm
0207:                        .getContext(LanguageConnectionContext.CONTEXT_ID);
0208:
0209:                if (SanityManager.DEBUG) {
0210:                    if (lcc == null)
0211:                        SanityManager
0212:                                .THROWASSERT("lcc is null in activation type "
0213:                                        + getClass());
0214:                }
0215:
0216:                dvFactory = lcc.getDataValueFactory();
0217:                if (SanityManager.DEBUG) {
0218:                    SanityManager.ASSERT(dvFactory != null,
0219:                            "No data value factory in getDataValueFactory");
0220:                }
0221:
0222:                ec = lcc.getExecutionContext();
0223:
0224:                // look for the execution context and
0225:                // get our result set factory from it.
0226:                rsFactory = ec.getResultSetFactory();
0227:                if (SanityManager.DEBUG) {
0228:                    SanityManager.ASSERT(rsFactory != null,
0229:                            "Unable to find ResultSetFactory");
0230:                }
0231:
0232:                exFactory = ec.getExecutionFactory();
0233:                if (SanityManager.DEBUG) {
0234:                    SanityManager.ASSERT(exFactory != null,
0235:                            "Unable to find ExecutionFactory");
0236:                }
0237:
0238:                // mark in use
0239:                inUse = true;
0240:
0241:                // add this activation to the pool for the connection.
0242:                lcc.addActivation(this );
0243:            }
0244:
0245:            //
0246:            // Activation interface
0247:            //
0248:
0249:            public final ExecPreparedStatement getPreparedStatement() {
0250:                return preStmt;
0251:            }
0252:
0253:            public ConstantAction getConstantAction() {
0254:                return preStmt.getConstantAction();
0255:            }
0256:
0257:            public final void checkStatementValidity() throws StandardException {
0258:
0259:                if (preStmt == null)
0260:                    return;
0261:
0262:                synchronized (preStmt) {
0263:
0264:                    if ((gc == preStmt.getActivationClass())
0265:                            && preStmt.upToDate())
0266:                        return;
0267:                }
0268:
0269:                StandardException se = StandardException
0270:                        .newException(SQLState.LANG_STATEMENT_NEEDS_RECOMPILE);
0271:                se.setReport(StandardException.REPORT_NEVER);
0272:                throw se;
0273:            }
0274:
0275:            /**
0276:            	Link this activation with its PreparedStatement.
0277:            	It can be called with null to break the link with the
0278:            	PreparedStatement.
0279:
0280:             */
0281:            public final void setupActivation(ExecPreparedStatement ps,
0282:                    boolean scrollable) {
0283:                preStmt = ps;
0284:
0285:                if (ps != null) {
0286:                    // get the result set description
0287:                    resultDescription = ps.getResultDescription();
0288:                    this .scrollable = scrollable;
0289:
0290:                    // Initialize the parameter set to have allocated
0291:                    // DataValueDescriptor objects for each parameter.
0292:                    if (pvs != null && pvs.getParameterCount() != 0)
0293:                        pvs.initialize(ps.getParameterTypes());
0294:
0295:                } else {
0296:                    resultDescription = null;
0297:                    this .scrollable = false;
0298:                }
0299:            }
0300:
0301:            public ResultSet getResultSet() {
0302:                return resultSet;
0303:            }
0304:
0305:            public void clearResultSet() {
0306:                resultSet = null;
0307:            }
0308:
0309:            /**
0310:            	Get the saved RowLocation.
0311:
0312:            	@param itemNumber	The saved item number.
0313:
0314:            	@return	A RowLocation template for the conglomerate
0315:             */
0316:            public RowLocation getRowLocationTemplate(int itemNumber) {
0317:                if (SanityManager.DEBUG) {
0318:                    SanityManager.ASSERT(itemNumber >= 0,
0319:                            "itemNumber expected to be >= 0");
0320:                    if (!(getPreparedStatement().getSavedObject(itemNumber) instanceof  RowLocation)) {
0321:                        SanityManager
0322:                                .THROWASSERT("getPreparedStatement().getSavedObject(itemNumber) expected to be "
0323:                                        + "instance of RowLocation, not "
0324:                                        + getPreparedStatement()
0325:                                                .getSavedObject(itemNumber)
0326:                                                .getClass().getName()
0327:                                        + ", query is "
0328:                                        + getPreparedStatement().getSource());
0329:                    }
0330:                    RowLocation rl = (RowLocation) getPreparedStatement()
0331:                            .getSavedObject(itemNumber);
0332:                    if (!(rl.cloneObject() instanceof  RowLocation)) {
0333:                        SanityManager
0334:                                .THROWASSERT("rl.cloneObject() expected to be "
0335:                                        + "instance of RowLocation, not "
0336:                                        + rl.getClass().getName()
0337:                                        + ", query is "
0338:                                        + getPreparedStatement().getSource());
0339:                    }
0340:                }
0341:                /* We have to return a clone of the saved RowLocation due
0342:                 * to the shared cache of SPSs.
0343:                 */
0344:                return (RowLocation) ((RowLocation) (getPreparedStatement()
0345:                        .getSavedObject(itemNumber))).cloneObject();
0346:            }
0347:
0348:            /*
0349:             */
0350:            public ResultDescription getResultDescription() {
0351:                if (SanityManager.DEBUG)
0352:                    SanityManager.ASSERT(resultDescription != null,
0353:                            "Must have a result description");
0354:                return resultDescription;
0355:            }
0356:
0357:            /**
0358:            	This is a partial implementation of reset.
0359:            	Subclasses will want to reset information
0360:            	they are aware of, such as parameters.
0361:            	<p>
0362:            	All subclasses must call super.reset() and
0363:            	then do their cleanup.
0364:            	<p>
0365:            	The execute call must set the resultSet field
0366:            	to be the resultSet that it has returned.
0367:
0368:            	@exception StandardException on error
0369:             */
0370:            public void reset() throws StandardException {
0371:                // if resultset holdability after commit is false, close it
0372:                if (resultSet != null) {
0373:                    if (!resultSetHoldability || !resultSet.returnsRows()) {
0374:                        // would really like to check if it is open,
0375:                        // this is as close as we can approximate that.
0376:                        resultSet.close();
0377:                        resultSet = null; // forget about it, prepare for next exec.
0378:                    } else if (resultSet.returnsRows()) {
0379:                        resultSet.clearCurrentRow();
0380:                    }
0381:                }
0382:                updateHeapCC = null;
0383:                // REMIND: do we need to get them to stop input as well?
0384:
0385:                if (!isSingleExecution())
0386:                    clearWarnings();
0387:            }
0388:
0389:            /**
0390:            	Closing an activation marks it as unusable. Any other
0391:            	requests made on it will fail.  An activation should be
0392:            	marked closed when it is expected to not be used any longer,
0393:            	i.e. when the connection for it is closed, or it has suffered some
0394:            	sort of severe error.
0395:
0396:            	This should also remove it from the language connection context.
0397:
0398:            	@exception StandardException on error
0399:             */
0400:            public final void close() throws StandardException {
0401:                if (!closed) {
0402:
0403:                    // markUnused();
0404:
0405:                    // we finish the result set before we call reset
0406:                    // because reset will set it to null.
0407:                    if (resultSet != null) {
0408:                        resultSet.finish();
0409:                        resultSet = null;
0410:                    }
0411:
0412:                    // we call reset so that if the actual type of "this"
0413:                    // is a subclass of BaseActivation, its cleanup will
0414:                    // also happen -- reset in the actual type is called,
0415:                    // not reset in BaseActivation.  Subclass reset's
0416:                    // are supposed to call super.reset() as well.
0417:                    reset(); // get everything related to executing released
0418:
0419:                    closed = true;
0420:
0421:                    LanguageConnectionContext lcc = getLanguageConnectionContext();
0422:
0423:                    lcc.removeActivation(this );
0424:                    if (preStmt != null) {
0425:                        preStmt.finish(lcc);
0426:                        preStmt = null;
0427:                    }
0428:
0429:                    try {
0430:                        closeActivationAction();
0431:                    } catch (Throwable e) {
0432:                        throw StandardException.plainWrapException(e);
0433:                    }
0434:
0435:                }
0436:
0437:            }
0438:
0439:            /**
0440:            	A generated class can create its own closeActivationAction
0441:            	method to invoke special logic when the activation is closed.
0442:             */
0443:            protected void closeActivationAction() throws Exception {
0444:                // no code to be added here as generated code
0445:                // will not call super.closeActivationAction()
0446:            }
0447:
0448:            /**
0449:            	Find out if the activation closed or not.
0450:            	@return true if the prepared statement has been closed.
0451:             */
0452:            public boolean isClosed() {
0453:                return closed;
0454:            }
0455:
0456:            /**
0457:            	Set this Activation for a single execution.
0458:
0459:            	@see Activation#setSingleExecution
0460:             */
0461:            public void setSingleExecution() {
0462:                singleExecution = true;
0463:            }
0464:
0465:            /**
0466:            	Returns true if this Activation is only going to be used for
0467:            	one execution.
0468:
0469:            	@see Activation#isSingleExecution
0470:             */
0471:            public boolean isSingleExecution() {
0472:                return singleExecution;
0473:            }
0474:
0475:            /**
0476:            	Get the number of subqueries in the entire query.
0477:            	@return int	 The number of subqueries in the entire query.
0478:             */
0479:            public int getNumSubqueries() {
0480:                return numSubqueries;
0481:            }
0482:
0483:            /**
0484:             * @see Activation#isCursorActivation
0485:             */
0486:            public boolean isCursorActivation() {
0487:                return false;
0488:            }
0489:
0490:            //
0491:            // GeneratedByteCode interface
0492:            //
0493:
0494:            public final void setGC(GeneratedClass gc) {
0495:                this .gc = gc;
0496:            }
0497:
0498:            public final GeneratedClass getGC() {
0499:
0500:                if (SanityManager.DEBUG) {
0501:                    if (gc == null)
0502:                        SanityManager
0503:                                .THROWASSERT("move code requiring GC to postConstructor() method!!");
0504:                }
0505:                return gc;
0506:            }
0507:
0508:            public final GeneratedMethod getMethod(String methodName)
0509:                    throws StandardException {
0510:
0511:                return getGC().getMethod(methodName);
0512:            }
0513:
0514:            public Object e0() throws StandardException {
0515:                return null;
0516:            }
0517:
0518:            public Object e1() throws StandardException {
0519:                return null;
0520:            }
0521:
0522:            public Object e2() throws StandardException {
0523:                return null;
0524:            }
0525:
0526:            public Object e3() throws StandardException {
0527:                return null;
0528:            }
0529:
0530:            public Object e4() throws StandardException {
0531:                return null;
0532:            }
0533:
0534:            public Object e5() throws StandardException {
0535:                return null;
0536:            }
0537:
0538:            public Object e6() throws StandardException {
0539:                return null;
0540:            }
0541:
0542:            public Object e7() throws StandardException {
0543:                return null;
0544:            }
0545:
0546:            public Object e8() throws StandardException {
0547:                return null;
0548:            }
0549:
0550:            public Object e9() throws StandardException {
0551:                return null;
0552:            }
0553:
0554:            //
0555:            // class interface
0556:            //
0557:
0558:            /**
0559:             * Temporary tables can be declared with ON COMMIT DELETE ROWS. But if the table has a held curosr open at
0560:             * commit time, data should not be deleted from the table. This method, (gets called at commit time) checks if this
0561:             * activation held cursor and if so, does that cursor reference the passed temp table name.
0562:             *
0563:             * @return	true if this activation has held cursor and if it references the passed temp table name
0564:             */
0565:            public boolean checkIfThisActivationHasHoldCursor(String tableName) {
0566:                if (!inUse)
0567:                    return false;
0568:
0569:                if (resultSetHoldability == false) //if this activation is not held over commit, do not need to worry about it
0570:                    return false;
0571:
0572:                if (indexOfSessionTableNamesInSavedObjects == -1) //if this activation does not refer to session schema tables, do not need to worry about it
0573:                    return false;
0574:
0575:                /* is there an open result set? */
0576:                if ((resultSet != null) && !resultSet.isClosed()
0577:                        && resultSet.returnsRows()) {
0578:                    //If we came here, it means this activation is held over commit and it reference session table names
0579:                    //Now let's check if it referneces the passed temporary table name which has ON COMMIT DELETE ROWS defined on it.
0580:                    return ((ArrayList) getPreparedStatement().getSavedObject(
0581:                            indexOfSessionTableNamesInSavedObjects))
0582:                            .contains(tableName);
0583:                }
0584:
0585:                return false;
0586:            }
0587:
0588:            /**
0589:               remember the cursor name
0590:             */
0591:
0592:            public void setCursorName(String cursorName) {
0593:                if (isCursorActivation())
0594:                    this .cursorName = cursorName;
0595:            }
0596:
0597:            /**
0598:              get the cursor name.  For something that isn't
0599:              a cursor, this is used as a string name of the
0600:              result set for messages from things like the
0601:              dependency manager.
0602:              <p>
0603:              Activations that do support cursors will override
0604:              this.	
0605:             */
0606:            public String getCursorName() {
0607:
0608:                return isCursorActivation() ? cursorName : null;
0609:            }
0610:
0611:            public void setResultSetHoldability(boolean resultSetHoldability) {
0612:                this .resultSetHoldability = resultSetHoldability;
0613:            }
0614:
0615:            public boolean getResultSetHoldability() {
0616:                return resultSetHoldability;
0617:            }
0618:
0619:            /** @see Activation#setAutoGeneratedKeysResultsetInfo */
0620:            public void setAutoGeneratedKeysResultsetInfo(int[] columnIndexes,
0621:                    String[] columnNames) {
0622:                autoGeneratedKeysResultSetMode = true;
0623:                autoGeneratedKeysColumnIndexes = columnIndexes;
0624:                autoGeneratedKeysColumnNames = columnNames;
0625:            }
0626:
0627:            /** @see Activation#getAutoGeneratedKeysResultsetMode */
0628:            public boolean getAutoGeneratedKeysResultsetMode() {
0629:                return autoGeneratedKeysResultSetMode;
0630:            }
0631:
0632:            /** @see Activation#getAutoGeneratedKeysColumnIndexes */
0633:            public int[] getAutoGeneratedKeysColumnIndexes() {
0634:                return autoGeneratedKeysColumnIndexes;
0635:            }
0636:
0637:            /** @see Activation#getAutoGeneratedKeysColumnNames */
0638:            public String[] getAutoGeneratedKeysColumnNames() {
0639:                return autoGeneratedKeysColumnNames;
0640:            }
0641:
0642:            //
0643:            // class implementation
0644:            //
0645:
0646:            /**
0647:            	Used in the execute method of activations for
0648:            	generating the result sets that they concatenate together.
0649:             */
0650:            public ResultSetFactory getResultSetFactory() {
0651:                return rsFactory;
0652:            }
0653:
0654:            /**
0655:            	Used in activations for generating rows.
0656:             */
0657:            public ExecutionFactory getExecutionFactory() {
0658:                return exFactory;
0659:            }
0660:
0661:            /**
0662:            	Used in CurrentOfResultSet to get to the target result set
0663:            	for a cursor. Overridden by activations generated for
0664:            	updatable cursors.  Those activations capture the target
0665:            	result set in a field in their execute() method, and then
0666:            	return the value of that field in their version of this method.
0667:
0668:            	@return null.
0669:             */
0670:            public CursorResultSet getTargetResultSet() {
0671:                if (SanityManager.DEBUG)
0672:                    SanityManager.THROWASSERT("Must be overridden to be used.");
0673:                return null;
0674:            }
0675:
0676:            /*
0677:             * Called by generated code to compute the next autoincrement value.
0678:             * 
0679:             * @return The next autoincrement value which should be inserted.
0680:             * returns the correct number datatype.
0681:             */
0682:            protected DataValueDescriptor getSetAutoincrementValue(
0683:                    int columnPosition, long increment)
0684:                    throws StandardException {
0685:                DataValueDescriptor l = ((InsertResultSet) resultSet)
0686:                        .getSetAutoincrementValue(columnPosition, increment);
0687:                return l;
0688:
0689:            }
0690:
0691:            /**
0692:            	Used in CurrentOfResultSet to get to the cursor result set
0693:            	for a cursor.  Overridden by activations generated for
0694:            	updatable cursors.  Those activations capture the cursor
0695:            	result set in a field in their execute() method, and then
0696:            	return the value of that field in their version of this method.
0697:
0698:            	@return null
0699:             */
0700:            public CursorResultSet getCursorResultSet() {
0701:                if (SanityManager.DEBUG)
0702:                    SanityManager.THROWASSERT("Must be overridden to be used.");
0703:                return null;
0704:            }
0705:
0706:            /**
0707:            	Various activation methods need to disallow their
0708:            	invocation if the activation is closed. This lets them
0709:            	check and throw without generating alot of code.
0710:            	<p>
0711:            	The code to write to generate the call to this is approximately:
0712:            	<verbatim>
0713:            		// jf is a JavaFactory
0714:            		CallableExpression ce = jf.newMethodCall(
0715:            			jf.thisExpression(),
0716:            			BaseActivation.CLASS_NAME,
0717:            			"throwIfClosed",
0718:            			"void",
0719:            			acb.exprArray(jf.newStringLiteral(...some literal here...)));
0720:
0721:            		//mb is a MethodBuilder
0722:            		mb.addStatement(jf.newStatement(ce));
0723:            	</verbatim>
0724:            	The java code to write to call this is:
0725:            	<verbatim>
0726:            		this.throwIfClosed(...some literal here...);
0727:            	</verbatim>
0728:            	In both cases, "...some literal here..." gets replaced with
0729:            	an expression of type String that evaluates to the name
0730:            	of the operation that is being checked, like "execute" or
0731:            	"reset".
0732:
0733:            	@exception StandardException thrown if closed
0734:             */
0735:            public void throwIfClosed(String op) throws StandardException {
0736:                if (closed)
0737:                    throw StandardException.newException(
0738:                            SQLState.LANG_ACTIVATION_CLOSED, op);
0739:            }
0740:
0741:            /**
0742:             * Set a column position in an array of column positions.
0743:             *
0744:             * @param columnPositions	The array of column positions
0745:             * @param positionToSet		The place to put the column position
0746:             * @param column			The column position
0747:             */
0748:            public static void setColumnPosition(int[] columnPositions,
0749:                    int positionToSet, int column) {
0750:                columnPositions[positionToSet] = column;
0751:            }
0752:
0753:            /**
0754:             * Allocate an array of qualifiers and initialize in Qualifier[][]
0755:             *
0756:             * @param qualifiers	The array of Qualifier arrays.
0757:             * @param position		The position in the array to set
0758:             * @param length		The array length of the qualifier array to allocate.
0759:             */
0760:            public static void allocateQualArray(Qualifier[][] qualifiers,
0761:                    int position, int length) {
0762:                qualifiers[position] = new Qualifier[length];
0763:            }
0764:
0765:            /**
0766:             * Set a Qualifier in a 2 dimensional array of Qualifiers.
0767:             *
0768:             * Set a single Qualifier into one slot of a 2 dimensional array of 
0769:             * Qualifiers.  @see Qualifier for detailed description of layout of
0770:             * the 2-d array.
0771:             *
0772:             * @param qualifiers	The array of Qualifiers
0773:             * @param qualifier		The Qualifier
0774:             * @param position_1    The Nth array index into qualifiers[N][M]
0775:             * @param position_2    The Nth array index into qualifiers[N][M]
0776:             */
0777:            public static void setQualifier(Qualifier[][] qualifiers,
0778:                    Qualifier qualifier, int position_1, int position_2) {
0779:                qualifiers[position_1][position_2] = qualifier;
0780:            }
0781:
0782:            /**
0783:             * Reinitialize all Qualifiers in an array of Qualifiers.
0784:             *
0785:             * @param qualifiers	The array of Qualifiers
0786:             */
0787:            public static void reinitializeQualifiers(Qualifier[][] qualifiers) {
0788:                if (qualifiers != null) {
0789:                    for (int term = 0; term < qualifiers.length; term++) {
0790:                        for (int i = 0; i < qualifiers[term].length; i++) {
0791:                            qualifiers[term][i].reinitialize();
0792:                        }
0793:                    }
0794:                }
0795:            }
0796:
0797:            /**
0798:             * Mark the activation as unused.  
0799:             */
0800:            public final void markUnused() {
0801:                if (isInUse()) {
0802:                    inUse = false;
0803:                    lcc.notifyUnusedActivation();
0804:                }
0805:            }
0806:
0807:            /**
0808:             * Is the activation in use?
0809:             *
0810:             * @return true/false
0811:             */
0812:            public final boolean isInUse() {
0813:                return inUse;
0814:            }
0815:
0816:            /**
0817:              @see org.apache.derby.iapi.sql.Activation#addWarning
0818:             */
0819:            public void addWarning(SQLWarning w) {
0820:                if (warnings == null)
0821:                    warnings = w;
0822:                else
0823:                    warnings.setNextWarning(w);
0824:            }
0825:
0826:            /**
0827:              @see org.apache.derby.iapi.sql.Activation#getWarnings
0828:             */
0829:            public SQLWarning getWarnings() {
0830:                return warnings;
0831:            }
0832:
0833:            /**
0834:              @see org.apache.derby.iapi.sql.Activation#clearWarnings
0835:             */
0836:            public void clearWarnings() {
0837:                warnings = null;
0838:            }
0839:
0840:            /**
0841:             * @exception StandardException on error
0842:             */
0843:            protected static void nullToPrimitiveTest(DataValueDescriptor dvd,
0844:                    String primitiveType) throws StandardException {
0845:                if (dvd.isNull()) {
0846:                    throw StandardException.newException(
0847:                            SQLState.LANG_NULL_TO_PRIMITIVE_PARAMETER,
0848:                            primitiveType);
0849:                }
0850:            }
0851:
0852:            /**
0853:            	@see Activation#informOfRowCount
0854:            	@exception StandardException	Thrown on error
0855:             */
0856:            public void informOfRowCount(NoPutResultSet resultSet,
0857:                    long currentRowCount) throws StandardException {
0858:
0859:                /* Do we want to check the row counts during this execution? */
0860:                if (checkRowCounts) {
0861:                    boolean significantChange = false;
0862:
0863:                    int resultSetNumber = resultSet.resultSetNumber();
0864:                    Integer rsn = ReuseFactory.getInteger(resultSetNumber);
0865:
0866:                    /* Check each result set only once per execution */
0867:                    if (rowCountsCheckedThisExecution.add(rsn)) {
0868:                        synchronized (getPreparedStatement()) {
0869:                            Vector rowCountCheckVector = getRowCountCheckVector();
0870:
0871:                            if (rowCountCheckVector == null) {
0872:                                rowCountCheckVector = new Vector();
0873:                                setRowCountCheckVector(rowCountCheckVector);
0874:                            }
0875:
0876:                            Long firstRowCount = null;
0877:
0878:                            /*
0879:                             ** Check whether this resultSet has been seen yet.
0880:                             */
0881:                            if (resultSetNumber < rowCountCheckVector.size()) {
0882:                                firstRowCount = (Long) rowCountCheckVector
0883:                                        .elementAt(resultSetNumber);
0884:                            } else {
0885:                                rowCountCheckVector
0886:                                        .setSize(resultSetNumber + 1);
0887:                            }
0888:
0889:                            if (firstRowCount != null) {
0890:                                /*
0891:                                 ** This ResultSet has been seen - has the row count
0892:                                 ** changed significantly?
0893:                                 */
0894:                                long n1 = firstRowCount.longValue();
0895:
0896:                                if (currentRowCount != n1) {
0897:                                    if (n1 >= TEN_PERCENT_THRESHOLD) {
0898:                                        /*
0899:                                         ** For tables with more than
0900:                                         ** TEN_PERCENT_THRESHOLD rows, the
0901:                                         ** threshold is 10% of the size of the table.
0902:                                         */
0903:                                        long changeFactor = n1
0904:                                                / (currentRowCount - n1);
0905:                                        if (Math.abs(changeFactor) <= 10)
0906:                                            significantChange = true;
0907:                                    } else {
0908:                                        /*
0909:                                         ** For tables with less than
0910:                                         ** TEN_PERCENT_THRESHOLD rows, the threshold
0911:                                         ** is non-linear.  This is because we want
0912:                                         ** recompilation to happen sooner for small
0913:                                         ** tables that change size.  This formula
0914:                                         ** is for a second-order equation (a parabola).
0915:                                         ** The derivation is:
0916:                                         **
0917:                                         **   c * n1 = (difference in row counts) ** 2
0918:                                         **				- or - 
0919:                                         **   c * n1 = (currentRowCount - n1) ** 2
0920:                                         **
0921:                                         ** Solving this for currentRowCount, we get:
0922:                                         **
0923:                                         **   currentRowCount = n1 + sqrt(c * n1)
0924:                                         **
0925:                                         **				- or -
0926:                                         **
0927:                                         **   difference in row counts = sqrt(c * n1)
0928:                                         **
0929:                                         **				- or -
0930:                                         **
0931:                                         **   (difference in row counts) ** 2 =
0932:                                         **					c * n1
0933:                                         **
0934:                                         ** Which means that we should recompile when
0935:                                         ** the current row count exceeds n1 (the first
0936:                                         ** row count) by sqrt(c * n1), or when the
0937:                                         ** square of the difference exceeds c * n1.
0938:                                         ** A good value for c seems to be 4.
0939:                                         **
0940:                                         ** We don't use this formula when c is greater
0941:                                         ** than TEN_PERCENT_THRESHOLD because we never
0942:                                         ** want to recompile unless the number of rows
0943:                                         ** changes by more than 10%, and this formula
0944:                                         ** is more sensitive than that for values of
0945:                                         ** n1 greater than TEN_PERCENT_THRESHOLD.
0946:                                         */
0947:                                        long changediff = currentRowCount - n1;
0948:
0949:                                        /*
0950:                                         ** Square changediff rather than take the square
0951:                                         ** root of (4 * n1), because multiplying is
0952:                                         ** faster than taking a square root.  Also,
0953:                                         ** check to be sure that squaring changediff
0954:                                         ** will not cause an overflow by comparing it
0955:                                         ** with the square root of the maximum value
0956:                                         ** for a long (this square root is taken only
0957:                                         ** once, when the class is loaded, or during
0958:                                         ** compilation if the compiler is smart enough).
0959:                                         */
0960:                                        if (Math.abs(changediff) <= MAX_SQRT) {
0961:                                            if ((changediff * changediff) > Math
0962:                                                    .abs(4 * n1)) {
0963:                                                significantChange = true;
0964:                                            }
0965:                                        }
0966:                                    }
0967:                                }
0968:                            } else {
0969:                                firstRowCount = new Long(currentRowCount);
0970:                                rowCountCheckVector.setElementAt(firstRowCount,
0971:                                        resultSetNumber);
0972:
0973:                            }
0974:                        }
0975:                    }
0976:
0977:                    /* Invalidate outside of the critical section */
0978:                    if (significantChange) {
0979:                        preStmt.makeInvalid(
0980:                                DependencyManager.INTERNAL_RECOMPILE_REQUEST,
0981:                                lcc);
0982:                    }
0983:                }
0984:
0985:            }
0986:
0987:            /**
0988:             * The subclass calls this method when it begins an execution.
0989:             *
0990:             * @exception StandardException		Thrown on error
0991:             */
0992:            public void startExecution() throws StandardException {
0993:                // determine if we should check row counts during this execution
0994:                shouldWeCheckRowCounts();
0995:
0996:                // If we are to check row counts, clear the hash table of row counts
0997:                // we have checked.
0998:                if (checkRowCounts)
0999:                    rowCountsCheckedThisExecution.clear();
1000:            }
1001:
1002:            /**
1003:             * @see Activation#getHeapConglomerateController
1004:             */
1005:            public ConglomerateController getHeapConglomerateController() {
1006:                return updateHeapCC;
1007:            }
1008:
1009:            /**
1010:             * @see Activation#setHeapConglomerateController
1011:             */
1012:            public void setHeapConglomerateController(
1013:                    ConglomerateController updateHeapCC) {
1014:                this .updateHeapCC = updateHeapCC;
1015:            }
1016:
1017:            /**
1018:             * @see Activation#clearHeapConglomerateController
1019:             */
1020:            public void clearHeapConglomerateController() {
1021:                updateHeapCC = null;
1022:            }
1023:
1024:            /**
1025:             * @see Activation#getIndexScanController
1026:             */
1027:            public ScanController getIndexScanController() {
1028:                return indexSC;
1029:            }
1030:
1031:            /**
1032:             * @see Activation#setIndexScanController
1033:             */
1034:            public void setIndexScanController(ScanController indexSC) {
1035:                this .indexSC = indexSC;
1036:            }
1037:
1038:            /**
1039:             * @see Activation#getIndexConglomerateNumber
1040:             */
1041:            public long getIndexConglomerateNumber() {
1042:                return indexConglomerateNumber;
1043:            }
1044:
1045:            /**
1046:             * @see Activation#setIndexConglomerateNumber
1047:             */
1048:            public void setIndexConglomerateNumber(long indexConglomerateNumber) {
1049:                this .indexConglomerateNumber = indexConglomerateNumber;
1050:            }
1051:
1052:            /**
1053:             * @see Activation#clearIndexScanInfo
1054:             */
1055:            public void clearIndexScanInfo() {
1056:                indexSC = null;
1057:                indexConglomerateNumber = -1;
1058:            }
1059:
1060:            /**
1061:             * @see Activation#setForCreateTable()
1062:             */
1063:            public void setForCreateTable() {
1064:                forCreateTable = true;
1065:            }
1066:
1067:            /**
1068:             * @see Activation#getForCreateTable()
1069:             */
1070:            public boolean getForCreateTable() {
1071:                return forCreateTable;
1072:            }
1073:
1074:            /**
1075:             * @see Activation#setDDLTableDescriptor
1076:             */
1077:            public void setDDLTableDescriptor(TableDescriptor td) {
1078:                ddlTableDescriptor = td;
1079:            }
1080:
1081:            /**
1082:             * @see Activation#getDDLTableDescriptor
1083:             */
1084:            public TableDescriptor getDDLTableDescriptor() {
1085:                return ddlTableDescriptor;
1086:            }
1087:
1088:            /**
1089:             * @see Activation#setMaxRows
1090:             */
1091:            public void setMaxRows(int maxRows) {
1092:                this .maxRows = maxRows;
1093:            }
1094:
1095:            /**
1096:             * @see Activation#getMaxRows
1097:             */
1098:            public int getMaxRows() {
1099:                return maxRows;
1100:            }
1101:
1102:            public void setTargetVTI(java.sql.ResultSet targetVTI) {
1103:                this .targetVTI = targetVTI;
1104:            }
1105:
1106:            public java.sql.ResultSet getTargetVTI() {
1107:                return targetVTI;
1108:            }
1109:
1110:            private void shouldWeCheckRowCounts() throws StandardException {
1111:                /*
1112:                 ** Check the row count only every N executions.  OK to check this
1113:                 ** without synchronization, since the value of this number is not
1114:                 ** critical.  The value of N is determined by the property
1115:                 ** derby.language.stalePlanCheckInterval.
1116:                 */
1117:                int executionCount = getExecutionCount() + 1;
1118:
1119:                /*
1120:                 ** Always check row counts the first time, to establish the
1121:                 ** row counts for each result set.  After that, don't check
1122:                 ** if the execution count is below the minimum row count check
1123:                 ** interval.  This saves us from checking a database property
1124:                 ** when we don't have to (checking involves querying the store,
1125:                 ** which can be expensive).
1126:                 */
1127:
1128:                if (executionCount == 1) {
1129:                    checkRowCounts = true;
1130:                } else if (executionCount < Property.MIN_LANGUAGE_STALE_PLAN_CHECK_INTERVAL) {
1131:                    checkRowCounts = false;
1132:                } else {
1133:                    int stalePlanCheckInterval = getStalePlanCheckInterval();
1134:
1135:                    /*
1136:                     ** Only query the database property once.  We can tell because
1137:                     ** the minimum value of the property is greater than zero.
1138:                     */
1139:                    if (stalePlanCheckInterval == 0) {
1140:                        TransactionController tc = getTransactionController();
1141:
1142:                        stalePlanCheckInterval = PropertyUtil
1143:                                .getServiceInt(
1144:                                        tc,
1145:                                        Property.LANGUAGE_STALE_PLAN_CHECK_INTERVAL,
1146:                                        Property.MIN_LANGUAGE_STALE_PLAN_CHECK_INTERVAL,
1147:                                        Integer.MAX_VALUE,
1148:                                        Property.DEFAULT_LANGUAGE_STALE_PLAN_CHECK_INTERVAL);
1149:                        setStalePlanCheckInterval(stalePlanCheckInterval);
1150:                    }
1151:
1152:                    checkRowCounts = (executionCount % stalePlanCheckInterval) == 1;
1153:
1154:                }
1155:
1156:                setExecutionCount(executionCount);
1157:            }
1158:
1159:            /*
1160:             ** These accessor methods are provided by the sub-class to help figure
1161:             ** out whether to check row counts during this execution.
1162:             */
1163:            abstract protected int getExecutionCount();
1164:
1165:            abstract protected void setExecutionCount(int newValue);
1166:
1167:            /*
1168:             ** These accessor methods are provided by the sub-class to help figure
1169:             ** out whether the row count for a particular result set has changed
1170:             ** enough to force recompilation.
1171:             */
1172:            abstract protected Vector getRowCountCheckVector();
1173:
1174:            abstract protected void setRowCountCheckVector(Vector newValue);
1175:
1176:            /*
1177:             ** These accessor methods are provided by the sub-class to remember the
1178:             ** value of the stale plan check interval property, so that we only
1179:             ** have to query the database properties once (there is heavyweight
1180:             ** synchronization around the database properties).
1181:             */
1182:            abstract protected int getStalePlanCheckInterval();
1183:
1184:            abstract protected void setStalePlanCheckInterval(int newValue);
1185:
1186:            public final boolean getScrollable() {
1187:                return scrollable;
1188:            }
1189:
1190:            protected final void setParameterValueSet(int paramCount,
1191:                    boolean hasReturnParam) {
1192:
1193:                pvs = lcc.getLanguageFactory().newParameterValueSet(
1194:                        lcc.getLanguageConnectionFactory().getClassFactory()
1195:                                .getClassInspector(), paramCount,
1196:                        hasReturnParam);
1197:            }
1198:
1199:            /**
1200:             * This method can help reduce the amount of generated code by changing
1201:             * instances of this.pvs.getParameter(position) to this.getParameter(position) 
1202:             * @param position
1203:             * @throws StandardException
1204:             */
1205:            protected final DataValueDescriptor getParameter(int position)
1206:                    throws StandardException {
1207:                return pvs.getParameter(position);
1208:            }
1209:
1210:            /**
1211:             return the parameters.
1212:             */
1213:            public ParameterValueSet getParameterValueSet() {
1214:                if (pvs == null)
1215:                    setParameterValueSet(0, false);
1216:                return pvs;
1217:            }
1218:
1219:            // how do we do/do we want any sanity checking for
1220:            // the number of parameters expected?
1221:            public void setParameters(ParameterValueSet parameterValues,
1222:                    DataTypeDescriptor[] parameterTypes)
1223:                    throws StandardException {
1224:                if (!isClosed()) {
1225:
1226:                    if (this .pvs == null || parameterTypes == null) {
1227:                        pvs = parameterValues;
1228:                        return;
1229:
1230:                    }
1231:
1232:                    DataTypeDescriptor[] newParamTypes = preStmt
1233:                            .getParameterTypes();
1234:
1235:                    /*
1236:                     ** If there are old parameters but not new ones,
1237:                     ** they aren't compatible.
1238:                     */
1239:                    boolean match = false;
1240:                    if (newParamTypes != null) {
1241:
1242:                        if (newParamTypes.length == parameterTypes.length) {
1243:
1244:                            /* Check each parameter */
1245:                            match = true;
1246:                            for (int i = 0; i < parameterTypes.length; i++) {
1247:                                DataTypeDescriptor oldType = parameterTypes[i];
1248:                                DataTypeDescriptor newType = newParamTypes[i];
1249:
1250:                                if (!oldType.isExactTypeAndLengthMatch(newType)) {
1251:                                    match = false;
1252:                                    break;
1253:                                }
1254:                                /*
1255:                                 ** We could probably get away without checking nullability,
1256:                                 ** since parameters are always nullable.
1257:                                 */
1258:                                if (oldType.isNullable() != newType
1259:                                        .isNullable()) {
1260:                                    match = false;
1261:                                    break;
1262:                                }
1263:                            }
1264:                        }
1265:
1266:                    }
1267:
1268:                    if (!match)
1269:                        throw StandardException
1270:                                .newException(SQLState.LANG_OBSOLETE_PARAMETERS);
1271:
1272:                    parameterValues.transferDataValues(pvs);
1273:
1274:                } else if (SanityManager.DEBUG) {
1275:                    SanityManager
1276:                            .THROWASSERT("isClosed() is expected to return false");
1277:                }
1278:            }
1279:
1280:            /**
1281:             	Throw an exception if any parameters are uninitialized.
1282:
1283:            	@exception StandardException	Thrown if any parameters
1284:            											are unitialized
1285:             */
1286:
1287:            public void throwIfMissingParms() throws StandardException {
1288:                if (pvs != null && !pvs.allAreSet()) {
1289:                    throw StandardException
1290:                            .newException(SQLState.LANG_MISSING_PARMS);
1291:                }
1292:            }
1293:
1294:            /**
1295:             * Remember the row for the specified ResultSet.
1296:             */
1297:            public void setCurrentRow(ExecRow currentRow, int resultSetNumber) {
1298:                if (SanityManager.DEBUG) {
1299:                    SanityManager.ASSERT(!isClosed(), "closed");
1300:                    if (row != null) {
1301:                        if (!(resultSetNumber >= 0 && resultSetNumber < row.length)) {
1302:                            SanityManager.THROWASSERT("resultSetNumber = "
1303:                                    + resultSetNumber
1304:                                    + ", expected to be between 0 and "
1305:                                    + row.length);
1306:                        }
1307:                    }
1308:                }
1309:                if (row != null) {
1310:                    row[resultSetNumber] = currentRow;
1311:                }
1312:            }
1313:
1314:            /**
1315:             * Clear the current row for the specified ResultSet.
1316:             */
1317:            public void clearCurrentRow(int resultSetNumber) {
1318:                if (SanityManager.DEBUG) {
1319:                    if (row != null) {
1320:                        if (!(resultSetNumber >= 0 && resultSetNumber < row.length)) {
1321:                            SanityManager.THROWASSERT("resultSetNumber = "
1322:                                    + resultSetNumber
1323:                                    + ", expected to be between 0 and "
1324:                                    + row.length);
1325:                        }
1326:                    }
1327:                }
1328:                if (row != null) {
1329:                    row[resultSetNumber] = null;
1330:                }
1331:            }
1332:
1333:            protected final DataValueDescriptor getColumnFromRow(int rsNumber,
1334:                    int colId) throws StandardException {
1335:
1336:                if (row[rsNumber] == null) {
1337:                    /* This actually happens. NoPutResultSetImpl.clearOrderableCache attempts to prefetch invariant values
1338:                     * into a cache. This fails in some deeply nested joins. See Beetle 4736 and 4880.
1339:                     */
1340:                    return null;
1341:                }
1342:                return row[rsNumber].getColumn(colId);
1343:            }
1344:
1345:            protected void checkPositionedStatement(String cursorName,
1346:                    String psName) throws StandardException {
1347:
1348:                ExecPreparedStatement ps = getPreparedStatement();
1349:                if (ps == null)
1350:                    return;
1351:
1352:                LanguageConnectionContext lcc = getLanguageConnectionContext();
1353:
1354:                CursorActivation cursorActivation = lcc
1355:                        .lookupCursorActivation(cursorName);
1356:
1357:                if (cursorActivation != null) {
1358:                    // check we are compiled against the correct cursor
1359:                    if (!psName.equals(cursorActivation.getPreparedStatement()
1360:                            .getObjectName())) {
1361:
1362:                        // our prepared statement is now invalid since there
1363:                        // exists another cursor with the same name but a different
1364:                        // statement.
1365:                        ps.makeInvalid(DependencyManager.CHANGED_CURSOR, lcc);
1366:                    }
1367:                }
1368:            }
1369:
1370:            /* This method is used to materialize a resultset if can actually fit in the memory
1371:             * specified by "maxMemoryPerTable" system property.  It converts the result set into
1372:             * union(union(union...(union(row, row), row), ...row), row).  It returns this
1373:             * in-memory converted resultset, or the original result set if not converted.
1374:             * See beetle 4373 for details.
1375:             *
1376:             * Optimization implemented as part of Beetle: 4373 can cause severe stack overflow
1377:             * problems. See JIRA entry DERBY-634. With default MAX_MEMORY_PER_TABLE of 1MG, it is
1378:             * possible that this optimization could attempt to cache upto 250K rows as nested
1379:             * union results. At runtime, this would cause stack overflow.
1380:             *
1381:             * As Jeff mentioned in DERBY-634, right way to optimize original problem would have been
1382:             * to address subquery materialization during optimization phase, through hash joins.
1383:             * Recent Army's optimizer work through DEBRY-781 and related work introduced a way to
1384:             * materialize subquery results correctly and needs to be extended to cover this case.
1385:             * While his optimization needs to be made more generic and stable, I propose to avoid
1386:             * this regression by limiting size of the materialized resultset created here to be
1387:             * less than MAX_MEMORY_PER_TABLE and MAX_DYNAMIC_MATERIALIZED_ROWS.
1388:             *
1389:             *	@param	rs	input result set
1390:             *	@return	materialized resultset, or original rs if it can't be materialized
1391:             */
1392:            public NoPutResultSet materializeResultSetIfPossible(
1393:                    NoPutResultSet rs) throws StandardException {
1394:                rs.openCore();
1395:                Vector rowCache = new Vector();
1396:                ExecRow aRow;
1397:                int cacheSize = 0;
1398:                FormatableBitSet toClone = null;
1399:
1400:                int maxMemoryPerTable = getLanguageConnectionContext()
1401:                        .getOptimizerFactory().getMaxMemoryPerTable();
1402:
1403:                aRow = rs.getNextRowCore();
1404:                if (aRow != null) {
1405:                    toClone = new FormatableBitSet(aRow.nColumns() + 1);
1406:                    toClone.set(1);
1407:                }
1408:                while (aRow != null) {
1409:                    cacheSize += aRow.getColumn(1).getLength();
1410:                    if (cacheSize > maxMemoryPerTable
1411:                            || rowCache.size() > Optimizer.MAX_DYNAMIC_MATERIALIZED_ROWS)
1412:                        break;
1413:                    rowCache.addElement(aRow.getClone(toClone));
1414:                    aRow = rs.getNextRowCore();
1415:                }
1416:                rs.close();
1417:
1418:                if (aRow == null) {
1419:                    int rsNum = rs.resultSetNumber();
1420:
1421:                    int numRows = rowCache.size();
1422:                    if (numRows == 0) {
1423:                        return new RowResultSet(this , (ExecRow) null, true,
1424:                                rsNum, 0, 0);
1425:                    }
1426:                    RowResultSet[] rrs = new RowResultSet[numRows];
1427:                    UnionResultSet[] urs = new UnionResultSet[numRows - 1];
1428:
1429:                    for (int i = 0; i < numRows; i++) {
1430:                        rrs[i] = new RowResultSet(this , (ExecRow) rowCache
1431:                                .elementAt(i), true, rsNum, 1, 0);
1432:                        if (i > 0) {
1433:                            urs[i - 1] = new UnionResultSet(
1434:                                    (i > 1) ? (NoPutResultSet) urs[i - 2]
1435:                                            : (NoPutResultSet) rrs[0], rrs[i],
1436:                                    this , rsNum, i + 1, 0);
1437:                        }
1438:                    }
1439:
1440:                    rs.finish();
1441:
1442:                    if (numRows == 1)
1443:                        return rrs[0];
1444:                    else
1445:                        return urs[urs.length - 1];
1446:                }
1447:                return rs;
1448:            }
1449:
1450:            //WARNING : this field name is referred in the DeleteNode generate routines.
1451:            protected CursorResultSet[] raParentResultSets;
1452:
1453:            // maintain hash table of parent result set vector
1454:            // a table can have more than one parent source.
1455:            protected Hashtable parentResultSets;
1456:
1457:            public void setParentResultSet(TemporaryRowHolder rs,
1458:                    String resultSetId) {
1459:                Vector rsVector;
1460:                if (parentResultSets == null)
1461:                    parentResultSets = new Hashtable();
1462:                rsVector = (Vector) parentResultSets.get(resultSetId);
1463:                if (rsVector == null) {
1464:                    rsVector = new Vector();
1465:                    rsVector.addElement(rs);
1466:                } else {
1467:                    rsVector.addElement(rs);
1468:                }
1469:                parentResultSets.put(resultSetId, rsVector);
1470:            }
1471:
1472:            /**
1473:             * get the reference to parent table ResultSets, that will be needed by the 
1474:             * referential action dependent table scans.
1475:             */
1476:            public Vector getParentResultSet(String resultSetId) {
1477:                return (Vector) parentResultSets.get(resultSetId);
1478:            }
1479:
1480:            public Hashtable getParentResultSets() {
1481:                return parentResultSets;
1482:            }
1483:
1484:            /**
1485:             ** prepared statement use the same activation for
1486:             ** multiple execution. For each excution we create new
1487:             ** set of temporary resultsets, we should clear this hash table.
1488:             ** otherwise we will refer to the released resources.
1489:             */
1490:            public void clearParentResultSets() {
1491:                if (parentResultSets != null)
1492:                    parentResultSets.clear();
1493:            }
1494:
1495:            /**
1496:             * beetle 3865: updateable cursor using index.  A way of communication
1497:             * between cursor activation and update activation.
1498:             */
1499:            public void setForUpdateIndexScan(CursorResultSet forUpdateIndexScan) {
1500:                this .forUpdateIndexScan = forUpdateIndexScan;
1501:            }
1502:
1503:            public CursorResultSet getForUpdateIndexScan() {
1504:                return forUpdateIndexScan;
1505:            }
1506:
1507:            private java.util.Calendar cal;
1508:
1509:            /**
1510:            	Return a calendar for use by this activation.
1511:            	Calendar objects are not thread safe, the one returned
1512:            	is purely for use by this activation and it is assumed
1513:            	that is it single threded through the single active
1514:            	thread in a connection model.
1515:             */
1516:            protected java.util.Calendar getCalendar() {
1517:                if (cal == null)
1518:                    cal = new java.util.GregorianCalendar();
1519:                return cal;
1520:
1521:            }
1522:
1523:            /*
1524:             ** Code originally in the parent class BaseExpressionActivation
1525:             */
1526:            /**
1527:                Get the language connection factory associated with this connection
1528:             */
1529:            public final LanguageConnectionContext getLanguageConnectionContext() {
1530:                return lcc;
1531:            }
1532:
1533:            public final TransactionController getTransactionController() {
1534:                return lcc.getTransactionExecute();
1535:            }
1536:
1537:            /**
1538:             * Get the ExecutionContext.
1539:             */
1540:            ExecutionContext getExecutionContext() {
1541:                return ec;
1542:            }
1543:
1544:            /**
1545:             * Get the Current ContextManager.
1546:             *
1547:             * @return Current ContextManager
1548:             */
1549:            public ContextManager getContextManager() {
1550:                return cm;
1551:            }
1552:
1553:            /**
1554:            	Used by activations to generate data values.  Most DML statements
1555:            	will use this method.  Possibly some DDL statements will, as well.
1556:             */
1557:            public DataValueFactory getDataValueFactory() {
1558:                return dvFactory;
1559:            }
1560:
1561:            /**
1562:             * Used to get a proxy for the current connection.
1563:             *
1564:             * @exception SQLException		Thrown on failure to get connection
1565:             */
1566:            public Connection getCurrentConnection() throws SQLException {
1567:
1568:                ConnectionContext cc = (ConnectionContext) cm
1569:                        .getContext(ConnectionContext.CONTEXT_ID);
1570:
1571:                return cc.getNestedConnection(true);
1572:            }
1573:
1574:            /**
1575:            	Real implementations of this method are provided by a generated class.
1576:             */
1577:            public java.sql.ResultSet[][] getDynamicResults() {
1578:                return null;
1579:            }
1580:
1581:            /**
1582:            	Real implementations of this method are provided by a generated class.
1583:             */
1584:            public int getMaxDynamicResults() {
1585:                return 0;
1586:            }
1587:
1588:            /**
1589:             * Compute the DB2 compatible length of a value.
1590:             *
1591:             * @param value
1592:             * @param constantLength The length, if it is a constant modulo null/not null. -1 if the length is not constant
1593:             * @param reUse If non-null then re-use this as a container for the length
1594:             *
1595:             * @return the DB2 compatible length, set to null if value is null.
1596:             */
1597:            public NumberDataValue getDB2Length(DataValueDescriptor value,
1598:                    int constantLength, NumberDataValue reUse)
1599:                    throws StandardException {
1600:                if (reUse == null)
1601:                    reUse = getDataValueFactory().getNullInteger(null);
1602:                if (value.isNull())
1603:                    reUse.setToNull();
1604:                else {
1605:                    if (constantLength >= 0)
1606:                        reUse.setValue(constantLength);
1607:                    else {
1608:                        reUse.setValue(value.getLength());
1609:                    }
1610:                }
1611:                return reUse;
1612:            } // end of getDB2Length
1613:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.