@Override protected String visitCurrentTime(CurrentTime node, Void context) { StringBuilder builder = new StringBuilder(); if (node.getType() == CurrentTime.Type.DATE) { builder.append("current_date()"); } else if (node.getType() == CurrentTime.Type.TIME) { builder.append("current_timestamp()"); } else if (node.getType() == CurrentTime.Type.TIMESTAMP) { builder.append("current_timestamp()"); } else { builder.append(node.getType().getName()); } return builder.toString(); }
@Override protected String visitCurrentTime(CurrentTime node, Void context) { StringBuilder builder = new StringBuilder(); if (node.getType() == CurrentTime.Type.TIME) { builder.append(CurrentTime.Type.DATE.getName()); } else { builder.append(node.getType().getName()); if (node.getPrecision() != null) { builder.append('(') .append(node.getPrecision()) .append(')'); } } return builder.toString(); }
@Override public Expression rewriteCurrentTime(CurrentTime node, Void context, ExpressionTreeRewriter<Void> treeRewriter) { if (node.getPrecision() != null) { throw new UnsupportedOperationException("not yet implemented: non-default precision"); } switch (node.getType()) { case DATE: return new FunctionCall(new QualifiedName("current_date"), ImmutableList.<Expression>of()); case TIME: return new FunctionCall(new QualifiedName("current_time"), ImmutableList.<Expression>of()); case LOCALTIME: return new FunctionCall(new QualifiedName("localtime"), ImmutableList.<Expression>of()); case TIMESTAMP: return new FunctionCall(new QualifiedName("current_timestamp"), ImmutableList.<Expression>of()); case LOCALTIMESTAMP: return new FunctionCall(new QualifiedName("localtimestamp"), ImmutableList.<Expression>of()); default: throw new UnsupportedOperationException("not yet implemented: " + node.getType()); } }
private static CurrentTime.Type getDateTimeFunctionType(Token token) { switch (token.getType()) { case SqlBaseLexer.CURRENT_DATE: return CurrentTime.Type.DATE; case SqlBaseLexer.CURRENT_TIME: return CurrentTime.Type.TIME; case SqlBaseLexer.CURRENT_TIMESTAMP: return CurrentTime.Type.TIMESTAMP; case SqlBaseLexer.LOCALTIME: return CurrentTime.Type.LOCALTIME; case SqlBaseLexer.LOCALTIMESTAMP: return CurrentTime.Type.LOCALTIMESTAMP; } throw new IllegalArgumentException("Unsupported special function: " + token.getText()); }
protected static Expression processFuncLast(ComparisonExpression node) { System.out.println("Processing last()"); Expression rightNode = node.getRight(); Expression leftNode = node.getLeft(); FunctionCall last = (FunctionCall) rightNode; // # of arguments are already checked outside 1 or 2 String number = last.getArguments().get(0).toString(); String format = "DAY"; // default if (last.getArguments().size() == 2) { format = last.getArguments().get(1).toString().replaceAll("\"", ""); } IntervalLiteral.Sign sign; if (number.startsWith("-")) { sign = IntervalLiteral.Sign.NEGATIVE; number = number.substring(1); } else { sign = IntervalLiteral.Sign.POSITIVE; } CurrentTime cTime = new CurrentTime(CurrentTime.Type.DATE); IntervalLiteral interval = new IntervalLiteral(number, sign, format); ArithmeticExpression arithmOp = new ArithmeticExpression(ArithmeticExpression.Type.SUBTRACT, cTime, interval); BetweenPredicate bPredicate = new BetweenPredicate(leftNode, arithmOp, cTime); return bPredicate; }
@Override protected String visitCurrentTime(CurrentTime node, Void context) { StringBuilder builder = new StringBuilder(); builder.append(node.getType().getName()); return builder.toString(); }
@Override protected String visitCurrentTime(CurrentTime node, Void context) { StringBuilder builder = new StringBuilder(); builder.append(node.getType().getName()); if (node.getPrecision() != null) { builder.append('(') .append(node.getPrecision()) .append(')'); } return builder.toString(); }
@Override protected String visitCurrentTime(CurrentTime node, Void context) { StringBuilder builder = new StringBuilder(); if (node.getType() == CurrentTime.Type.DATE) { builder.append("convert(date, ").append("current_timestamp").append(")"); } else if (node.getType() == CurrentTime.Type.TIME) { builder.append("convert(time, ").append("current_timestamp").append(")"); } else { builder.append(node.getType().getName()); } return builder.toString(); }
@Override protected String visitCurrentTime(CurrentTime node, StackableAstVisitorContext<Integer> indent) { StringBuilder builder = new StringBuilder(); builder.append(node.getType().getName()); if (node.getPrecision() != null) { builder.append('(') .append(node.getPrecision()) .append(')'); } return builder.toString(); }
/** * Extracts the literal value from an expression (if expression is supported) * @param expression * @param state * @return a Long, Boolean, Double or String object */ private Object getLiteralValue(Expression expression, QueryState state){ if(expression instanceof LongLiteral) return ((LongLiteral)expression).getValue(); else if(expression instanceof BooleanLiteral) return ((BooleanLiteral)expression).getValue(); else if(expression instanceof DoubleLiteral) return ((DoubleLiteral)expression).getValue(); else if(expression instanceof StringLiteral) return ((StringLiteral)expression).getValue(); else if(expression instanceof ArithmeticUnaryExpression){ ArithmeticUnaryExpression unaryExp = (ArithmeticUnaryExpression)expression; Sign sign = unaryExp.getSign(); Number num = (Number)getLiteralValue(unaryExp.getValue(), state); if(sign == Sign.MINUS){ if(num instanceof Long) return -1*num.longValue(); else if(num instanceof Double) return -1*num.doubleValue(); else { state.addException("Unsupported numeric literal expression encountered : "+num.getClass()); return null; } } return num; } else if(expression instanceof FunctionCall){ FunctionCall fc = (FunctionCall)expression; if(fc.getName().toString().equals("now")) return new Date(); else state.addException("Function '"+fc.getName()+"' is not supported"); }else if(expression instanceof CurrentTime){ CurrentTime ct = (CurrentTime)expression; if(ct.getType() == CurrentTime.Type.DATE) return new LocalDate().toDate(); else if(ct.getType() == CurrentTime.Type.TIME) return new Date(new LocalTime(DateTimeZone.UTC).getMillisOfDay()); else if(ct.getType() == CurrentTime.Type.TIMESTAMP) return new Date(); else if(ct.getType() == CurrentTime.Type.LOCALTIME) return new Date(new LocalTime(DateTimeZone.UTC).getMillisOfDay()); else if(ct.getType() == CurrentTime.Type.LOCALTIMESTAMP) return new Date(); else state.addException("CurrentTime function '"+ct.getType()+"' is not supported"); }else state.addException("Literal type "+expression.getClass().getSimpleName()+" is not supported"); return null; }
@Override protected Type visitCurrentTime(CurrentTime node, StackableAstVisitorContext<AnalysisContext> context) { if (node.getPrecision() != null) { throw new SemanticException(NOT_SUPPORTED, node, "non-default precision not yet supported"); } Type type; switch (node.getType()) { case DATE: type = DATE; break; case TIME: type = TIME_WITH_TIME_ZONE; break; case LOCALTIME: type = TIME; break; case TIMESTAMP: type = TIMESTAMP_WITH_TIME_ZONE; break; case LOCALTIMESTAMP: type = TIMESTAMP; break; default: throw new SemanticException(NOT_SUPPORTED, node, "%s not yet supported", node.getType().getName()); } expressionTypes.put(node, type); return type; }
@Override public Node visitSpecialDateTimeFunction(SqlBaseParser.SpecialDateTimeFunctionContext context) { CurrentTime.Type type = getDateTimeFunctionType(context.name); if (context.precision != null) { return new CurrentTime(getLocation(context), type, Integer.parseInt(context.precision.getText())); } return new CurrentTime(getLocation(context), type); }
@Override protected String visitCurrentTime(CurrentTime node, Boolean unmangleNames) { StringBuilder builder = new StringBuilder(); builder.append(node.getType().getName()); if (node.getPrecision() != null) { builder.append('(') .append(node.getPrecision()) .append(')'); } return builder.toString(); }
@Override protected Boolean visitCurrentTime(CurrentTime node, Void context) { return true; }
@Test public void testCurrentTimestamp() throws Exception { assertExpression("CURRENT_TIMESTAMP", new CurrentTime(CurrentTime.Type.TIMESTAMP)); }