+ yaz_log(YLOG_DEBUG, "reg_id=%c", reg_id);
+ yaz_log(YLOG_DEBUG, "complete_flag=%d", complete_flag);
+ yaz_log(YLOG_DEBUG, "search_type=%s", search_type);
+ yaz_log(YLOG_DEBUG, "rank_type=%s", rank_type);
+
+ if (zapt_term_to_utf8(zh, zapt, termz) == ZEBRA_FAIL)
+ return ZEBRA_FAIL;
+
+ if (sort_flag)
+ return rpn_sort_spec(zh, zapt, attributeSet, stream, sort_sequence,
+ rank_type, rset_nmem, rset, kc);
+ /* consider if an X-Path query is used */
+ xpath_len = rpn_check_xpath(zh, zapt, attributeSet,
+ xpath, MAX_XPATH_STEPS, stream);
+ if (xpath_len >= 0)
+ {
+ if (xpath[xpath_len-1].part[0] == '@')
+ xpath_use = ZEBRA_XPATH_ATTR_CDATA; /* last step is attribute */
+ else
+ xpath_use = ZEBRA_XPATH_CDATA; /* searching for cdata */
+
+ if (1)
+ {
+ AttrType relation;
+ int relation_value;
+
+ attr_init_APT(&relation, zapt, 2);
+ relation_value = attr_find(&relation, NULL);
+
+ if (relation_value == 103) /* alwaysmatches */
+ {
+ *rset = 0; /* signal no "term" set */
+ return rpn_search_xpath(zh, num_bases, basenames,
+ stream, rank_type, *rset,
+ xpath_len, xpath, rset_nmem, rset, kc);
+ }
+ }
+ }
+
+ /* search using one of the various search type strategies
+ termz is our UTF-8 search term
+ attributeSet is top-level default attribute set
+ stream is ODR for search
+ reg_id is the register type
+ complete_flag is 1 for complete subfield, 0 for incomplete
+ xpath_use is use-attribute to be used for X-Path search, 0 for none
+ */
+ if (!strcmp(search_type, "phrase"))
+ {
+ res = rpn_search_APT_phrase(zh, zapt, termz, attributeSet, stream,
+ reg_id, complete_flag, rank_type,
+ xpath_use,
+ num_bases, basenames, rset_nmem,
+ rset, kc);
+ }
+ else if (!strcmp(search_type, "and-list"))
+ {
+ res = rpn_search_APT_and_list(zh, zapt, termz, attributeSet, stream,
+ reg_id, complete_flag, rank_type,
+ xpath_use,
+ num_bases, basenames, rset_nmem,
+ rset, kc);
+ }
+ else if (!strcmp(search_type, "or-list"))
+ {
+ res = rpn_search_APT_or_list(zh, zapt, termz, attributeSet, stream,
+ reg_id, complete_flag, rank_type,
+ xpath_use,
+ num_bases, basenames, rset_nmem,
+ rset, kc);
+ }
+ else if (!strcmp(search_type, "local"))
+ {
+ res = rpn_search_APT_local(zh, zapt, termz, attributeSet, stream,
+ rank_type, rset_nmem, rset, kc);
+ }
+ else if (!strcmp(search_type, "numeric"))
+ {
+ res = rpn_search_APT_numeric(zh, zapt, termz, attributeSet, stream,
+ reg_id, complete_flag, rank_type,
+ xpath_use,
+ num_bases, basenames, rset_nmem,
+ rset, kc);
+ }
+ else
+ {
+ zebra_setError(zh, YAZ_BIB1_UNSUPP_SEARCH, 0);
+ res = ZEBRA_FAIL;
+ }
+ if (res != ZEBRA_OK)
+ return res;
+ if (!*rset)
+ return ZEBRA_FAIL;
+ return rpn_search_xpath(zh, num_bases, basenames,
+ stream, rank_type, *rset,
+ xpath_len, xpath, rset_nmem, rset, kc);
+}
+
+static ZEBRA_RES rpn_search_structure(ZebraHandle zh, Z_RPNStructure *zs,
+ oid_value attributeSet,
+ NMEM stream, NMEM rset_nmem,
+ Z_SortKeySpecList *sort_sequence,
+ int num_bases, char **basenames,
+ RSET **result_sets, int *num_result_sets,
+ Z_Operator *parent_op,
+ struct rset_key_control *kc);
+
+ZEBRA_RES rpn_search_top(ZebraHandle zh, Z_RPNStructure *zs,
+ oid_value attributeSet,
+ NMEM stream, NMEM rset_nmem,
+ Z_SortKeySpecList *sort_sequence,
+ int num_bases, char **basenames,
+ RSET *result_set)
+{
+ RSET *result_sets = 0;
+ int num_result_sets = 0;
+ ZEBRA_RES res;
+ struct rset_key_control *kc = zebra_key_control_create(zh);
+
+ res = rpn_search_structure(zh, zs, attributeSet,
+ stream, rset_nmem,
+ sort_sequence,
+ num_bases, basenames,
+ &result_sets, &num_result_sets,
+ 0 /* no parent op */,
+ kc);
+ if (res != ZEBRA_OK)
+ {
+ int i;
+ for (i = 0; i<num_result_sets; i++)
+ rset_delete(result_sets[i]);
+ *result_set = 0;
+ }
+ else
+ {
+ assert(num_result_sets == 1);
+ assert(result_sets);
+ assert(*result_sets);
+ *result_set = *result_sets;
+ }
+ (*kc->dec)(kc);
+ return res;