Skip to content

store: Populate fulltext columns when copying a subgraph#6687

Merged
lutter merged 1 commit into
masterfrom
lutter/copy-fts
Jul 20, 2026
Merged

store: Populate fulltext columns when copying a subgraph#6687
lutter merged 1 commit into
masterfrom
lutter/copy-fts

Conversation

@lutter

@lutter lutter commented Jul 16, 2026

Copy link
Copy Markdown
Collaborator

CopyEntityBatchQuery::new looked up source columns via Table::column, which deliberately hides tsvector (fulltext) columns. Because fulltext columns are nullable, they were silently dropped from the copy instead of hitting the non-nullable error path, so the destination's fulltext search column and its GIN index were left empty after a copy/graft.

Add Table::column_including_fulltext and use it in the copy so fulltext columns are matched and their already-computed tsvector value is copied verbatim; document that Table::column skips fulltext search columns. Add a regression test that copies the User table and verifies a fulltext query against the copy returns the expected entity.

// would be silently dropped from the copy (they are nullable, so
// the error branch below is not taken) and the destination's
// search index would be left empty.
if let Some(scol) = src.column_including_fulltext(&dcol.name) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should can_copy_from also use column_including_fulltext it uses column() currently?

// the error branch below is not taken) and the destination's
// search index would be left empty.
if let Some(scol) = src.column_including_fulltext(&dcol.name) {
if let Some(msg) = dcol.is_assignable_from(scol, &src.object) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One thing that claude flagged during the review:

is_assignable_from only compares FulltextConfig, which is language and algorithm, not fulltext_fields. So a graft that adds a field to include: copies the old tsvectors and searches on the new field quietly return nothing. Compare fulltext_fields here too?

@incrypto32 incrypto32 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apart from the comments, LGTM

CopyEntityBatchQuery::new looked up source columns via Table::column,
which deliberately hides tsvector (fulltext) columns. Because fulltext
columns are nullable, they were silently dropped from the copy instead
of hitting the non-nullable error path, so the destination's fulltext
search column and its GIN index were left empty after a copy/graft.

Add Table::column_including_fulltext and use it in the copy so fulltext
columns are matched and their already-computed tsvector value is copied
verbatim; document that Table::column skips fulltext search columns. Add
a regression test that copies the User table and verifies a fulltext
query against the copy returns the expected entity.
@lutter
lutter force-pushed the lutter/copy-fts branch from 105e24a to a98babc Compare July 20, 2026 23:43
@lutter
lutter merged commit a98babc into master Jul 20, 2026
6 checks passed
@lutter
lutter deleted the lutter/copy-fts branch July 20, 2026 23:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants