001: /*
002:
003: Derby - Class org.apache.derby.iapi.types.DataType
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.types.DataValueDescriptor;
025: import org.apache.derby.iapi.types.DataTypeDescriptor;
026: import org.apache.derby.iapi.types.BooleanDataValue;
027: import org.apache.derby.iapi.types.CloneableObject;
028: import org.apache.derby.iapi.types.Orderable;
029:
030: import org.apache.derby.iapi.reference.SQLState;
031: import org.apache.derby.iapi.error.StandardException;
032: import org.apache.derby.iapi.services.i18n.MessageService;
033: import org.apache.derby.iapi.services.sanity.SanityManager;
034:
035: import org.apache.derby.iapi.services.i18n.LocaleFinder;
036:
037: import java.io.InputStream;
038: import java.sql.Date;
039: import java.sql.Time;
040: import java.sql.Timestamp;
041: import java.sql.PreparedStatement;
042: import java.sql.SQLException;
043: import java.sql.ResultSet;
044:
045: import java.util.Calendar;
046:
047: /**
048: *
049: * DataType is the superclass for all data types.
050: * It provides common behavior
051: * for datavalue descriptors -- it throws
052: * exceptions for all of the get* and setvalue(*) methods of
053: * DataValueDescriptor; the subtypes need only
054: * override the one for the type they represent
055: * and all types it can also be returned as,
056: * and the methods dealing with nulls.
057: *
058: * Since all types satisfy getString
059: * DataType does not define that
060: * interfaces of DataValueDescriptor.
061: *
062: * DataType is a little glue for columns to hold
063: * values with.
064: *
065: */
066: public abstract class DataType implements DataValueDescriptor,
067: CloneableObject {
068: /*
069: * DataValueDescriptor Interface
070: */
071:
072: /**
073: * Gets the value in the data value descriptor as a boolean.
074: * Throws an exception if the data value is not receivable as a boolean.
075: *
076: * @return The data value as a boolean.
077: *
078: * @exception StandardException Thrown on error
079: */
080: public boolean getBoolean() throws StandardException {
081: throw dataTypeConversion("boolean");
082: }
083:
084: /**
085: * Gets the value in the data value descriptor as a byte.
086: * Throws an exception if the data value is not receivable as a byte.
087: *
088: * @return The data value as a byte.
089: *
090: * @exception StandardException Thrown on error
091: */
092: public byte getByte() throws StandardException {
093: throw dataTypeConversion("byte");
094: }
095:
096: /**
097: * Gets the value in the data value descriptor as a short.
098: * Throws an exception if the data value is not receivable as a short.
099: *
100: * @return The data value as a short.
101: *
102: * @exception StandardException Thrown on error
103: */
104: public short getShort() throws StandardException {
105: throw dataTypeConversion("short");
106: }
107:
108: /**
109: * Gets the value in the data value descriptor as a int.
110: * Throws an exception if the data value is not receivable as a int.
111: *
112: * @return The data value as a int.
113: *
114: * @exception StandardException Thrown on error
115: */
116: public int getInt() throws StandardException {
117: throw dataTypeConversion("int");
118: }
119:
120: /**
121: * Gets the value in the data value descriptor as a long.
122: * Throws an exception if the data value is not receivable as a long.
123: *
124: * @return The data value as a long.
125: *
126: * @exception StandardException Thrown on error
127: */
128: public long getLong() throws StandardException {
129: throw dataTypeConversion("long");
130: }
131:
132: /**
133: * Gets the value in the data value descriptor as a float.
134: * Throws an exception if the data value is not receivable as a float.
135: *
136: * @return The data value as a float.
137: *
138: * @exception StandardException Thrown on error
139: */
140: public float getFloat() throws StandardException {
141: throw dataTypeConversion("float");
142: }
143:
144: /**
145: * Gets the value in the data value descriptor as a double.
146: * Throws an exception if the data value is not receivable as a double.
147: *
148: * @return The data value as a double.
149: *
150: * @exception StandardException Thrown on error
151: */
152: public double getDouble() throws StandardException {
153: throw dataTypeConversion("double");
154: }
155:
156: public int typeToBigDecimal() throws StandardException {
157: throw dataTypeConversion("java.math.BigDecimal");
158: }
159:
160: /**
161: * Gets the value in the data value descriptor as a byte[].
162: * Throws an exception if the data value is not receivable as a Binary or Varbinary.
163: *
164: * @return The Binary value as a byte[].
165: *
166: * @exception StandardException Thrown on error
167: */
168: public byte[] getBytes() throws StandardException {
169: throw dataTypeConversion("byte[]");
170: }
171:
172: /**
173: * Gets the value in the data value descriptor as a java.sql.Date.
174: * Throws an exception if the data value is not receivable as a Date.
175: * @param cal calendar for object creation
176: * @return The data value as a java.sql.Date.
177: *
178: * @exception StandardException Thrown on error
179: */
180: public Date getDate(Calendar cal) throws StandardException {
181: throw dataTypeConversion("java.sql.Date");
182: }
183:
184: /**
185: * Gets the value in the data value descriptor as a java.sql.Time.
186: * Throws an exception if the data value is not receivable as a Time.
187: * @param cal calendar for object creation
188: * @return The data value as a java.sql.Time.
189: *
190: * @exception StandardException Thrown on error
191: */
192: public Time getTime(Calendar cal) throws StandardException {
193: throw dataTypeConversion("java.sql.Time");
194: }
195:
196: /**
197: * Gets the value in the data value descriptor as a java.sql.Timestamp.
198: * Throws an exception if the data value is not receivable as a Timestamp.
199: * @param cal calendar for object creation
200: * @return The data value as a java.sql.Timestamp.
201: *
202: * @exception StandardException Thrown on error
203: */
204: public Timestamp getTimestamp(Calendar cal)
205: throws StandardException {
206: throw dataTypeConversion("java.sql.Timestamp");
207: }
208:
209: /**
210: * Gets the value in the data stream descriptor as an InputStream.
211: * Throws an exception if the data value is not receivable as a stream.
212: *
213: * @return The data value as an InputStream.
214: *
215: * @exception StandardException Thrown on error
216: */
217: public InputStream getStream() throws StandardException {
218: throw dataTypeConversion(MessageService
219: .getTextMessage(SQLState.LANG_STREAM));
220: }
221:
222: /**
223: * Gets the value in the data stream descriptor as a trace string.
224: * This default implementation simply forwards the call to
225: * <code>getString</code>.
226: *
227: * @return The data value in a representation suitable for tracing.
228: * @throws StandardException if getting the data value fails.
229: * @see DataValueDescriptor#getString
230: */
231: public String getTraceString() throws StandardException {
232: return getString();
233: }
234:
235: /*
236: * Column interface
237: */
238:
239: /**
240: * The is null operator as called from the language module, as opposed to
241: * the storage module.
242: *
243: *
244: * @return A SQL boolean value telling whether the operand is null
245: *
246: */
247:
248: public final BooleanDataValue isNullOp() {
249: return SQLBoolean.truthValue(isNull());
250: }
251:
252: /**
253: * The is not null operator as called from the language module, as opposed to
254: * the storage module.
255: *
256: *
257: * @return A SQL boolean value telling whether the operand is not null
258: *
259: */
260:
261: public final BooleanDataValue isNotNull() {
262: return SQLBoolean.truthValue(!isNull());
263: }
264:
265: /**
266: * Set the value of this DataValueDescriptor.
267: * At DataType level just throws an error lower classes will override
268: *
269: * @param theValue The Time value to set this DataValueDescriptor to
270: */
271: public void setValue(Time theValue) throws StandardException {
272: setValue(theValue, (Calendar) null);
273: }
274:
275: /**
276: * Set the value of this DataValueDescriptor.
277: * At DataType level just throws an error lower classes will override
278: *
279: * @param theValue The Time value to set this DataValueDescriptor to
280: * @param cal The time zone from the calendar is used to construct the database time value
281: */
282: public void setValue(Time theValue, Calendar cal)
283: throws StandardException {
284: throwLangSetMismatch("java.sql.Time");
285: }
286:
287: /**
288: * Set the value of this DataValueDescriptor.
289: * At DataType level just throws an error lower classes will override
290: *
291: * @param theValue The Timestamp value to set this DataValueDescriptor to
292: */
293: public void setValue(Timestamp theValue) throws StandardException {
294: setValue(theValue, (Calendar) null);
295: }
296:
297: /**
298: * Set the value of this DataValueDescriptor.
299: * At DataType level just throws an error lower classes will override
300: *
301: * @param theValue The Timestamp value to set this DataValueDescriptor to
302: * @param cal The time zone from the calendar is used to construct the database timestamp value
303: */
304: public void setValue(Timestamp theValue, Calendar cal)
305: throws StandardException {
306: throwLangSetMismatch("java.sql.Timestamp");
307: }
308:
309: /**
310: * Set the value of this DataValueDescriptor.
311: * At DataType level just throws an error lower classes will override
312: *
313: * @param theValue The Date value to set this DataValueDescriptor to
314: */
315: public void setValue(Date theValue) throws StandardException {
316: setValue(theValue, (Calendar) null);
317: }
318:
319: /**
320: * Set the value of this DataValueDescriptor.
321: * At DataType level just throws an error lower classes will override
322: *
323: * @param theValue The Date value to set this DataValueDescriptor to
324: * @param cal The time zone from the calendar is used to construct the database date value
325: */
326: public void setValue(Date theValue, Calendar cal)
327: throws StandardException {
328: throwLangSetMismatch("java.sql.Date");
329: }
330:
331: /**
332: * Set the value of this DataValueDescriptor.
333: * At DataType level just throws an error lower classes will override
334: *
335: * @param theValue The BigDecimal value to set this DataValueDescriptor to
336: */
337: public void setValue(String theValue) throws StandardException {
338: throwLangSetMismatch("java.lang.String");
339: }
340:
341: /**
342: * Set the value of this DataValueDescriptor to the given int value
343: * At DataType level just throws an error lower classes will override
344: *
345: * @param theValue The value to set this DataValueDescriptor to
346: *
347: * @exception StandardException Thrown on error
348: */
349: public void setValue(int theValue) throws StandardException {
350: throwLangSetMismatch("int");
351: }
352:
353: /**
354: * Set the value of this DataValueDescriptor to the given double value
355: * At DataType level just throws an error lower classes will override
356: *
357: * @param theValue The value to set this DataValueDescriptor to
358: *
359: * @exception StandardException Thrown on error
360: */
361: public void setValue(double theValue) throws StandardException {
362: throwLangSetMismatch("double");
363: }
364:
365: /**
366: * Set the value of this DataValueDescriptor to the given float value
367: * At DataType level just throws an error lower classes will override
368: *
369: * @param theValue The value to set this DataValueDescriptor to
370: *
371: * @exception StandardException Thrown on error
372: */
373: public void setValue(float theValue) throws StandardException {
374: throwLangSetMismatch("float");
375: }
376:
377: /**
378: * Set the value of this DataValueDescriptor to the given short value
379: * At DataType level just throws an error lower classes will override
380: *
381: * @param theValue The value to set this DataValueDescriptor to
382: *
383: * @exception StandardException Thrown on error
384: */
385: public void setValue(short theValue) throws StandardException {
386: throwLangSetMismatch("short");
387: }
388:
389: /**
390: * Set the value of this DataValueDescriptor to the given long value
391: * At DataType level just throws an error lower classes will override
392: *
393: * @param theValue The value to set this DataValueDescriptor to
394: *
395: * @exception StandardException Thrown on error
396: */
397: public void setValue(long theValue) throws StandardException {
398: throwLangSetMismatch("long");
399: }
400:
401: /**
402: * Set the value of this DataValueDescriptor to the given byte value
403: * At DataType level just throws an error lower classes will override
404: *
405: * @param theValue The value to set this DataValueDescriptor to
406: *
407: * @exception StandardException Thrown on error
408: */
409: public void setValue(byte theValue) throws StandardException {
410: throwLangSetMismatch("byte");
411: }
412:
413: /**
414: * Set the value.
415: * At DataType level just throws an error lower classes will override
416: *
417: * @param theValue Contains the boolean value to set this to
418: *
419: */
420: public void setValue(boolean theValue) throws StandardException {
421: throwLangSetMismatch("boolean");
422: }
423:
424: /**
425: * Set the value of this DataValueDescriptor.
426: * At DataType level just throws an error lower classes will override
427: *
428: * @param theValue The byte value to set this DataValueDescriptor to
429: *
430: */
431: public void setValue(byte[] theValue) throws StandardException {
432: throwLangSetMismatch("byte[]");
433: }
434:
435: /**
436: Only to be called when the application sets a value using BigDecimal
437: */
438: public void setBigDecimal(Number bigDecimal)
439: throws StandardException {
440: throwLangSetMismatch("java.math.BigDecimal");
441: }
442:
443: public final void setValue(DataValueDescriptor dvd)
444: throws StandardException {
445:
446: if (dvd.isNull()) {
447: setToNull();
448: return;
449: }
450:
451: try {
452: setFrom(dvd);
453: } catch (StandardException se) {
454: String msgId = se.getMessageId();
455:
456: if (SQLState.LANG_OUTSIDE_RANGE_FOR_DATATYPE.equals(msgId))
457: throw outOfRange();
458:
459: if (SQLState.LANG_FORMAT_EXCEPTION.equals(msgId))
460: throw invalidFormat();
461:
462: throw se;
463:
464: }
465: }
466:
467: /**
468: * Set the value of this DataValueDescriptor based on the value
469: * of the specified DataValueDescriptor.
470: *
471: * @param dvd The DataValueDescriptor that holds the value to
472: * which we want to set this DataValueDescriptor's value.
473: *
474: */
475: protected void setFrom(DataValueDescriptor dvd)
476: throws StandardException {
477: throw StandardException.newException(SQLState.NOT_IMPLEMENTED);
478: }
479:
480: /**
481: * @see DataValueDescriptor#setToNull
482: */
483: public void setToNull() {
484: restoreToNull();
485: }
486:
487: /**
488: * @see DataValueDescriptor#setObjectForCast
489: *
490: * @exception StandardException
491: * thrown on failure
492: *
493: */
494: public void setObjectForCast(Object theValue,
495: boolean instanceOfResultType, String resultTypeClassName)
496: throws StandardException {
497:
498: if (theValue == null) {
499: setToNull();
500: return;
501: }
502:
503: /*
504: * Is the object of the right type? (only do the check if value is
505: * non-null
506: */
507: if (!instanceOfResultType) {
508: throw StandardException.newException(
509: SQLState.LANG_DATA_TYPE_SET_MISMATCH, theValue
510: .getClass().getName(),
511: getTypeName(resultTypeClassName));
512: }
513:
514: setObject(theValue);
515: }
516:
517: /**
518: * Set the value from an non-null object. Usually overridden.
519: * This implementation throws an exception.
520: * The object will have been correctly typed from the call to setObjectForCast.
521: */
522: void setObject(Object theValue) throws StandardException {
523: genericSetObject(theValue);
524: }
525:
526: /**
527: * Get the type name of this value, possibly overriding
528: * with the passed in class name (for user/java types).
529: * @param className
530: */
531: String getTypeName(String className) {
532: return getTypeName();
533: }
534:
535: /**
536: * Gets the value in the data value descriptor as a int.
537: * Throws an exception if the data value is not receivable as a int.
538: *
539: * @return The data value as a int.
540: *
541: * @exception StandardException Thrown on error
542: */
543: public Object getObject() throws StandardException {
544: throw dataTypeConversion("java.lang.Object");
545: }
546:
547: void genericSetObject(Object theValue) throws StandardException {
548:
549: throwLangSetMismatch(theValue);
550: }
551:
552: /**
553: * From CloneableObject
554: *
555: * @return clone of me as an Object
556: */
557: public Object cloneObject() {
558: return getClone();
559: }
560:
561: // International support
562:
563: /**
564: * International version of getString(). Overridden for date, time,
565: * and timestamp in SQLDate, SQLTime, SQLTimestamp.
566: *
567: * @exception StandardException Thrown on error
568: */
569: protected String getNationalString(LocaleFinder localeFinder)
570: throws StandardException {
571: return getString();
572: }
573:
574: public void throwLangSetMismatch(Object value)
575: throws StandardException {
576: throwLangSetMismatch(value.getClass().getName());
577: }
578:
579: void throwLangSetMismatch(String argTypeName)
580: throws StandardException {
581: throw StandardException.newException(
582: SQLState.LANG_DATA_TYPE_SET_MISMATCH, argTypeName, this
583: .getTypeName());
584:
585: }
586:
587: public void setInto(PreparedStatement ps, int position)
588: throws SQLException, StandardException {
589:
590: ps.setObject(position, getObject());
591: }
592:
593: /**
594: Set this value into a ResultSet for a subsequent ResultSet.insertRow
595: or ResultSet.updateRow. This method will only be called for non-null values.
596:
597: @exception SQLException thrown by the ResultSet object
598: @exception StandardException thrown by me accessing my value.
599: */
600: public void setInto(ResultSet rs, int position)
601: throws SQLException, StandardException {
602: rs.updateObject(position, getObject());
603: }
604:
605: /**
606: * Default normalization method. No information needed from DataTypeDescriptor.
607: *
608: * @param desiredType The type to normalize the source column to
609: * @param source The value to normalize
610: *
611: *
612: * @exception StandardException Thrown normalization error.
613: */
614:
615: public void normalize(DataTypeDescriptor desiredType,
616: DataValueDescriptor source) throws StandardException {
617: ((DataValueDescriptor) this ).setValue(source);
618: }
619:
620: /**
621: * Each built-in type in JSQL has a precedence. This precedence determines
622: * how to do type promotion when using binary operators. For example, float
623: * has a higher precedence than int, so when adding an int to a float, the
624: * result type is float.
625: *
626: * The precedence for some types is arbitrary. For example, it doesn't
627: * matter what the precedence of the boolean type is, since it can't be
628: * mixed with other types. But the precedence for the number types is
629: * critical. The SQL standard requires that exact numeric types be
630: * promoted to approximate numeric when one operator uses both. Also,
631: * the precedence is arranged so that one will not lose precision when
632: * promoting a type.
633: *
634: * @return The precedence of this type.
635: */
636: public int typePrecedence() {
637: return -1;
638: }
639:
640: /**
641: * The = operator as called from the language module, as opposed to
642: * the storage module. This default implementations uses compare().
643: *
644: * @param left The value on the left side of the =
645: * @param right The value on the right side of the =
646: *
647: * @return A SQL boolean value telling whether the two parameters are equal
648: *
649: * @exception StandardException Thrown on error
650: */
651:
652: public BooleanDataValue equals(DataValueDescriptor left,
653: DataValueDescriptor right) throws StandardException {
654: return SQLBoolean.truthValue(left, right,
655: left.compare(right) == 0);
656: }
657:
658: /**
659: * The <> operator as called from the language module, as opposed to
660: * the storage module. This default implementations uses compare().
661: *
662: * @param left The value on the left side of the <>
663: * @param right The value on the right side of the <>
664: *
665: * @return A SQL boolean value telling whether the two parameters
666: * are not equal
667: *
668: * @exception StandardException Thrown on error
669: */
670:
671: public BooleanDataValue notEquals(DataValueDescriptor left,
672: DataValueDescriptor right) throws StandardException {
673: return SQLBoolean.truthValue(left, right,
674: left.compare(right) != 0);
675: }
676:
677: /**
678: * The < operator as called from the language module, as opposed to
679: * the storage module.
680: *
681: * @param left The value on the left side of the <
682: * @param right The value on the right side of the <
683: *
684: * @return A SQL boolean value telling whether the first operand is less
685: * than the second operand
686: *
687: * @exception StandardException Thrown on error
688: */
689:
690: public BooleanDataValue lessThan(DataValueDescriptor left,
691: DataValueDescriptor right) throws StandardException {
692: return SQLBoolean.truthValue(left, right,
693: left.compare(right) < 0);
694: }
695:
696: /**
697: * The > operator as called from the language module, as opposed to
698: * the storage module. This default implementations uses compare().
699: *
700: * @param left The value on the left side of the >
701: * @param right The value on the right side of the >
702: *
703: * @return A SQL boolean value telling whether the first operand is greater
704: * than the second operand
705: *
706: * @exception StandardException Thrown on error
707: */
708:
709: public BooleanDataValue greaterThan(DataValueDescriptor left,
710: DataValueDescriptor right) throws StandardException {
711: return SQLBoolean.truthValue(left, right,
712: left.compare(right) > 0);
713: }
714:
715: /**
716: * The <= operator as called from the language module, as opposed to
717: * the storage module. This default implementations uses compare().
718: *
719: * @param left The value on the left side of the <=
720: * @param right The value on the right side of the <=
721: *
722: * @return A SQL boolean value telling whether the first operand is less
723: * than or equal to the second operand
724: *
725: * @exception StandardException Thrown on error
726: */
727:
728: public BooleanDataValue lessOrEquals(DataValueDescriptor left,
729: DataValueDescriptor right) throws StandardException {
730: return SQLBoolean.truthValue(left, right,
731: left.compare(right) <= 0);
732: }
733:
734: /**
735: * The >= operator as called from the language module, as opposed to
736: * the storage module. This default implementation uses compare().
737: *
738: * @param left The value on the left side of the >=
739: * @param right The value on the right side of the >=
740: *
741: * @return A SQL boolean value telling whether the first operand is greater
742: * than or equal to the second operand
743: *
744: * @exception StandardException Thrown on error
745: */
746:
747: public BooleanDataValue greaterOrEquals(DataValueDescriptor left,
748: DataValueDescriptor right) throws StandardException {
749: return SQLBoolean.truthValue(left, right,
750: left.compare(right) >= 0);
751: }
752:
753: public boolean compare(int op, DataValueDescriptor other,
754: boolean orderedNulls, boolean unknownRV)
755: throws StandardException {
756: /* Use compare method from dominant type, flipping the operator
757: * to reflect flipping of sides.
758: */
759: if (typePrecedence() < other.typePrecedence()) {
760: return other.compare(flip(op), this , orderedNulls,
761: unknownRV);
762: }
763:
764: int result = compare(other);
765:
766: switch (op) {
767: case ORDER_OP_LESSTHAN:
768: return (result < 0); // this < other
769: case ORDER_OP_EQUALS:
770: return (result == 0); // this == other
771: case ORDER_OP_LESSOREQUALS:
772: return (result <= 0); // this <= other
773: // flipped operators
774: case ORDER_OP_GREATERTHAN:
775: return (result > 0); // this > other
776: case ORDER_OP_GREATEROREQUALS:
777: return (result >= 0); // this >= other
778: default:
779: if (SanityManager.DEBUG)
780: SanityManager.THROWASSERT("Invalid Operator");
781: return false;
782: }
783: }
784:
785: /**
786: * Flip the operator used in a comparison (< -> >).
787: * This is useful when flipping a comparison due to
788: * type precedence.
789: *
790: * @param operator The operator to flip.
791: *
792: * @return The flipped operator.
793: */
794: protected static int flip(int operator) {
795: switch (operator) {
796: case Orderable.ORDER_OP_LESSTHAN:
797: // < -> >
798: return Orderable.ORDER_OP_GREATERTHAN;
799: case Orderable.ORDER_OP_LESSOREQUALS:
800: // <= -> >=
801: return Orderable.ORDER_OP_GREATEROREQUALS;
802: case Orderable.ORDER_OP_EQUALS:
803: // = -> =
804: return Orderable.ORDER_OP_EQUALS;
805: default:
806: // These operators only appear due to flipping.
807: // They should never be flipped themselves.
808: if (SanityManager.DEBUG) {
809: SanityManager
810: .THROWASSERT("Attempting to flip an operator that is not "
811: + "expected to be flipped.");
812: }
813: return operator;
814: }
815: }
816:
817: /*
818: * DataValueDescriptor interface
819: */
820:
821: /**
822: * @see DataValueDescriptor#coalesce
823: * @exception StandardException Thrown on error
824: */
825: public DataValueDescriptor coalesce(
826: DataValueDescriptor[] argumentsList,
827: DataValueDescriptor returnValue) throws StandardException {
828: // arguments list should have at least 2 arguments
829: if (SanityManager.DEBUG) {
830: SanityManager.ASSERT(argumentsList != null,
831: "argumentsList expected to be non-null");
832: SanityManager.ASSERT(argumentsList.length > 1,
833: "argumentsList.length expected to be > 1");
834: }
835:
836: /* Walk the arguments list until we find a non-null value. Otherwise we will return null
837: */
838: int index;
839: for (index = 0; index < argumentsList.length; index++) {
840: if (!(argumentsList[index].isNull())) {
841: returnValue.setValue(argumentsList[index]);
842: return returnValue;
843: }
844: }
845:
846: returnValue.setToNull();
847: return returnValue;
848:
849: }
850:
851: /**
852: * @see DataValueDescriptor#in
853: * @exception StandardException Thrown on error
854: */
855: public BooleanDataValue in(DataValueDescriptor left,
856: DataValueDescriptor[] inList, boolean orderedList)
857: throws StandardException {
858: BooleanDataValue retval = null;
859:
860: // in list should be non-empty
861: if (SanityManager.DEBUG) {
862: SanityManager.ASSERT(inList != null,
863: "inList expected to be non-null");
864: SanityManager.ASSERT(inList.length > 0,
865: "inList.length expected to be > 0");
866: }
867:
868: // if left is null then just return false
869: if (left.isNull()) {
870: return SQLBoolean.truthValue(left, inList[0], false);
871: }
872:
873: int start = 0;
874: int finish = inList.length;
875:
876: /* Do a binary search if the list is ordered until the
877: * range of values to search is 3 or less.
878: * NOTE: We've ensured that the IN list and the left all have
879: * the same precedence at compile time. If we don't enforce
880: * the same precendence then
881: * we could get the wrong result when doing a binary search.
882: */
883: if (orderedList) {
884: while (finish - start > 2) {
885: int mid = ((finish - start) / 2) + start;
886: // Search left
887: retval = equals(left, inList[mid]);
888: if (retval.equals(true)) {
889: return retval;
890: }
891: BooleanDataValue goLeft = greaterThan(inList[mid], left);
892: if (goLeft.equals(true)) {
893: // search left
894: finish = mid;
895: } else {
896: // search right
897: start = mid;
898: }
899: }
900: }
901:
902: /* Walk the in list comparing the values. Return as soon as we
903: * find a match. If the list is ordered, return as soon as the left
904: * value is greater than an element in the in list.
905: */
906: for (int index = start; index < finish; index++) {
907: retval = equals(left, inList[index]);
908: if (retval.equals(true)) {
909: break;
910: }
911:
912: // Can we stop searching?
913: if (orderedList) {
914: BooleanDataValue stop = greaterThan(inList[index], left);
915: if (stop.equals(true)) {
916: break;
917: }
918: }
919: }
920:
921: return retval;
922: }
923:
924: /*
925: * equals
926: */
927: public boolean equals(Object other) {
928: if (!(other instanceof DataValueDescriptor)) {
929: return false;
930: }
931:
932: try {
933: return compare(ORDER_OP_EQUALS,
934: (DataValueDescriptor) other, true, false);
935: } catch (StandardException se) {
936: return false;
937: }
938: }
939:
940: public void setValue(InputStream theStream, int valueLength)
941: throws StandardException {
942: throwLangSetMismatch("java.io.InputStream");
943: }
944:
945: /**
946: Check the value to seem if it conforms to the restrictions
947: imposed by DB2/JCC on host variables for this type.
948:
949: @exception StandardException Variable is too big.
950: */
951: public void checkHostVariable(int declaredLength)
952: throws StandardException {
953: }
954:
955: /**
956: Return an conversion exception from this type to another.
957: */
958: protected final StandardException dataTypeConversion(
959: String targetType) {
960: return StandardException.newException(
961: SQLState.LANG_DATA_TYPE_GET_MISMATCH, targetType, this
962: .getTypeName());
963:
964: }
965:
966: /**
967: Return an out of range exception for this type.
968: */
969: protected final StandardException outOfRange() {
970: return StandardException
971: .newException(SQLState.LANG_OUTSIDE_RANGE_FOR_DATATYPE,
972: getTypeName());
973: }
974:
975: /**
976: Return an out of range exception for this type.
977: */
978: protected final StandardException invalidFormat() {
979: return StandardException.newException(
980: SQLState.LANG_FORMAT_EXCEPTION, getTypeName());
981: }
982: }
|