Repository navigation
feat: the SQL dialect a filter is written in - #28
Merged
Merged
Conversation
The parser checks an expression and does not translate one: a caller hands the filter's text to its database, so what the parser accepts has to be what that database runs. It always read PostgreSQL's grammar and said so nowhere but in its tests. WithDialect names it: DialectPostgreSQL, the default and the zero value, every operator as before; or DialectSQLStandard, ISO/IEC 9075:2023, which refuses what PostgreSQL's manual calls its own (!=, ILIKE, the ~~ and ~ operators, ISNULL and NOTNULL, an empty ESCAPE), each refusal naming the standard's spelling. What it keeps is listed with the standard's feature ids, from PostgreSQL's SQL Conformance appendix. The dialect is checked before the allow-list: an operator it does not have is refused however allowed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The package doc (what pkg.go.dev shows) was two lines; it says the filter grammar is PostgreSQL's by default, or the standard's with WithDialect. The documentation index's diagram shows the dialect gating the filter parser, and its guide table names it; Getting Started, Error Handling and Filtering (its opening and its pipeline diagram) say it; ExampleWithDialect is runnable on pkg.go.dev. Every diagram was rendered. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What was wrong
The parser checks an expression and does not translate one: a caller hands the filter's text to its database. So "accepted" has to mean "this database runs it". The grammar was always PostgreSQL's, every rule checked against PostgreSQL 18, but the package said so nowhere except in its tests.
What changes
Dialect, chosen withWithDialect. It is a small struct with two exported values, so a dialect that does not exist cannot be named. The zero value isDialectPostgreSQL, and nothing changes for a caller that passes no option.DialectPostgreSQL(default)DialectSQLStandardThe standard dialect refuses PostgreSQL's own spellings. Each refusal names the standard's spelling, and each quotes PostgreSQL's manual:
!=: write<>;ILIKE;~~operators: writeLIKE;~: the standard's regular expressions areLIKE_REGEX, which this package does not parse;ISNULLandNOTNULL: writeIS [NOT] NULL;ESCAPE.What it keeps, with the standard's feature IDs:
BETWEEN, T461 itsSYMMETRICform, E061-03IN;LIKE, E061-05 itsESCAPEclause;SIMILAR TO, T151 and T152IS [NOT] DISTINCT FROM;The dialect is checked before the allow-list. An operator the dialect does not have is refused whether
WithAllowedOperatorsallows it or not.Dialect.Operators()says which operators a dialect has.One difference cannot be checked, and the docs say so: without
ESCAPE, the standard has no escape character, where PostgreSQL's is the backslash.Together with #27 (
ESCAPE), this is v1.1.0. The migration guide's v1.0.5 → v1.1.0 section covers both.How it was checked
TestTheSQLStandardDialect:TestTheDefaultDialectIsPostgreSQL: the zero value is PostgreSQL, and those 14 inputs are accepted with and without the option.TestTheDialectNarrowsTheAllowedOperators: allowingILIKEdoes not put it in the standard.!=not checked.~~not checked.ISNULLnot checked.ESCAPEaccepted in the standard.go test -racepasses, coverage is 98.2%, andgolangci-lintreports 0 issues.Docs, every page that describes the filter parser, and each changed diagram rendered:
configuration.md: a section on the dialect, with its tables, and the gating diagram;docs/README.md: the parsers diagram shows the dialect, and the guide table names it;filtering.md: its opening and its pipeline diagram;getting-started.md,error-handling.md,README.md,migration.md;docs.go, which is what pkg.go.dev shows;ExampleWithDialect.🤖 Generated with Claude Code