Source Code Cross Referenced for ExpressionArithmetic.java in  » Database-DBMS » smallsql » smallsql » database » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Database DBMS » smallsql » smallsql.database 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /* =============================================================
0002:         * SmallSQL : a free Java DBMS library for the Java(tm) platform
0003:         * =============================================================
0004:         *
0005:         * (C) Copyright 2004-2007, by Volker Berlin.
0006:         *
0007:         * Project Info:  http://www.smallsql.de/
0008:         *
0009:         * This library is free software; you can redistribute it and/or modify it 
0010:         * under the terms of the GNU Lesser General Public License as published by 
0011:         * the Free Software Foundation; either version 2.1 of the License, or 
0012:         * (at your option) any later version.
0013:         *
0014:         * This library is distributed in the hope that it will be useful, but 
0015:         * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
0016:         * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 
0017:         * License for more details.
0018:         *
0019:         * You should have received a copy of the GNU Lesser General Public
0020:         * License along with this library; if not, write to the Free Software
0021:         * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, 
0022:         * USA.  
0023:         *
0024:         * [Java is a trademark or registered trademark of Sun Microsystems, Inc. 
0025:         * in the United States and other countries.]
0026:         *
0027:         * ---------------
0028:         * ExpressionArithmethic.java
0029:         * ---------------
0030:         * Author: Volker Berlin
0031:         * 
0032:         */
0033:        package smallsql.database;
0034:
0035:        import java.sql.*;
0036:        import smallsql.database.language.Language;
0037:
0038:        public class ExpressionArithmetic extends Expression {
0039:
0040:            private Expression left;
0041:            private Expression right;
0042:            private Expression right2;
0043:            private Expression[] inList;
0044:            final private int operation;
0045:
0046:            /**
0047:             * Constructor for NOT, NEGATIVE, BIT_NOT, ISNULL and ISNOTNULL
0048:             */
0049:            ExpressionArithmetic(Expression left, int operation) {
0050:                super (FUNCTION);
0051:                this .left = left;
0052:                this .operation = operation;
0053:                super .setParams(new Expression[] { left });
0054:            }
0055:
0056:            ExpressionArithmetic(Expression left, Expression right,
0057:                    int operation) {
0058:                super (FUNCTION);
0059:                this .left = left;
0060:                this .right = right;
0061:                this .operation = operation;
0062:                super .setParams(new Expression[] { left, right });
0063:            }
0064:
0065:            /**
0066:             * Constructor for BETWEEN
0067:             */
0068:            ExpressionArithmetic(Expression left, Expression right,
0069:                    Expression right2, int operation) {
0070:                super (FUNCTION);
0071:                this .left = left;
0072:                this .right = right;
0073:                this .right2 = right2;
0074:                this .operation = operation;
0075:                super .setParams(new Expression[] { left, right, right2 });
0076:            }
0077:
0078:            /**
0079:             * Constructor for IN
0080:             */
0081:            ExpressionArithmetic(Expression left, Expressions inList,
0082:                    int operation) {
0083:                super (FUNCTION);
0084:                this .left = left;
0085:                this .operation = operation;
0086:                Expression[] params;
0087:                if (inList != null) {
0088:                    this .inList = inList.toArray();
0089:                    params = new Expression[this .inList.length + 1];
0090:                    params[0] = left;
0091:                    System.arraycopy(this .inList, 0, params, 1,
0092:                            this .inList.length);
0093:                } else {
0094:                    //Occur with ExpressionInSelect, in this case the method isInList() is overridden
0095:                    params = new Expression[] { left };
0096:                }
0097:                super .setParams(params);
0098:            }
0099:
0100:            /**
0101:             * Get the arithmetic operation of this expression.
0102:             * @return
0103:             */
0104:            int getOperation() {
0105:                return operation;
0106:            }
0107:
0108:            private Expression convertExpressionIfNeeded(Expression expr,
0109:                    Expression other) {
0110:                if (expr == null || other == null) {
0111:                    return expr;
0112:                }
0113:                switch (expr.getDataType()) {
0114:                case SQLTokenizer.CHAR:
0115:                case SQLTokenizer.NCHAR:
0116:                case SQLTokenizer.BINARY:
0117:                    switch (other.getDataType()) {
0118:                    case SQLTokenizer.VARCHAR:
0119:                    case SQLTokenizer.NVARCHAR:
0120:                    case SQLTokenizer.CLOB:
0121:                    case SQLTokenizer.NCLOB:
0122:                    case SQLTokenizer.LONGNVARCHAR:
0123:                    case SQLTokenizer.LONGVARCHAR:
0124:                    case SQLTokenizer.VARBINARY:
0125:                        ExpressionFunctionRTrim trim = new ExpressionFunctionRTrim();
0126:                        trim.setParams(new Expression[] { expr });
0127:                        return trim;
0128:                    case SQLTokenizer.CHAR:
0129:                    case SQLTokenizer.NCHAR:
0130:                    case SQLTokenizer.BINARY:
0131:                        if (other.getPrecision() > expr.getPrecision()) {
0132:                            return new ExpressionFunctionConvert(
0133:                                    new ColumnExpression(other), expr, null);
0134:                        }
0135:                        break;
0136:                    }
0137:                    break;
0138:                }
0139:                return expr;
0140:            }
0141:
0142:            final void setParamAt(Expression param, int idx) {
0143:                switch (idx) {
0144:                case 0:
0145:                    left = param;
0146:                    break;
0147:                case 1:
0148:                    if (right != null) {
0149:                        right = param;
0150:                    }
0151:                    break;
0152:                case 2:
0153:                    if (right != null) {
0154:                        right2 = param;
0155:                    }
0156:                    break;
0157:                }
0158:                if (inList != null && idx > 0 && idx <= inList.length) {
0159:                    inList[idx - 1] = param;
0160:                }
0161:                super .setParamAt(param, idx);
0162:            }
0163:
0164:            /**
0165:             * Is used in GroupResult.
0166:             */
0167:            public boolean equals(Object expr) {
0168:                if (!super .equals(expr))
0169:                    return false;
0170:                if (!(expr instanceof  ExpressionArithmetic))
0171:                    return false;
0172:                if (((ExpressionArithmetic) expr).operation != operation)
0173:                    return false;
0174:                return true;
0175:            }
0176:
0177:            int getInt() throws java.lang.Exception {
0178:                if (isNull())
0179:                    return 0;
0180:                int dataType = getDataType();
0181:                switch (dataType) {
0182:                case SQLTokenizer.BIT:
0183:                case SQLTokenizer.BOOLEAN:
0184:                    return getBoolean() ? 1 : 0;
0185:                case SQLTokenizer.TINYINT:
0186:                case SQLTokenizer.SMALLINT:
0187:                case SQLTokenizer.INT:
0188:                    return getIntImpl();
0189:                case SQLTokenizer.BIGINT:
0190:                    return (int) getLongImpl();
0191:                case SQLTokenizer.REAL:
0192:                    return (int) getFloatImpl();
0193:                case SQLTokenizer.FLOAT:
0194:                case SQLTokenizer.DOUBLE:
0195:                case SQLTokenizer.MONEY:
0196:                case SQLTokenizer.SMALLMONEY:
0197:                case SQLTokenizer.NUMERIC:
0198:                case SQLTokenizer.DECIMAL:
0199:                    // FIXME: bug! if get returns a number outside of
0200:                    // integer interval, it's not rounded to max/min, 
0201:                    // instead it returns a wrong value
0202:                    return (int) getDoubleImpl();
0203:                }
0204:                throw createUnspportedConversion(SQLTokenizer.INT);
0205:            }
0206:
0207:            private int getIntImpl() throws java.lang.Exception {
0208:                switch (operation) {
0209:                case ADD:
0210:                    return left.getInt() + right.getInt();
0211:                case SUB:
0212:                    return left.getInt() - right.getInt();
0213:                case MUL:
0214:                    return left.getInt() * right.getInt();
0215:                case DIV:
0216:                    return left.getInt() / right.getInt();
0217:                case NEGATIVE:
0218:                    return -left.getInt();
0219:                case MOD:
0220:                    return left.getInt() % right.getInt();
0221:                case BIT_NOT:
0222:                    return ~left.getInt();
0223:                }
0224:                throw createUnspportedConversion(SQLTokenizer.INT);
0225:            }
0226:
0227:            long getLong() throws java.lang.Exception {
0228:                if (isNull())
0229:                    return 0;
0230:                int dataType = getDataType();
0231:                switch (dataType) {
0232:                case SQLTokenizer.BIT:
0233:                case SQLTokenizer.BOOLEAN:
0234:                    return getBoolean() ? 1 : 0;
0235:                case SQLTokenizer.TINYINT:
0236:                case SQLTokenizer.SMALLINT:
0237:                case SQLTokenizer.INT:
0238:                    return getIntImpl();
0239:                case SQLTokenizer.BIGINT:
0240:                    return getLongImpl();
0241:                case SQLTokenizer.REAL:
0242:                    return (long) getFloatImpl();
0243:                case SQLTokenizer.FLOAT:
0244:                case SQLTokenizer.DOUBLE:
0245:                case SQLTokenizer.MONEY:
0246:                case SQLTokenizer.SMALLMONEY:
0247:                case SQLTokenizer.NUMERIC:
0248:                case SQLTokenizer.DECIMAL:
0249:                    return (long) getDoubleImpl();
0250:                }
0251:                throw createUnspportedConversion(SQLTokenizer.LONG);
0252:            }
0253:
0254:            private long getLongImpl() throws java.lang.Exception {
0255:                if (isNull())
0256:                    return 0;
0257:                switch (operation) {
0258:                case ADD:
0259:                    return left.getLong() + right.getLong();
0260:                case SUB:
0261:                    return left.getLong() - right.getLong();
0262:                case MUL:
0263:                    return left.getLong() * right.getLong();
0264:                case DIV:
0265:                    return left.getLong() / right.getLong();
0266:                case NEGATIVE:
0267:                    return -left.getLong();
0268:                case MOD:
0269:                    return left.getLong() % right.getLong();
0270:                case BIT_NOT:
0271:                    return ~right.getInt();
0272:                }
0273:                throw createUnspportedConversion(SQLTokenizer.LONG);
0274:            }
0275:
0276:            double getDouble() throws java.lang.Exception {
0277:                if (isNull())
0278:                    return 0;
0279:                int dataType = getDataType();
0280:                switch (dataType) {
0281:                case SQLTokenizer.BIT:
0282:                case SQLTokenizer.BOOLEAN:
0283:                    return getBoolean() ? 1 : 0;
0284:                case SQLTokenizer.TINYINT:
0285:                case SQLTokenizer.SMALLINT:
0286:                case SQLTokenizer.INT:
0287:                    return getIntImpl();
0288:                case SQLTokenizer.BIGINT:
0289:                    return getLongImpl();
0290:                case SQLTokenizer.REAL:
0291:                    return getFloatImpl();
0292:                case SQLTokenizer.FLOAT:
0293:                case SQLTokenizer.DOUBLE:
0294:                case SQLTokenizer.MONEY:
0295:                case SQLTokenizer.SMALLMONEY:
0296:                case SQLTokenizer.NUMERIC:
0297:                case SQLTokenizer.DECIMAL:
0298:                    return getDoubleImpl();
0299:                }
0300:                throw createUnspportedConversion(SQLTokenizer.DOUBLE);
0301:            }
0302:
0303:            private double getDoubleImpl() throws java.lang.Exception {
0304:                if (operation == NEGATIVE)
0305:                    return getDoubleImpl(0, left.getDouble());
0306:                return getDoubleImpl(left.getDouble(), right.getDouble());
0307:            }
0308:
0309:            private double getDoubleImpl(double lVal, double rVal)
0310:                    throws java.lang.Exception {
0311:                switch (operation) {
0312:                case ADD:
0313:                    return lVal + rVal;
0314:                case SUB:
0315:                    return lVal - rVal;
0316:                case MUL:
0317:                    return lVal * rVal;
0318:                case DIV:
0319:                    return lVal / rVal;
0320:                case NEGATIVE:
0321:                    return -rVal;
0322:                case MOD:
0323:                    return lVal % rVal;
0324:                }
0325:                throw createUnspportedConversion(SQLTokenizer.DOUBLE);
0326:            }
0327:
0328:            float getFloat() throws java.lang.Exception {
0329:                if (isNull())
0330:                    return 0;
0331:                int dataType = getDataType();
0332:                switch (dataType) {
0333:                case SQLTokenizer.BIT:
0334:                case SQLTokenizer.BOOLEAN:
0335:                    return getBoolean() ? 1 : 0;
0336:                case SQLTokenizer.TINYINT:
0337:                case SQLTokenizer.SMALLINT:
0338:                case SQLTokenizer.INT:
0339:                    return getIntImpl();
0340:                case SQLTokenizer.BIGINT:
0341:                    return getLongImpl();
0342:                case SQLTokenizer.REAL:
0343:                    return getFloatImpl();
0344:                case SQLTokenizer.FLOAT:
0345:                case SQLTokenizer.DOUBLE:
0346:                case SQLTokenizer.MONEY:
0347:                case SQLTokenizer.SMALLMONEY:
0348:                case SQLTokenizer.NUMERIC:
0349:                case SQLTokenizer.DECIMAL:
0350:                    return (float) getDoubleImpl();
0351:                }
0352:                throw createUnspportedConversion(SQLTokenizer.DOUBLE);
0353:            }
0354:
0355:            private float getFloatImpl() throws java.lang.Exception {
0356:                switch (operation) {
0357:                case ADD:
0358:                    return left.getFloat() + right.getFloat();
0359:                case SUB:
0360:                    return left.getFloat() - right.getFloat();
0361:                case MUL:
0362:                    return left.getFloat() * right.getFloat();
0363:                case DIV:
0364:                    return left.getFloat() / right.getFloat();
0365:                case NEGATIVE:
0366:                    return -left.getFloat();
0367:                case MOD:
0368:                    return left.getFloat() % right.getFloat();
0369:                }
0370:                throw createUnspportedConversion(SQLTokenizer.REAL);
0371:            }
0372:
0373:            long getMoney() throws java.lang.Exception {
0374:                if (isNull())
0375:                    return 0;
0376:                int dataType = getDataType();
0377:                switch (dataType) {
0378:                case SQLTokenizer.BIT:
0379:                case SQLTokenizer.BOOLEAN:
0380:                    return getBoolean() ? 10000 : 0;
0381:                case SQLTokenizer.TINYINT:
0382:                case SQLTokenizer.SMALLINT:
0383:                case SQLTokenizer.INT:
0384:                    return getIntImpl() * 10000;
0385:                case SQLTokenizer.BIGINT:
0386:                    return getLongImpl() * 10000;
0387:                case SQLTokenizer.REAL:
0388:                    return Utils.doubleToMoney(getFloatImpl());
0389:                case SQLTokenizer.FLOAT:
0390:                case SQLTokenizer.DOUBLE:
0391:                case SQLTokenizer.NUMERIC:
0392:                case SQLTokenizer.DECIMAL:
0393:                    return Utils.doubleToMoney(getDoubleImpl());
0394:                case SQLTokenizer.MONEY:
0395:                case SQLTokenizer.SMALLMONEY:
0396:                    return getMoneyImpl();
0397:                }
0398:                throw createUnspportedConversion(SQLTokenizer.DOUBLE);
0399:            }
0400:
0401:            private long getMoneyImpl() throws java.lang.Exception {
0402:                switch (operation) {
0403:                case ADD:
0404:                    return left.getMoney() + right.getMoney();
0405:                case SUB:
0406:                    return left.getMoney() - right.getMoney();
0407:                case MUL:
0408:                    return left.getMoney() * right.getMoney() / 10000;
0409:                case DIV:
0410:                    return left.getMoney() * 10000 / right.getMoney();
0411:                case NEGATIVE:
0412:                    return -left.getMoney();
0413:                }
0414:                throw createUnspportedConversion(SQLTokenizer.MONEY);
0415:            }
0416:
0417:            MutableNumeric getNumeric() throws java.lang.Exception {
0418:                if (isNull())
0419:                    return null;
0420:                int dataType = getDataType();
0421:                switch (dataType) {
0422:                case SQLTokenizer.BIT:
0423:                case SQLTokenizer.BOOLEAN:
0424:                    return new MutableNumeric(getBoolean() ? 1 : 0);
0425:                case SQLTokenizer.TINYINT:
0426:                case SQLTokenizer.SMALLINT:
0427:                case SQLTokenizer.INT:
0428:                    return new MutableNumeric(getIntImpl());
0429:                case SQLTokenizer.BIGINT:
0430:                    return new MutableNumeric(getLongImpl());
0431:                case SQLTokenizer.REAL:
0432:                    return new MutableNumeric(getFloatImpl());
0433:                case SQLTokenizer.FLOAT:
0434:                case SQLTokenizer.DOUBLE:
0435:                    return new MutableNumeric(getDoubleImpl());
0436:                case SQLTokenizer.NUMERIC:
0437:                case SQLTokenizer.DECIMAL:
0438:                    return getNumericImpl();
0439:                case SQLTokenizer.MONEY:
0440:                case SQLTokenizer.SMALLMONEY:
0441:                    return new MutableNumeric(getMoneyImpl(), 4);
0442:                }
0443:                throw createUnspportedConversion(SQLTokenizer.DOUBLE);
0444:            }
0445:
0446:            private MutableNumeric getNumericImpl() throws java.lang.Exception {
0447:                switch (operation) {
0448:                case ADD: {
0449:                    MutableNumeric num = left.getNumeric();
0450:                    num.add(right.getNumeric());
0451:                    return num;
0452:                }
0453:                case SUB: {
0454:                    MutableNumeric num = left.getNumeric();
0455:                    num.sub(right.getNumeric());
0456:                    return num;
0457:                }
0458:                case MUL:
0459:                    if (getDataType(right.getDataType(), SQLTokenizer.INT) == SQLTokenizer.INT) {
0460:                        MutableNumeric num = left.getNumeric();
0461:                        num.mul(right.getInt());
0462:                        return num;
0463:                    } else if (getDataType(left.getDataType(), SQLTokenizer.INT) == SQLTokenizer.INT) {
0464:                        MutableNumeric num = right.getNumeric();
0465:                        num.mul(left.getInt());
0466:                        return num;
0467:                    } else {
0468:                        MutableNumeric num = left.getNumeric();
0469:                        num.mul(right.getNumeric());
0470:                        return num;
0471:                    }
0472:                case DIV: {
0473:                    MutableNumeric num = left.getNumeric();
0474:                    if (getDataType(right.getDataType(), SQLTokenizer.INT) == SQLTokenizer.INT)
0475:                        num.div(right.getInt());
0476:                    else
0477:                        num.div(right.getNumeric());
0478:                    return num;
0479:                }
0480:                case NEGATIVE: {
0481:                    MutableNumeric num = left.getNumeric();
0482:                    num.setSignum(-num.getSignum());
0483:                    return num;
0484:                }
0485:                case MOD: {
0486:                    if (getDataType(getDataType(), SQLTokenizer.INT) == SQLTokenizer.INT)
0487:                        return new MutableNumeric(getInt());
0488:                    MutableNumeric num = left.getNumeric();
0489:                    num.mod(right.getNumeric());
0490:                    return num;
0491:                }
0492:                default:
0493:                    throw createUnspportedConversion(SQLTokenizer.NUMERIC);
0494:                }
0495:            }
0496:
0497:            Object getObject() throws java.lang.Exception {
0498:                if (isNull())
0499:                    return null;
0500:                int dataType = getDataType();
0501:                switch (dataType) {
0502:                case SQLTokenizer.BIT:
0503:                case SQLTokenizer.BOOLEAN:
0504:                    return getBoolean() ? Boolean.TRUE : Boolean.FALSE;
0505:                case SQLTokenizer.BINARY:
0506:                case SQLTokenizer.VARBINARY:
0507:                    return getBytes();
0508:                case SQLTokenizer.TINYINT:
0509:                case SQLTokenizer.SMALLINT:
0510:                case SQLTokenizer.INT:
0511:                    return new Integer(getInt());
0512:                case SQLTokenizer.BIGINT:
0513:                    return new Long(getLong());
0514:                case SQLTokenizer.REAL:
0515:                    return new Float(getFloat());
0516:                case SQLTokenizer.FLOAT:
0517:                case SQLTokenizer.DOUBLE:
0518:                    return new Double(getDouble());
0519:                case SQLTokenizer.MONEY:
0520:                case SQLTokenizer.SMALLMONEY:
0521:                    return Money.createFromUnscaledValue(getMoney());
0522:                case SQLTokenizer.NUMERIC:
0523:                case SQLTokenizer.DECIMAL:
0524:                    return getNumeric();
0525:                case SQLTokenizer.CHAR:
0526:                case SQLTokenizer.NCHAR:
0527:                case SQLTokenizer.VARCHAR:
0528:                case SQLTokenizer.NVARCHAR:
0529:                case SQLTokenizer.LONGNVARCHAR:
0530:                case SQLTokenizer.LONGVARCHAR:
0531:                    return getString(left.getString(), right.getString());
0532:                case SQLTokenizer.JAVA_OBJECT:
0533:                    Object lObj = left.getObject();
0534:                    //FIXME NullPointerException bei NEGATIVE
0535:                    Object rObj = right.getObject();
0536:                    if (lObj instanceof  Number && rObj instanceof  Number)
0537:                        return new Double(getDoubleImpl(((Number) lObj)
0538:                                .doubleValue(), ((Number) rObj).doubleValue()));
0539:                    else
0540:                        return getString(lObj.toString(), rObj.toString());
0541:                case SQLTokenizer.LONGVARBINARY:
0542:                    return getBytes();
0543:                case SQLTokenizer.DATE:
0544:                case SQLTokenizer.TIME:
0545:                case SQLTokenizer.TIMESTAMP:
0546:                case SQLTokenizer.SMALLDATETIME:
0547:                    return new DateTime(getLong(), dataType);
0548:                case SQLTokenizer.UNIQUEIDENTIFIER:
0549:                    return getBytes();
0550:                default:
0551:                    throw createUnspportedDataType();
0552:                }
0553:            }
0554:
0555:            boolean getBoolean() throws java.lang.Exception {
0556:                switch (operation) {
0557:                case OR:
0558:                    return left.getBoolean() || right.getBoolean();
0559:                case AND:
0560:                    return left.getBoolean() && right.getBoolean();
0561:                case NOT:
0562:                    return !left.getBoolean();
0563:                case LIKE:
0564:                    return Utils.like(left.getString(), right.getString());
0565:                case ISNULL:
0566:                    return left.isNull();
0567:                case ISNOTNULL:
0568:                    return !left.isNull();
0569:                case IN:
0570:                    if (right == null)
0571:                        return isInList();
0572:                    break;
0573:                }
0574:                final boolean leftIsNull = left.isNull();
0575:                int dataType;
0576:                if (operation == NEGATIVE || operation == BIT_NOT) {
0577:                    if (leftIsNull)
0578:                        return false;
0579:                    dataType = left.getDataType();
0580:                } else {
0581:                    final boolean rightIsNull = right.isNull();
0582:                    if (operation == EQUALS_NULL && leftIsNull && rightIsNull)
0583:                        return true;
0584:                    if (leftIsNull || rightIsNull)
0585:                        return false;
0586:                    dataType = getDataType(left, right);
0587:                }
0588:                switch (dataType) {
0589:                case SQLTokenizer.BOOLEAN:
0590:                    switch (operation) {
0591:                    case IN:
0592:                    case EQUALS_NULL:
0593:                    case EQUALS:
0594:                        return left.getBoolean() == right.getBoolean();
0595:                    case UNEQUALS:
0596:                        return left.getBoolean() != right.getBoolean();
0597:                    }
0598:                    //break; interpret it as BIT 
0599:                case SQLTokenizer.TINYINT:
0600:                case SQLTokenizer.SMALLINT:
0601:                case SQLTokenizer.INT:
0602:                case SQLTokenizer.BIT:
0603:                    switch (operation) {
0604:                    case IN:
0605:                    case EQUALS_NULL:
0606:                    case EQUALS:
0607:                        return left.getInt() == right.getInt();
0608:                    case GREATER:
0609:                        return left.getInt() > right.getInt();
0610:                    case GRE_EQU:
0611:                        return left.getInt() >= right.getInt();
0612:                    case LESSER:
0613:                        return left.getInt() < right.getInt();
0614:                    case LES_EQU:
0615:                        return left.getInt() <= right.getInt();
0616:                    case UNEQUALS:
0617:                        return left.getInt() != right.getInt();
0618:                    case BETWEEN:
0619:                        int _left = left.getInt();
0620:                        return _left >= right.getInt()
0621:                                && right2.getInt() >= _left;
0622:                    default:
0623:                        return getInt() != 0;
0624:                    }
0625:                case SQLTokenizer.BIGINT:
0626:                case SQLTokenizer.TIMESTAMP:
0627:                case SQLTokenizer.TIME:
0628:                case SQLTokenizer.DATE:
0629:                case SQLTokenizer.SMALLDATETIME:
0630:                    switch (operation) {
0631:                    case IN:
0632:                    case EQUALS_NULL:
0633:                    case EQUALS:
0634:                        return left.getLong() == right.getLong();
0635:                    case GREATER:
0636:                        return left.getLong() > right.getLong();
0637:                    case GRE_EQU:
0638:                        return left.getLong() >= right.getLong();
0639:                    case LESSER:
0640:                        return left.getLong() < right.getLong();
0641:                    case LES_EQU:
0642:                        return left.getLong() <= right.getLong();
0643:                    case UNEQUALS:
0644:                        return left.getLong() != right.getLong();
0645:                    case BETWEEN:
0646:                        long _left = left.getLong();
0647:                        return _left >= right.getLong()
0648:                                && right2.getLong() >= _left;
0649:                    default:
0650:                        return getLong() != 0;
0651:                    }
0652:                case SQLTokenizer.REAL:
0653:                    switch (operation) {
0654:                    case IN:
0655:                    case EQUALS_NULL:
0656:                    case EQUALS:
0657:                        return left.getFloat() == right.getFloat();
0658:                    case GREATER:
0659:                        return left.getFloat() > right.getFloat();
0660:                    case GRE_EQU:
0661:                        return left.getFloat() >= right.getFloat();
0662:                    case LESSER:
0663:                        return left.getFloat() < right.getFloat();
0664:                    case LES_EQU:
0665:                        return left.getFloat() <= right.getFloat();
0666:                    case UNEQUALS:
0667:                        return left.getFloat() != right.getFloat();
0668:                    case BETWEEN:
0669:                        float _left = left.getFloat();
0670:                        return _left >= right.getFloat()
0671:                                && right2.getFloat() >= _left;
0672:                    default:
0673:                        return getFloat() != 0;
0674:                    }
0675:                case SQLTokenizer.FLOAT:
0676:                case SQLTokenizer.DOUBLE:
0677:                    switch (operation) {
0678:                    case IN:
0679:                    case EQUALS_NULL:
0680:                    case EQUALS:
0681:                        return left.getDouble() == right.getDouble();
0682:                    case GREATER:
0683:                        return left.getDouble() > right.getDouble();
0684:                    case GRE_EQU:
0685:                        return left.getDouble() >= right.getDouble();
0686:                    case LESSER:
0687:                        return left.getDouble() < right.getDouble();
0688:                    case LES_EQU:
0689:                        return left.getDouble() <= right.getDouble();
0690:                    case UNEQUALS:
0691:                        return left.getDouble() != right.getDouble();
0692:                    case BETWEEN:
0693:                        double _left = left.getDouble();
0694:                        return _left >= right.getDouble()
0695:                                && right2.getDouble() >= _left;
0696:                    default:
0697:                        return getDouble() != 0;
0698:                    }
0699:                case SQLTokenizer.MONEY:
0700:                case SQLTokenizer.SMALLMONEY:
0701:                    switch (operation) {
0702:                    case IN:
0703:                    case EQUALS_NULL:
0704:                    case EQUALS:
0705:                        return left.getMoney() == right.getMoney();
0706:                    case GREATER:
0707:                        return left.getMoney() > right.getMoney();
0708:                    case GRE_EQU:
0709:                        return left.getMoney() >= right.getMoney();
0710:                    case LESSER:
0711:                        return left.getMoney() < right.getMoney();
0712:                    case LES_EQU:
0713:                        return left.getMoney() <= right.getMoney();
0714:                    case UNEQUALS:
0715:                        return left.getMoney() != right.getMoney();
0716:                    case BETWEEN:
0717:                        long _left = left.getMoney();
0718:                        return _left >= right.getMoney()
0719:                                && right2.getMoney() >= _left;
0720:                    default:
0721:                        return getMoney() != 0;
0722:                    }
0723:                case SQLTokenizer.DECIMAL:
0724:                case SQLTokenizer.NUMERIC: {
0725:                    if (operation == NEGATIVE)
0726:                        return left.getNumeric().getSignum() != 0;
0727:                    int comp = left.getNumeric().compareTo(right.getNumeric());
0728:                    switch (operation) {
0729:                    case IN:
0730:                    case EQUALS_NULL:
0731:                    case EQUALS:
0732:                        return comp == 0;
0733:                    case GREATER:
0734:                        return comp > 0;
0735:                    case GRE_EQU:
0736:                        return comp >= 0;
0737:                    case LESSER:
0738:                        return comp < 0;
0739:                    case LES_EQU:
0740:                        return comp <= 0;
0741:                    case UNEQUALS:
0742:                        return comp != 0;
0743:                    case BETWEEN:
0744:                        return comp >= 0
0745:                                && 0 >= left.getNumeric().compareTo(
0746:                                        right2.getNumeric());
0747:                    default:
0748:                        return getNumeric().getSignum() != 0;
0749:                    }
0750:                }
0751:                case SQLTokenizer.VARCHAR:
0752:                case SQLTokenizer.NVARCHAR:
0753:                case SQLTokenizer.CHAR:
0754:                case SQLTokenizer.NCHAR:
0755:                case SQLTokenizer.LONGVARCHAR:
0756:                case SQLTokenizer.LONGNVARCHAR:
0757:                case SQLTokenizer.CLOB: {
0758:                    final String leftStr = left.getString();
0759:                    final String rightStr = right.getString();
0760:                    int comp = String.CASE_INSENSITIVE_ORDER.compare(leftStr,
0761:                            rightStr);
0762:                    switch (operation) {
0763:                    case IN:
0764:                    case EQUALS_NULL:
0765:                    case EQUALS:
0766:                        return comp == 0;
0767:                    case GREATER:
0768:                        return comp > 0;
0769:                    case GRE_EQU:
0770:                        return comp >= 0;
0771:                    case LESSER:
0772:                        return comp < 0;
0773:                    case LES_EQU:
0774:                        return comp <= 0;
0775:                    case UNEQUALS:
0776:                        return comp != 0;
0777:                    case BETWEEN:
0778:                        return comp >= 0
0779:                                && 0 >= String.CASE_INSENSITIVE_ORDER.compare(
0780:                                        leftStr, right2.getString());
0781:                    case ADD:
0782:                        return Utils.string2boolean(leftStr + rightStr);
0783:                    }
0784:                    break;
0785:                }
0786:                case SQLTokenizer.BINARY:
0787:                case SQLTokenizer.VARBINARY:
0788:                case SQLTokenizer.LONGVARBINARY:
0789:                case SQLTokenizer.BLOB:
0790:                case SQLTokenizer.UNIQUEIDENTIFIER: {
0791:                    byte[] leftBytes = left.getBytes();
0792:                    byte[] rightBytes = right.getBytes();
0793:                    int comp = Utils.compareBytes(leftBytes, rightBytes);
0794:                    switch (operation) {
0795:                    case IN:
0796:                    case EQUALS_NULL:
0797:                    case EQUALS:
0798:                        return comp == 0;
0799:                    case GREATER:
0800:                        return comp > 0;
0801:                    case GRE_EQU:
0802:                        return comp >= 0;
0803:                    case LESSER:
0804:                        return comp < 0;
0805:                    case LES_EQU:
0806:                        return comp <= 0;
0807:                    case UNEQUALS:
0808:                        return comp != 0;
0809:                    case BETWEEN:
0810:                        return comp >= 0
0811:                                && 0 >= Utils.compareBytes(leftBytes, right2
0812:                                        .getBytes());
0813:                    }
0814:                    break;
0815:                }
0816:                }
0817:                throw createUnspportedDataType();
0818:            }
0819:
0820:            String getString() throws java.lang.Exception {
0821:                if (isNull())
0822:                    return null;
0823:                return getObject().toString();
0824:            }
0825:
0826:            final private String getString(String lVal, String rVal)
0827:                    throws java.lang.Exception {
0828:                switch (operation) {
0829:                case ADD:
0830:                    return lVal + rVal;
0831:                }
0832:                throw createUnspportedConversion(SQLTokenizer.VARCHAR);
0833:            }
0834:
0835:            int getDataType() {
0836:                switch (operation) {
0837:                case NEGATIVE:
0838:                case BIT_NOT:
0839:                    return left.getDataType();
0840:                case EQUALS:
0841:                case EQUALS_NULL:
0842:                case GREATER:
0843:                case GRE_EQU:
0844:                case LESSER:
0845:                case LES_EQU:
0846:                case UNEQUALS:
0847:                case BETWEEN:
0848:                case OR:
0849:                case AND:
0850:                case NOT:
0851:                case LIKE:
0852:                case ISNULL:
0853:                case ISNOTNULL:
0854:                    return SQLTokenizer.BOOLEAN;
0855:                default:
0856:                    return getDataType(left, right);
0857:                }
0858:            }
0859:
0860:            int getScale() {
0861:                int dataType = getDataType();
0862:                switch (dataType) {
0863:                case SQLTokenizer.DECIMAL:
0864:                case SQLTokenizer.NUMERIC:
0865:                    switch (operation) {
0866:                    case ADD:
0867:                    case SUB:
0868:                        return Math.max(left.getScale(), right.getScale());
0869:                    case MUL:
0870:                        return left.getScale() + right.getScale();
0871:                    case DIV:
0872:                        return Math.max(left.getScale() + 5,
0873:                                right.getScale() + 4);
0874:                    case NEGATIVE:
0875:                        return left.getScale();
0876:                    case MOD:
0877:                        return 0;
0878:                    }
0879:                }
0880:                return getScale(dataType);
0881:            }
0882:
0883:            boolean isNull() throws Exception {
0884:                switch (operation) {
0885:                case OR:
0886:                case AND:
0887:                case NOT:
0888:                case LIKE:
0889:                case ISNULL:
0890:                case ISNOTNULL:
0891:                case IN:
0892:                    return false; //Boolean operations return ever a result ???, but at least ISNULL and ISNOTNULL
0893:                case NEGATIVE:
0894:                case BIT_NOT:
0895:                    return left.isNull();
0896:                default:
0897:                    return left.isNull() || right.isNull();
0898:                }
0899:            }
0900:
0901:            byte[] getBytes() throws java.lang.Exception {
0902:                throw createUnspportedConversion(SQLTokenizer.BINARY);
0903:            }
0904:
0905:            boolean isInList() throws Exception {
0906:                if (left.isNull())
0907:                    return false;
0908:                try {
0909:                    for (int i = 0; i < inList.length; i++) {
0910:                        right = inList[i];
0911:                        if (getBoolean())
0912:                            return true;
0913:                    }
0914:                } finally {
0915:                    right = null;
0916:                }
0917:                return false;
0918:            }
0919:
0920:            SQLException createUnspportedDataType() {
0921:                Object[] params = {
0922:                        SQLTokenizer.getKeyWord(getDataType(left, right)),
0923:                        getKeywordFromOperation(operation) };
0924:                return SmallSQLException.create(
0925:                        Language.UNSUPPORTED_DATATYPE_OPER, params);
0926:            }
0927:
0928:            SQLException createUnspportedConversion(int dataType) {
0929:                int type = left == null ? right.getDataType() : getDataType(
0930:                        left, right);
0931:                Object[] params = new Object[] {
0932:                        SQLTokenizer.getKeyWord(dataType),
0933:                        SQLTokenizer.getKeyWord(type),
0934:                        getKeywordFromOperation(operation) };
0935:                return SmallSQLException.create(
0936:                        Language.UNSUPPORTED_CONVERSION_OPER, params);
0937:            }
0938:
0939:            void optimize() throws SQLException {
0940:                super .optimize();
0941:                Expression[] params = getParams();
0942:                if (params.length == 1) {
0943:                    return;
0944:                }
0945:                setParamAt(convertExpressionIfNeeded(params[0], params[1]), 0);
0946:
0947:                for (int p = 1; p < params.length; p++) {
0948:                    setParamAt(convertExpressionIfNeeded(params[p], left), p);
0949:                }
0950:            }
0951:
0952:            /**
0953:             * This method only for creating an error message. Thats there is no optimizing.
0954:             * @param value
0955:             * @return
0956:             */
0957:            private static String getKeywordFromOperation(int operation) {
0958:                int token = 0;
0959:                for (int i = 1; i < 1000; i++) {
0960:                    if (getOperationFromToken(i) == operation) {
0961:                        token = i;
0962:                        break;
0963:                    }
0964:                }
0965:                if (operation == NEGATIVE)
0966:                    token = SQLTokenizer.MINUS;
0967:                if (operation == ISNOTNULL)
0968:                    token = SQLTokenizer.IS;
0969:                String keyword = SQLTokenizer.getKeyWord(token);
0970:                if (keyword == null)
0971:                    keyword = "" + (char) token;
0972:                return keyword;
0973:            }
0974:
0975:            static int getOperationFromToken(int value) {
0976:                switch (value) {
0977:                case SQLTokenizer.PLUS:
0978:                    return ADD;
0979:                case SQLTokenizer.MINUS:
0980:                    return SUB;
0981:                case SQLTokenizer.ASTERISK:
0982:                    return MUL;
0983:                case SQLTokenizer.SLACH:
0984:                    return DIV;
0985:                case SQLTokenizer.PERCENT:
0986:                    return MOD;
0987:                case SQLTokenizer.EQUALS:
0988:                    return EQUALS;
0989:                case SQLTokenizer.GREATER:
0990:                    return GREATER;
0991:                case SQLTokenizer.GREATER_EQU:
0992:                    return GRE_EQU;
0993:                case SQLTokenizer.LESSER:
0994:                    return LESSER;
0995:                case SQLTokenizer.LESSER_EQU:
0996:                    return LES_EQU;
0997:                case SQLTokenizer.UNEQUALS:
0998:                    return UNEQUALS;
0999:                case SQLTokenizer.BETWEEN:
1000:                    return BETWEEN;
1001:                case SQLTokenizer.LIKE:
1002:                    return LIKE;
1003:                case SQLTokenizer.IN:
1004:                    return IN;
1005:                case SQLTokenizer.IS:
1006:                    return ISNULL;
1007:                case SQLTokenizer.OR:
1008:                    return OR;
1009:                case SQLTokenizer.AND:
1010:                    return AND;
1011:                case SQLTokenizer.NOT:
1012:                    return NOT;
1013:                case SQLTokenizer.BIT_OR:
1014:                    return BIT_OR;
1015:                case SQLTokenizer.BIT_AND:
1016:                    return BIT_AND;
1017:                case SQLTokenizer.BIT_XOR:
1018:                    return BIT_XOR;
1019:                case SQLTokenizer.TILDE:
1020:                    return BIT_NOT;
1021:                default:
1022:                    return 0;
1023:                }
1024:            }
1025:
1026:            /**
1027:             * Returns the higher level data type from 2 expressions. 
1028:             */
1029:            static int getDataType(Expression left, Expression right) {
1030:                int typeLeft = left.getDataType();
1031:                int typeRight = right.getDataType();
1032:                return getDataType(typeLeft, typeRight);
1033:            }
1034:
1035:            /**
1036:             * Return the best data type for a complex number operation. This method return only 
1037:             * SQLTokenizer.INT,
1038:             * SQLTokenizer.BIGINT,
1039:             * SQLTokenizer.MONEY,
1040:             * SQLTokenizer.DECIMAL or
1041:             * SQLTokenizer.DOUBLE.
1042:             * @param paramDataType
1043:             */
1044:            static int getBestNumberDataType(int paramDataType) {
1045:                int dataTypeIdx = Utils.indexOf(paramDataType, DatatypeRange);
1046:                if (dataTypeIdx >= NVARCHAR_IDX)
1047:                    return SQLTokenizer.DOUBLE;
1048:                if (dataTypeIdx >= INT_IDX)
1049:                    return SQLTokenizer.INT;
1050:                if (dataTypeIdx >= BIGINT_IDX)
1051:                    return SQLTokenizer.BIGINT;
1052:                if (dataTypeIdx >= MONEY_IDX)
1053:                    return SQLTokenizer.MONEY;
1054:                if (dataTypeIdx >= DECIMAL_IDX)
1055:                    return SQLTokenizer.DECIMAL;
1056:                return SQLTokenizer.DOUBLE;
1057:            }
1058:
1059:            /**
1060:             * Returns the higher level data type from 2 data types. 
1061:             */
1062:            static int getDataType(int typeLeft, int typeRight) {
1063:                if (typeLeft == typeRight)
1064:                    return typeLeft;
1065:
1066:                int dataTypeIdx = Math
1067:                        .min(Utils.indexOf(typeLeft, DatatypeRange), Utils
1068:                                .indexOf(typeRight, DatatypeRange));
1069:                if (dataTypeIdx < 0)
1070:                    throw new Error("getDataType(): " + typeLeft + ", "
1071:                            + typeRight);
1072:                return DatatypeRange[dataTypeIdx];
1073:            }
1074:
1075:            // value decade is the operation order
1076:            static final int OR = 11; // OR
1077:            static final int AND = 21; // AND
1078:            static final int NOT = 31; // NOT
1079:            static final int BIT_OR = 41; // |
1080:            static final int BIT_AND = 42; // &
1081:            static final int BIT_XOR = 43; // ^
1082:            static final int EQUALS = 51; // =
1083:            static final int EQUALS_NULL = 52; // like Equals but (null = null) --> true 
1084:            static final int GREATER = 53; // >
1085:            static final int GRE_EQU = 54; // >=
1086:            static final int LESSER = 55; // <
1087:            static final int LES_EQU = 56; // <=
1088:            static final int UNEQUALS = 57; // <>
1089:            static final int IN = 61; // IN
1090:            static final int BETWEEN = 62; // BETWEEN
1091:            static final int LIKE = 63; // LIKE
1092:            static final int ISNULL = 64; // IS NULL
1093:            static final int ISNOTNULL = ISNULL + 1; // IS NOT NULL 
1094:            static final int ADD = 71; // +
1095:            static final int SUB = 72; // -
1096:            static final int MUL = 81; // *
1097:            static final int DIV = 82; // /
1098:            static final int MOD = 83; // %
1099:            static final int BIT_NOT = 91; // ~
1100:            static final int NEGATIVE = 101; // -
1101:
1102:            private static final int[] DatatypeRange = {
1103:                    SQLTokenizer.TIMESTAMP, SQLTokenizer.SMALLDATETIME,
1104:                    SQLTokenizer.DATE, SQLTokenizer.TIME, SQLTokenizer.DOUBLE,
1105:                    SQLTokenizer.FLOAT, SQLTokenizer.REAL,
1106:                    SQLTokenizer.DECIMAL, SQLTokenizer.NUMERIC,
1107:                    SQLTokenizer.MONEY, SQLTokenizer.SMALLMONEY,
1108:                    SQLTokenizer.BIGINT, SQLTokenizer.INT,
1109:                    SQLTokenizer.SMALLINT, SQLTokenizer.TINYINT,
1110:                    SQLTokenizer.BIT, SQLTokenizer.BOOLEAN,
1111:                    SQLTokenizer.LONGNVARCHAR, SQLTokenizer.UNIQUEIDENTIFIER,
1112:                    SQLTokenizer.NVARCHAR, SQLTokenizer.NCHAR,
1113:                    SQLTokenizer.VARCHAR, SQLTokenizer.CHAR,
1114:                    SQLTokenizer.LONGVARCHAR, SQLTokenizer.CLOB,
1115:                    SQLTokenizer.VARBINARY, SQLTokenizer.BINARY,
1116:                    SQLTokenizer.LONGVARBINARY, SQLTokenizer.BLOB,
1117:                    SQLTokenizer.NULL };
1118:
1119:            private static int NVARCHAR_IDX = Utils.indexOf(
1120:                    SQLTokenizer.NVARCHAR, DatatypeRange);
1121:            private static int INT_IDX = Utils.indexOf(SQLTokenizer.INT,
1122:                    DatatypeRange);
1123:            private static int BIGINT_IDX = Utils.indexOf(SQLTokenizer.BIGINT,
1124:                    DatatypeRange);
1125:            private static int MONEY_IDX = Utils.indexOf(SQLTokenizer.MONEY,
1126:                    DatatypeRange);
1127:            private static int DECIMAL_IDX = Utils.indexOf(
1128:                    SQLTokenizer.DECIMAL, DatatypeRange);
1129:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.