@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 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 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()) + ")"; }
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 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); }
@Override public Node visitSearchedCase(SqlBaseParser.SearchedCaseContext context) { return new SearchedCaseExpression( getLocation(context), visit(context.whenClause(), WhenClause.class), visitIfPresent(context.elseExpression, Expression.class)); }
@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; } }
public static Expression caseWhen(Expression operand, Expression result) { return new SearchedCaseExpression(ImmutableList.of(new WhenClause(operand, result)), Optional.empty()); }