feat(c_api): add FTS support for sub-query (#520)

Add zvec_sub_query_set_fts and zvec_sub_query_set_fts_params to allow
setting FTS clause and FTS query parameters on sub-queries, mirroring
the existing zvec_vector_query_set_fts interface.

- zvec_sub_query_set_fts: set/clear FTS clause (copies payload)
- zvec_sub_query_set_fts_params: set FTS query params (takes ownership)
- Add unit test test_fts_wiring_on_sub_query
This commit is contained in:
egolearner 2026-06-24 10:12:39 +08:00 committed by GitHub
parent 4292bd337d
commit 22744f2c81
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 86 additions and 0 deletions

View File

@ -6122,6 +6122,34 @@ zvec_error_code_t zvec_sub_query_set_vamana_params(
return ZVEC_OK;
}
zvec_error_code_t zvec_sub_query_set_fts_params(
zvec_sub_query_t *query, zvec_fts_query_params_t *fts_params) {
if (!query || !fts_params) {
SET_LAST_ERROR(ZVEC_ERROR_INVALID_ARGUMENT,
"Sub-query or FTS params pointer is null");
return ZVEC_ERROR_INVALID_ARGUMENT;
}
auto *ptr = reinterpret_cast<zvec::SubQuery *>(query);
auto *params_ptr = reinterpret_cast<zvec::FtsQueryParams *>(fts_params);
ptr->target_.query_params_.reset(params_ptr);
return ZVEC_OK;
}
zvec_error_code_t zvec_sub_query_set_fts(zvec_sub_query_t *query,
const zvec_fts_t *fts) {
if (!query) {
SET_LAST_ERROR(ZVEC_ERROR_INVALID_ARGUMENT, "Sub-query pointer is null");
return ZVEC_ERROR_INVALID_ARGUMENT;
}
auto *ptr = reinterpret_cast<zvec::SubQuery *>(query);
if (!fts) {
ptr->target_.clause_ = zvec::VectorClause{};
} else {
ptr->target_.clause_ = *reinterpret_cast<const zvec::FtsClause *>(fts);
}
return ZVEC_OK;
}
// =============================================================================
// Index Interface Implementation
// =============================================================================

View File

@ -2359,6 +2359,24 @@ ZVEC_EXPORT zvec_error_code_t ZVEC_CALL zvec_sub_query_set_flat_params(
ZVEC_EXPORT zvec_error_code_t ZVEC_CALL zvec_sub_query_set_vamana_params(
zvec_sub_query_t *query, zvec_vamana_query_params_t *vamana_params);
/**
* @brief Set FTS query parameters on a sub-query (takes ownership)
* @param query Sub-query pointer
* @param fts_params FTS query parameters pointer
* @return zvec_error_code_t Error code
*/
ZVEC_EXPORT zvec_error_code_t ZVEC_CALL zvec_sub_query_set_fts_params(
zvec_sub_query_t *query, zvec_fts_query_params_t *fts_params);
/**
* @brief Set FTS clause on a sub-query (copies the FTS clause)
* @param query Sub-query pointer
* @param fts FTS clause pointer, or NULL to clear
* @return zvec_error_code_t Error code
*/
ZVEC_EXPORT zvec_error_code_t ZVEC_CALL
zvec_sub_query_set_fts(zvec_sub_query_t *query, const zvec_fts_t *fts);
// =============================================================================
// Collection Options and Statistics (Opaque Pointer Pattern)
// =============================================================================

View File

@ -4307,6 +4307,45 @@ void test_fts_wiring_on_vector_query(void) {
TEST_END();
}
void test_fts_wiring_on_sub_query(void) {
TEST_START();
zvec_fts_t *fts = zvec_fts_create();
TEST_ASSERT(fts != NULL);
zvec_error_code_t err =
zvec_fts_set_query_string(fts, "+hello -world \"phrase\"");
TEST_ASSERT(err == ZVEC_OK);
err = zvec_fts_set_match_string(fts, "machine learning");
TEST_ASSERT(err == ZVEC_OK);
zvec_sub_query_t *sq = zvec_sub_query_create();
TEST_ASSERT(sq != NULL);
// Set FTS clause.
err = zvec_sub_query_set_fts(sq, fts);
TEST_ASSERT(err == ZVEC_OK);
// Clearing.
err = zvec_sub_query_set_fts(sq, NULL);
TEST_ASSERT(err == ZVEC_OK);
// Attach FtsQueryParams (transfers ownership).
zvec_fts_query_params_t *fts_params = zvec_query_params_fts_create("AND");
TEST_ASSERT(fts_params != NULL);
err = zvec_sub_query_set_fts_params(sq, fts_params);
TEST_ASSERT(err == ZVEC_OK);
// NULL argument checks.
TEST_ASSERT(zvec_sub_query_set_fts(NULL, fts) == ZVEC_ERROR_INVALID_ARGUMENT);
TEST_ASSERT(zvec_sub_query_set_fts_params(NULL, NULL) ==
ZVEC_ERROR_INVALID_ARGUMENT);
zvec_sub_query_destroy(sq);
zvec_fts_destroy(fts);
TEST_END();
}
void test_fts_end_to_end(void) {
TEST_START();
@ -5964,6 +6003,7 @@ int main(void) {
test_fts_index_params_functions();
test_fts_query_params_functions();
test_fts_wiring_on_vector_query();
test_fts_wiring_on_sub_query();
test_fts_end_to_end();
test_multi_vector_query_with_rrf_reranker();