EMMA Coverage Report (generated Sun Mar 01 22:06:14 CET 2015)
[all classes][org.h2.value]

COVERAGE SUMMARY FOR SOURCE FILE [Value.java]

nameclass, %method, %block, %line, %
Value.java100% (1/1)80%  (43/54)85%  (1174/1386)87%  (253.6/291)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class Value100% (1/1)80%  (43/54)85%  (1174/1386)87%  (253.6/291)
add (Value): Value 0%   (0/1)0%   (0/4)0%   (0/1)
copyToTemp (): Value 0%   (0/1)0%   (0/2)0%   (0/1)
divide (Value): Value 0%   (0/1)0%   (0/4)0%   (0/1)
getBytes (): byte [] 0%   (0/1)0%   (0/6)0%   (0/1)
getSignum (): int 0%   (0/1)0%   (0/4)0%   (0/1)
getSmall (): byte [] 0%   (0/1)0%   (0/2)0%   (0/1)
getTableId (): int 0%   (0/1)0%   (0/2)0%   (0/1)
modulus (Value): Value 0%   (0/1)0%   (0/4)0%   (0/1)
multiply (Value): Value 0%   (0/1)0%   (0/4)0%   (0/1)
negate (): Value 0%   (0/1)0%   (0/4)0%   (0/1)
subtract (Value): Value 0%   (0/1)0%   (0/4)0%   (0/1)
convertToInt (long): int 100% (1/1)69%  (11/16)67%  (2/3)
convertToLong (double): long 100% (1/1)69%  (11/16)67%  (2/3)
convertToByte (long): byte 100% (1/1)71%  (12/17)67%  (2/3)
convertToShort (long): short 100% (1/1)71%  (12/17)67%  (2/3)
getHigherOrder (int, int): int 100% (1/1)81%  (35/43)83%  (10/12)
getOrder (int): int 100% (1/1)83%  (50/60)96%  (25/26)
convertTo (int): Value 100% (1/1)85%  (725/856)88%  (136/155)
checkPrecision (long): boolean 100% (1/1)89%  (8/9)88%  (0.9/1)
compareTo (Value, CompareMode): int 100% (1/1)96%  (43/45)97%  (9.7/10)
<static initializer> 100% (1/1)100% (12/12)100% (3/3)
Value (): void 100% (1/1)100% (3/3)100% (2/2)
cache (Value): Value 100% (1/1)100% (55/55)100% (15/15)
clearCache (): void 100% (1/1)100% (3/3)100% (2/2)
close (): void 100% (1/1)100% (1/1)100% (1/1)
compareTypeSave (Value, CompareMode): int 100% (1/1)100% (20/20)100% (7/7)
convertPrecision (long, boolean): Value 100% (1/1)100% (2/2)100% (1/1)
convertScale (boolean, int): Value 100% (1/1)100% (2/2)100% (1/1)
convertToLong (BigDecimal): long 100% (1/1)100% (19/19)100% (3/3)
copyToResult (): Value 100% (1/1)100% (2/2)100% (1/1)
getBigDecimal (): BigDecimal 100% (1/1)100% (6/6)100% (1/1)
getBoolean (): Boolean 100% (1/1)100% (6/6)100% (1/1)
getByte (): byte 100% (1/1)100% (6/6)100% (1/1)
getBytesNoCopy (): byte [] 100% (1/1)100% (6/6)100% (1/1)
getDataHandler (): DataHandler 100% (1/1)100% (2/2)100% (1/1)
getDate (): Date 100% (1/1)100% (6/6)100% (1/1)
getDouble (): double 100% (1/1)100% (6/6)100% (1/1)
getFloat (): float 100% (1/1)100% (6/6)100% (1/1)
getInputStream (): InputStream 100% (1/1)100% (6/6)100% (1/1)
getInt (): int 100% (1/1)100% (6/6)100% (1/1)
getLong (): long 100% (1/1)100% (6/6)100% (1/1)
getMemory (): int 100% (1/1)100% (5/5)100% (1/1)
getReader (): Reader 100% (1/1)100% (6/6)100% (1/1)
getResultSet (): ResultSet 100% (1/1)100% (29/29)100% (5/5)
getScale (): int 100% (1/1)100% (2/2)100% (1/1)
getShort (): short 100% (1/1)100% (6/6)100% (1/1)
getTime (): Time 100% (1/1)100% (6/6)100% (1/1)
getTimestamp (): Timestamp 100% (1/1)100% (6/6)100% (1/1)
getTraceSQL (): String 100% (1/1)100% (3/3)100% (1/1)
isLinked (): boolean 100% (1/1)100% (2/2)100% (1/1)
link (DataHandler, int): Value 100% (1/1)100% (2/2)100% (1/1)
throwUnsupportedExceptionForType (String): DbException 100% (1/1)100% (15/15)100% (1/1)
toString (): String 100% (1/1)100% (3/3)100% (1/1)
unlink (DataHandler): void 100% (1/1)100% (1/1)100% (1/1)

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

[all classes][org.h2.value]
EMMA 2.0.5312 (C) Vladimir Roubtsov