(
name: &str,
func: &ast::Function,
table: &crate::resolver::columns::ResolvedTable,
extra_filter: Option<&ast::Expr>,
)
| 191 | } |
| 192 | |
| 193 | fn plan_vector_from_where( |
| 194 | name: &str, |
| 195 | func: &ast::Function, |
| 196 | table: &crate::resolver::columns::ResolvedTable, |
| 197 | extra_filter: Option<&ast::Expr>, |
| 198 | ) -> Result<Option<SqlPlan>> { |
| 199 | let args = extract_func_args(func)?; |
| 200 | if args.len() < 2 { |
| 201 | return Ok(None); |
| 202 | } |
| 203 | let field = extract_column_name(&args[0])?; |
| 204 | let query_vector = extract_float_array(&args[1])?; |
| 205 | |
| 206 | let raw_func_args: &[ast::FunctionArg] = match &func.args { |
| 207 | ast::FunctionArguments::List(list) => &list.args, |
| 208 | _ => &[], |
| 209 | }; |
| 210 | let ann_options = parse_ann_options(raw_func_args)?; |
| 211 | let ef_search = ann_options |
| 212 | .ef_search_override |
| 213 | .unwrap_or(DEFAULT_TOP_K * DEFAULT_EF_SEARCH_MULTIPLIER); |
| 214 | |
| 215 | Ok(Some(SqlPlan::VectorSearch { |
| 216 | collection: table.name.clone(), |
| 217 | field, |
| 218 | query_vector, |
| 219 | top_k: DEFAULT_TOP_K, |
| 220 | ef_search, |
| 221 | metric: metric_from_func_name(name), |
| 222 | filters: extra_filter_to_filters(extra_filter)?, |
| 223 | array_prefilter: None, |
| 224 | ann_options, |
| 225 | // Vector-primary skip-payload-fetch and payload-filter peeling are |
| 226 | // applied uniformly by the post-pass in `entry::plan_query` after |
| 227 | // planning returns — see the `if let SqlPlan::VectorSearch ...` |
| 228 | // block there. WHERE-derived plans flow through the same post-pass |
| 229 | // and need no special handling here. |
| 230 | skip_payload_fetch: false, |
| 231 | payload_filters: Vec::new(), |
| 232 | })) |
| 233 | } |
| 234 | |
| 235 | fn plan_multi_vector_from_where( |
| 236 | func: &ast::Function, |
no test coverage detected