mirror of
https://github.com/nosqlbench/nosqlbench.git
synced 2026-10-13 09:52:01 -05:00
feat(vectordata): bind an already-decoded predicate through its binder
A caller that decodes a record itself, to read its fingerprint and pick one binder per shape, binds the node directly with the same shape check rather than decoding twice; the binder also names the shape it was compiled against.
This commit is contained in:
1 parent
7a7928b4e9
commit
19bee2506d
2 files changed
+33
-2
No files matched your search
@@ -70,6 +70,11 @@ public final class PredicateBinder {
|
||||
/// The conditions, in order. Read once, to build the filter.
|
||||
public List<Condition> conditions() { return conditions; }
|
||||
|
||||
/// The shape this binder was compiled against, in the display
|
||||
/// grammar with every comparand replaced by its type default — the
|
||||
/// identity a caller keys one binder per shape by.
|
||||
public String shape() { return shape.display(); }
|
||||
|
||||
/// Receives one condition's comparands from a bound predicate.
|
||||
@FunctionalInterface
|
||||
public interface ConditionSink { void accept(Condition condition, List<Comparand> comparands); }
|
||||
@@ -91,9 +96,17 @@ public final class PredicateBinder {
|
||||
// template cannot make an MNode into a predicate.
|
||||
if (!(node instanceof ANode.P p))
|
||||
throw BindException.record("this record is not a predicate — its dialect byte says MNode, and a form does not override what a record is");
|
||||
if (!p.node().isCongruent(shape))
|
||||
bindEach(p.node(), sink);
|
||||
}
|
||||
|
||||
/// Binds one already-decoded predicate, for a caller that decoded
|
||||
/// the record itself — to read its fingerprint and choose the
|
||||
/// binder, say — so the node is not decoded twice. The shape check
|
||||
/// is the same.
|
||||
public void bindEach(PNode predicate, ConditionSink sink) {
|
||||
if (!predicate.isCongruent(shape))
|
||||
throw BindException.record("this predicate's shape differs from the one this binder was compiled against; its values would bind to the wrong conditions");
|
||||
List<Scan.FlatCondition> flat = Scan.flattenAnd(p.node());
|
||||
List<Scan.FlatCondition> flat = Scan.flattenAnd(predicate);
|
||||
if (flat == null) throw BindException.record("predicate is not a flat conjunction");
|
||||
for (int i = 0; i < conditions.size() && i < flat.size(); i++) sink.accept(conditions.get(i), flat.get(i).comparands());
|
||||
}
|
||||
|
||||
@@ -374,6 +374,24 @@ class RecordBindingTest {
|
||||
assertTrue(e.getMessage().contains("flat conjunction"), e.getMessage());
|
||||
}
|
||||
|
||||
/// A caller that decoded the record itself — to read its fingerprint
|
||||
/// and pick one binder per shape — binds the node directly, with the
|
||||
/// same shape check, and the binder names the shape it was compiled
|
||||
/// against.
|
||||
@Test void aDecodedPredicateBindsWithoutASecondDecode() throws IOException {
|
||||
Layout layout = typedLayout("decoded");
|
||||
PNode template = and(pred("created", OpType.GE, new Comparand.Int(0)), pred("tag", OpType.EQ, new Comparand.Text("")));
|
||||
PredicateBinder binder = PredicateBinder.compile(template, layout);
|
||||
assertEquals("(created >= 0 AND tag = '')", binder.shape());
|
||||
PNode actual = and(pred("created", OpType.GE, new Comparand.Int(7)), pred("tag", OpType.EQ, new Comparand.Text("red")));
|
||||
assertEquals(binder.shape(), actual.fingerprint().display(), "the same shape keys the same binder");
|
||||
List<Comparand> bound = new ArrayList<>();
|
||||
binder.bindEach(actual, (cond, cs) -> bound.add(cs.get(0)));
|
||||
assertEquals(List.of(new Comparand.Int(7), new Comparand.Text("red")), bound);
|
||||
PNode other = pred("id", OpType.EQ, new Comparand.Int(1));
|
||||
assertTrue(assertThrows(BindException.class, () -> binder.bindEach(other, (c, cs) -> { })).getMessage().contains("shape differs"));
|
||||
}
|
||||
|
||||
// ── error paths and the small surface ──────────────────────────
|
||||
|
||||
/// A facet with no records has no layout to learn, and says so
|
||||
|
||||
Reference in new issue
Block a user