1 /* $Id: zrpn.c,v 1.208 2005-11-29 11:38:34 adam Exp $
2 Copyright (C) 1995-2005
5 This file is part of the Zebra server.
7 Zebra is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
12 Zebra is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 You should have received a copy of the GNU General Public License
18 along with Zebra; see the file LICENSE.zebra. If not, write to the
19 Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
33 #include <yaz/diagbib1.h>
35 #include <zebra_xpath.h>
40 struct rpn_char_map_info
51 Z_AttributesPlusTerm *zapt;
54 static int log_level_set = 0;
55 static int log_level_rpn = 0;
57 static const char **rpn_char_map_handler(void *vp, const char **from, int len)
59 struct rpn_char_map_info *p = (struct rpn_char_map_info *) vp;
60 const char **out = zebra_maps_input(p->zm, p->reg_type, from, len, 0);
64 const char *outp = *out;
65 yaz_log(YLOG_LOG, "---");
68 yaz_log(YLOG_LOG, "%02X", *outp);
76 static void rpn_char_map_prepare(struct zebra_register *reg, int reg_type,
77 struct rpn_char_map_info *map_info)
79 map_info->zm = reg->zebra_maps;
80 map_info->reg_type = reg_type;
81 dict_grep_cmap(reg->dict, map_info, rpn_char_map_handler);
84 static int attr_find_ex(AttrType *src, oid_value *attributeSetP,
85 const char **string_value)
89 num_attributes = src->zapt->attributes->num_attributes;
90 while (src->major < num_attributes)
92 Z_AttributeElement *element;
94 element = src->zapt->attributes->attributes[src->major];
95 if (src->type == *element->attributeType)
97 switch (element->which)
99 case Z_AttributeValue_numeric:
101 if (element->attributeSet && attributeSetP)
105 attrset = oid_getentbyoid(element->attributeSet);
106 *attributeSetP = attrset->value;
108 return *element->value.numeric;
110 case Z_AttributeValue_complex:
111 if (src->minor >= element->value.complex->num_list)
113 if (element->attributeSet && attributeSetP)
117 attrset = oid_getentbyoid(element->attributeSet);
118 *attributeSetP = attrset->value;
120 if (element->value.complex->list[src->minor]->which ==
121 Z_StringOrNumeric_numeric)
125 *element->value.complex->list[src->minor-1]->u.numeric;
127 else if (element->value.complex->list[src->minor]->which ==
128 Z_StringOrNumeric_string)
134 element->value.complex->list[src->minor-1]->u.string;
148 static int attr_find(AttrType *src, oid_value *attributeSetP)
150 return attr_find_ex(src, attributeSetP, 0);
153 static void attr_init(AttrType *src, Z_AttributesPlusTerm *zapt,
176 void zebra_term_untrans(ZebraHandle zh, int reg_type,
177 char *dst, const char *src)
182 const char *cp = zebra_maps_output(zh->reg->zebra_maps,
184 if (!cp && len < IT_MAX_WORD-1)
187 while (*cp && len < IT_MAX_WORD-1)
193 static void add_isam_p(const char *name, const char *info,
198 log_level_rpn = yaz_log_module_level("rpn");
201 if (p->isam_p_indx == p->isam_p_size)
203 ISAM_P *new_isam_p_buf;
207 p->isam_p_size = 2*p->isam_p_size + 100;
208 new_isam_p_buf = (ISAM_P *) xmalloc(sizeof(*new_isam_p_buf) *
212 memcpy(new_isam_p_buf, p->isam_p_buf,
213 p->isam_p_indx * sizeof(*p->isam_p_buf));
214 xfree(p->isam_p_buf);
216 p->isam_p_buf = new_isam_p_buf;
219 new_term_no = (int *) xmalloc(sizeof(*new_term_no) * p->isam_p_size);
222 memcpy(new_term_no, p->isam_p_buf,
223 p->isam_p_indx * sizeof(*p->term_no));
226 p->term_no = new_term_no;
229 assert(*info == sizeof(*p->isam_p_buf));
230 memcpy(p->isam_p_buf + p->isam_p_indx, info+1, sizeof(*p->isam_p_buf));
237 char term_tmp[IT_MAX_WORD];
239 int len = key_SU_decode (&ord, (const unsigned char *) name);
241 zebra_term_untrans (p->zh, p->reg_type, term_tmp, name+len+1);
242 yaz_log(log_level_rpn, "grep: %d %c %s", ord, name[len], term_tmp);
243 zebraExplain_lookup_ord (p->zh->reg->zei,
244 ord, 0 /* index_type */, &db, &set, &use);
245 yaz_log(log_level_rpn, "grep: set=%d use=%d db=%s", set, use, db);
247 resultSetAddTerm(p->zh, p->termset, name[len], db,
254 static int grep_handle(char *name, const char *info, void *p)
256 add_isam_p(name, info, (struct grep_info *) p);
260 static int term_pre(ZebraMaps zebra_maps, int reg_type, const char **src,
261 const char *ct1, const char *ct2, int first)
263 const char *s1, *s0 = *src;
266 /* skip white space */
269 if (ct1 && strchr(ct1, *s0))
271 if (ct2 && strchr(ct2, *s0))
274 map = zebra_maps_input(zebra_maps, reg_type, &s1, strlen(s1), first);
275 if (**map != *CHR_SPACE)
284 static void esc_str(char *out_buf, int out_size,
285 const char *in_buf, int in_size)
291 assert(out_size > 20);
293 for (k = 0; k<in_size; k++)
295 int c = in_buf[k] & 0xff;
297 if (c < 32 || c > 126)
301 sprintf(out_buf +strlen(out_buf), "%02X:%c ", c, pc);
302 if (strlen(out_buf) > out_size-20)
304 strcat(out_buf, "..");
310 #define REGEX_CHARS " []()|.*+?!"
312 /* term_100: handle term, where trunc = none(no operators at all) */
313 static int term_100(ZebraMaps zebra_maps, int reg_type,
314 const char **src, char *dst, int space_split,
322 const char *space_start = 0;
323 const char *space_end = 0;
325 if (!term_pre(zebra_maps, reg_type, src, NULL, NULL, !space_split))
332 map = zebra_maps_search(zebra_maps, reg_type, &s0, strlen(s0),
336 if (**map == *CHR_SPACE)
339 else /* complete subfield only. */
341 if (**map == *CHR_SPACE)
342 { /* save space mapping for later .. */
347 else if (space_start)
348 { /* reload last space */
349 while (space_start < space_end)
351 if (strchr(REGEX_CHARS, *space_start))
353 dst_term[j++] = *space_start;
354 dst[i++] = *space_start++;
357 space_start = space_end = 0;
360 /* add non-space char */
361 memcpy(dst_term+j, s1, s0 - s1);
367 if (strchr(REGEX_CHARS, *s1))
375 esc_str(tmpbuf, sizeof(tmpbuf), map[0], strlen(map[0]));
377 strcpy(dst + i, map[0]);
387 /* term_101: handle term, where trunc = Process # */
388 static int term_101(ZebraMaps zebra_maps, int reg_type,
389 const char **src, char *dst, int space_split,
397 if (!term_pre(zebra_maps, reg_type, src, "#", "#", !space_split))
406 dst_term[j++] = *s0++;
412 map = zebra_maps_search(zebra_maps, reg_type, &s0, strlen(s0),
414 if (space_split && **map == *CHR_SPACE)
417 /* add non-space char */
418 memcpy(dst_term+j, s1, s0 - s1);
424 if (strchr(REGEX_CHARS, *s1))
432 esc_str(tmpbuf, sizeof(tmpbuf), map[0], strlen(map[0]));
434 strcpy(dst + i, map[0]);
440 dst_term[j++] = '\0';
445 /* term_103: handle term, where trunc = re-2 (regular expressions) */
446 static int term_103(ZebraMaps zebra_maps, int reg_type, const char **src,
447 char *dst, int *errors, int space_split,
455 if (!term_pre(zebra_maps, reg_type, src, "^\\()[].*+?|", "(", !space_split))
458 if (errors && *s0 == '+' && s0[1] && s0[2] == '+' && s0[3] &&
459 isdigit(((const unsigned char *)s0)[1]))
461 *errors = s0[1] - '0';
468 if (strchr("^\\()[].*+?|-", *s0))
477 map = zebra_maps_search(zebra_maps, reg_type, &s0, strlen(s0),
479 if (space_split && **map == *CHR_SPACE)
482 /* add non-space char */
483 memcpy(dst_term+j, s1, s0 - s1);
489 if (strchr(REGEX_CHARS, *s1))
497 esc_str(tmpbuf, sizeof(tmpbuf), map[0], strlen(map[0]));
499 strcpy(dst + i, map[0]);
511 /* term_103: handle term, where trunc = re-1 (regular expressions) */
512 static int term_102(ZebraMaps zebra_maps, int reg_type, const char **src,
513 char *dst, int space_split, char *dst_term)
515 return term_103(zebra_maps, reg_type, src, dst, NULL, space_split,
520 /* term_104: handle term, where trunc = Process # and ! */
521 static int term_104(ZebraMaps zebra_maps, int reg_type,
522 const char **src, char *dst, int space_split,
530 if (!term_pre(zebra_maps, reg_type, src, "?*#", "?*#", !space_split))
537 dst_term[j++] = *s0++;
538 if (*s0 >= '0' && *s0 <= '9')
541 while (*s0 >= '0' && *s0 <= '9')
543 limit = limit * 10 + (*s0 - '0');
544 dst_term[j++] = *s0++;
564 dst_term[j++] = *s0++;
569 dst_term[j++] = *s0++;
575 map = zebra_maps_search(zebra_maps, reg_type, &s0, strlen(s0),
577 if (space_split && **map == *CHR_SPACE)
580 /* add non-space char */
581 memcpy(dst_term+j, s1, s0 - s1);
587 if (strchr(REGEX_CHARS, *s1))
595 esc_str(tmpbuf, sizeof(tmpbuf), map[0], strlen(map[0]));
597 strcpy(dst + i, map[0]);
603 dst_term[j++] = '\0';
608 /* term_105/106: handle term, where trunc = Process * and ! and right trunc */
609 static int term_105(ZebraMaps zebra_maps, int reg_type,
610 const char **src, char *dst, int space_split,
611 char *dst_term, int right_truncate)
618 if (!term_pre(zebra_maps, reg_type, src, "*!", "*!", !space_split))
627 dst_term[j++] = *s0++;
632 dst_term[j++] = *s0++;
638 map = zebra_maps_search(zebra_maps, reg_type, &s0, strlen(s0),
640 if (space_split && **map == *CHR_SPACE)
643 /* add non-space char */
644 memcpy(dst_term+j, s1, s0 - s1);
650 if (strchr(REGEX_CHARS, *s1))
658 esc_str(tmpbuf, sizeof(tmpbuf), map[0], strlen(map[0]));
660 strcpy(dst + i, map[0]);
672 dst_term[j++] = '\0';
678 /* gen_regular_rel - generate regular expression from relation
679 * val: border value (inclusive)
680 * islt: 1 if <=; 0 if >=.
682 static void gen_regular_rel(char *dst, int val, int islt)
689 yaz_log(YLOG_DEBUG, "gen_regular_rel. val=%d, islt=%d", val, islt);
693 strcpy(dst, "(-[0-9]+|(");
701 strcpy(dst, "([0-9]+|-(");
713 sprintf(numstr, "%d", val);
714 for (w = strlen(numstr); --w >= 0; pos++)
733 strcpy(dst + dst_p, numstr);
734 dst_p = strlen(dst) - pos - 1;
762 for (i = 0; i<pos; i++)
775 /* match everything less than 10^(pos-1) */
777 for (i = 1; i<pos; i++)
778 strcat(dst, "[0-9]?");
782 /* match everything greater than 10^pos */
783 for (i = 0; i <= pos; i++)
784 strcat(dst, "[0-9]");
785 strcat(dst, "[0-9]*");
790 void string_rel_add_char(char **term_p, const char *src, int *indx)
792 if (src[*indx] == '\\')
793 *(*term_p)++ = src[(*indx)++];
794 *(*term_p)++ = src[(*indx)++];
798 * > abc ([b-].*|a[c-].*|ab[d-].*|abc.+)
799 * ([^-a].*|a[^-b].*ab[^-c].*|abc.+)
800 * >= abc ([b-].*|a[c-].*|ab[c-].*)
801 * ([^-a].*|a[^-b].*|ab[c-].*)
802 * < abc ([-0].*|a[-a].*|ab[-b].*)
803 * ([^a-].*|a[^b-].*|ab[^c-].*)
804 * <= abc ([-0].*|a[-a].*|ab[-b].*|abc)
805 * ([^a-].*|a[^b-].*|ab[^c-].*|abc)
807 static int string_relation(ZebraHandle zh, Z_AttributesPlusTerm *zapt,
808 const char **term_sub, char *term_dict,
809 oid_value attributeSet,
810 int reg_type, int space_split, char *term_dst,
816 char *term_tmp = term_dict + strlen(term_dict);
817 char term_component[2*IT_MAX_WORD+20];
819 attr_init(&relation, zapt, 2);
820 relation_value = attr_find(&relation, NULL);
823 yaz_log(YLOG_DEBUG, "string relation value=%d", relation_value);
824 switch (relation_value)
827 if (!term_100(zh->reg->zebra_maps, reg_type,
828 term_sub, term_component,
829 space_split, term_dst))
831 yaz_log(log_level_rpn, "Relation <");
834 for (i = 0; term_component[i]; )
841 string_rel_add_char(&term_tmp, term_component, &j);
846 string_rel_add_char(&term_tmp, term_component, &i);
853 if ((term_tmp - term_dict) > IT_MAX_WORD)
860 if (!term_100(zh->reg->zebra_maps, reg_type,
861 term_sub, term_component,
862 space_split, term_dst))
864 yaz_log(log_level_rpn, "Relation <=");
867 for (i = 0; term_component[i]; )
872 string_rel_add_char(&term_tmp, term_component, &j);
876 string_rel_add_char(&term_tmp, term_component, &i);
885 if ((term_tmp - term_dict) > IT_MAX_WORD)
888 for (i = 0; term_component[i]; )
889 string_rel_add_char(&term_tmp, term_component, &i);
894 if (!term_100 (zh->reg->zebra_maps, reg_type,
895 term_sub, term_component, space_split, term_dst))
897 yaz_log(log_level_rpn, "Relation >");
900 for (i = 0; term_component[i];)
905 string_rel_add_char(&term_tmp, term_component, &j);
910 string_rel_add_char(&term_tmp, term_component, &i);
918 if ((term_tmp - term_dict) > IT_MAX_WORD)
921 for (i = 0; term_component[i];)
922 string_rel_add_char(&term_tmp, term_component, &i);
929 if (!term_100(zh->reg->zebra_maps, reg_type, term_sub,
930 term_component, space_split, term_dst))
932 yaz_log(log_level_rpn, "Relation >=");
935 for (i = 0; term_component[i];)
942 string_rel_add_char(&term_tmp, term_component, &j);
945 if (term_component[i+1])
949 string_rel_add_char(&term_tmp, term_component, &i);
953 string_rel_add_char(&term_tmp, term_component, &i);
960 if ((term_tmp - term_dict) > IT_MAX_WORD)
969 yaz_log(log_level_rpn, "Relation =");
970 if (!term_100(zh->reg->zebra_maps, reg_type, term_sub,
971 term_component, space_split, term_dst))
973 strcat(term_tmp, "(");
974 strcat(term_tmp, term_component);
975 strcat(term_tmp, ")");
978 *error_code = YAZ_BIB1_UNSUPP_RELATION_ATTRIBUTE;
984 static ZEBRA_RES string_term(ZebraHandle zh, Z_AttributesPlusTerm *zapt,
985 const char **term_sub,
986 oid_value attributeSet, NMEM stream,
987 struct grep_info *grep_info,
988 int reg_type, int complete_flag,
989 int num_bases, char **basenames,
990 char *term_dst, int xpath_use,
991 struct ord_list **ol);
993 static ZEBRA_RES term_limits_APT(ZebraHandle zh,
994 Z_AttributesPlusTerm *zapt,
995 zint *hits_limit_value,
996 const char **term_ref_id_str,
999 AttrType term_ref_id_attr;
1000 AttrType hits_limit_attr;
1001 int term_ref_id_int;
1003 attr_init(&hits_limit_attr, zapt, 9);
1004 *hits_limit_value = attr_find(&hits_limit_attr, NULL);
1006 attr_init(&term_ref_id_attr, zapt, 10);
1007 term_ref_id_int = attr_find_ex(&term_ref_id_attr, NULL, term_ref_id_str);
1008 if (term_ref_id_int >= 0)
1010 char *res = nmem_malloc(nmem, 20);
1011 sprintf(res, "%d", term_ref_id_int);
1012 *term_ref_id_str = res;
1015 /* no limit given ? */
1016 if (*hits_limit_value == -1)
1018 if (*term_ref_id_str)
1020 /* use global if term_ref is present */
1021 *hits_limit_value = zh->approx_limit;
1025 /* no counting if term_ref is not present */
1026 *hits_limit_value = 0;
1029 else if (*hits_limit_value == 0)
1031 /* 0 is the same as global limit */
1032 *hits_limit_value = zh->approx_limit;
1034 yaz_log(YLOG_DEBUG, "term_limits_APT ref_id=%s limit=" ZINT_FORMAT,
1035 *term_ref_id_str ? *term_ref_id_str : "none",
1040 static ZEBRA_RES term_trunc(ZebraHandle zh,
1041 Z_AttributesPlusTerm *zapt,
1042 const char **term_sub,
1043 oid_value attributeSet, NMEM stream,
1044 struct grep_info *grep_info,
1045 int reg_type, int complete_flag,
1046 int num_bases, char **basenames,
1048 const char *rank_type, int xpath_use,
1051 struct rset_key_control *kc)
1054 struct ord_list *ol;
1055 zint hits_limit_value;
1056 const char *term_ref_id_str = 0;
1059 term_limits_APT(zh, zapt, &hits_limit_value, &term_ref_id_str,
1061 grep_info->isam_p_indx = 0;
1062 res = string_term(zh, zapt, term_sub, attributeSet, stream, grep_info,
1063 reg_type, complete_flag, num_bases, basenames,
1064 term_dst, xpath_use, &ol);
1065 if (res != ZEBRA_OK)
1067 if (!*term_sub) /* no more terms ? */
1069 yaz_log(log_level_rpn, "term: %s", term_dst);
1070 *rset = rset_trunc(zh, grep_info->isam_p_buf,
1071 grep_info->isam_p_indx, term_dst,
1072 strlen(term_dst), rank_type, 1 /* preserve pos */,
1073 zapt->term->which, rset_nmem,
1074 kc, kc->scope, ol, reg_type, hits_limit_value,
1081 static ZEBRA_RES string_term(ZebraHandle zh, Z_AttributesPlusTerm *zapt,
1082 const char **term_sub,
1083 oid_value attributeSet, NMEM stream,
1084 struct grep_info *grep_info,
1085 int reg_type, int complete_flag,
1086 int num_bases, char **basenames,
1087 char *term_dst, int xpath_use,
1088 struct ord_list **ol)
1090 char term_dict[2*IT_MAX_WORD+4000];
1092 AttrType truncation;
1093 int truncation_value;
1096 const char *use_string = 0;
1097 oid_value curAttributeSet = attributeSet;
1099 struct rpn_char_map_info rcmi;
1100 int space_split = complete_flag ? 0 : 1;
1102 int bases_ok = 0; /* no of databases with OK attribute */
1104 *ol = ord_list_create(stream);
1106 rpn_char_map_prepare (zh->reg, reg_type, &rcmi);
1107 attr_init(&use, zapt, 1);
1108 use_value = attr_find_ex(&use, &curAttributeSet, &use_string);
1109 yaz_log(log_level_rpn, "string_term, use value %d", use_value);
1110 attr_init(&truncation, zapt, 5);
1111 truncation_value = attr_find(&truncation, NULL);
1112 yaz_log(log_level_rpn, "truncation value %d", truncation_value);
1114 if (use_value == -1) /* no attribute - assumy "any" */
1116 for (base_no = 0; base_no < num_bases; base_no++)
1120 int regex_range = 0;
1123 data1_local_attribute id_xpath_attr;
1124 data1_local_attribute *local_attr;
1125 int max_pos, prefix_len = 0;
1130 if (zebraExplain_curDatabase (zh->reg->zei, basenames[base_no]))
1132 zebra_setError(zh, YAZ_BIB1_DATABASE_UNAVAILABLE,
1133 basenames[base_no]);
1136 if (xpath_use > 0 && use_value == -2)
1138 /* xpath mode and we have a string attribute */
1139 attp.local_attributes = &id_xpath_attr;
1140 attp.attset_ordinal = VAL_IDXPATH;
1141 id_xpath_attr.next = 0;
1143 use_value = xpath_use; /* xpath_use as use-attribute now */
1144 id_xpath_attr.local = use_value;
1146 else if (curAttributeSet == VAL_IDXPATH && use_value >= 0)
1148 /* X-Path attribute, use numeric value directly */
1149 attp.local_attributes = &id_xpath_attr;
1150 attp.attset_ordinal = VAL_IDXPATH;
1151 id_xpath_attr.next = 0;
1152 id_xpath_attr.local = use_value;
1154 else if (use_string &&
1155 (ord = zebraExplain_lookup_attr_str(zh->reg->zei,
1159 /* we have a match for a raw string attribute */
1164 term_dict[prefix_len++] = '|';
1166 term_dict[prefix_len++] = '(';
1168 ord_len = key_SU_encode (ord, ord_buf);
1169 for (i = 0; i<ord_len; i++)
1171 term_dict[prefix_len++] = 1;
1172 term_dict[prefix_len++] = ord_buf[i];
1174 attp.local_attributes = 0; /* no more attributes */
1175 *ol = ord_list_append(stream, *ol, ord);
1179 /* lookup in the .att files . Allow string as well */
1180 if ((r = att_getentbyatt (zh, &attp, curAttributeSet, use_value,
1183 yaz_log(YLOG_DEBUG, "att_getentbyatt fail. set=%d use=%d r=%d",
1184 curAttributeSet, use_value, r);
1187 /* set was found, but value wasn't defined */
1190 YAZ_BIB1_UNSUPP_USE_ATTRIBUTE,
1193 zebra_setError_zint(zh, YAZ_BIB1_UNSUPP_USE_ATTRIBUTE,
1199 struct oident oident;
1201 oident.proto = PROTO_Z3950;
1202 oident.oclass = CLASS_ATTSET;
1203 oident.value = curAttributeSet;
1204 oid_ent_to_oid (&oident, oid);
1207 YAZ_BIB1_UNSUPP_ATTRIBUTE_SET,
1214 for (local_attr = attp.local_attributes; local_attr;
1215 local_attr = local_attr->next)
1220 ord = zebraExplain_lookup_attr_su(zh->reg->zei,
1222 attp.attset_ordinal,
1226 *ol = ord_list_append(stream, *ol, ord);
1228 term_dict[prefix_len++] = '|';
1230 term_dict[prefix_len++] = '(';
1232 ord_len = key_SU_encode (ord, ord_buf);
1233 for (i = 0; i<ord_len; i++)
1235 term_dict[prefix_len++] = 1;
1236 term_dict[prefix_len++] = ord_buf[i];
1243 term_dict[prefix_len++] = ')';
1244 term_dict[prefix_len] = '\0';
1246 switch (truncation_value)
1248 case -1: /* not specified */
1249 case 100: /* do not truncate */
1250 if (!string_relation (zh, zapt, &termp, term_dict,
1252 reg_type, space_split, term_dst,
1257 zebra_setError(zh, relation_error, 0);
1264 case 1: /* right truncation */
1265 term_dict[j++] = '(';
1266 if (!term_100(zh->reg->zebra_maps, reg_type,
1267 &termp, term_dict + j, space_split, term_dst))
1272 strcat(term_dict, ".*)");
1274 case 2: /* keft truncation */
1275 term_dict[j++] = '('; term_dict[j++] = '.'; term_dict[j++] = '*';
1276 if (!term_100(zh->reg->zebra_maps, reg_type,
1277 &termp, term_dict + j, space_split, term_dst))
1282 strcat(term_dict, ")");
1284 case 3: /* left&right truncation */
1285 term_dict[j++] = '('; term_dict[j++] = '.'; term_dict[j++] = '*';
1286 if (!term_100(zh->reg->zebra_maps, reg_type,
1287 &termp, term_dict + j, space_split, term_dst))
1292 strcat(term_dict, ".*)");
1294 case 101: /* process # in term */
1295 term_dict[j++] = '(';
1296 if (!term_101(zh->reg->zebra_maps, reg_type,
1297 &termp, term_dict + j, space_split, term_dst))
1302 strcat(term_dict, ")");
1304 case 102: /* Regexp-1 */
1305 term_dict[j++] = '(';
1306 if (!term_102(zh->reg->zebra_maps, reg_type,
1307 &termp, term_dict + j, space_split, term_dst))
1312 strcat(term_dict, ")");
1314 case 103: /* Regexp-2 */
1316 term_dict[j++] = '(';
1318 if (!term_103(zh->reg->zebra_maps, reg_type,
1319 &termp, term_dict + j, ®ex_range,
1320 space_split, term_dst))
1325 strcat(term_dict, ")");
1327 case 104: /* process # and ! in term */
1328 term_dict[j++] = '(';
1329 if (!term_104(zh->reg->zebra_maps, reg_type,
1330 &termp, term_dict + j, space_split, term_dst))
1335 strcat(term_dict, ")");
1337 case 105: /* process * and ! in term */
1338 term_dict[j++] = '(';
1339 if (!term_105(zh->reg->zebra_maps, reg_type,
1340 &termp, term_dict + j, space_split, term_dst, 1))
1345 strcat(term_dict, ")");
1347 case 106: /* process * and ! in term */
1348 term_dict[j++] = '(';
1349 if (!term_105(zh->reg->zebra_maps, reg_type,
1350 &termp, term_dict + j, space_split, term_dst, 0))
1355 strcat(term_dict, ")");
1358 zebra_setError_zint(zh,
1359 YAZ_BIB1_UNSUPP_TRUNCATION_ATTRIBUTE,
1366 const char *input = term_dict + prefix_len;
1367 esc_str(buf, sizeof(buf), input, strlen(input));
1371 yaz_log(log_level_rpn, "dict_lookup_grep: %s", term_dict+prefix_len);
1372 r = dict_lookup_grep(zh->reg->dict, term_dict, regex_range,
1373 grep_info, &max_pos, init_pos,
1376 yaz_log(YLOG_WARN, "dict_lookup_grep fail %d", r);
1382 yaz_log(YLOG_DEBUG, "%d positions", grep_info->isam_p_indx);
1387 /* convert APT search term to UTF8 */
1388 static ZEBRA_RES zapt_term_to_utf8(ZebraHandle zh, Z_AttributesPlusTerm *zapt,
1392 Z_Term *term = zapt->term;
1394 switch (term->which)
1396 case Z_Term_general:
1397 if (zh->iconv_to_utf8 != 0)
1399 char *inbuf = (char *) term->u.general->buf;
1400 size_t inleft = term->u.general->len;
1401 char *outbuf = termz;
1402 size_t outleft = IT_MAX_WORD-1;
1405 ret = yaz_iconv(zh->iconv_to_utf8, &inbuf, &inleft,
1407 if (ret == (size_t)(-1))
1409 ret = yaz_iconv(zh->iconv_to_utf8, 0, 0, 0, 0);
1412 YAZ_BIB1_QUERY_TERM_INCLUDES_CHARS_THAT_DO_NOT_TRANSLATE_INTO_,
1420 sizez = term->u.general->len;
1421 if (sizez > IT_MAX_WORD-1)
1422 sizez = IT_MAX_WORD-1;
1423 memcpy (termz, term->u.general->buf, sizez);
1424 termz[sizez] = '\0';
1427 case Z_Term_characterString:
1428 sizez = strlen(term->u.characterString);
1429 if (sizez > IT_MAX_WORD-1)
1430 sizez = IT_MAX_WORD-1;
1431 memcpy (termz, term->u.characterString, sizez);
1432 termz[sizez] = '\0';
1435 zebra_setError(zh, YAZ_BIB1_UNSUPP_CODED_VALUE_FOR_TERM, 0);
1441 /* convert APT SCAN term to internal cmap */
1442 static ZEBRA_RES trans_scan_term(ZebraHandle zh, Z_AttributesPlusTerm *zapt,
1443 char *termz, int reg_type)
1445 char termz0[IT_MAX_WORD];
1447 if (zapt_term_to_utf8(zh, zapt, termz0) == ZEBRA_FAIL)
1448 return ZEBRA_FAIL; /* error */
1452 const char *cp = (const char *) termz0;
1453 const char *cp_end = cp + strlen(cp);
1456 const char *space_map = NULL;
1459 while ((len = (cp_end - cp)) > 0)
1461 map = zebra_maps_input(zh->reg->zebra_maps, reg_type, &cp, len, 0);
1462 if (**map == *CHR_SPACE)
1467 for (src = space_map; *src; src++)
1470 for (src = *map; *src; src++)
1479 static void grep_info_delete(struct grep_info *grep_info)
1482 xfree(grep_info->term_no);
1484 xfree(grep_info->isam_p_buf);
1487 static ZEBRA_RES grep_info_prepare(ZebraHandle zh,
1488 Z_AttributesPlusTerm *zapt,
1489 struct grep_info *grep_info,
1493 int termset_value_numeric;
1494 const char *termset_value_string;
1497 grep_info->term_no = 0;
1499 grep_info->isam_p_size = 0;
1500 grep_info->isam_p_buf = NULL;
1502 grep_info->reg_type = reg_type;
1503 grep_info->termset = 0;
1507 attr_init(&termset, zapt, 8);
1508 termset_value_numeric =
1509 attr_find_ex(&termset, NULL, &termset_value_string);
1510 if (termset_value_numeric != -1)
1513 const char *termset_name = 0;
1514 if (termset_value_numeric != -2)
1517 sprintf(resname, "%d", termset_value_numeric);
1518 termset_name = resname;
1521 termset_name = termset_value_string;
1522 yaz_log(log_level_rpn, "creating termset set %s", termset_name);
1523 grep_info->termset = resultSetAdd(zh, termset_name, 1);
1524 if (!grep_info->termset)
1526 zebra_setError(zh, YAZ_BIB1_ILLEGAL_RESULT_SET_NAME, termset_name);
1534 \brief Create result set(s) for list of terms
1535 \param zh Zebra Handle
1536 \param termz term as used in query but converted to UTF-8
1537 \param attributeSet default attribute set
1538 \param stream memory for result
1539 \param reg_type register type ('w', 'p',..)
1540 \param complete_flag whether it's phrases or not
1541 \param rank_type term flags for ranking
1542 \param xpath_use use attribute for X-Path (-1 for no X-path)
1543 \param num_bases number of databases
1544 \param basenames array of databases
1545 \param rset_mem memory for result sets
1546 \param result_sets output result set for each term in list (output)
1547 \param number number of output result sets
1548 \param kc rset key control to be used for created result sets
1550 static ZEBRA_RES term_list_trunc(ZebraHandle zh,
1551 Z_AttributesPlusTerm *zapt,
1553 oid_value attributeSet,
1555 int reg_type, int complete_flag,
1556 const char *rank_type, int xpath_use,
1557 int num_bases, char **basenames,
1559 RSET **result_sets, int *num_result_sets,
1560 struct rset_key_control *kc)
1562 char term_dst[IT_MAX_WORD+1];
1563 struct grep_info grep_info;
1564 const char *termp = termz;
1567 *num_result_sets = 0;
1569 if (grep_info_prepare(zh, zapt, &grep_info, reg_type) == ZEBRA_FAIL)
1575 if (alloc_sets == *num_result_sets)
1578 RSET *rnew = (RSET *) nmem_malloc(stream, (alloc_sets+add) *
1581 memcpy(rnew, *result_sets, alloc_sets * sizeof(*rnew));
1582 alloc_sets = alloc_sets + add;
1583 *result_sets = rnew;
1585 res = term_trunc(zh, zapt, &termp, attributeSet,
1587 reg_type, complete_flag,
1588 num_bases, basenames,
1589 term_dst, rank_type,
1590 xpath_use, rset_nmem,
1591 &(*result_sets)[*num_result_sets],
1593 if (res != ZEBRA_OK)
1596 for (i = 0; i < *num_result_sets; i++)
1597 rset_delete((*result_sets)[i]);
1598 grep_info_delete (&grep_info);
1601 if ((*result_sets)[*num_result_sets] == 0)
1603 (*num_result_sets)++;
1605 grep_info_delete(&grep_info);
1609 static ZEBRA_RES rpn_search_APT_phrase(ZebraHandle zh,
1610 Z_AttributesPlusTerm *zapt,
1611 const char *termz_org,
1612 oid_value attributeSet,
1614 int reg_type, int complete_flag,
1615 const char *rank_type, int xpath_use,
1616 int num_bases, char **basenames,
1619 struct rset_key_control *kc)
1621 RSET *result_sets = 0;
1622 int num_result_sets = 0;
1624 term_list_trunc(zh, zapt, termz_org, attributeSet,
1625 stream, reg_type, complete_flag,
1626 rank_type, xpath_use,
1627 num_bases, basenames,
1629 &result_sets, &num_result_sets, kc);
1630 if (res != ZEBRA_OK)
1632 if (num_result_sets == 0)
1633 *rset = rsnull_create (rset_nmem, kc, 0);
1634 else if (num_result_sets == 1)
1635 *rset = result_sets[0];
1637 *rset = rsprox_create(rset_nmem, kc, kc->scope,
1638 num_result_sets, result_sets,
1639 1 /* ordered */, 0 /* exclusion */,
1640 3 /* relation */, 1 /* distance */);
1646 static ZEBRA_RES rpn_search_APT_or_list(ZebraHandle zh,
1647 Z_AttributesPlusTerm *zapt,
1648 const char *termz_org,
1649 oid_value attributeSet,
1651 int reg_type, int complete_flag,
1652 const char *rank_type,
1654 int num_bases, char **basenames,
1657 struct rset_key_control *kc)
1659 RSET *result_sets = 0;
1660 int num_result_sets = 0;
1662 term_list_trunc(zh, zapt, termz_org, attributeSet,
1663 stream, reg_type, complete_flag,
1664 rank_type, xpath_use,
1665 num_bases, basenames,
1667 &result_sets, &num_result_sets, kc);
1668 if (res != ZEBRA_OK)
1670 if (num_result_sets == 0)
1671 *rset = rsnull_create (rset_nmem, kc, 0);
1672 else if (num_result_sets == 1)
1673 *rset = result_sets[0];
1675 *rset = rsmulti_or_create(rset_nmem, kc, kc->scope, 0 /* termid */,
1676 num_result_sets, result_sets);
1682 static ZEBRA_RES rpn_search_APT_and_list(ZebraHandle zh,
1683 Z_AttributesPlusTerm *zapt,
1684 const char *termz_org,
1685 oid_value attributeSet,
1687 int reg_type, int complete_flag,
1688 const char *rank_type,
1690 int num_bases, char **basenames,
1693 struct rset_key_control *kc)
1695 RSET *result_sets = 0;
1696 int num_result_sets = 0;
1698 term_list_trunc(zh, zapt, termz_org, attributeSet,
1699 stream, reg_type, complete_flag,
1700 rank_type, xpath_use,
1701 num_bases, basenames,
1703 &result_sets, &num_result_sets,
1705 if (res != ZEBRA_OK)
1707 if (num_result_sets == 0)
1708 *rset = rsnull_create (rset_nmem, kc, 0);
1709 else if (num_result_sets == 1)
1710 *rset = result_sets[0];
1712 *rset = rsmulti_and_create(rset_nmem, kc, kc->scope,
1713 num_result_sets, result_sets);
1719 static int numeric_relation(ZebraHandle zh, Z_AttributesPlusTerm *zapt,
1720 const char **term_sub,
1722 oid_value attributeSet,
1723 struct grep_info *grep_info,
1733 char *term_tmp = term_dict + strlen(term_dict);
1736 attr_init(&relation, zapt, 2);
1737 relation_value = attr_find(&relation, NULL);
1739 yaz_log(log_level_rpn, "numeric relation value=%d", relation_value);
1741 if (!term_100(zh->reg->zebra_maps, reg_type, term_sub, term_tmp, 1,
1744 term_value = atoi (term_tmp);
1745 switch (relation_value)
1748 yaz_log(log_level_rpn, "Relation <");
1749 gen_regular_rel(term_tmp, term_value-1, 1);
1752 yaz_log(log_level_rpn, "Relation <=");
1753 gen_regular_rel(term_tmp, term_value, 1);
1756 yaz_log(log_level_rpn, "Relation >=");
1757 gen_regular_rel(term_tmp, term_value, 0);
1760 yaz_log(log_level_rpn, "Relation >");
1761 gen_regular_rel(term_tmp, term_value+1, 0);
1765 yaz_log(log_level_rpn, "Relation =");
1766 sprintf(term_tmp, "(0*%d)", term_value);
1769 *error_code = YAZ_BIB1_UNSUPP_RELATION_ATTRIBUTE;
1772 yaz_log(log_level_rpn, "dict_lookup_grep: %s", term_tmp);
1773 r = dict_lookup_grep(zh->reg->dict, term_dict, 0, grep_info, max_pos,
1776 yaz_log(YLOG_WARN, "dict_lookup_grep fail, rel = gt: %d", r);
1777 yaz_log(log_level_rpn, "%d positions", grep_info->isam_p_indx);
1781 static ZEBRA_RES numeric_term(ZebraHandle zh, Z_AttributesPlusTerm *zapt,
1782 const char **term_sub,
1783 oid_value attributeSet,
1784 struct grep_info *grep_info,
1785 int reg_type, int complete_flag,
1786 int num_bases, char **basenames,
1787 char *term_dst, int xpath_use, NMEM stream)
1789 char term_dict[2*IT_MAX_WORD+2];
1793 const char *use_string = 0;
1794 oid_value curAttributeSet = attributeSet;
1796 struct rpn_char_map_info rcmi;
1798 int bases_ok = 0; /* no of databases with OK attribute */
1800 rpn_char_map_prepare (zh->reg, reg_type, &rcmi);
1801 attr_init(&use, zapt, 1);
1802 use_value = attr_find_ex(&use, &curAttributeSet, &use_string);
1804 if (use_value == -1)
1807 for (base_no = 0; base_no < num_bases; base_no++)
1810 data1_local_attribute id_xpath_attr;
1811 data1_local_attribute *local_attr;
1812 int max_pos, prefix_len = 0;
1813 int relation_error = 0;
1816 if (use_value == -2) /* string attribute (assume IDXPATH/any) */
1818 use_value = xpath_use;
1819 attp.local_attributes = &id_xpath_attr;
1820 attp.attset_ordinal = VAL_IDXPATH;
1821 id_xpath_attr.next = 0;
1822 id_xpath_attr.local = use_value;
1824 else if (curAttributeSet == VAL_IDXPATH)
1826 attp.local_attributes = &id_xpath_attr;
1827 attp.attset_ordinal = VAL_IDXPATH;
1828 id_xpath_attr.next = 0;
1829 id_xpath_attr.local = use_value;
1833 if ((r = att_getentbyatt (zh, &attp, curAttributeSet, use_value,
1836 yaz_log(YLOG_DEBUG, "att_getentbyatt fail. set=%d use=%d r=%d",
1837 curAttributeSet, use_value, r);
1842 YAZ_BIB1_UNSUPP_USE_ATTRIBUTE,
1845 zebra_setError_zint(zh, YAZ_BIB1_UNSUPP_USE_ATTRIBUTE,
1849 zebra_setError(zh, YAZ_BIB1_UNSUPP_ATTRIBUTE_SET, 0);
1853 if (zebraExplain_curDatabase (zh->reg->zei, basenames[base_no]))
1855 zebra_setError(zh, YAZ_BIB1_DATABASE_UNAVAILABLE,
1856 basenames[base_no]);
1859 for (local_attr = attp.local_attributes; local_attr;
1860 local_attr = local_attr->next)
1866 ord = zebraExplain_lookup_attr_su(zh->reg->zei,
1868 attp.attset_ordinal,
1873 term_dict[prefix_len++] = '|';
1875 term_dict[prefix_len++] = '(';
1877 ord_len = key_SU_encode (ord, ord_buf);
1878 for (i = 0; i<ord_len; i++)
1880 term_dict[prefix_len++] = 1;
1881 term_dict[prefix_len++] = ord_buf[i];
1886 zebra_setError_zint(zh, YAZ_BIB1_UNSUPP_USE_ATTRIBUTE, use_value);
1890 term_dict[prefix_len++] = ')';
1891 term_dict[prefix_len] = '\0';
1892 if (!numeric_relation(zh, zapt, &termp, term_dict,
1893 attributeSet, grep_info, &max_pos, reg_type,
1894 term_dst, &relation_error))
1898 zebra_setError(zh, relation_error, 0);
1908 yaz_log(YLOG_DEBUG, "%d positions", grep_info->isam_p_indx);
1913 static ZEBRA_RES rpn_search_APT_numeric(ZebraHandle zh,
1914 Z_AttributesPlusTerm *zapt,
1916 oid_value attributeSet,
1918 int reg_type, int complete_flag,
1919 const char *rank_type, int xpath_use,
1920 int num_bases, char **basenames,
1923 struct rset_key_control *kc)
1925 char term_dst[IT_MAX_WORD+1];
1926 const char *termp = termz;
1927 RSET *result_sets = 0;
1928 int num_result_sets = 0;
1930 struct grep_info grep_info;
1932 zint hits_limit_value;
1933 const char *term_ref_id_str = 0;
1935 term_limits_APT(zh, zapt, &hits_limit_value, &term_ref_id_str, stream);
1937 yaz_log(log_level_rpn, "APT_numeric t='%s'", termz);
1938 if (grep_info_prepare(zh, zapt, &grep_info, reg_type) == ZEBRA_FAIL)
1942 if (alloc_sets == num_result_sets)
1945 RSET *rnew = (RSET *) nmem_malloc(stream, (alloc_sets+add) *
1948 memcpy(rnew, result_sets, alloc_sets * sizeof(*rnew));
1949 alloc_sets = alloc_sets + add;
1952 yaz_log(YLOG_DEBUG, "APT_numeric termp=%s", termp);
1953 grep_info.isam_p_indx = 0;
1954 res = numeric_term(zh, zapt, &termp, attributeSet, &grep_info,
1955 reg_type, complete_flag, num_bases, basenames,
1956 term_dst, xpath_use,
1958 if (res == ZEBRA_FAIL || termp == 0)
1960 yaz_log(YLOG_DEBUG, "term: %s", term_dst);
1961 result_sets[num_result_sets] =
1962 rset_trunc(zh, grep_info.isam_p_buf,
1963 grep_info.isam_p_indx, term_dst,
1964 strlen(term_dst), rank_type,
1965 0 /* preserve position */,
1966 zapt->term->which, rset_nmem,
1967 kc, kc->scope, 0, reg_type,
1970 if (!result_sets[num_result_sets])
1974 grep_info_delete(&grep_info);
1978 for (i = 0; i<num_result_sets; i++)
1979 rset_delete(result_sets[i]);
1982 if (num_result_sets == 0)
1983 *rset = rsnull_create(rset_nmem, kc, 0);
1984 if (num_result_sets == 1)
1985 *rset = result_sets[0];
1987 *rset = rsmulti_and_create(rset_nmem, kc, kc->scope,
1988 num_result_sets, result_sets);
1994 static ZEBRA_RES rpn_search_APT_local(ZebraHandle zh,
1995 Z_AttributesPlusTerm *zapt,
1997 oid_value attributeSet,
1999 const char *rank_type, NMEM rset_nmem,
2001 struct rset_key_control *kc)
2006 *rset = rstemp_create(rset_nmem, kc, kc->scope,
2007 res_get (zh->res, "setTmpDir"),0 );
2008 rsfd = rset_open(*rset, RSETF_WRITE);
2016 rset_write (rsfd, &key);
2021 static ZEBRA_RES rpn_sort_spec(ZebraHandle zh, Z_AttributesPlusTerm *zapt,
2022 oid_value attributeSet, NMEM stream,
2023 Z_SortKeySpecList *sort_sequence,
2024 const char *rank_type,
2027 struct rset_key_control *kc)
2030 int sort_relation_value;
2031 AttrType sort_relation_type;
2038 attr_init(&sort_relation_type, zapt, 7);
2039 sort_relation_value = attr_find(&sort_relation_type, &attributeSet);
2041 if (!sort_sequence->specs)
2043 sort_sequence->num_specs = 10;
2044 sort_sequence->specs = (Z_SortKeySpec **)
2045 nmem_malloc(stream, sort_sequence->num_specs *
2046 sizeof(*sort_sequence->specs));
2047 for (i = 0; i<sort_sequence->num_specs; i++)
2048 sort_sequence->specs[i] = 0;
2050 if (zapt->term->which != Z_Term_general)
2053 i = atoi_n ((char *) zapt->term->u.general->buf,
2054 zapt->term->u.general->len);
2055 if (i >= sort_sequence->num_specs)
2057 sprintf(termz, "%d", i);
2059 oe.proto = PROTO_Z3950;
2060 oe.oclass = CLASS_ATTSET;
2061 oe.value = attributeSet;
2062 if (!oid_ent_to_oid (&oe, oid))
2065 sks = (Z_SortKeySpec *) nmem_malloc(stream, sizeof(*sks));
2066 sks->sortElement = (Z_SortElement *)
2067 nmem_malloc(stream, sizeof(*sks->sortElement));
2068 sks->sortElement->which = Z_SortElement_generic;
2069 sk = sks->sortElement->u.generic = (Z_SortKey *)
2070 nmem_malloc(stream, sizeof(*sk));
2071 sk->which = Z_SortKey_sortAttributes;
2072 sk->u.sortAttributes = (Z_SortAttributes *)
2073 nmem_malloc(stream, sizeof(*sk->u.sortAttributes));
2075 sk->u.sortAttributes->id = oid;
2076 sk->u.sortAttributes->list = zapt->attributes;
2078 sks->sortRelation = (int *)
2079 nmem_malloc(stream, sizeof(*sks->sortRelation));
2080 if (sort_relation_value == 1)
2081 *sks->sortRelation = Z_SortKeySpec_ascending;
2082 else if (sort_relation_value == 2)
2083 *sks->sortRelation = Z_SortKeySpec_descending;
2085 *sks->sortRelation = Z_SortKeySpec_ascending;
2087 sks->caseSensitivity = (int *)
2088 nmem_malloc(stream, sizeof(*sks->caseSensitivity));
2089 *sks->caseSensitivity = 0;
2091 sks->which = Z_SortKeySpec_null;
2092 sks->u.null = odr_nullval ();
2093 sort_sequence->specs[i] = sks;
2094 *rset = rsnull_create (rset_nmem, kc, 0);
2099 static int parse_xpath(ZebraHandle zh, Z_AttributesPlusTerm *zapt,
2100 oid_value attributeSet,
2101 struct xpath_location_step *xpath, int max, NMEM mem)
2103 oid_value curAttributeSet = attributeSet;
2105 const char *use_string = 0;
2107 attr_init(&use, zapt, 1);
2108 attr_find_ex(&use, &curAttributeSet, &use_string);
2110 if (!use_string || *use_string != '/')
2113 return zebra_parse_xpath_str(use_string, xpath, max, mem);
2118 static RSET xpath_trunc(ZebraHandle zh, NMEM stream,
2119 int reg_type, const char *term, int use,
2120 oid_value curAttributeSet, NMEM rset_nmem,
2121 struct rset_key_control *kc)
2124 struct grep_info grep_info;
2125 char term_dict[2048];
2128 int ord = zebraExplain_lookup_attr_su(zh->reg->zei, reg_type,
2129 curAttributeSet, use);
2130 int ord_len, i, r, max_pos;
2131 int term_type = Z_Term_characterString;
2132 const char *flags = "void";
2134 if (grep_info_prepare(zh, 0 /* zapt */, &grep_info, '0') == ZEBRA_FAIL)
2135 return rsnull_create(rset_nmem, kc, 0);
2138 return rsnull_create(rset_nmem, kc, 0);
2140 term_dict[prefix_len++] = '|';
2142 term_dict[prefix_len++] = '(';
2144 ord_len = key_SU_encode (ord, ord_buf);
2145 for (i = 0; i<ord_len; i++)
2147 term_dict[prefix_len++] = 1;
2148 term_dict[prefix_len++] = ord_buf[i];
2150 term_dict[prefix_len++] = ')';
2151 strcpy(term_dict+prefix_len, term);
2153 grep_info.isam_p_indx = 0;
2154 r = dict_lookup_grep(zh->reg->dict, term_dict, 0,
2155 &grep_info, &max_pos, 0, grep_handle);
2156 yaz_log(YLOG_DEBUG, "%s %d positions", term,
2157 grep_info.isam_p_indx);
2158 rset = rset_trunc(zh, grep_info.isam_p_buf,
2159 grep_info.isam_p_indx, term, strlen(term),
2160 flags, 1, term_type,rset_nmem,
2161 kc, kc->scope, 0, reg_type, 0 /* hits_limit */,
2162 0 /* term_ref_id_str */);
2163 grep_info_delete(&grep_info);
2168 ZEBRA_RES rpn_search_xpath(ZebraHandle zh,
2169 oid_value attributeSet,
2170 int num_bases, char **basenames,
2171 NMEM stream, const char *rank_type, RSET rset,
2172 int xpath_len, struct xpath_location_step *xpath,
2175 struct rset_key_control *kc)
2177 oid_value curAttributeSet = attributeSet;
2187 yaz_log(YLOG_DEBUG, "xpath len=%d", xpath_len);
2188 for (i = 0; i<xpath_len; i++)
2190 yaz_log(log_level_rpn, "XPATH %d %s", i, xpath[i].part);
2194 curAttributeSet = VAL_IDXPATH;
2204 a[@attr = value]/b[@other = othervalue]
2206 /e/@a val range(e/,range(@a,freetext(w,1015,val),@a),e/)
2207 /a/b val range(b/a/,freetext(w,1016,val),b/a/)
2208 /a/b/@c val range(b/a/,range(@c,freetext(w,1016,val),@c),b/a/)
2209 /a/b[@c = y] val range(b/a/,freetext(w,1016,val),b/a/,@c = y)
2210 /a[@c = y]/b val range(a/,range(b/a/,freetext(w,1016,val),b/a/),a/,@c = y)
2211 /a[@c = x]/b[@c = y] range(a/,range(b/a/,freetext(w,1016,val),b/a/,@c = y),a/,@c = x)
2215 dict_grep_cmap (zh->reg->dict, 0, 0);
2217 for (base_no = 0; base_no < num_bases; base_no++)
2219 int level = xpath_len;
2222 if (zebraExplain_curDatabase (zh->reg->zei, basenames[base_no]))
2224 zebra_setError(zh, YAZ_BIB1_DATABASE_UNAVAILABLE,
2225 basenames[base_no]);
2229 while (--level >= 0)
2231 char xpath_rev[128];
2233 RSET rset_start_tag = 0, rset_end_tag = 0, rset_attr = 0;
2237 for (i = level; i >= 1; --i)
2239 const char *cp = xpath[i].part;
2245 memcpy (xpath_rev + len, "[^/]*", 5);
2248 else if (*cp == ' ')
2251 xpath_rev[len++] = 1;
2252 xpath_rev[len++] = ' ';
2256 xpath_rev[len++] = *cp;
2257 xpath_rev[len++] = '/';
2259 else if (i == 1) /* // case */
2261 xpath_rev[len++] = '.';
2262 xpath_rev[len++] = '*';
2267 if (xpath[level].predicate &&
2268 xpath[level].predicate->which == XPATH_PREDICATE_RELATION &&
2269 xpath[level].predicate->u.relation.name[0])
2271 WRBUF wbuf = wrbuf_alloc();
2272 wrbuf_puts(wbuf, xpath[level].predicate->u.relation.name+1);
2273 if (xpath[level].predicate->u.relation.value)
2275 const char *cp = xpath[level].predicate->u.relation.value;
2276 wrbuf_putc(wbuf, '=');
2280 if (strchr(REGEX_CHARS, *cp))
2281 wrbuf_putc(wbuf, '\\');
2282 wrbuf_putc(wbuf, *cp);
2286 wrbuf_puts(wbuf, "");
2287 rset_attr = xpath_trunc(
2288 zh, stream, '0', wrbuf_buf(wbuf), 3,
2289 curAttributeSet, rset_nmem, kc);
2290 wrbuf_free(wbuf, 1);
2297 yaz_log(log_level_rpn, "xpath_rev (%d) = %s", level, xpath_rev);
2298 if (strlen(xpath_rev))
2300 rset_start_tag = xpath_trunc(zh, stream, '0',
2301 xpath_rev, 1, curAttributeSet, rset_nmem, kc);
2303 rset_end_tag = xpath_trunc(zh, stream, '0',
2304 xpath_rev, 2, curAttributeSet, rset_nmem, kc);
2306 rset = rsbetween_create(rset_nmem, kc, kc->scope,
2307 rset_start_tag, rset,
2308 rset_end_tag, rset_attr);
2317 static ZEBRA_RES rpn_search_APT(ZebraHandle zh, Z_AttributesPlusTerm *zapt,
2318 oid_value attributeSet, NMEM stream,
2319 Z_SortKeySpecList *sort_sequence,
2320 int num_bases, char **basenames,
2323 struct rset_key_control *kc)
2325 ZEBRA_RES res = ZEBRA_OK;
2327 char *search_type = NULL;
2328 char rank_type[128];
2331 char termz[IT_MAX_WORD+1];
2334 struct xpath_location_step xpath[10];
2338 log_level_rpn = yaz_log_module_level("rpn");
2341 zebra_maps_attr(zh->reg->zebra_maps, zapt, ®_id, &search_type,
2342 rank_type, &complete_flag, &sort_flag);
2344 yaz_log(YLOG_DEBUG, "reg_id=%c", reg_id);
2345 yaz_log(YLOG_DEBUG, "complete_flag=%d", complete_flag);
2346 yaz_log(YLOG_DEBUG, "search_type=%s", search_type);
2347 yaz_log(YLOG_DEBUG, "rank_type=%s", rank_type);
2349 if (zapt_term_to_utf8(zh, zapt, termz) == ZEBRA_FAIL)
2353 return rpn_sort_spec(zh, zapt, attributeSet, stream, sort_sequence,
2354 rank_type, rset_nmem, rset, kc);
2355 /* consider if an X-Path query is used */
2356 xpath_len = parse_xpath(zh, zapt, attributeSet, xpath, 10, stream);
2359 xpath_use = 1016; /* searching for element by default */
2360 if (xpath[xpath_len-1].part[0] == '@')
2361 xpath_use = 1015; /* last step an attribute .. */
2364 /* search using one of the various search type strategies
2365 termz is our UTF-8 search term
2366 attributeSet is top-level default attribute set
2367 stream is ODR for search
2368 reg_id is the register type
2369 complete_flag is 1 for complete subfield, 0 for incomplete
2370 xpath_use is use-attribute to be used for X-Path search, 0 for none
2372 if (!strcmp(search_type, "phrase"))
2374 res = rpn_search_APT_phrase(zh, zapt, termz, attributeSet, stream,
2375 reg_id, complete_flag, rank_type,
2377 num_bases, basenames, rset_nmem,
2380 else if (!strcmp(search_type, "and-list"))
2382 res = rpn_search_APT_and_list(zh, zapt, termz, attributeSet, stream,
2383 reg_id, complete_flag, rank_type,
2385 num_bases, basenames, rset_nmem,
2388 else if (!strcmp(search_type, "or-list"))
2390 res = rpn_search_APT_or_list(zh, zapt, termz, attributeSet, stream,
2391 reg_id, complete_flag, rank_type,
2393 num_bases, basenames, rset_nmem,
2396 else if (!strcmp(search_type, "local"))
2398 res = rpn_search_APT_local(zh, zapt, termz, attributeSet, stream,
2399 rank_type, rset_nmem, rset, kc);
2401 else if (!strcmp(search_type, "numeric"))
2403 res = rpn_search_APT_numeric(zh, zapt, termz, attributeSet, stream,
2404 reg_id, complete_flag, rank_type,
2406 num_bases, basenames, rset_nmem,
2411 zebra_setError(zh, YAZ_BIB1_UNSUPP_STRUCTURE_ATTRIBUTE, 0);
2414 if (res != ZEBRA_OK)
2418 return rpn_search_xpath(zh, attributeSet, num_bases, basenames,
2419 stream, rank_type, *rset,
2420 xpath_len, xpath, rset_nmem, rset, kc);
2423 static ZEBRA_RES rpn_search_structure(ZebraHandle zh, Z_RPNStructure *zs,
2424 oid_value attributeSet,
2425 NMEM stream, NMEM rset_nmem,
2426 Z_SortKeySpecList *sort_sequence,
2427 int num_bases, char **basenames,
2428 RSET **result_sets, int *num_result_sets,
2429 Z_Operator *parent_op,
2430 struct rset_key_control *kc);
2432 ZEBRA_RES rpn_search_top(ZebraHandle zh, Z_RPNStructure *zs,
2433 oid_value attributeSet,
2434 NMEM stream, NMEM rset_nmem,
2435 Z_SortKeySpecList *sort_sequence,
2436 int num_bases, char **basenames,
2439 RSET *result_sets = 0;
2440 int num_result_sets = 0;
2442 struct rset_key_control *kc = zebra_key_control_create(zh);
2444 res = rpn_search_structure(zh, zs, attributeSet,
2447 num_bases, basenames,
2448 &result_sets, &num_result_sets,
2449 0 /* no parent op */,
2451 if (res != ZEBRA_OK)
2454 for (i = 0; i<num_result_sets; i++)
2455 rset_delete(result_sets[i]);
2460 assert(num_result_sets == 1);
2461 assert(result_sets);
2462 assert(*result_sets);
2463 *result_set = *result_sets;
2469 ZEBRA_RES rpn_search_structure(ZebraHandle zh, Z_RPNStructure *zs,
2470 oid_value attributeSet,
2471 NMEM stream, NMEM rset_nmem,
2472 Z_SortKeySpecList *sort_sequence,
2473 int num_bases, char **basenames,
2474 RSET **result_sets, int *num_result_sets,
2475 Z_Operator *parent_op,
2476 struct rset_key_control *kc)
2478 *num_result_sets = 0;
2479 if (zs->which == Z_RPNStructure_complex)
2482 Z_Operator *zop = zs->u.complex->roperator;
2483 RSET *result_sets_l = 0;
2484 int num_result_sets_l = 0;
2485 RSET *result_sets_r = 0;
2486 int num_result_sets_r = 0;
2488 res = rpn_search_structure(zh, zs->u.complex->s1,
2489 attributeSet, stream, rset_nmem,
2491 num_bases, basenames,
2492 &result_sets_l, &num_result_sets_l,
2494 if (res != ZEBRA_OK)
2497 for (i = 0; i<num_result_sets_l; i++)
2498 rset_delete(result_sets_l[i]);
2501 res = rpn_search_structure(zh, zs->u.complex->s2,
2502 attributeSet, stream, rset_nmem,
2504 num_bases, basenames,
2505 &result_sets_r, &num_result_sets_r,
2507 if (res != ZEBRA_OK)
2510 for (i = 0; i<num_result_sets_l; i++)
2511 rset_delete(result_sets_l[i]);
2512 for (i = 0; i<num_result_sets_r; i++)
2513 rset_delete(result_sets_r[i]);
2517 /* make a new list of result for all children */
2518 *num_result_sets = num_result_sets_l + num_result_sets_r;
2519 *result_sets = nmem_malloc(stream, *num_result_sets *
2520 sizeof(**result_sets));
2521 memcpy(*result_sets, result_sets_l,
2522 num_result_sets_l * sizeof(**result_sets));
2523 memcpy(*result_sets + num_result_sets_l, result_sets_r,
2524 num_result_sets_r * sizeof(**result_sets));
2526 if (!parent_op || parent_op->which != zop->which
2527 || (zop->which != Z_Operator_and &&
2528 zop->which != Z_Operator_or))
2530 /* parent node different from this one (or non-present) */
2531 /* we must combine result sets now */
2535 case Z_Operator_and:
2536 rset = rsmulti_and_create(rset_nmem, kc,
2538 *num_result_sets, *result_sets);
2541 rset = rsmulti_or_create(rset_nmem, kc,
2542 kc->scope, 0, /* termid */
2543 *num_result_sets, *result_sets);
2545 case Z_Operator_and_not:
2546 rset = rsbool_create_not(rset_nmem, kc,
2551 case Z_Operator_prox:
2552 if (zop->u.prox->which != Z_ProximityOperator_known)
2555 YAZ_BIB1_UNSUPP_PROX_UNIT_CODE,
2559 if (*zop->u.prox->u.known != Z_ProxUnit_word)
2561 zebra_setError_zint(zh,
2562 YAZ_BIB1_UNSUPP_PROX_UNIT_CODE,
2563 *zop->u.prox->u.known);
2568 rset = rsprox_create(rset_nmem, kc,
2570 *num_result_sets, *result_sets,
2571 *zop->u.prox->ordered,
2572 (!zop->u.prox->exclusion ?
2573 0 : *zop->u.prox->exclusion),
2574 *zop->u.prox->relationType,
2575 *zop->u.prox->distance );
2579 zebra_setError(zh, YAZ_BIB1_OPERATOR_UNSUPP, 0);
2582 *num_result_sets = 1;
2583 *result_sets = nmem_malloc(stream, *num_result_sets *
2584 sizeof(**result_sets));
2585 (*result_sets)[0] = rset;
2588 else if (zs->which == Z_RPNStructure_simple)
2593 if (zs->u.simple->which == Z_Operand_APT)
2595 yaz_log(YLOG_DEBUG, "rpn_search_APT");
2596 res = rpn_search_APT(zh, zs->u.simple->u.attributesPlusTerm,
2597 attributeSet, stream, sort_sequence,
2598 num_bases, basenames, rset_nmem, &rset,
2600 if (res != ZEBRA_OK)
2603 else if (zs->u.simple->which == Z_Operand_resultSetId)
2605 yaz_log(YLOG_DEBUG, "rpn_search_ref");
2606 rset = resultSetRef(zh, zs->u.simple->u.resultSetId);
2610 YAZ_BIB1_SPECIFIED_RESULT_SET_DOES_NOT_EXIST,
2611 zs->u.simple->u.resultSetId);
2618 zebra_setError(zh, YAZ_BIB1_UNSUPP_SEARCH, 0);
2621 *num_result_sets = 1;
2622 *result_sets = nmem_malloc(stream, *num_result_sets *
2623 sizeof(**result_sets));
2624 (*result_sets)[0] = rset;
2628 zebra_setError(zh, YAZ_BIB1_UNSUPP_SEARCH, 0);
2634 struct scan_info_entry {
2640 struct scan_info_entry *list;
2646 static int scan_handle (char *name, const char *info, int pos, void *client)
2648 int len_prefix, idx;
2649 struct scan_info *scan_info = (struct scan_info *) client;
2651 len_prefix = strlen(scan_info->prefix);
2652 if (memcmp (name, scan_info->prefix, len_prefix))
2655 idx = scan_info->after - pos + scan_info->before;
2661 scan_info->list[idx].term = (char *)
2662 odr_malloc(scan_info->odr, strlen(name + len_prefix)+1);
2663 strcpy(scan_info->list[idx].term, name + len_prefix);
2664 assert (*info == sizeof(ISAM_P));
2665 memcpy (&scan_info->list[idx].isam_p, info+1, sizeof(ISAM_P));
2669 void zebra_term_untrans_iconv(ZebraHandle zh, NMEM stream, int reg_type,
2670 char **dst, const char *src)
2672 char term_src[IT_MAX_WORD];
2673 char term_dst[IT_MAX_WORD];
2675 zebra_term_untrans (zh, reg_type, term_src, src);
2677 if (zh->iconv_from_utf8 != 0)
2680 char *inbuf = term_src;
2681 size_t inleft = strlen(term_src);
2682 char *outbuf = term_dst;
2683 size_t outleft = sizeof(term_dst)-1;
2686 ret = yaz_iconv (zh->iconv_from_utf8, &inbuf, &inleft,
2688 if (ret == (size_t)(-1))
2691 len = outbuf - term_dst;
2692 *dst = nmem_malloc(stream, len + 1);
2694 memcpy (*dst, term_dst, len);
2698 *dst = nmem_strdup(stream, term_src);
2701 static void count_set(ZebraHandle zh, RSET rset, zint *count)
2707 yaz_log(YLOG_DEBUG, "count_set");
2709 rset->hits_limit = zh->approx_limit;
2712 rfd = rset_open(rset, RSETF_READ);
2713 while (rset_read(rfd, &key,0 /* never mind terms */))
2715 if (key.mem[0] != psysno)
2717 psysno = key.mem[0];
2718 if (rfd->counted_items >= rset->hits_limit)
2723 *count = rset->hits_count;
2726 ZEBRA_RES rpn_scan(ZebraHandle zh, ODR stream, Z_AttributesPlusTerm *zapt,
2727 oid_value attributeset,
2728 int num_bases, char **basenames,
2729 int *position, int *num_entries, ZebraScanEntry **list,
2730 int *is_partial, RSET limit_set, int return_zero)
2733 int pos = *position;
2734 int num = *num_entries;
2738 char termz[IT_MAX_WORD+20];
2741 const char *use_string = 0;
2742 struct scan_info *scan_info_array;
2743 ZebraScanEntry *glist;
2744 int ords[32], ord_no = 0;
2747 int bases_ok = 0; /* no of databases with OK attribute */
2748 int errCode = 0; /* err code (if any is not OK) */
2749 char *errString = 0; /* addinfo */
2752 char *search_type = NULL;
2753 char rank_type[128];
2756 NMEM rset_nmem = NULL;
2757 struct rset_key_control *kc = 0;
2762 if (attributeset == VAL_NONE)
2763 attributeset = VAL_BIB1;
2768 int termset_value_numeric;
2769 const char *termset_value_string;
2770 attr_init(&termset, zapt, 8);
2771 termset_value_numeric =
2772 attr_find_ex(&termset, NULL, &termset_value_string);
2773 if (termset_value_numeric != -1)
2776 const char *termset_name = 0;
2778 if (termset_value_numeric != -2)
2781 sprintf(resname, "%d", termset_value_numeric);
2782 termset_name = resname;
2785 termset_name = termset_value_string;
2787 limit_set = resultSetRef (zh, termset_name);
2791 yaz_log(YLOG_DEBUG, "position = %d, num = %d set=%d",
2792 pos, num, attributeset);
2794 attr_init(&use, zapt, 1);
2795 use_value = attr_find_ex(&use, &attributeset, &use_string);
2797 if (zebra_maps_attr(zh->reg->zebra_maps, zapt, ®_id, &search_type,
2798 rank_type, &complete_flag, &sort_flag))
2801 zebra_setError(zh, YAZ_BIB1_UNSUPP_ATTRIBUTE_TYPE, 0);
2804 yaz_log(YLOG_DEBUG, "use_value = %d", use_value);
2806 if (use_value == -1)
2808 for (base_no = 0; base_no < num_bases && ord_no < 32; base_no++)
2810 data1_local_attribute *local_attr;
2814 if (zebraExplain_curDatabase (zh->reg->zei, basenames[base_no]))
2816 zebra_setError(zh, YAZ_BIB1_DATABASE_UNAVAILABLE,
2817 basenames[base_no]);
2823 (ord = zebraExplain_lookup_attr_str(zh->reg->zei, reg_id,
2826 /* we have a match for a raw string attribute */
2828 ords[ord_no++] = ord;
2829 attp.local_attributes = 0; /* no more attributes */
2835 if ((r = att_getentbyatt (zh, &attp, attributeset, use_value,
2838 yaz_log(YLOG_DEBUG, "att_getentbyatt fail. set=%d use=%d",
2839 attributeset, use_value);
2842 errCode = YAZ_BIB1_UNSUPP_USE_ATTRIBUTE;
2844 zebra_setError(zh, YAZ_BIB1_UNSUPP_USE_ATTRIBUTE,
2847 zebra_setError_zint(zh, YAZ_BIB1_UNSUPP_USE_ATTRIBUTE,
2852 zebra_setError(zh, YAZ_BIB1_UNSUPP_ATTRIBUTE_SET, 0);
2858 for (local_attr = attp.local_attributes; local_attr && ord_no < 32;
2859 local_attr = local_attr->next)
2861 ord = zebraExplain_lookup_attr_su(zh->reg->zei, reg_id,
2862 attp.attset_ordinal,
2865 ords[ord_no++] = ord;
2868 if (!bases_ok && errCode)
2870 zebra_setError(zh, errCode, errString);
2879 /* prepare dictionary scanning */
2891 yaz_log(YLOG_DEBUG, "rpn_scan pos=%d num=%d before=%d "
2892 "after=%d before+after=%d",
2893 pos, num, before, after, before+after);
2894 scan_info_array = (struct scan_info *)
2895 odr_malloc(stream, ord_no * sizeof(*scan_info_array));
2896 for (i = 0; i < ord_no; i++)
2898 int j, prefix_len = 0;
2899 int before_tmp = before, after_tmp = after;
2900 struct scan_info *scan_info = scan_info_array + i;
2901 struct rpn_char_map_info rcmi;
2903 rpn_char_map_prepare (zh->reg, reg_id, &rcmi);
2905 scan_info->before = before;
2906 scan_info->after = after;
2907 scan_info->odr = stream;
2909 scan_info->list = (struct scan_info_entry *)
2910 odr_malloc(stream, (before+after) * sizeof(*scan_info->list));
2911 for (j = 0; j<before+after; j++)
2912 scan_info->list[j].term = NULL;
2914 prefix_len += key_SU_encode (ords[i], termz + prefix_len);
2915 termz[prefix_len] = 0;
2916 strcpy(scan_info->prefix, termz);
2918 if (trans_scan_term(zh, zapt, termz+prefix_len, reg_id) == ZEBRA_FAIL)
2921 dict_scan(zh->reg->dict, termz, &before_tmp, &after_tmp,
2922 scan_info, scan_handle);
2924 glist = (ZebraScanEntry *)
2925 odr_malloc(stream, (before+after)*sizeof(*glist));
2927 rset_nmem = nmem_create();
2928 kc = zebra_key_control_create(zh);
2930 /* consider terms after main term */
2931 for (i = 0; i < ord_no; i++)
2935 for (i = 0; i<after; i++)
2938 const char *mterm = NULL;
2941 int lo = i + pos-1; /* offset in result list */
2943 /* find: j0 is the first of the minimal values */
2944 for (j = 0; j < ord_no; j++)
2946 if (ptr[j] < before+after && ptr[j] >= 0 &&
2947 (tst = scan_info_array[j].list[ptr[j]].term) &&
2948 (!mterm || strcmp (tst, mterm) < 0))
2955 break; /* no value found, stop */
2957 /* get result set for first one , but only if it's within bounds */
2960 /* get result set for first term */
2961 zebra_term_untrans_iconv(zh, stream->mem, reg_id,
2962 &glist[lo].term, mterm);
2963 rset = rset_trunc(zh, &scan_info_array[j0].list[ptr[j0]].isam_p, 1,
2964 glist[lo].term, strlen(glist[lo].term),
2965 NULL, 0, zapt->term->which, rset_nmem,
2966 kc, kc->scope, 0, reg_id, 0 /* hits_limit */,
2967 0 /* term_ref_id_str */);
2969 ptr[j0]++; /* move index for this set .. */
2970 /* get result set for remaining scan terms */
2971 for (j = j0+1; j<ord_no; j++)
2973 if (ptr[j] < before+after && ptr[j] >= 0 &&
2974 (tst = scan_info_array[j].list[ptr[j]].term) &&
2975 !strcmp (tst, mterm))
2984 zh, &scan_info_array[j].list[ptr[j]].isam_p, 1,
2986 strlen(glist[lo].term), NULL, 0,
2987 zapt->term->which,rset_nmem,
2988 kc, kc->scope, 0, reg_id, 0 /* hits_limit */,
2989 0 /* term_ref_id_str */ );
2990 rset = rsmulti_or_create(rset_nmem, kc,
2991 kc->scope, 0 /* termid */,
3000 /* merge with limit_set if given */
3005 rsets[1] = rset_dup(limit_set);
3007 rset = rsmulti_and_create(rset_nmem, kc,
3012 count_set(zh, rset, &count);
3013 glist[lo].occurrences = count;
3019 *num_entries -= (after-i);
3021 if (*num_entries < 0)
3024 nmem_destroy(rset_nmem);
3029 /* consider terms before main term */
3030 for (i = 0; i<ord_no; i++)
3033 for (i = 0; i<before; i++)
3036 const char *mterm = NULL;
3039 int lo = before-1-i; /* offset in result list */
3042 for (j = 0; j <ord_no; j++)
3044 if (ptr[j] < before && ptr[j] >= 0 &&
3045 (tst = scan_info_array[j].list[before-1-ptr[j]].term) &&
3046 (!mterm || strcmp (tst, mterm) > 0))
3055 zebra_term_untrans_iconv(zh, stream->mem, reg_id,
3056 &glist[lo].term, mterm);
3059 (zh, &scan_info_array[j0].list[before-1-ptr[j0]].isam_p, 1,
3060 glist[lo].term, strlen(glist[lo].term),
3061 NULL, 0, zapt->term->which, rset_nmem,
3062 kc, kc->scope, 0, reg_id, 0 /* hits_limit */,
3063 0 /* term_ref_id_str */);
3067 for (j = j0+1; j<ord_no; j++)
3069 if (ptr[j] < before && ptr[j] >= 0 &&
3070 (tst = scan_info_array[j].list[before-1-ptr[j]].term) &&
3071 !strcmp (tst, mterm))
3076 rsets[1] = rset_trunc(
3078 &scan_info_array[j].list[before-1-ptr[j]].isam_p, 1,
3080 strlen(glist[lo].term), NULL, 0,
3081 zapt->term->which, rset_nmem,
3082 kc, kc->scope, 0, reg_id, 0 /* hits_limit */,
3083 0 /* term_ref_id_str */);
3084 rset = rsmulti_or_create(rset_nmem, kc,
3085 kc->scope, 0 /* termid */, 2, rsets);
3094 rsets[1] = rset_dup(limit_set);
3096 rset = rsmulti_and_create(rset_nmem, kc,
3097 kc->scope, 2, rsets);
3099 count_set(zh, rset, &count);
3100 glist[lo].occurrences = count;
3104 nmem_destroy(rset_nmem);
3111 if (*num_entries <= 0)
3118 *list = glist + i; /* list is set to first 'real' entry */
3120 yaz_log(YLOG_DEBUG, "position = %d, num_entries = %d",
3121 *position, *num_entries);