KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > versant > core > jdbc > sql > exp > BinaryOpExp


1
2 /*
3  * Copyright (c) 1998 - 2005 Versant Corporation
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License v1.0
6  * which accompanies this distribution, and is available at
7  * http://www.eclipse.org/legal/epl-v10.html
8  *
9  * Contributors:
10  * Versant Corporation - initial API and implementation
11  */

12 package com.versant.core.jdbc.sql.exp;
13
14 import com.versant.core.util.CharBuf;
15 import com.versant.core.jdbc.sql.SqlDriver;
16 import com.versant.core.jdbc.query.SqlStruct;
17
18 import java.util.Map JavaDoc;
19
20 /**
21  * An expression comprised of two args and an operator.
22  */

23 public class BinaryOpExp extends BinaryExp {
24
25     public static final int EQUAL = 1;
26     public static final int NOT_EQUAL = 2;
27     public static final int GT = 3;
28     public static final int LT = 4;
29     public static final int GE = 5;
30     public static final int LE = 6;
31     public static final int LIKE = 7;
32     public static final int CONCAT = 8;
33     public static final int PLUS = 9;
34     public static final int MINUS = 10;
35     public static final int TIMES = 11;
36     public static final int DIVIDE = 12;
37
38     public int op;
39
40     /**
41      * The index of the first character of our operator in the sql output
42      * buffer.
43      */

44     private int firstCharIndex;
45
46     public BinaryOpExp(SqlExp left, int op, SqlExp right) {
47         super(left, right);
48         this.op = op;
49     }
50
51     public BinaryOpExp(int op) {
52         this.op = op;
53     }
54
55     public BinaryOpExp() {
56     }
57
58     public SqlExp createInstance() {
59         return new BinaryOpExp();
60     }
61
62     public SqlExp getClone(SqlExp exp, Map JavaDoc cloneMap) {
63         super.getClone(exp, cloneMap);
64         BinaryOpExp cst = (BinaryOpExp) exp;
65
66         cst.op = op;
67         cst.firstCharIndex = firstCharIndex;
68
69         return exp;
70     }
71
72     public static String JavaDoc toOpString(int op) {
73         switch (op) {
74             case EQUAL:
75                 return "=";
76             case NOT_EQUAL:
77                 return "<>";
78             case GT:
79                 return ">";
80             case LT:
81                 return "<";
82             case GE:
83                 return ">=";
84             case LE:
85                 return "<=";
86             case LIKE:
87                 return "LIKE";
88             case CONCAT:
89                 return "||";
90             case PLUS:
91                 return "+";
92             case MINUS:
93                 return "-";
94             case TIMES:
95                 return "*";
96             case DIVIDE:
97                 return "/";
98         }
99         return "<unknown " + op + ">";
100     }
101
102     public String JavaDoc toString() {
103         return super.toString() + " " + toOpString(op);
104     }
105
106     /**
107      * Append SQL for this node to s.
108      *
109      * @param driver The driver being used
110      * @param s Append the SQL here
111      * @param leftSibling
112      */

113     public void appendSQLImp(SqlDriver driver, CharBuf s, SqlExp leftSibling) {
114         childList.appendSQL(driver, s, null);
115
116         SqlExp right = childList.next;
117
118         // convert == and != to 'is null' or 'is not null' if the right hand
119
// side is a null literal
120
if ((op == EQUAL || op == NOT_EQUAL) && right instanceof LiteralExp
121                 && ((LiteralExp) right).type == LiteralExp.TYPE_NULL) {
122             if (op == EQUAL) {
123                 s.append(" is null");
124             } else {
125                 s.append(" is not null");
126             }
127             return;
128         }
129
130         s.append(' ');
131         firstCharIndex = s.size();
132         s.append(driver.getSqlBinaryOp(op));
133         s.append(' ');
134         if (!removeConcat(driver, s, right)) {
135             right.appendSQL(driver, s, childList);
136         }
137
138         // make space for 'is null' or 'is not null' if required
139
if (childList.next instanceof ParamExp) {
140             if (op == EQUAL) {
141                 int n = s.size() - firstCharIndex;
142                 for (; n < 11; n++) s.append(' ');
143             } else if (op == NOT_EQUAL) {
144                 int n = s.size() - firstCharIndex;
145                 for (; n < 11; n++) s.append(' ');
146             }
147         }
148     }
149
150     /**
151      * If this is a LIKE and the driver does not handle LIKE well and the
152      * right subtree contains a percent literal and a parameter then output
153      * just the parameter with modification to add the percent before the
154      * query runs.
155      */

156     private boolean removeConcat(SqlDriver driver, CharBuf s,
157                                  SqlExp right) {
158         if (op == LIKE && driver.isLikeStupid() && right instanceof BinaryOpExp
159                 && ((BinaryOpExp) right).isConcatParamAndPercent()) {
160             ParamExp pe;
161             int mod;
162             if (right.childList instanceof ParamExp) {
163                 pe = (ParamExp) right.childList;
164                 mod = SqlStruct.Param.MOD_APPEND_PERCENT;
165             } else {
166                 pe = (ParamExp) right.childList.next;
167                 mod = SqlStruct.Param.MOD_PREPEND_PERCENT;
168             }
169             pe.usage.mod = mod;
170             pe.appendSQL(driver, s, null);
171             return true;
172         } else {
173             return false;
174         }
175     }
176
177     private boolean isConcatParamAndPercent() {
178         if (op != CONCAT) return false;
179         if (childList instanceof ParamExp) {
180             return isLiteralPercent(childList.next);
181         } else if (childList.next instanceof ParamExp) {
182             return isLiteralPercent(childList);
183         }
184         return false;
185     }
186
187     private static boolean isLiteralPercent(SqlExp e) {
188         return e instanceof LiteralExp && ((LiteralExp) e).value.equals("%");
189     }
190
191     /**
192      * Get the index of first character of the 'is null' parameter
193      * replacement span for this expression.
194      */

195     public int getFirstCharIndex() {
196         return firstCharIndex;
197     }
198
199     /**
200      * Is this a negative expression for the purposes of replacing parameter
201      * values with 'is null' (false) or 'is not null' (true)?
202      */

203     public boolean isNegative() {
204         return op == NOT_EQUAL;
205     }
206 }
207
208
Popular Tags