#!/bin/sh
# Reproduces an ArrayIndexOutOfBoundsException in Solr 10.1 when faceting a multi-valued field
# on a combined (RRF) query. Run inside a stock container, e.g.:
#   docker run -d --name repro -e SOLR_OPTS=-Dsolr.security.allow.urls.enabled=false solr:10.1 solr-precreate repro
#   docker cp this.sh repro:/tmp/r.sh && docker exec repro sh /tmp/r.sh
# Conditions: >= 2 segments; every sub-query matches few enough docs to get a SortedIntDocSet;
# all matches sit well before the start of a later segment.
B=http://localhost:8983/solr/repro
curl -s -H 'Content-Type: application/json' $B/config -d '{
  "add-requesthandler":  {"name":"/hybrid", "class":"solr.CombinedQuerySearchHandler"},
  "add-searchcomponent": {"name":"combined_query", "class":"solr.CombinedQueryComponent"}}' > /dev/null

add() { # $1=prefix $2=count $3=how many get "apple banana"
  : > /tmp/docs.json
  for i in $(seq 0 $(($2 - 1))); do
    if [ $i -lt $3 ]; then t="apple banana"; else t="cherry"; fi
    printf "{\"id\":\"%s%d\",\"color_ss\":[\"c%d\",\"any\"],\"text_txt\":\"%s\"}\n" $1 $i $((i % 2)) "$t" >> /tmp/docs.json
  done
  curl -s -H 'Content-Type: application/json' "$B/update/json/docs?commit=true" --data-binary @/tmp/docs.json > /dev/null
}
add a 2000 3    # segment _0: docs 0-1999, only 0-2 match
add b 5000 0    # segment _1: docs 2000-6999, none match

q() {
  echo "--- $1"
  curl -s -H 'Content-Type: application/json' "$B/hybrid?rows=0$2" --data-binary '{
    "queries": {
      "q1": {"lucene": {"query": "text_txt:apple"}},
      "q2": {"lucene": {"query": "text_txt:banana"}}
    },
    "params": {
      "combiner": true,
      "combiner.query": ["q1", "q2"],
      "facet": true,
      "facet.field": "color_ss"
    }
  }' | tr -d '\n ' | grep -o '"numFound":[0-9]*\|"msg":"[^"]*"\|"color_ss":\[[^]]*\]' | sort -u
}
q "combined query + facet.field"
q "combined query, facet=false" "&facet=false"
