Skip to content

feat(drizzle): support mixed has-many/single select in polymorphic join where - #18235

Draft
r1tsuu wants to merge 1 commit into
3.xfrom
feat/polymorphic-join-where-restore-support-3x
Draft

r1tsuu wants to merge 1 commit into
3.xfrom
feat/polymorphic-join-where-restore-support-3x

Conversation

@r1tsuu

@r1tsuu r1tsuu commented Sep 21, 2026

Copy link
Copy Markdown
Member

Written by AI

Draft. 3.x backport of #18233 — follow-up to 9339d63 (PYLD-3840). Partially restores one of the polymorphic-join where shapes that 9339d63 made fail-closed. Arguably more valuable on the stable line, since it shrinks the breaking-change surface of 9339d63.

What this restores

A select field stored has-many (separate value rows) in one polymorphic target collection and as a single select column in another — when the targets share identical option values. This is the common case of the same logical field declared hasMany in one collection but not another.

Each branch is compiled per-collection with its own storage handler (has-many → JSON value-table subquery; single → scalar column) and unioned on the stable id/relationTo/sort projection, so the combined caller + access where is applied in full to every branch — nothing dropped or truncated (no PYLD-3840 regression). The two rejects.toThrow mixed-shape int tests are flipped to positive filtering assertions that prove the constraint includes the authorized has-many row and excludes the unauthorized single-select row; the plan unit spec gains a mixedSelect acceptance case + a differing-options rejection case.

Shapes that cannot be compiled soundly stay fail-closed: text-vs-number scalars, differing option sets, unsupported operators.

Still deferred

The remaining categories (localized, array/blocks, relationship/upload/json traversal, geo operators) remain fail-closed. The per-category secure implementation plan — including the text-vs-number fail-open hazard (Number('x')→NaN→null→IS NULL matching all value-less rows) that must be guarded before it can ever be enabled — is tracked in the oss-main PR #18233 (polymorphic-join-where-support-plan.md). It applies to 3.x too, except 3.x lacks the buildOperatorConstraint/locale plumbing main has, so the localized/relationship plans there need the equivalent wiring built first.

Verification

  • Unit (packages/drizzle/src/find): 85 pass
  • test/joins/int.spec.ts: 114 pass / 2 skip (sqlite), 116 pass (postgres)

Independently written and run against 3.x. Left as a draft for review — not for merge.

Companion: #18233 (main).

…in where

Restore polymorphic join `where` support for a select path that is stored
has-many (separate value rows) in one target collection and as a single
select column in another, when the targets share identical option values.
Each branch is compiled per-collection with its own storage handler and
unioned on the stable id/relationTo/sort projection, so the combined
caller + access `where` is applied in full to every branch (no dropped or
truncated constraints). Shapes that cannot be compiled soundly — text vs
number scalars, differing option sets, unsupported operators — remain
fail-closed.

Backport of the mixed-select restoration from the oss-main change; the
remaining categories (localized, array/blocks, relationship/upload/json,
geo) stay fail-closed with the secure plan tracked on the oss-main PR.
@github-actions

Copy link
Copy Markdown
Contributor

📦 esbuild Bundle Analysis for payload

This analysis was generated by esbuild-bundle-analyzer. 🤖

Meta File Out File Size (raw) Note
packages/next/meta_index.json esbuild/index.js 1.00 MB 🆕 Added
packages/payload/meta_index.json esbuild/index.js 1.47 MB 🆕 Added
packages/payload/meta_shared.json esbuild/exports/shared.js 202.55 KB 🆕 Added
packages/richtext-lexical/meta_client.json esbuild/exports/client_optimized/index.js 290.90 KB 🆕 Added
packages/ui/meta_client.json esbuild/exports/client_optimized/index.js 1.19 MB 🆕 Added
packages/ui/meta_shared.json esbuild/exports/shared_optimized/index.js 16.32 KB 🆕 Added
Largest paths These visualization shows top 20 largest paths in the bundle.

Meta file: packages/next/meta_index.json, Out file: esbuild/index.js

Path Size
../../node_modules ${{\color{Goldenrod}{ ████████████████████▌ }}}$ 82.4%, 820.17 KB
dist/views/Version ${{\color{Goldenrod}{ █▎ }}}$ 5.2%, 51.86 KB
dist/views/Dashboard ${{\color{Goldenrod}{ ▌ }}}$ 2.1%, 21.39 KB
dist/views/Document ${{\color{Goldenrod}{ ▍ }}}$ 1.7%, 16.71 KB
dist/views/List ${{\color{Goldenrod}{ ▎ }}}$ 1.1%, 11.42 KB
dist/views/Root ${{\color{Goldenrod}{ ▎ }}}$ 1.0%, 9.90 KB
dist/views/Versions ${{\color{Goldenrod}{ ▏ }}}$ 0.6%, 6.17 KB
dist/views/API ${{\color{Goldenrod}{ ▏ }}}$ 0.6%, 6.13 KB
dist/elements/Nav ${{\color{Goldenrod}{ ▏ }}}$ 0.6%, 5.96 KB
dist/views/Account ${{\color{Goldenrod}{ ▏ }}}$ 0.6%, 5.56 KB
dist/elements/DocumentHeader ${{\color{Goldenrod}{ ▏ }}}$ 0.5%, 4.84 KB
dist/views/ForgotPassword ${{\color{Goldenrod}{ }}}$ 0.4%, 4.45 KB
dist/views/Login ${{\color{Goldenrod}{ }}}$ 0.4%, 4.40 KB
dist/layouts/Root ${{\color{Goldenrod}{ }}}$ 0.3%, 3.19 KB
dist/views/CreateFirstUser ${{\color{Goldenrod}{ }}}$ 0.3%, 2.81 KB
dist/templates/Default ${{\color{Goldenrod}{ }}}$ 0.3%, 2.64 KB
dist/views/BrowseByFolder ${{\color{Goldenrod}{ }}}$ 0.3%, 2.61 KB
dist/views/CollectionFolders ${{\color{Goldenrod}{ }}}$ 0.2%, 2.44 KB
dist/views/ResetPassword ${{\color{Goldenrod}{ }}}$ 0.2%, 2.40 KB
dist/views/Logout ${{\color{Goldenrod}{ }}}$ 0.2%, 1.94 KB
(other) ${{\color{Goldenrod}{ ████▍ }}}$ 17.6%, 175.39 KB

Meta file: packages/payload/meta_index.json, Out file: esbuild/index.js

Path Size
../../node_modules ${{\color{Goldenrod}{ ████████████████▋ }}}$ 66.8%, 974.49 KB
dist/collections/operations ${{\color{Goldenrod}{ ▊ }}}$ 3.4%, 49.17 KB
dist/fields/hooks ${{\color{Goldenrod}{ ▊ }}}$ 3.2%, 46.02 KB
dist/versions/migrations ${{\color{Goldenrod}{ ▎ }}}$ 1.3%, 18.50 KB
dist/auth/operations ${{\color{Goldenrod}{ ▎ }}}$ 1.2%, 16.98 KB
dist/globals/operations ${{\color{Goldenrod}{ ▎ }}}$ 1.0%, 14.75 KB
dist/fields/config ${{\color{Goldenrod}{ ▎ }}}$ 1.0%, 14.17 KB
dist/queues/operations ${{\color{Goldenrod}{ ▏ }}}$ 0.9%, 13.15 KB
dist/utilities/configToJSONSchema.js ${{\color{Goldenrod}{ ▏ }}}$ 0.9%, 13.13 KB
dist/utilities/telemetry ${{\color{Goldenrod}{ ▏ }}}$ 0.8%, 11.40 KB
dist/fields/validations.js ${{\color{Goldenrod}{ ▏ }}}$ 0.7%, 10.62 KB
dist/collections/config ${{\color{Goldenrod}{ ▏ }}}$ 0.6%, 9.29 KB
dist/bin/generateImportMap ${{\color{Goldenrod}{ ▏ }}}$ 0.6%, 9.08 KB
dist/config/orderable ${{\color{Goldenrod}{ ▏ }}}$ 0.6%, 8.73 KB
dist/uploads/fetchAPI-multipart ${{\color{Goldenrod}{ ▏ }}}$ 0.6%, 8.35 KB
dist/index.js ${{\color{Goldenrod}{ ▏ }}}$ 0.5%, 7.57 KB
dist/database/migrations ${{\color{Goldenrod}{ ▏ }}}$ 0.5%, 7.54 KB
dist/auth/strategies ${{\color{Goldenrod}{ ▏ }}}$ 0.5%, 6.97 KB
dist/auth/endpoints ${{\color{Goldenrod}{ ▏ }}}$ 0.5%, 6.59 KB
dist/config/sanitize.js ${{\color{Goldenrod}{ }}}$ 0.4%, 6.30 KB
(other) ${{\color{Goldenrod}{ ████████▎ }}}$ 33.2%, 484.32 KB

Meta file: packages/payload/meta_shared.json, Out file: esbuild/exports/shared.js

Path Size
../../node_modules ${{\color{Goldenrod}{ ███████████████████▊ }}}$ 79.2%, 157.26 KB
dist/fields/validations.js ${{\color{Goldenrod}{ █▎ }}}$ 5.3%, 10.60 KB
dist/utilities/deepCopyObject.js ${{\color{Goldenrod}{ ▍ }}}$ 1.7%, 3.35 KB
dist/config/orderable ${{\color{Goldenrod}{ ▍ }}}$ 1.6%, 3.13 KB
dist/fields/baseFields ${{\color{Goldenrod}{ ▎ }}}$ 1.4%, 2.79 KB
dist/auth/cookies.js ${{\color{Goldenrod}{ ▏ }}}$ 0.8%, 1.55 KB
dist/utilities/flattenTopLevelFields.js ${{\color{Goldenrod}{ ▏ }}}$ 0.7%, 1.42 KB
dist/fields/config ${{\color{Goldenrod}{ ▏ }}}$ 0.6%, 1.28 KB
dist/utilities/getVersionsConfig.js ${{\color{Goldenrod}{ ▏ }}}$ 0.5%, 1.04 KB
dist/utilities/flattenAllFields.js ${{\color{Goldenrod}{ ▏ }}}$ 0.5%, 943 B
dist/folders/utils ${{\color{Goldenrod}{ ▏ }}}$ 0.5%, 916 B
dist/utilities/unflatten.js ${{\color{Goldenrod}{ }}}$ 0.4%, 850 B
dist/utilities/sanitizeUserDataForEmail.js ${{\color{Goldenrod}{ }}}$ 0.4%, 713 B
dist/utilities/getFieldPermissions.js ${{\color{Goldenrod}{ }}}$ 0.3%, 651 B
dist/utilities/fieldPath.js ${{\color{Goldenrod}{ }}}$ 0.3%, 639 B
dist/utilities/getSafeRedirect.js ${{\color{Goldenrod}{ }}}$ 0.3%, 632 B
dist/uploads/getFileTypeIdentity.js ${{\color{Goldenrod}{ }}}$ 0.3%, 625 B
dist/collections/config ${{\color{Goldenrod}{ }}}$ 0.3%, 570 B
dist/bin/generateImportMap ${{\color{Goldenrod}{ }}}$ 0.3%, 561 B
dist/auth/sessions.js ${{\color{Goldenrod}{ }}}$ 0.3%, 525 B
(other) ${{\color{Goldenrod}{ █████▏ }}}$ 20.8%, 41.40 KB

Meta file: packages/richtext-lexical/meta_client.json, Out file: esbuild/exports/client_optimized/index.js

Path Size
dist/features/blocks ${{\color{Goldenrod}{ ███▏ }}}$ 12.7%, 36.44 KB
dist/lexical/plugins ${{\color{Goldenrod}{ ██▊ }}}$ 11.4%, 32.65 KB
dist/lexical/ui ${{\color{Goldenrod}{ ██▏ }}}$ 8.5%, 24.36 KB
dist/features/experimental_table ${{\color{Goldenrod}{ ██ }}}$ 8.2%, 23.66 KB
dist/packages/@lexical ${{\color{Goldenrod}{ █▋ }}}$ 6.9%, 19.80 KB
dist/features/link ${{\color{Goldenrod}{ █▋ }}}$ 6.5%, 18.63 KB
dist/features/toolbars ${{\color{Goldenrod}{ █▍ }}}$ 5.6%, 16.08 KB
dist/features/upload ${{\color{Goldenrod}{ █▏ }}}$ 4.8%, 13.92 KB
dist/features/textState ${{\color{Goldenrod}{ ▉ }}}$ 3.9%, 11.08 KB
dist/features/relationship ${{\color{Goldenrod}{ ▊ }}}$ 3.2%, 9.10 KB
dist/lexical/utils ${{\color{Goldenrod}{ ▊ }}}$ 3.1%, 8.79 KB
dist/features/converters ${{\color{Goldenrod}{ ▋ }}}$ 2.9%, 8.40 KB
dist/features/debug ${{\color{Goldenrod}{ ▋ }}}$ 2.6%, 7.40 KB
dist/utilities/fieldsDrawer ${{\color{Goldenrod}{ ▋ }}}$ 2.5%, 7.18 KB
dist/lexical/config ${{\color{Goldenrod}{ ▍ }}}$ 1.8%, 5.08 KB
dist/features/lists ${{\color{Goldenrod}{ ▍ }}}$ 1.7%, 5.03 KB
dist/features/format ${{\color{Goldenrod}{ ▎ }}}$ 1.2%, 3.46 KB
dist/lexical/LexicalEditor.js ${{\color{Goldenrod}{ ▎ }}}$ 1.1%, 3.23 KB
dist/field/Field.js ${{\color{Goldenrod}{ ▎ }}}$ 1.0%, 2.81 KB
dist/lexical/nodes ${{\color{Goldenrod}{ ▏ }}}$ 0.9%, 2.66 KB
(other) ${{\color{Goldenrod}{ █████████████████████▊ }}}$ 87.3%, 251.16 KB

Meta file: packages/ui/meta_client.json, Out file: esbuild/exports/client_optimized/index.js

Path Size
../../node_modules ${{\color{Goldenrod}{ ████████████▎ }}}$ 49.1%, 579.15 KB
dist/elements/FolderView ${{\color{Goldenrod}{ ▋ }}}$ 2.5%, 29.40 KB
dist/elements/BulkUpload ${{\color{Goldenrod}{ ▌ }}}$ 2.4%, 28.57 KB
dist/views/Edit ${{\color{Goldenrod}{ ▍ }}}$ 1.8%, 21.17 KB
dist/elements/WhereBuilder ${{\color{Goldenrod}{ ▍ }}}$ 1.5%, 17.36 KB
dist/forms/Form ${{\color{Goldenrod}{ ▎ }}}$ 1.4%, 16.05 KB
dist/elements/Table ${{\color{Goldenrod}{ ▎ }}}$ 1.3%, 15.80 KB
dist/fields/Relationship ${{\color{Goldenrod}{ ▎ }}}$ 1.3%, 15.79 KB
dist/fields/Upload ${{\color{Goldenrod}{ ▎ }}}$ 1.2%, 14.24 KB
dist/fields/Blocks ${{\color{Goldenrod}{ ▎ }}}$ 1.2%, 13.90 KB
dist/elements/QueryPresets ${{\color{Goldenrod}{ ▏ }}}$ 0.9%, 10.36 KB
dist/elements/PublishButton ${{\color{Goldenrod}{ ▏ }}}$ 0.7%, 8.59 KB
dist/providers/Folders ${{\color{Goldenrod}{ ▏ }}}$ 0.7%, 8.46 KB
dist/elements/HTMLDiff ${{\color{Goldenrod}{ ▏ }}}$ 0.7%, 8.38 KB
dist/views/CollectionFolder ${{\color{Goldenrod}{ ▏ }}}$ 0.7%, 7.83 KB
dist/fields/Array ${{\color{Goldenrod}{ ▏ }}}$ 0.7%, 7.73 KB
dist/views/List ${{\color{Goldenrod}{ ▏ }}}$ 0.6%, 7.36 KB
dist/elements/ReactSelect ${{\color{Goldenrod}{ ▏ }}}$ 0.6%, 7.33 KB
dist/elements/ListHeader ${{\color{Goldenrod}{ ▏ }}}$ 0.6%, 7.12 KB
dist/elements/LivePreview ${{\color{Goldenrod}{ ▏ }}}$ 0.6%, 7.03 KB
(other) ${{\color{Goldenrod}{ ████████████▋ }}}$ 50.9%, 601.04 KB

Meta file: packages/ui/meta_shared.json, Out file: esbuild/exports/shared_optimized/index.js

Path Size
dist/graphics/Logo ${{\color{Goldenrod}{ █████ }}}$ 20.0%, 3.12 KB
../../node_modules ${{\color{Goldenrod}{ ████▎ }}}$ 17.0%, 2.65 KB
dist/graphics/Icon ${{\color{Goldenrod}{ ██▍ }}}$ 9.8%, 1.52 KB
dist/utilities/formatDocTitle ${{\color{Goldenrod}{ ██▏ }}}$ 8.5%, 1.32 KB
dist/providers/TableColumns ${{\color{Goldenrod}{ █▍ }}}$ 5.5%, 862 B
dist/utilities/groupNavItems.js ${{\color{Goldenrod}{ █▎ }}}$ 5.2%, 814 B
dist/utilities/getGlobalData.js ${{\color{Goldenrod}{ █▏ }}}$ 4.9%, 762 B
dist/utilities/api.js ${{\color{Goldenrod}{ █▏ }}}$ 4.8%, 756 B
dist/elements/Translation ${{\color{Goldenrod}{ ▊ }}}$ 3.2%, 493 B
dist/utilities/handleTakeOver.js ${{\color{Goldenrod}{ ▋ }}}$ 2.8%, 440 B
dist/utilities/traverseForLocalizedFields.js ${{\color{Goldenrod}{ ▋ }}}$ 2.6%, 399 B
dist/elements/withMergedProps ${{\color{Goldenrod}{ ▌ }}}$ 2.2%, 339 B
dist/utilities/getVisibleEntities.js ${{\color{Goldenrod}{ ▌ }}}$ 2.1%, 329 B
dist/utilities/getNavGroups.js ${{\color{Goldenrod}{ ▍ }}}$ 1.9%, 301 B
dist/elements/WithServerSideProps ${{\color{Goldenrod}{ ▍ }}}$ 1.5%, 232 B
dist/utilities/handleGoBack.js ${{\color{Goldenrod}{ ▎ }}}$ 1.2%, 180 B
dist/fields/mergeFieldStyles.js ${{\color{Goldenrod}{ ▎ }}}$ 1.0%, 159 B
dist/utilities/handleBackToDashboard.js ${{\color{Goldenrod}{ ▎ }}}$ 1.0%, 152 B
dist/forms/Form ${{\color{Goldenrod}{ ▏ }}}$ 0.9%, 147 B
dist/utilities/abortAndIgnore.js ${{\color{Goldenrod}{ ▏ }}}$ 0.9%, 146 B
(other) ${{\color{Goldenrod}{ ████████████████████ }}}$ 80.0%, 12.51 KB
Details

Next to the size is how much the size has increased or decreased compared with the base branch of this PR.

  • ‼️: Size increased by 20% or more. Special attention should be given to this.
  • ⚠️: Size increased in acceptable range (lower than 20%).
  • ✅: No change or even downsized.
  • 🗑️: The out file is deleted: not found in base branch.
  • 🆕: The out file is newly found: will be added to base branch.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants