Skip to content

docs: plan filtrify conditions as a runtime translator - #10

Open
roderm wants to merge 1 commit into
masterfrom
docs/filtrify-conditions
Open

roderm wants to merge 1 commit into
masterfrom
docs/filtrify-conditions

Conversation

@roderm

@roderm roderm commented Sep 7, 2026

Copy link
Copy Markdown
Collaborator

Design only — nothing implemented. Carried over from the pre-move repository, where it was never pushed.

The main finding

The third plugin does not need a writer. Load<Msg> already takes conds ...query.Cond, so a filter is just another condition:

cond, err := filter.Build(crmv1.PersonTable, expr)
people, err := crmv1.LoadPerson(ctx, conn, mask, cond)

The generated files stay exactly as they are. The work is metadata plus one translation function.

What is missing is metadata

Three small additions to what the schema writer already emits — proto_name on SchemaColumn (filters name proto fields, never columns), entity on SchemaTable, and a per-file Tables registry so HasChildren can find a child table. The registry also closes the gap where migration.Create makes callers hand-list every table.

The blocking decision

filtrify speaks message fields and entities and never learns table or column names, so the translation has to happen on this side, where the metadata and the SQL assembly already live. That needs the AST types here, which the two-dependency rule forbids — and importing filtrify/ast/v1 today also links grpc, since the generated gRPC service shares that package.

Recommended: relax the rule for the AST once those messages move to a package without the service. Alternative is a bridge module. Both are laid out in the doc, along with why walking the AST through protoreflect to dodge the dependency was rejected.

Also recorded

  • Whether to replace the hand-rolled builder with a library. Measured rather than assumed: one would own about a quarter of pkg/query and none of the subtle parts (Mask, Key), which are the two that have actually had bugs. bob/dialect/psql and goqu are the only candidates with a real upsert API — relevant since conflict handling is on the roadmap.
  • filtrify's parser defaults an unrecognised operator to equality rather than failing, so a ~ b becomes a = b before the AST exists. Any operator a SQL whitelist would reject is already lost upstream.

Open questions

  1. HasChildren.entity — entity name or relation field name? They differ as soon as a parent has two relations to the same entity, and an entity name cannot disambiguate.
  2. contains semantics: %/_ escaping and case sensitivity both differ per dialect.
  3. IsNullExpr is declared but not in Expr's oneof — wire it in or drop it.

🤖 Generated with Claude Code

@roderm
roderm force-pushed the master branch 2 times, most recently from 084c9bd to 3e43337 Compare September 7, 2026 07:47
Carried over from the pre-move repository, where it was never pushed.

The third plugin turns out not to need a writer. Load<Msg> already takes
`conds ...query.Cond`, so a filter is just another condition and the
generated files stay as they are -- the work is metadata plus one
translation function, not templates.

What is missing is metadata, not code: SchemaColumn carries only the SQL
name while filters name proto fields, SchemaTable has no message name for
HasChildren to resolve, and there is no runtime registry to look a table
up by entity. The registry also closes the existing gap where
migration.Create makes callers hand-list every table.

Because filtrify speaks message fields and entities and never learns
table or column names, the translation has to happen on this side, where
the metadata and the SQL assembly already are. That needs the AST types
here, which the two-dependency rule currently forbids -- and importing
filtrify/ast/v1 today also links grpc, since the generated gRPC service
shares that package.

Also weighs replacing the hand-rolled builder: measured, a library owns
about a quarter of pkg/query and none of the subtle parts, but bob and
goqu are the only ones with a real upsert API.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@roderm
roderm force-pushed the docs/filtrify-conditions branch from d0acfdd to b45e296 Compare September 7, 2026 08:21
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.

1 participant