Skip to content

Facet kinds from Python: HIERARCHY, DISTINCT, STATS, AFTER and facet.searchValues (closes #291) - #301

Merged
tae898 merged 2 commits into
mainfrom
feat/291-facet-kinds
Nov 7, 2026
Merged

tae898 merged 2 commits into
mainfrom
feat/291-facet-kinds

Conversation

@tae898

@tae898 tae898 commented Nov 7, 2026 •

Copy link
Copy Markdown
Collaborator

Closes #291

I read the engine side of the later facet kinds (ArcadeData/arcadedb PR #11344) against the decoders from #299 and found no decoding gap in either package, so this PR changes no behavior. STATS min and max, DISTINCT value and exact, the hierarchy bucket attributes (parent, depth, orphan) and the AFTER cursor all pass through the same value conversion a row uses (convert_java_to_python on arcadedb-jvm, NativeCodec.append in FacetsReply on native), and facet.searchValues is an ordinary SQL function whose rows decode like any other. What the issue still needed was proof and documentation.

tests/test_result_set_facets_kinds.py runs on both packages through the public API and is version-gated like tests/test_result_set_facets.py (an engine older than 26.12.1 must refuse the clause with SQL syntax error, nothing is skipped).

  • STATS: int, FLOAT and DOUBLE columns with exact sums, DATE and DATETIME extremes equal to what a row of the column holds (with sum and avg None), no match, records without a value, NaN and the infinities against SQL's own min, max, sum and avg, signed zeros.
  • DISTINCT: exact counts against GROUP BY, a list indexed BY ITEM, PRECISION n with exact False and meta["exact"] False.
  • HIERARCHY: the flat bucket list with parent, depth and orphan, TOP with other_count, and a FILTER parameter narrowing the hierarchy.
  • AFTER: paging a string, LONG and DATETIME facet until the cursor is None and comparing with GROUP BY, MISSING once on the last page, a positional cursor, a cursor past the end, other_count on the last page, and the refusal of ORDER BY COUNT.
  • facet.searchValues: prefix, limit, counts against GROUP BY, named, positional and literal arguments, the value of a deleted record, and the errors.
  • Parameters: named and positional in every FILTER and in AFTER, through query and command. The grammar takes TOP, MIN_COUNT and PRECISION as integer literals only, so those are not tested with parameters.

facet.searchValues reads dictionaries the projection has applied, so its tests retry until the projection caught up (a hang detector, not a latency bound). Facet queries need no wait, the engine patches lagging records.

The facets docstring of both packages now states the shape of each kind and which clauses take parameters.

Verified: compile(), pyflakes (only the existing unused-import notes in _native/database.py), pre-commit and Bandit on the new file. Not verified: nothing was run locally because the laptop guard blocks workloads, so CI is the first run. The JVM lane runs the real facet tests; the native PR gate links 26.11.1, so there they assert the refusal. The real native run is a dispatched test-native.yml against 26.12.1-SNAPSHOT (run https://github.com/ArcadeData/arcadedb-python/actions/runs/42321136193).

🤖 Generated with Claude Code

tae898 and others added 2 commits November 7, 2026 09:55
…searchValues (closes #291)

Reading the engine (ArcadeData/arcadedb PR #11344) against the decoders of #299 found no gap in either package: STATS min and max, DISTINCT value and exact, the hierarchy attributes (parent, depth, orphan) and the AFTER cursor all go through the same value conversion a row uses (convert_java_to_python on the JVM, NativeCodec.append in FacetsReply on native), and facet.searchValues is an ordinary SQL function whose rows decode like any other. So no code changes, only what the issue asks for: proof and documentation.

- tests/test_result_set_facets_kinds.py runs on both packages through the public API and is version-gated like test_result_set_facets.py (an older engine must refuse the clause with 'SQL syntax error'). STATS: int, FLOAT and DOUBLE columns with exact sums, DATE and DATETIME extremes equal to what a row of the column holds (sum and avg None), no match, records without a value, NaN and the infinities against SQL's own min, max, sum and avg, signed zeros. DISTINCT: exact counts against GROUP BY, a list indexed BY ITEM, PRECISION n with exact False and meta exact False. HIERARCHY: the flat bucket list with parent, depth and orphan, TOP and other_count, a FILTER parameter. AFTER: paging a STRING, LONG and DATETIME facet until the cursor is None and comparing with GROUP BY, MISSING once on the last page, a positional cursor, a cursor past the end, other_count on the last page, the refusal of ORDER BY COUNT. facet.searchValues: prefix, limit, counts against GROUP BY, named, positional and literal arguments, a deleted record's value, the errors.
- Parameters: named and positional in every FILTER (STATS, DISTINCT, HIERARCHY's neighbour) and in AFTER, through query and command. The grammar takes TOP, MIN_COUNT and PRECISION as integer literals only; that is documented.
- facet.searchValues reads dictionaries the projection has applied, so its tests retry until the projection caught up (a hang detector, not a latency bound); facet queries need no wait, the engine patches lagging records.
- The facets docstring of both packages now states the shape of each kind and which clauses take parameters.

Nothing was run locally (the laptop guard blocks workloads); CI is the first run.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…e's threshold (refs #291)

The native snapshot run showed `DISTINCT PRECISION 10` on a column of ten values reports exact True. The engine (DistinctFacetCollector) keeps the exact set while it holds at most n values and switches to a HyperLogLog only when exactSize() > precisionThreshold, so ten values never cross PRECISION 10; my test guessed the flag. The approximate case now uses PRECISION 5 on the ten-valued DOUBLE column price (the numeric path the engine documents as approximable), with the error tolerance widened to 2, and a new test pins the other side: PRECISION 10 on the same ten values stays exact.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@tae898
tae898 merged commit 5323778 into main Nov 7, 2026
50 checks passed
@tae898
tae898 deleted the feat/291-facet-kinds branch November 7, 2026 02:06
@github-actions github-actions Bot added this to the 26.12.1 milestone Nov 7, 2026
abhirajadhikary06 pushed a commit to abhirajadhikary06/arcadedb-python that referenced this pull request Nov 10, 2026
The release line (tag 26.11.1.post2 = 1454809, which contains the post1 tag
26.11.1.post1 = dbe1670) branched from the 26.11.1 tag and carries the post1
candidates (the native column frames ArcadeData#331, the other native and JVM load and read changes
of ArcadeData#327 to ArcadeData#339, and the cherry-picks of main's ArcadeData#320 and ArcadeData#321),
the post2 additions (Windows parity harness ArcadeData#295/ArcadeData#347, ArcadeData#340, the JVM Arrow
vector load change) and their test fixes. Main did not have them. The merge
uses a merge commit so that the release tag stays an ancestor of main.

Four files conflicted, each because main and the release line changed the
same lines. Resolutions, each checked against the history of both sides:

- src/arcadedb/_native/columns.py (modify/delete): deleted. Main changed it
  only with ArcadeData#321 (6c6a5a1). The release line holds the same change as the
  cherry-pick 946dfda (identical blobs of columns.py and of
  test_native_columns_reference.py at both commits) and then deleted the
  module with the native column frames (ArcadeData#331, d606cce). Nothing else imports
  it; the merged database.py reads columns through the frames code.
- src/arcadedb/_native/database.py: kept both. Main's facets lines in _fill
  and its facets property (ArcadeData#299, ArcadeData#301), then the release line's
  self._note_vectors(reply) before the return and its _note_vectors method.
- tests/conftest.py: the release side of the native-only block (the
  comment of test_native_columns_reference.py now says what the file
  compares, plus the two new native-only files), and both entries in
  WINDOWS_NOT_APPLICABLE (main's test_dev_engine_pin.py and the release
  line's test_parity_gate_awk.py).
- tests/test_native_columns_reference.py (add/add): the release side whole.
  Main's file tested the deleted module.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Columnar faceting: HIERARCHY, DISTINCT, STATS, AFTER and facet.searchValues from Python

1 participant