Source Code Cross Referenced for ValueNode.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.ValueNode
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.types.DataTypeDescriptor;
0025:        import org.apache.derby.iapi.types.TypeId;
0026:        import org.apache.derby.iapi.sql.dictionary.DataDictionary;
0027:        import org.apache.derby.iapi.error.StandardException;
0028:
0029:        import org.apache.derby.iapi.sql.compile.TypeCompiler;
0030:        import org.apache.derby.iapi.types.DataValueFactory;
0031:
0032:        import org.apache.derby.iapi.types.SQLChar;
0033:
0034:        import org.apache.derby.iapi.services.sanity.SanityManager;
0035:
0036:        import org.apache.derby.iapi.sql.compile.CompilerContext;
0037:        import org.apache.derby.iapi.sql.compile.Optimizable;
0038:        import org.apache.derby.iapi.sql.compile.C_NodeTypes;
0039:        import org.apache.derby.iapi.sql.compile.NodeFactory;
0040:
0041:        import org.apache.derby.iapi.reference.SQLState;
0042:
0043:        import org.apache.derby.iapi.store.access.Qualifier;
0044:
0045:        import org.apache.derby.impl.sql.compile.ActivationClassBuilder;
0046:        import org.apache.derby.impl.sql.compile.ExpressionClassBuilder;
0047:
0048:        import org.apache.derby.iapi.services.compiler.MethodBuilder;
0049:
0050:        import org.apache.derby.iapi.util.JBitSet;
0051:        import org.apache.derby.iapi.services.i18n.MessageService;
0052:
0053:        import java.lang.reflect.Modifier;
0054:
0055:        import java.sql.Date;
0056:        import java.sql.Time;
0057:        import java.sql.Timestamp;
0058:
0059:        import java.util.Vector;
0060:
0061:        /**
0062:         * A ValueNode is an abstract class for all nodes that can represent data
0063:         * values, that is, constants, columns, and expressions.
0064:         *
0065:         * @author Jeff Lichtman
0066:         */
0067:
0068:        public abstract class ValueNode extends QueryTreeNode {
0069:            public static final int IN_UNKNOWN_CLAUSE = 0;
0070:            public static final int IN_SELECT_LIST = 1;
0071:            public static final int IN_WHERE_CLAUSE = 2;
0072:            public static final int IN_HAVING_CLAUSE = 3;
0073:
0074:            protected DataTypeDescriptor dataTypeServices;
0075:            private TypeId typeId;
0076:            private TypeCompiler typeCompiler;
0077:            protected int clause = IN_UNKNOWN_CLAUSE;
0078:
0079:            // Whether or not additional predicates have been created from this one.
0080:            boolean transformed;
0081:
0082:            /*
0083:             ** Constructor for untyped ValueNodes, for example, untyped NULLs
0084:             ** and parameter nodes.
0085:             **
0086:             ** Binding will replace all untyped ValueNodes with typed ValueNodes
0087:             ** when it figures out what their types should be.
0088:             */
0089:            public ValueNode() {
0090:            }
0091:
0092:            /**
0093:             * Initializer for numeric types.
0094:             * 
0095:             *
0096:             * @param typeId	The TypeID of this new node
0097:             * @param precision	The precision of this new node
0098:             * @param scale		The scale of this new node
0099:             * @param isNullable	The nullability of this new node
0100:             * @param maximumWidth	The maximum width of this new node
0101:             *
0102:             * @exception StandardException
0103:             */
0104:
0105:            public void init(Object typeId, Object precision, Object scale,
0106:                    Object isNullable, Object maximumWidth)
0107:                    throws StandardException {
0108:                setType(new DataTypeDescriptor((TypeId) typeId,
0109:                        ((Integer) precision).intValue(), ((Integer) scale)
0110:                                .intValue(), ((Boolean) isNullable)
0111:                                .booleanValue(), ((Integer) maximumWidth)
0112:                                .intValue()));
0113:            }
0114:
0115:            /**
0116:             * Initializer for non-numeric types.
0117:             * 
0118:             *
0119:             * @param tcf		The factory to get the
0120:             *					DataTypeServicesFactory from
0121:             * @param typeId	The TypeID of this new node
0122:             * @param isNullable	The nullability of this new node
0123:             * @param maximumWidth	The maximum width of this new node
0124:             *
0125:             * @exception StandardException
0126:             */
0127:
0128:            ValueNode(Object tcf, Object typeId, Object isNullable,
0129:                    Object maximumWidth) throws StandardException {
0130:                setType(new DataTypeDescriptor((TypeId) typeId,
0131:                        ((Boolean) isNullable).booleanValue(),
0132:                        ((Integer) maximumWidth).intValue()));
0133:            }
0134:
0135:            /**
0136:             * Convert this object to a String.  See comments in QueryTreeNode.java
0137:             * for how this should be done for tree printing.
0138:             *
0139:             * @return	This object as a String
0140:             */
0141:
0142:            public String toString() {
0143:                if (SanityManager.DEBUG) {
0144:                    return "dataTypeServices: "
0145:                            + ((dataTypeServices != null) ? dataTypeServices
0146:                                    .toString() : "null") + "\n" + "clause: "
0147:                            + clause + "\n" + super .toString();
0148:                } else {
0149:                    return "";
0150:                }
0151:            }
0152:
0153:            /**
0154:             * Get the DataTypeServices from this ValueNode.
0155:             *
0156:             * @return	The DataTypeServices from this ValueNode.  This
0157:             *		may be null if the node isn't bound yet.
0158:             */
0159:            public DataTypeDescriptor getTypeServices()
0160:                    throws StandardException {
0161:                return dataTypeServices;
0162:            }
0163:
0164:            /**
0165:             * Get the TypeId from this ValueNode.
0166:             *
0167:             * @return	The TypeId from this ValueNode.  This
0168:             *		may be null if the node isn't bound yet.
0169:             */
0170:            public TypeId getTypeId() throws StandardException {
0171:                return typeId;
0172:            }
0173:
0174:            /**
0175:            	Return the DataValueFactory
0176:             */
0177:            protected final DataValueFactory getDataValueFactory() {
0178:                return getLanguageConnectionContext().getDataValueFactory();
0179:            }
0180:
0181:            /**
0182:             * Get the TypeCompiler from this ValueNode, based on its TypeId.
0183:             *
0184:             * @return	This ValueNode's TypeCompiler
0185:             *
0186:             */
0187:            public TypeCompiler getTypeCompiler() throws StandardException {
0188:                if (typeCompiler == null) {
0189:                    /*
0190:                     ** getTypeId() is overriddend by parameter node so
0191:                     ** don't get smart and remove the extra method call.
0192:                     */
0193:                    typeCompiler = getTypeCompiler(getTypeId());
0194:                }
0195:
0196:                return typeCompiler;
0197:            }
0198:
0199:            /**
0200:             * Set the DataTypeServices for this ValueNode.  This method is
0201:             * overridden in ParameterNode.
0202:             *
0203:             * @param dataTypeServices	The DataTypeServices to set in this
0204:             *				ValueNode
0205:             */
0206:
0207:            public void setType(DataTypeDescriptor dataTypeServices)
0208:                    throws StandardException {
0209:                this .dataTypeServices = dataTypeServices;
0210:
0211:                /* Get this now so we only have to cast it once */
0212:                if (dataTypeServices == null)
0213:                    typeId = null;
0214:                else
0215:                    typeId = dataTypeServices.getTypeId();
0216:
0217:                // Clear the typeCompiler, just in case type has changed
0218:                typeCompiler = null;
0219:            }
0220:
0221:            /**
0222:             * Get the source for this ValueNode.
0223:             *
0224:             * @return	The source of this ValueNode.
0225:             */
0226:
0227:            public ResultColumn getSourceResultColumn() {
0228:                if (SanityManager.DEBUG)
0229:                    SanityManager.ASSERT(false,
0230:                            "getSourceResultColumn() not expected to be called for this node - "
0231:                                    + getClass().toString());
0232:                return null;
0233:            }
0234:
0235:            /**
0236:             * Get the clause that this node appears in.
0237:             *
0238:             * @return int	The clause that this node appears in.
0239:             */
0240:            public int getClause() {
0241:                return clause;
0242:            }
0243:
0244:            /**
0245:             * Set the clause that this node appears in.
0246:             *
0247:             * @param clause	The clause that this node appears in.
0248:             */
0249:            public void setClause(int clause) {
0250:                this .clause = clause;
0251:            }
0252:
0253:            /**
0254:             * Mark this predicate has having been transformed (other predicates
0255:             * were generated from it).  This will help us with ensure that the
0256:             * predicate does not get calculated into the selectivity multiple
0257:             * times.
0258:             */
0259:            void setTransformed() {
0260:                transformed = true;
0261:            }
0262:
0263:            /** 
0264:             * Return whether or not this predicate has been transformed.
0265:             *
0266:             * @return Whether or not this predicate has been transformed.
0267:             */
0268:            boolean getTransformed() {
0269:                return transformed;
0270:            }
0271:
0272:            public ValueNode bindExpression(FromList fromList,
0273:                    SubqueryList subqueryList, Vector aggregateVector)
0274:                    throws StandardException {
0275:                return bindExpression(fromList, subqueryList, aggregateVector,
0276:                        false);
0277:            }
0278:
0279:            /**
0280:             * Bind this expression.  This is a place-holder method - it should never
0281:             * be called.
0282:             *
0283:             * @param fromList			The FROM list to use for binding
0284:             * @param subqueryList		The SubqueryList we are building as we hit
0285:             *							SubqueryNodes.
0286:             * @param aggregateVector	The aggregate vector being built as we find AggregateNodes
0287:             *
0288:             * @return	The new top of the expression tree.
0289:             *
0290:             * @exception StandardException	Thrown on error
0291:             */
0292:
0293:            public ValueNode bindExpression(FromList fromList,
0294:                    SubqueryList subqueryList, Vector aggregateVector,
0295:                    boolean forQueryRewrite) throws StandardException {
0296:                /* There are a bizillion classes which extend ValueNode.  Here is info
0297:                 * on some of the classes that bindExpression() should not be called on
0298:                 * and why:
0299:                 *	o  BaseColumnNodes should only appear under the ResultColumnList
0300:                 *     in the FromBaseTable.  They are created/bound when binding the
0301:                 *     FromBaseTable.
0302:                 */
0303:                if (SanityManager.DEBUG) {
0304:                    SanityManager.ASSERT(false,
0305:                            "bindExpression() not expected to be called on a "
0306:                                    + this .getClass().toString());
0307:                }
0308:
0309:                return this ;
0310:            }
0311:
0312:            /**
0313:             * Generate a SQL->Java->SQL conversion tree above the current node
0314:             * and bind the new nodes individually.
0315:             * This is useful when doing comparisons, built-in functions, etc. on
0316:             * java types which have a direct mapping to system built-in types.
0317:             *
0318:             * @return ValueNode	The new tree.
0319:             *
0320:             * @exception StandardException	Thrown on error
0321:             */
0322:            public ValueNode genSQLJavaSQLTree() throws StandardException {
0323:                if (SanityManager.DEBUG) {
0324:                    SanityManager
0325:                            .ASSERT(typeId != null,
0326:                                    "genSQLJavaSQLTree() only expected to be called on a bound node");
0327:                    SanityManager
0328:                            .ASSERT(typeId.userType(),
0329:                                    "genSQLJavaSQLTree() only expected to be called on user types");
0330:                }
0331:
0332:                JavaValueNode stjvn = (JavaValueNode) getNodeFactory().getNode(
0333:                        C_NodeTypes.SQL_TO_JAVA_VALUE_NODE, this ,
0334:                        getContextManager());
0335:
0336:                ValueNode jtsvn = (ValueNode) getNodeFactory().getNode(
0337:                        C_NodeTypes.JAVA_TO_SQL_VALUE_NODE, stjvn,
0338:                        getContextManager());
0339:                jtsvn.setType(DataTypeDescriptor.getSQLDataTypeDescriptor(stjvn
0340:                        .getJavaTypeName()));
0341:                return jtsvn;
0342:            }
0343:
0344:            /**
0345:             * Preprocess an expression tree.  We do a number of transformations
0346:             * here (including subqueries, IN lists, LIKE and BETWEEN) plus
0347:             * subquery flattening.
0348:             * NOTE: This is done before the outer ResultSetNode is preprocessed.
0349:             *
0350:             * @param	numTables			Number of tables in the DML Statement
0351:             * @param	outerFromList		FromList from outer query block
0352:             * @param	outerSubqueryList	SubqueryList from outer query block
0353:             * @param	outerPredicateList	PredicateList from outer query block
0354:             *
0355:             * @return		The modified expression
0356:             *
0357:             * @exception StandardException		Thrown on error
0358:             */
0359:            public ValueNode preprocess(int numTables, FromList outerFromList,
0360:                    SubqueryList outerSubqueryList,
0361:                    PredicateList outerPredicateList) throws StandardException {
0362:                return this ;
0363:            }
0364:
0365:            /**
0366:             * Eliminate NotNodes in the current query block.  We traverse the tree, 
0367:             * inverting ANDs and ORs and eliminating NOTs as we go.  We stop at 
0368:             * ComparisonOperators and boolean expressions.  We invert 
0369:             * ComparisonOperators and replace boolean expressions with 
0370:             * boolean expression = false.
0371:             * NOTE: Since we do not recurse under ComparisonOperators, there
0372:             * still could be NotNodes left in the tree.
0373:             *
0374:             * @param	underNotNode		Whether or not we are under a NotNode.
0375:             *							
0376:             *
0377:             * @return		The modified expression
0378:             *
0379:             * @exception StandardException		Thrown on error
0380:             */
0381:            ValueNode eliminateNots(boolean underNotNode)
0382:                    throws StandardException {
0383:                if (!underNotNode) {
0384:                    return this ;
0385:                }
0386:
0387:                /* bind() has ensured that this node's type is SQLBoolean */
0388:                if (SanityManager.DEBUG)
0389:                    SanityManager.ASSERT(dataTypeServices.getTypeId().equals(
0390:                            TypeId.BOOLEAN_ID), "Node's type ("
0391:                            + dataTypeServices.getTypeId().getSQLTypeName()
0392:                            + ") is expected to be boolean");
0393:
0394:                /* Return ValueNode = false */
0395:                return genEqualsFalseTree();
0396:            }
0397:
0398:            /**
0399:             * Transform this into this = false.  Useful for NOT elimination.
0400:             *
0401:             *
0402:             * @return		The modified expression
0403:             *
0404:             * @exception StandardException		Thrown on error
0405:             */
0406:            public ValueNode genEqualsFalseTree() throws StandardException {
0407:                BinaryRelationalOperatorNode equalsNode;
0408:                BooleanConstantNode falseNode;
0409:                boolean nullableResult;
0410:                NodeFactory nodeFactory = getNodeFactory();
0411:
0412:                falseNode = (BooleanConstantNode) nodeFactory.getNode(
0413:                        C_NodeTypes.BOOLEAN_CONSTANT_NODE, Boolean.FALSE,
0414:                        getContextManager());
0415:                equalsNode = (BinaryRelationalOperatorNode) nodeFactory
0416:                        .getNode(C_NodeTypes.BINARY_EQUALS_OPERATOR_NODE, this ,
0417:                                falseNode, getContextManager());
0418:                nullableResult = dataTypeServices.isNullable();
0419:                equalsNode.setType(new DataTypeDescriptor(TypeId.BOOLEAN_ID,
0420:                        nullableResult));
0421:                return equalsNode;
0422:            }
0423:
0424:            /**
0425:             * Transform this into this is null.  Useful for NOT elimination.
0426:             *
0427:             * @return		The modified expression
0428:             *
0429:             * @exception StandardException		Thrown on error
0430:             */
0431:            public ValueNode genIsNullTree() throws StandardException {
0432:                IsNullNode isNullNode;
0433:
0434:                isNullNode = (IsNullNode) getNodeFactory().getNode(
0435:                        C_NodeTypes.IS_NULL_NODE, this , getContextManager());
0436:                isNullNode.setType(new DataTypeDescriptor(TypeId.BOOLEAN_ID,
0437:                        false));
0438:                return isNullNode;
0439:            }
0440:
0441:            /**
0442:             * Verify that eliminateNots() did its job correctly.  Verify that
0443:             * there are no NotNodes above the top level comparison operators
0444:             * and boolean expressions.
0445:             *
0446:             * @return		Boolean which reflects validity of the tree.
0447:             */
0448:            boolean verifyEliminateNots() {
0449:                if (SanityManager.ASSERT) {
0450:                    return (!(this  instanceof  NotNode));
0451:                } else {
0452:                    return true;
0453:                }
0454:            }
0455:
0456:            /**
0457:             * Do the 1st step in putting an expression into conjunctive normal
0458:             * form.  This step ensures that the top level of the expression is
0459:             * a chain of AndNodes.
0460:             *
0461:             * @return		The modified expression
0462:             *
0463:             * @exception StandardException		Thrown on error
0464:             */
0465:            public ValueNode putAndsOnTop() throws StandardException {
0466:                NodeFactory nodeFactory = getNodeFactory();
0467:
0468:                QueryTreeNode trueNode = nodeFactory.getNode(
0469:                        C_NodeTypes.BOOLEAN_CONSTANT_NODE, Boolean.TRUE,
0470:                        getContextManager());
0471:                AndNode andNode = (AndNode) nodeFactory.getNode(
0472:                        C_NodeTypes.AND_NODE, this , trueNode,
0473:                        getContextManager());
0474:                andNode.postBindFixup();
0475:                return andNode;
0476:            }
0477:
0478:            /**
0479:             * Verify that putAndsOnTop() did its job correctly.  Verify that the top level 
0480:             * of the expression is a chain of AndNodes.
0481:             *
0482:             * @return		Boolean which reflects validity of the tree.
0483:             */
0484:            public boolean verifyPutAndsOnTop() {
0485:                return true;
0486:            }
0487:
0488:            /**
0489:             * Finish putting an expression into conjunctive normal
0490:             * form.  An expression tree in conjunctive normal form meets
0491:             * the following criteria:
0492:             *		o  If the expression tree is not null,
0493:             *		   the top level will be a chain of AndNodes terminating
0494:             *		   in a true BooleanConstantNode.
0495:             *		o  The left child of an AndNode will never be an AndNode.
0496:             *		o  Any right-linked chain that includes an AndNode will
0497:             *		   be entirely composed of AndNodes terminated by a true BooleanConstantNode.
0498:             *		o  The left child of an OrNode will never be an OrNode.
0499:             *		o  Any right-linked chain that includes an OrNode will
0500:             *		   be entirely composed of OrNodes terminated by a false BooleanConstantNode.
0501:             *		o  ValueNodes other than AndNodes and OrNodes are considered
0502:             *		   leaf nodes for purposes of expression normalization.
0503:             *		   In other words, we won't do any normalization under
0504:             *		   those nodes.
0505:             *
0506:             * In addition, we track whether or not we are under a top level AndNode.  
0507:             * SubqueryNodes need to know this for subquery flattening.
0508:             *
0509:             * @param	underTopAndNode		Whether or not we are under a top level AndNode.
0510:             *							
0511:             *
0512:             * @return		The modified expression
0513:             *
0514:             * @exception StandardException		Thrown on error
0515:             */
0516:            public ValueNode changeToCNF(boolean underTopAndNode)
0517:                    throws StandardException {
0518:                return this ;
0519:            }
0520:
0521:            /**
0522:             * Verify that changeToCNF() did its job correctly.  Verify that:
0523:             *		o  AndNode  - rightOperand is not instanceof OrNode
0524:             *				      leftOperand is not instanceof AndNode
0525:             *		o  OrNode	- rightOperand is not instanceof AndNode
0526:             *					  leftOperand is not instanceof OrNode
0527:             *
0528:             * @return		Boolean which reflects validity of the tree.
0529:             */
0530:            public boolean verifyChangeToCNF() {
0531:                return true;
0532:            }
0533:
0534:            /**
0535:             * Categorize this predicate.  Initially, this means
0536:             * building a bit map of the referenced tables for each predicate.
0537:             * If the source of this ColumnReference (at the next underlying level) 
0538:             * is not a ColumnReference or a VirtualColumnNode then this predicate
0539:             * will not be pushed down.
0540:             *
0541:             * For example, in:
0542:             *		select * from (select 1 from s) a (x) where x = 1
0543:             * we will not push down x = 1.
0544:             * NOTE: It would be easy to handle the case of a constant, but if the
0545:             * inner SELECT returns an arbitrary expression, then we would have to copy
0546:             * that tree into the pushed predicate, and that tree could contain
0547:             * subqueries and method calls.
0548:             * RESOLVE - revisit this issue once we have views.
0549:             *
0550:             * @param referencedTabs	JBitSet with bit map of referenced FromTables
0551:             * @param simplePredsOnly	Whether or not to consider method
0552:             *							calls, field references and conditional nodes
0553:             *							when building bit map
0554:             *
0555:             * @return boolean		Whether or not source.expression is a ColumnReference
0556:             *						or a VirtualColumnNode.
0557:             *
0558:             * @exception StandardException			Thrown on error
0559:             */
0560:            public boolean categorize(JBitSet referencedTabs,
0561:                    boolean simplePredsOnly) throws StandardException {
0562:                return true;
0563:            }
0564:
0565:            /**
0566:             * This returns the user-supplied schema name of the column.
0567:             * At this class level, it simply returns null. But, the subclasses
0568:             * of ValueNode will overwrite this method to return the
0569:             * user-supplied schema name.
0570:             * 
0571:             * When the value node is in a result column of a select list,
0572:             * the user can request metadata information. The result column
0573:             * won't have a column descriptor, so we return some default
0574:             * information through the expression. This lets expressions that
0575:             * are simply columns return all of the info, and others use
0576:             * this supertype's default values.
0577:             *
0578:             * @return the default schema name for an expression -- null
0579:             */
0580:            public String getSchemaName() throws StandardException {
0581:                return null;
0582:            }
0583:
0584:            /**
0585:             * This returns the user-supplied table name of the column.
0586:             * At this class level, it simply returns null. But, the subclasses
0587:             * of ValueNode will overwrite this method to return the
0588:             * user-supplied table name.
0589:             *
0590:             * When the value node is in a result column of a select list,
0591:             * the user can request metadata information. The result column
0592:             * won't have a column descriptor, so we return some default
0593:             * information through the expression. This lets expressions that
0594:             * are simply columns return all of the info, and others use
0595:             * this supertype's default values.
0596:             *
0597:             * @return the default table name for an expression -- null
0598:             */
0599:            public String getTableName() {
0600:                return null;
0601:            }
0602:
0603:            /**
0604:             * @return the default updatability for an expression - false
0605:             */
0606:            public boolean updatableByCursor() {
0607:                return false;
0608:            }
0609:
0610:            /**
0611:             * This is null so that the caller will substitute in the resultset generated
0612:             * name as needed.
0613:             *
0614:             * @return the default column name for an expression -- null.
0615:             */
0616:            public String getColumnName() {
0617:                return null;
0618:            }
0619:
0620:            /**
0621:             * Get a bit map of table references in this expression
0622:             *
0623:             * @return	A bit map of table numbers referred to in this expression
0624:             *
0625:             * @exception StandardException			Thrown on error
0626:             */
0627:            JBitSet getTablesReferenced() throws StandardException {
0628:                ReferencedTablesVisitor rtv = new ReferencedTablesVisitor(
0629:                        new JBitSet(0));
0630:                accept(rtv);
0631:                return rtv.getTableMap();
0632:            }
0633:
0634:            /**
0635:             * Return whether or not this expression tree is cloneable.
0636:             *
0637:             * @return boolean	Whether or not this expression tree is cloneable.
0638:             */
0639:            public boolean isCloneable() {
0640:                return false;
0641:            }
0642:
0643:            /**
0644:             * Return a clone of this node.
0645:             *
0646:             * @return ValueNode	A clone of this node.
0647:             *
0648:             * @exception StandardException			Thrown on error
0649:             */
0650:            public ValueNode getClone() throws StandardException {
0651:                if (SanityManager.DEBUG) {
0652:                    SanityManager.ASSERT(false,
0653:                            "getClone() not expected to be called for "
0654:                                    + getClass().getName());
0655:                }
0656:                return null;
0657:            }
0658:
0659:            /**
0660:             * Copy all of the "appropriate fields" for a shallow copy.
0661:             *
0662:             * @param oldVN		The ValueNode to copy from.
0663:             *
0664:             */
0665:            public void copyFields(ValueNode oldVN) throws StandardException {
0666:                dataTypeServices = oldVN.getTypeServices();
0667:                typeId = oldVN.getTypeId();
0668:            }
0669:
0670:            /**
0671:             * Remap all ColumnReferences in this tree to be clones of the
0672:             * underlying expression.
0673:             *
0674:             * @return ValueNode			The remapped expression tree.
0675:             *
0676:             * @exception StandardException			Thrown on error
0677:             */
0678:            public ValueNode remapColumnReferencesToExpressions()
0679:                    throws StandardException {
0680:                return this ;
0681:            }
0682:
0683:            /**
0684:             * Return whether or not this expression tree represents a constant expression.
0685:             *
0686:             * @return	Whether or not this expression tree represents a constant expression.
0687:             */
0688:            public boolean isConstantExpression() {
0689:                return false;
0690:            }
0691:
0692:            /**
0693:             * Return whether or not this expression tree represents a constant value.
0694:             * In this case, "constant" means that it will always evaluate to the
0695:             * same thing, even if it includes columns.  A column is constant if it
0696:             * is compared to a constant expression.
0697:             *
0698:             * @return	True means this expression tree represents a constant value.
0699:             */
0700:            public boolean constantExpression(PredicateList whereClause) {
0701:                return false;
0702:            }
0703:
0704:            /**
0705:             * Bind time logic. Raises an error if this ValueNode, once compiled, returns
0706:             * unstable results AND if we're in a context where unstable results are
0707:             * forbidden.
0708:             *
0709:             * Called by children who may NOT appear in the WHERE subclauses of ADD TABLE clauses.
0710:             *
0711:             *	@param	fragmentType	Type of fragment as a String, for inclusion in error messages.
0712:             *	@param	fragmentBitMask	Type of fragment as a bitmask of possible fragment types
0713:             *
0714:             * @exception StandardException		Thrown on error
0715:             */
0716:            public void checkReliability(String fragmentType,
0717:                    int fragmentBitMask) throws StandardException {
0718:                // if we're in a context that forbids unreliable fragments, raise an error
0719:                if ((getCompilerContext().getReliability() & fragmentBitMask) != 0) {
0720:                    throwReliabilityException(fragmentType);
0721:                }
0722:            }
0723:
0724:            /**
0725:             * Bind time logic. Raises an error if this ValueNode, once compiled, returns
0726:             * unstable results AND if we're in a context where unstable results are
0727:             * forbidden.
0728:             *
0729:             * Called by children who may NOT appear in the WHERE subclauses of ADD TABLE clauses.
0730:             *
0731:             *	@param	fragmentBitMask	Type of fragment as a bitmask of possible fragment types
0732:             *	@param	fragmentType	Type of fragment as a String, to be fetch for the error message.
0733:             *
0734:             * @exception StandardException		Thrown on error
0735:             */
0736:            public void checkReliability(int fragmentBitMask,
0737:                    String fragmentType) throws StandardException {
0738:                // if we're in a context that forbids unreliable fragments, raise an error
0739:                if ((getCompilerContext().getReliability() & fragmentBitMask) != 0) {
0740:                    String fragmentTypeTxt = MessageService
0741:                            .getTextMessage(fragmentType);
0742:                    throwReliabilityException(fragmentTypeTxt);
0743:                }
0744:            }
0745:
0746:            /**
0747:             * Common code for the 2 checkReliability functions.  Always throws StandardException.
0748:             *
0749:             * @param fragmentType Type of fragment as a string, for inclusion in error messages.
0750:             * @exception StandardException        Throws an error, always.
0751:             */
0752:            private void throwReliabilityException(String fragmentType)
0753:                    throws StandardException {
0754:                String sqlState;
0755:                /* Error string somewhat dependent on operation due to different
0756:                 * nodes being allowed for different operations.
0757:                 */
0758:                if (getCompilerContext().getReliability() == CompilerContext.DEFAULT_RESTRICTION) {
0759:                    sqlState = SQLState.LANG_INVALID_DEFAULT_DEFINITION;
0760:                } else {
0761:                    sqlState = SQLState.LANG_UNRELIABLE_QUERY_FRAGMENT;
0762:                }
0763:                throw StandardException.newException(sqlState, fragmentType);
0764:            }
0765:
0766:            /**
0767:             * Return the variant type for the underlying expression.
0768:             * The variant type can be:
0769:             *		VARIANT				- variant within a scan
0770:             *							  (method calls and non-static field access)
0771:             *		SCAN_INVARIANT		- invariant within a scan
0772:             *							  (column references from outer tables)
0773:             *		QUERY_INVARIANT		- invariant within the life of a query
0774:             *							  (constant expressions)
0775:             *
0776:             * @return	The variant type for the underlying expression.
0777:             * @exception StandardException		Thrown on error
0778:             */
0779:            protected int getOrderableVariantType() throws StandardException {
0780:                // The default is VARIANT
0781:                return Qualifier.VARIANT;
0782:            }
0783:
0784:            /**
0785:             * Bind time logic. Raises an error if this ValueNode does not resolve to
0786:             *	a boolean value. This method is called by WHERE clauses.
0787:             *
0788:             *	@return	bound coercion of this node to a builtin type as necessary
0789:             *
0790:             * @exception StandardException		Thrown on error
0791:             */
0792:            public ValueNode checkIsBoolean() throws StandardException {
0793:                ValueNode whereClause = this ;
0794:
0795:                /*
0796:                 ** Is the datatype of the WHERE clause BOOLEAN?
0797:                 **
0798:                 ** NOTE: This test is not necessary in SQL92 entry level, because
0799:                 ** it is syntactically impossible to have a non-Boolean WHERE clause
0800:                 ** in that level of the standard.  But we intend to extend the
0801:                 ** language to allow Boolean user functions in the WHERE clause,
0802:                 ** so we need to test for the error condition.
0803:                 */
0804:                TypeId whereTypeId = whereClause.getTypeId();
0805:
0806:                /* If the where clause is not a built-in type, then generate a bound 
0807:                 * conversion tree to a built-in type.
0808:                 */
0809:                if (whereTypeId.userType()) {
0810:                    whereClause = whereClause.genSQLJavaSQLTree();
0811:                    whereTypeId = whereClause.getTypeId();
0812:                }
0813:
0814:                if (!whereTypeId.equals(TypeId.BOOLEAN_ID)) {
0815:                    throw StandardException.newException(
0816:                            SQLState.LANG_NON_BOOLEAN_WHERE_CLAUSE, whereTypeId
0817:                                    .getSQLTypeName());
0818:                }
0819:
0820:                return whereClause;
0821:            }
0822:
0823:            /**
0824:             * Return an Object representing the bind time value of this
0825:             * expression tree.  If the expression tree does not evaluate to
0826:             * a constant at bind time then we return null.
0827:             * This is useful for bind time resolution of VTIs.
0828:             * RESOLVE: What do we do for primitives?
0829:             *
0830:             * @return	An Object representing the bind time value of this expression tree.
0831:             *			(null if not a bind time constant.)
0832:             *
0833:             * @exception StandardException		Thrown on error
0834:             */
0835:            Object getConstantValueAsObject() throws StandardException {
0836:                return null;
0837:            }
0838:
0839:            /////////////////////////////////////////////////////////////////////////
0840:            //
0841:            //	The ValueNode defers its generate() work to a method that works on
0842:            //	ExpressionClassBuilders rather than ActivationClassBuilders. This
0843:            //	is so that expression generation can be shared by the Core compiler
0844:            //	AND the Replication Filter compiler.
0845:            //
0846:            /////////////////////////////////////////////////////////////////////////
0847:
0848:            /**
0849:             * Do the code generation for this node.  Call the more general
0850:             * routine that generates expressions.
0851:             *
0852:             * @param acb	The ActivationClassBuilder for the class being built
0853:             * @param mb	The method the expression will go into
0854:             *
0855:             *
0856:             * @exception StandardException		Thrown on error
0857:             */
0858:
0859:            protected final void generate(ActivationClassBuilder acb,
0860:                    MethodBuilder mb) throws StandardException {
0861:                generateExpression(acb, mb);
0862:            }
0863:
0864:            /**
0865:             * The only reason this routine exists is so that I don't have to change
0866:             * the protection on generateExpression() and rototill all of QueryTree.
0867:             *
0868:             * @param ecb	The ExpressionClassBuilder for the class being built
0869:             * @param mb	The method the expression will go into
0870:             *
0871:             *
0872:             * @exception StandardException		Thrown on error
0873:             */
0874:            public void generateFilter(ExpressionClassBuilder ecb,
0875:                    MethodBuilder mb) throws StandardException {
0876:                generateExpression(ecb, mb);
0877:            }
0878:
0879:            /**
0880:             * The default selectivity for value nodes is 50%.  This is overridden
0881:             * in specific cases, such as the RelationalOperators.
0882:             */
0883:            public double selectivity(Optimizable optTable)
0884:                    throws StandardException {
0885:                // Return 1 if additional predicates have been generated from this one.
0886:                if (transformed) {
0887:                    return 1.0;
0888:                } else {
0889:                    return 0.5d;
0890:                }
0891:            }
0892:
0893:            /**
0894:             * Update the array of columns in = conditions with expressions without
0895:             * column references from the same table.  This is useful when doing
0896:             * subquery flattening on the basis of an equality condition.
0897:             * eqOuterCols or tableColMap may be null if the calling routine
0898:             * doesn't need the information provided
0899:             *
0900:             * @param tableNumber	The tableNumber of the table from which
0901:             *						the columns of interest come from.
0902:             * @param eqOuterCols	Array of booleans for noting which columns
0903:             *						are in = predicates without columns from the
0904:             *						subquery block. May be null.
0905:             * @param tableNumbers	Array of table numbers in this query block.
0906:             * @param tableColMap	Array of bits for noting which columns
0907:             *						are in = predicates for each table in the
0908:             *						query block. May be null.
0909:             * @param resultColTable True if tableNumber is the table containing result
0910:             * 						columns
0911:             *
0912:             * @exception StandardException			Thrown on error
0913:             * 
0914:             */
0915:            void checkTopPredicatesForEqualsConditions(int tableNumber,
0916:                    boolean[] eqOuterCols, int[] tableNumbers,
0917:                    JBitSet[] tableColMap, boolean resultColTable)
0918:                    throws StandardException {
0919:                for (ValueNode whereWalker = this ; whereWalker instanceof  AndNode; whereWalker = ((AndNode) whereWalker)
0920:                        .getRightOperand()) {
0921:                    // See if this is a candidate =
0922:                    AndNode and = (AndNode) whereWalker;
0923:
0924:                    if (!and.getLeftOperand().isRelationalOperator()
0925:                            || !(((RelationalOperator) (and.getLeftOperand()))
0926:                                    .getOperator() == RelationalOperator.EQUALS_RELOP)) {
0927:                        continue;
0928:                    }
0929:
0930:                    BinaryRelationalOperatorNode beon = (BinaryRelationalOperatorNode) and
0931:                            .getLeftOperand();
0932:                    ValueNode left = beon.getLeftOperand();
0933:                    ValueNode right = beon.getRightOperand();
0934:                    int resultTable = 0;
0935:                    if (resultColTable) {
0936:                        for (; resultTable < tableNumbers.length; resultTable++) {
0937:                            if (tableNumbers[resultTable] == tableNumber)
0938:                                break;
0939:                        }
0940:                    } else
0941:                        resultTable = -1;
0942:
0943:                    /* Is this = of the right form? */
0944:                    if ((left instanceof  ColumnReference)
0945:                            && ((ColumnReference) left).getTableNumber() == tableNumber) {
0946:                        updateMaps(tableColMap, eqOuterCols, tableNumbers,
0947:                                tableNumber, resultTable, right, left);
0948:                    } else if ((right instanceof  ColumnReference)
0949:                            && ((ColumnReference) right).getTableNumber() == tableNumber) {
0950:                        updateMaps(tableColMap, eqOuterCols, tableNumbers,
0951:                                tableNumber, resultTable, left, right);
0952:                    }
0953:                }
0954:            }
0955:
0956:            /**
0957:             * Does this represent a true constant.
0958:             *
0959:             * @return Whether or not this node represents a true constant.
0960:             */
0961:            boolean isBooleanTrue() {
0962:                return false;
0963:            }
0964:
0965:            /**
0966:             * Does this represent a false constant.
0967:             *
0968:             * @return Whether or not this node represents a false constant.
0969:             */
0970:            boolean isBooleanFalse() {
0971:                return false;
0972:            }
0973:
0974:            /**
0975:             * Generate code for this calculation.  This is a place-holder method -
0976:             * it should not be called.
0977:             *
0978:             * @param acb	The ExpressionClassBuilder for the class being built
0979:             * @param mb	The method the expression will go into
0980:             *
0981:             *
0982:             * @exception StandardException		Thrown on error
0983:             */
0984:
0985:            public void generateExpression(ExpressionClassBuilder acb,
0986:                    MethodBuilder mb) throws StandardException {
0987:                if (SanityManager.DEBUG)
0988:                    SanityManager
0989:                            .ASSERT(false,
0990:                                    "Code generation for this type of ValueNode is unimplemented");
0991:            }
0992:
0993:            /**
0994:             * Set the correct bits in tableColMap and set the boolean value in eqOuterCols 
0995:             * given two arguments to an = predicate
0996:             * tableColMap[t] - bit is set if the column is in an = predicate with a column 
0997:             *					in table t, or a bit is set if the column is in an 
0998:             *					= predicate with a constant,parameter or correlation variable 
0999:             *				    (for all table t, if this tableColMap is not for the
1000:             *					table with the result columns)
1001:             * eqOuterCols[c] - is true if the column is in an = predicate with a constant,
1002:             *					parameter or correlation variable
1003:             * 
1004:             *
1005:             * @param tableColMap	Array of bitmaps for noting which columns are in = 
1006:             *						predicates with columns from each table
1007:             * @param eqOuterCols	Array of booleans for noting which columns
1008:             *						are in = predicates without columns from the
1009:             *						subquery block.
1010:             * @param tableNumber	table number for which we are setting up the Maps
1011:             * @param resultTable	-1 if this table is not the result table; otherwise
1012:             *						the index into tableNumbers for the result table
1013:             * @param arg1			one side of the = predicate
1014:             * @param arg2			other side of the = predicate
1015:             *
1016:             *
1017:             * @exception StandardException		Thrown on error
1018:             */
1019:            private void updateMaps(JBitSet[] tableColMap,
1020:                    boolean[] eqOuterCols, int[] tableNumbers, int tableNumber,
1021:                    int resultTable, ValueNode arg1, ValueNode arg2)
1022:                    throws StandardException {
1023:                /* arg2 is a column from our table.  This
1024:                 * is a good = for both All tables and Outer arrays
1025:                 * if the right side is a constant or a parameter
1026:                 * or a column from an outer table.
1027:                 * It is a good = for only the All array if
1028:                 * the right side is a column from this query block.
1029:                 */
1030:                if ((arg1 instanceof  ConstantNode)
1031:                        || (arg1.requiresTypeFromContext())) {
1032:                    setValueCols(tableColMap, eqOuterCols,
1033:                            ((ColumnReference) arg2).getColumnNumber(),
1034:                            resultTable);
1035:                } else if ((arg1 instanceof  ColumnReference && ((ColumnReference) arg1)
1036:                        .getTableNumber() != tableNumber)) {
1037:                    /* See if other columns is a correlation column */
1038:                    int otherTN = ((ColumnReference) arg1).getTableNumber();
1039:                    int index = 0;
1040:                    int colNumber = ((ColumnReference) arg2).getColumnNumber();
1041:
1042:                    for (; index < tableNumbers.length; index++) {
1043:                        if (otherTN == tableNumbers[index]) {
1044:                            break;
1045:                        }
1046:                    }
1047:                    /* Correlation column, so we can treat it as a constant */
1048:                    if (index == tableNumbers.length) {
1049:                        setValueCols(tableColMap, eqOuterCols, colNumber,
1050:                                resultTable);
1051:                    } else if (tableColMap != null) {
1052:                        tableColMap[index].set(colNumber);
1053:                    }
1054:
1055:                } else {
1056:                    /* See if other side contains a column reference from the same table */
1057:                    JBitSet referencedTables = arg1.getTablesReferenced();
1058:                    /* See if other columns are all correlation columns */
1059:                    int index = 0;
1060:                    int colNumber = ((ColumnReference) arg2).getColumnNumber();
1061:                    for (; index < tableNumbers.length; index++) {
1062:                        if (referencedTables.get(tableNumbers[index])) {
1063:                            break;
1064:                        }
1065:                    }
1066:                    /* Correlation column, so we can treat it as a constant */
1067:                    if (index == tableNumbers.length) {
1068:                        setValueCols(tableColMap, eqOuterCols, colNumber,
1069:                                resultTable);
1070:                    } else if (tableColMap != null
1071:                            && !referencedTables.get(tableNumber)) {
1072:                        tableColMap[index].set(colNumber);
1073:                    }
1074:                }
1075:            }
1076:
1077:            /**
1078:             * Set eqOuterCols and the column in all the tables for constants,
1079:             * parmeters and correlation columns
1080:             * The column in the tableColMap is set only for the current table
1081:             * if the table is the result column table.  For other tables in the
1082:             * query we set the column for all the tables since the constant will
1083:             * reduced the number of columns required in a unique multicolumn index for
1084:             * distinctness.
1085:             * For example, given an unique index on t1(a,b), setting b=1 means that
1086:             * t1(a) is unique since there can be no duplicates for a where b=1 without
1087:             * destroying the uniqueness of t1(a,b).  However, for the result columns
1088:             * setting b=1, does not mean that a select list of t1.a is distinct if
1089:             * t1.a is the only column used in joining with another table
1090:             * e.g. select t1.a from t1, t2 where t1.a = t2.a and t1.b = 1;
1091:             * 
1092:             * 	t1			t2			result
1093:             *	a	b		a			a
1094:             *  1	1		1			1
1095:             *  1 	2		2			1
1096:             *	2	1
1097:             * 
1098:             *
1099:             * @param tableColMap	Array of bitmaps for noting which columns are in = 
1100:             *						predicates with columns from each table
1101:             * @param eqOuterCols	Array of booleans for noting which columns
1102:             *						are in = predicates without columns from the
1103:             *						subquery block.
1104:             * @param colReference	The column to set
1105:             * @param resultTable	If -1 set all the bit for all the tables for that
1106:             *						column; otherwise set the bit for the specified table
1107:             *
1108:             *
1109:             */
1110:            private void setValueCols(JBitSet[] tableColMap,
1111:                    boolean[] eqOuterCols, int colReference, int resultTable) {
1112:                if (eqOuterCols != null)
1113:                    eqOuterCols[colReference] = true;
1114:
1115:                if (tableColMap != null) {
1116:                    if (resultTable == -1) {
1117:                        for (int i = 0; i < tableColMap.length; i++)
1118:                            tableColMap[i].set(colReference);
1119:                    } else
1120:                        tableColMap[resultTable].set(colReference);
1121:                }
1122:            }
1123:
1124:            /**
1125:             * Returns true if this ValueNode is a relational operator. Relational
1126:             * Operators are <, <=, =, >, >=, <> as well as IS NULL and IS NOT
1127:             * NULL. This is the preferred way of figuring out if a ValueNode is
1128:             * relational or not. 
1129:             * @see RelationalOperator
1130:             * @see BinaryRelationalOperatorNode
1131:             * @see IsNullNode
1132:             */
1133:            public boolean isRelationalOperator() {
1134:                return false;
1135:            }
1136:
1137:            /**
1138:             * Returns true if this value node is a <em>equals</em> operator. 
1139:             *
1140:             * @see ValueNode#isRelationalOperator
1141:             */
1142:            public boolean isBinaryEqualsOperatorNode() {
1143:                return false;
1144:            }
1145:
1146:            /** Return true if the predicate represents an optimizable equality node.
1147:             * an expression is considered to be an optimizable equality node if all the
1148:             * following conditions are met:
1149:             * <ol>
1150:             * <li> the operator is an <em>=</em> or <em>IS NULL</em> operator </li>
1151:             * <li> one of the operands is a column specified by optTable/columnNumber</li>
1152:             * <li> Both operands are not the same column; i.e tab.col = tab.col </li>
1153:             * <li> There are no implicit varchar comparisons of the operands; i.e
1154:             * either both operands are string like (varchar, char, longvarchar) or
1155:             * neither operand is string like </li>
1156:             * </ol>
1157:             * 
1158:             * @param optTable	the table being optimized. Column reference must be from
1159:             * this table.
1160:             * @param columnNumber the column number. One of the operands of this
1161:             * predicate must be the column number specified by optTable/columnNumber
1162:             * @param isNullOkay if set to true we also consider IS NULL predicates;
1163:             * otherwise consider only = predicates.
1164:             */
1165:            public boolean optimizableEqualityNode(Optimizable optTable,
1166:                    int columnNumber, boolean isNullOkay)
1167:                    throws StandardException {
1168:                return false;
1169:            }
1170:
1171:            /**
1172:             * Returns TRUE if the type of this node will be determined from the
1173:             * context in which it is getting used.
1174:             *
1175:             * @return Whether this node's type will be determined from the context
1176:             */
1177:            public boolean requiresTypeFromContext() {
1178:                return false;
1179:            }
1180:
1181:            /**
1182:             * Returns TRUE if this is a parameter node. We do lots of special things
1183:             * with Parameter Nodes.
1184:             *
1185:             */
1186:            public boolean isParameterNode() {
1187:                return false;
1188:            }
1189:
1190:            /**
1191:             * Tests if this node is equivalent to the specified ValueNode. Two 
1192:             * ValueNodes are considered equivalent if they will evaluate to the same
1193:             * value during query execution. 
1194:             * <p> 
1195:             * This method provides basic expression matching facility for the derived 
1196:             * class of ValueNode and it is used by the language layer to compare the 
1197:             * node structural form of the two expressions for equivalence at bind 
1198:             * phase.  
1199:             *  <p>
1200:             * Note that it is not comparing the actual row values at runtime to produce 
1201:             * a result; hence, when comparing SQL NULLs, they are considered to be 
1202:             * equivalent and not unknown.  
1203:             *  <p>
1204:             * One usage case of this method in this context is to compare the select 
1205:             * column expression against the group by expression to check if they are 
1206:             * equivalent.  e.g.:
1207:             *  <p>
1208:             * SELECT c1+c2 FROM t1 GROUP BY c1+c2   
1209:             *  <p>
1210:             * In general, node equivalence is determined by the derived class of 
1211:             * ValueNode.  But they generally abide to the rules below:
1212:             *  <ul>
1213:             * <li>The two ValueNodes must be of the same node type to be considered 
1214:             *   equivalent.  e.g.:  CastNode vs. CastNode - equivalent (if their args 
1215:             *   also match), ColumnReference vs CastNode - not equivalent.
1216:             *   
1217:             * <li>If node P contains other ValueNode(s) and so on, those node(s) must 
1218:             *   also be of the same node type to be considered equivalent.
1219:             *   
1220:             * <li>If node P takes a parameter list, then the number of arguments and its 
1221:             *   arguments for the two nodes must also match to be considered 
1222:             *   equivalent.  e.g.:  CAST(c1 as INTEGER) vs CAST(c1 as SMALLINT), they 
1223:             *   are not equivalent.
1224:             *   
1225:             * <li>When comparing SQL NULLs in this context, they are considered to be 
1226:             *   equivalent.
1227:             * 
1228:             * <li>If this does not apply or it is determined that the two nodes are not 
1229:             *   equivalent then the derived class of this method should return false; 
1230:             *   otherwise, return true.
1231:             * </ul>   
1232:             *   
1233:             * @param other the node to compare this ValueNode against.
1234:             * @return <code>true</code> if the two nodes are equivalent, 
1235:             * <code>false</code> otherwise.
1236:             * 
1237:             * @throws StandardException 
1238:             */
1239:            protected abstract boolean isEquivalent(ValueNode other)
1240:                    throws StandardException;
1241:
1242:            /**
1243:             * Tests if this node is of the same type as the specified node as
1244:             * reported by {@link QueryTreeNode#getNodeType()}.
1245:             * 
1246:             * @param other the node to compare this value node against. 
1247:             * 
1248:             * @return <code>true</code> if the two nodes are of the same type.  
1249:             */
1250:            protected final boolean isSameNodeType(ValueNode other) {
1251:                if (other != null) {
1252:                    return other.getNodeType() == getNodeType();
1253:                }
1254:                return false;
1255:            }
1256:
1257:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.