public static Function<Expression, Expression> expressionOrNullSymbols(final Predicate<Symbol>... nullSymbolScopes) { return expression -> { ImmutableList.Builder<Expression> resultDisjunct = ImmutableList.builder(); resultDisjunct.add(expression); for (Predicate<Symbol> nullSymbolScope : nullSymbolScopes) { Iterable<Symbol> symbols = filter(DependencyExtractor.extractUnique(expression), nullSymbolScope); if (Iterables.isEmpty(symbols)) { continue; } ImmutableList.Builder<Expression> nullConjuncts = ImmutableList.builder(); for (Symbol symbol : symbols) { nullConjuncts.add(new IsNullPredicate(new QualifiedNameReference(symbol.toQualifiedName()))); } resultDisjunct.add(and(nullConjuncts.build())); } return or(resultDisjunct.build()); }; }
private static Expression toPredicate(Domain domain, QualifiedNameReference reference) { if (domain.getValues().isNone()) { return domain.isNullAllowed() ? new IsNullPredicate(reference) : FALSE_LITERAL; } if (domain.getValues().isAll()) { return domain.isNullAllowed() ? TRUE_LITERAL : new NotExpression(new IsNullPredicate(reference)); } List<Expression> disjuncts = new ArrayList<>(); disjuncts.addAll(domain.getValues().getValuesProcessor().transform( ranges -> extractDisjuncts(domain.getType(), ranges, reference), discreteValues -> extractDisjuncts(domain.getType(), discreteValues, reference), allOrNone -> { throw new IllegalStateException("Case should not be reachable"); })); // Add nullability disjuncts if (domain.isNullAllowed()) { disjuncts.add(new IsNullPredicate(reference)); } return combineDisjunctsWithDefault(disjuncts, TRUE_LITERAL); }
@Override protected RowExpression visitIsNullPredicate(IsNullPredicate node, Void context) { RowExpression expression = process(node.getValue(), context); return call(Signatures.isNullSignature(expression.getType()), BOOLEAN, expression); }
@Override protected Object visitIsNullPredicate(IsNullPredicate node, Object context) { Object value = process(node.getValue(), context); if (value instanceof Expression) { return new IsNullPredicate(toExpression(value, expressionTypes.get(node.getValue()))); } return value == null; }
@Override protected ExtractionResult visitIsNullPredicate(IsNullPredicate node, Boolean complement) { if (!(node.getValue() instanceof QualifiedNameReference)) { return super.visitIsNullPredicate(node, complement); } Symbol symbol = Symbol.fromQualifiedName(((QualifiedNameReference) node.getValue()).getName()); Type columnType = checkedTypeLookup(symbol); Domain domain = complementIfNecessary(Domain.onlyNull(columnType), complement); return new ExtractionResult( TupleDomain.withColumnDomains(ImmutableMap.of(symbol, domain)), TRUE_LITERAL); }
@Override protected Type visitIsNullPredicate(IsNullPredicate node, StackableAstVisitorContext<AnalysisContext> context) { process(node.getValue(), context); expressionTypes.put(node, BOOLEAN); return BOOLEAN; }
@Override public Node visitNullPredicate(SqlBaseParser.NullPredicateContext context) { Expression child = (Expression) visit(context.value); if (context.NOT() == null) { return new IsNullPredicate(getLocation(context), child); } return new IsNotNullPredicate(getLocation(context), child); }
@Override protected String visitIsNullPredicate(IsNullPredicate node, Void context) { return "(" + process(node.getValue(), null) + " IS NULL)"; }
@Override protected String visitIsNullPredicate(IsNullPredicate node, StackableAstVisitorContext<Integer> indent) { return "(" + process(node.getValue(), indent) + " IS NULL)"; }
@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 Expression rewriteIsNotNullPredicate(IsNotNullPredicate node, Void context, ExpressionTreeRewriter<Void> treeRewriter) { Expression value = treeRewriter.rewrite(node.getValue(), context); return new NotExpression(new IsNullPredicate(value)); }
@Override protected Boolean visitIsNullPredicate(IsNullPredicate node, Void context) { return process(node.getValue(), context); }
private static Expression isNotNull(Symbol symbol) { return new NotExpression(new IsNullPredicate(reference(symbol))); }
private static IsNullPredicate isNull(Symbol symbol) { return new IsNullPredicate(reference(symbol)); }
private static IsNullPredicate isNull(Expression expression) { return new IsNullPredicate(expression); }
@Override protected String visitIsNullPredicate(IsNullPredicate node, Boolean unmangleNames) { return "(" + process(node.getValue(), unmangleNames) + " IS NULL)"; }