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. -
#3172
ead97bc
Thanks @benjie! -build.getGraphQLTypeByPgCodec
now reflects input/output type based on variant; manual narrowing is no longer
required. -
#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. -
#3173
c7dfb07
Thanks @benjie! - Fixed @returntype for functions
returning setof (for lists and connections) - thanks @tsnobip! -
#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. -
#3138
3953e87
Thanks @benjie! - Slightly more stable ordering
is used in schema construction, to make schemas ordering more stable. (Sadly,
introducing this is likely to change the order of your schema.) -
#3144
56ae052
Thanks @benjie! -addPgTableCondition()and
addPgTableOrderBy()now support the match being specified as a string:
my_schema.my_tableor"my.weird.schema"."my""weird""table"saving you
having to type out object definitions (previously:
{schemaName:"my_schema",tableName:"my_table"})
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. -
#3173
901c0d1
Thanks @benjie! - Fixes bug in "Reads and enables
pagination through a set of ..." message (Int4 -> Int, Int8 -> BigInt, honours
inflection for types, etc) -
#3182
061e9b2
Thanks @benjie! - Performance: add deduplication
of queries directly topgSelect. -
#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. -
#3176
0ea54a4
Thanks @benjaie! - Improve types for
wrapPlans()' SmartFieldPlanResolver. -
#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. -
#3142
582e349
Thanks @benjie! -addPgTableOrderBy's
orderByAscDeschelper can now handle a list of expressions via the callback
shape. -
#3187
92dbe1b
Thanks @benjie! -*WithPgClient()steps can now
use full Multistep syntax, not just record syntax -
#3194
4b948fc
Thanks @benjie! - Fix a bug inconnection()
where adding pagination arguments (e.g.first: 0) for a connection over a
full-pagination-support step would force the underlying collection to fetch
even when none of the data was needed for rendering (e.g. no
nodes/edges/pageInforequested). This is particularly relevant to
PostGraphile queries such as{ allRows(first: 0) { totalCount } }which
would incorrectly issue two SQL queries instead of one. -
#3135
f47ce6d
Thanks @benjie! -wrapPlanscan use full
GraphileBuild.Buildobject in callback, not partial type. -
#3188
a38b59f
Thanks @benjie! - Exposepreparefunction that
performs operation planning but does not execute the operation. Useful for
pre-warming the operation plan cache on server start. -
#3172
18bbd00
Thanks @benjie! -build.getTypeMetaByNamenow
returns a TypeScript union of TypeMeta that differentiates over
{kind: "OBJECT" | "INTERFACE" | "UNION" | "SCALAR" | "ENUM" | "INPUT_OBJECT", ...},
allowing you to get a typedscopeby simply asserting thetypeMeta.kind
you're expecting. -
Updated dependencies
[8fc04f0,
5e6bb5f,
854e98a,
7c39592,
85a3d1c,
26a3fc4,
ead97bc,
92978f3,
f309fd7,
80545aa,
fac3cd3,
e991bd8,
631ed94,
e8709d1,
c7dfb07,
901c0d1,
e3bbac3,
061e9b2,
cfda9fa,
a531205,
261078d,
2ab53f8,
90810f5,
03251c3,
0c73163,
753ee63,
ce7a395,
0ea54a4,
7d10815,
bd44c67,
23fe156,
6856d78,
582e349,
92dbe1b,
e529f24,
4b948fc,
3953e87,
f0efc90,
f47ce6d,
56ae052,
92b3ddf,
a38b59f,
18bbd00]:- grafast@1.2.0
- graphile-utils@5.1.0
- @dataplan/pg@1.2.0
- graphile-build-pg@5.2.0
- @dataplan/json@1.0.2
- @graphile/lru@5.0.1
- grafserv@1.0.3
- graphile-build@5.2.0
- graphile-config@1.1.2
- pg-sql2@5.0.2
- tamedevil@0.1.2