1 28 29 package com.caucho.amber.expr; 30 31 import com.caucho.amber.query.FromItem; 32 import com.caucho.amber.query.QueryParser; 33 import com.caucho.amber.type.EnumType; 34 import com.caucho.amber.type.Type; 35 import com.caucho.util.CharBuffer; 36 import com.caucho.util.L10N; 37 38 39 42 public class BinaryExpr extends AbstractAmberExpr { 43 private static final L10N L = new L10N(BinaryExpr.class); 44 45 private AmberExpr _left; 46 private AmberExpr _right; 47 private int _token; 48 49 52 public BinaryExpr(int token, AmberExpr left, AmberExpr right) 53 { 54 _token = token; 55 _left = left; 56 _right = right; 57 } 58 59 62 public boolean isBoolean() 63 { 64 switch (_token) { 65 case QueryParser.EQ: 66 case QueryParser.NE: 67 case QueryParser.LT: 68 case QueryParser.LE: 69 case QueryParser.GT: 70 case QueryParser.GE: 71 return true; 72 default: 73 return false; 74 } 75 } 76 77 80 public Class getJavaType() 81 { 82 switch (_token) { 83 case QueryParser.EQ: 84 case QueryParser.NE: 85 case QueryParser.LT: 86 case QueryParser.LE: 87 case QueryParser.GT: 88 case QueryParser.GE: 89 return boolean.class; 90 default: 91 return double.class; 92 } 93 } 94 95 98 public AmberExpr bindSelect(QueryParser parser) 99 { 100 _left = _left.bindSelect(parser); 101 _right = _right.bindSelect(parser); 102 103 bindTypes(_left, _right); 104 bindTypes(_right, _left); 105 106 return this; 107 } 108 109 112 public boolean usesFrom(FromItem from, int type, boolean isNot) 113 { 114 return (_left.usesFrom(from, type) || _right.usesFrom(from, type)); 115 } 116 117 120 @Override 121 public boolean exists(FromItem from) 122 { 123 if (_token == QueryParser.EQ) { 124 if (_left instanceof KeyColumnExpr 125 && _left.usesFrom(from, AmberExpr.IS_INNER_JOIN, false) 126 && _right.exists()) 127 return true; 128 else if (_right instanceof KeyColumnExpr 129 && _right.usesFrom(from, AmberExpr.IS_INNER_JOIN, false) 130 && _right.exists(from) 131 && _left.exists()) 132 return true; 133 else 134 return false; 135 } 136 else 137 return false; 138 } 139 140 143 public AmberExpr replaceJoin(JoinExpr join) 144 { 145 _left = _left.replaceJoin(join); 146 _right = _right.replaceJoin(join); 147 148 return this; 149 } 150 151 154 public void generateWhere(CharBuffer cb) 155 { 156 generateInternalWhere(cb, true); 157 } 158 159 162 public void generateUpdateWhere(CharBuffer cb) 163 { 164 generateInternalWhere(cb, false); 165 } 166 167 170 public void generateHaving(CharBuffer cb) 171 { 172 generateWhere(cb); 173 } 174 175 public String toString() 176 { 177 String str = "(" + _left; 178 179 switch (_token) { 180 case QueryParser.EQ: 181 str += " = "; 182 break; 183 case QueryParser.NE: 184 str += " <> "; 185 break; 186 case QueryParser.LT: 187 str += " < "; 188 break; 189 case QueryParser.LE: 190 str += " <= "; 191 break; 192 case QueryParser.GT: 193 str += " > "; 194 break; 195 case QueryParser.GE: 196 str += " >= "; 197 break; 198 case '+': 199 str += " + "; 200 break; 201 case '-': 202 str += " - "; 203 break; 204 case '*': 205 str += " * "; 206 break; 207 case '/': 208 str += " / "; 209 break; 210 case '%': 211 str += " % "; 212 break; 213 } 214 215 return str + _right + ")"; 216 } 217 218 221 private static void bindTypes(AmberExpr left, 222 AmberExpr right) 223 { 224 226 Type leftType = left.getType(); 227 Type rightType = right.getType(); 228 229 if (left instanceof EnumExpr) { 230 EnumExpr enumExpr = (EnumExpr) left; 231 enumExpr.setOrdinal(rightType.isNumeric()); 232 } 233 else if (left instanceof ArgExpr) { 234 if (rightType instanceof EnumType) { 235 ((ArgExpr) left).setType(rightType); 236 } 237 } 238 } 239 240 private void generateInternalWhere(CharBuffer cb, 241 boolean select) 242 { 243 cb.append('('); 244 245 ArgExpr arg; 246 247 if ((_left instanceof ArgExpr) && 248 (_right instanceof AbstractAmberExpr)) { 249 arg = (ArgExpr) _left; 250 arg.setType(((AbstractAmberExpr) _right).getType()); 251 } 252 253 if ((_right instanceof ArgExpr) && 254 (_left instanceof AbstractAmberExpr)) { 255 arg = (ArgExpr) _right; 256 arg.setType(((AbstractAmberExpr) _left).getType()); 257 } 258 259 if (select) 260 _left.generateWhere(cb); 261 else 262 _left.generateUpdateWhere(cb); 263 264 switch (_token) { 265 case QueryParser.EQ: 266 cb.append(" = "); 267 break; 268 case QueryParser.NE: 269 cb.append(" <> "); 270 break; 271 case QueryParser.LT: 272 cb.append(" < "); 273 break; 274 case QueryParser.LE: 275 cb.append(" <= "); 276 break; 277 case QueryParser.GT: 278 cb.append(" > "); 279 break; 280 case QueryParser.GE: 281 cb.append(" >= "); 282 break; 283 case '+': 284 cb.append(" + "); 285 break; 286 case '-': 287 cb.append(" - "); 288 break; 289 case '*': 290 cb.append(" * "); 291 break; 292 case '/': 293 cb.append(" / "); 294 break; 295 case '%': 296 cb.append(" % "); 297 break; 298 default: 299 throw new IllegalStateException (); 300 } 301 302 if (select) 303 _right.generateWhere(cb); 304 else 305 _right.generateUpdateWhere(cb); 306 307 cb.append(')'); 308 } 309 } 310 | Popular Tags |