Skip to content

[Enhancement] Fulltext index BloomFilter pushdown pre-filter#23833

Open
ck89119 wants to merge 8 commits intomatrixorigin:mainfrom
ck89119:fulltext-pushdown-23832
Open

[Enhancement] Fulltext index BloomFilter pushdown pre-filter#23833
ck89119 wants to merge 8 commits intomatrixorigin:mainfrom
ck89119:fulltext-pushdown-23832

Conversation

@ck89119
Copy link
Contributor

@ck89119 ck89119 commented Mar 10, 2026

What type of PR is this?

  • API-change
  • BUG
  • Improvement
  • Documentation
  • Feature
  • Test and CI
  • Code Refactoring

Which issue(s) this PR fixes:

issue #23832

What this PR does / why we need it:

Implement BloomFilter pushdown for fulltext index tables, similar to the existing IVF index pushdown.

When a fulltext search query has additional filter predicates (e.g. WHERE match(...) against(...) AND category = 'tech'), the filtered PKs are collected into a BloomFilter and pushed down to the fulltext index table reader to skip irrelevant rows early.

current applyJoinFullTextIndices's query plan:

Project
  -> Sort (score DESC)
    -> Join (src.pk = ft_alias.doc_id)
      -> Table Scan on src (with filter)
      -> Table Function fulltext_index_scan

When there is a filter, the doc_id returned by fulltext_index_scan can be massively selected for filters, resulting in wastes significant I/O.

optimized query plan(with filter)

Project
  -> Sort (score DESC, LIMIT)
    -> Join INNER (src.pk = ft_alias.doc_id)  [runtime filter: IN-list -> scanNode]
      -> Table Scan on src (with filter)
      -> Join INNER (ft_alias.doc_id = second.pk)  [runtime filter: BloomFilter -> ft_func]
        -> Table Function fulltext_index_scan
        -> Project (pk only)
          -> Table Scan on src (with filter, copy)

Key changes:

  1. plan (apply_indices_fulltext.go): applyJoinFullTextIndices builds RuntimeFilterBuildList with BloomFilter for the inner join between fulltext results and the source table.

  2. compile (scope.go, remoterun.go): Pass BloomFilter from context to FilterHint when the target table is a fulltext index table (TableType == "fulltext").

  3. reader (reader.go): tryUpdateColumns uses doc_id column for BF filtering on fulltext tables, independent of pkPos since internal SQL does not include __mo_fake_pk_col.

  4. pk_filter_mem (pk_filter_mem.go): NewMemPKFilter sets BFSeqNum using doc_id column for fulltext tables as fallback when __mo_index_pri_col is absent.

  5. build_ddl (build_ddl.go): Fix fulltext index table relkind from SystemIndexRel ("i") to FullTextIndex_TblType ("fulltext") so the TableType check matches at runtime.

Bug fixes included:

  • relkind mismatch: buildFullTextIndexTable wrote "i" to mo_tables.relkind instead of "fulltext", causing BF context propagation to be skipped.
  • pkPos gate: BF filtering logic was inside if pkPos != -1 block, but fulltext internal SQL never includes the PK column.
  • BFSeqNum not set: NewMemPKFilter only looked for __mo_index_pri_col to set BFSeqNum; fulltext tables use doc_id instead.

Tests:

  • Unit tests for NewMemPKFilter with fulltext table BFSeqNum
  • Unit tests for tryUpdateColumns with fulltext BF filtering
  • BVT: test/distributed/cases/fulltext/fulltext_pushdown.sql with 7 scenarios

…rigin#23832)

Implement BloomFilter pushdown for fulltext index tables, similar to
the existing IVF index pushdown. When a fulltext search query has
additional filter predicates (e.g. WHERE match(...) against(...) AND
category = 'tech'), the filtered PKs are collected into a BloomFilter
and pushed down to the fulltext index table reader to skip irrelevant
rows early.

Key changes:
- plan: applyJoinFullTextIndices builds RuntimeFilterBuildList with BF
- compile: scope.go/remoterun.go pass BF from context to FilterHint
- reader: tryUpdateColumns uses doc_id column for BF filtering on
  fulltext tables (independent of pkPos since internal SQL doesn't
  include __mo_fake_pk_col)
- pk_filter_mem: NewMemPKFilter sets BFSeqNum using doc_id column for
  fulltext tables (fallback when __mo_index_pri_col is absent)
- build_ddl: fix fulltext index table relkind from SystemIndexRel to
  FullTextIndex_TblType so TableType check matches at runtime

Approved by: @xxx
Ref matrixorigin#23832
…lkind

1. Apply BloomFilter probe to all fulltext table function nodes instead
   of only the first one when multiple fulltext_match expressions exist.

2. Add IsFullTextIndexTableType() to handle legacy fulltext index tables
   whose relkind is still 'i' (SystemIndexRel) instead of 'fulltext',
   so BF pushdown works for pre-upgrade tables as well.
@mergify
Copy link
Contributor

mergify bot commented Mar 23, 2026

Merge Queue Status

  • Entered queue2026-03-23 07:19 UTC · Rule: main
  • Checks started · in-place · dashboard
  • 🟠 Running checks
  • ⏳ Merge · ETA: 2026-03-23 08:15 UTC 🚀
Required conditions to merge
  • any of [🛡 GitHub branch protection]:
    • check-neutral = Matrixone Upgrade CI / Compatibility Test With Target on Linux/x64(LAUNCH)
    • check-skipped = Matrixone Upgrade CI / Compatibility Test With Target on Linux/x64(LAUNCH)
    • check-success = Matrixone Upgrade CI / Compatibility Test With Target on Linux/x64(LAUNCH)
  • any of [🛡 GitHub branch protection]:
    • check-neutral = Matrixone Utils CI / Coverage
    • check-skipped = Matrixone Utils CI / Coverage
    • check-success = Matrixone Utils CI / Coverage
  • #approved-reviews-by >= 1 [🛡 GitHub branch protection]
  • #changes-requested-reviews-by = 0 [🛡 GitHub branch protection]
  • #review-threads-unresolved = 0 [🛡 GitHub branch protection]
  • branch-protection-review-decision = APPROVED [🛡 GitHub branch protection]
  • any of [🛡 GitHub branch protection]:
    • check-success = Matrixone Compose CI / multi cn e2e bvt test docker compose(PESSIMISTIC)
    • check-neutral = Matrixone Compose CI / multi cn e2e bvt test docker compose(PESSIMISTIC)
    • check-skipped = Matrixone Compose CI / multi cn e2e bvt test docker compose(PESSIMISTIC)
  • any of [🛡 GitHub branch protection]:
    • check-success = Matrixone Standlone CI / Multi-CN e2e BVT Test on Linux/x64(LAUNCH, PROXY)
    • check-neutral = Matrixone Standlone CI / Multi-CN e2e BVT Test on Linux/x64(LAUNCH, PROXY)
    • check-skipped = Matrixone Standlone CI / Multi-CN e2e BVT Test on Linux/x64(LAUNCH, PROXY)
  • any of [🛡 GitHub branch protection]:
    • check-success = Matrixone Standlone CI / e2e BVT Test on Linux/x64(LAUNCH, PESSIMISTIC)
    • check-neutral = Matrixone Standlone CI / e2e BVT Test on Linux/x64(LAUNCH, PESSIMISTIC)
    • check-skipped = Matrixone Standlone CI / e2e BVT Test on Linux/x64(LAUNCH, PESSIMISTIC)
  • any of [🛡 GitHub branch protection]:
    • check-success = Matrixone CI / SCA Test on Ubuntu/x86
    • check-neutral = Matrixone CI / SCA Test on Ubuntu/x86
    • check-skipped = Matrixone CI / SCA Test on Ubuntu/x86
  • any of [🛡 GitHub branch protection]:
    • check-success = Matrixone CI / UT Test on Ubuntu/x86
    • check-neutral = Matrixone CI / UT Test on Ubuntu/x86
    • check-skipped = Matrixone CI / UT Test on Ubuntu/x86
  • any of [🛡 GitHub branch protection]:
    • check-success = Matrixone Compose CI / multi cn e2e bvt test docker compose(Optimistic/PUSH)
    • check-neutral = Matrixone Compose CI / multi cn e2e bvt test docker compose(Optimistic/PUSH)
    • check-skipped = Matrixone Compose CI / multi cn e2e bvt test docker compose(Optimistic/PUSH)
  • any of [🛡 GitHub branch protection]:
    • check-success = Matrixone Standlone CI / e2e BVT Test on Linux/x64(LAUNCH,Optimistic)
    • check-neutral = Matrixone Standlone CI / e2e BVT Test on Linux/x64(LAUNCH,Optimistic)
    • check-skipped = Matrixone Standlone CI / e2e BVT Test on Linux/x64(LAUNCH,Optimistic)
Required conditions to stay in the queue
  • any of [🔀 queue conditions]:
    • all of [📌 queue conditions of queue main]:
      • any of [🛡 GitHub branch protection]:
        • check-neutral = Matrixone Upgrade CI / Compatibility Test With Target on Linux/x64(LAUNCH)
        • check-skipped = Matrixone Upgrade CI / Compatibility Test With Target on Linux/x64(LAUNCH)
        • check-success = Matrixone Upgrade CI / Compatibility Test With Target on Linux/x64(LAUNCH)
      • any of [🛡 GitHub branch protection]:
        • check-neutral = Matrixone Utils CI / Coverage
        • check-skipped = Matrixone Utils CI / Coverage
        • check-success = Matrixone Utils CI / Coverage
      • #approved-reviews-by >= 1 [🛡 GitHub branch protection]
      • #changes-requested-reviews-by = 0 [🛡 GitHub branch protection]
      • #review-threads-unresolved = 0 [🛡 GitHub branch protection]
      • branch-protection-review-decision = APPROVED [🛡 GitHub branch protection]
      • any of [🛡 GitHub branch protection]:
        • check-success = Matrixone Compose CI / multi cn e2e bvt test docker compose(PESSIMISTIC)
        • check-neutral = Matrixone Compose CI / multi cn e2e bvt test docker compose(PESSIMISTIC)
        • check-skipped = Matrixone Compose CI / multi cn e2e bvt test docker compose(PESSIMISTIC)
      • any of [🛡 GitHub branch protection]:
        • check-success = Matrixone Standlone CI / Multi-CN e2e BVT Test on Linux/x64(LAUNCH, PROXY)
        • check-neutral = Matrixone Standlone CI / Multi-CN e2e BVT Test on Linux/x64(LAUNCH, PROXY)
        • check-skipped = Matrixone Standlone CI / Multi-CN e2e BVT Test on Linux/x64(LAUNCH, PROXY)
      • any of [🛡 GitHub branch protection]:
        • check-success = Matrixone Standlone CI / e2e BVT Test on Linux/x64(LAUNCH, PESSIMISTIC)
        • check-neutral = Matrixone Standlone CI / e2e BVT Test on Linux/x64(LAUNCH, PESSIMISTIC)
        • check-skipped = Matrixone Standlone CI / e2e BVT Test on Linux/x64(LAUNCH, PESSIMISTIC)
      • any of [🛡 GitHub branch protection]:
        • check-success = Matrixone CI / SCA Test on Ubuntu/x86
        • check-neutral = Matrixone CI / SCA Test on Ubuntu/x86
        • check-skipped = Matrixone CI / SCA Test on Ubuntu/x86
      • any of [🛡 GitHub branch protection]:
        • check-success = Matrixone CI / UT Test on Ubuntu/x86
        • check-neutral = Matrixone CI / UT Test on Ubuntu/x86
        • check-skipped = Matrixone CI / UT Test on Ubuntu/x86
      • any of [🛡 GitHub branch protection]:
        • check-success = Matrixone Compose CI / multi cn e2e bvt test docker compose(Optimistic/PUSH)
        • check-neutral = Matrixone Compose CI / multi cn e2e bvt test docker compose(Optimistic/PUSH)
        • check-skipped = Matrixone Compose CI / multi cn e2e bvt test docker compose(Optimistic/PUSH)
      • any of [🛡 GitHub branch protection]:
        • check-success = Matrixone Standlone CI / e2e BVT Test on Linux/x64(LAUNCH,Optimistic)
        • check-neutral = Matrixone Standlone CI / e2e BVT Test on Linux/x64(LAUNCH,Optimistic)
        • check-skipped = Matrixone Standlone CI / e2e BVT Test on Linux/x64(LAUNCH,Optimistic)
    • all of [📌 queue conditions of queue release-2.1]:
      • any of [🛡 GitHub branch protection]:
        • check-neutral = Matrixone Upgrade CI / Compatibility Test With Target on Linux/x64(LAUNCH)
        • check-skipped = Matrixone Upgrade CI / Compatibility Test With Target on Linux/x64(LAUNCH)
        • check-success = Matrixone Upgrade CI / Compatibility Test With Target on Linux/x64(LAUNCH)
      • any of [🛡 GitHub branch protection]:
        • check-neutral = Matrixone Utils CI / Coverage
        • check-skipped = Matrixone Utils CI / Coverage
        • check-success = Matrixone Utils CI / Coverage
      • #approved-reviews-by >= 1 [🛡 GitHub branch protection]
      • #changes-requested-reviews-by = 0 [🛡 GitHub branch protection]
      • #review-threads-unresolved = 0 [🛡 GitHub branch protection]
      • branch-protection-review-decision = APPROVED [🛡 GitHub branch protection]
      • any of [🛡 GitHub branch protection]:
        • check-success = Matrixone Compose CI / multi cn e2e bvt test docker compose(PESSIMISTIC)
        • check-neutral = Matrixone Compose CI / multi cn e2e bvt test docker compose(PESSIMISTIC)
        • check-skipped = Matrixone Compose CI / multi cn e2e bvt test docker compose(PESSIMISTIC)
      • any of [🛡 GitHub branch protection]:
        • check-success = Matrixone Standlone CI / Multi-CN e2e BVT Test on Linux/x64(LAUNCH, PROXY)
        • check-neutral = Matrixone Standlone CI / Multi-CN e2e BVT Test on Linux/x64(LAUNCH, PROXY)
        • check-skipped = Matrixone Standlone CI / Multi-CN e2e BVT Test on Linux/x64(LAUNCH, PROXY)
      • any of [🛡 GitHub branch protection]:
        • check-success = Matrixone Standlone CI / e2e BVT Test on Linux/x64(LAUNCH, PESSIMISTIC)
        • check-neutral = Matrixone Standlone CI / e2e BVT Test on Linux/x64(LAUNCH, PESSIMISTIC)
        • check-skipped = Matrixone Standlone CI / e2e BVT Test on Linux/x64(LAUNCH, PESSIMISTIC)
      • any of [🛡 GitHub branch protection]:
        • check-success = Matrixone CI / SCA Test on Ubuntu/x86
        • check-neutral = Matrixone CI / SCA Test on Ubuntu/x86
        • check-skipped = Matrixone CI / SCA Test on Ubuntu/x86
      • any of [🛡 GitHub branch protection]:
        • check-success = Matrixone CI / UT Test on Ubuntu/x86
        • check-neutral = Matrixone CI / UT Test on Ubuntu/x86
        • check-skipped = Matrixone CI / UT Test on Ubuntu/x86
      • any of [🛡 GitHub branch protection]:
        • check-success = Matrixone Compose CI / multi cn e2e bvt test docker compose(Optimistic/PUSH)
        • check-neutral = Matrixone Compose CI / multi cn e2e bvt test docker compose(Optimistic/PUSH)
        • check-skipped = Matrixone Compose CI / multi cn e2e bvt test docker compose(Optimistic/PUSH)
      • any of [🛡 GitHub branch protection]:
        • check-success = Matrixone Standlone CI / e2e BVT Test on Linux/x64(LAUNCH,Optimistic)
        • check-neutral = Matrixone Standlone CI / e2e BVT Test on Linux/x64(LAUNCH,Optimistic)
        • check-skipped = Matrixone Standlone CI / e2e BVT Test on Linux/x64(LAUNCH,Optimistic)
    • all of [📌 queue conditions of queue release-2.2]:
      • any of [🛡 GitHub branch protection]:
        • check-neutral = Matrixone Upgrade CI / Compatibility Test With Target on Linux/x64(LAUNCH)
        • check-skipped = Matrixone Upgrade CI / Compatibility Test With Target on Linux/x64(LAUNCH)
        • check-success = Matrixone Upgrade CI / Compatibility Test With Target on Linux/x64(LAUNCH)
      • any of [🛡 GitHub branch protection]:
        • check-neutral = Matrixone Utils CI / Coverage
        • check-skipped = Matrixone Utils CI / Coverage
        • check-success = Matrixone Utils CI / Coverage
      • #approved-reviews-by >= 1 [🛡 GitHub branch protection]
      • #changes-requested-reviews-by = 0 [🛡 GitHub branch protection]
      • #review-threads-unresolved = 0 [🛡 GitHub branch protection]
      • branch-protection-review-decision = APPROVED [🛡 GitHub branch protection]
      • any of [🛡 GitHub branch protection]:
        • check-success = Matrixone Compose CI / multi cn e2e bvt test docker compose(PESSIMISTIC)
        • check-neutral = Matrixone Compose CI / multi cn e2e bvt test docker compose(PESSIMISTIC)
        • check-skipped = Matrixone Compose CI / multi cn e2e bvt test docker compose(PESSIMISTIC)
      • any of [🛡 GitHub branch protection]:
        • check-success = Matrixone Standlone CI / Multi-CN e2e BVT Test on Linux/x64(LAUNCH, PROXY)
        • check-neutral = Matrixone Standlone CI / Multi-CN e2e BVT Test on Linux/x64(LAUNCH, PROXY)
        • check-skipped = Matrixone Standlone CI / Multi-CN e2e BVT Test on Linux/x64(LAUNCH, PROXY)
      • any of [🛡 GitHub branch protection]:
        • check-success = Matrixone Standlone CI / e2e BVT Test on Linux/x64(LAUNCH, PESSIMISTIC)
        • check-neutral = Matrixone Standlone CI / e2e BVT Test on Linux/x64(LAUNCH, PESSIMISTIC)
        • check-skipped = Matrixone Standlone CI / e2e BVT Test on Linux/x64(LAUNCH, PESSIMISTIC)
      • any of [🛡 GitHub branch protection]:
        • check-success = Matrixone CI / SCA Test on Ubuntu/x86
        • check-neutral = Matrixone CI / SCA Test on Ubuntu/x86
        • check-skipped = Matrixone CI / SCA Test on Ubuntu/x86
      • any of [🛡 GitHub branch protection]:
        • check-success = Matrixone CI / UT Test on Ubuntu/x86
        • check-neutral = Matrixone CI / UT Test on Ubuntu/x86
        • check-skipped = Matrixone CI / UT Test on Ubuntu/x86
      • any of [🛡 GitHub branch protection]:
        • check-success = Matrixone Compose CI / multi cn e2e bvt test docker compose(Optimistic/PUSH)
        • check-neutral = Matrixone Compose CI / multi cn e2e bvt test docker compose(Optimistic/PUSH)
        • check-skipped = Matrixone Compose CI / multi cn e2e bvt test docker compose(Optimistic/PUSH)
      • any of [🛡 GitHub branch protection]:
        • check-success = Matrixone Standlone CI / e2e BVT Test on Linux/x64(LAUNCH,Optimistic)
        • check-neutral = Matrixone Standlone CI / e2e BVT Test on Linux/x64(LAUNCH,Optimistic)
        • check-skipped = Matrixone Standlone CI / e2e BVT Test on Linux/x64(LAUNCH,Optimistic)
    • all of [📌 queue conditions of queue release-3.0]:
      • any of [🛡 GitHub branch protection]:
        • check-neutral = Matrixone Upgrade CI / Compatibility Test With Target on Linux/x64(LAUNCH)
        • check-skipped = Matrixone Upgrade CI / Compatibility Test With Target on Linux/x64(LAUNCH)
        • check-success = Matrixone Upgrade CI / Compatibility Test With Target on Linux/x64(LAUNCH)
      • any of [🛡 GitHub branch protection]:
        • check-neutral = Matrixone Utils CI / Coverage
        • check-skipped = Matrixone Utils CI / Coverage
        • check-success = Matrixone Utils CI / Coverage
      • #approved-reviews-by >= 1 [🛡 GitHub branch protection]
      • #changes-requested-reviews-by = 0 [🛡 GitHub branch protection]
      • #review-threads-unresolved = 0 [🛡 GitHub branch protection]
      • branch-protection-review-decision = APPROVED [🛡 GitHub branch protection]
      • any of [🛡 GitHub branch protection]:
        • check-success = Matrixone Compose CI / multi cn e2e bvt test docker compose(PESSIMISTIC)
        • check-neutral = Matrixone Compose CI / multi cn e2e bvt test docker compose(PESSIMISTIC)
        • check-skipped = Matrixone Compose CI / multi cn e2e bvt test docker compose(PESSIMISTIC)
      • any of [🛡 GitHub branch protection]:
        • check-success = Matrixone Standlone CI / Multi-CN e2e BVT Test on Linux/x64(LAUNCH, PROXY)
        • check-neutral = Matrixone Standlone CI / Multi-CN e2e BVT Test on Linux/x64(LAUNCH, PROXY)
        • check-skipped = Matrixone Standlone CI / Multi-CN e2e BVT Test on Linux/x64(LAUNCH, PROXY)
      • any of [🛡 GitHub branch protection]:
        • check-success = Matrixone Standlone CI / e2e BVT Test on Linux/x64(LAUNCH, PESSIMISTIC)
        • check-neutral = Matrixone Standlone CI / e2e BVT Test on Linux/x64(LAUNCH, PESSIMISTIC)
        • check-skipped = Matrixone Standlone CI / e2e BVT Test on Linux/x64(LAUNCH, PESSIMISTIC)
      • any of [🛡 GitHub branch protection]:
        • check-success = Matrixone CI / SCA Test on Ubuntu/x86
        • check-neutral = Matrixone CI / SCA Test on Ubuntu/x86
        • check-skipped = Matrixone CI / SCA Test on Ubuntu/x86
      • any of [🛡 GitHub branch protection]:
        • check-success = Matrixone CI / UT Test on Ubuntu/x86
        • check-neutral = Matrixone CI / UT Test on Ubuntu/x86
        • check-skipped = Matrixone CI / UT Test on Ubuntu/x86
      • any of [🛡 GitHub branch protection]:
        • check-success = Matrixone Compose CI / multi cn e2e bvt test docker compose(Optimistic/PUSH)
        • check-neutral = Matrixone Compose CI / multi cn e2e bvt test docker compose(Optimistic/PUSH)
        • check-skipped = Matrixone Compose CI / multi cn e2e bvt test docker compose(Optimistic/PUSH)
      • any of [🛡 GitHub branch protection]:
        • check-success = Matrixone Standlone CI / e2e BVT Test on Linux/x64(LAUNCH,Optimistic)
        • check-neutral = Matrixone Standlone CI / e2e BVT Test on Linux/x64(LAUNCH,Optimistic)
        • check-skipped = Matrixone Standlone CI / e2e BVT Test on Linux/x64(LAUNCH,Optimistic)
  • -closed [📌 queue requirement]
  • -conflict [📌 queue requirement]
  • -draft [📌 queue requirement]
  • any of [📌 queue -> configuration change requirements]:
    • -mergify-configuration-changed
    • check-success = Configuration changed
  • any of [📌 queue requirement]:
    • check-neutral = Mergify Merge Protections
    • check-skipped = Mergify Merge Protections
    • check-success = Mergify Merge Protections

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants