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


001:        /*
002:
003:           Derby - Class org.apache.derby.impl.sql.compile.ConcatenationOperatorNode
004:
005:           Licensed to the Apache Software Foundation (ASF) under one or more
006:           contributor license agreements.  See the NOTICE file distributed with
007:           this work for additional information regarding copyright ownership.
008:           The ASF licenses this file to you under the Apache License, Version 2.0
009:           (the "License"); you may not use this file except in compliance with
010:           the License.  You may obtain a copy of the License at
011:
012:              http://www.apache.org/licenses/LICENSE-2.0
013:
014:           Unless required by applicable law or agreed to in writing, software
015:           distributed under the License is distributed on an "AS IS" BASIS,
016:           WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017:           See the License for the specific language governing permissions and
018:           limitations under the License.
019:
020:         */
021:
022:        package org.apache.derby.impl.sql.compile;
023:
024:        import org.apache.derby.iapi.sql.compile.C_NodeTypes;
025:
026:        import org.apache.derby.iapi.services.sanity.SanityManager;
027:
028:        import org.apache.derby.iapi.error.StandardException;
029:
030:        import org.apache.derby.iapi.sql.dictionary.DataDictionary;
031:        import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
032:        import org.apache.derby.iapi.types.TypeId;
033:
034:        import org.apache.derby.iapi.types.ConcatableDataValue;
035:        import org.apache.derby.iapi.types.BitDataValue;
036:
037:        import org.apache.derby.iapi.sql.compile.TypeCompiler;
038:        import org.apache.derby.iapi.types.DataTypeDescriptor;
039:
040:        import org.apache.derby.iapi.services.compiler.MethodBuilder;
041:        import org.apache.derby.iapi.services.compiler.LocalField;
042:        import org.apache.derby.impl.sql.compile.ExpressionClassBuilder;
043:
044:        import org.apache.derby.iapi.reference.Limits;
045:        import org.apache.derby.iapi.reference.SQLState;
046:        import org.apache.derby.iapi.reference.ClassName;
047:
048:        import java.sql.Types;
049:
050:        import java.util.Vector;
051:
052:        /**
053:         * This node represents a concatenation comparison operator
054:         *
055:         * @author Jerry Brenner -- modified by jamie for bit and bit
056:         *							varying.
057:         */
058:
059:        public class ConcatenationOperatorNode extends BinaryOperatorNode {
060:            /**
061:             * Initializer for a ConcatenationOperatorNode
062:             *
063:             * @param leftOperand	The left operand of the concatenation
064:             * @param rightOperand	The right operand of the concatenation
065:             */
066:            public void init(Object leftOperand, Object rightOperand) {
067:                super .init(leftOperand, rightOperand, "||", "concatenate",
068:                        ClassName.ConcatableDataValue,
069:                        ClassName.ConcatableDataValue);
070:            }
071:
072:            /**
073:             * overrides BindOperatorNode.bindExpression because concatenation has special
074:             * requirements for parameter binding.
075:             *
076:             * @exception StandardException thrown on failure
077:             */
078:            public ValueNode bindExpression(FromList fromList,
079:                    SubqueryList subqueryList, Vector aggregateVector)
080:                    throws StandardException {
081:                // deal with binding operands
082:                leftOperand = leftOperand.bindExpression(fromList,
083:                        subqueryList, aggregateVector);
084:                rightOperand = rightOperand.bindExpression(fromList,
085:                        subqueryList, aggregateVector);
086:
087:                // deal with operand parameters
088:                /*
089:                	Is there a ? parameter on the left?
090:                	If so, it's type is the type of the other parameter, with
091:                	maximum length for that type.
092:                 */
093:
094:                if (leftOperand.requiresTypeFromContext()) {
095:                    if (rightOperand.requiresTypeFromContext()) {
096:                        throw StandardException.newException(
097:                                SQLState.LANG_BINARY_OPERANDS_BOTH_PARMS,
098:                                operator);
099:                    }
100:
101:                    TypeId leftType;
102:
103:                    /*
104:                     ** A ? on the left gets its type from the right.  There are eight
105:                     ** legal types for the concatenation operator: CHAR, VARCHAR,
106:                     ** LONG VARCHAR, CLOB, BIT, BIT VARYING, LONG BIT VARYING, and BLOB.
107:                     ** If the right type is BLOB, set the parameter type to BLOB with max length.
108:                     ** If the right type is one of the other bit types, set the parameter type to
109:                     ** BIT VARYING with maximum length.
110:                     **
111:                     ** If the right type is CLOB, set parameter type to CLOB with max length.
112:                     ** If the right type is anything else, set it to VARCHAR with
113:                     ** maximum length.  We count on the resolveConcatOperation method to
114:                     ** catch an illegal type.
115:                     **
116:                     ** NOTE: When I added the long types, I could have changed the
117:                     ** resulting parameter types to LONG VARCHAR and LONG BIT VARYING,
118:                     ** but they were already VARCHAR and BIT VARYING, and it wasn't
119:                     ** clear to me what effect it would have to change it. -	Jeff
120:                     */
121:                    if (rightOperand.getTypeId().isBitTypeId()) {
122:                        if (rightOperand.getTypeId().isBlobTypeId())
123:                            leftType = TypeId.getBuiltInTypeId(Types.BLOB);
124:                        else
125:                            leftType = TypeId.getBuiltInTypeId(Types.VARBINARY);
126:                    } else {
127:                        if (rightOperand.getTypeId().isClobTypeId())
128:                            leftType = TypeId.getBuiltInTypeId(Types.CLOB);
129:                        else
130:                            leftType = TypeId.getBuiltInTypeId(Types.VARCHAR);
131:                    }
132:
133:                    leftOperand.setType(new DataTypeDescriptor(leftType, true));
134:                }
135:
136:                /*
137:                	Is there a ? parameter on the right?
138:                 */
139:                if (rightOperand.requiresTypeFromContext()) {
140:                    TypeId rightType;
141:
142:                    /*
143:                     ** A ? on the right gets its type from the left.  There are eight
144:                     ** legal types for the concatenation operator: CHAR, VARCHAR,
145:                     ** LONG VARCHAR, CLOB, BIT, BIT VARYING, LONG BIT VARYING, and BLOB.
146:                     ** If the left type is BLOB, set the parameter type to BLOB with max length.
147:                     ** If the left type is one of the other bit types, set the parameter type to
148:                     ** BIT VARYING with maximum length.
149:                     **
150:                     ** If the left type is CLOB, set parameter type to CLOB with max length.
151:                     ** If the left type is anything else, set it to VARCHAR with
152:                     ** maximum length.  We count on the resolveConcatOperation method to
153:                     ** catch an illegal type.
154:                     **
155:                     ** NOTE: When I added the long types, I could have changed the
156:                     ** resulting parameter types to LONG VARCHAR and LONG BIT VARYING,
157:                     ** but they were already VARCHAR and BIT VARYING, and it wasn't
158:                     ** clear to me what effect it would have to change it. -	Jeff
159:                     */
160:                    if (leftOperand.getTypeId().isBitTypeId()) {
161:                        if (leftOperand.getTypeId().isBlobTypeId())
162:                            rightType = TypeId.getBuiltInTypeId(Types.BLOB);
163:                        else
164:                            rightType = TypeId
165:                                    .getBuiltInTypeId(Types.VARBINARY);
166:                    } else {
167:                        if (leftOperand.getTypeId().isClobTypeId())
168:                            rightType = TypeId.getBuiltInTypeId(Types.CLOB);
169:                        else
170:                            rightType = TypeId.getBuiltInTypeId(Types.VARCHAR);
171:                    }
172:
173:                    rightOperand
174:                            .setType(new DataTypeDescriptor(rightType, true));
175:                }
176:
177:                /* If the left operand is not a built-in type, then generate a bound conversion
178:                 * tree to a built-in type.
179:                 */
180:                if (leftOperand.getTypeId().userType()) {
181:                    leftOperand = leftOperand.genSQLJavaSQLTree();
182:                }
183:
184:                /* If the right operand is not a built-in type, then generate a bound conversion
185:                 * tree to a built-in type.
186:                 */
187:                if (rightOperand.getTypeId().userType()) {
188:                    rightOperand = rightOperand.genSQLJavaSQLTree();
189:                }
190:
191:                /* If either the left or right operands are non-string, non-bit types,
192:                 * then we generate an implicit cast to VARCHAR.
193:                 */
194:                TypeCompiler tc = leftOperand.getTypeCompiler();
195:                if (!(leftOperand.getTypeId().isStringTypeId() || leftOperand
196:                        .getTypeId().isBitTypeId())) {
197:                    leftOperand = (ValueNode) getNodeFactory().getNode(
198:                            C_NodeTypes.CAST_NODE,
199:                            leftOperand,
200:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
201:                                    Types.VARCHAR, true, tc
202:                                            .getCastToCharWidth(leftOperand
203:                                                    .getTypeServices())),
204:                            getContextManager());
205:                    ((CastNode) leftOperand).bindCastNodeOnly();
206:                }
207:                tc = rightOperand.getTypeCompiler();
208:                if (!(rightOperand.getTypeId().isStringTypeId() || rightOperand
209:                        .getTypeId().isBitTypeId())) {
210:                    rightOperand = (ValueNode) getNodeFactory().getNode(
211:                            C_NodeTypes.CAST_NODE,
212:                            rightOperand,
213:                            DataTypeDescriptor.getBuiltInDataTypeDescriptor(
214:                                    Types.VARCHAR, true, tc
215:                                            .getCastToCharWidth(rightOperand
216:                                                    .getTypeServices())),
217:                            getContextManager());
218:                    ((CastNode) rightOperand).bindCastNodeOnly();
219:                }
220:
221:                /*
222:                 ** Set the result type of this operator based on the operands.
223:                 ** By convention, the left operand gets to decide the result type
224:                 ** of a binary operator.
225:                 */
226:                tc = leftOperand.getTypeCompiler();
227:                setType(resolveConcatOperation(leftOperand.getTypeServices(),
228:                        rightOperand.getTypeServices()));
229:
230:                /*
231:                 ** Make sure the maximum width set for the result doesn't exceed the result type's maximum width
232:                 */
233:                if (SanityManager.DEBUG) {
234:                    if (getTypeServices().getMaximumWidth() > getTypeId()
235:                            .getMaximumMaximumWidth()) {
236:                        SanityManager
237:                                .THROWASSERT("The maximum length "
238:                                        + getTypeServices().getMaximumWidth()
239:                                        + " for the result type "
240:                                        + getTypeId().getSQLTypeName()
241:                                        + " can't be greater than it's maximum width of result's typeid"
242:                                        + getTypeId().getMaximumMaximumWidth());
243:                    }
244:                }
245:
246:                /*
247:                 ** Now that we know the target interface type, set it.  This assumes
248:                 ** that both operands have the same interface type, which is a safe
249:                 ** assumption for the concatenation operator.
250:                 */
251:                this .setLeftRightInterfaceType(tc.interfaceName());
252:
253:                return this ;
254:            }
255:
256:            /**
257:             * Resolve a concatenation operator
258:             *
259:             * @param leftType	The DataTypeDescriptor of the left operand
260:             * @param rightType	The DataTypeDescriptor of the right operand
261:             *
262:             * @return	A DataTypeDescriptor telling the result type of the 
263:             *			concatenate operation
264:             *
265:             * @exception StandardException BinaryOperatorNotSupported
266:             *						Thrown when a BinaryOperator is not supported
267:             *						on the operand types.
268:             */
269:            private DataTypeDescriptor resolveConcatOperation(
270:                    DataTypeDescriptor leftType, DataTypeDescriptor rightType)
271:                    throws StandardException {
272:                TypeId leftTypeId;
273:                TypeId rightTypeId;
274:                String higherType;
275:                int resultLength;
276:                boolean nullable;
277:
278:                leftTypeId = leftType.getTypeId();
279:                rightTypeId = rightType.getTypeId();
280:
281:                /*
282:                 ** Check the right type to be sure it's a concatable.  By convention,
283:                 ** we call this method off the TypeId of the left operand, so if
284:                 ** we get here, we know the left operand is a concatable.
285:                 */
286:                /*
287:                 ** Make sure we haven't been given a char and a
288:                 ** bit to concatenate.
289:                 */
290:
291:                if (!leftTypeId.isConcatableTypeId()
292:                        || !rightTypeId.isConcatableTypeId()
293:                        || (rightTypeId.isBitTypeId() && leftTypeId
294:                                .isStringTypeId())
295:                        || (leftTypeId.isBitTypeId() && rightTypeId
296:                                .isStringTypeId()))
297:                    throw StandardException.newException(
298:                            SQLState.LANG_DB2_FUNCTION_INCOMPATIBLE, "||",
299:                            "FUNCTION");
300:
301:                /*
302:                 ** The types aren't the same.  The result of the operation is the
303:                 ** type of higher precedence.
304:                 */
305:
306:                higherType = (leftTypeId.typePrecedence() >= rightTypeId
307:                        .typePrecedence()) ? leftType.getTypeName() : rightType
308:                        .getTypeName();
309:
310:                /* Get the length of the result */
311:                resultLength = leftType.getMaximumWidth()
312:                        + rightType.getMaximumWidth();
313:
314:                /*
315:                 ** Use following chart to handle overflow
316:                 ** operands CHAR(A) CHAR(B) and A+B<255 then result is CHAR(A+B)
317:                 ** operands CHAR FOR BIT DATA(A) CHAR FOR BIT DATA(B) and A+B<255 then result is CHAR FOR BIT DATA(A+B)
318:                 **
319:                 ** operands CHAR(A) CHAR(B) and A+B>254 then result is VARCHAR(A+B)
320:                 ** operands CHAR FOR BIT DATA(A) CHAR FOR BIT DATA(B) and A+B>254 then result is VARCHAR FOR BIT DATA(A+B)
321:                 **
322:                 ** operands CHAR(A) VARCHAR(B) and A+B<4001 then result is VARCHAR(A+B)
323:                 ** operands CHAR FOR BIT DATA(A) VARCHAR FOR BIT DATA(B) and A+B<4001 then result is VARCHAR FOR BIT DATA(A+B)
324:                 **
325:                 ** operands CHAR(A) VARCHAR(B) and A+B>4000 then result is LONG VARCHAR
326:                 ** operands CHAR FOR BIT DATA(A) VARCHAR FOR BIT DATA(B) and A+B>4000 then result is LONG VARCHAR FOR BIT DATA
327:                 **
328:                 ** operands CHAR(A) LONG VARCHAR then result is LONG VARCHAR
329:                 ** operands CHAR FOR BIT DATA(A) LONG VARCHAR FOR BIT DATA then result is LONG VARCHAR FOR BIT DATA
330:                 **
331:                 ** operands VARCHAR(A) VARCHAR(B) and A+B<4001 then result is VARCHAR(A+B)
332:                 ** operands VARCHAR FOR BIT DATA(A) VARCHAR FOR BIT DATA(B) and A+B<4001 then result is VARCHAR FOR BIT DATA(A+B)
333:                 **
334:                 ** operands VARCHAR(A) VARCHAR(B) and A+B>4000 then result is LONG VARCHAR
335:                 ** operands VARCHAR FOR BIT DATA(A) VARCHAR FOR BIT DATA(B) and A+B>4000 then result is LONG VARCHAR FOR BIT DATA
336:                 **
337:                 ** operands VARCHAR(A) LONG VARCHAR then result is LONG VARCHAR
338:                 ** operands VARCHAR FOR BIT DATA(A) LONG VARCHAR FOR BIT DATA then result is LONG VARCHAR FOR BIT DATA
339:                 **
340:                 ** operands LONG VARCHAR, LONG VARCHAR then result is LONG VARCHAR
341:                 ** operands LONG VARCHAR FOR BIT DATA, LONG VARCHAR FOR BIT DATA then result is LONG VARCHAR FOR BIT DATA
342:                 **
343:                 ** operands CLOB(A), CHAR(B) then result is CLOB(MIN(A+B,2G))
344:                 ** operands CLOB(A), VARCHAR(B) then result is CLOB(MIN(A+B,2G))
345:                 ** operands CLOB(A), LONG VARCHAR then result is CLOB(MIN(A+32K,2G))
346:                 ** operands CLOB(A), CLOB(B) then result is CLOB(MIN(A+B,2G))
347:                 **
348:                 ** operands BLOB(A), CHAR FOR BIT DATA(B) then result is BLOB(MIN(A+B,2G))
349:                 ** operands BLOB(A), VARCHAR FOR BIT DATA(B) then result is BLOB(MIN(A+B,2G))
350:                 ** operands BLOB(A), LONG VARCHAR FOR BIT DATA then result is BLOB(MIN(A+32K,2G))
351:                 ** operands BLOB(A), BLOB(B) then result is BLOB(MIN(A+B,2G))
352:                 **
353:                 ** operands CHAR(A)/VARCHAR(A)/LONGVARCHAR, LONGVARCHAR and "concatenated string length">32700 does not cause automatic escalation
354:                 ** to LOB for compatibility with previous releases. Any such cases would result in an error at runtime
355:                 **
356:                 */
357:                //in the following code, I can assume that left and right operands both will be either char kind
358:                //of datatypes or they will be both binary kind of datatypes. That's because operand datatypes
359:                //mismatch has already been handled earlier
360:                if (leftTypeId.getJDBCTypeId() == Types.CHAR
361:                        || leftTypeId.getJDBCTypeId() == Types.BINARY) {
362:                    switch (rightTypeId.getJDBCTypeId()) {
363:                    case Types.CHAR:
364:                    case Types.BINARY:
365:                        if (resultLength > Limits.DB2_CHAR_MAXWIDTH) {
366:                            if (rightTypeId.getJDBCTypeId() == Types.CHAR)
367:                                //operands CHAR(A) CHAR(B) and A+B>254 then result is VARCHAR(A+B)
368:                                higherType = TypeId.VARCHAR_NAME;
369:                            else
370:                                //operands CHAR FOR BIT DATA(A) CHAR FOR BIT DATA(B) and A+B>254 then result is VARCHAR FOR BIT DATA(A+B)
371:                                higherType = TypeId.VARBIT_NAME;
372:                        }
373:                        break;
374:
375:                    case Types.VARCHAR:
376:                    case Types.VARBINARY:
377:                        if (resultLength > Limits.DB2_CONCAT_VARCHAR_LENGTH) {
378:                            if (rightTypeId.getJDBCTypeId() == Types.VARCHAR)
379:                                //operands CHAR(A) VARCHAR(B) and A+B>4000 then result is LONG VARCHAR
380:                                higherType = TypeId.LONGVARCHAR_NAME;
381:                            else
382:                                //operands CHAR FOR BIT DATA(A) VARCHAR FOR BIT DATA(B) and A+B>4000 then result is LONG VARCHAR FOR BIT DATA
383:                                higherType = TypeId.LONGVARBIT_NAME;
384:                        }
385:                        break;
386:
387:                    case Types.CLOB:
388:                    case Types.BLOB:
389:                        //operands CHAR(A), CLOB(B) then result is CLOB(MIN(A+B,2G))
390:                        //operands CHAR FOR BIT DATA(A), BLOB(B) then result is BLOB(MIN(A+B,2G))
391:                        resultLength = clobBlobHandling(rightType, leftType);
392:                        break;
393:                    }
394:                } else if (leftTypeId.getJDBCTypeId() == Types.VARCHAR) {
395:                    switch (rightTypeId.getJDBCTypeId()) {
396:                    case Types.CHAR: //operands CHAR(A) VARCHAR(B) and A+B>4000 then result is LONG VARCHAR
397:                    case Types.VARCHAR: //operands VARCHAR(A) VARCHAR(B) and A+B>4000 then result is LONG VARCHAR
398:                        if (resultLength > Limits.DB2_CONCAT_VARCHAR_LENGTH)
399:                            higherType = TypeId.LONGVARCHAR_NAME;
400:                        break;
401:
402:                    case Types.CLOB:
403:                        //operands VARCHAR(A), CLOB(B) then result is CLOB(MIN(A+B,2G))
404:                        resultLength = clobBlobHandling(rightType, leftType);
405:                        break;
406:                    }
407:                } else if (leftTypeId.getJDBCTypeId() == Types.VARBINARY) {
408:                    switch (rightTypeId.getJDBCTypeId()) {
409:                    case Types.BINARY: //operands CHAR FOR BIT DATA(A) VARCHAR FOR BIT DATA(B) and A+B>4000 then result is LONG VARCHAR FOR BIT DATA
410:                    case Types.VARBINARY://operands VARCHAR FOR BIT DATA(A) VARCHAR FOR BIT DATA(B) and A+B>4000 then result is LONG VARCHAR FOR BIT DATA
411:                        if (resultLength > Limits.DB2_CONCAT_VARCHAR_LENGTH)
412:                            higherType = TypeId.LONGVARBIT_NAME;
413:                        break;
414:
415:                    case Types.BLOB:
416:                        //operands VARCHAR FOR BIT DATA(A), BLOB(B) then result is BLOB(MIN(A+B,2G))
417:                        resultLength = clobBlobHandling(rightType, leftType);
418:                        break;
419:                    }
420:                } else if (leftTypeId.getJDBCTypeId() == Types.CLOB
421:                        || leftTypeId.getJDBCTypeId() == Types.BLOB) {
422:                    //operands CLOB(A), CHAR(B) then result is CLOB(MIN(A+B,2G))
423:                    //operands CLOB(A), VARCHAR(B) then result is CLOB(MIN(A+B,2G))
424:                    //operands CLOB(A), LONG VARCHAR then result is CLOB(MIN(A+32K,2G))
425:                    //operands CLOB(A), CLOB(B) then result is CLOB(MIN(A+B,2G))
426:                    //operands BLOB(A), CHAR FOR BIT DATA(B) then result is BLOB(MIN(A+B,2G))
427:                    //operands BLOB(A), VARCHAR FOR BIT DATA(B) then result is BLOB(MIN(A+B,2G))
428:                    //operands BLOB(A), LONG VARCHAR FOR BIT DATA then result is BLOB(MIN(A+32K,2G))
429:                    //operands BLOB(A), BLOB(B) then result is BLOB(MIN(A+B,2G))
430:                    resultLength = clobBlobHandling(leftType, rightType);
431:                } else if (rightTypeId.getJDBCTypeId() == Types.CLOB
432:                        || rightTypeId.getJDBCTypeId() == Types.BLOB) {
433:                    //operands LONG VARCHAR, CLOB(A) then result is CLOB(MIN(A+32K,2G))
434:                    //operands LONG VARCHAR FOR BIT DATA, BLOB(A) then result is BLOB(MIN(A+32K,2G))
435:                    resultLength = clobBlobHandling(rightType, leftType);
436:                }
437:
438:                //bug - 5837. long varchar and long binary can't hold more data than their specific limits. If this length is violated by resulting
439:                //concatenated string, an exception will be thrown at execute time.
440:                if (higherType.equals(TypeId.LONGVARCHAR_NAME))
441:                    resultLength = TypeId.LONGVARCHAR_MAXWIDTH;
442:                else if (higherType.equals(TypeId.LONGVARBIT_NAME))
443:                    resultLength = TypeId.LONGVARBIT_MAXWIDTH;
444:
445:                /*
446:                 ** Result Length can't be negative
447:                 */
448:                if (SanityManager.DEBUG) {
449:                    if (resultLength < 0) {
450:                        SanityManager
451:                                .THROWASSERT("There should not be an overflow of maximum length for any result type at this point. Overflow for BLOB/CLOB has already been handled earlier");
452:                    }
453:                }
454:
455:                /* The result is nullable if either side is nullable */
456:                nullable = leftType.isNullable() || rightType.isNullable();
457:
458:                /*
459:                 ** Create a new DataTypeDescriptor that has the correct
460:                 ** type and nullability.
461:                 **
462:                 ** It's OK to call the implementation of the DataTypeDescriptorFactory
463:                 ** here, because we're in the same package.
464:                 */
465:                return new DataTypeDescriptor(TypeId
466:                        .getBuiltInTypeId(higherType), nullable, resultLength);
467:            }
468:
469:            /*
470:             *for conatenation operator, we generate code as follows
471:             *field = method(p1, p2, field);
472:             *what we are ensuring here is if field is null then initialize it to NULL SQLxxx type.
473:             *Because of the following, at execution time, SQLxxx concatenate method do not have to
474:             *worry about field coming in as null
475:             */
476:            protected void initializeResultField(ExpressionClassBuilder acb,
477:                    MethodBuilder mb, LocalField resultField)
478:                    throws StandardException {
479:                mb.conditionalIfNull();//get the field on the stack and if it is null
480:                acb.generateNull(mb, getTypeCompiler());// yes, it is, hence create a NULL SQLxxx type object and put that on stack
481:                mb.startElseCode(); //no, it is not null
482:                mb.getField(resultField); //so put it back on the stack
483:                mb.completeConditional(); //complete if else block
484:            }
485:
486:            private static int clobBlobHandling(
487:                    DataTypeDescriptor clobBlobType,
488:                    DataTypeDescriptor otherType) throws StandardException {
489:                int resultLength;
490:
491:                if (otherType.getTypeId().getJDBCTypeId() == Types.LONGVARCHAR
492:                        || otherType.getTypeId().getJDBCTypeId() == Types.LONGVARBINARY) {
493:                    //operands CLOB(A), LONG VARCHAR then result is CLOB(MIN(A+32K,2G))
494:                    //operands BLOB(A), LONG VARCHAR FOR BIT DATA then result is BLOB(MIN(A+32K,2G))
495:                    resultLength = clobBlobType.getMaximumWidth() + 32768;
496:                } else {
497:                    //operands CLOB(A), CHAR(B) then result is CLOB(MIN(A+B,2G))
498:                    //operands CLOB(A), VARCHAR(B) then result is CLOB(MIN(A+B,2G))
499:                    //operands CLOB(A), CLOB(B) then result is CLOB(MIN(A+B,2G))
500:                    //operands BLOB(A), CHAR FOR BIT DATA(B) then result is BLOB(MIN(A+B,2G))
501:                    //operands BLOB(A), VARCHAR FOR BIT DATA(B) then result is BLOB(MIN(A+B,2G))
502:                    //operands BLOB(A), BLOB(B) then result is BLOB(MIN(A+B,2G))
503:                    resultLength = clobBlobType.getMaximumWidth()
504:                            + otherType.getMaximumWidth();
505:                }
506:
507:                if (resultLength < 1) //this mean A+B or A+32K is bigger than 2G
508:                    return (Integer.MAX_VALUE);
509:                else
510:                    return (resultLength);
511:
512:            }
513:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.