github graphile/crystal postgraphile@5.2.0

Minor Changes

  • #3148
    854e98a
    Thanks @benjie! - Switch PgSelectStep and
    PgUnionStep from 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,
    PgUpdateSingleStep and PgDeleteSingleStep gain 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! - PgSelectStep now allows
    influencing the inlining strategy used to inline one query into a parent with
    setInliningStrategy(...): preferLeftJoin, preferSubquery, auto or
    forbidden. It also allows influencing how child queries inline into the
    current query with setChildInliningStrategy(...); this applies when the
    child uses auto, unless set to forbidden in 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! - Use unnest() 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; previously Step<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/pg around codecs, resources, nullability, range values, and
    resource execution arguments. Adds support for PostGraphile Pro (V5) type
    generation.

    NOTE: pgResource.execute(...) no longer accepts pgCodec in 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 of wrapPlans(), pass the scope property 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 the scopedPlugin(...) 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 to WHERE some_column = null (which is
    always falsy).

  • #3185
    e529f24
    Thanks @benjie! - PgUpdateSingleStep no 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_table or "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 to pgSelect.

  • #3186
    03251c3
    Thanks @benjaie! - Add
    GraphileConfig.DataplanPgClient in more places so you get your chosen
    adaptor showing up in the types automatically.

  • #3132
    ce7a395
    Thanks @copilot-swe-agent! -
    Remove stripInternal from the shared TypeScript compiler options.
    Previously, symbols tagged with /** @internal */ were stripped from the
    generated .d.ts declaration 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/pg adaptor
    type is now guessed from which adaptors you have loaded into TypeScript (via
    path imports), so casting @dataplan/pg's PgClient to
    NodePostgresPgClient (to indicate you're using @dataplan/pg/adaptors/pg)
    should no longer be necessary in most cases.

  • #3142
    582e349
    Thanks @benjie! - addPgTableOrderBy's
    orderByAscDesc helper 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 in connection()
    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/pageInfo requested). 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! - wrapPlans can use full
    GraphileBuild.Build object in callback, not partial type.

  • #3188
    a38b59f
    Thanks @benjie! - Expose prepare function 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.getTypeMetaByName now
    returns a TypeScript union of TypeMeta that differentiates over
    {kind: "OBJECT" | "INTERFACE" | "UNION" | "SCALAR" | "ENUM" | "INPUT_OBJECT", ...},
    allowing you to get a typed scope by simply asserting the typeMeta.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

Don't miss a new crystal release

NewReleases is sending notifications on new releases.