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
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