JingsongLi commented on code in PR #760:
URL: https://github.com/apache/paimon-rust/pull/760#discussion_r3901245270
##########
crates/paimon/src/table/vector_search_builder.rs:
##########
@@ -1217,11 +1270,30 @@ impl<'a> BatchVectorSearchBuilder<'a> {
pub async fn execute(&self) -> crate::Result<Vec<SearchResult>> {
let timing_enabled = vector_search_timing_enabled();
let total_start = timing_enabled.then(Instant::now);
+ if let Some(prepared) = &self.prepared_filter {
+ if !same_vector_search_table(self.table, prepared.table()) {
+ return Err(crate::Error::DataInvalid {
+ message: format!(
+ "Prepared vector search filter belongs to a different
table: builder target is '{}@{}', prepared filter target is '{}@{}'",
+ self.table.location(),
+ self.table.branch(),
+ prepared.table().location(),
+ prepared.table().branch(),
+ ),
+ source: None,
+ });
+ }
+ }
// Fail closed: like `execute_read` and the single-query builder, this
// returns data-derived row ids/scores outside `TableScan`/`TableRead`,
// so it must refuse a `query-auth.enabled` table before any fast path
// (an empty snapshot would otherwise return empty results and bypass
it).
- let core = CoreOptions::new(self.table.schema().options());
+ let execution_table = self
+ .prepared_filter
+ .as_ref()
+ .map(PreparedVectorSearchFilter::table)
+ .unwrap_or(self.table);
+ let core = CoreOptions::new(execution_table.schema().options());
Review Comment:
[P1] Authorize the builder target before switching to the prepared snapshot
The lineage check still permits different schema/option copies of the same
physical table, but this guard now checks only `execution_table`. A prepared
filter created before `query-auth.enabled` was enabled carries the old
auth-disabled schema; after the catalog reloads the table with auth enabled
(the same catalog FileIO clone keeps the same lineage), attaching that prepared
value passes `same_vector_search_table`, replaces the builder target here, and
bypasses the fail-closed guard. I reproduced the minimal public-API form with
`source.prepare_vector_search_filter(...)`, `target =
source.copy_with_options({query-auth.enabled: true})`, and
`target.new_batch_vector_search_builder().with_prepared_filter(prepared).execute()`:
it returns `Ok([empty SearchResult])` instead of `Unsupported`. This
contradicts the existing time-travel rule that current stored auth cannot be
disabled by a historical/dynamic copy. Please call `ensure_read_authorized` on
`self.table` before selecting the pi
nned prepared table (and keep the prepared-table check as defense in depth),
with a stale-prepared -> auth-enabled-target regression.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]