KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > smallsql > database > ExpressionArithmetic


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  * ExpressionArithmethic.java
29  * ---------------
30  * Author: Volker Berlin
31  *
32  */

33 package smallsql.database;
34
35 import java.sql.*;
36
37
38 public class ExpressionArithmetic extends Expression {
39
40     private Expression left;
41     private Expression right;
42     private Expression right2;
43     private Expression[] inList;
44     final private int operation;
45
46     /**
47      * Constructor for NOT, NEGATIVE, BIT_NOT, ISNULL and ISNOTNULL
48      */

49     ExpressionArithmetic( Expression right, int operation){
50         super(FUNCTION);
51         this.right = right;
52         this.operation = operation;
53         super.setParams( new Expression[]{ right });
54     }
55
56     ExpressionArithmetic( Expression left, Expression right, int operation){
57         super(FUNCTION);
58         this.left = left;
59         this.right = right;
60         this.operation = operation;
61         super.setParams( new Expression[]{ left, right });
62     }
63
64     /**
65      * Constructor for BETWEEN
66      */

67     ExpressionArithmetic( Expression left, Expression right, Expression right2, int operation){
68         super(FUNCTION);
69         this.left = left;
70         this.right = right;
71         this.right2 = right2;
72         this.operation = operation;
73         super.setParams( new Expression[]{ left, right, right2 });
74     }
75     
76     /**
77      * Constructor for IN
78      */

79     ExpressionArithmetic( Expression left, Expressions inList, int operation){
80         super(FUNCTION);
81         this.left = left;
82         this.operation = operation;
83         Expression[] params;
84         if(inList != null){
85             this.inList = inList.toArray();
86             params = new Expression[this.inList.length+1];
87             params[0] = left;
88             System.arraycopy(this.inList, 0, params, 1, this.inList.length);
89         }else{
90             params = new Expression[]{ left };
91         }
92         super.setParams( params );
93     }
94         
95
96     final void setParamAt( Expression param, int idx){
97         switch(idx){
98             case 0:
99                 left = param;
100                 break;
101             case 1:
102                 right = param;
103                 break;
104             case 2:
105                 right2 = param;
106                 break;
107         }
108         if(inList != null && idx>0 && idx<=inList.length){
109             inList[idx+1] = param;
110         }
111         super.setParamAt( param, idx );
112     }
113
114
115     /**
116      * Is used in GroupResult.
117      */

118     public boolean equals(Object JavaDoc expr){
119         if(!super.equals(expr)) return false;
120         if(!(expr instanceof ExpressionArithmetic)) return false;
121         if( ((ExpressionArithmetic)expr).operation != operation) return false;
122         return true;
123     }
124
125
126     
127     int getInt() throws java.lang.Exception JavaDoc {
128         if(isNull()) return 0;
129         int dataType = getDataType();
130         switch(dataType){
131             case SQLTokenizer.BIT:
132             case SQLTokenizer.BOOLEAN:
133                 return getBoolean() ? 1 : 0;
134             case SQLTokenizer.TINYINT:
135             case SQLTokenizer.SMALLINT:
136             case SQLTokenizer.INT:
137                 return getIntImpl();
138             case SQLTokenizer.BIGINT:
139                 return (int)getLongImpl();
140             case SQLTokenizer.REAL:
141                 return (int)getFloatImpl();
142             case SQLTokenizer.FLOAT:
143             case SQLTokenizer.DOUBLE:
144             case SQLTokenizer.MONEY:
145             case SQLTokenizer.SMALLMONEY:
146             case SQLTokenizer.NUMERIC:
147             case SQLTokenizer.DECIMAL:
148                 return (int)getDoubleImpl();
149         }
150         throw createUnspportedConversion( SQLTokenizer.INT);
151     }
152     
153     
154     private int getIntImpl() throws java.lang.Exception JavaDoc {
155         switch(operation){
156             case ADD: return left.getInt() + right.getInt();
157             case SUB: return left.getInt() - right.getInt();
158             case MUL: return left.getInt() * right.getInt();
159             case DIV: return left.getInt() / right.getInt();
160             case NEGATIVE: return - right.getInt();
161             case MOD: return left.getInt() % right.getInt();
162             case BIT_NOT: return ~ right.getInt();
163         }
164         throw createUnspportedConversion( SQLTokenizer.INT);
165     }
166     
167     
168     long getLong() throws java.lang.Exception JavaDoc {
169         if(isNull()) return 0;
170         int dataType = getDataType();
171         switch(dataType){
172             case SQLTokenizer.BIT:
173             case SQLTokenizer.BOOLEAN:
174                 return getBoolean() ? 1 : 0;
175             case SQLTokenizer.TINYINT:
176             case SQLTokenizer.SMALLINT:
177             case SQLTokenizer.INT:
178                 return getIntImpl();
179             case SQLTokenizer.BIGINT:
180                 return getLongImpl();
181             case SQLTokenizer.REAL:
182                 return (long)getFloatImpl();
183             case SQLTokenizer.FLOAT:
184             case SQLTokenizer.DOUBLE:
185             case SQLTokenizer.MONEY:
186             case SQLTokenizer.SMALLMONEY:
187             case SQLTokenizer.NUMERIC:
188             case SQLTokenizer.DECIMAL:
189                 return (long)getDoubleImpl();
190         }
191         throw createUnspportedConversion( SQLTokenizer.LONG);
192     }
193     
194     
195     private long getLongImpl() throws java.lang.Exception JavaDoc {
196         if(isNull()) return 0;
197         switch(operation){
198             case ADD: return left.getLong() + right.getLong();
199             case SUB: return left.getLong() - right.getLong();
200             case MUL: return left.getLong() * right.getLong();
201             case DIV: return left.getLong() / right.getLong();
202             case NEGATIVE: return - right.getLong();
203             case MOD: return left.getLong() % right.getLong();
204             case BIT_NOT: return ~ right.getInt();
205         }
206         throw createUnspportedConversion( SQLTokenizer.LONG);
207     }
208     
209     
210     double getDouble() throws java.lang.Exception JavaDoc {
211         if(isNull()) return 0;
212         int dataType = getDataType();
213         switch(dataType){
214             case SQLTokenizer.BIT:
215             case SQLTokenizer.BOOLEAN:
216                 return getBoolean() ? 1 : 0;
217             case SQLTokenizer.TINYINT:
218             case SQLTokenizer.SMALLINT:
219             case SQLTokenizer.INT:
220                 return getIntImpl();
221             case SQLTokenizer.BIGINT:
222                 return getLongImpl();
223             case SQLTokenizer.REAL:
224                 return getFloatImpl();
225             case SQLTokenizer.FLOAT:
226             case SQLTokenizer.DOUBLE:
227             case SQLTokenizer.MONEY:
228             case SQLTokenizer.SMALLMONEY:
229             case SQLTokenizer.NUMERIC:
230             case SQLTokenizer.DECIMAL:
231                 return getDoubleImpl();
232         }
233         throw createUnspportedConversion( SQLTokenizer.DOUBLE);
234     }
235     
236     
237     private double getDoubleImpl() throws java.lang.Exception JavaDoc{
238         if(operation == NEGATIVE)
239             return getDoubleImpl(0, right.getDouble());
240         return getDoubleImpl(left.getDouble(), right.getDouble());
241     }
242     
243     
244     private double getDoubleImpl( double lVal, double rVal) throws java.lang.Exception JavaDoc{
245         switch(operation){
246             case ADD: return lVal + rVal;
247             case SUB: return lVal - rVal;
248             case MUL: return lVal * rVal;
249             case DIV: return lVal / rVal;
250             case NEGATIVE: return - rVal;
251             case MOD: return lVal % rVal;
252         }
253         throw createUnspportedConversion( SQLTokenizer.DOUBLE);
254     }
255     
256
257     float getFloat() throws java.lang.Exception JavaDoc {
258         if(isNull()) return 0;
259         int dataType = getDataType();
260         switch(dataType){
261             case SQLTokenizer.BIT:
262             case SQLTokenizer.BOOLEAN:
263                 return getBoolean() ? 1 : 0;
264             case SQLTokenizer.TINYINT:
265             case SQLTokenizer.SMALLINT:
266             case SQLTokenizer.INT:
267                 return getIntImpl();
268             case SQLTokenizer.BIGINT:
269                 return getLongImpl();
270             case SQLTokenizer.REAL:
271                 return getFloatImpl();
272             case SQLTokenizer.FLOAT:
273             case SQLTokenizer.DOUBLE:
274             case SQLTokenizer.MONEY:
275             case SQLTokenizer.SMALLMONEY:
276             case SQLTokenizer.NUMERIC:
277             case SQLTokenizer.DECIMAL:
278                 return (float)getDoubleImpl();
279         }
280         throw createUnspportedConversion( SQLTokenizer.DOUBLE);
281     }
282     
283     
284     private float getFloatImpl() throws java.lang.Exception JavaDoc {
285         switch(operation){
286             case ADD: return left.getFloat() + right.getFloat();
287             case SUB: return left.getFloat() - right.getFloat();
288             case MUL: return left.getFloat() * right.getFloat();
289             case DIV: return left.getFloat() / right.getFloat();
290             case NEGATIVE: return - right.getFloat();
291             case MOD: return left.getFloat() % right.getFloat();
292         }
293         throw createUnspportedConversion( SQLTokenizer.REAL );
294     }
295     
296     
297     long getMoney() throws java.lang.Exception JavaDoc {
298         if(isNull()) return 0;
299         int dataType = getDataType();
300         switch(dataType){
301             case SQLTokenizer.BIT:
302             case SQLTokenizer.BOOLEAN:
303                 return getBoolean() ? 10000 : 0;
304             case SQLTokenizer.TINYINT:
305             case SQLTokenizer.SMALLINT:
306             case SQLTokenizer.INT:
307                 return getIntImpl() * 10000;
308             case SQLTokenizer.BIGINT:
309                 return getLongImpl() * 10000;
310             case SQLTokenizer.REAL:
311                 return Utils.doubleToMoney( getFloatImpl() );
312             case SQLTokenizer.FLOAT:
313             case SQLTokenizer.DOUBLE:
314             case SQLTokenizer.NUMERIC:
315             case SQLTokenizer.DECIMAL:
316                 return Utils.doubleToMoney( getDoubleImpl() );
317             case SQLTokenizer.MONEY:
318             case SQLTokenizer.SMALLMONEY:
319                 return getMoneyImpl();
320         }
321         throw createUnspportedConversion( SQLTokenizer.DOUBLE);
322     }
323     
324
325     private long getMoneyImpl() throws java.lang.Exception JavaDoc {
326         switch(operation){
327             case ADD: return left.getMoney() + right.getMoney();
328             case SUB: return left.getMoney() - right.getMoney();
329             case MUL: return left.getMoney() * right.getMoney() / 10000;
330             case DIV: return left.getMoney() * 10000 / right.getMoney();
331             case NEGATIVE: return - right.getMoney();
332         }
333         throw createUnspportedConversion( SQLTokenizer.MONEY );
334     }
335     
336
337     MutableNumeric getNumeric() throws java.lang.Exception JavaDoc {
338         if(isNull()) return null;
339         int dataType = getDataType();
340         switch(dataType){
341             case SQLTokenizer.BIT:
342             case SQLTokenizer.BOOLEAN:
343                 return new MutableNumeric(getBoolean() ? 1 : 0);
344             case SQLTokenizer.TINYINT:
345             case SQLTokenizer.SMALLINT:
346             case SQLTokenizer.INT:
347                 return new MutableNumeric(getIntImpl());
348             case SQLTokenizer.BIGINT:
349                 return new MutableNumeric(getLongImpl());
350             case SQLTokenizer.REAL:
351                 return new MutableNumeric(getFloatImpl());
352             case SQLTokenizer.FLOAT:
353             case SQLTokenizer.DOUBLE:
354                 return new MutableNumeric( getDoubleImpl() );
355             case SQLTokenizer.NUMERIC:
356             case SQLTokenizer.DECIMAL:
357                 return getNumericImpl();
358             case SQLTokenizer.MONEY:
359             case SQLTokenizer.SMALLMONEY:
360                 return new MutableNumeric(getMoneyImpl(),4);
361         }
362         throw createUnspportedConversion( SQLTokenizer.DOUBLE);
363     }
364     
365     
366     private MutableNumeric getNumericImpl() throws java.lang.Exception JavaDoc {
367         switch(operation){
368             case ADD:
369                 {
370                     MutableNumeric num = left.getNumeric();
371                     num.add( right.getNumeric() );
372                     return num;
373                 }
374             case SUB:
375                 {
376                     MutableNumeric num = left.getNumeric();
377                     num.sub( right.getNumeric() );
378                     return num;
379                 }
380             case MUL:
381                 if(getDataType(right.getDataType(), SQLTokenizer.INT) == SQLTokenizer.INT){
382                     MutableNumeric num = left.getNumeric();
383                     num.mul(right.getInt());
384                     return num;
385                 }else
386                 if(getDataType(left.getDataType(), SQLTokenizer.INT) == SQLTokenizer.INT){
387                     MutableNumeric num = right.getNumeric();
388                     num.mul(left.getInt());
389                     return num;
390                 }else{
391                     MutableNumeric num = left.getNumeric();
392                     num.mul( right.getNumeric() );
393                     return num;
394                 }
395             case DIV:
396                 {
397                     MutableNumeric num = left.getNumeric();
398                     if(getDataType(right.getDataType(), SQLTokenizer.INT) == SQLTokenizer.INT)
399                         num.div( right.getInt() );
400                     else
401                         num.div( right.getNumeric() );
402                     return num;
403                 }
404             case NEGATIVE:
405                 {
406                     MutableNumeric num = right.getNumeric();
407                     num.setSignum(-num.getSignum());
408                     return num;
409                 }
410             case MOD:
411                 {
412                     if(getDataType(getDataType(), SQLTokenizer.INT) == SQLTokenizer.INT)
413                         return new MutableNumeric(getInt());
414                     MutableNumeric num = left.getNumeric();
415                     num.mod( right.getNumeric() );
416                     return num;
417                 }
418             default: throw createUnspportedConversion( SQLTokenizer.NUMERIC );
419         }
420     }
421     
422     
423     Object JavaDoc getObject() throws java.lang.Exception JavaDoc {
424         if(isNull()) return null;
425         int dataType = getDataType();
426         switch(dataType){
427             case SQLTokenizer.BIT:
428             case SQLTokenizer.BOOLEAN:
429                     return getBoolean() ? Boolean.TRUE : Boolean.FALSE;
430             case SQLTokenizer.BINARY:
431             case SQLTokenizer.VARBINARY:
432                     return getBytes();
433             case SQLTokenizer.TINYINT:
434             case SQLTokenizer.SMALLINT:
435             case SQLTokenizer.INT:
436                     return new Integer JavaDoc( getInt() );
437             case SQLTokenizer.BIGINT:
438                     return new Long JavaDoc( getLong() );
439             case SQLTokenizer.REAL:
440                     return new Float JavaDoc( getFloat() );
441             case SQLTokenizer.FLOAT:
442             case SQLTokenizer.DOUBLE:
443                     return new Double JavaDoc( getDouble() );
444             case SQLTokenizer.MONEY:
445             case SQLTokenizer.SMALLMONEY:
446                     return Money.createFromUnscaledValue( getMoney() );
447             case SQLTokenizer.NUMERIC:
448             case SQLTokenizer.DECIMAL:
449                     return getNumeric();
450             case SQLTokenizer.CHAR:
451             case SQLTokenizer.NCHAR:
452             case SQLTokenizer.VARCHAR:
453             case SQLTokenizer.NVARCHAR:
454             case SQLTokenizer.LONGNVARCHAR:
455             case SQLTokenizer.LONGVARCHAR:
456                     return getString( left.getString(), right.getString() );
457             case SQLTokenizer.JAVA_OBJECT:
458                     Object JavaDoc lObj = left.getObject();
459                     //FIXME NullPointerException bei NEGATIVE
460
Object JavaDoc rObj = right.getObject();
461                     if(lObj instanceof Number JavaDoc && rObj instanceof Number JavaDoc)
462                         return new Double JavaDoc( getDoubleImpl( ((Number JavaDoc)lObj).doubleValue(), ((Number JavaDoc)rObj).doubleValue() ) );
463                     else
464                         return getString( lObj.toString(), rObj.toString() );
465             case SQLTokenizer.LONGVARBINARY:
466                     return getBytes();
467             case SQLTokenizer.DATE:
468             case SQLTokenizer.TIME:
469             case SQLTokenizer.TIMESTAMP:
470             case SQLTokenizer.SMALLDATETIME:
471                 return new DateTime( getLong(), dataType );
472             case SQLTokenizer.UNIQUEIDENTIFIER:
473                     return getBytes();
474             default: throw createUnspportedDataType();
475         }
476     }
477     
478     
479     boolean getBoolean() throws java.lang.Exception JavaDoc {
480         switch(operation){
481             case OR: return left.getBoolean() || right.getBoolean();
482             case AND: return left.getBoolean() && right.getBoolean();
483             case NOT: return !right.getBoolean();
484             case LIKE: return Utils.like( left.getString(), right.getString());
485             case ISNULL:return right.isNull();
486             case ISNOTNULL: return !right.isNull();
487             case IN: if(right == null)
488                             return isInList();
489                         break;
490         }
491         final boolean rightIsNull = right.isNull();
492         int dataType;
493         if(operation == NEGATIVE || operation == BIT_NOT){
494             if(rightIsNull) return false;
495             dataType = right.getDataType();
496         }else{
497             final boolean leftIsNull = left.isNull();
498             if(operation == EQUALS_NULL && leftIsNull && rightIsNull) return true;
499             if(leftIsNull || rightIsNull) return false;
500             dataType = getDataType(left, right);
501         }
502         switch(dataType){
503             case SQLTokenizer.BOOLEAN:
504                     switch(operation){
505                         case IN:
506                         case EQUALS_NULL:
507                         case EQUALS: return left.getBoolean() == right.getBoolean();
508                         case UNEQUALS: return left.getBoolean() != right.getBoolean();
509                     }
510                     //break; interpret it as BIT
511
case SQLTokenizer.TINYINT:
512             case SQLTokenizer.SMALLINT:
513             case SQLTokenizer.INT:
514             case SQLTokenizer.BIT:
515                     switch(operation){
516                         case IN:
517                         case EQUALS_NULL:
518                         case EQUALS: return left.getInt() == right.getInt();
519                         case GREATER: return left.getInt() > right.getInt();
520                         case GRE_EQU: return left.getInt() >= right.getInt();
521                         case LESSER: return left.getInt() < right.getInt();
522                         case LES_EQU: return left.getInt() <= right.getInt();
523                         case UNEQUALS: return left.getInt() != right.getInt();
524                         case BETWEEN:
525                                         int _left = left.getInt();
526                                         return _left >= right.getInt() && right2.getInt() >= _left;
527                         default:
528                             return getInt() != 0;
529                     }
530             case SQLTokenizer.BIGINT:
531             case SQLTokenizer.TIMESTAMP:
532             case SQLTokenizer.TIME:
533             case SQLTokenizer.DATE:
534             case SQLTokenizer.SMALLDATETIME:
535                     switch(operation){
536                         case IN:
537                         case EQUALS_NULL:
538                         case EQUALS: return left.getLong() == right.getLong();
539                         case GREATER: return left.getLong() > right.getLong();
540                         case GRE_EQU: return left.getLong() >= right.getLong();
541                         case LESSER: return left.getLong() < right.getLong();
542                         case LES_EQU: return left.getLong() <= right.getLong();
543                         case UNEQUALS: return left.getLong() != right.getLong();
544                         case BETWEEN:
545                                         long _left = left.getLong();
546                                         return _left >= right.getLong() && right2.getLong() >= _left;
547                         default:
548                             return getLong() != 0;
549                     }
550             case SQLTokenizer.REAL:
551                     switch(operation){
552                         case IN:
553                         case EQUALS_NULL:
554                         case EQUALS: return left.getFloat() == right.getFloat();
555                         case GREATER: return left.getFloat() > right.getFloat();
556                         case GRE_EQU: return left.getFloat() >= right.getFloat();
557                         case LESSER: return left.getFloat() < right.getFloat();
558                         case LES_EQU: return left.getFloat() <= right.getFloat();
559                         case UNEQUALS: return left.getFloat() != right.getFloat();
560                         case BETWEEN:
561                                         float _left = left.getFloat();
562                                         return _left >= right.getFloat() && right2.getFloat() >= _left;
563                         default:
564                             return getFloat() != 0;
565                     }
566             case SQLTokenizer.FLOAT:
567             case SQLTokenizer.DOUBLE:
568                     switch(operation){
569                         case IN:
570                         case EQUALS_NULL:
571                         case EQUALS: return left.getDouble() == right.getDouble();
572                         case GREATER: return left.getDouble() > right.getDouble();
573                         case GRE_EQU: return left.getDouble() >= right.getDouble();
574                         case LESSER: return left.getDouble() < right.getDouble();
575                         case LES_EQU: return left.getDouble() <= right.getDouble();
576                         case UNEQUALS: return left.getDouble() != right.getDouble();
577                         case BETWEEN:
578                                         double _left = left.getDouble();
579                                         return _left >= right.getDouble() && right2.getDouble() >= _left;
580                         default:
581                             return getDouble() != 0;
582                     }
583             case SQLTokenizer.MONEY:
584             case SQLTokenizer.SMALLMONEY:
585                     switch(operation){
586                         case IN:
587                         case EQUALS_NULL:
588                         case EQUALS: return left.getMoney() == right.getMoney();
589                         case GREATER: return left.getMoney() > right.getMoney();
590                         case GRE_EQU: return left.getMoney() >= right.getMoney();
591                         case LESSER: return left.getMoney() < right.getMoney();
592                         case LES_EQU: return left.getMoney() <= right.getMoney();
593                         case UNEQUALS: return left.getMoney() != right.getMoney();
594                         case BETWEEN:
595                                         long _left = left.getMoney();
596                                         return _left >= right.getMoney() && right2.getMoney() >= _left;
597                         default:
598                             return getMoney() != 0;
599                     }
600             case SQLTokenizer.DECIMAL:
601             case SQLTokenizer.NUMERIC:{
602                     if(operation == NEGATIVE)
603                         return right.getNumeric().getSignum() != 0;
604                     int comp = left.getNumeric().compareTo( right.getNumeric() );
605                     switch(operation){
606                         case IN:
607                         case EQUALS_NULL:
608                         case EQUALS: return comp == 0;
609                         case GREATER: return comp > 0;
610                         case GRE_EQU: return comp >= 0;
611                         case LESSER: return comp < 0;
612                         case LES_EQU: return comp <= 0;
613                         case UNEQUALS: return comp != 0;
614                         case BETWEEN:
615                                         return comp >= 0 && 0 >= left.getNumeric().compareTo( right2.getNumeric() );
616                         default:
617                             return getNumeric().getSignum() != 0;
618                     }
619                     }
620             case SQLTokenizer.VARCHAR:
621             case SQLTokenizer.NVARCHAR:
622             case SQLTokenizer.CHAR:
623             case SQLTokenizer.NCHAR:
624             case SQLTokenizer.LONGVARCHAR:
625             case SQLTokenizer.LONGNVARCHAR:
626             case SQLTokenizer.CLOB:{
627                     int comp = String.CASE_INSENSITIVE_ORDER.compare( left.getString(), right.getString() );
628                     switch(operation){
629                         case IN:
630                         case EQUALS_NULL:
631                         case EQUALS: return comp == 0;
632                         case GREATER: return comp > 0;
633                         case GRE_EQU: return comp >= 0;
634                         case LESSER: return comp < 0;
635                         case LES_EQU: return comp <= 0;
636                         case UNEQUALS: return comp != 0;
637                         case BETWEEN:
638                                         return comp >= 0 && 0 >= String.CASE_INSENSITIVE_ORDER.compare( left.getString(), right2.getString() );
639                         case ADD: return Utils.string2boolean(left.getString() + right.getString());
640                     }
641                     break;}
642             case SQLTokenizer.BINARY:
643             case SQLTokenizer.VARBINARY:
644             case SQLTokenizer.LONGVARBINARY:
645             case SQLTokenizer.BLOB:
646             case SQLTokenizer.UNIQUEIDENTIFIER:{
647                     byte[] leftBytes = left.getBytes();
648                     byte[] rightBytes= right.getBytes();
649                     int comp = Utils.compareBytes( leftBytes, rightBytes);
650                     switch(operation){
651                         case IN:
652                         case EQUALS_NULL:
653                         case EQUALS: return comp == 0;
654                         case GREATER: return comp > 0;
655                         case GRE_EQU: return comp >= 0;
656                         case LESSER: return comp < 0;
657                         case LES_EQU: return comp <= 0;
658                         case UNEQUALS: return comp != 0;
659                         case BETWEEN:
660                                         return comp >= 0 && 0 >= Utils.compareBytes( leftBytes, right2.getBytes() );
661                     }
662                     break;}
663         }
664         throw createUnspportedDataType();
665     }
666     
667     
668     String JavaDoc getString() throws java.lang.Exception JavaDoc {
669         if(isNull()) return null;
670         return getObject().toString();
671     }
672     
673     
674     final private String JavaDoc getString( String JavaDoc lVal, String JavaDoc rVal ) throws java.lang.Exception JavaDoc {
675         switch(operation){
676             case ADD: return lVal + rVal;
677         }
678         throw createUnspportedConversion( SQLTokenizer.VARCHAR );
679     }
680
681     
682     int getDataType() {
683         switch(operation){
684             case NEGATIVE:
685             case BIT_NOT:
686                 return right.getDataType();
687             case EQUALS:
688             case EQUALS_NULL:
689             case GREATER:
690             case GRE_EQU:
691             case LESSER:
692             case LES_EQU:
693             case UNEQUALS:
694             case BETWEEN:
695             case OR:
696             case AND:
697             case NOT:
698             case LIKE:
699             case ISNULL:
700             case ISNOTNULL:
701                 return SQLTokenizer.BOOLEAN;
702             default:
703                 return getDataType(left, right);
704         }
705     }
706     
707     
708     int getScale(){
709         int dataType = getDataType();
710         switch(dataType){
711             case SQLTokenizer.DECIMAL:
712             case SQLTokenizer.NUMERIC:
713                 switch(operation){
714                     case ADD:
715                     case SUB:
716                         return Math.max(left.getScale(), right.getScale());
717                     case MUL:
718                         return left.getScale() + right.getScale();
719                     case DIV:
720                         return Math.max(left.getScale()+5, right.getScale()+4);
721                     case NEGATIVE:
722                         return right.getScale();
723                     case MOD:
724                         return 0;
725                 }
726         }
727         return getScale(dataType);
728     }
729
730     
731     boolean isNull() throws Exception JavaDoc{
732         switch(operation){
733             case OR:
734             case AND:
735             case NOT:
736             case LIKE:
737             case ISNULL:
738             case ISNOTNULL:
739             case IN:
740                             return false; //Boolesche Operationen liefern immer ein Ergebniss ???, midestends aber ISNULL und ISNOTNULL
741
case NEGATIVE:
742             case BIT_NOT:
743                            return right.isNull();
744             default: return left.isNull() || right.isNull();
745         }
746     }
747
748
749     byte[] getBytes() throws java.lang.Exception JavaDoc {
750         throw createUnspportedConversion( SQLTokenizer.BINARY );
751     }
752     
753     
754     boolean isInList() throws Exception JavaDoc{
755         if(left.isNull()) return false;
756         try{
757             for(int i=0; i<inList.length; i++){
758                 right = inList[i];
759                 if(getBoolean()) return true;
760             }
761         }finally{
762             right = null;
763         }
764         return false;
765     }
766
767     
768     SQLException createUnspportedDataType(){
769         return Utils.createSQLException("Unsupported data type '" +
770                     SQLTokenizer.getKeyWord(getDataType(left, right)) +
771                     "' for Operation '" + getKeywordFromOperation(operation)+'\'');
772     }
773
774     
775     SQLException createUnspportedConversion( int dataType ){
776         int type = left == null ? right.getDataType() : getDataType(left, right);
777         return Utils.createSQLException("Unsupported conversion to data type '" +
778                     SQLTokenizer.getKeyWord(dataType) +
779                     "' from data type '" +
780                     SQLTokenizer.getKeyWord(type) +
781                     "' for Operation '" + getKeywordFromOperation(operation)+'\'');
782     }
783     
784     
785     /**
786      * This method only for creating an error message. Thats there is no optimizing.
787      * @param value
788      * @return
789      */

790     private static String JavaDoc getKeywordFromOperation(int operation){
791         int token = 0;
792         for(int i=1; i<1000; i++){
793             if(getOperationFromToken(i) == operation){
794                 token = i;
795                 break;
796             }
797         }
798         if(operation == NEGATIVE) token = SQLTokenizer.MINUS;
799         if(operation == ISNOTNULL) token = SQLTokenizer.IS;
800         String JavaDoc keyword = SQLTokenizer.getKeyWord(token);
801         if(keyword == null) keyword = "" + (char)token;
802         return keyword;
803     }
804
805     
806     static int getOperationFromToken( int value ){
807         switch(value){
808             case SQLTokenizer.PLUS: return ADD;
809             case SQLTokenizer.MINUS: return SUB;
810             case SQLTokenizer.ASTERISK: return MUL;
811             case SQLTokenizer.SLACH: return DIV;
812             case SQLTokenizer.PERCENT: return MOD;
813             case SQLTokenizer.EQUALS: return EQUALS;
814             case SQLTokenizer.GREATER: return GREATER;
815             case SQLTokenizer.GREATER_EQU: return GRE_EQU;
816             case SQLTokenizer.LESSER: return LESSER;
817             case SQLTokenizer.LESSER_EQU: return LES_EQU;
818             case SQLTokenizer.UNEQUALS: return UNEQUALS;
819             case SQLTokenizer.BETWEEN: return BETWEEN;
820             case SQLTokenizer.LIKE: return LIKE;
821             case SQLTokenizer.IN: return IN;
822             case SQLTokenizer.IS: return ISNULL;
823             case SQLTokenizer.OR: return OR;
824             case SQLTokenizer.AND: return AND;
825             case SQLTokenizer.NOT: return NOT;
826             case SQLTokenizer.BIT_OR: return BIT_OR;
827             case SQLTokenizer.BIT_AND: return BIT_AND;
828             case SQLTokenizer.BIT_XOR: return BIT_XOR;
829             case SQLTokenizer.TILDE: return BIT_NOT;
830             default: return 0;
831         }
832     }
833     
834     
835     /**
836      * Returns the higher level data type from 2 expressions.
837      */

838     static int getDataType(Expression left, Expression right){
839         int typeLeft = left.getDataType();
840         int typeRight = right.getDataType();
841         return getDataType( typeLeft, typeRight);
842     }
843     
844
845     /**
846      * Return the best data type for a complex number operation. This method return only
847      * SQLTokenizer.INT,
848      * SQLTokenizer.BIGINT,
849      * SQLTokenizer.MONEY,
850      * SQLTokenizer.DECIMAL or
851      * SQLTokenizer.DOUBLE.
852      * @param paramDataType
853      */

854     static int getBestNumberDataType(int paramDataType){
855         int dataTypeIdx = Utils.indexOf( paramDataType, DatatypeRange);
856         if(dataTypeIdx >= NVARCHAR_IDX)
857             return SQLTokenizer.DOUBLE;
858         if(dataTypeIdx >= INT_IDX)
859             return SQLTokenizer.INT;
860         if(dataTypeIdx >= BIGINT_IDX)
861             return SQLTokenizer.BIGINT;
862         if(dataTypeIdx >= MONEY_IDX)
863             return SQLTokenizer.MONEY;
864         if(dataTypeIdx >= DECIMAL_IDX)
865             return SQLTokenizer.DECIMAL;
866         return SQLTokenizer.DOUBLE;
867     }
868     
869     /**
870      * Returns the higher level data type from 2 data types.
871      */

872     static int getDataType(int typeLeft, int typeRight){
873         if(typeLeft == typeRight) return typeLeft;
874
875         int dataTypeIdx = Math.min( Utils.indexOf( typeLeft, DatatypeRange), Utils.indexOf( typeRight, DatatypeRange) );
876         if(dataTypeIdx < 0) throw new Error JavaDoc("getDataType(): "+typeLeft+", "+typeRight);
877         return DatatypeRange[ dataTypeIdx ];
878     }
879     
880
881     // value decade is the operation order
882
static final int OR = 11; // OR
883
static final int AND = 21; // AND
884
static final int NOT = 31; // NOT
885
static final int BIT_OR = 41; // |
886
static final int BIT_AND = 42; // &
887
static final int BIT_XOR = 43; // ^
888
static final int EQUALS = 51; // =
889
static final int EQUALS_NULL= 52; // like Equals but (null = null) --> true
890
static final int GREATER = 53; // >
891
static final int GRE_EQU = 54; // >=
892
static final int LESSER = 55; // <
893
static final int LES_EQU = 56; // <=
894
static final int UNEQUALS = 57; // <>
895
static final int IN = 61; // IN
896
static final int BETWEEN = 62; // BETWEEN
897
static final int LIKE = 63; // LIKE
898
static final int ISNULL = 64; // IS NULL
899
static final int ISNOTNULL = ISNULL+1; // IS NOT NULL
900
static final int ADD = 71; // +
901
static final int SUB = 72; // -
902
static final int MUL = 81; // *
903
static final int DIV = 82; // /
904
static final int MOD = 83; // %
905
static final int BIT_NOT = 91; // ~
906
static final int NEGATIVE =101; // -
907

908     private static final int[] DatatypeRange = {
909         SQLTokenizer.TIMESTAMP,
910         SQLTokenizer.SMALLDATETIME,
911         SQLTokenizer.DATE,
912         SQLTokenizer.TIME,
913         SQLTokenizer.DOUBLE,
914         SQLTokenizer.FLOAT,
915         SQLTokenizer.REAL,
916         SQLTokenizer.DECIMAL,
917         SQLTokenizer.NUMERIC,
918         SQLTokenizer.MONEY,
919         SQLTokenizer.SMALLMONEY,
920         SQLTokenizer.BIGINT,
921         SQLTokenizer.INT,
922         SQLTokenizer.SMALLINT,
923         SQLTokenizer.TINYINT,
924         SQLTokenizer.BIT,
925         SQLTokenizer.BOOLEAN,
926         SQLTokenizer.LONGNVARCHAR,
927         SQLTokenizer.UNIQUEIDENTIFIER,
928         SQLTokenizer.NVARCHAR,
929         SQLTokenizer.NCHAR,
930         SQLTokenizer.VARCHAR,
931         SQLTokenizer.CHAR,
932         SQLTokenizer.LONGVARCHAR,
933         SQLTokenizer.CLOB,
934         SQLTokenizer.VARBINARY,
935         SQLTokenizer.BINARY,
936         SQLTokenizer.LONGVARBINARY,
937         SQLTokenizer.BLOB,
938         SQLTokenizer.NULL};
939
940     
941     private static int NVARCHAR_IDX = Utils.indexOf( SQLTokenizer.NVARCHAR, DatatypeRange);
942     private static int INT_IDX = Utils.indexOf( SQLTokenizer.INT, DatatypeRange);
943     private static int BIGINT_IDX = Utils.indexOf( SQLTokenizer.BIGINT, DatatypeRange);
944     private static int MONEY_IDX = Utils.indexOf( SQLTokenizer.MONEY, DatatypeRange);
945     private static int DECIMAL_IDX = Utils.indexOf( SQLTokenizer.DECIMAL, DatatypeRange);
946 }
Popular Tags