1 28 29 package com.caucho.ejb.ql; 30 31 import com.caucho.config.ConfigException; 32 import com.caucho.util.CharBuffer; 33 34 37 class BinaryExpr extends Expr { 38 private int _op; 40 private Expr _left; 42 private Expr _right; 44 45 52 BinaryExpr(Query query, int op, Expr left, Expr right) 53 throws ConfigException 54 { 55 _query = query; 56 _op = op; 57 _left = left; 58 _right = right; 59 60 evalTypes(); 61 } 62 63 Expr getLeft() 64 { 65 return _left; 66 } 67 68 71 void evalTypes() 72 throws ConfigException 73 { 74 81 82 switch (_op) { 83 case Query.EQ: 84 case Query.NE: 85 if (! _left.getJavaType().equals(_right.getJavaType()) && 86 _left.isNumeric() != _right.isNumeric() && 87 ! (_left.isDate() && _right.isDate())) 88 throw error(L.l("`{0}' has mismatched types `{1}' != `{2}'", 89 this, _left.getJavaType().getName(), 90 _right.getJavaType().getName())); 91 setJavaType(boolean.class); 92 break; 93 94 case Query.LT: 95 case Query.GT: 96 case Query.LE: 97 case Query.GE: 98 if (_left.isDate() && _right.isDate()) { 99 } 100 else if (! _left.isNumeric()) 101 throw error(L.l("`{0}' expects a numeric value at {1}. Less-than and greater-than comparisons only make sense with numbers and dates.", 102 this, _left.getJavaType().getName())); 103 else if (! _right.isNumeric()) 104 throw error(L.l("`{0}' expects a numeric value at {1}. Less-than and greater-than comparisons only make sense with numbers and dates.", 105 this, _right.getJavaType().getName())); 106 107 setJavaType(boolean.class); 108 break; 109 110 case Query.AND: 111 case Query.OR: 112 if (! _left.isBoolean()) 113 throw error(L.l("`{0}' expects a boolean value at {1}", 114 _left, _left.getJavaType().getName())); 115 if (! _right.isBoolean()) 116 throw error(L.l("`{0}' expects a boolean value at {1}", 117 _right, _right.getJavaType().getName())); 118 119 setJavaType(boolean.class); 120 break; 121 122 case '+': 123 case '-': 124 case '*': 125 case '/': 126 if (! _left.isNumeric()) 127 throw error(L.l("`{0}' expects a numeric value at {1}", 128 _left, _left.getJavaType().getName())); 129 if (! _right.isNumeric()) 130 throw error(L.l("`{0}' expects a numeric value at {1}", 131 _right, _right.getJavaType().getName())); 132 133 143 if (isInteger(_left.getJavaType()) && 144 isInteger(_right.getJavaType())) 145 setJavaType(long.class); 146 else 147 setJavaType(double.class); 148 break; 149 150 default: 151 throw new RuntimeException ("unknown binary op:" + _op + " " + (char) _op); 152 } 153 } 154 155 160 void generateWhere(CharBuffer cb) 161 { 162 if (_left.isKey()) { 163 int componentCount = _left.getComponentCount(); 164 165 generateWhereComponents(cb, componentCount); 166 167 return; 168 } 169 else if (_right.isKey()) { 170 int componentCount = _right.getComponentCount(); 171 172 generateWhereComponents(cb, componentCount); 173 174 return; 175 } 176 177 _left.generateComponent(cb, 0); 179 180 switch (_op) { 181 case Query.EQ: 182 cb.append(" = "); 183 break; 184 case Query.NE: 185 cb.append(" <> "); 186 break; 187 case Query.LT: 188 cb.append(" < "); 189 break; 190 case Query.GT: 191 cb.append(" > "); 192 break; 193 case Query.LE: 194 cb.append(" <= "); 195 break; 196 case Query.GE: 197 cb.append(" >= "); 198 break; 199 200 case Query.AND: 201 cb.append(" AND "); 202 break; 203 case Query.OR: 204 cb.append(" OR "); 205 break; 206 207 default: 208 cb.append(" " + ((char) _op) + " "); 209 break; 210 } 211 212 _right.generateComponent(cb, 0); 214 } 215 216 private void generateWhereComponents(CharBuffer cb, int componentCount) 217 { 218 for (int i = 0; i < componentCount; i++) { 219 if (i != 0) 220 cb.append(" AND "); 221 222 _left.generateComponent(cb, i); 223 224 if (_op == Query.EQ) 225 cb.append(" = "); 226 else if (_op == Query.NE) 227 cb.append(" <> "); 228 229 _right.generateComponent(cb, i); 230 } 231 } 232 233 236 void generateWhereSubExpr(CharBuffer cb) 237 { 238 cb.append("("); 239 generateWhere(cb); 240 cb.append(")"); 241 } 242 243 void generateSelect(CharBuffer cb) 244 { 245 cb.append("("); 246 generateWhere(cb); 247 cb.append(")"); 248 } 249 250 public String toString() 251 { 252 CharBuffer value = CharBuffer.allocate(); 253 254 if (_left instanceof BinaryExpr) { 255 value.append("("); 256 value.append(_left.toString()); 257 value.append(")"); 258 } 259 else 260 value.append(_left.toString()); 261 262 switch (_op) { 263 case Query.EQ: 264 value.append(" = "); 265 break; 266 case Query.NE: 267 value.append(" <> "); 268 break; 269 case Query.LT: 270 value.append(" < "); 271 break; 272 case Query.GT: 273 value.append(" > "); 274 break; 275 case Query.LE: 276 value.append(" <= "); 277 break; 278 case Query.GE: 279 value.append(" >= "); 280 break; 281 282 case Query.AND: 283 value.append(" AND "); 284 break; 285 case Query.OR: 286 value.append(" OR "); 287 break; 288 289 default: 290 value.append(" " + ((char) _op) + " "); 291 break; 292 } 293 294 if (_right instanceof BinaryExpr) { 295 value.append("("); 296 value.append(_right.toString()); 297 value.append(")"); 298 } 299 else 300 value.append(_right.toString()); 301 302 return value.close(); 303 } 304 } 305 | Popular Tags |