Skip to content

store: Populate fulltext columns when copying a subgraph#6687

Open
lutter wants to merge 1 commit into
masterfrom
lutter/copy-fts
Open

store: Populate fulltext columns when copying a subgraph#6687
lutter wants to merge 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.

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

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