1 | /* ============================================================= |
2 | * SmallSQL : a free Java DBMS library for the Java(tm) platform |
3 | * ============================================================= |
4 | * |
5 | * (C) Copyright 2004-2006, by Volker Berlin. |
6 | * |
7 | * Project Info: http://www.smallsql.de/ |
8 | * |
9 | * This library is free software; you can redistribute it and/or modify it |
10 | * under the terms of the GNU Lesser General Public License as published by |
11 | * the Free Software Foundation; either version 2.1 of the License, or |
12 | * (at your option) any later version. |
13 | * |
14 | * This library is distributed in the hope that it will be useful, but |
15 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY |
16 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public |
17 | * License for more details. |
18 | * |
19 | * You should have received a copy of the GNU Lesser General Public |
20 | * License along with this library; if not, write to the Free Software |
21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, |
22 | * USA. |
23 | * |
24 | * [Java is a trademark or registered trademark of Sun Microsystems, Inc. |
25 | * in the United States and other countries.] |
26 | * |
27 | * --------------- |
28 | * ExpressionValue.java |
29 | * --------------- |
30 | * Author: Volker Berlin |
31 | * |
32 | */ |
33 | package smallsql.database; |
34 | |
35 | import java.math.BigDecimal; |
36 | import java.sql.*; |
37 | |
38 | |
39 | public class ExpressionValue extends Expression { |
40 | |
41 | private Object value; |
42 | private int dataType; |
43 | private int length; |
44 | |
45 | /** |
46 | * Constructor is used from PreparedStatement parameters ( '?' in sql expression ) |
47 | */ |
48 | ExpressionValue(){ |
49 | super(VALUE); |
50 | clear(); |
51 | } |
52 | |
53 | /** |
54 | * Constructor is used from Constructor GroupResult |
55 | */ |
56 | ExpressionValue(int type){ |
57 | super(type); |
58 | switch(type){ |
59 | case GROUP_BY: |
60 | case SUM: |
61 | case FIRST: |
62 | case LAST: |
63 | clear(); |
64 | break; |
65 | case MIN: |
66 | case MAX: |
67 | // set value to null |
68 | break; |
69 | case COUNT: |
70 | value = new MutableInteger(0); |
71 | dataType = SQLTokenizer.INT; |
72 | break; |
73 | default: throw new Error(); |
74 | } |
75 | } |
76 | |
77 | |
78 | /** |
79 | * Constructor for static Expression i.e. 0x23, 67, 23.8, 'qwert' |
80 | */ |
81 | ExpressionValue(Object value, int dataType ){ |
82 | super(VALUE); |
83 | this.value = value; |
84 | this.dataType = dataType; |
85 | } |
86 | |
87 | |
88 | /** |
89 | * Is used in GroupResult. |
90 | */ |
91 | public boolean equals(Object expr){ |
92 | if(!super.equals(expr)) return false; |
93 | if(!(expr instanceof ExpressionValue)) return false; |
94 | Object v = ((ExpressionValue)expr).value; |
95 | if(v == value) return true; |
96 | if(value == null) return false; |
97 | return value.equals(v); |
98 | } |
99 | |
100 | |
101 | /*============================================================================== |
102 | methods for Grouping |
103 | ==============================================================================*/ |
104 | /** |
105 | * Accumulate the value of the expression to this aggregate function value. |
106 | */ |
107 | void accumulate(Expression expr) throws Exception{ |
108 | int type = getType(); |
109 | if(type != GROUP_BY) expr = expr.getParams()[0]; |
110 | switch(type){ |
111 | case GROUP_BY: |
112 | case FIRST: |
113 | if(isEmpty()) set( expr.getObject(), expr.getDataType() ); |
114 | break; |
115 | case LAST: |
116 | set( expr.getObject(), expr.getDataType() ); |
117 | break; |
118 | case COUNT: |
119 | if(!expr.isNull()) ((MutableInteger)value).value++; |
120 | break; |
121 | case SUM: |
122 | if(isEmpty()){ |
123 | initValue( expr ); |
124 | }else |
125 | switch(dataType){ |
126 | case SQLTokenizer.TINYINT: |
127 | case SQLTokenizer.SMALLINT: |
128 | case SQLTokenizer.INT: |
129 | ((MutableInteger)value).value += expr.getInt(); |
130 | break; |
131 | case SQLTokenizer.BIGINT: |
132 | ((MutableLong)value).value += expr.getLong(); |
133 | break; |
134 | case SQLTokenizer.REAL: |
135 | ((MutableFloat)value).value += expr.getFloat(); |
136 | break; |
137 | case SQLTokenizer.FLOAT: |
138 | case SQLTokenizer.DOUBLE: |
139 | ((MutableDouble)value).value += expr.getDouble(); |
140 | break; |
141 | case SQLTokenizer.NUMERIC: |
142 | case SQLTokenizer.DECIMAL: |
143 | MutableNumeric newValue = expr.getNumeric(); |
144 | if(newValue != null) |
145 | ((MutableNumeric)value).add( newValue ); |
146 | break; |
147 | case SQLTokenizer.MONEY: |
148 | ((Money)value).value += expr.getMoney(); |
149 | break; |
150 | default: throw Utils.createSQLException("Unsupported data type "+SQLTokenizer.getKeyWord(dataType) +" for SUM function."); |
151 | } |
152 | break; |
153 | case MAX: |
154 | if(value == null){ |
155 | if(expr.isNull()) |
156 | dataType = expr.getDataType(); |
157 | else |
158 | initValue( expr ); |
159 | }else if(!expr.isNull()){ |
160 | switch(dataType){ |
161 | case SQLTokenizer.TINYINT: |
162 | case SQLTokenizer.SMALLINT: |
163 | case SQLTokenizer.INT: |
164 | ((MutableInteger)value).value = Math.max( ((MutableInteger)value).value, expr.getInt()); |
165 | break; |
166 | case SQLTokenizer.BIGINT: |
167 | ((MutableLong)value).value = Math.max( ((MutableLong)value).value, expr.getLong()); |
168 | break; |
169 | case SQLTokenizer.REAL: |
170 | ((MutableFloat)value).value = Math.max( ((MutableFloat)value).value, expr.getFloat()); |
171 | break; |
172 | case SQLTokenizer.FLOAT: |
173 | case SQLTokenizer.DOUBLE: |
174 | ((MutableDouble)value).value = Math.max( ((MutableDouble)value).value, expr.getDouble()); |
175 | break; |
176 | case SQLTokenizer.CHAR: |
177 | case SQLTokenizer.VARCHAR: |
178 | case SQLTokenizer.LONGVARCHAR: |
179 | String str = expr.getString(); |
180 | if(String.CASE_INSENSITIVE_ORDER.compare( value, str ) < 0) |
181 | value = str; |
182 | break; |
183 | case SQLTokenizer.NUMERIC: |
184 | case SQLTokenizer.DECIMAL: |
185 | MutableNumeric newValue = expr.getNumeric(); |
186 | if(((MutableNumeric)value).compareTo( newValue ) < 0) |
187 | value = newValue; |
188 | break; |
189 | case SQLTokenizer.MONEY: |
190 | ((Money)value).value = Math.max( ((Money)value).value, expr.getMoney()); |
191 | break; |
192 | case SQLTokenizer.TIMESTAMP: |
193 | case SQLTokenizer.SMALLDATETIME: |
194 | case SQLTokenizer.DATE: |
195 | case SQLTokenizer.TIME: |
196 | ((DateTime)value).time = Math.max( ((DateTime)value).time, expr.getLong()); |
197 | break; |
198 | default: throw new Error(""+dataType); |
199 | } |
200 | } |
201 | break; |
202 | case MIN: |
203 | if(value == null){ |
204 | if(expr.isNull()) |
205 | dataType = expr.getDataType(); |
206 | else |
207 | initValue( expr ); |
208 | }else if(!expr.isNull()){ |
209 | switch(dataType){ |
210 | case SQLTokenizer.TINYINT: |
211 | case SQLTokenizer.SMALLINT: |
212 | case SQLTokenizer.INT: |
213 | ((MutableInteger)value).value = Math.min( ((MutableInteger)value).value, expr.getInt()); |
214 | break; |
215 | case SQLTokenizer.BIGINT: |
216 | ((MutableLong)value).value = Math.min( ((MutableLong)value).value, expr.getLong()); |
217 | break; |
218 | case SQLTokenizer.REAL: |
219 | ((MutableFloat)value).value = Math.min( ((MutableFloat)value).value, expr.getFloat()); |
220 | break; |
221 | case SQLTokenizer.FLOAT: |
222 | case SQLTokenizer.DOUBLE: |
223 | ((MutableDouble)value).value = Math.min( ((MutableDouble)value).value, expr.getDouble()); |
224 | break; |
225 | case SQLTokenizer.CHAR: |
226 | case SQLTokenizer.VARCHAR: |
227 | case SQLTokenizer.LONGVARCHAR: |
228 | String str = expr.getString(); |
229 | if(String.CASE_INSENSITIVE_ORDER.compare( value, str ) > 0) |
230 | value = str; |
231 | break; |
232 | case SQLTokenizer.NUMERIC: |
233 | case SQLTokenizer.DECIMAL: |
234 | MutableNumeric newValue = expr.getNumeric(); |
235 | if(((MutableNumeric)value).compareTo( newValue ) > 0) |
236 | value = newValue; |
237 | break; |
238 | case SQLTokenizer.MONEY: |
239 | ((Money)value).value = Math.min( ((Money)value).value, expr.getMoney()); |
240 | break; |
241 | case SQLTokenizer.TIMESTAMP: |
242 | case SQLTokenizer.SMALLDATETIME: |
243 | case SQLTokenizer.DATE: |
244 | case SQLTokenizer.TIME: |
245 | ((DateTime)value).time = Math.min( ((DateTime)value).time, expr.getLong()); |
246 | break; |
247 | default: throw new Error(""+dataType); |
248 | } |
249 | } |
250 | break; |
251 | default: throw new Error(); |
252 | } |
253 | } |
254 | |
255 | |
256 | /** |
257 | * Init a summary field with a Mutable |
258 | * @param expr the expression that produce the values which should be summary |
259 | * @throws Exception |
260 | */ |
261 | private void initValue(Expression expr) throws Exception{ |
262 | dataType = expr.getDataType(); |
263 | switch(dataType){ |
264 | case SQLTokenizer.TINYINT: |
265 | case SQLTokenizer.SMALLINT: |
266 | case SQLTokenizer.INT: |
267 | value = new MutableInteger(expr.getInt()); |
268 | break; |
269 | case SQLTokenizer.BIGINT: |
270 | value = new MutableLong(expr.getLong()); |
271 | break; |
272 | case SQLTokenizer.REAL: |
273 | value = new MutableFloat(expr.getFloat()); |
274 | break; |
275 | case SQLTokenizer.FLOAT: |
276 | case SQLTokenizer.DOUBLE: |
277 | value = new MutableDouble(expr.getDouble()); |
278 | break; |
279 | case SQLTokenizer.SMALLMONEY: |
280 | case SQLTokenizer.MONEY: |
281 | value = Money.createFromUnscaledValue(expr.getMoney()); |
282 | break; |
283 | case SQLTokenizer.NUMERIC: |
284 | case SQLTokenizer.DECIMAL: |
285 | value = new MutableNumeric(expr.getNumeric()); |
286 | break; |
287 | case SQLTokenizer.TIMESTAMP: |
288 | case SQLTokenizer.SMALLDATETIME: |
289 | case SQLTokenizer.DATE: |
290 | case SQLTokenizer.TIME: |
291 | value = new DateTime(expr.getLong(), dataType); |
292 | break; |
293 | default: |
294 | // is used for MAX and MIN |
295 | value = expr.getObject(); |
296 | } |
297 | } |
298 | /*============================================================================== |
299 | methods for PreparedStatement parameters |
300 | ==============================================================================*/ |
301 | private static final Object EMPTY = new Object(); |
302 | final boolean isEmpty(){ |
303 | return value == EMPTY; |
304 | } |
305 | |
306 | final void clear(){ |
307 | value = EMPTY; |
308 | } |
309 | |
310 | |
311 | final void set( Object value, int _dataType, int length ) throws SQLException{ |
312 | set( value, _dataType ); |
313 | this.length = length; |
314 | } |
315 | |
316 | |
317 | /** |
318 | * |
319 | * @param newValue The new Value. |
320 | * @param newDataType The data type of the new Value (One of the SQLTokenizer const). |
321 | * If the type is -1 then the data type is verify with many instanceof expressions. |
322 | * @throws SQLException If the newValue is not a instance of a know class. |
323 | */ |
324 | final void set( Object newValue, int newDataType ) throws SQLException{ |
325 | this.value = newValue; |
326 | this.dataType = newDataType; |
327 | if(dataType < 0){ |
328 | if(newValue == null) |
329 | this.dataType = SQLTokenizer.NULL; |
330 | else |
331 | if(newValue instanceof String) |
332 | this.dataType = SQLTokenizer.VARCHAR; |
333 | else |
334 | if(newValue instanceof Byte) |
335 | this.dataType = SQLTokenizer.TINYINT; |
336 | else |
337 | if(newValue instanceof Short) |
338 | this.dataType = SQLTokenizer.SMALLINT; |
339 | else |
340 | if(newValue instanceof Integer) |
341 | this.dataType = SQLTokenizer.INT; |
342 | else |
343 | if(newValue instanceof Long) |
344 | this.dataType = SQLTokenizer.BIGINT; |
345 | else |
346 | if(newValue instanceof Float) |
347 | this.dataType = SQLTokenizer.REAL; |
348 | else |
349 | if(newValue instanceof Double) |
350 | this.dataType = SQLTokenizer.DOUBLE; |
351 | else |
352 | if(newValue instanceof Number) |
353 | this.dataType = SQLTokenizer.DECIMAL; |
354 | else |
355 | if(newValue instanceof java.util.Date){ |
356 | DateTime dateTime; |
357 | this.value = dateTime = DateTime.valueOf((java.util.Date)newValue); |
358 | this.dataType = dateTime.getDataType(); |
359 | }else |
360 | if(newValue instanceof byte[]) |
361 | this.dataType = SQLTokenizer.VARBINARY; |
362 | else |
363 | if(newValue instanceof Boolean) |
364 | this.dataType = SQLTokenizer.BOOLEAN; |
365 | else |
366 | if(newValue instanceof Money) |
367 | this.dataType = SQLTokenizer.MONEY; |
368 | else |
369 | throw Utils.createSQLException("Unknown parameter class:" + newValue.getClass().getName()); |
370 | } |
371 | } |
372 | |
373 | |
374 | final void set(ExpressionValue val){ |
375 | this.value = val.value; |
376 | this.dataType = val.dataType; |
377 | this.length = val.length; |
378 | } |
379 | /*============================================================================== |
380 | overriden abstact methods extends from expression |
381 | ==============================================================================*/ |
382 | |
383 | |
384 | boolean isNull(){ |
385 | return value == null; |
386 | } |
387 | |
388 | boolean getBoolean() throws Exception{ |
389 | return getBoolean( value, dataType ); |
390 | } |
391 | |
392 | static boolean getBoolean(Object obj, int dataType) throws Exception{ |
393 | if(obj == null) return false; |
394 | switch(dataType){ |
395 | case SQLTokenizer.BIT: |
396 | case SQLTokenizer.BOOLEAN: |
397 | return (obj.equals(Boolean.TRUE)); |
398 | case SQLTokenizer.TINYINT: |
399 | case SQLTokenizer.SMALLINT: |
400 | case SQLTokenizer.INT: |
401 | case SQLTokenizer.BIGINT: |
402 | return ((Number)obj).intValue() != 0; |
403 | case SQLTokenizer.REAL: |
404 | case SQLTokenizer.DOUBLE: |
405 | case SQLTokenizer.MONEY: |
406 | return ((Number)obj).doubleValue() != 0; |
407 | default: return Utils.string2boolean( obj.toString() ); |
408 | } |
409 | } |
410 | |
411 | int getInt() throws Exception{ |
412 | return getInt( value, dataType ); |
413 | } |
414 | |
415 | static int getInt(Object obj, int dataType) throws Exception{ |
416 | if(obj == null) return 0; |
417 | switch(dataType){ |
418 | case SQLTokenizer.BIT: |
419 | case SQLTokenizer.BOOLEAN: |
420 | return (obj == Boolean.TRUE) ? 1 : 0; |
421 | case SQLTokenizer.TINYINT: |
422 | case SQLTokenizer.SMALLINT: |
423 | case SQLTokenizer.INT: |
424 | case SQLTokenizer.BIGINT: |
425 | case SQLTokenizer.REAL: |
426 | case SQLTokenizer.DOUBLE: |
427 | case SQLTokenizer.MONEY: |
428 | return ((Number)obj).intValue(); |
429 | case SQLTokenizer.TIMESTAMP: |
430 | case SQLTokenizer.TIME: |
431 | case SQLTokenizer.DATE: |
432 | case SQLTokenizer.SMALLDATETIME: |
433 | return (int)((DateTime)obj).getTimeMillis(); |
434 | default: |
435 | String str = obj.toString(); |
436 | try{ |
437 | return Integer.parseInt( str ); |
438 | }catch(Throwable th){} |
439 | return (int)Double.parseDouble( str ); |
440 | } |
441 | } |
442 | |
443 | long getLong() throws Exception{ |
444 | return getLong(value, dataType); |
445 | } |
446 | |
447 | static long getLong(Object obj, int dataType) throws Exception{ |
448 | if(obj == null) return 0; |
449 | switch(dataType){ |
450 | case SQLTokenizer.BIT: |
451 | case SQLTokenizer.BOOLEAN: |
452 | return (obj == Boolean.TRUE) ? 1 : 0; |
453 | case SQLTokenizer.TINYINT: |
454 | case SQLTokenizer.SMALLINT: |
455 | case SQLTokenizer.INT: |
456 | case SQLTokenizer.BIGINT: |
457 | case SQLTokenizer.DOUBLE: |
458 | case SQLTokenizer.MONEY: |
459 | return ((Number)obj).longValue(); |
460 | case SQLTokenizer.TIMESTAMP: |
461 | case SQLTokenizer.TIME: |
462 | case SQLTokenizer.DATE: |
463 | case SQLTokenizer.SMALLDATETIME: |
464 | return ((DateTime)obj).getTimeMillis(); |
465 | default: |
466 | String str = obj.toString(); |
467 | if(str.indexOf('-') > 0 || str.indexOf(':') > 0) |
468 | return DateTime.parse(str); |
469 | try{ |
470 | return Long.parseLong( str ); |
471 | }catch(NumberFormatException e){ |
472 | return (long)Double.parseDouble( str ); |
473 | } |
474 | } |
475 | } |
476 | |
477 | float getFloat() throws Exception{ |
478 | return getFloat( value, dataType); |
479 | } |
480 | |
481 | static float getFloat(Object obj, int dataType) throws Exception{ |
482 | if(obj == null) return 0; |
483 | switch(dataType){ |
484 | case SQLTokenizer.BIT: |
485 | return (obj.equals(Boolean.TRUE)) ? 1 : 0; |
486 | case SQLTokenizer.INT: |
487 | case SQLTokenizer.BIGINT: |
488 | case SQLTokenizer.DOUBLE: |
489 | case SQLTokenizer.FLOAT: |
490 | case SQLTokenizer.REAL: |
491 | case SQLTokenizer.MONEY: |
492 | return ((Number)obj).floatValue(); |
493 | case SQLTokenizer.TIMESTAMP: |
494 | case SQLTokenizer.TIME: |
495 | case SQLTokenizer.DATE: |
496 | case SQLTokenizer.SMALLDATETIME: |
497 | return ((DateTime)obj).getTimeMillis(); |
498 | default: return Float.parseFloat( obj.toString() ); |
499 | } |
500 | } |
501 | |
502 | double getDouble() throws Exception{ |
503 | return getDouble( value, dataType); |
504 | } |
505 | |
506 | static double getDouble(Object obj, int dataType) throws Exception{ |
507 | if(obj == null) return 0; |
508 | switch(dataType){ |
509 | case SQLTokenizer.BIT: |
510 | return (obj.equals(Boolean.TRUE)) ? 1 : 0; |
511 | case SQLTokenizer.INT: |
512 | case SQLTokenizer.BIGINT: |
513 | case SQLTokenizer.DOUBLE: |
514 | case SQLTokenizer.MONEY: |
515 | return ((Number)obj).doubleValue(); |
516 | case SQLTokenizer.TIMESTAMP: |
517 | case SQLTokenizer.TIME: |
518 | case SQLTokenizer.DATE: |
519 | case SQLTokenizer.SMALLDATETIME: |
520 | return ((DateTime)obj).getTimeMillis(); |
521 | default: return Double.parseDouble( obj.toString() ); |
522 | } |
523 | } |
524 | |
525 | |
526 | long getMoney() throws Exception{ |
527 | return getMoney( value, dataType ); |
528 | } |
529 | |
530 | |
531 | static long getMoney(Object obj, int dataType) throws Exception{ |
532 | if(obj == null) return 0; |
533 | switch(dataType){ |
534 | case SQLTokenizer.BIT: |
535 | return (obj == Boolean.TRUE) ? 10000 : 0; |
536 | case SQLTokenizer.TINYINT: |
537 | case SQLTokenizer.SMALLINT: |
538 | case SQLTokenizer.INT: |
539 | case SQLTokenizer.BIGINT: |
540 | return ((Number)obj).longValue() * 10000; |
541 | case SQLTokenizer.REAL: |
542 | case SQLTokenizer.FLOAT: |
543 | case SQLTokenizer.DOUBLE: |
544 | return Utils.doubleToMoney(((Number)obj).doubleValue()); |
545 | case SQLTokenizer.MONEY: |
546 | case SQLTokenizer.SMALLMONEY: |
547 | return ((Money)obj).value; |
548 | default: return Money.parseMoney( obj.toString() ); |
549 | } |
550 | } |
551 | |
552 | |
553 | MutableNumeric getNumeric(){ |
554 | return getNumeric(value, dataType ); |
555 | } |
556 | |
557 | |
558 | static MutableNumeric getNumeric(Object obj, int dataType){ |
559 | if(obj == null) return null; |
560 | switch(dataType){ |
561 | case SQLTokenizer.BIT: |
562 | return new MutableNumeric( (obj == Boolean.TRUE) ? 1 : 0); |
563 | case SQLTokenizer.INT: |
564 | return new MutableNumeric( ((Number)obj).intValue() ); |
565 | case SQLTokenizer.BIGINT: |
566 | return new MutableNumeric( ((Number)obj).longValue() ); |
567 | case SQLTokenizer.REAL: |
568 | float fValue = ((Number)obj).floatValue(); |
569 | if(Float.isInfinite(fValue) || Float.isNaN(fValue)) |
570 | return null; |
571 | return new MutableNumeric( fValue ); |
572 | case SQLTokenizer.FLOAT: |
573 | case SQLTokenizer.DOUBLE: |
574 | double dValue = ((Number)obj).doubleValue(); |
575 | if(Double.isInfinite(dValue) || Double.isNaN(dValue)) |
576 | return null; |
577 | return new MutableNumeric( dValue ); |
578 | case SQLTokenizer.MONEY: |
579 | case SQLTokenizer.SMALLMONEY: |
580 | return new MutableNumeric( ((Money)obj).value, 4 ); |
581 | case SQLTokenizer.DECIMAL: |
582 | case SQLTokenizer.NUMERIC: |
583 | if(obj instanceof MutableNumeric) |
584 | return (MutableNumeric)obj; |
585 | return new MutableNumeric( (BigDecimal)obj ); |
586 | default: return new MutableNumeric( obj.toString() ); |
587 | } |
588 | } |
589 | |
590 | |
591 | Object getObject(){ |
592 | return value; |
593 | } |
594 | |
595 | String getString(){ |
596 | if(value == null) return null; |
597 | if(dataType == SQLTokenizer.BIT){ |
598 | return (value == Boolean.TRUE) ? "1" : "0"; |
599 | } |
600 | return value.toString(); |
601 | } |
602 | |
603 | byte[] getBytes() throws Exception{ |
604 | return getBytes( value, dataType); |
605 | } |
606 | |
607 | |
608 | static byte[] getBytes(Object obj, int dataType) throws Exception{ |
609 | if(obj == null) return null; |
610 | switch(dataType){ |
611 | case SQLTokenizer.BINARY: |
612 | case SQLTokenizer.VARBINARY: |
613 | return (byte[])obj; |
614 | case SQLTokenizer.VARCHAR: |
615 | case SQLTokenizer.CHAR: |
616 | case SQLTokenizer.NVARCHAR: |
617 | case SQLTokenizer.NCHAR: |
618 | return ((String)obj).getBytes(); |
619 | case SQLTokenizer.INT: |
620 | return Utils.int2bytes( ((Number)obj).intValue() ); |
621 | case SQLTokenizer.UNIQUEIDENTIFIER: |
622 | return Utils.unique2bytes((String)obj); |
623 | default: throw createUnspportedConversion(dataType, obj, SQLTokenizer.VARBINARY); |
624 | } |
625 | } |
626 | |
627 | |
628 | |
629 | final int getDataType(){ |
630 | return dataType; |
631 | } |
632 | |
633 | /*======================================================================= |
634 | |
635 | Methods for ResultSetMetaData |
636 | |
637 | =======================================================================*/ |
638 | |
639 | String getTableName(){ |
640 | return null; |
641 | } |
642 | |
643 | final int getPrecision(){ |
644 | switch(dataType){ |
645 | case SQLTokenizer.VARCHAR: |
646 | case SQLTokenizer.CHAR: |
647 | return ((String)value).length(); |
648 | case SQLTokenizer.VARBINARY: |
649 | case SQLTokenizer.BINARY: |
650 | return ((byte[])value).length; |
651 | default: |
652 | return super.getPrecision(); |
653 | } |
654 | } |
655 | |
656 | |
657 | int getScale(){ |
658 | switch(dataType){ |
659 | case SQLTokenizer.DECIMAL: |
660 | case SQLTokenizer.NUMERIC: |
661 | MutableNumeric obj = getNumeric(); |
662 | return (obj == null) ? 0: obj.scale; |
663 | default: |
664 | return getScale(dataType); |
665 | } |
666 | } |
667 | |
668 | |
669 | static SQLException createUnspportedConversion( int fromDataType, Object obj, int toDataType ){ |
670 | return Utils.createSQLException("Can't convert '" + |
671 | SQLTokenizer.getKeyWord(fromDataType) + |
672 | "' [" + obj + ']' + |
673 | "' to '" + |
674 | SQLTokenizer.getKeyWord(toDataType) + '\''); |
675 | } |
676 | |
677 | |
678 | } |