feat: data representations allow custom parsing and formatting of API fields.

See PR #2523. Most notable code changes:

- Load data representation casts into schema cache.
- Data representations for reads, filters, inserts, updates, views, over joins.
- `CoercibleField` represents name references in queries where coercion may be needed.
- `ResolverContext` help facilitate field resolution during planning.
- Planner 'resolves' names in the API query and pairs them with any implicit conversions to be used in the query builder stage.
- Tests for all of the above.
- More consistent naming (TypedX -> CoercibleX).

New: unit tests for more data representation use cases; helpful as examples as well.

New: update CHANGELOG with data representations feature description.

Fixed failing idempotence test.

New: replace date formatter test with one that does something.

Fixup: inadvertent CHANGELOG change after rebase.

Cleanup: `tfName` -> `cfName` and related.

Document what IRType means.

Formatting.

New: use a subquery to interpret `IN` literals requiring data rep transformation.

- With the previous method, very long queries such as `ANY (ARRAY[test.color('000100'), test.color('CAFE12'), test.color('01E240'), ...` could be generated. Consider the case where the parser function name is 45 characters and there's a hundred literals. That's 4.5kB of SQL just for the function name alone!
- New version uses `unnest`: `ANY (SELECT test.color(unnest('{000100,CAFE12,01E240,...}'::text[]))` to produce a much shorter query.
- This is likely to be more performant and either way much more readable and debuggable in the logs.
This commit is contained in:
Alexander Ljungberg
2023-06-29 15:01:58 -05:00
committed by Steve Chavez
parent 078c6ec08c
commit 0a1564ba5a
17 changed files with 1045 additions and 163 deletions
+8 -7
View File
@@ -6,8 +6,9 @@ where
import qualified Data.ByteString.Lazy as LBS
import PostgREST.ApiRequest.Preferences (PreferResolution)
import PostgREST.ApiRequest.Types (LogicTree, OrderTerm)
import PostgREST.Plan.Types (TypedField)
import PostgREST.ApiRequest.Types (OrderTerm)
import PostgREST.Plan.Types (CoercibleField,
CoercibleLogicTree)
import PostgREST.RangeQuery (NonnegRange)
import PostgREST.SchemaCache.Identifiers (FieldName,
QualifiedIdentifier)
@@ -18,19 +19,19 @@ import Protolude
data MutatePlan
= Insert
{ in_ :: QualifiedIdentifier
, insCols :: [TypedField]
, insCols :: [CoercibleField]
, insBody :: Maybe LBS.ByteString
, onConflict :: Maybe (PreferResolution, [FieldName])
, where_ :: [LogicTree]
, where_ :: [CoercibleLogicTree]
, returning :: [FieldName]
, insPkCols :: [FieldName]
, applyDefs :: Bool
}
| Update
{ in_ :: QualifiedIdentifier
, updCols :: [TypedField]
, updCols :: [CoercibleField]
, updBody :: Maybe LBS.ByteString
, where_ :: [LogicTree]
, where_ :: [CoercibleLogicTree]
, mutRange :: NonnegRange
, mutOrder :: [OrderTerm]
, returning :: [FieldName]
@@ -38,7 +39,7 @@ data MutatePlan
}
| Delete
{ in_ :: QualifiedIdentifier
, where_ :: [LogicTree]
, where_ :: [CoercibleLogicTree]
, mutRange :: NonnegRange
, mutOrder :: [OrderTerm]
, returning :: [FieldName]