File D:\maven-qcr-plugin-testsunitaires\qcr4java\h2-1.3.170-sources\target\site\qc\lecode\value\Value.java.html

1 /*
2 * Copyright 2004-2011 H2 Group. Multiple-Licensed under the H2 License,
3 * Version 1.0, and under the Eclipse Public License, Version 1.0
4 * (http://h2database.com/html/license.html).
5 * Initial Developer: H2 Group
6 */
7 package org.h2.value;
8
9 import java.io.ByteArrayInputStream;
10 import java.io.InputStream;
11 import java.io.Reader;
12 import java.lang.ref.SoftReference;
13 import java.math.BigDecimal;
14 import java.sql.Date;
15 import java.sql.PreparedStatement;
16 import java.sql.ResultSet;
17 import java.sql.SQLException;
18 import java.sql.Time;
19 import java.sql.Timestamp;
20 import java.sql.Types;
21 import org.h2.constant.ErrorCode;
22 import org.h2.constant.SysProperties;
23 import org.h2.message.DbException;
24 import org.h2.store.DataHandler;
25 import org.h2.store.LobStorage;
26 import org.h2.tools.SimpleResultSet;
27 import org.h2.util.DateTimeUtils;
28 import org.h2.util.IOUtils;
29 import org.h2.util.MathUtils;
30 import org.h2.util.StringUtils;
31 import org.h2.util.Utils;
32
33 /**
34 * This is the base class for all value classes.
35 * It provides conversion and comparison methods.
36 */
37 public abstract class Value {
38
39 /**
40 * The data type is unknown at this time.
41 */
42 public static final int UNKNOWN = -1;
43
44 /**
45 * The value type for NULL.
46 */
47 public static final int NULL = 0;
48
49 /**
50 * The value type for BOOLEAN values.
51 */
52 public static final int BOOLEAN = 1;
53
54 /**
55 * The value type for BYTE values.
56 */
57 public static final int BYTE = 2;
58
59 /**
60 * The value type for SHORT values.
61 */
62 public static final int SHORT = 3;
63
64 /**
65 * The value type for INT values.
66 */
67 public static final int INT = 4;
68
69 /**
70 * The value type for LONG values.
71 */
72 public static final int LONG = 5;
73
74 /**
75 * The value type for DECIMAL values.
76 */
77 public static final int DECIMAL = 6;
78
79 /**
80 * The value type for DOUBLE values.
81 */
82 public static final int DOUBLE = 7;
83
84 /**
85 * The value type for FLOAT values.
86 */
87 public static final int FLOAT = 8;
88
89 /**
90 * The value type for INT values.
91 */
92 public static final int TIME = 9;
93
94 /**
95 * The value type for DATE values.
96 */
97 public static final int DATE = 10;
98
99 /**
100 * The value type for TIMESTAMP values.
101 */
102 public static final int TIMESTAMP = 11;
103
104 /**
105 * The value type for BYTES values.
106 */
107 public static final int BYTES = 12;
108
109 /**
110 * The value type for STRING values.
111 */
112 public static final int STRING = 13;
113
114 /**
115 * The value type for case insensitive STRING values.
116 */
117 public static final int STRING_IGNORECASE = 14;
118
119 /**
120 * The value type for BLOB values.
121 */
122 public static final int BLOB = 15;
123
124 /**
125 * The value type for CLOB values.
126 */
127 public static final int CLOB = 16;
128
129 /**
130 * The value type for ARRAY values.
131 */
132 public static final int ARRAY = 17;
133
134 /**
135 * The value type for RESULT_SET values.
136 */
137 public static final int RESULT_SET = 18;
138 /**
139 * The value type for JAVA_OBJECT values.
140 */
141 public static final int JAVA_OBJECT = 19;
142
143 /**
144 * The value type for UUID values.
145 */
146 public static final int UUID = 20;
147
148 /**
149 * The value type for string values with a fixed size.
150 */
151 public static final int STRING_FIXED = 21;
152
153 /**
154 * The number of value types.
155 */
156 public static final int TYPE_COUNT = STRING_FIXED + 1;
157
158 private static SoftReference<Value[]> softCache = new SoftReference<Value[]>(null);
159 private static final BigDecimal MAX_LONG_DECIMAL = BigDecimal.valueOf(Long.MAX_VALUE);
160 private static final BigDecimal MIN_LONG_DECIMAL = BigDecimal.valueOf(Long.MIN_VALUE);
161
162 /**
163 * Get the SQL expression for this value.
164 *
165 * @return the SQL expression
166 */
167 public abstract String getSQL();
168
169 /**
170 * Get the value type.
171 *
172 * @return the type
173 */
174 public abstract int getType();
175
176 /**
177 * Get the precision.
178 *
179 * @return the precision
180 */
181 public abstract long getPrecision();
182
183 /**
184 * Get the display size in characters.
185 *
186 * @return the display size
187 */
188 public abstract int getDisplaySize();
189
190 /**
191 * Get the memory used by this object.
192 *
193 * @return the memory used in bytes
194 */
195 public int getMemory() {
196 return DataType.getDataType(getType()).memory;
197 }
198
199 /**
200 * Get the value as a string.
201 *
202 * @return the string
203 */
204 public abstract String getString();
205
206 /**
207 * Get the value as an object.
208 *
209 * @return the object
210 */
211 public abstract Object getObject();
212
213 /**
214 * Set the value as a parameter in a prepared statement.
215 *
216 * @param prep the prepared statement
217 * @param parameterIndex the parameter index
218 */
219 public abstract void set(PreparedStatement prep, int parameterIndex) throws SQLException;
220
221 /**
222 * Compare the value with another value of the same type.
223 *
224 * @param v the other value
225 * @param mode the compare mode
226 * @return 0 if both values are equal, -1 if the other value is smaller, and
227 * 1 otherwise
228 */
229 protected abstract int compareSecure(Value v, CompareMode mode);
230
231 public abstract int hashCode();
232
233 /**
234 * Check if the two values have the same hash code. No data conversion is
235 * made; this method returns false if the other object is not of the same
236 * class. For some values, compareTo may return 0 even if equals return
237 * false. Example: ValueDecimal 0.0 and 0.00.
238 *
239 * @param other the other value
240 * @return true if they are equal
241 */
242 public abstract boolean equals(Object other);
243
244 /**
245 * Get the order of this value type.
246 *
247 * @param type the value type
248 * @return the order number
249 */
250 static int getOrder(int type) {
251 switch(type) {
252 case UNKNOWN:
253 return 1;
254 case NULL:
255 return 2;
256 case STRING:
257 return 10;
258 case CLOB:
259 return 11;
260 case STRING_FIXED:
261 return 12;
262 case STRING_IGNORECASE:
263 return 13;
264 case BOOLEAN:
265 return 20;
266 case BYTE:
267 return 21;
268 case SHORT:
269 return 22;
270 case INT:
271 return 23;
272 case LONG:
273 return 24;
274 case DECIMAL:
275 return 25;
276 case FLOAT:
277 return 26;
278 case DOUBLE:
279 return 27;
280 case TIME:
281 return 30;
282 case DATE:
283 return 31;
284 case TIMESTAMP:
285 return 32;
286 case BYTES:
287 return 40;
288 case BLOB:
289 return 41;
290 case UUID:
291 return 42;
292 case JAVA_OBJECT:
293 return 43;
294 case ARRAY:
295 return 50;
296 case RESULT_SET:
297 return 51;
298 default:
299 throw DbException.throwInternalError("type:"+type);
300 }
301 }
302
303 /**
304 * Get the higher value order type of two value types. If values need to be
305 * converted to match the other operands value type, the value with the
306 * lower order is converted to the value with the higher order.
307 *
308 * @param t1 the first value type
309 * @param t2 the second value type
310 * @return the higher value type of the two
311 */
312 public static int getHigherOrder(int t1, int t2) {
313 if (t1 == Value.UNKNOWN || t2 == Value.UNKNOWN) {
314 if (t1 == t2) {
315 throw DbException.get(ErrorCode.UNKNOWN_DATA_TYPE_1, "?, ?");
316 } else if (t1 == Value.NULL) {
317 throw DbException.get(ErrorCode.UNKNOWN_DATA_TYPE_1, "NULL, ?");
318 } else if (t2 == Value.NULL) {
319 throw DbException.get(ErrorCode.UNKNOWN_DATA_TYPE_1, "?, NULL");
320 }
321 }
322 if (t1 == t2) {
323 return t1;
324 }
325 int o1 = getOrder(t1);
326 int o2 = getOrder(t2);
327 return o1 > o2 ? t1 : t2;
328 }
329
330 /**
331 * Check if a value is in the cache that is equal to this value. If yes,
332 * this value should be used to save memory. If the value is not in the
333 * cache yet, it is added.
334 *
335 * @param v the value to look for
336 * @return the value in the cache or the value passed
337 */
338 static Value cache(Value v) {
339 if (SysProperties.OBJECT_CACHE) {
340 int hash = v.hashCode();
341 if (softCache == null) {
342 softCache = new SoftReference<Value[]>(null);
343 }
344 Value[] cache = softCache.get();
345 if (cache == null) {
346 cache = new Value[SysProperties.OBJECT_CACHE_SIZE];
347 softCache = new SoftReference<Value[]>(cache);
348 }
349 int index = hash & (SysProperties.OBJECT_CACHE_SIZE - 1);
350 Value cached = cache[index];
351 if (cached != null) {
352 if (cached.getType() == v.getType() && v.equals(cached)) {
353 // cacheHit++;
354 return cached;
355 }
356 }
357 // cacheMiss++;
358 // cache[cacheCleaner] = null;
359 // cacheCleaner = (cacheCleaner + 1) & (Constants.OBJECT_CACHE_SIZE - 1);
360 cache[index] = v;
361 }
362 return v;
363 }
364
365 /**
366 * Clear the value cache. Used for testing.
367 */
368 public static void clearCache() {
369 softCache = null;
370 }
371
372 public Boolean getBoolean() {
373 return ((ValueBoolean) convertTo(Value.BOOLEAN)).getBoolean();
374 }
375
376 public Date getDate() {
377 return ((ValueDate) convertTo(Value.DATE)).getDate();
378 }
379
380 public Time getTime() {
381 return ((ValueTime) convertTo(Value.TIME)).getTime();
382 }
383
384 public Timestamp getTimestamp() {
385 return ((ValueTimestamp) convertTo(Value.TIMESTAMP)).getTimestamp();
386 }
387
388 public byte[] getBytes() {
389 return ((ValueBytes) convertTo(Value.BYTES)).getBytes();
390 }
391
392 public byte[] getBytesNoCopy() {
393 return ((ValueBytes) convertTo(Value.BYTES)).getBytesNoCopy();
394 }
395
396 public byte getByte() {
397 return ((ValueByte) convertTo(Value.BYTE)).getByte();
398 }
399
400 public short getShort() {
401 return ((ValueShort) convertTo(Value.SHORT)).getShort();
402 }
403
404 public BigDecimal getBigDecimal() {
405 return ((ValueDecimal) convertTo(Value.DECIMAL)).getBigDecimal();
406 }
407
408 public double getDouble() {
409 return ((ValueDouble) convertTo(Value.DOUBLE)).getDouble();
410 }
411
412 public float getFloat() {
413 return ((ValueFloat) convertTo(Value.FLOAT)).getFloat();
414 }
415
416 public int getInt() {
417 return ((ValueInt) convertTo(Value.INT)).getInt();
418 }
419
420 public long getLong() {
421 return ((ValueLong) convertTo(Value.LONG)).getLong();
422 }
423
424 public InputStream getInputStream() {
425 return new ByteArrayInputStream(getBytesNoCopy());
426 }
427
428 public Reader getReader() {
429 return IOUtils.getReaderFromString(getString());
430 }
431
432 /**
433 * Add a value and return the result.
434 *
435 * @param v the value to add
436 * @return the result
437 */
438 public Value add(Value v) {
439 throw throwUnsupportedExceptionForType("+");
440 }
441
442 public int getSignum() {
443 throw throwUnsupportedExceptionForType("SIGNUM");
444 }
445
446 /**
447 * Return -value if this value support arithmetic operations.
448 *
449 * @return the negative
450 */
451 public Value negate() {
452 throw throwUnsupportedExceptionForType("NEG");
453 }
454
455 /**
456 * Subtract a value and return the result.
457 *
458 * @param v the value to subtract
459 * @return the result
460 */
461 public Value subtract(Value v) {
462 throw throwUnsupportedExceptionForType("-");
463 }
464
465 /**
466 * Divide by a value and return the result.
467 *
468 * @param v the value to divide by
469 * @return the result
470 */
471 public Value divide(Value v) {
472 throw throwUnsupportedExceptionForType("/");
473 }
474
475 /**
476 * Multiply with a value and return the result.
477 *
478 * @param v the value to multiply with
479 * @return the result
480 */
481 public Value multiply(Value v) {
482 throw throwUnsupportedExceptionForType("*");
483 }
484
485 /**
486 * Take the modulus with a value and return the result.
487 *
488 * @param v the value to take the modulus with
489 * @return the result
490 */
491 public Value modulus(Value v) {
492 throw throwUnsupportedExceptionForType("%");
493 }
494
495 /**
496 * Compare a value to the specified type.
497 *
498 * @param targetType the type of the returned value
499 * @return the converted value
500 */
501 public Value convertTo(int targetType) {
502 // converting NULL is done in ValueNull
503 // converting BLOB to CLOB and vice versa is done in ValueLob
504 if (getType() == targetType) {
505 return this;
506 }
507 try {
508 // decimal conversion
509 switch (targetType) {
510 case BOOLEAN: {
511 switch (getType()) {
512 case BYTE:
513 case SHORT:
514 case INT:
515 case LONG:
516 case DECIMAL:
517 case DOUBLE:
518 case FLOAT:
519 return ValueBoolean.get(getSignum() != 0);
520 case TIME:
521 case DATE:
522 case TIMESTAMP:
523 case BYTES:
524 case JAVA_OBJECT:
525 case UUID:
526 throw DbException.get(ErrorCode.DATA_CONVERSION_ERROR_1, getString());
527 }
528 break;
529 }
530 case BYTE: {
531 switch (getType()) {
532 case BOOLEAN:
533 return ValueByte.get(getBoolean().booleanValue() ? (byte) 1 : (byte) 0);
534 case SHORT:
535 return ValueByte.get(convertToByte(getShort()));
536 case INT:
537 return ValueByte.get(convertToByte(getInt()));
538 case LONG:
539 return ValueByte.get(convertToByte(getLong()));
540 case DECIMAL:
541 return ValueByte.get(convertToByte(convertToLong(getBigDecimal())));
542 case DOUBLE:
543 return ValueByte.get(convertToByte(convertToLong(getDouble())));
544 case FLOAT:
545 return ValueByte.get(convertToByte(convertToLong(getFloat())));
546 case BYTES:
547 return ValueByte.get((byte) Integer.parseInt(getString(), 16));
548 }
549 break;
550 }
551 case SHORT: {
552 switch (getType()) {
553 case BOOLEAN:
554 return ValueShort.get(getBoolean().booleanValue() ? (short) 1 : (short) 0);
555 case BYTE:
556 return ValueShort.get(getByte());
557 case INT:
558 return ValueShort.get(convertToShort(getInt()));
559 case LONG:
560 return ValueShort.get(convertToShort(getLong()));
561 case DECIMAL:
562 return ValueShort.get(convertToShort(convertToLong(getBigDecimal())));
563 case DOUBLE:
564 return ValueShort.get(convertToShort(convertToLong(getDouble())));
565 case FLOAT:
566 return ValueShort.get(convertToShort(convertToLong(getFloat())));
567 case BYTES:
568 return ValueShort.get((short) Integer.parseInt(getString(), 16));
569 }
570 break;
571 }
572 case INT: {
573 switch (getType()) {
574 case BOOLEAN:
575 return ValueInt.get(getBoolean().booleanValue() ? 1 : 0);
576 case BYTE:
577 return ValueInt.get(getByte());
578 case SHORT:
579 return ValueInt.get(getShort());
580 case LONG:
581 return ValueInt.get(convertToInt(getLong()));
582 case DECIMAL:
583 return ValueInt.get(convertToInt(convertToLong(getBigDecimal())));
584 case DOUBLE:
585 return ValueInt.get(convertToInt(convertToLong(getDouble())));
586 case FLOAT:
587 return ValueInt.get(convertToInt(convertToLong(getFloat())));
588 case BYTES:
589 return ValueInt.get((int) Long.parseLong(getString(), 16));
590 }
591 break;
592 }
593 case LONG: {
594 switch (getType()) {
595 case BOOLEAN:
596 return ValueLong.get(getBoolean().booleanValue() ? 1 : 0);
597 case BYTE:
598 return ValueLong.get(getByte());
599 case SHORT:
600 return ValueLong.get(getShort());
601 case INT:
602 return ValueLong.get(getInt());
603 case DECIMAL:
604 return ValueLong.get(convertToLong(getBigDecimal()));
605 case DOUBLE:
606 return ValueLong.get(convertToLong(getDouble()));
607 case FLOAT:
608 return ValueLong.get(convertToLong(getFloat()));
609 case BYTES: {
610 // parseLong doesn't work for ffffffffffffffff
611 byte[] d = getBytes();
612 if (d.length == 8) {
613 return ValueLong.get(Utils.readLong(d, 0));
614 }
615 return ValueLong.get(Long.parseLong(getString(), 16));
616 }
617 }
618 break;
619 }
620 case DECIMAL: {
621 // convert to string is required for JDK 1.4
622 switch (getType()) {
623 case BOOLEAN:
624 return ValueDecimal.get(BigDecimal.valueOf(getBoolean().booleanValue() ? 1 : 0));
625 case BYTE:
626 return ValueDecimal.get(BigDecimal.valueOf(getByte()));
627 case SHORT:
628 return ValueDecimal.get(BigDecimal.valueOf(getShort()));
629 case INT:
630 return ValueDecimal.get(BigDecimal.valueOf(getInt()));
631 case LONG:
632 return ValueDecimal.get(BigDecimal.valueOf(getLong()));
633 case DOUBLE: {
634 double d = getDouble();
635 if (Double.isInfinite(d) || Double.isNaN(d)) {
636 throw DbException.get(ErrorCode.DATA_CONVERSION_ERROR_1, "" + d);
637 }
638 return ValueDecimal.get(BigDecimal.valueOf(d));
639 }
640 case FLOAT: {
641 float f = getFloat();
642 if (Float.isInfinite(f) || Float.isNaN(f)) {
643 throw DbException.get(ErrorCode.DATA_CONVERSION_ERROR_1, "" + f);
644 }
645 return ValueDecimal.get(new BigDecimal(Float.toString(f)));
646 }
647 }
648 break;
649 }
650 case DOUBLE: {
651 switch (getType()) {
652 case BOOLEAN:
653 return ValueDouble.get(getBoolean().booleanValue() ? 1 : 0);
654 case BYTE:
655 return ValueDouble.get(getByte());
656 case SHORT:
657 return ValueDouble.get(getShort());
658 case INT:
659 return ValueDouble.get(getInt());
660 case LONG:
661 return ValueDouble.get(getLong());
662 case DECIMAL:
663 return ValueDouble.get(getBigDecimal().doubleValue());
664 case FLOAT:
665 return ValueDouble.get(getFloat());
666 }
667 break;
668 }
669 case FLOAT: {
670 switch (getType()) {
671 case BOOLEAN:
672 return ValueFloat.get(getBoolean().booleanValue() ? 1 : 0);
673 case BYTE:
674 return ValueFloat.get(getByte());
675 case SHORT:
676 return ValueFloat.get(getShort());
677 case INT:
678 return ValueFloat.get(getInt());
679 case LONG:
680 return ValueFloat.get(getLong());
681 case DECIMAL:
682 return ValueFloat.get(getBigDecimal().floatValue());
683 case DOUBLE:
684 return ValueFloat.get((float) getDouble());
685 }
686 break;
687 }
688 case DATE: {
689 switch (getType()) {
690 case TIME:
691 // because the time has set the date to 1970-01-01,
692 // this will be the result
693 return ValueDate.fromDateValue(DateTimeUtils.dateValue(1970, 1, 1));
694 case TIMESTAMP:
695 return ValueDate.fromDateValue(((ValueTimestamp) this).getDateValue());
696 }
697 break;
698 }
699 case TIME: {
700 switch (getType()) {
701 case DATE:
702 // need to normalize the year, month and day
703 // because a date has the time set to 0, the result will be 0
704 return ValueTime.fromNanos(0);
705 case TIMESTAMP:
706 return ValueTime.fromNanos(((ValueTimestamp) this).getNanos());
707 }
708 break;
709 }
710 case TIMESTAMP: {
711 switch (getType()) {
712 case TIME:
713 return DateTimeUtils.normalizeTimestamp(0, ((ValueTime) this).getNanos());
714 case DATE:
715 return ValueTimestamp.fromDateValueAndNanos(((ValueDate) this).getDateValue(), 0);
716 }
717 break;
718 }
719 case BYTES: {
720 switch(getType()) {
721 case JAVA_OBJECT:
722 case BLOB:
723 return ValueBytes.getNoCopy(getBytesNoCopy());
724 case UUID:
725 return ValueBytes.getNoCopy(getBytes());
726 case BYTE:
727 return ValueBytes.getNoCopy(new byte[]{getByte()});
728 case SHORT: {
729 int x = getShort();
730 return ValueBytes.getNoCopy(new byte[]{
731 (byte) (x >> 8),
732 (byte) x
733 });
734 }
735 case INT: {
736 int x = getInt();
737 return ValueBytes.getNoCopy(new byte[]{
738 (byte) (x >> 24),
739 (byte) (x >> 16),
740 (byte) (x >> 8),
741 (byte) x
742 });
743 }
744 case LONG: {
745 long x = getLong();
746 return ValueBytes.getNoCopy(new byte[]{
747 (byte) (x >> 56),
748 (byte) (x >> 48),
749 (byte) (x >> 40),
750 (byte) (x >> 32),
751 (byte) (x >> 24),
752 (byte) (x >> 16),
753 (byte) (x >> 8),
754 (byte) x
755 });
756 }
757 }
758 break;
759 }
760 case JAVA_OBJECT: {
761 switch(getType()) {
762 case BYTES:
763 case BLOB:
764 return ValueJavaObject.getNoCopy(null, getBytesNoCopy());
765 }
766 break;
767 }
768 case BLOB: {
769 switch(getType()) {
770 case BYTES:
771
772 return LobStorage.createSmallLob(Value.BLOB, getBytesNoCopy());
773 }
774 break;
775 }
776 case UUID: {
777 switch(getType()) {
778 case BYTES:
779 return ValueUuid.get(getBytesNoCopy());
780 }
781 }
782 }
783 // conversion by parsing the string value
784 String s = getString();
785 switch (targetType) {
786 case NULL:
787 return ValueNull.INSTANCE;
788 case BOOLEAN: {
789 if (s.equalsIgnoreCase("true") ||
790 s.equalsIgnoreCase("t") ||
791 s.equalsIgnoreCase("yes") ||
792 s.equalsIgnoreCase("y")) {
793 return ValueBoolean.get(true);
794 } else if (s.equalsIgnoreCase("false") ||
795 s.equalsIgnoreCase("f") ||
796 s.equalsIgnoreCase("no") ||
797 s.equalsIgnoreCase("n")) {
798 return ValueBoolean.get(false);
799 } else {
800 // convert to a number, and if it is not 0 then it is true
801 return ValueBoolean.get(new BigDecimal(s).signum() != 0);
802 }
803 }
804 case BYTE:
805 return ValueByte.get(Byte.parseByte(s.trim()));
806 case SHORT:
807 return ValueShort.get(Short.parseShort(s.trim()));
808 case INT:
809 return ValueInt.get(Integer.parseInt(s.trim()));
810 case LONG:
811 return ValueLong.get(Long.parseLong(s.trim()));
812 case DECIMAL:
813 return ValueDecimal.get(new BigDecimal(s.trim()));
814 case TIME:
815 return ValueTime.parse(s.trim());
816 case DATE:
817 return ValueDate.parse(s.trim());
818 case TIMESTAMP:
819 return ValueTimestamp.parse(s.trim());
820 case BYTES:
821 return ValueBytes.getNoCopy(StringUtils.convertHexToBytes(s.trim()));
822 case JAVA_OBJECT:
823 return ValueJavaObject.getNoCopy(null, StringUtils.convertHexToBytes(s.trim()));
824 case STRING:
825 return ValueString.get(s);
826 case STRING_IGNORECASE:
827 return ValueStringIgnoreCase.get(s);
828 case STRING_FIXED:
829 return ValueStringFixed.get(s);
830 case DOUBLE:
831 return ValueDouble.get(Double.parseDouble(s.trim()));
832 case FLOAT:
833 return ValueFloat.get(Float.parseFloat(s.trim()));
834 case CLOB:
835 return LobStorage.createSmallLob(CLOB, StringUtils.utf8Encode(s));
836 case BLOB:
837 return LobStorage.createSmallLob(BLOB, StringUtils.convertHexToBytes(s.trim()));
838 case ARRAY:
839 return ValueArray.get(new Value[]{ValueString.get(s)});
840 case RESULT_SET: {
841 SimpleResultSet rs = new SimpleResultSet();
842 rs.addColumn("X", Types.VARCHAR, s.length(), 0);
843 rs.addRow(s);
844 return ValueResultSet.get(rs);
845 }
846 case UUID:
847 return ValueUuid.get(s);
848 default:
849 throw DbException.throwInternalError("type=" + targetType);
850 }
851 } catch (NumberFormatException e) {
852 throw DbException.get(ErrorCode.DATA_CONVERSION_ERROR_1, e, getString());
853 }
854 }
855
856 /**
857 * Compare this value against another value given that the values are of the
858 * same data type.
859 *
860 * @param v the other value
861 * @param mode the compare mode
862 * @return 0 if both values are equal, -1 if the other value is smaller, and
863 * 1 otherwise
864 */
865 public final int compareTypeSave(Value v, CompareMode mode) {
866 if (this == v) {
867 return 0;
868 } else if (this == ValueNull.INSTANCE) {
869 return -1;
870 } else if (v == ValueNull.INSTANCE) {
871 return 1;
872 }
873 return compareSecure(v, mode);
874 }
875
876 /**
877 * Compare this value against another value using the specified compare
878 * mode.
879 *
880 * @param v the other value
881 * @param mode the compare mode
882 * @return 0 if both values are equal, -1 if the other value is smaller, and
883 * 1 otherwise
884 */
885 public final int compareTo(Value v, CompareMode mode) {
886 if (this == v) {
887 return 0;
888 }
889 if (this == ValueNull.INSTANCE) {
890 return v == ValueNull.INSTANCE ? 0 : -1;
891 } else if (v == ValueNull.INSTANCE) {
892 return 1;
893 }
894 if (getType() == v.getType()) {
895 return compareSecure(v, mode);
896 }
897 int t2 = Value.getHigherOrder(getType(), v.getType());
898 return convertTo(t2).compareSecure(v.convertTo(t2), mode);
899 }
900
901 public int getScale() {
902 return 0;
903 }
904
905 /**
906 * Convert the scale.
907 *
908 * @param onlyToSmallerScale if the scale should not reduced
909 * @param targetScale the requested scale
910 * @return the value
911 */
912 public Value convertScale(boolean onlyToSmallerScale, int targetScale) {
913 return this;
914 }
915
916 /**
917 * Convert the precision to the requested value. The precision of the
918 * returned value may be somewhat larger than requested, because values with
919 * a fixed precision are not truncated.
920 *
921 * @param precision the new precision
922 * @param force true if losing numeric precision is allowed
923 * @return the new value
924 */
925 public Value convertPrecision(long precision, boolean force) {
926 return this;
927 }
928
929 private static byte convertToByte(long x) {
930 if (x > Byte.MAX_VALUE || x < Byte.MIN_VALUE) {
931 throw DbException.get(ErrorCode.NUMERIC_VALUE_OUT_OF_RANGE_1, Long.toString(x));
932 }
933 return (byte) x;
934 }
935
936 private static short convertToShort(long x) {
937 if (x > Short.MAX_VALUE || x < Short.MIN_VALUE) {
938 throw DbException.get(ErrorCode.NUMERIC_VALUE_OUT_OF_RANGE_1, Long.toString(x));
939 }
940 return (short) x;
941 }
942
943 private static int convertToInt(long x) {
944 if (x > Integer.MAX_VALUE || x < Integer.MIN_VALUE) {
945 throw DbException.get(ErrorCode.NUMERIC_VALUE_OUT_OF_RANGE_1, Long.toString(x));
946 }
947 return (int) x;
948 }
949
950 private static long convertToLong(double x) {
951 if (x > Long.MAX_VALUE || x < Long.MIN_VALUE) {
952 // TODO document that +Infinity, -Infinity throw an exception and NaN returns 0
953 throw DbException.get(ErrorCode.NUMERIC_VALUE_OUT_OF_RANGE_1, Double.toString(x));
954 }
955 return Math.round(x);
956 }
957
958 private static long convertToLong(BigDecimal x) {
959 if (x.compareTo(MAX_LONG_DECIMAL) > 0 || x.compareTo(Value.MIN_LONG_DECIMAL) < 0) {
960 throw DbException.get(ErrorCode.NUMERIC_VALUE_OUT_OF_RANGE_1, x.toString());
961 }
962 return x.setScale(0, BigDecimal.ROUND_HALF_UP).longValue();
963 }
964
965 /**
966 * Link a large value to a given table. For values that are kept fully in
967 * memory this method has no effect.
968 *
969 * @param handler the data handler
970 * @param tableId the table to link to
971 * @return the new value or itself
972 */
973 public Value link(DataHandler handler, int tableId) {
974 return this;
975 }
976
977 /**
978 * Check if this value is linked to a specific table. For values that are
979 * kept fully in memory, this method returns false.
980 *
981 * @return true if it is
982 */
983 public boolean isLinked() {
984 return false;
985 }
986
987 /**
988 * Mark any underlying resource as 'not linked to any table'. For values
989 * that are kept fully in memory this method has no effect.
990 */
991 public void unlink() {
992 // nothing to do
993 }
994
995 /**
996 * Close the underlying resource, if any. For values that are kept fully in
997 * memory this method has no effect.
998 */
999 public void close() {
1000 // nothing to do
1001 }
1002
1003 /**
1004 * Check if the precision is smaller or equal than the given precision.
1005 *
1006 * @param precision the maximum precision
1007 * @return true if the precision of this value is smaller or equal to the
1008 * given precision
1009 */
1010 public boolean checkPrecision(long precision) {
1011 return getPrecision() <= precision;
1012 }
1013
1014 /**
1015 * Get a medium size SQL expression for debugging or tracing. If the precision is
1016 * too large, only a subset of the value is returned.
1017 *
1018 * @return the SQL expression
1019 */
1020 public String getTraceSQL() {
1021 return getSQL();
1022 }
1023
1024 public String toString() {
1025 return getTraceSQL();
1026 }
1027
1028 /**
1029 * Throw the exception that the feature is not support for the given data type.
1030 *
1031 * @param op the operation
1032 * @return never returns normally
1033 * @throws DbException the exception
1034 */
1035 protected DbException throwUnsupportedExceptionForType(String op) {
1036 throw DbException.getUnsupportedException(DataType.getDataType(getType()).name + " " + op);
1037 }
1038
1039 /**
1040 * Get the table (only for LOB object).
1041 *
1042 * @return the table id
1043 */
1044 public int getTableId() {
1045 return 0;
1046 }
1047
1048 /**
1049 * Get the byte array.
1050 *
1051 * @return the byte array
1052 */
1053 public byte[] getSmall() {
1054 return null;
1055 }
1056
1057 /**
1058 * Copy this value to a temporary file if necessary.
1059 *
1060 * @return the new value
1061 */
1062 public Value copyToTemp() {
1063 return this;
1064 }
1065
1066 public ResultSet getResultSet() {
1067 SimpleResultSet rs = new SimpleResultSet();
1068 rs.addColumn("X", DataType.convertTypeToSQLType(getType()), MathUtils.convertLongToInt(getPrecision()), getScale());
1069 rs.addRow(getObject());
1070 return rs;
1071 }
1072
1073 /**
1074 * A "binary large object".
1075 */
1076 public interface ValueClob {
1077 // this is a marker interface
1078 }
1079
1080 /**
1081 * A "character large object".
1082 */
1083 public interface ValueBlob {
1084 // this is a marker interface
1085 }
1086
1087 }
1088