protected AndedParts completeKey(AndedParts existing, PEColumn c, ConstantExpression litex) { EqualityPart ep = (EqualityPart) existing.getParts().get(0); EqualityPart np = makeNewEqualityPart(ep, c, litex); ArrayList<Part> subp = new ArrayList<Part>(); subp.addAll(existing.getParts()); subp.add(np); List<ExpressionNode> subexprs = Functional.apply(subp, Part.castToExpression); FunctionCall andEx = new FunctionCall(FunctionName.makeAnd(), subexprs); return buildAndedParts(andEx, subp); }
protected AndedParts completeKey(EqualityPart existing, PEColumn c, ConstantExpression litex) { EqualityPart np = makeNewEqualityPart(existing, c, litex); FunctionCall andEx = new FunctionCall( FunctionName.makeAnd(), (ExpressionNode) existing.getParent(), (ExpressionNode) np.getParent()); ArrayList<Part> subp = new ArrayList<Part>(); subp.add(existing); subp.add(np); return buildAndedParts(andEx, subp); }
private LanguageNode handleAndFunction(FunctionCall fc) { // and functions take incomplete simple parts and turn them into complete parts, if so desired ArrayList<Part> incompletes = new ArrayList<Part>(); ArrayList<ExpressionNode> ok = new ArrayList<ExpressionNode>(); ArrayList<Part> subparts = new ArrayList<Part>(); for (ExpressionNode en : fc.getParameters()) { Part p = state.get(en); if (p == null || p.isComplete()) { ok.add(en); if (p != null) subparts.add(p); continue; } incompletes.add(p); } if (incompletes.isEmpty()) return fc; // now we have the problem of a mishmash of incompletes. some may be complex, some may be // simple // some may be collections. we need to handle cases like the following: // (a = 1) and (b = 2) {a,b} (1 key) // (a = 1) and (b = 2 or b = 3) {a,b} (2 keys) // (a = 1 or a = 2) and (b = 3) {a,b} (2 keys) // (a = 1 or a = 2) and (b = 3 or b = 4) {a,b} (4 keys here) // all of the above, where the result is still not complete due to missing tenant column MultiMap<Part, ColumnKey> needed = new MultiMap<Part, ColumnKey>(); MultiMap<ColumnKey, Part> classified = new MultiMap<ColumnKey, Part>(); for (Part p : incompletes) { ListSet<ColumnKey> has = new ListSet<ColumnKey>(); has.addAll(p.getColumns()); needed.putAll(p, parent.getNeeded(has)); for (ColumnKey ck : has) { classified.put(ck, p); } } // so let's say we have a part that is (a = 1 and b = 2), needs c and tenant, and we have a // part // that is c in (1,2,3). The needed for (a = 1 and b = 2) is {c,tenant}. we'll pull (c in // (1,2,3)) // so we'll get at least (a = 1 and b = 2 and c = 3) or (a = 1 and b =2 and c = 3) ... // these we can then individually try to complete. while (!needed.isEmpty()) { combineParts(needed, classified, ok, subparts); } for (Part p : subparts) state.put(p.getParent(), p); if (ok.size() == 1) return ok.get(0); else { // what's left is a mix of unrelated and complete or incomplete subexprs. unrelated nodes // would come in from above, as would previously complete. return new FunctionCall(FunctionName.makeAnd(), ok); } }
@Override public Part copy() { List<Part> newparts = new ArrayList<Part>(); for (Part p : parts) newparts.add(p.copy()); FunctionCall newp = new FunctionCall( FunctionName.makeAnd(), Functional.apply( newparts, new UnaryFunction<ExpressionNode, Part>() { @Override public ExpressionNode evaluate(Part object) { return (ExpressionNode) object.getParent(); } })); return new AndedParts(newp, getTableKey(), newparts, complete); }
private Part buildNewComplexPart(Part lp, Part rp) { ListSet<Part> allParts = new ListSet<Part>(); allParts.addAll(lp.getParts()); allParts.addAll(rp.getParts()); FunctionCall andCall = new FunctionCall( FunctionName.makeAnd(), Functional.apply(allParts, Part.castToExpression)); AndedParts cp = parent.buildAndedParts(andCall, allParts); if (parent.isComplete(cp)) { setComplete(cp); } else if (!parent.isComplete(cp)) { AndedParts ncp = parent.maybeMakeComplete(cp); if (ncp != null) { setComplete(ncp); return ncp; } } return cp; }