| 325 | } |
| 326 | |
| 327 | private RexNode toRex(Ast.Node exp) { |
| 328 | final Ast.Call call; |
| 329 | switch (exp.op) { |
| 330 | case LITERAL: |
| 331 | return builder.literal(((Ast.Literal) exp).value); |
| 332 | case IDENTIFIER: |
| 333 | final String value = ((Ast.Identifier) exp).value; |
| 334 | if (value.matches("^\\$[0-9]+")) { |
| 335 | int i = Integer.valueOf(value.substring(1)); |
| 336 | return builder.field(i); |
| 337 | } |
| 338 | return builder.field(value); |
| 339 | case DOT: |
| 340 | call = (Ast.Call) exp; |
| 341 | final RexNode left = toRex(call.operands.get(0)); |
| 342 | final Ast.Identifier right = (Ast.Identifier) call.operands.get(1); |
| 343 | return builder.dot(left, right.value); |
| 344 | case EQ: |
| 345 | case NE: |
| 346 | case GT: |
| 347 | case GTE: |
| 348 | case LT: |
| 349 | case LTE: |
| 350 | case AND: |
| 351 | case OR: |
| 352 | case NOT: |
| 353 | case PLUS: |
| 354 | case MINUS: |
| 355 | call = (Ast.Call) exp; |
| 356 | return builder.call(op(exp.op), toRex(call.operands)); |
| 357 | default: |
| 358 | throw new AssertionError("unknown op " + exp.op); |
| 359 | } |
| 360 | } |
| 361 | |
| 362 | private static SqlOperator op(Ast.Op op) { |
| 363 | switch (op) { |