EMMA Coverage Report (generated Wed Jun 28 19:54:35 CEST 2006)
[all classes][smallsql.database]

COVERAGE SUMMARY FOR SOURCE FILE [ExpressionArithmetic.java]

nameclass, %method, %block, %line, %
ExpressionArithmetic.java100% (1/1)89%  (32/36)77%  (1783/2327)78%  (337/434)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class ExpressionArithmetic100% (1/1)89%  (32/36)77%  (1783/2327)78%  (337/434)
createUnspportedConversion (int): SQLException 0%   (0/1)0%   (0/36)0%   (0/6)
createUnspportedDataType (): SQLException 0%   (0/1)0%   (0/22)0%   (0/3)
getBytes (): byte [] 0%   (0/1)0%   (0/4)0%   (0/1)
getKeywordFromOperation (int): String 0%   (0/1)0%   (0/41)0%   (0/10)
getFloatImpl (): float 100% (1/1)21%  (11/52)25%  (2/8)
getMoneyImpl (): long 100% (1/1)33%  (16/48)43%  (3/7)
getLongImpl (): long 100% (1/1)34%  (22/64)36%  (3,6/10)
getObject (): Object 100% (1/1)46%  (50/109)48%  (10/21)
getMoney (): long 100% (1/1)47%  (21/45)56%  (5,6/10)
setParamAt (Expression, int): void 100% (1/1)51%  (18/35)73%  (7,3/10)
getDataType (int, int): int 100% (1/1)56%  (19/34)85%  (3,4/4)
getDouble (): double 100% (1/1)62%  (23/37)73%  (6,6/9)
getFloat (): float 100% (1/1)62%  (23/37)73%  (6,6/9)
getLong (): long 100% (1/1)62%  (23/37)73%  (6,6/9)
getInt (): int 100% (1/1)69%  (25/36)78%  (7/9)
getNumericImpl (): MutableNumeric 100% (1/1)72%  (96/134)72%  (23/32)
getNumeric (): MutableNumeric 100% (1/1)72%  (42/58)78%  (8,6/11)
getString (String, String): String 100% (1/1)75%  (12/16)67%  (2/3)
getString (): String 100% (1/1)78%  (7/9)80%  (1,6/2)
getOperationFromToken (int): int 100% (1/1)79%  (38/48)79%  (19/24)
equals (Object): boolean 100% (1/1)81%  (17/21)84%  (3,4/4)
getDataType (): int 100% (1/1)87%  (13/15)75%  (3/4)
getDoubleImpl (double, double): double 100% (1/1)87%  (26/30)88%  (7/8)
isInList (): boolean 100% (1/1)90%  (36/40)93%  (7,5/8)
isNull (): boolean 100% (1/1)90%  (19/21)75%  (3/4)
getBoolean (): boolean 100% (1/1)92%  (802/868)92%  (97,2/106)
getIntImpl (): int 100% (1/1)93%  (54/58)89%  (8/9)
getScale (): int 100% (1/1)96%  (43/45)89%  (8/9)
<static initializer> 100% (1/1)100% (144/144)100% (37/37)
ExpressionArithmetic (Expression, Expression, Expression, int): void 100% (1/1)100% (32/32)100% (7/7)
ExpressionArithmetic (Expression, Expression, int): void 100% (1/1)100% (25/25)100% (6/6)
ExpressionArithmetic (Expression, Expressions, int): void 100% (1/1)100% (47/47)100% (11/11)
ExpressionArithmetic (Expression, int): void 100% (1/1)100% (18/18)100% (5/5)
getBestNumberDataType (int): int 100% (1/1)100% (31/31)100% (12/12)
getDataType (Expression, Expression): int 100% (1/1)100% (10/10)100% (3/3)
getDoubleImpl (): double 100% (1/1)100% (20/20)100% (3/3)

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 */
33package smallsql.database;
34 
35import java.sql.*;
36 
37 
38public 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 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 {
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 {
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 {
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 {
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 {
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{
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{
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 {
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 {
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 {
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 {
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 {
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 {
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.signum = -num.signum;
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 getObject() throws java.lang.Exception {
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( getInt() );
437            case SQLTokenizer.BIGINT:
438                    return new Long( getLong() );
439            case SQLTokenizer.REAL:
440                    return new Float( getFloat() );
441            case SQLTokenizer.FLOAT:
442            case SQLTokenizer.DOUBLE:
443                    return new Double( 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 lObj = left.getObject();
459                    //FIXME NullPointerException bei NEGATIVE
460                    Object rObj = right.getObject();
461                    if(lObj instanceof Number && rObj instanceof Number)
462                        return new Double( getDoubleImpl( ((Number)lObj).doubleValue(), ((Number)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 {
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().signum != 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().signum != 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 getString() throws java.lang.Exception {
669        if(isNull()) return null;
670        return getObject().toString();
671    }
672    
673    
674    final private String getString( String lVal, String rVal ) throws java.lang.Exception {
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{
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 {
750        throw createUnspportedConversion( SQLTokenizer.BINARY );
751    }
752    
753    
754    boolean isInList() throws Exception{
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 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 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("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}

[all classes][smallsql.database]
EMMA 2.1.5320 (stable) (C) Vladimir Roubtsov