Source Code Cross Referenced for ResultColumn.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.ResultColumn
0004:
0005:           Licensed to the Apache Software Foundation (ASF) under one or more
0006:           contributor license agreements.  See the NOTICE file distributed with
0007:           this work for additional information regarding copyright ownership.
0008:           The ASF licenses this file to you under the Apache License, Version 2.0
0009:           (the "License"); you may not use this file except in compliance with
0010:           the License.  You may obtain a copy of the License at
0011:
0012:              http://www.apache.org/licenses/LICENSE-2.0
0013:
0014:           Unless required by applicable law or agreed to in writing, software
0015:           distributed under the License is distributed on an "AS IS" BASIS,
0016:           WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0017:           See the License for the specific language governing permissions and
0018:           limitations under the License.
0019:
0020:         */
0021:
0022:        package org.apache.derby.impl.sql.compile;
0023:
0024:        import org.apache.derby.iapi.services.compiler.MethodBuilder;
0025:
0026:        import org.apache.derby.iapi.services.sanity.SanityManager;
0027:        import org.apache.derby.iapi.services.context.ContextManager;
0028:
0029:        import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
0030:
0031:        import org.apache.derby.iapi.types.DataTypeDescriptor;
0032:        import org.apache.derby.iapi.types.DataValueDescriptor;
0033:        import org.apache.derby.iapi.types.StringDataValue;
0034:        import org.apache.derby.iapi.sql.ResultColumnDescriptor;
0035:        import org.apache.derby.iapi.types.DataTypeDescriptor;
0036:        import org.apache.derby.iapi.types.DataValueDescriptor;
0037:        import org.apache.derby.iapi.types.TypeId;
0038:        import org.apache.derby.iapi.services.io.StoredFormatIds;
0039:        import org.apache.derby.iapi.types.DataValueFactory;
0040:
0041:        import org.apache.derby.iapi.sql.dictionary.DataDictionary;
0042:        import org.apache.derby.iapi.sql.dictionary.TableDescriptor;
0043:        import org.apache.derby.iapi.sql.dictionary.ColumnDescriptor;
0044:
0045:        import org.apache.derby.iapi.sql.compile.CompilerContext;
0046:        import org.apache.derby.iapi.sql.compile.RowOrdering;
0047:        import org.apache.derby.iapi.sql.compile.Visitable;
0048:        import org.apache.derby.iapi.sql.compile.Visitor;
0049:        import org.apache.derby.iapi.sql.compile.C_NodeTypes;
0050:
0051:        import org.apache.derby.impl.sql.compile.ActivationClassBuilder;
0052:        import org.apache.derby.impl.sql.compile.ExpressionClassBuilder;
0053:
0054:        import org.apache.derby.iapi.store.access.Qualifier;
0055:
0056:        import org.apache.derby.iapi.error.StandardException;
0057:        import org.apache.derby.iapi.reference.SQLState;
0058:        import org.apache.derby.iapi.reference.ClassName;
0059:
0060:        import org.apache.derby.iapi.util.JBitSet;
0061:        import org.apache.derby.iapi.util.StringUtil;
0062:
0063:        import java.sql.Types;
0064:
0065:        import java.util.Vector;
0066:
0067:        /**
0068:         * A ResultColumn represents a result column in a SELECT, INSERT, or UPDATE
0069:         * statement.  In a SELECT statement, the result column just represents an
0070:         * expression in a row being returned to the client.  For INSERT and UPDATE
0071:         * statements, the result column represents an column in a stored table.
0072:         * So, a ResultColumn has to be bound differently depending on the type of
0073:         * statement it appears in.
0074:         *
0075:         * @author Jeff Lichtman
0076:         */
0077:
0078:        public class ResultColumn extends ValueNode implements 
0079:                ResultColumnDescriptor, Comparable {
0080:            /* name and exposedName should point to the same string, unless there is a
0081:             * derived column list, in which case name will point to the underlying name
0082:             * and exposedName will point to the name from the derived column list.
0083:             */
0084:            String name;
0085:            String exposedName;
0086:            String tableName;
0087:            String sourceTableName;
0088:            //Used by metadata api ResultSetMetaData.getSchemaName to get a column's table's schema.
0089:            String sourceSchemaName;
0090:            ValueNode expression;
0091:            ColumnDescriptor columnDescriptor;
0092:            boolean isGenerated;
0093:            boolean isGeneratedForUnmatchedColumnInInsert;
0094:            boolean isGroupingColumn;
0095:            boolean isReferenced;
0096:            boolean isRedundant;
0097:            boolean isNameGenerated;
0098:            boolean updated;
0099:            boolean updatableByCursor;
0100:            private boolean defaultColumn;
0101:
0102:            // tells us if this ResultColumn is a placeholder for a generated
0103:            // autoincrement value for an insert statement.
0104:            boolean autoincrementGenerated;
0105:
0106:            // tells us if this ResultColumn represents an autoincrement column in a
0107:            // base table.
0108:            boolean autoincrement;
0109:
0110:            /* ResultSetNumber for the ResultSet (at generate() time) that we belong to */
0111:            private int resultSetNumber = -1;
0112:            ColumnReference reference; // used to verify quals at bind time, if given.
0113:
0114:            /* virtualColumnId is the ResultColumn's position (1-based) within the ResultSet */
0115:            private int virtualColumnId;
0116:
0117:            /**
0118:             * Different types of initializer parameters indicate different
0119:             * types of initialization. Parameters may be:
0120:             *
0121:             * <ul>
0122:             * <li>arg1	The name of the column, if any.</li>
0123:             * <li>arg2	The expression this result column represents</li>
0124:             * </ul>
0125:             *
0126:             * <p>
0127:             * - OR -
0128:             * </p>
0129:             *
0130:             * <ul>
0131:             * <li>arg1	a column reference node</li>
0132:             * <li>arg2	The expression this result column represents</li>
0133:             * </ul>
0134:             *
0135:             * <p>
0136:             * - OR -
0137:             * </p>
0138:             *
0139:             * <ul>
0140:             * <li>arg1	The column descriptor.</li>
0141:             * <li>arg2	The expression this result column represents</li>
0142:             * </ul>
0143:             *
0144:             * <p>
0145:             * - OR -
0146:             * </p>
0147:             *
0148:             * <ul>
0149:             * <li>dtd			The type of the column</li>
0150:             * <li>expression	The expression this result column represents</li>
0151:             * </ul>
0152:             */
0153:            public void init(Object arg1, Object arg2) throws StandardException {
0154:                // RESOLVE: This is something of a hack - it is not obvious that
0155:                // the first argument being null means it should be treated as
0156:                // a String.
0157:                if ((arg1 instanceof  String) || (arg1 == null)) {
0158:                    this .name = (String) arg1;
0159:                    this .exposedName = this .name;
0160:                    this .expression = (ValueNode) arg2;
0161:                } else if (arg1 instanceof  ColumnReference) {
0162:                    ColumnReference ref = (ColumnReference) arg1;
0163:
0164:                    this .name = ref.getColumnName();
0165:                    this .exposedName = ref.getColumnName();
0166:                    /*
0167:                    	when we bind, we'll want to make sure
0168:                    	the reference has the right table name.
0169:                     */
0170:                    this .reference = ref;
0171:                    this .expression = (ValueNode) arg2;
0172:                } else if (arg1 instanceof  ColumnDescriptor) {
0173:                    ColumnDescriptor coldes = (ColumnDescriptor) arg1;
0174:                    DataTypeDescriptor colType = coldes.getType();
0175:
0176:                    this .name = coldes.getColumnName();
0177:                    this .exposedName = name;
0178:                    /* Clone the type info here, so we can change nullability if needed */
0179:                    setType(new DataTypeDescriptor(colType, colType
0180:                            .isNullable()));
0181:                    this .columnDescriptor = coldes;
0182:                    this .expression = (ValueNode) arg2;
0183:                    this .autoincrement = coldes.isAutoincrement();
0184:                } else {
0185:                    setType((DataTypeDescriptor) arg1);
0186:                    this .expression = (ValueNode) arg2;
0187:                    if (arg2 instanceof  ColumnReference) {
0188:                        reference = (ColumnReference) arg2;
0189:                    }
0190:                }
0191:
0192:                /* this result column represents a <default> keyword in an insert or
0193:                 * update statement
0194:                 */
0195:                if (expression != null
0196:                        && expression.isInstanceOf(C_NodeTypes.DEFAULT_NODE))
0197:                    defaultColumn = true;
0198:            }
0199:
0200:            /**
0201:             * Returns TRUE if the ResultColumn is standing in for a DEFAULT keyword in
0202:             * an insert/update statement.
0203:             */
0204:            public boolean isDefaultColumn() {
0205:                return defaultColumn;
0206:            }
0207:
0208:            public void setDefaultColumn(boolean value) {
0209:                defaultColumn = value;
0210:            }
0211:
0212:            /**
0213:             * The following methods implement the ResultColumnDescriptor
0214:             * interface.  See the Language Module Interface for details.
0215:             */
0216:
0217:            public String getName() {
0218:                return exposedName;
0219:            }
0220:
0221:            public String getSchemaName() throws StandardException {
0222:                if ((columnDescriptor != null)
0223:                        && (columnDescriptor.getTableDescriptor() != null))
0224:                    return columnDescriptor.getTableDescriptor()
0225:                            .getSchemaName();
0226:                else {
0227:                    if (expression != null)
0228:                        // REMIND: could look in reference, if set.
0229:                        return expression.getSchemaName();
0230:                    else
0231:                        return null;
0232:                }
0233:            }
0234:
0235:            public String getTableName() {
0236:                if (tableName != null) {
0237:                    return tableName;
0238:                }
0239:                if ((columnDescriptor != null)
0240:                        && (columnDescriptor.getTableDescriptor() != null)) {
0241:                    return columnDescriptor.getTableDescriptor().getName();
0242:                } else {
0243:                    return expression.getTableName();
0244:                }
0245:            }
0246:
0247:            /**
0248:             * @see ResultColumnDescriptor#getSourceTableName
0249:             */
0250:            public String getSourceTableName() {
0251:                return sourceTableName;
0252:            }
0253:
0254:            /**
0255:             * @see ResultColumnDescriptor#getSourceSchemaName
0256:             */
0257:            public String getSourceSchemaName() {
0258:                return sourceSchemaName;
0259:            }
0260:
0261:            /**
0262:             * Clear the table name for the underlying ColumnReference.
0263:             * See UpdateNode.scrubResultColumns() for full explaination.
0264:             */
0265:            public void clearTableName() {
0266:                if (expression instanceof  ColumnReference) {
0267:                    ((ColumnReference) expression)
0268:                            .setTableNameNode((TableName) null);
0269:                }
0270:            }
0271:
0272:            public DataTypeDescriptor getType() {
0273:                return dataTypeServices;
0274:            }
0275:
0276:            public DataTypeDescriptor getExpressionType()
0277:                    throws StandardException {
0278:                return (expression == null) ? dataTypeServices : expression
0279:                        .getTypeServices();
0280:            }
0281:
0282:            public int getColumnPosition() {
0283:                if (columnDescriptor != null)
0284:                    return columnDescriptor.getPosition();
0285:                else
0286:                    return virtualColumnId;
0287:
0288:            }
0289:
0290:            /**
0291:             * Set the expression in this ResultColumn.  This is useful in those
0292:             * cases where you don't know the expression in advance, like for
0293:             * INSERT statements with column lists, where the column list and
0294:             * SELECT or VALUES clause are parsed separately, and then have to
0295:             * be hooked up.
0296:             *
0297:             * @param expression	The expression to be set in this ResultColumn
0298:             */
0299:
0300:            public void setExpression(ValueNode expression) {
0301:                this .expression = expression;
0302:            }
0303:
0304:            /**
0305:             * Get the expression in this ResultColumn.  
0306:             *
0307:             * @return ValueNode	this.expression
0308:             */
0309:
0310:            public ValueNode getExpression() {
0311:                return expression;
0312:            }
0313:
0314:            /**
0315:             * Set the expression to a null node of the
0316:             * correct type.
0317:             *
0318:             * @exception StandardException		Thrown on error
0319:             */
0320:            void setExpressionToNullNode() throws StandardException {
0321:                expression = getNullNode(getTypeId(), getContextManager());
0322:            }
0323:
0324:            /**
0325:             * Set the name in this ResultColumn.  This is useful when you don't
0326:             * know the name at the time you create the ResultColumn, for example,
0327:             * in an insert-select statement, where you want the names of the
0328:             * result columns to match the table being inserted into, not the
0329:             * table they came from.
0330:             *
0331:             * @param name	The name to set in this ResultColumn
0332:             */
0333:
0334:            public void setName(String name) {
0335:                if (this .name == null) {
0336:                    this .name = name;
0337:                } else {
0338:                    if (SanityManager.DEBUG)
0339:                        SanityManager.ASSERT(reference == null
0340:                                || name.equals(reference.getColumnName()),
0341:                                "don't change name from reference name");
0342:                }
0343:
0344:                this .exposedName = name;
0345:            }
0346:
0347:            /**
0348:             * Is the name for this ResultColumn generated?
0349:             */
0350:            public boolean isNameGenerated() {
0351:                return isNameGenerated;
0352:            }
0353:
0354:            /**
0355:             * Set that this result column name is generated.
0356:             */
0357:            public void setNameGenerated(boolean value) {
0358:                isNameGenerated = value;
0359:            }
0360:
0361:            /**
0362:             * Set the resultSetNumber for this ResultColumn.  This is the 
0363:             * resultSetNumber for the ResultSet that we belong to.  This
0364:             * is useful for generate() and necessary since we do not have a
0365:             * back pointer to the RSN.
0366:             *
0367:             * @param resultSetNumber	The resultSetNumber.
0368:             */
0369:            public void setResultSetNumber(int resultSetNumber) {
0370:                this .resultSetNumber = resultSetNumber;
0371:            }
0372:
0373:            /**
0374:             * Get the resultSetNumber for this ResultColumn.
0375:             *
0376:             * @return int	The resultSetNumber.
0377:             */
0378:            public int getResultSetNumber() {
0379:                return resultSetNumber;
0380:            }
0381:
0382:            /**
0383:             * Set the clause that this node appears in.
0384:             *
0385:             * @param clause	The clause that this node appears in.
0386:             */
0387:            public void setClause(int clause) {
0388:                super .setClause(clause);
0389:                /* expression will be null for AllResultColumn */
0390:                if (expression != null) {
0391:                    expression.setClause(clause);
0392:                } else if (SanityManager.DEBUG) {
0393:                    SanityManager
0394:                            .ASSERT(this  instanceof  AllResultColumn,
0395:                                    "this expected to be instanceof AllResultColumn when expression is null");
0396:                }
0397:            }
0398:
0399:            /** 
0400:             * Adjust the virtualColumnId for this ResultColumn	by the specified amount
0401:             * 
0402:             * @param adjust	The adjustment for the virtualColumnId
0403:             */
0404:
0405:            public void adjustVirtualColumnId(int adjust) {
0406:                virtualColumnId += adjust;
0407:            }
0408:
0409:            /** 
0410:             * Set the virtualColumnId for this ResultColumn
0411:             * 
0412:             * @param id	The virtualColumnId for this ResultColumn
0413:             */
0414:
0415:            public void setVirtualColumnId(int id) {
0416:                virtualColumnId = id;
0417:            }
0418:
0419:            /**
0420:             * Get the virtualColumnId for this ResultColumn
0421:             *
0422:             * @return virtualColumnId for this ResultColumn
0423:             */
0424:            public int getVirtualColumnId() {
0425:                return virtualColumnId;
0426:            }
0427:
0428:            /**
0429:             * Generate a unique (across the entire statement) column name for unnamed
0430:             * ResultColumns
0431:             *
0432:             * @exception StandardException		Thrown on error
0433:             */
0434:            public void guaranteeColumnName() throws StandardException {
0435:                if (exposedName == null) {
0436:                    /* Unions may also need generated names, if both sides name don't match */
0437:                    exposedName = "SQLCol"
0438:                            + getCompilerContext().getNextColumnNumber();
0439:                    isNameGenerated = true;
0440:                }
0441:            }
0442:
0443:            /**
0444:             * Convert this object to a String.  See comments in QueryTreeNode.java
0445:             * for how this should be done for tree printing.
0446:             *
0447:             * @return	This object as a String
0448:             */
0449:
0450:            public String toString() {
0451:                if (SanityManager.DEBUG) {
0452:                    return "exposedName: " + exposedName + "\n" + "name: "
0453:                            + name + "\n" + "tableName: " + tableName + "\n"
0454:                            + "isNameGenerated: " + isNameGenerated + "\n"
0455:                            + "sourceTableName: " + sourceTableName + "\n"
0456:                            + "type: " + dataTypeServices + "\n"
0457:                            + "columnDescriptor: " + columnDescriptor + "\n"
0458:                            + "isGenerated: " + isGenerated + "\n"
0459:                            + "isGeneratedForUnmatchedColumnInInsert: "
0460:                            + isGeneratedForUnmatchedColumnInInsert + "\n"
0461:                            + "isGroupingColumn: " + isGroupingColumn + "\n"
0462:                            + "isReferenced: " + isReferenced + "\n"
0463:                            + "isRedundant: " + isRedundant + "\n"
0464:                            + "virtualColumnId: " + virtualColumnId + "\n"
0465:                            + "resultSetNumber: " + resultSetNumber + "\n"
0466:                            + super .toString();
0467:                } else {
0468:                    return "";
0469:                }
0470:            }
0471:
0472:            /**
0473:             * Prints the sub-nodes of this object.  See QueryTreeNode.java for
0474:             * how tree printing is supposed to work.
0475:             *
0476:             * @param depth		The depth of this node in the tree
0477:             */
0478:
0479:            public void printSubNodes(int depth) {
0480:                if (SanityManager.DEBUG) {
0481:                    super .printSubNodes(depth);
0482:                    if (expression != null) {
0483:                        printLabel(depth, "expression: ");
0484:                        expression.treePrint(depth + 1);
0485:                    }
0486:                    if (reference != null) {
0487:                        printLabel(depth, "reference: ");
0488:                        reference.treePrint(depth + 1);
0489:                    }
0490:                }
0491:            }
0492:
0493:            /**
0494:             * Bind this expression.  This means binding the sub-expressions.
0495:             * In this case, we figure out what the result type of this result
0496:             * column is when we call one of the bindResultColumn*() methods.
0497:             * The reason is that there are different ways of binding the
0498:             * result columns depending on the statement type, and this is
0499:             * a standard interface that does not take the statement type as
0500:             * a parameter.
0501:             *
0502:             * @param fromList		The FROM list for the query this
0503:             *				expression is in, for binding columns.
0504:             * @param subqueryList		The subquery list being built as we find SubqueryNodes
0505:             * @param aggregateVector	The aggregate vector being built as we find AggregateNodes
0506:             *
0507:             * @return	The new top of the expression tree.
0508:             *
0509:             * @exception StandardException		Thrown on error
0510:             */
0511:
0512:            public ValueNode bindExpression(FromList fromList,
0513:                    SubqueryList subqueryList, Vector aggregateVector)
0514:                    throws StandardException {
0515:                /*
0516:                 ** Set the type of a parameter to the type of the result column.
0517:                 ** Don't do it if this result column doesn't have a type yet.
0518:                 ** This can happen if the parameter is part of a table constructor.
0519:                 */
0520:                if (expression.requiresTypeFromContext()) {
0521:                    if (getTypeServices() != null) {
0522:                        expression.setType(getTypeServices());
0523:                    }
0524:                }
0525:
0526:                expression = expression.bindExpression(fromList, subqueryList,
0527:                        aggregateVector);
0528:
0529:                if (expression instanceof  ColumnReference) {
0530:                    autoincrement = ((ColumnReference) expression).getSource()
0531:                            .isAutoincrement();
0532:                }
0533:
0534:                return this ;
0535:            }
0536:
0537:            /**
0538:             * Bind this result column by ordinal position and set the VirtualColumnId.  
0539:             * This is useful for INSERT statements like "insert into t values (1, 2, 3)", 
0540:             * where the user did not specify a column list.
0541:             * If a columnDescriptor is not found for a given position, then
0542:             * the user has specified more values than the # of columns in
0543:             * the table and an exception is thrown.
0544:             *
0545:             * NOTE: We must set the VirtualColumnId here because INSERT does not
0546:             * construct the ResultColumnList in the usual way.
0547:             *
0548:             * @param tableDescriptor	The descriptor for the table being
0549:             *				inserted into
0550:             * @param columnId		The ordinal position of the column
0551:             *						in the table, starting at 1.
0552:             *
0553:             * @exception StandardException		Thrown on error
0554:             */
0555:
0556:            void bindResultColumnByPosition(TableDescriptor tableDescriptor,
0557:                    int columnId) throws StandardException {
0558:                ColumnDescriptor columnDescriptor;
0559:
0560:                columnDescriptor = tableDescriptor
0561:                        .getColumnDescriptor(columnId);
0562:
0563:                if (columnDescriptor == null) {
0564:                    String errorString;
0565:                    String schemaName;
0566:
0567:                    errorString = "";
0568:                    schemaName = tableDescriptor.getSchemaName();
0569:                    if (schemaName != null)
0570:                        errorString += schemaName + ".";
0571:                    errorString += tableDescriptor.getName();
0572:
0573:                    throw StandardException.newException(
0574:                            SQLState.LANG_TOO_MANY_RESULT_COLUMNS, errorString);
0575:                }
0576:
0577:                setColumnDescriptor(tableDescriptor, columnDescriptor);
0578:                setVirtualColumnId(columnId);
0579:            }
0580:
0581:            /**
0582:             * Bind this result column by its name and set the VirtualColumnId.  
0583:             * This is useful for update statements, and for INSERT statements 
0584:             * like "insert into t (a, b, c) values (1, 2, 3)" where the user 
0585:             * specified a column list.
0586:             * An exception is thrown when a columnDescriptor cannot be found for a
0587:             * given name.  (There is no column with that name.)
0588:             *
0589:             * NOTE: We must set the VirtualColumnId here because INSERT does not
0590:             * construct the ResultColumnList in the usual way.
0591:             *
0592:             * @param tableDescriptor	The descriptor for the table being
0593:             *				updated or inserted into
0594:             * @param columnId		The ordinal position of the column
0595:             *						in the table, starting at 1. (Used to
0596:             *						set the VirtualColumnId.)
0597:             *
0598:             * @exception StandardException		Thrown on error
0599:             */
0600:
0601:            public void bindResultColumnByName(TableDescriptor tableDescriptor,
0602:                    int columnId) throws StandardException {
0603:                ColumnDescriptor columnDescriptor;
0604:
0605:                columnDescriptor = tableDescriptor
0606:                        .getColumnDescriptor(exposedName);
0607:
0608:                if (columnDescriptor == null) {
0609:                    String errorString;
0610:                    String schemaName;
0611:
0612:                    errorString = "";
0613:                    schemaName = tableDescriptor.getSchemaName();
0614:                    if (schemaName != null)
0615:                        errorString += schemaName + ".";
0616:                    errorString += tableDescriptor.getName();
0617:
0618:                    throw StandardException.newException(
0619:                            SQLState.LANG_COLUMN_NOT_FOUND_IN_TABLE,
0620:                            exposedName, errorString);
0621:                }
0622:
0623:                setColumnDescriptor(tableDescriptor, columnDescriptor);
0624:                setVirtualColumnId(columnId);
0625:                if (isPrivilegeCollectionRequired())
0626:                    getCompilerContext()
0627:                            .addRequiredColumnPriv(columnDescriptor);
0628:            }
0629:
0630:            /**
0631:             * Change an untyped null to a typed null.
0632:             *
0633:             * @exception StandardException		Thrown on error
0634:             */
0635:            public void typeUntypedNullExpression(ResultColumn bindingRC)
0636:                    throws StandardException {
0637:                TypeId typeId = bindingRC.getTypeId();
0638:                /* This is where we catch null in a VALUES clause outside
0639:                 * of INSERT VALUES()
0640:                 */
0641:                if (typeId == null) {
0642:                    throw StandardException
0643:                            .newException(SQLState.LANG_NULL_IN_VALUES_CLAUSE);
0644:                }
0645:
0646:                if (expression instanceof  UntypedNullConstantNode)
0647:                    expression = getNullNode(typeId, getContextManager());
0648:                else if ((expression instanceof  ColumnReference)
0649:                        && expression.getTypeServices() == null) {
0650:                    // The expression must be a reference to a null column in a values table.
0651:                    expression.setType(bindingRC.getType());
0652:                }
0653:            }
0654:
0655:            /**
0656:             * Set the column descriptor for this result column.  It also gets
0657:             * the data type services from the column descriptor and stores it in
0658:             * this result column: this is redundant, but we have to store the result
0659:             * type here for SELECT statements, and it is more orthogonal if the type
0660:             * can be found here regardless of what type of statement it is.
0661:             *
0662:             * @param tableDescriptor	The TableDescriptor for the table
0663:             *				being updated or inserted into.
0664:             *				This parameter is used only for
0665:             *				error reporting.
0666:             * @param columnDescriptor	The ColumnDescriptor to set in
0667:             *				this ResultColumn.
0668:             *
0669:             * @exception StandardException tableNameMismatch
0670:             */
0671:            void setColumnDescriptor(TableDescriptor tableDescriptor,
0672:                    ColumnDescriptor columnDescriptor) throws StandardException {
0673:                /* Callers are responsible for verifying that the column exists */
0674:                if (SanityManager.DEBUG)
0675:                    SanityManager
0676:                            .ASSERT(columnDescriptor != null,
0677:                                    "Caller is responsible for verifying that column exists");
0678:
0679:                setType(columnDescriptor.getType());
0680:                this .columnDescriptor = columnDescriptor;
0681:
0682:                /*
0683:                	If the node was created using a reference, the table name
0684:                	of the reference must agree with that of the tabledescriptor.
0685:                 */
0686:                if (reference != null && reference.getTableName() != null) {
0687:                    if (!tableDescriptor.getName().equals(
0688:                            reference.getTableName())) {
0689:                        /* REMIND: need to have schema name comparison someday as well...
0690:                         ** left out for now, lots of null checking needed...
0691:                         ** || ! tableDescriptor.getSchemaName().equals(
0692:                         **	reference.getTableNameNode().getSchemaName())) {
0693:                         */
0694:                        String realName = tableDescriptor.getName();
0695:                        String refName = reference.getTableName();
0696:
0697:                        throw StandardException.newException(
0698:                                SQLState.LANG_TABLE_NAME_MISMATCH, realName,
0699:                                refName);
0700:                    }
0701:                }
0702:            }
0703:
0704:            /**
0705:             * Bind the result column to the expression that lives under it.
0706:             * All this does is copy the datatype information to this node.
0707:             * This is useful for SELECT statements, where the result type
0708:             * of each column is the type of the column's expression.
0709:             *
0710:             * @exception StandardException		Thrown on error
0711:             */
0712:            public void bindResultColumnToExpression() throws StandardException {
0713:                /*
0714:                 ** This gets the same DataTypeServices object as
0715:                 ** is used in the expression.  It is probably not
0716:                 ** necessary to clone the object here.
0717:                 */
0718:                setType(expression.getTypeServices());
0719:
0720:                if (expression instanceof  ColumnReference) {
0721:                    ColumnReference cr = (ColumnReference) expression;
0722:                    tableName = cr.getTableName();
0723:                    sourceTableName = cr.getSourceTableName();
0724:                    sourceSchemaName = cr.getSourceSchemaName();
0725:                }
0726:            }
0727:
0728:            /**
0729:             * Preprocess an expression tree.  We do a number of transformations
0730:             * here (including subqueries, IN lists, LIKE and BETWEEN) plus
0731:             * subquery flattening.
0732:             * NOTE: This is done before the outer ResultSetNode is preprocessed.
0733:             *
0734:             * @param	numTables			Number of tables in the DML Statement
0735:             * @param	outerFromList		FromList from outer query block
0736:             * @param	outerSubqueryList	SubqueryList from outer query block
0737:             * @param	outerPredicateList	PredicateList from outer query block
0738:             *
0739:             * @return		The modified expression
0740:             *
0741:             * @exception StandardException		Thrown on error
0742:             */
0743:            public ValueNode preprocess(int numTables, FromList outerFromList,
0744:                    SubqueryList outerSubqueryList,
0745:                    PredicateList outerPredicateList) throws StandardException {
0746:                if (expression == null)
0747:                    return this ;
0748:                expression = expression.preprocess(numTables, outerFromList,
0749:                        outerSubqueryList, outerPredicateList);
0750:                return this ;
0751:            }
0752:
0753:            /**
0754:            	This verifies that the expression is storable into the result column.
0755:            	It checks versus the given ResultColumn.
0756:
0757:            	This method should not be called until the result column and
0758:            	expression both have a valid type, i.e. after they are bound
0759:            	appropriately. Its use is for statements like insert, that need to
0760:            	verify if a given value can be stored into a column.
0761:
0762:            	@exception StandardException thrown if types not suitable.
0763:             */
0764:            public void checkStorableExpression(ResultColumn toStore)
0765:                    throws StandardException {
0766:                TypeId columnTypeId, toStoreTypeId;
0767:
0768:                toStoreTypeId = toStore.getTypeId();
0769:                if (toStoreTypeId == null)
0770:                    return;
0771:
0772:                columnTypeId = getTypeId();
0773:
0774:                if (!getTypeCompiler().storable(toStoreTypeId,
0775:                        getClassFactory()))
0776:                    throw StandardException.newException(
0777:                            SQLState.LANG_NOT_STORABLE, columnTypeId
0778:                                    .getSQLTypeName(), toStoreTypeId
0779:                                    .getSQLTypeName());
0780:            }
0781:
0782:            /**
0783:            	This verifies that the expression is storable into the result column.
0784:            	It checks versus the expression under this ResultColumn.
0785:
0786:            	This method should not be called until the result column and
0787:            	expression both have a valid type, i.e. after they are bound
0788:            	appropriately. Its use is for statements like update, that need to
0789:            	verify if a given value can be stored into a column.
0790:
0791:            	@exception StandardException thrown if types not suitable.
0792:             */
0793:            public void checkStorableExpression() throws StandardException {
0794:                TypeId columnTypeId = getTypeId();
0795:                TypeId toStoreTypeId = getExpressionType().getTypeId();
0796:
0797:                if (!getTypeCompiler().storable(toStoreTypeId,
0798:                        getClassFactory()))
0799:                    throw StandardException.newException(
0800:                            SQLState.LANG_NOT_STORABLE, columnTypeId
0801:                                    .getSQLTypeName(), toStoreTypeId
0802:                                    .getSQLTypeName());
0803:            }
0804:
0805:            /**
0806:             * Do code generation for a result column.  This consists of doing the code
0807:             * generation for the underlying expression.
0808:             *
0809:             * @param ecb	The ExpressionClassBuilder for the class we're generating
0810:             * @param mb	The method the expression will go into
0811:             *
0812:             *
0813:             * @exception StandardException		Thrown on error
0814:             */
0815:
0816:            public void generateExpression(ExpressionClassBuilder ecb,
0817:                    MethodBuilder mb) throws StandardException {
0818:                expression.generateExpression(ecb, mb);
0819:            }
0820:
0821:            /**
0822:             * Do code generation to return a Null of the appropriate type
0823:             * for the result column.  
0824:               Requires the getCOlumnExpress value pushed onto the stack
0825:             *
0826:             * @param acb		The ActivationClassBuilder for the class we're generating
0827:             * @param eb		The ExpressionBlock that the generate code is to go into
0828:             * @param getColumnExpression "fieldx.getColumn(y)"
0829:             *
0830:             * @exception StandardException		Thrown on error
0831:             */
0832:            /*PUSHCOMPILE
0833:             public void generateNulls(ExpressionClassBuilder acb,
0834:             MethodBuilder mb,
0835:             Expression getColumnExpress) 
0836:             throws StandardException
0837:             {
0838:
0839:             acb.pushDataValueFactory(mb);
0840:             getTypeCompiler().generateNull(mb, acb.getBaseClassName());
0841:
0842:            
0843:             mb.cast(ClassName.DataValueDescriptor);
0844:
0845:
0846:             return eb.newCastExpression(
0847:             ClassName.DataValueDescriptor, 
0848:             getTypeCompiler().
0849:             generateNull(
0850:             eb,
0851:             acb.getBaseClassName(),
0852:             acb.getDataValueFactory(eb),
0853:             getColumnExpress));
0854:             }
0855:             */
0856:            /**
0857:            	Generate the code to create a column the same shape and
0858:            	size as this ResultColumn.
0859:
0860:            	Used in ResultColumnList.generateHolder().
0861:
0862:            	@exception StandardException  thrown on failure
0863:             */
0864:            public void generateHolder(ExpressionClassBuilder acb,
0865:                    MethodBuilder mb) throws StandardException {
0866:                // generate expression of the form
0867:                // (DataValueDescriptor) columnSpace
0868:
0869:                acb.generateNull(mb, getTypeCompiler());
0870:                mb.upCast(ClassName.DataValueDescriptor);
0871:            }
0872:
0873:            /*
0874:             ** Check whether the column length and type of this result column
0875:             ** match the expression under the columns.  This is useful for
0876:             ** INSERT and UPDATE statements.  For SELECT statements this method
0877:             ** should always return true.  There is no need to call this for a
0878:             ** DELETE statement.
0879:             **
0880:             ** @return	true means the column matches its expressions,
0881:             **			false means it doesn't match.
0882:             */
0883:
0884:            boolean columnTypeAndLengthMatch() throws StandardException {
0885:                DataTypeDescriptor resultColumnType;
0886:                DataTypeDescriptor expressionType = expression
0887:                        .getTypeServices();
0888:
0889:                /*
0890:                 ** We can never make any assumptions about
0891:                 ** parameters.  So don't even bother in this
0892:                 ** case.
0893:                 */
0894:                if (expression.requiresTypeFromContext()) {
0895:                    return false;
0896:                }
0897:
0898:                resultColumnType = getType();
0899:
0900:                if (SanityManager.DEBUG) {
0901:                    if (!(resultColumnType != null)) {
0902:                        SanityManager.THROWASSERT("Type is null for column "
0903:                                + this );
0904:                    }
0905:                }
0906:
0907:                // Are we inserting/updating an XML column?  If so, we always
0908:                // return false so that normalization will occur.  We have to
0909:                // do this because there are different "kinds" of XML values
0910:                // and we need to make sure they match--but we don't know
0911:                // the "kind" until execution time.  See the "normalize"
0912:                // method in org.apache.derby.iapi.types.XML for more.
0913:                if (resultColumnType.getTypeId().isXMLTypeId())
0914:                    return false;
0915:
0916:                /* Are they the same type? */
0917:                if (!resultColumnType.getTypeId().getSQLTypeName().equals(
0918:                        expressionType.getTypeId().getSQLTypeName())) {
0919:                    return false;
0920:                }
0921:
0922:                /* Are they the same precision? */
0923:                if (resultColumnType.getPrecision() != expressionType
0924:                        .getPrecision()) {
0925:                    return false;
0926:                }
0927:
0928:                /* Are they the same scale? */
0929:                if (resultColumnType.getScale() != expressionType.getScale()) {
0930:                    return false;
0931:                }
0932:
0933:                /* Are they the same width? */
0934:                if (resultColumnType.getMaximumWidth() != expressionType
0935:                        .getMaximumWidth()) {
0936:                    return false;
0937:                }
0938:
0939:                /* Is the source nullable and the target non-nullable? */
0940:                if ((!resultColumnType.isNullable())
0941:                        && expressionType.isNullable()) {
0942:                    return false;
0943:                }
0944:
0945:                return true;
0946:            }
0947:
0948:            boolean columnTypeAndLengthMatch(ResultColumn otherColumn)
0949:                    throws StandardException {
0950:                DataTypeDescriptor resultColumnType;
0951:                DataTypeDescriptor otherResultColumnType;
0952:                ValueNode otherExpression = otherColumn.getExpression();
0953:
0954:                resultColumnType = getType();
0955:                otherResultColumnType = otherColumn.getType();
0956:
0957:                if (SanityManager.DEBUG) {
0958:                    SanityManager.ASSERT(resultColumnType != null,
0959:                            "Type is null for column " + this );
0960:                    SanityManager.ASSERT(otherResultColumnType != null,
0961:                            "Type is null for column " + otherColumn);
0962:                }
0963:
0964:                /*
0965:                 ** We can never make any assumptions about
0966:                 ** parameters.  So don't even bother in this
0967:                 ** case.
0968:                 */
0969:                if ((otherExpression != null)
0970:                        && (otherExpression.requiresTypeFromContext())
0971:                        || (expression.requiresTypeFromContext())) {
0972:                    return false;
0973:                }
0974:
0975:                // Are we inserting/updating an XML column?  If so, we always
0976:                // return false so that normalization will occur.  We have to
0977:                // do this because there are different "kinds" of XML values
0978:                // and we need to make sure they match--but we don't know
0979:                // the "kind" until execution time.  See the "normalize"
0980:                // method in org.apache.derby.iapi.types.XML for more.
0981:                if (resultColumnType.getTypeId().isXMLTypeId())
0982:                    return false;
0983:
0984:                /* Are they the same type? */
0985:                if (!resultColumnType.getTypeId().equals(
0986:                        otherResultColumnType.getTypeId())) {
0987:                    /* If the source is a constant of a different type then
0988:                     * we try to convert that constant to a constant of our
0989:                     * type. (The initial implementation only does the conversion
0990:                     * to string types because the most common problem is a char
0991:                     * constant with a varchar column.)  
0992:                     * NOTE: We do not attempt any conversion here if the source
0993:                     * is a string type and the target is not or vice versa in 
0994:                     * order to avoid problems with implicit varchar conversions.
0995:                     * Anyway, we will check if the "converted" constant has the
0996:                     * same type as the original constant.  If not, then the conversion
0997:                     * happened.  In that case, we will reuse the ConstantNode, for simplicity,
0998:                     * and reset the type to match the desired type.
0999:                     */
1000:                    if (otherExpression instanceof  ConstantNode) {
1001:                        ConstantNode constant = (ConstantNode) otherColumn
1002:                                .getExpression();
1003:                        DataValueDescriptor oldValue = constant.getValue();
1004:
1005:                        DataValueDescriptor newValue = convertConstant(
1006:                                resultColumnType.getTypeId(), resultColumnType
1007:                                        .getMaximumWidth(), oldValue);
1008:
1009:                        if ((oldValue != newValue)
1010:                                && (oldValue instanceof  StringDataValue == newValue instanceof  StringDataValue)) {
1011:                            constant.setValue(newValue);
1012:                            constant.setType(getTypeServices());
1013:                            otherColumn.bindResultColumnToExpression();
1014:                            otherResultColumnType = otherColumn.getType();
1015:                        }
1016:                    }
1017:                    if (!resultColumnType.getTypeId().equals(
1018:                            otherResultColumnType.getTypeId())) {
1019:                        return false;
1020:                    }
1021:                }
1022:
1023:                /* Are they the same precision? */
1024:                if (resultColumnType.getPrecision() != otherResultColumnType
1025:                        .getPrecision()) {
1026:                    return false;
1027:                }
1028:
1029:                /* Are they the same scale? */
1030:                if (resultColumnType.getScale() != otherResultColumnType
1031:                        .getScale()) {
1032:                    return false;
1033:                }
1034:
1035:                /* Are they the same width? */
1036:                if (resultColumnType.getMaximumWidth() != otherResultColumnType
1037:                        .getMaximumWidth()) {
1038:                    return false;
1039:                }
1040:
1041:                /* Is the source nullable and the target non-nullable? 
1042:                 * The source is nullable if it is nullable or if the target is generated
1043:                 * for an unmatched column in an insert with a column list.
1044:                 * This additional check is needed because when we generate any additional
1045:                 * source RCs for an insert with a column list the generated RCs for any 
1046:                 * non-specified columns get the type info from the column.  Thus, 
1047:                 * for t1(non_nullable, nullable)
1048:                 *	insert into t2 (nullable) values 1;
1049:                 * RCType.isNullable() returns false for the generated source RC for 
1050:                 * non_nullable.  In this case, we want to see it as
1051:                 */
1052:                if ((!resultColumnType.isNullable())
1053:                        && (otherResultColumnType.isNullable() || otherColumn
1054:                                .isGeneratedForUnmatchedColumnInInsert())) {
1055:                    return false;
1056:                }
1057:
1058:                return true;
1059:            }
1060:
1061:            /**
1062:             * Is this a generated column?
1063:             *
1064:             * @return Boolean - whether or not this column is a generated column.
1065:             */
1066:            public boolean isGenerated() {
1067:                return (isGenerated == true);
1068:            }
1069:
1070:            /**
1071:             * Is this columm generated for an unmatched column in an insert?
1072:             *
1073:             * @return Boolean - whether or not this columm was generated for an unmatched column in an insert.
1074:             */
1075:            public boolean isGeneratedForUnmatchedColumnInInsert() {
1076:                return (isGeneratedForUnmatchedColumnInInsert == true);
1077:            }
1078:
1079:            /**
1080:             * Mark this a columm as a generated column
1081:             */
1082:            public void markGenerated() {
1083:                isGenerated = true;
1084:                /* A generated column is a referenced column */
1085:                isReferenced = true;
1086:            }
1087:
1088:            /**
1089:             * Mark this a columm as generated for an unmatched column in an insert
1090:             */
1091:            public void markGeneratedForUnmatchedColumnInInsert() {
1092:                isGeneratedForUnmatchedColumnInInsert = true;
1093:                /* A generated column is a referenced column */
1094:                isReferenced = true;
1095:            }
1096:
1097:            /**
1098:             * Is this a referenced column?
1099:             *
1100:             * @return Boolean - whether or not this column is a referenced column.
1101:             */
1102:            public boolean isReferenced() {
1103:                return isReferenced;
1104:            }
1105:
1106:            /**
1107:             * Mark this column as a referenced column.
1108:             */
1109:            public void setReferenced() {
1110:                isReferenced = true;
1111:            }
1112:
1113:            /**
1114:             * Mark this column as a referenced column if it is already marked as referenced or if any result column in
1115:             * its chain of virtual columns is marked as referenced.
1116:             */
1117:            void pullVirtualIsReferenced() {
1118:                if (isReferenced())
1119:                    return;
1120:
1121:                for (ValueNode expr = expression; expr != null
1122:                        && (expr instanceof  VirtualColumnNode);) {
1123:                    VirtualColumnNode vcn = (VirtualColumnNode) expr;
1124:                    ResultColumn src = vcn.getSourceColumn();
1125:                    if (src.isReferenced()) {
1126:                        setReferenced();
1127:                        return;
1128:                    }
1129:                    expr = src.getExpression();
1130:                }
1131:            } // end of pullVirtualIsReferenced
1132:
1133:            /**
1134:             * Mark this column as an unreferenced column.
1135:             */
1136:            public void setUnreferenced() {
1137:                isReferenced = false;
1138:            }
1139:
1140:            /**
1141:             * Mark this RC and all RCs in the underlying
1142:             * RC/VCN chain as referenced.
1143:             */
1144:            void markAllRCsInChainReferenced() {
1145:                setReferenced();
1146:
1147:                ValueNode vn = expression;
1148:
1149:                while (vn instanceof  VirtualColumnNode) {
1150:                    VirtualColumnNode vcn = (VirtualColumnNode) vn;
1151:                    ResultColumn rc = vcn.getSourceColumn();
1152:                    rc.setReferenced();
1153:                    vn = rc.getExpression();
1154:                }
1155:            }
1156:
1157:            /**
1158:             * Is this a redundant ResultColumn?
1159:             *
1160:             * @return Boolean - whether or not this RC is redundant.
1161:             */
1162:            public boolean isRedundant() {
1163:                return isRedundant;
1164:            }
1165:
1166:            /**
1167:             * Mark this ResultColumn as redundant.
1168:             */
1169:            public void setRedundant() {
1170:                isRedundant = true;
1171:            }
1172:
1173:            /**
1174:             * Mark this ResultColumn as a grouping column in the SELECT list
1175:             */
1176:            public void markAsGroupingColumn() {
1177:                isGroupingColumn = true;
1178:            }
1179:
1180:            /**
1181:             * Look for and reject ?/-?/+? parameter under this ResultColumn.  This is
1182:             * called for SELECT statements.
1183:             *
1184:             * @exception StandardException		Thrown if a ?/-?/+? parameter was found
1185:             *									directly under this ResultColumn.
1186:             */
1187:
1188:            void rejectParameter() throws StandardException {
1189:                if ((expression != null) && (expression.isParameterNode()))
1190:                    throw StandardException
1191:                            .newException(SQLState.LANG_PARAM_IN_SELECT_LIST);
1192:                if ((expression != null)
1193:                        && (expression instanceof  UnaryOperatorNode)
1194:                        && ((UnaryOperatorNode) expression)
1195:                                .isUnaryMinusOrPlusWithParameter())
1196:                    throw StandardException
1197:                            .newException(SQLState.LANG_PARAM_IN_SELECT_LIST);
1198:            }
1199:
1200:            /*
1201:             ** The following methods implement the Comparable interface.
1202:             */
1203:            public int compareTo(Object other) {
1204:                ResultColumn otherResultColumn = (ResultColumn) other;
1205:
1206:                return this .getColumnPosition()
1207:                        - otherResultColumn.getColumnPosition();
1208:            }
1209:
1210:            /**
1211:             * Mark this column as being updated by an update statemment.
1212:             */
1213:            void markUpdated() {
1214:                updated = true;
1215:            }
1216:
1217:            /**
1218:             * Mark this column as being updatable, so we can make sure it is in the
1219:             * "for update" list of a positioned update.
1220:             */
1221:            void markUpdatableByCursor() {
1222:                updatableByCursor = true;
1223:            }
1224:
1225:            /**
1226:             * Tell whether this column is being updated.
1227:             *
1228:             * @return	true means this column is being updated.
1229:             */
1230:            boolean updated() {
1231:                return updated;
1232:            }
1233:
1234:            /**
1235:             * Tell whether this column is updatable by a positioned update.
1236:             *
1237:             * @return	true means this column is updatable
1238:             */
1239:            public boolean updatableByCursor() {
1240:                return updatableByCursor;
1241:            }
1242:
1243:            /** 
1244:             * @see QueryTreeNode#disablePrivilegeCollection
1245:             */
1246:            public void disablePrivilegeCollection() {
1247:                super .disablePrivilegeCollection();
1248:                if (expression != null)
1249:                    expression.disablePrivilegeCollection();
1250:            }
1251:
1252:            /**
1253:             * Make a copy of this ResultColumn in a new ResultColumn
1254:             *
1255:             * @return	A new ResultColumn with the same contents as this one
1256:             *
1257:             * @exception StandardException		Thrown on error
1258:             */
1259:            ResultColumn cloneMe() throws StandardException {
1260:                ResultColumn newResultColumn;
1261:                ValueNode cloneExpr;
1262:
1263:                /* If expression is a ColumnReference, then we want to 
1264:                 * have the RC's clone have a clone of the ColumnReference
1265:                 * for it's expression.  This is for the special case of
1266:                 * cloning the SELECT list for the HAVING clause in the parser.
1267:                 * The SELECT generated for the HAVING needs its own copy
1268:                 * of the ColumnReferences.
1269:                 */
1270:                if (expression instanceof  ColumnReference) {
1271:                    cloneExpr = ((ColumnReference) expression).getClone();
1272:                } else {
1273:                    cloneExpr = expression;
1274:                }
1275:
1276:                /* If a columnDescriptor exists, then we must propagate it */
1277:                if (columnDescriptor != null) {
1278:                    newResultColumn = (ResultColumn) getNodeFactory().getNode(
1279:                            C_NodeTypes.RESULT_COLUMN, columnDescriptor,
1280:                            expression, getContextManager());
1281:                    newResultColumn.setExpression(cloneExpr);
1282:                } else {
1283:
1284:                    newResultColumn = (ResultColumn) getNodeFactory().getNode(
1285:                            C_NodeTypes.RESULT_COLUMN, getName(), cloneExpr,
1286:                            getContextManager());
1287:                }
1288:
1289:                /* Set the VirtualColumnId and name in the new node */
1290:                newResultColumn.setVirtualColumnId(getVirtualColumnId());
1291:
1292:                /* Set the type and name information in the new node */
1293:                newResultColumn.setName(getName());
1294:                newResultColumn.setType(getTypeServices());
1295:                newResultColumn.setNameGenerated(isNameGenerated());
1296:
1297:                /* Set the "is generated for unmatched column in insert" status in the new node
1298:                This if for bug 4194*/
1299:                if (isGeneratedForUnmatchedColumnInInsert())
1300:                    newResultColumn.markGeneratedForUnmatchedColumnInInsert();
1301:
1302:                /* Set the "is referenced" status in the new node */
1303:                if (isReferenced())
1304:                    newResultColumn.setReferenced();
1305:
1306:                /* Set the "updated" status in the new node */
1307:                if (updated())
1308:                    newResultColumn.markUpdated();
1309:
1310:                /* Setthe "updatable by cursor" status in the new node */
1311:                if (updatableByCursor())
1312:                    newResultColumn.markUpdatableByCursor();
1313:
1314:                if (isAutoincrementGenerated())
1315:                    newResultColumn.setAutoincrementGenerated();
1316:
1317:                if (isAutoincrement())
1318:                    newResultColumn.setAutoincrement();
1319:                if (isGroupingColumn())
1320:                    newResultColumn.markAsGroupingColumn();
1321:                return newResultColumn;
1322:            }
1323:
1324:            /**
1325:             * Get the maximum size of the column
1326:             *
1327:             * @return the max size
1328:             */
1329:            public int getMaximumColumnSize() {
1330:                return dataTypeServices.getTypeId()
1331:                        .getApproximateLengthInBytes(dataTypeServices);
1332:            }
1333:
1334:            /**
1335:             * Return the variant type for the underlying expression.
1336:             * The variant type can be:
1337:             *		VARIANT				- variant within a scan
1338:             *							  (method calls and non-static field access)
1339:             *		SCAN_INVARIANT		- invariant within a scan
1340:             *							  (column references from outer tables)
1341:             *		QUERY_INVARIANT		- invariant within the life of a query
1342:             *		CONSTANT				- constant
1343:             *
1344:             * @return	The variant type for the underlying expression.
1345:             * @exception StandardException	thrown on error
1346:             */
1347:            protected int getOrderableVariantType() throws StandardException {
1348:                /*
1349:                 ** If the expression is VARIANT, then
1350:                 ** return VARIANT.  Otherwise, we return
1351:                 ** CONSTANT. For result columns that are 
1352:                 ** generating autoincrement values, the result
1353:                 ** is variant-- note that there is no expression
1354:                 ** associated with an autoincrement column in 
1355:                 ** an insert statement.
1356:                 */
1357:                int expType = ((expression != null) ? expression
1358:                        .getOrderableVariantType()
1359:                        : ((isAutoincrementGenerated()) ? Qualifier.VARIANT
1360:                                : Qualifier.CONSTANT));
1361:
1362:                switch (expType) {
1363:                case Qualifier.VARIANT:
1364:                    return Qualifier.VARIANT;
1365:
1366:                case Qualifier.SCAN_INVARIANT:
1367:                case Qualifier.QUERY_INVARIANT:
1368:                    return Qualifier.SCAN_INVARIANT;
1369:
1370:                default:
1371:                    return Qualifier.CONSTANT;
1372:                }
1373:            }
1374:
1375:            /**
1376:             * Accept a visitor, and call v.visit()
1377:             * on child nodes as necessary.  
1378:             * 
1379:             * @param v the visitor
1380:             *
1381:             * @exception StandardException on error
1382:             */
1383:            public Visitable accept(Visitor v) throws StandardException {
1384:                Visitable returnNode = v.visit(this );
1385:
1386:                if (v.skipChildren(this )) {
1387:                    return returnNode;
1388:                }
1389:
1390:                if (expression != null && !v.stopTraversal()) {
1391:                    expression = (ValueNode) expression.accept(v);
1392:                }
1393:                return returnNode;
1394:            }
1395:
1396:            /**
1397:             * Set the nullability of this ResultColumn.
1398:             */
1399:            public void setNullability(boolean nullability) {
1400:                dataTypeServices.setNullability(nullability);
1401:            }
1402:
1403:            /**
1404:             * Is this column in this array of strings?
1405:             *
1406:             * @param list the array of column names to compare
1407:             *
1408:             * @return true/false
1409:             */
1410:            public boolean foundInList(String[] list) {
1411:                return foundString(list, name);
1412:            }
1413:
1414:            /**
1415:             * Verify that this RC is orderable.
1416:             *
1417:             * @exception StandardException		Thrown on error
1418:             */
1419:            void verifyOrderable() throws StandardException {
1420:                /*
1421:                 * Do not check to see if we can map user types
1422:                 * to built-in types.  The ability to do so does
1423:                 * not mean that ordering will work.  In fact,
1424:                 * as of version 2.0, ordering does not work on
1425:                 * user types.
1426:                 */
1427:                if (!getTypeId().orderable(getClassFactory())) {
1428:                    throw StandardException
1429:                            .newException(
1430:                                    SQLState.LANG_COLUMN_NOT_ORDERABLE_DURING_EXECUTION,
1431:                                    getTypeId().getSQLTypeName());
1432:                }
1433:            }
1434:
1435:            /**
1436:              If this ResultColumn is bound to a column in a table
1437:              get the column descriptor for the column in the table.
1438:              Otherwise return null.
1439:             */
1440:            ColumnDescriptor getTableColumnDescriptor() {
1441:                return columnDescriptor;
1442:            }
1443:
1444:            /**
1445:             * Returns true if this result column is a placeholder for a generated
1446:             * autoincrement value.
1447:             */
1448:            public boolean isAutoincrementGenerated() {
1449:                return autoincrementGenerated;
1450:            }
1451:
1452:            public void setAutoincrementGenerated() {
1453:                autoincrementGenerated = true;
1454:            }
1455:
1456:            public void resetAutoincrementGenerated() {
1457:                autoincrementGenerated = false;
1458:            }
1459:
1460:            public boolean isAutoincrement() {
1461:                return autoincrement;
1462:            }
1463:
1464:            public void setAutoincrement() {
1465:                autoincrement = true;
1466:            }
1467:
1468:            public boolean isGroupingColumn() {
1469:                return isGroupingColumn;
1470:            }
1471:
1472:            /**
1473:             * @exception StandardException		Thrown on error
1474:             */
1475:            private DataValueDescriptor convertConstant(TypeId toTypeId,
1476:                    int maxWidth, DataValueDescriptor constantValue)
1477:                    throws StandardException {
1478:                int formatId = toTypeId.getTypeFormatId();
1479:                DataValueFactory dvf = getDataValueFactory();
1480:                switch (formatId) {
1481:                default:
1482:                case StoredFormatIds.CHAR_TYPE_ID:
1483:                    return constantValue;
1484:
1485:                case StoredFormatIds.VARCHAR_TYPE_ID:
1486:                case StoredFormatIds.NATIONAL_CHAR_TYPE_ID:
1487:                case StoredFormatIds.NATIONAL_VARCHAR_TYPE_ID:
1488:                    String sourceValue = constantValue.getString();
1489:                    int sourceWidth = sourceValue.length();
1490:                    int posn;
1491:
1492:                    /*
1493:                     ** If the input is already the right length, no normalization is
1494:                     ** necessary - just return the source.
1495:                     ** 
1496:                     */
1497:
1498:                    if (sourceWidth <= maxWidth) {
1499:                        switch (formatId) {
1500:                        // For NCHAR we must pad the result, saves on normilization later if all
1501:                        // constants are of the correct size
1502:                        case StoredFormatIds.NATIONAL_CHAR_TYPE_ID:
1503:
1504:                            if (sourceWidth < maxWidth) {
1505:                                StringBuffer stringBuffer = new StringBuffer(
1506:                                        sourceValue);
1507:
1508:                                int needed = maxWidth - sourceWidth;
1509:                                char blankArray[] = new char[needed];
1510:                                for (int i = 0; i < needed; i++)
1511:                                    blankArray[i] = ' ';
1512:                                stringBuffer.append(blankArray, 0, maxWidth
1513:                                        - sourceWidth);
1514:                                sourceValue = stringBuffer.toString();
1515:                            }
1516:                            return dvf.getNationalCharDataValue(sourceValue);
1517:
1518:                        case StoredFormatIds.NATIONAL_VARCHAR_TYPE_ID:
1519:                            return dvf.getNationalVarcharDataValue(sourceValue);
1520:
1521:                        case StoredFormatIds.VARCHAR_TYPE_ID:
1522:                            return dvf.getVarcharDataValue(sourceValue);
1523:                        }
1524:                    }
1525:
1526:                    /*
1527:                     ** Check whether any non-blank characters will be truncated.
1528:                     */
1529:                    for (posn = maxWidth; posn < sourceWidth; posn++) {
1530:                        if (sourceValue.charAt(posn) != ' ') {
1531:                            String typeName = null;
1532:                            switch (formatId) {
1533:                            case StoredFormatIds.NATIONAL_CHAR_TYPE_ID:
1534:                                typeName = TypeId.NATIONAL_CHAR_NAME;
1535:                                break;
1536:
1537:                            case StoredFormatIds.NATIONAL_VARCHAR_TYPE_ID:
1538:                                typeName = TypeId.NATIONAL_VARCHAR_NAME;
1539:                                break;
1540:
1541:                            case StoredFormatIds.VARCHAR_TYPE_ID:
1542:                                typeName = TypeId.VARCHAR_NAME;
1543:                                break;
1544:                            }
1545:                            throw StandardException.newException(
1546:                                    SQLState.LANG_STRING_TRUNCATION, typeName,
1547:                                    StringUtil.formatForPrint(sourceValue),
1548:                                    String.valueOf(maxWidth));
1549:                        }
1550:                    }
1551:
1552:                    switch (formatId) {
1553:                    case StoredFormatIds.NATIONAL_CHAR_TYPE_ID:
1554:                        return dvf.getNationalCharDataValue(sourceValue
1555:                                .substring(0, maxWidth));
1556:
1557:                    case StoredFormatIds.NATIONAL_VARCHAR_TYPE_ID:
1558:                        return dvf.getNationalVarcharDataValue(sourceValue
1559:                                .substring(0, maxWidth));
1560:
1561:                    case StoredFormatIds.VARCHAR_TYPE_ID:
1562:                        return dvf.getVarcharDataValue(sourceValue.substring(0,
1563:                                maxWidth));
1564:                    }
1565:
1566:                case StoredFormatIds.LONGVARCHAR_TYPE_ID:
1567:                    //No need to check widths here (unlike varchar), since no max width
1568:                    return dvf.getLongvarcharDataValue(constantValue
1569:                            .getString());
1570:
1571:                case StoredFormatIds.NATIONAL_LONGVARCHAR_TYPE_ID:
1572:                    //No need to check widths here (unlike varchar), since no max width
1573:                    return dvf.getNationalLongvarcharDataValue(constantValue
1574:                            .getString());
1575:
1576:                }
1577:            }
1578:
1579:            /**
1580:             * Get the TypeId from this Node.
1581:             *
1582:             * @return	The TypeId from this Node.  This
1583:             *		may be null if the node isn't bound yet.
1584:             */
1585:            public TypeId getTypeId() throws StandardException {
1586:                TypeId t = super .getTypeId();
1587:                if (t == null) {
1588:                    if (expression != null) {
1589:                        DataTypeDescriptor dtd = getTypeServices();
1590:                        if (dtd != null)
1591:                            t = dtd.getTypeId();
1592:                    }
1593:                }
1594:                return t;
1595:            } // end of getTypeId
1596:
1597:            /**
1598:             * Get the DataTypeServices from this Node.
1599:             *
1600:             * @return	The DataTypeServices from this Node.  This
1601:             *		may be null if the node isn't bound yet.
1602:             */
1603:            public DataTypeDescriptor getTypeServices()
1604:                    throws StandardException {
1605:                DataTypeDescriptor dtd = super .getTypeServices();
1606:                if (dtd == null && expression != null) {
1607:                    dtd = expression.getTypeServices();
1608:                    if (dtd != null)
1609:                        setType(dtd);
1610:                }
1611:                return dtd;
1612:            } // end of getTypeServices
1613:
1614:            public TableName getTableNameObject() {
1615:                return null;
1616:            }
1617:
1618:            /* Get the wrapped reference if any */
1619:            public ColumnReference getReference() {
1620:                return reference;
1621:            }
1622:
1623:            /**
1624:             * Get the source BaseColumnNode for this result column. The
1625:             * BaseColumnNode cannot be found unless the ResultColumn is bound
1626:             * and is a simple reference to a column in a BaseFromTable.
1627:             *
1628:             * @return a BaseColumnNode,
1629:             *   or null if a BaseColumnNode cannot be found
1630:             */
1631:            public BaseColumnNode getBaseColumnNode() {
1632:                ValueNode vn = expression;
1633:                while (true) {
1634:                    if (vn instanceof  ResultColumn) {
1635:                        vn = ((ResultColumn) vn).expression;
1636:                    } else if (vn instanceof  ColumnReference) {
1637:                        vn = ((ColumnReference) vn).getSource();
1638:                    } else if (vn instanceof  VirtualColumnNode) {
1639:                        vn = ((VirtualColumnNode) vn).getSourceColumn();
1640:                    } else if (vn instanceof  BaseColumnNode) {
1641:                        return (BaseColumnNode) vn;
1642:                    } else {
1643:                        return null;
1644:                    }
1645:                }
1646:            }
1647:
1648:            /**
1649:             * Search the tree beneath this ResultColumn until we find
1650:             * the number of the table to which this RC points, and
1651:             * return that table number.  If we can't determine which
1652:             * table this RC is for, then return -1.
1653:             *
1654:             * There are two places we can find the table number: 1) if
1655:             * our expression is a ColumnReference, then we can get the
1656:             * target table number from the ColumnReference and that's
1657:             * it; 2) if expression is a VirtualColumnNode, then if
1658:             * the VirtualColumnNode points to a FromBaseTable, we can
1659:             * get that FBT's table number; otherwise, we walk the
1660:             * VirtualColumnNode-ResultColumn chain and do a recursive
1661:             * search.
1662:             *
1663:             * @return The number of the table to which this ResultColumn	
1664:             *  points, or -1 if we can't determine that from where we are.
1665:             */
1666:            public int getTableNumber() throws StandardException {
1667:                if (expression instanceof  ColumnReference)
1668:                    return ((ColumnReference) expression).getTableNumber();
1669:                else if (expression instanceof  VirtualColumnNode) {
1670:                    VirtualColumnNode vcn = (VirtualColumnNode) expression;
1671:
1672:                    // If the VCN points to a FromBaseTable, just get that
1673:                    // table's number.
1674:                    if (vcn.getSourceResultSet() instanceof  FromBaseTable) {
1675:                        return ((FromBaseTable) vcn.getSourceResultSet())
1676:                                .getTableNumber();
1677:                    }
1678:
1679:                    // Else recurse down the VCN.
1680:                    return vcn.getSourceColumn().getTableNumber();
1681:                }
1682:
1683:                // We can get here if expression has neither a column
1684:                // reference nor a FromBaseTable beneath it--for example,
1685:                // if it is of type BaseColumnNode. 
1686:                return -1;
1687:            }
1688:
1689:            public boolean isEquivalent(ValueNode o) throws StandardException {
1690:                if (o.getNodeType() == getNodeType()) {
1691:                    ResultColumn other = (ResultColumn) o;
1692:                    if (expression != null) {
1693:                        return expression.isEquivalent(other.expression);
1694:                    }
1695:                }
1696:                return false;
1697:            }
1698:
1699:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.