Skip to content

Commit 7e87fae

Browse files
ruoliu2claude
authored andcommitted
fix(es-compat): reject empty index_filter to match ES behavior
- Remove empty object {} handling in parse_index_filter_to_query_ast - ES rejects empty index_filter with 400, now QW does too - Add tag_fields config and tag-based index_filter test - Update unit and integration tests accordingly Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> Signed-off-by: ruo <ruoliu.dev@gmail.com>
1 parent 7f1b70c commit 7e87fae

3 files changed

Lines changed: 23 additions & 6 deletions

File tree

quickwit/quickwit-serve/src/elasticsearch_api/model/field_capability.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -178,14 +178,14 @@ pub fn convert_to_es_field_capabilities_response(
178178

179179
/// Parses an Elasticsearch index_filter JSON value into a Quickwit QueryAst.
180180
///
181-
/// Returns `Ok(None)` if the index_filter is null or empty.
181+
/// Returns `Ok(None)` if the index_filter is null.
182182
/// Returns `Ok(Some(QueryAst))` if the index_filter is valid.
183-
/// Returns `Err` if the index_filter is invalid or cannot be converted.
183+
/// Returns `Err` if the index_filter is invalid or cannot be converted (including empty object).
184184
#[allow(clippy::result_large_err)]
185185
pub fn parse_index_filter_to_query_ast(
186186
index_filter: serde_json::Value,
187187
) -> Result<Option<QueryAst>, ElasticsearchError> {
188-
if index_filter.is_null() || index_filter == serde_json::Value::Object(Default::default()) {
188+
if index_filter.is_null() {
189189
return Ok(None);
190190
}
191191

@@ -378,8 +378,9 @@ mod tests {
378378

379379
#[test]
380380
fn test_parse_index_filter_to_query_ast_empty_object() {
381-
let result = parse_index_filter_to_query_ast(json!({})).unwrap();
382-
assert!(result.is_none());
381+
// Empty object {} should return error to match ES behavior
382+
let result = parse_index_filter_to_query_ast(json!({}));
383+
assert!(result.is_err());
383384
}
384385

385386
#[test]

quickwit/rest-api-tests/scenarii/es_field_capabilities/0001-field-capabilities.yaml

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -437,14 +437,25 @@ json:
437437
field: "value"
438438
status_code: 400
439439
---
440-
# Test _field_caps API with empty index_filter (should work like no filter)
440+
# Test _field_caps API with empty index_filter (should return 400 like ES)
441441
method: [POST]
442442
engines:
443443
- quickwit
444444
- elasticsearch
445445
endpoint: fieldcaps/_field_caps?fields=name
446446
json:
447447
index_filter: {}
448+
status_code: 400
449+
---
450+
# Test _field_caps API with index_filter using tag field for split pruning (QW-only)
451+
method: [POST]
452+
engines:
453+
- quickwit
454+
endpoint: fieldcaps/_field_caps?fields=name
455+
json:
456+
index_filter:
457+
term:
458+
tags: "nice"
448459
expected:
449460
indices:
450461
- fieldcaps

quickwit/rest-api-tests/scenarii/es_field_capabilities/_setup.quickwit.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ json:
2222
tokenizer: default
2323
fast: true
2424
timestamp_field: date
25+
tag_fields: ["tags"]
2526
field_mappings:
2627
- name: date
2728
type: datetime
@@ -32,6 +33,10 @@ json:
3233
- name: host
3334
type: ip
3435
fast: true
36+
- name: tags
37+
type: array<text>
38+
tokenizer: raw
39+
fast: true
3540
---
3641
# Create index
3742
method: POST

0 commit comments

Comments
 (0)