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


001:        /*
002:
003:           Derby - Class org.apache.derby.iapi.types.SQLBinary
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.iapi.types;
023:
024:        import org.apache.derby.iapi.reference.SQLState;
025:
026:        import org.apache.derby.iapi.services.io.ArrayInputStream;
027:        import org.apache.derby.iapi.services.io.FormatableBitSet;
028:        import org.apache.derby.iapi.services.io.NewByteArrayInputStream;
029:
030:        import org.apache.derby.iapi.types.DataTypeDescriptor;
031:        import org.apache.derby.iapi.types.DataValueDescriptor;
032:        import org.apache.derby.iapi.types.TypeId;
033:        import org.apache.derby.iapi.types.BitDataValue;
034:        import org.apache.derby.iapi.types.DataValueDescriptor;
035:        import org.apache.derby.iapi.types.ConcatableDataValue;
036:        import org.apache.derby.iapi.types.VariableSizeDataValue;
037:        import org.apache.derby.iapi.error.StandardException;
038:
039:        import org.apache.derby.iapi.services.io.FormatIdUtil;
040:        import org.apache.derby.iapi.services.io.StoredFormatIds;
041:        import org.apache.derby.iapi.services.io.StreamStorable;
042:        import org.apache.derby.iapi.services.io.FormatIdInputStream;
043:
044:        import org.apache.derby.iapi.services.sanity.SanityManager;
045:
046:        import org.apache.derby.iapi.types.BooleanDataValue;
047:        import org.apache.derby.iapi.types.StringDataValue;
048:        import org.apache.derby.iapi.types.NumberDataValue;
049:
050:        import org.apache.derby.iapi.services.cache.ClassSize;
051:        import org.apache.derby.iapi.util.StringUtil;
052:
053:        import org.apache.derby.iapi.types.SQLInteger;
054:
055:        import java.io.ObjectOutput;
056:        import java.io.ObjectInput;
057:        import java.io.IOException;
058:        import java.io.InputStream;
059:
060:        import java.sql.ResultSet;
061:        import java.sql.SQLException;
062:        import java.sql.PreparedStatement;
063:
064:        /**
065:         * SQLBinary is the abstract class for the binary datatypes.
066:         * <UL>
067:         * <LI> CHAR FOR BIT DATA
068:         * <LI> VARCHAR FOR BIT DATA
069:         * <LI> LONG VARCHAR
070:         * <LI> BLOB
071:         * </UL>
072:
073:         <P>
074:         Format : <encoded length><raw data>
075:         <BR>
076:         Length is encoded to support Cloudscape 5.x databases where the length was stored as the number of bits.
077:         The first bit of the first byte indicates if the format is an old (Cloudscape 5.x) style or a new Derby style.
078:         Derby then uses the next two bits to indicate how the length is encoded.
079:         <BR>
080:         <encoded length> is one of N styles.
081:         <UL>
082:         <LI> (5.x format zero) 4 byte Java format integer value 0 - either <raw data> is 0 bytes/bits  or an unknown number of bytes.
083:         <LI> (5.x format bits) 4 byte Java format integer value >0 (positive) - number of bits in <raw data>, number of bytes in <raw data>
084:         is the minimum number of bytes required to store the number of bits.
085:         <LI> (Derby format) 1 byte encoded length (0 <= L <= 31) - number of bytes of <raw data> - encoded = 0x80 & L
086:         <LI> (Derby format) 3 byte encoded length (32 <= L < 64k) - number of bytes of <raw data> - encoded = 0xA0 <L as Java format unsigned short>
087:         <LI> (Derby format) 5 byte encoded length (64k <= L < 2G) - number of bytes of <raw data> - encoded = 0xC0 <L as Java format integer>
088:         <LI> (future) to be determined L >= 2G - encoded 0xE0 <encoding of L to be determined>
089:         (0xE0 is an esacape to allow any number of arbitary encodings in the future).
090:         </UL>
091:         <BR>
092:         When the value was written from a byte array the Derby encoded byte
093:         length format was always used from Derby 10.0 onwards (ie. all open
094:         source versions).
095:         <BR>
096:         When the value was written from a stream (e.g. PreparedStatement.setBinaryStream)
097:         then the Cloudscape '5.x format zero' was used by 10.0 and 10.1.
098:         The was due to the class RawToBinaryFormatStream always writing
099:         four zero bytes for the length before the data.
100:         <BR>
101:         The Cloudscape '5.x format bits' format I think was never used by Derby.
102:         */
103:        abstract class SQLBinary extends DataType implements  BitDataValue {
104:
105:            static final byte PAD = (byte) 0x20;
106:
107:            private static final int BASE_MEMORY_USAGE = ClassSize
108:                    .estimateBaseFromCatalog(SQLBinary.class);
109:
110:            public int estimateMemoryUsage() {
111:                if (dataValue == null) {
112:                    if (streamValueLength >= 0) {
113:                        return BASE_MEMORY_USAGE + streamValueLength;
114:                    } else {
115:                        return getMaxMemoryUsage();
116:                    }
117:                } else {
118:                    return BASE_MEMORY_USAGE + dataValue.length;
119:                }
120:            } // end of estimateMemoryUsage
121:
122:            /**
123:             * Return max memory usage for a SQL Binary
124:             */
125:            abstract int getMaxMemoryUsage();
126:
127:            /*
128:             * object state
129:             */
130:            byte[] dataValue;
131:
132:            /**
133:             * Value as a stream, this stream represents the on-disk
134:             * format of the value. That is it has length information
135:             * encoded in the first fe bytes.
136:             */
137:            InputStream stream;
138:
139:            /**
140:            	Length of the value in bytes when this value
141:                is set as a stream. Represents the length of the
142:                value itself and not the length of the stream
143:                which contains this length encoded as the first
144:                few bytes. If the value of the stream is unknown
145:                then this will be set to -1. If this value is
146:                not set as a stream then this value should be ignored.
147:             */
148:            int streamValueLength;
149:
150:            /**
151:            	no-arg constructor, required by Formattable.
152:             */
153:            SQLBinary() {
154:            }
155:
156:            SQLBinary(byte[] val) {
157:                dataValue = val;
158:            }
159:
160:            public final void setValue(byte[] theValue) {
161:                dataValue = theValue;
162:                stream = null;
163:                streamValueLength = -1;
164:            }
165:
166:            /**
167:             * Used by JDBC -- string should not contain
168:             * SQL92 formatting.
169:             *
170:             * @exception StandardException		Thrown on error
171:             */
172:            public final String getString() throws StandardException {
173:                if (getValue() == null)
174:                    return null;
175:                else if (dataValue.length * 2 < 0) //if converted to hex, length exceeds max int
176:                {
177:                    throw StandardException.newException(
178:                            SQLState.LANG_STRING_TRUNCATION, getTypeName(), "",
179:                            String.valueOf(Integer.MAX_VALUE));
180:                } else {
181:                    return org.apache.derby.iapi.util.StringUtil.toHexString(
182:                            dataValue, 0, dataValue.length);
183:                }
184:            }
185:
186:            /**
187:             * @exception StandardException		Thrown on error
188:             */
189:            public final InputStream getStream() {
190:                return (stream);
191:            }
192:
193:            /**
194:             *
195:             * @exception StandardException		Thrown on error
196:             */
197:            public final byte[] getBytes() throws StandardException {
198:                return getValue();
199:            }
200:
201:            byte[] getValue() throws StandardException {
202:                try {
203:                    if ((dataValue == null) && (stream != null)) {
204:
205:                        if (stream instanceof  FormatIdInputStream) {
206:                            readExternal((FormatIdInputStream) stream);
207:                        } else {
208:                            readExternal(new FormatIdInputStream(stream));
209:                        }
210:                        stream = null;
211:                        streamValueLength = -1;
212:
213:                    }
214:                } catch (IOException ioe) {
215:                    throw StandardException.newException(
216:                            SQLState.LANG_STREAMING_COLUMN_I_O_EXCEPTION, ioe,
217:                            getTypeName());
218:                }
219:                return dataValue;
220:            }
221:
222:            /**
223:             * length in bytes
224:             *
225:             * @exception StandardException		Thrown on error
226:             */
227:            public final int getLength() throws StandardException {
228:                if (stream != null) {
229:
230:                    if (streamValueLength != -1)
231:                        return streamValueLength;
232:                }
233:
234:                return (getBytes() == null) ? 0 : getBytes().length;
235:            }
236:
237:            /*
238:             * Storable interface, implies Externalizable, TypedFormat
239:             */
240:
241:            /**
242:             * see if the Bit value is null.
243:             * @see org.apache.derby.iapi.services.io.Storable#isNull
244:             */
245:            public final boolean isNull() {
246:                return (dataValue == null) && (stream == null);
247:            }
248:
249:            /** 
250:            	Write the value out from the byte array (not called if null)
251:            	using the 8.1 encoding.
252:
253:             * @exception IOException		io exception
254:             */
255:            public final void writeExternal(ObjectOutput out)
256:                    throws IOException {
257:
258:                int len = dataValue.length;
259:                if (len <= 31) {
260:                    out.write((byte) (0x80 | (len & 0xff)));
261:                } else if (len <= 0xFFFF) {
262:                    out.write((byte) 0xA0);
263:                    out.writeShort((short) len);
264:                } else {
265:                    out.write((byte) 0xC0);
266:                    out.writeInt(len);
267:
268:                }
269:                out.write(dataValue, 0, dataValue.length);
270:            }
271:
272:            /** 
273:             * delegated to bit 
274:             *
275:             * @exception IOException			io exception
276:             * @exception ClassNotFoundException	class not found
277:             */
278:            public final void readExternal(ObjectInput in) throws IOException {
279:                // need to clear stream first, in case this object is reused, and
280:                // stream is set by previous use.  Track 3794.
281:                stream = null;
282:                streamValueLength = -1;
283:
284:                int len = SQLBinary.readBinaryLength(in);
285:
286:                if (len != 0) {
287:                    dataValue = new byte[len];
288:                    in.readFully(dataValue);
289:                } else {
290:                    readFromStream((InputStream) in);
291:                }
292:            }
293:
294:            public final void readExternalFromArray(ArrayInputStream in)
295:                    throws IOException {
296:                // need to clear stream first, in case this object is reused, and
297:                // stream is set by previous use.  Track 3794.
298:                stream = null;
299:                streamValueLength = -1;
300:
301:                int len = SQLBinary.readBinaryLength(in);
302:
303:                if (len != 0) {
304:                    dataValue = new byte[len];
305:                    in.readFully(dataValue);
306:                } else {
307:                    readFromStream(in);
308:                }
309:            }
310:
311:            /**
312:             * Read the encoded length of the value from the on-disk format.
313:             * 
314:             * @see SQLBinary
315:             */
316:            private static int readBinaryLength(ObjectInput in)
317:                    throws IOException {
318:
319:                int bl = in.read();
320:                if (bl == -1)
321:                    throw new java.io.EOFException();
322:
323:                byte li = (byte) bl;
324:
325:                int len;
326:                if ((li & ((byte) 0x80)) != 0) {
327:                    if (li == ((byte) 0xC0)) {
328:                        len = in.readInt();
329:                    } else if (li == ((byte) 0xA0)) {
330:                        len = in.readUnsignedShort();
331:                    } else {
332:                        len = li & 0x1F;
333:                    }
334:                } else {
335:
336:                    // old length in bits
337:                    int v2 = in.read();
338:                    int v3 = in.read();
339:                    int v4 = in.read();
340:                    if (v2 == -1 || v3 == -1 || v4 == -1)
341:                        throw new java.io.EOFException();
342:                    int lenInBits = (((bl & 0xff) << 24) | ((v2 & 0xff) << 16)
343:                            | ((v3 & 0xff) << 8) | (v4 & 0xff));
344:
345:                    len = lenInBits / 8;
346:                    if ((lenInBits % 8) != 0)
347:                        len++;
348:                }
349:                return len;
350:            }
351:
352:            /**
353:             * Read the value from an input stream. The length
354:             * encoded in the input stream has already been read
355:             * and determined to be unknown.
356:             */
357:            private void readFromStream(InputStream in) throws IOException {
358:
359:                dataValue = null; // allow gc of the old value before the new.
360:                byte[] tmpData = new byte[32 * 1024];
361:
362:                int off = 0;
363:                for (;;) {
364:
365:                    int len = in.read(tmpData, off, tmpData.length - off);
366:                    if (len == -1)
367:                        break;
368:                    off += len;
369:
370:                    int available = Math.max(1, in.available());
371:                    int extraSpace = available - (tmpData.length - off);
372:                    if (extraSpace > 0) {
373:                        // need to grow the array
374:                        int size = tmpData.length * 2;
375:                        if (extraSpace > tmpData.length)
376:                            size += extraSpace;
377:
378:                        byte[] grow = new byte[size];
379:                        System.arraycopy(tmpData, 0, grow, 0, off);
380:                        tmpData = grow;
381:                    }
382:                }
383:
384:                dataValue = new byte[off];
385:                System.arraycopy(tmpData, 0, dataValue, 0, off);
386:            }
387:
388:            /**
389:             * @see org.apache.derby.iapi.services.io.Storable#restoreToNull
390:             */
391:            public final void restoreToNull() {
392:                dataValue = null;
393:                stream = null;
394:                streamValueLength = -1;
395:            }
396:
397:            /**
398:            	@exception StandardException thrown on error
399:             */
400:            public final boolean compare(int op, DataValueDescriptor other,
401:                    boolean orderedNulls, boolean unknownRV)
402:                    throws StandardException {
403:                if (!orderedNulls) // nulls are unordered
404:                {
405:                    if (SanityManager.DEBUG) {
406:                        int otherTypeFormatId = other.getTypeFormatId();
407:                        if (!((StoredFormatIds.SQL_BIT_ID == otherTypeFormatId)
408:                                || (StoredFormatIds.SQL_VARBIT_ID == otherTypeFormatId)
409:                                || (StoredFormatIds.SQL_LONGVARBIT_ID == otherTypeFormatId)
410:
411:                                || (StoredFormatIds.SQL_CHAR_ID == otherTypeFormatId)
412:                                || (StoredFormatIds.SQL_VARCHAR_ID == otherTypeFormatId)
413:                                || (StoredFormatIds.SQL_LONGVARCHAR_ID == otherTypeFormatId)
414:
415:                        || ((StoredFormatIds.SQL_BLOB_ID == otherTypeFormatId) && (StoredFormatIds.SQL_BLOB_ID == getTypeFormatId()))))
416:                            SanityManager.THROWASSERT("Some fool passed in a "
417:                                    + other.getClass().getName() + ", "
418:                                    + otherTypeFormatId
419:                                    + " to SQLBinary.compare()");
420:                    }
421:                    String otherString = other.getString();
422:                    if (this .getString() == null || otherString == null)
423:                        return unknownRV;
424:                }
425:                /* Do the comparison */
426:                return super .compare(op, other, orderedNulls, unknownRV);
427:            }
428:
429:            /**
430:            	@exception StandardException thrown on error
431:             */
432:            public final int compare(DataValueDescriptor other)
433:                    throws StandardException {
434:
435:                /* Use compare method from dominant type, negating result
436:                 * to reflect flipping of sides.
437:                 */
438:                if (typePrecedence() < other.typePrecedence()) {
439:                    return -(other.compare(this ));
440:                }
441:
442:                /*
443:                 ** By convention, nulls sort High, and null == null
444:                 */
445:                if (this .isNull() || other.isNull()) {
446:                    if (!isNull())
447:                        return -1;
448:                    if (!other.isNull())
449:                        return 1;
450:                    return 0; // both null
451:                }
452:
453:                return SQLBinary.compare(getBytes(), other.getBytes());
454:            }
455:
456:            /*
457:             * CloneableObject interface
458:             */
459:
460:            /** From CloneableObject
461:             *	Shallow clone a StreamStorable without objectifying.  This is used to avoid
462:             *	unnecessary objectifying of a stream object.  The only difference of this method
463:             *  from getClone is this method does not objectify a stream.  beetle 4896
464:             */
465:            public final Object cloneObject() {
466:                if (stream == null)
467:                    return getClone();
468:                SQLBinary self = (SQLBinary) getNewNull();
469:                self.setValue(stream, streamValueLength);
470:                return self;
471:            }
472:
473:            /*
474:             * DataValueDescriptor interface
475:             */
476:
477:            /** @see DataValueDescriptor#getClone */
478:            public final DataValueDescriptor getClone() {
479:                try {
480:                    DataValueDescriptor cloneDVD = getNewNull();
481:                    cloneDVD.setValue(getValue());
482:                    return cloneDVD;
483:                } catch (StandardException se) {
484:                    if (SanityManager.DEBUG)
485:                        SanityManager.THROWASSERT("Unexpected exception " + se);
486:                    return null;
487:                }
488:            }
489:
490:            /*
491:             * DataValueDescriptor interface
492:             */
493:
494:            /*
495:             * StreamStorable interface : 
496:             */
497:            public final InputStream returnStream() {
498:                return stream;
499:            }
500:
501:            /**
502:             * Set me to the value represented by this stream.
503:             * The format of the stream is the on-disk format
504:             * described in this class's javadoc. That is the
505:             * length is encoded in the first few bytes of the
506:             * stream.
507:             */
508:            public final void setStream(InputStream newStream) {
509:                this .dataValue = null;
510:                this .stream = newStream;
511:                streamValueLength = -1;
512:            }
513:
514:            public final void loadStream() throws StandardException {
515:                getValue();
516:            }
517:
518:            /*
519:             * class interface
520:             */
521:
522:            boolean objectNull(Object o) {
523:                if (o == null) {
524:                    setToNull();
525:                    return true;
526:                }
527:                return false;
528:            }
529:
530:            /**
531:             * Set the value from the stream which is in the on-disk format.
532:             * @param theStream On disk format of the stream
533:             * @param valueLength length of the logical value in bytes.
534:             */
535:            public final void setValue(InputStream theStream, int valueLength) {
536:                dataValue = null;
537:                stream = theStream;
538:                this .streamValueLength = valueLength;
539:            }
540:
541:            protected final void setFrom(DataValueDescriptor theValue)
542:                    throws StandardException {
543:
544:                if (theValue instanceof  SQLBinary) {
545:                    SQLBinary theValueBinary = (SQLBinary) theValue;
546:                    dataValue = theValueBinary.dataValue;
547:                    stream = theValueBinary.stream;
548:                    streamValueLength = theValueBinary.streamValueLength;
549:                } else {
550:                    setValue(theValue.getBytes());
551:                }
552:            }
553:
554:            /*
555:             ** SQL Operators
556:             */
557:
558:            /**
559:             * The = operator as called from the language module, as opposed to
560:             * the storage module.
561:             *
562:             * @param left			The value on the left side of the =
563:             * @param right			The value on the right side of the =
564:             *						is not.
565:             * @return	A SQL boolean value telling whether the two parameters are equal
566:             *
567:             * @exception StandardException		Thrown on error
568:             */
569:
570:            public final BooleanDataValue equals(DataValueDescriptor left,
571:                    DataValueDescriptor right) throws StandardException {
572:                boolean isEqual;
573:
574:                if (left.isNull() || right.isNull()) {
575:                    isEqual = false;
576:                } else {
577:                    isEqual = SQLBinary.compare(left.getBytes(), right
578:                            .getBytes()) == 0;
579:                }
580:
581:                return SQLBoolean.truthValue(left, right, isEqual);
582:            }
583:
584:            /**
585:             * The <> operator as called from the language module, as opposed to
586:             * the storage module.
587:             *
588:             * @param left			The value on the left side of the <>
589:             * @param right			The value on the right side of the <>
590:             *
591:             * @return	A SQL boolean value telling whether the two parameters
592:             * are not equal
593:             *
594:             * @exception StandardException		Thrown on error
595:             */
596:
597:            public final BooleanDataValue notEquals(DataValueDescriptor left,
598:                    DataValueDescriptor right) throws StandardException {
599:                boolean isNotEqual;
600:
601:                if (left.isNull() || right.isNull()) {
602:                    isNotEqual = false;
603:                } else {
604:                    isNotEqual = SQLBinary.compare(left.getBytes(), right
605:                            .getBytes()) != 0;
606:                }
607:
608:                return SQLBoolean.truthValue(left, right, isNotEqual);
609:            }
610:
611:            /**
612:             * The < operator as called from the language module, as opposed to
613:             * the storage module.
614:             *
615:             * @param left			The value on the left side of the <
616:             * @param right			The value on the right side of the <
617:             *
618:             * @return	A SQL boolean value telling whether the first operand is
619:             *			less than the second operand
620:             *
621:             * @exception StandardException		Thrown on error
622:             */
623:
624:            public final BooleanDataValue lessThan(DataValueDescriptor left,
625:                    DataValueDescriptor right) throws StandardException {
626:                boolean isLessThan;
627:
628:                if (left.isNull() || right.isNull()) {
629:                    isLessThan = false;
630:                } else {
631:                    isLessThan = SQLBinary.compare(left.getBytes(), right
632:                            .getBytes()) < 0;
633:                }
634:
635:                return SQLBoolean.truthValue(left, right, isLessThan);
636:            }
637:
638:            /**
639:             * The > operator as called from the language module, as opposed to
640:             * the storage module.
641:             *
642:             * @param left			The value on the left side of the >
643:             * @param right			The value on the right side of the >
644:             *
645:             * @return	A SQL boolean value telling whether the first operand is
646:             *			greater than the second operand
647:             *
648:             * @exception StandardException		Thrown on error
649:             */
650:
651:            public final BooleanDataValue greaterThan(DataValueDescriptor left,
652:                    DataValueDescriptor right) throws StandardException {
653:                boolean isGreaterThan = false;
654:
655:                if (left.isNull() || right.isNull()) {
656:                    isGreaterThan = false;
657:                } else {
658:                    isGreaterThan = SQLBinary.compare(left.getBytes(), right
659:                            .getBytes()) > 0;
660:                }
661:
662:                return SQLBoolean.truthValue(left, right, isGreaterThan);
663:            }
664:
665:            /**
666:             * The <= operator as called from the language module, as opposed to
667:             * the storage module.
668:             *
669:             * @param left			The value on the left side of the <=
670:             * @param right			The value on the right side of the <=
671:             *
672:             * @return	A SQL boolean value telling whether the first operand is
673:             *			less than or equal to the second operand
674:             *
675:             * @exception StandardException		Thrown on error
676:             */
677:
678:            public final BooleanDataValue lessOrEquals(
679:                    DataValueDescriptor left, DataValueDescriptor right)
680:                    throws StandardException {
681:                boolean isLessEquals = false;
682:
683:                if (left.isNull() || right.isNull()) {
684:                    isLessEquals = false;
685:                } else {
686:                    isLessEquals = SQLBinary.compare(left.getBytes(), right
687:                            .getBytes()) <= 0;
688:                }
689:
690:                return SQLBoolean.truthValue(left, right, isLessEquals);
691:            }
692:
693:            /**
694:             * The >= operator as called from the language module, as opposed to
695:             * the storage module.
696:             *
697:             * @param left			The value on the left side of the >=
698:             * @param right			The value on the right side of the >=
699:             *
700:             * @return	A SQL boolean value telling whether the first operand is
701:             *			greater than or equal to the second operand
702:             *
703:             * @exception StandardException		Thrown on error
704:             */
705:
706:            public final BooleanDataValue greaterOrEquals(
707:                    DataValueDescriptor left, DataValueDescriptor right)
708:                    throws StandardException {
709:                boolean isGreaterEquals = false;
710:
711:                if (left.isNull() || right.isNull()) {
712:                    isGreaterEquals = false;
713:                } else {
714:                    isGreaterEquals = SQLBinary.compare(left.getBytes(), right
715:                            .getBytes()) >= 0;
716:                }
717:
718:                return SQLBoolean.truthValue(left, right, isGreaterEquals);
719:            }
720:
721:            /**
722:             *
723:             * This method implements the char_length function for bit.
724:             *
725:             * @param result	The result of a previous call to this method, null
726:             *					if not called yet
727:             *
728:             * @return	A SQLInteger containing the length of the char value
729:             *
730:             * @exception StandardException		Thrown on error
731:             *
732:             * @see ConcatableDataValue#charLength
733:             */
734:
735:            public final NumberDataValue charLength(NumberDataValue result)
736:                    throws StandardException {
737:                if (result == null) {
738:                    result = new SQLInteger();
739:                }
740:
741:                if (this .isNull()) {
742:                    result.setToNull();
743:                    return result;
744:                }
745:
746:                result.setValue(getValue().length);
747:                return result;
748:            }
749:
750:            /**
751:             * @see BitDataValue#concatenate
752:             *
753:             * @exception StandardException		Thrown on error
754:             */
755:            public final BitDataValue concatenate(BitDataValue left,
756:                    BitDataValue right, BitDataValue result)
757:                    throws StandardException {
758:                if (left.isNull() || right.isNull()) {
759:                    result.setToNull();
760:                    return result;
761:                }
762:
763:                byte[] leftData = left.getBytes();
764:                byte[] rightData = right.getBytes();
765:
766:                byte[] concatData = new byte[leftData.length + rightData.length];
767:
768:                System.arraycopy(leftData, 0, concatData, 0, leftData.length);
769:                System.arraycopy(rightData, 0, concatData, leftData.length,
770:                        rightData.length);
771:
772:                result.setValue(concatData);
773:                return result;
774:            }
775:
776:            /**
777:             * The SQL substr() function.
778:             *
779:             * @param start		Start of substr
780:             * @param length	Length of substr
781:             * @param result	The result of a previous call to this method,
782:             *					null if not called yet.
783:             * @param maxLen	Maximum length of the result
784:             *
785:             * @return	A ConcatableDataValue containing the result of the substr()
786:             *
787:             * @exception StandardException		Thrown on error
788:             */
789:            public final ConcatableDataValue substring(NumberDataValue start,
790:                    NumberDataValue length, ConcatableDataValue result,
791:                    int maxLen) throws StandardException {
792:                int startInt;
793:                int lengthInt;
794:                BitDataValue varbitResult;
795:
796:                if (result == null) {
797:                    result = new SQLVarbit();
798:                }
799:
800:                varbitResult = (BitDataValue) result;
801:
802:                /* The result is null if the receiver (this) is null or if the length is negative.
803:                 * Oracle docs don't say what happens if the start position or the length is a usernull.
804:                 * We will return null, which is the only sensible thing to do.
805:                 * (If the user did not specify a length then length is not a user null.)
806:                 */
807:                if (this .isNull() || start.isNull()
808:                        || (length != null && length.isNull())) {
809:                    varbitResult.setToNull();
810:                    return varbitResult;
811:                }
812:
813:                startInt = start.getInt();
814:
815:                // If length is not specified, make it till end of the string
816:                if (length != null) {
817:                    lengthInt = length.getInt();
818:                } else
819:                    lengthInt = getLength() - startInt + 1;
820:
821:                /* DB2 Compatibility: Added these checks to match DB2. We currently enforce these
822:                 * limits in both modes. We could do these checks in DB2 mode only, if needed, so
823:                 * leaving earlier code for out of range in for now, though will not be exercised
824:                 */
825:                if ((startInt <= 0 || lengthInt < 0 || startInt > getLength() || lengthInt > getLength()
826:                        - startInt + 1))
827:                    throw StandardException
828:                            .newException(SQLState.LANG_SUBSTR_START_OR_LEN_OUT_OF_RANGE);
829:
830:                // Return null if length is non-positive
831:                if (lengthInt < 0) {
832:                    varbitResult.setToNull();
833:                    return varbitResult;
834:                }
835:
836:                /* If startInt < 0 then we count from the right of the string */
837:                if (startInt < 0) {
838:                    startInt += getLength();
839:                    if (startInt < 0) {
840:                        lengthInt += startInt;
841:                        startInt = 0;
842:                    }
843:                    if (lengthInt + startInt > 0) {
844:                        lengthInt += startInt;
845:                    } else {
846:                        lengthInt = 0;
847:                    }
848:                } else if (startInt > 0) {
849:                    /* java substr() is 0 based */
850:                    startInt--;
851:                }
852:
853:                /* Oracle docs don't say what happens if the window is to the
854:                 * left of the string.  Return "" if the window
855:                 * is to the left or right or if the length is 0.
856:                 */
857:                if (lengthInt == 0 || lengthInt <= 0 - startInt
858:                        || startInt > getLength()) {
859:                    varbitResult.setValue(new byte[0]);
860:                    return varbitResult;
861:                }
862:
863:                if (lengthInt >= getLength() - startInt) {
864:                    byte[] substring = new byte[dataValue.length - startInt];
865:                    System.arraycopy(dataValue, startInt, substring, 0,
866:                            substring.length);
867:                    varbitResult.setValue(substring);
868:                } else {
869:                    byte[] substring = new byte[lengthInt];
870:                    System.arraycopy(dataValue, startInt, substring, 0,
871:                            substring.length);
872:                    varbitResult.setValue(substring);
873:                }
874:
875:                return varbitResult;
876:            }
877:
878:            /**
879:            	Host variables are rejected if their length is
880:            	bigger than the declared length, regardless of
881:            	if the trailing bytes are the pad character.
882:
883:            	@exception StandardException Variable is too big.
884:             */
885:            public final void checkHostVariable(int declaredLength)
886:                    throws StandardException {
887:                // stream length checking occurs at the JDBC layer
888:                int variableLength = -1;
889:                if (stream == null) {
890:                    if (dataValue != null)
891:                        variableLength = dataValue.length;
892:                } else {
893:                    variableLength = streamValueLength;
894:                }
895:
896:                if (variableLength != -1 && variableLength > declaredLength)
897:                    throw StandardException.newException(
898:                            SQLState.LANG_STRING_TRUNCATION, getTypeName(),
899:                            "XX-RESOLVE-XX", String.valueOf(declaredLength));
900:            }
901:
902:            /*
903:             * String display of value
904:             */
905:
906:            public final String toString() {
907:                if (dataValue == null) {
908:                    if (stream == null) {
909:                        return "NULL";
910:                    } else {
911:                        if (SanityManager.DEBUG)
912:                            SanityManager
913:                                    .THROWASSERT("value is null, stream is not null");
914:                        return "";
915:                    }
916:                } else {
917:                    return org.apache.derby.iapi.util.StringUtil.toHexString(
918:                            dataValue, 0, dataValue.length);
919:                }
920:            }
921:
922:            /*
923:             * Hash code
924:             */
925:            public final int hashCode() {
926:                try {
927:                    if (getValue() == null) {
928:                        return 0;
929:                    }
930:                } catch (StandardException se) {
931:                    if (SanityManager.DEBUG)
932:                        SanityManager.THROWASSERT("Unexpected exception " + se);
933:                    return 0;
934:                }
935:
936:                /* Hash code is simply the sum of all of the bytes */
937:                byte[] bytes = dataValue;
938:                int hashcode = 0;
939:
940:                // Build the hash code
941:                for (int index = 0; index < bytes.length; index++) {
942:                    byte bv = bytes[index];
943:                    if (bv != SQLBinary.PAD)
944:                        hashcode += bytes[index];
945:                }
946:
947:                return hashcode;
948:            }
949:
950:            private static int compare(byte[] left, byte[] right) {
951:
952:                int minLen = left.length;
953:                byte[] longer = right;
954:                if (right.length < minLen) {
955:                    minLen = right.length;
956:                    longer = left;
957:                }
958:
959:                for (int i = 0; i < minLen; i++) {
960:
961:                    int lb = left[i] & 0xff;
962:                    int rb = right[i] & 0xff;
963:
964:                    if (lb == rb)
965:                        continue;
966:
967:                    return lb - rb;
968:                }
969:
970:                // complete match on all the bytes for the smallest value.
971:
972:                // if the longer value is all pad characters
973:                // then the values are equal.
974:                for (int i = minLen; i < longer.length; i++) {
975:                    byte nb = longer[i];
976:                    if (nb == SQLBinary.PAD)
977:                        continue;
978:
979:                    // longer value is bigger.
980:                    if (left == longer)
981:                        return 1;
982:                    return -1;
983:                }
984:
985:                return 0;
986:
987:            }
988:
989:            /** Adding this method to ensure that super class' setInto method doesn't get called
990:             * that leads to the violation of JDBC spec( untyped nulls ) when batching is turned on.
991:             */
992:            public void setInto(PreparedStatement ps, int position)
993:                    throws SQLException, StandardException {
994:
995:                ps.setBytes(position, getBytes());
996:            }
997:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.