@Override protected String visitSearchedCaseExpression(SearchedCaseExpression node, Void context) { ImmutableList.Builder<String> parts = ImmutableList.builder(); parts.add("CASE").add("\n"); for (WhenClause whenClause : node.getWhenClauses()) { parts.add(process(whenClause, context)).add("\n"); } if (node.getDefaultValue() != null) { parts.add("ELSE") .add(process(node.getDefaultValue(), context)).add("\n"); } parts.add("END").add("\n"); return "(" + Joiner.on(' ').join(parts.build()) + ")"; }
@Override protected String visitSimpleCaseExpression(SimpleCaseExpression node, Void context) { ImmutableList.Builder<String> parts = ImmutableList.builder(); parts.add("CASE").add(process(node.getOperand(), context)); for (WhenClause whenClause : node.getWhenClauses()) { parts.add(process(whenClause, context)); } if (node.getDefaultValue() != null) { parts.add("ELSE").add(process(node.getDefaultValue(), context)); } parts.add("END"); return "(" + Joiner.on(' ').join(parts.build()) + ")"; }
@Override protected String visitSearchedCaseExpression(SearchedCaseExpression node, StackableAstVisitorContext<Integer> indent) { ImmutableList.Builder<String> parts = ImmutableList.builder(); parts.add("CASE"); for (WhenClause whenClause : node.getWhenClauses()) { parts.add(process(whenClause, indent)); } node.getDefaultValue() .ifPresent((value) -> parts.add("ELSE").add(process(value, indent))); parts.add("END"); return "(" + Joiner.on(' ').join(parts.build()) + ")"; }
@Override protected String visitSimpleCaseExpression(SimpleCaseExpression node, StackableAstVisitorContext<Integer> indent) { ImmutableList.Builder<String> parts = ImmutableList.builder(); parts.add("CASE") .add(process(node.getOperand(), indent)); for (WhenClause whenClause : node.getWhenClauses()) { parts.add(process(whenClause, indent)); } node.getDefaultValue() .ifPresent((value) -> parts.add("ELSE").add(process(value, indent))); parts.add("END"); return "(" + Joiner.on(' ').join(parts.build()) + ")"; }
@Override protected RowExpression visitSimpleCaseExpression(SimpleCaseExpression node, Void context) { ImmutableList.Builder<RowExpression> arguments = ImmutableList.builder(); arguments.add(process(node.getOperand(), context)); for (WhenClause clause : node.getWhenClauses()) { arguments.add(call(whenSignature(types.get(clause)), types.get(clause), process(clause.getOperand(), context), process(clause.getResult(), context))); } Type returnType = types.get(node); arguments.add(node.getDefaultValue() .map((value) -> process(value, context)) .orElse(constantNull(returnType))); return call(switchSignature(returnType), returnType, arguments.build()); }
@Override protected Boolean visitSimpleCaseExpression(SimpleCaseExpression node, Void context) { if (!process(node.getOperand(), context)) { return false; } for (WhenClause whenClause : node.getWhenClauses()) { if (!process(whenClause.getOperand(), context) || !process(whenClause.getResult(), context)) { return false; } } if (node.getDefaultValue().isPresent() && !process(node.getDefaultValue().get(), context)) { return false; } return true; }
@Override protected String visitSearchedCaseExpression(SearchedCaseExpression node, Boolean unmangleNames) { ImmutableList.Builder<String> parts = ImmutableList.builder(); parts.add("CASE"); for (WhenClause whenClause : node.getWhenClauses()) { parts.add(process(whenClause, unmangleNames)); } node.getDefaultValue() .ifPresent((value) -> parts.add("ELSE").add(process(value, unmangleNames))); parts.add("END"); return "(" + Joiner.on(' ').join(parts.build()) + ")"; }
@Override protected String visitSimpleCaseExpression(SimpleCaseExpression node, Boolean unmangleNames) { ImmutableList.Builder<String> parts = ImmutableList.builder(); parts.add("CASE") .add(process(node.getOperand(), unmangleNames)); for (WhenClause whenClause : node.getWhenClauses()) { parts.add(process(whenClause, unmangleNames)); } node.getDefaultValue() .ifPresent((value) -> parts.add("ELSE").add(process(value, unmangleNames))); parts.add("END"); return "(" + Joiner.on(' ').join(parts.build()) + ")"; }
protected static String processFuncNullifzero(Formatter formatter, FunctionCall node) { Expression x = node.getArguments().get(0); List<WhenClause> listWhen = new ArrayList<WhenClause>(); ComparisonExpression ce = new ComparisonExpression(ComparisonExpression.Type.EQUAL, x, new LongLiteral("0")); WhenClause wc = new WhenClause(ce, new NullLiteral()); listWhen.add(wc); SearchedCaseExpression sce = new SearchedCaseExpression(listWhen, x); return formatter.process(sce, null); }
@Override protected RowExpression visitSearchedCaseExpression(SearchedCaseExpression node, Void context) { /* Translates an expression like: case when cond1 then value1 when cond2 then value2 when cond3 then value3 else value4 end To: IF(cond1, value1, IF(cond2, value2, If(cond3, value3, value4))) */ RowExpression expression = node.getDefaultValue() .map((value) -> process(value, context)) .orElse(constantNull(types.get(node))); for (WhenClause clause : Lists.reverse(node.getWhenClauses())) { expression = call( Signatures.ifSignature(types.get(node)), types.get(node), process(clause.getOperand(), context), process(clause.getResult(), context), expression); } return expression; }
@Override protected Object visitSearchedCaseExpression(SearchedCaseExpression node, Object context) { Object defaultResult = processWithExceptionHandling(node.getDefaultValue().orElse(null), context); List<WhenClause> whenClauses = new ArrayList<>(); for (WhenClause whenClause : node.getWhenClauses()) { Object whenOperand = processWithExceptionHandling(whenClause.getOperand(), context); Object result = processWithExceptionHandling(whenClause.getResult(), context); if (whenOperand instanceof Expression) { // cannot fully evaluate, add updated whenClause whenClauses.add(new WhenClause( toExpression(whenOperand, type(whenClause.getOperand())), toExpression(result, type(whenClause.getResult())))); } else if (Boolean.TRUE.equals(whenOperand)) { // condition is true, use this as defaultResult defaultResult = result; break; } } if (whenClauses.isEmpty()) { return defaultResult; } Expression resultExpression = (defaultResult == null) ? null : toExpression(defaultResult, type(node)); return new SearchedCaseExpression(whenClauses, Optional.ofNullable(resultExpression)); }
@Override protected Object visitSimpleCaseExpression(SimpleCaseExpression node, Object context) { Object operand = processWithExceptionHandling(node.getOperand(), context); Type operandType = type(node.getOperand()); // evaluate defaultClause Expression defaultClause = node.getDefaultValue().orElse(null); Object defaultResult = processWithExceptionHandling(defaultClause, context); // if operand is null, return defaultValue if (operand == null) { return defaultResult; } List<WhenClause> whenClauses = new ArrayList<>(); for (WhenClause whenClause : node.getWhenClauses()) { Object whenOperand = processWithExceptionHandling(whenClause.getOperand(), context); Object result = processWithExceptionHandling(whenClause.getResult(), context); if (whenOperand instanceof Expression || operand instanceof Expression) { // cannot fully evaluate, add updated whenClause whenClauses.add(new WhenClause( toExpression(whenOperand, type(whenClause.getOperand())), toExpression(result, type(whenClause.getResult())))); } else if (whenOperand != null && isEqual(operand, operandType, whenOperand, type(whenClause.getOperand()))) { // condition is true, use this as defaultResult defaultResult = result; break; } } if (whenClauses.isEmpty()) { return defaultResult; } Expression defaultExpression = (defaultResult == null) ? null : toExpression(defaultResult, type(node)); return new SimpleCaseExpression(toExpression(operand, type(node.getOperand())), whenClauses, Optional.ofNullable(defaultExpression)); }
@Override public Expression rewriteIfExpression(IfExpression node, Void context, ExpressionTreeRewriter<Void> treeRewriter) { Expression condition = treeRewriter.rewrite(node.getCondition(), context); Expression trueValue = treeRewriter.rewrite(node.getTrueValue(), context); Optional<Expression> falseValue = node.getFalseValue() .map((value) -> treeRewriter.rewrite(value, context)); return new SearchedCaseExpression(ImmutableList.of(new WhenClause(condition, trueValue)), falseValue); }
@Override protected Boolean visitSearchedCaseExpression(SearchedCaseExpression node, Void context) { for (WhenClause whenClause : node.getWhenClauses()) { if (!process(whenClause.getOperand(), context) || !process(whenClause.getResult(), context)) { return false; } } return !node.getDefaultValue().isPresent() || process(node.getDefaultValue().get(), context); }
private List<Expression> getCaseResultExpressions(List<WhenClause> whenClauses, Optional<Expression> defaultValue) { List<Expression> resultExpressions = new ArrayList<>(); for (WhenClause whenClause : whenClauses) { resultExpressions.add(whenClause.getResult()); } defaultValue.ifPresent(resultExpressions::add); return resultExpressions; }
@Override public Node visitSimpleCase(SqlBaseParser.SimpleCaseContext context) { return new SimpleCaseExpression( getLocation(context), (Expression) visit(context.valueExpression()), visit(context.whenClause(), WhenClause.class), visitIfPresent(context.elseExpression, Expression.class)); }
@Override public Node visitSearchedCase(SqlBaseParser.SearchedCaseContext context) { return new SearchedCaseExpression( getLocation(context), visit(context.whenClause(), WhenClause.class), visitIfPresent(context.elseExpression, Expression.class)); }
@Override protected String visitWhenClause(WhenClause node, Void context) { return "WHEN " + process(node.getOperand(), context) + " THEN " + process(node.getResult(), context); }
@Override protected String visitWhenClause(WhenClause node, StackableAstVisitorContext<Integer> indent) { return "WHEN " + process(node.getOperand(), indent) + " THEN " + process(node.getResult(), indent); }
@Override protected OrderBy visitSortItem(SortItem si, QueryState state){ String orderKey = null; if(si.getSortKey() instanceof DereferenceExpression){ orderKey = SelectParser.visitDereferenceExpression((DereferenceExpression)si.getSortKey()); }else if (si.getSortKey() instanceof FunctionCall){ orderKey = si.getSortKey().toString().replaceAll("\"",""); }else if(si.getSortKey() instanceof SearchedCaseExpression){ //... order by CASE WHEN field IS NULL THEN 1 ELSE 0 END // TODO: improve this quick and dirty implementation SearchedCaseExpression sce = (SearchedCaseExpression)si.getSortKey(); for(WhenClause when : sce.getWhenClauses()){ orderKey = SelectParser.visitDereferenceExpression( (DereferenceExpression)((IsNullPredicate)when.getOperand()).getValue()); } }else if(si.getSortKey() instanceof QualifiedNameReference){ orderKey = ((QualifiedNameReference)si.getSortKey()).getName().toString(); }else { state.addException("Order statement with type '"+si.getSortKey().getClass().getName()+"' is not supported"); return null; } // fix case orderKey = Heading.findOriginal(state.originalSql()+";", orderKey, "order by.+", "\\W"); // remove any table reference or alias if(orderKey.contains(".")){ String prefix = orderKey.split("\\.")[0]; for(QuerySource tr : state.getSources()){ if(tr.getAlias() != null){ if(prefix.equals(tr.getAlias())) orderKey = orderKey.substring(orderKey.indexOf('.')+1); }else if (tr.getSource() != null && prefix.equals(tr.getSource())) orderKey = orderKey.substring(orderKey.indexOf('.')+1); } } // select column to order on Column column = state.getHeading().getColumnByLabel(orderKey); if(column != null){ if(si.getOrdering().toString().startsWith("ASC")){ return new OrderBy(column.getColumn(), SortOrder.ASC, column.getIndex()); }else{ return new OrderBy(column.getColumn(), SortOrder.DESC, column.getIndex()); } }else{ state.addException("Order key '"+orderKey+"' is not specified in SELECT clause"); return null; } }
@Override public Node visitWhenClause(SqlBaseParser.WhenClauseContext context) { return new WhenClause(getLocation(context), (Expression) visit(context.condition), (Expression) visit(context.result)); }
@Override protected String visitWhenClause(WhenClause node, Boolean unmangleNames) { return "WHEN " + process(node.getOperand(), unmangleNames) + " THEN " + process(node.getResult(), unmangleNames); }
public static Expression caseWhen(Expression operand, Expression result) { return new SearchedCaseExpression(ImmutableList.of(new WhenClause(operand, result)), Optional.empty()); }