001: /*
002: * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved
003: *
004: * This file is part of Resin(R) Open Source
005: *
006: * Each copy or derived work must preserve the copyright notice and this
007: * notice unmodified.
008: *
009: * Resin Open Source is free software; you can redistribute it and/or modify
010: * it under the terms of the GNU General Public License as published by
011: * the Free Software Foundation; either version 2 of the License, or
012: * (at your option) any later version.
013: *
014: * Resin Open Source is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
017: * of NON-INFRINGEMENT. See the GNU General Public License for more
018: * details.
019: *
020: * You should have received a copy of the GNU General Public License
021: * along with Resin Open Source; if not, write to the
022: *
023: * Free Software Foundation, Inc.
024: * 59 Temple Place, Suite 330
025: * Boston, MA 02111-1307 USA
026: *
027: * @author Scott Ferguson
028: */
029:
030: package com.caucho.db.sql;
031:
032: import com.caucho.log.Log;
033:
034: import java.sql.SQLException;
035: import java.util.ArrayList;
036: import java.util.logging.Logger;
037:
038: class CmpExpr extends Expr {
039: private static final Logger log = Log.open(CmpExpr.class);
040:
041: private Expr _left;
042: private Expr _right;
043: private int _op;
044:
045: CmpExpr(Expr left, Expr right, int op) {
046: _left = left;
047: _right = right;
048: _op = op;
049: }
050:
051: protected Expr bind(Query query) throws SQLException {
052: _left = _left.bind(query);
053: _right = _right.bind(query);
054:
055: switch (_op) {
056: case Parser.LT:
057: case Parser.LE:
058: case Parser.GT:
059: case Parser.GE:
060: return new DoubleCmpExpr(_op, _left, _right);
061: }
062:
063: if (_left.isDouble() || _right.isDouble())
064: return new DoubleCmpExpr(_op, _left, _right);
065:
066: return this ;
067: }
068:
069: /**
070: * Returns the type of the expression.
071: */
072: public Class getType() {
073: return boolean.class;
074: }
075:
076: /**
077: * Returns the cost based on the given FromList.
078: */
079: public long subCost(ArrayList<FromItem> fromList) {
080: return _left.subCost(fromList) + _right.subCost(fromList);
081: }
082:
083: /**
084: * Evaluates the expression as a boolean.
085: */
086: public int evalBoolean(QueryContext context) throws SQLException {
087: if (_left.isNull(context) || _right.isNull(context))
088: return UNKNOWN;
089:
090: switch (_op) {
091: case Parser.NE: {
092: String leftValue = _left.evalString(context);
093: String rightValue = _right.evalString(context);
094:
095: if (!(leftValue == rightValue || leftValue != null
096: && leftValue.equals(rightValue)))
097: return TRUE;
098: else
099: return FALSE;
100: }
101:
102: case Parser.EQ: {
103: String leftValue = _left.evalString(context);
104: String rightValue = _right.evalString(context);
105:
106: if (leftValue == rightValue || leftValue != null
107: && leftValue.equals(rightValue))
108: return TRUE;
109: else
110: return FALSE;
111: }
112:
113: default:
114: throw new SQLException("can't compare");
115: }
116: }
117:
118: public String evalString(QueryContext context) throws SQLException {
119: throw new SQLException("can't convert string to boolean");
120: }
121:
122: /**
123: * Evaluates aggregate functions during the group phase.
124: *
125: * @param state the current database tuple
126: */
127: public void evalGroup(QueryContext context) throws SQLException {
128: _left.evalGroup(context);
129: _right.evalGroup(context);
130: }
131:
132: public String toString() {
133: switch (_op) {
134: case Parser.EQ:
135: return "(" + _left + " = " + _right + ")";
136: case Parser.NE:
137: return "(" + _left + " <> " + _right + ")";
138: case Parser.LT:
139: return "(" + _left + " < " + _right + ")";
140: case Parser.LE:
141: return "(" + _left + " <= " + _right + ")";
142: case Parser.GT:
143: return "(" + _left + " > " + _right + ")";
144: case Parser.GE:
145: return "(" + _left + " >= " + _right + ")";
146: default:
147: return "(" + _left + " =? " + _right + ")";
148: }
149: }
150: }
|