Minor Changes
-
#3148
854e98a
Thanks @benjie! - SwitchPgSelectStepand
PgUnionStepfrom a subquery lateral join to a materialized CTE lateral
join. This appears to fix some bad planning decisions that Postgres can make,
e.g. where it might attempt a full table scan hash join rather than a fast
loop with efficient index lookups. -
#3178
80545aa
Thanks @benjie! -pgResource.get(...)now
allows steps representing null/undefined in each field - requiring the steps
be non-null does not guarantee the result will exist so it just adds burden
for plan writers without benefit. -
#3185
fac3cd3
Thanks @benjie! -PgInsertSingleStep,
PgUpdateSingleStepandPgDeleteSingleStepgain new experimental "wrap"
functionality allowing you to wrap a CRUD mutation with logic before and after
whilst retaining access to the database transaction (e.g. to allow
abort/rollback). Useful for data validation, coercion, result validation, and
auditing. -
#3192
e8709d1
Thanks @benjie! - PgExecutor now groups similar
queries and runs them through the same connection, reducing the overhead from
multiple transaction handshakes and making better use of prepared statements
and similar optimizations. Reduces both parallelism and overhead, hopefully
netting an overall performance win with some potential per-request latency
trade-offs. -
#3146
cfda9fa
Thanks @benjie! -PgSelectStepnow allows
influencing the inlining strategy used to inline one query into a parent with
setInliningStrategy(...):preferLeftJoin,preferSubquery,autoor
forbidden. It also allows influencing how child queries inline into the
current query withsetChildInliningStrategy(...); this applies when the
child usesauto, unless set toforbiddenin which case children are not
inlined.The auto behavior (default) is now smarter: rather than always using a left
join where possible (as before), the system will now aim to have no more than
7 joins (to avoid combinatorics pressure in PostgreSQL query planning) and
will also not use a left join to inline a PgSelectStep that itself has joins,
inlined children, or.apply()s - instead a subquery will be used. This will
likely impact your query performances (hence semver minor) but hopefully in a
positive way - especially if you have large queries with lots of to-one
relations at many depths. -
#3125
a531205
Thanks @benjie! - Empty ranges are now recognized
and represented both on input and output. -
#3180
2ab53f8
Thanks @benjie! - Useunnest()rather than
json_array_elements()to feed pgSettings to Postgres. -
#3178
753ee63
Thanks @benjie! -pgResource.find(...)is now
more precise about the requirements of the fields; previouslyStep<any>was
accepted, but now the Step must represent the datatype of the field (or
null/undefined). -
#3122
7d10815
Thanks @benjie! - Improves types in
@dataplan/pgaround codecs, resources, nullability, range values, and
resource execution arguments. Adds support for PostGraphile Pro (V5) type
generation.NOTE:
pgResource.execute(...)no longer acceptspgCodecin the
arguments; it was always ignored internally because the parameter codec was
used, now we explicitly don't accept it.{ step, name?, pgCodec }→
{ step, name? }The new PostGraphile Pro (V5) plugin can generate registry, plan resolver,
introspection (for smart tags) and other related types, and even supports
correct types across multiple PostGraphile schemas in the same TypeScript
environment. The generated-schema-aware types provide checked schema names,
tables, fields, arguments, nullability, and PostgreSQL resource types where
available, while preserving broad fallbacks when they are not.With this plugin, many of the standard PostGraphile APIs can become more
strongly typed with minimal user input. If you only have one PostGraphile
instance then using the default generation should be picked up automatically
by most plugin helpers --extendSchema(),wrapPlans()(for the
filter-based form ofwrapPlans(), pass thescopeproperty to options
rather than adding a generic, this allows the filter return type to still be
inferred automatically),pgSmartTags(),changeNullability(),
addPgTableCondition(),addPgTableOrderBy()-- and for manual plugins you
can use thescopedPlugin(...)helper to define your plugin. If you run
multiple schemas then you can pass a generic (e.g.
extendSchema<"public-api">(...)) to indicate the types to use. -
#3177
23fe156
Thanks @benjie! - Automatically skip fetches when
we know no rows can be returned due toWHERE some_column = null(which is
always falsy). -
#3185
e529f24
Thanks @benjie! -PgUpdateSingleStepno longer
throws an error if you don't provide any values to update; instead it simply
exits having changed no rows.
Patch Changes
-
#3151
f309fd7
Thanks @benjie! - Did you know the parent step
for a table type isn't necessarily a PgSelectSingleStep? It can also be a
PgInsertSingleStep, PgUpdateSingleStep or PgDeleteSingleStep. Normally this
doesn't matter to much - if all you're doing is.get(attr)then it should
work great (and makes the mutations better because they're only
RETURNING ...the attributes you need); but if you want to do
$parent.select(...)now you have an issue...Introducing
PgClassSingleStep.toSelectSingle(); now you can easily get a
PgSelectSingleStep to work with:const myPlan = ($parentClass: PgClassSingleStep, fieldArgs) => { const $parent: PgSelectSingleStep = $parentClass.toSelectSingle(); $parent.select(/*...*/)
-
#3109
e991bd8
Thanks @benjaie! - Add groundwork for modified
PostgreSQL codecs keyed by type modifier and constraints, including base-codec
relationships for GraphQL type resolution. -
#3231
e3bbac3
Thanks @benjie! - ExportPgWrapCallbacktype
(experimental) -
#3182
061e9b2
Thanks @benjie! - Performance: add deduplication
of queries directly topgSelect. -
#3153
90810f5
Thanks @benjie! -
makeWithPgClientViaPgClientAlreadyInTransactionis intended to be used in
tests for a PoolClient fresh from apgconnection pool, not in positions
where you've extracted the client from a*WithPgClient(...)step via the
.rawClientattribute. To help avoid users causing themselves deadlocks,
we've added a throw if you try to
makeWithPgClientViaPgClientAlreadyInTransaction(nodePostgresPgClient.rawClient). -
#3186
03251c3
Thanks @benjaie! - Add
GraphileConfig.DataplanPgClientin more places so you get your chosen
adaptor showing up in the types automatically. -
#3132
ce7a395
Thanks @copilot-swe-agent! -
RemovestripInternalfrom the shared TypeScript compiler options.
Previously, symbols tagged with/** @internal */were stripped from the
generated.d.tsdeclaration files; they will now be included. This makes
internal APIs visible in TypeScript but does not change any runtime behaviour. -
#3152
bd44c67
Thanks @benjie! - Query builder gains
.getOrderIsUnique()with some big comments about how you probably shouldn't
use it... -
#3175
6856d78
Thanks @benjaie! - The@dataplan/pgadaptor
type is now guessed from which adaptors you have loaded into TypeScript (via
path imports), so casting@dataplan/pg'sPgClientto
NodePostgresPgClient(to indicate you're using@dataplan/pg/adaptors/pg)
should no longer be necessary in most cases. -
#3174
f0efc90
Thanks @benjaie! -PgResource.execute()now
infers result type from underlying function signature. This has added two more
generics toPgResourceandPgResourceOptions, so you may need to update
your code if you are explicitly stating these generics. -
Updated dependencies
[8fc04f0,
7c39592,
85a3d1c,
26a3fc4,
92978f3,
631ed94,
0c73163,
ce7a395,
7d10815,
4b948fc,
a38b59f]:- grafast@1.2.0
- @dataplan/json@1.0.2
- @graphile/lru@5.0.1
- pg-sql2@5.0.2