1 /* $Id: zrpn.c,v 1.205 2005-08-26 10:13:31 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)
998 AttrType term_ref_id_attr;
999 AttrType hits_limit_attr;
1001 attr_init(&hits_limit_attr, zapt, 9);
1002 *hits_limit_value = attr_find(&hits_limit_attr, NULL);
1004 attr_init(&term_ref_id_attr, zapt, 10);
1005 attr_find_ex(&term_ref_id_attr, NULL, term_ref_id_str);
1007 /* no limit given ? */
1008 if (*hits_limit_value == -1)
1009 if (*term_ref_id_str)
1011 /* use global if term_ref is present */
1012 *hits_limit_value = zh->approx_limit;
1016 /* no counting if term_ref is not present */
1017 *hits_limit_value = 0;
1019 else if (*hits_limit_value == 0)
1021 /* 0 is the same as global limit */
1022 *hits_limit_value = zh->approx_limit;
1024 yaz_log(YLOG_DEBUG, "term_limits_APT ref_id=%s limit=" ZINT_FORMAT,
1025 *term_ref_id_str ? *term_ref_id_str : "none",
1030 static ZEBRA_RES term_trunc(ZebraHandle zh,
1031 Z_AttributesPlusTerm *zapt,
1032 const char **term_sub,
1033 oid_value attributeSet, NMEM stream,
1034 struct grep_info *grep_info,
1035 int reg_type, int complete_flag,
1036 int num_bases, char **basenames,
1038 const char *rank_type, int xpath_use,
1041 struct rset_key_control *kc)
1044 struct ord_list *ol;
1045 zint hits_limit_value;
1046 const char *term_ref_id_str = 0;
1049 term_limits_APT(zh, zapt, &hits_limit_value, &term_ref_id_str);
1050 grep_info->isam_p_indx = 0;
1051 res = string_term(zh, zapt, term_sub, attributeSet, stream, grep_info,
1052 reg_type, complete_flag, num_bases, basenames,
1053 term_dst, xpath_use, &ol);
1054 if (res != ZEBRA_OK)
1056 if (!*term_sub) /* no more terms ? */
1058 yaz_log(log_level_rpn, "term: %s", term_dst);
1059 *rset = rset_trunc(zh, grep_info->isam_p_buf,
1060 grep_info->isam_p_indx, term_dst,
1061 strlen(term_dst), rank_type, 1 /* preserve pos */,
1062 zapt->term->which, rset_nmem,
1063 kc, kc->scope, ol, reg_type, hits_limit_value,
1070 static ZEBRA_RES string_term(ZebraHandle zh, Z_AttributesPlusTerm *zapt,
1071 const char **term_sub,
1072 oid_value attributeSet, NMEM stream,
1073 struct grep_info *grep_info,
1074 int reg_type, int complete_flag,
1075 int num_bases, char **basenames,
1076 char *term_dst, int xpath_use,
1077 struct ord_list **ol)
1079 char term_dict[2*IT_MAX_WORD+4000];
1081 AttrType truncation;
1082 int truncation_value;
1085 const char *use_string = 0;
1086 oid_value curAttributeSet = attributeSet;
1088 struct rpn_char_map_info rcmi;
1089 int space_split = complete_flag ? 0 : 1;
1091 int bases_ok = 0; /* no of databases with OK attribute */
1093 *ol = ord_list_create(stream);
1095 rpn_char_map_prepare (zh->reg, reg_type, &rcmi);
1096 attr_init(&use, zapt, 1);
1097 use_value = attr_find_ex(&use, &curAttributeSet, &use_string);
1098 yaz_log(log_level_rpn, "string_term, use value %d", use_value);
1099 attr_init(&truncation, zapt, 5);
1100 truncation_value = attr_find(&truncation, NULL);
1101 yaz_log(log_level_rpn, "truncation value %d", truncation_value);
1103 if (use_value == -1) /* no attribute - assumy "any" */
1105 for (base_no = 0; base_no < num_bases; base_no++)
1109 int regex_range = 0;
1112 data1_local_attribute id_xpath_attr;
1113 data1_local_attribute *local_attr;
1114 int max_pos, prefix_len = 0;
1119 if (zebraExplain_curDatabase (zh->reg->zei, basenames[base_no]))
1121 zebra_setError(zh, YAZ_BIB1_DATABASE_UNAVAILABLE,
1122 basenames[base_no]);
1125 if (xpath_use > 0 && use_value == -2)
1127 /* xpath mode and we have a string attribute */
1128 attp.local_attributes = &id_xpath_attr;
1129 attp.attset_ordinal = VAL_IDXPATH;
1130 id_xpath_attr.next = 0;
1132 use_value = xpath_use; /* xpath_use as use-attribute now */
1133 id_xpath_attr.local = use_value;
1135 else if (curAttributeSet == VAL_IDXPATH && use_value >= 0)
1137 /* X-Path attribute, use numeric value directly */
1138 attp.local_attributes = &id_xpath_attr;
1139 attp.attset_ordinal = VAL_IDXPATH;
1140 id_xpath_attr.next = 0;
1141 id_xpath_attr.local = use_value;
1143 else if (use_string &&
1144 (ord = zebraExplain_lookup_attr_str(zh->reg->zei,
1148 /* we have a match for a raw string attribute */
1153 term_dict[prefix_len++] = '|';
1155 term_dict[prefix_len++] = '(';
1157 ord_len = key_SU_encode (ord, ord_buf);
1158 for (i = 0; i<ord_len; i++)
1160 term_dict[prefix_len++] = 1;
1161 term_dict[prefix_len++] = ord_buf[i];
1163 attp.local_attributes = 0; /* no more attributes */
1164 *ol = ord_list_append(stream, *ol, ord);
1168 /* lookup in the .att files . Allow string as well */
1169 if ((r = att_getentbyatt (zh, &attp, curAttributeSet, use_value,
1172 yaz_log(YLOG_DEBUG, "att_getentbyatt fail. set=%d use=%d r=%d",
1173 curAttributeSet, use_value, r);
1176 /* set was found, but value wasn't defined */
1179 YAZ_BIB1_UNSUPP_USE_ATTRIBUTE,
1182 zebra_setError_zint(zh, YAZ_BIB1_UNSUPP_USE_ATTRIBUTE,
1188 struct oident oident;
1190 oident.proto = PROTO_Z3950;
1191 oident.oclass = CLASS_ATTSET;
1192 oident.value = curAttributeSet;
1193 oid_ent_to_oid (&oident, oid);
1196 YAZ_BIB1_UNSUPP_ATTRIBUTE_SET,
1203 for (local_attr = attp.local_attributes; local_attr;
1204 local_attr = local_attr->next)
1209 ord = zebraExplain_lookup_attr_su(zh->reg->zei,
1211 attp.attset_ordinal,
1215 *ol = ord_list_append(stream, *ol, ord);
1217 term_dict[prefix_len++] = '|';
1219 term_dict[prefix_len++] = '(';
1221 ord_len = key_SU_encode (ord, ord_buf);
1222 for (i = 0; i<ord_len; i++)
1224 term_dict[prefix_len++] = 1;
1225 term_dict[prefix_len++] = ord_buf[i];
1232 term_dict[prefix_len++] = ')';
1234 term_dict[prefix_len++] = 1;
1235 term_dict[prefix_len++] = reg_type;
1236 yaz_log(log_level_rpn, "reg_type = %d", term_dict[prefix_len-1]);
1238 term_dict[prefix_len] = '\0';
1240 switch (truncation_value)
1242 case -1: /* not specified */
1243 case 100: /* do not truncate */
1244 if (!string_relation (zh, zapt, &termp, term_dict,
1246 reg_type, space_split, term_dst,
1251 zebra_setError(zh, relation_error, 0);
1258 case 1: /* right truncation */
1259 term_dict[j++] = '(';
1260 if (!term_100(zh->reg->zebra_maps, reg_type,
1261 &termp, term_dict + j, space_split, term_dst))
1266 strcat(term_dict, ".*)");
1268 case 2: /* keft truncation */
1269 term_dict[j++] = '('; term_dict[j++] = '.'; term_dict[j++] = '*';
1270 if (!term_100(zh->reg->zebra_maps, reg_type,
1271 &termp, term_dict + j, space_split, term_dst))
1276 strcat(term_dict, ")");
1278 case 3: /* left&right truncation */
1279 term_dict[j++] = '('; term_dict[j++] = '.'; term_dict[j++] = '*';
1280 if (!term_100(zh->reg->zebra_maps, reg_type,
1281 &termp, term_dict + j, space_split, term_dst))
1286 strcat(term_dict, ".*)");
1288 case 101: /* process # in term */
1289 term_dict[j++] = '(';
1290 if (!term_101(zh->reg->zebra_maps, reg_type,
1291 &termp, term_dict + j, space_split, term_dst))
1296 strcat(term_dict, ")");
1298 case 102: /* Regexp-1 */
1299 term_dict[j++] = '(';
1300 if (!term_102(zh->reg->zebra_maps, reg_type,
1301 &termp, term_dict + j, space_split, term_dst))
1306 strcat(term_dict, ")");
1308 case 103: /* Regexp-2 */
1310 term_dict[j++] = '(';
1312 if (!term_103(zh->reg->zebra_maps, reg_type,
1313 &termp, term_dict + j, ®ex_range,
1314 space_split, term_dst))
1319 strcat(term_dict, ")");
1321 case 104: /* process # and ! in term */
1322 term_dict[j++] = '(';
1323 if (!term_104(zh->reg->zebra_maps, reg_type,
1324 &termp, term_dict + j, space_split, term_dst))
1329 strcat(term_dict, ")");
1331 case 105: /* process * and ! in term */
1332 term_dict[j++] = '(';
1333 if (!term_105(zh->reg->zebra_maps, reg_type,
1334 &termp, term_dict + j, space_split, term_dst, 1))
1339 strcat(term_dict, ")");
1341 case 106: /* process * and ! in term */
1342 term_dict[j++] = '(';
1343 if (!term_105(zh->reg->zebra_maps, reg_type,
1344 &termp, term_dict + j, space_split, term_dst, 0))
1349 strcat(term_dict, ")");
1352 zebra_setError_zint(zh,
1353 YAZ_BIB1_UNSUPP_TRUNCATION_ATTRIBUTE,
1360 const char *input = term_dict + prefix_len;
1361 esc_str(buf, sizeof(buf), input, strlen(input));
1365 yaz_log(log_level_rpn, "dict_lookup_grep: %s", term_dict+prefix_len);
1366 r = dict_lookup_grep(zh->reg->dict, term_dict, regex_range,
1367 grep_info, &max_pos, init_pos,
1370 yaz_log(YLOG_WARN, "dict_lookup_grep fail %d", r);
1376 yaz_log(YLOG_DEBUG, "%d positions", grep_info->isam_p_indx);
1381 /* convert APT search term to UTF8 */
1382 static ZEBRA_RES zapt_term_to_utf8(ZebraHandle zh, Z_AttributesPlusTerm *zapt,
1386 Z_Term *term = zapt->term;
1388 switch (term->which)
1390 case Z_Term_general:
1391 if (zh->iconv_to_utf8 != 0)
1393 char *inbuf = (char *) term->u.general->buf;
1394 size_t inleft = term->u.general->len;
1395 char *outbuf = termz;
1396 size_t outleft = IT_MAX_WORD-1;
1399 ret = yaz_iconv(zh->iconv_to_utf8, &inbuf, &inleft,
1401 if (ret == (size_t)(-1))
1403 ret = yaz_iconv(zh->iconv_to_utf8, 0, 0, 0, 0);
1406 YAZ_BIB1_QUERY_TERM_INCLUDES_CHARS_THAT_DO_NOT_TRANSLATE_INTO_,
1414 sizez = term->u.general->len;
1415 if (sizez > IT_MAX_WORD-1)
1416 sizez = IT_MAX_WORD-1;
1417 memcpy (termz, term->u.general->buf, sizez);
1418 termz[sizez] = '\0';
1421 case Z_Term_characterString:
1422 sizez = strlen(term->u.characterString);
1423 if (sizez > IT_MAX_WORD-1)
1424 sizez = IT_MAX_WORD-1;
1425 memcpy (termz, term->u.characterString, sizez);
1426 termz[sizez] = '\0';
1429 zebra_setError(zh, YAZ_BIB1_UNSUPP_CODED_VALUE_FOR_TERM, 0);
1435 /* convert APT SCAN term to internal cmap */
1436 static ZEBRA_RES trans_scan_term(ZebraHandle zh, Z_AttributesPlusTerm *zapt,
1437 char *termz, int reg_type)
1439 char termz0[IT_MAX_WORD];
1441 if (zapt_term_to_utf8(zh, zapt, termz0) == ZEBRA_FAIL)
1442 return ZEBRA_FAIL; /* error */
1446 const char *cp = (const char *) termz0;
1447 const char *cp_end = cp + strlen(cp);
1450 const char *space_map = NULL;
1453 while ((len = (cp_end - cp)) > 0)
1455 map = zebra_maps_input(zh->reg->zebra_maps, reg_type, &cp, len, 0);
1456 if (**map == *CHR_SPACE)
1461 for (src = space_map; *src; src++)
1464 for (src = *map; *src; src++)
1473 static void grep_info_delete(struct grep_info *grep_info)
1476 xfree(grep_info->term_no);
1478 xfree(grep_info->isam_p_buf);
1481 static ZEBRA_RES grep_info_prepare(ZebraHandle zh,
1482 Z_AttributesPlusTerm *zapt,
1483 struct grep_info *grep_info,
1487 int termset_value_numeric;
1488 const char *termset_value_string;
1491 grep_info->term_no = 0;
1493 grep_info->isam_p_size = 0;
1494 grep_info->isam_p_buf = NULL;
1496 grep_info->reg_type = reg_type;
1497 grep_info->termset = 0;
1501 attr_init(&termset, zapt, 8);
1502 termset_value_numeric =
1503 attr_find_ex(&termset, NULL, &termset_value_string);
1504 if (termset_value_numeric != -1)
1507 const char *termset_name = 0;
1508 if (termset_value_numeric != -2)
1511 sprintf(resname, "%d", termset_value_numeric);
1512 termset_name = resname;
1515 termset_name = termset_value_string;
1516 yaz_log(log_level_rpn, "creating termset set %s", termset_name);
1517 grep_info->termset = resultSetAdd(zh, termset_name, 1);
1518 if (!grep_info->termset)
1520 zebra_setError(zh, YAZ_BIB1_ILLEGAL_RESULT_SET_NAME, termset_name);
1528 \brief Create result set(s) for list of terms
1529 \param zh Zebra Handle
1530 \param termz term as used in query but converted to UTF-8
1531 \param attributeSet default attribute set
1532 \param stream memory for result
1533 \param reg_type register type ('w', 'p',..)
1534 \param complete_flag whether it's phrases or not
1535 \param rank_type term flags for ranking
1536 \param xpath_use use attribute for X-Path (-1 for no X-path)
1537 \param num_bases number of databases
1538 \param basenames array of databases
1539 \param rset_mem memory for result sets
1540 \param result_sets output result set for each term in list (output)
1541 \param number number of output result sets
1542 \param kc rset key control to be used for created result sets
1544 static ZEBRA_RES term_list_trunc(ZebraHandle zh,
1545 Z_AttributesPlusTerm *zapt,
1547 oid_value attributeSet,
1549 int reg_type, int complete_flag,
1550 const char *rank_type, int xpath_use,
1551 int num_bases, char **basenames,
1553 RSET **result_sets, int *num_result_sets,
1554 struct rset_key_control *kc)
1556 char term_dst[IT_MAX_WORD+1];
1557 struct grep_info grep_info;
1558 const char *termp = termz;
1561 *num_result_sets = 0;
1563 if (grep_info_prepare(zh, zapt, &grep_info, reg_type) == ZEBRA_FAIL)
1569 if (alloc_sets == *num_result_sets)
1572 RSET *rnew = (RSET *) nmem_malloc(stream, (alloc_sets+add) *
1575 memcpy(rnew, *result_sets, alloc_sets * sizeof(*rnew));
1576 alloc_sets = alloc_sets + add;
1577 *result_sets = rnew;
1579 res = term_trunc(zh, zapt, &termp, attributeSet,
1581 reg_type, complete_flag,
1582 num_bases, basenames,
1583 term_dst, rank_type,
1584 xpath_use, rset_nmem,
1585 &(*result_sets)[*num_result_sets],
1587 if (res != ZEBRA_OK)
1590 for (i = 0; i < *num_result_sets; i++)
1591 rset_delete((*result_sets)[i]);
1592 grep_info_delete (&grep_info);
1595 if ((*result_sets)[*num_result_sets] == 0)
1597 (*num_result_sets)++;
1599 grep_info_delete(&grep_info);
1603 static ZEBRA_RES rpn_search_APT_phrase(ZebraHandle zh,
1604 Z_AttributesPlusTerm *zapt,
1605 const char *termz_org,
1606 oid_value attributeSet,
1608 int reg_type, int complete_flag,
1609 const char *rank_type, int xpath_use,
1610 int num_bases, char **basenames,
1613 struct rset_key_control *kc)
1615 RSET *result_sets = 0;
1616 int num_result_sets = 0;
1618 term_list_trunc(zh, zapt, termz_org, attributeSet,
1619 stream, reg_type, complete_flag,
1620 rank_type, xpath_use,
1621 num_bases, basenames,
1623 &result_sets, &num_result_sets, kc);
1624 if (res != ZEBRA_OK)
1626 if (num_result_sets == 0)
1627 *rset = rsnull_create (rset_nmem, kc, 0);
1628 else if (num_result_sets == 1)
1629 *rset = result_sets[0];
1631 *rset = rsprox_create(rset_nmem, kc, kc->scope,
1632 num_result_sets, result_sets,
1633 1 /* ordered */, 0 /* exclusion */,
1634 3 /* relation */, 1 /* distance */);
1640 static ZEBRA_RES rpn_search_APT_or_list(ZebraHandle zh,
1641 Z_AttributesPlusTerm *zapt,
1642 const char *termz_org,
1643 oid_value attributeSet,
1645 int reg_type, int complete_flag,
1646 const char *rank_type,
1648 int num_bases, char **basenames,
1651 struct rset_key_control *kc)
1653 RSET *result_sets = 0;
1654 int num_result_sets = 0;
1656 term_list_trunc(zh, zapt, termz_org, attributeSet,
1657 stream, reg_type, complete_flag,
1658 rank_type, xpath_use,
1659 num_bases, basenames,
1661 &result_sets, &num_result_sets, kc);
1662 if (res != ZEBRA_OK)
1664 if (num_result_sets == 0)
1665 *rset = rsnull_create (rset_nmem, kc, 0);
1666 else if (num_result_sets == 1)
1667 *rset = result_sets[0];
1669 *rset = rsmulti_or_create(rset_nmem, kc, kc->scope, 0 /* termid */,
1670 num_result_sets, result_sets);
1676 static ZEBRA_RES rpn_search_APT_and_list(ZebraHandle zh,
1677 Z_AttributesPlusTerm *zapt,
1678 const char *termz_org,
1679 oid_value attributeSet,
1681 int reg_type, int complete_flag,
1682 const char *rank_type,
1684 int num_bases, char **basenames,
1687 struct rset_key_control *kc)
1689 RSET *result_sets = 0;
1690 int num_result_sets = 0;
1692 term_list_trunc(zh, zapt, termz_org, attributeSet,
1693 stream, reg_type, complete_flag,
1694 rank_type, xpath_use,
1695 num_bases, basenames,
1697 &result_sets, &num_result_sets,
1699 if (res != ZEBRA_OK)
1701 if (num_result_sets == 0)
1702 *rset = rsnull_create (rset_nmem, kc, 0);
1703 else if (num_result_sets == 1)
1704 *rset = result_sets[0];
1706 *rset = rsmulti_and_create(rset_nmem, kc, kc->scope,
1707 num_result_sets, result_sets);
1713 static int numeric_relation(ZebraHandle zh, Z_AttributesPlusTerm *zapt,
1714 const char **term_sub,
1716 oid_value attributeSet,
1717 struct grep_info *grep_info,
1727 char *term_tmp = term_dict + strlen(term_dict);
1730 attr_init(&relation, zapt, 2);
1731 relation_value = attr_find(&relation, NULL);
1733 yaz_log(log_level_rpn, "numeric relation value=%d", relation_value);
1735 if (!term_100(zh->reg->zebra_maps, reg_type, term_sub, term_tmp, 1,
1738 term_value = atoi (term_tmp);
1739 switch (relation_value)
1742 yaz_log(log_level_rpn, "Relation <");
1743 gen_regular_rel(term_tmp, term_value-1, 1);
1746 yaz_log(log_level_rpn, "Relation <=");
1747 gen_regular_rel(term_tmp, term_value, 1);
1750 yaz_log(log_level_rpn, "Relation >=");
1751 gen_regular_rel(term_tmp, term_value, 0);
1754 yaz_log(log_level_rpn, "Relation >");
1755 gen_regular_rel(term_tmp, term_value+1, 0);
1759 yaz_log(log_level_rpn, "Relation =");
1760 sprintf(term_tmp, "(0*%d)", term_value);
1763 *error_code = YAZ_BIB1_UNSUPP_RELATION_ATTRIBUTE;
1766 yaz_log(log_level_rpn, "dict_lookup_grep: %s", term_tmp);
1767 r = dict_lookup_grep(zh->reg->dict, term_dict, 0, grep_info, max_pos,
1770 yaz_log(YLOG_WARN, "dict_lookup_grep fail, rel = gt: %d", r);
1771 yaz_log(log_level_rpn, "%d positions", grep_info->isam_p_indx);
1775 static ZEBRA_RES numeric_term(ZebraHandle zh, Z_AttributesPlusTerm *zapt,
1776 const char **term_sub,
1777 oid_value attributeSet,
1778 struct grep_info *grep_info,
1779 int reg_type, int complete_flag,
1780 int num_bases, char **basenames,
1781 char *term_dst, int xpath_use, NMEM stream)
1783 char term_dict[2*IT_MAX_WORD+2];
1787 const char *use_string = 0;
1788 oid_value curAttributeSet = attributeSet;
1790 struct rpn_char_map_info rcmi;
1792 int bases_ok = 0; /* no of databases with OK attribute */
1794 rpn_char_map_prepare (zh->reg, reg_type, &rcmi);
1795 attr_init(&use, zapt, 1);
1796 use_value = attr_find_ex(&use, &curAttributeSet, &use_string);
1798 if (use_value == -1)
1801 for (base_no = 0; base_no < num_bases; base_no++)
1804 data1_local_attribute id_xpath_attr;
1805 data1_local_attribute *local_attr;
1806 int max_pos, prefix_len = 0;
1807 int relation_error = 0;
1810 if (use_value == -2) /* string attribute (assume IDXPATH/any) */
1812 use_value = xpath_use;
1813 attp.local_attributes = &id_xpath_attr;
1814 attp.attset_ordinal = VAL_IDXPATH;
1815 id_xpath_attr.next = 0;
1816 id_xpath_attr.local = use_value;
1818 else if (curAttributeSet == VAL_IDXPATH)
1820 attp.local_attributes = &id_xpath_attr;
1821 attp.attset_ordinal = VAL_IDXPATH;
1822 id_xpath_attr.next = 0;
1823 id_xpath_attr.local = use_value;
1827 if ((r = att_getentbyatt (zh, &attp, curAttributeSet, use_value,
1830 yaz_log(YLOG_DEBUG, "att_getentbyatt fail. set=%d use=%d r=%d",
1831 curAttributeSet, use_value, r);
1836 YAZ_BIB1_UNSUPP_USE_ATTRIBUTE,
1839 zebra_setError_zint(zh, YAZ_BIB1_UNSUPP_USE_ATTRIBUTE,
1843 zebra_setError(zh, YAZ_BIB1_UNSUPP_ATTRIBUTE_SET, 0);
1847 if (zebraExplain_curDatabase (zh->reg->zei, basenames[base_no]))
1849 zebra_setError(zh, YAZ_BIB1_DATABASE_UNAVAILABLE,
1850 basenames[base_no]);
1853 for (local_attr = attp.local_attributes; local_attr;
1854 local_attr = local_attr->next)
1860 ord = zebraExplain_lookup_attr_su(zh->reg->zei,
1862 attp.attset_ordinal,
1867 term_dict[prefix_len++] = '|';
1869 term_dict[prefix_len++] = '(';
1871 ord_len = key_SU_encode (ord, ord_buf);
1872 for (i = 0; i<ord_len; i++)
1874 term_dict[prefix_len++] = 1;
1875 term_dict[prefix_len++] = ord_buf[i];
1880 zebra_setError_zint(zh, YAZ_BIB1_UNSUPP_USE_ATTRIBUTE, use_value);
1884 term_dict[prefix_len++] = ')';
1886 term_dict[prefix_len++] = 1;
1887 term_dict[prefix_len++] = reg_type;
1888 yaz_log(YLOG_DEBUG, "reg_type = %d", term_dict[prefix_len-1]);
1890 term_dict[prefix_len] = '\0';
1891 if (!numeric_relation(zh, zapt, &termp, term_dict,
1892 attributeSet, grep_info, &max_pos, reg_type,
1893 term_dst, &relation_error))
1897 zebra_setError(zh, relation_error, 0);
1907 yaz_log(YLOG_DEBUG, "%d positions", grep_info->isam_p_indx);
1912 static ZEBRA_RES rpn_search_APT_numeric(ZebraHandle zh,
1913 Z_AttributesPlusTerm *zapt,
1915 oid_value attributeSet,
1917 int reg_type, int complete_flag,
1918 const char *rank_type, int xpath_use,
1919 int num_bases, char **basenames,
1922 struct rset_key_control *kc)
1924 char term_dst[IT_MAX_WORD+1];
1925 const char *termp = termz;
1926 RSET *result_sets = 0;
1927 int num_result_sets = 0;
1929 struct grep_info grep_info;
1931 zint hits_limit_value;
1932 const char *term_ref_id_str = 0;
1934 term_limits_APT(zh, zapt, &hits_limit_value, &term_ref_id_str);
1936 yaz_log(log_level_rpn, "APT_numeric t='%s'", termz);
1937 if (grep_info_prepare(zh, zapt, &grep_info, reg_type) == ZEBRA_FAIL)
1941 if (alloc_sets == num_result_sets)
1944 RSET *rnew = (RSET *) nmem_malloc(stream, (alloc_sets+add) *
1947 memcpy(rnew, result_sets, alloc_sets * sizeof(*rnew));
1948 alloc_sets = alloc_sets + add;
1951 yaz_log(YLOG_DEBUG, "APT_numeric termp=%s", termp);
1952 grep_info.isam_p_indx = 0;
1953 res = numeric_term(zh, zapt, &termp, attributeSet, &grep_info,
1954 reg_type, complete_flag, num_bases, basenames,
1955 term_dst, xpath_use,
1957 if (res == ZEBRA_FAIL || termp == 0)
1959 yaz_log(YLOG_DEBUG, "term: %s", term_dst);
1960 result_sets[num_result_sets] =
1961 rset_trunc(zh, grep_info.isam_p_buf,
1962 grep_info.isam_p_indx, term_dst,
1963 strlen(term_dst), rank_type,
1964 0 /* preserve position */,
1965 zapt->term->which, rset_nmem,
1966 kc, kc->scope, 0, reg_type,
1969 if (!result_sets[num_result_sets])
1973 grep_info_delete(&grep_info);
1977 for (i = 0; i<num_result_sets; i++)
1978 rset_delete(result_sets[i]);
1981 if (num_result_sets == 0)
1982 *rset = rsnull_create(rset_nmem, kc, 0);
1983 if (num_result_sets == 1)
1984 *rset = result_sets[0];
1986 *rset = rsmulti_and_create(rset_nmem, kc, kc->scope,
1987 num_result_sets, result_sets);
1993 static ZEBRA_RES rpn_search_APT_local(ZebraHandle zh,
1994 Z_AttributesPlusTerm *zapt,
1996 oid_value attributeSet,
1998 const char *rank_type, NMEM rset_nmem,
2000 struct rset_key_control *kc)
2005 *rset = rstemp_create(rset_nmem, kc, kc->scope,
2006 res_get (zh->res, "setTmpDir"),0 );
2007 rsfd = rset_open(*rset, RSETF_WRITE);
2015 rset_write (rsfd, &key);
2020 static ZEBRA_RES rpn_sort_spec(ZebraHandle zh, Z_AttributesPlusTerm *zapt,
2021 oid_value attributeSet, NMEM stream,
2022 Z_SortKeySpecList *sort_sequence,
2023 const char *rank_type,
2026 struct rset_key_control *kc)
2029 int sort_relation_value;
2030 AttrType sort_relation_type;
2037 attr_init(&sort_relation_type, zapt, 7);
2038 sort_relation_value = attr_find(&sort_relation_type, &attributeSet);
2040 if (!sort_sequence->specs)
2042 sort_sequence->num_specs = 10;
2043 sort_sequence->specs = (Z_SortKeySpec **)
2044 nmem_malloc(stream, sort_sequence->num_specs *
2045 sizeof(*sort_sequence->specs));
2046 for (i = 0; i<sort_sequence->num_specs; i++)
2047 sort_sequence->specs[i] = 0;
2049 if (zapt->term->which != Z_Term_general)
2052 i = atoi_n ((char *) zapt->term->u.general->buf,
2053 zapt->term->u.general->len);
2054 if (i >= sort_sequence->num_specs)
2056 sprintf(termz, "%d", i);
2058 oe.proto = PROTO_Z3950;
2059 oe.oclass = CLASS_ATTSET;
2060 oe.value = attributeSet;
2061 if (!oid_ent_to_oid (&oe, oid))
2064 sks = (Z_SortKeySpec *) nmem_malloc(stream, sizeof(*sks));
2065 sks->sortElement = (Z_SortElement *)
2066 nmem_malloc(stream, sizeof(*sks->sortElement));
2067 sks->sortElement->which = Z_SortElement_generic;
2068 sk = sks->sortElement->u.generic = (Z_SortKey *)
2069 nmem_malloc(stream, sizeof(*sk));
2070 sk->which = Z_SortKey_sortAttributes;
2071 sk->u.sortAttributes = (Z_SortAttributes *)
2072 nmem_malloc(stream, sizeof(*sk->u.sortAttributes));
2074 sk->u.sortAttributes->id = oid;
2075 sk->u.sortAttributes->list = zapt->attributes;
2077 sks->sortRelation = (int *)
2078 nmem_malloc(stream, sizeof(*sks->sortRelation));
2079 if (sort_relation_value == 1)
2080 *sks->sortRelation = Z_SortKeySpec_ascending;
2081 else if (sort_relation_value == 2)
2082 *sks->sortRelation = Z_SortKeySpec_descending;
2084 *sks->sortRelation = Z_SortKeySpec_ascending;
2086 sks->caseSensitivity = (int *)
2087 nmem_malloc(stream, sizeof(*sks->caseSensitivity));
2088 *sks->caseSensitivity = 0;
2090 sks->which = Z_SortKeySpec_null;
2091 sks->u.null = odr_nullval ();
2092 sort_sequence->specs[i] = sks;
2093 *rset = rsnull_create (rset_nmem, kc, 0);
2098 static int parse_xpath(ZebraHandle zh, Z_AttributesPlusTerm *zapt,
2099 oid_value attributeSet,
2100 struct xpath_location_step *xpath, int max, NMEM mem)
2102 oid_value curAttributeSet = attributeSet;
2104 const char *use_string = 0;
2106 attr_init(&use, zapt, 1);
2107 attr_find_ex(&use, &curAttributeSet, &use_string);
2109 if (!use_string || *use_string != '/')
2112 return zebra_parse_xpath_str(use_string, xpath, max, mem);
2117 static RSET xpath_trunc(ZebraHandle zh, NMEM stream,
2118 int reg_type, const char *term, int use,
2119 oid_value curAttributeSet, NMEM rset_nmem,
2120 struct rset_key_control *kc)
2123 struct grep_info grep_info;
2124 char term_dict[2048];
2127 int ord = zebraExplain_lookup_attr_su(zh->reg->zei, reg_type,
2128 curAttributeSet, use);
2129 int ord_len, i, r, max_pos;
2130 int term_type = Z_Term_characterString;
2131 const char *flags = "void";
2133 if (grep_info_prepare(zh, 0 /* zapt */, &grep_info, '0') == ZEBRA_FAIL)
2134 return rsnull_create(rset_nmem, kc, 0);
2137 return rsnull_create(rset_nmem, kc, 0);
2139 term_dict[prefix_len++] = '|';
2141 term_dict[prefix_len++] = '(';
2143 ord_len = key_SU_encode (ord, ord_buf);
2144 for (i = 0; i<ord_len; i++)
2146 term_dict[prefix_len++] = 1;
2147 term_dict[prefix_len++] = ord_buf[i];
2149 term_dict[prefix_len++] = ')';
2151 term_dict[prefix_len++] = 1;
2152 term_dict[prefix_len++] = reg_type;
2154 strcpy(term_dict+prefix_len, term);
2156 grep_info.isam_p_indx = 0;
2157 r = dict_lookup_grep(zh->reg->dict, term_dict, 0,
2158 &grep_info, &max_pos, 0, grep_handle);
2159 yaz_log(YLOG_DEBUG, "%s %d positions", term,
2160 grep_info.isam_p_indx);
2161 rset = rset_trunc(zh, grep_info.isam_p_buf,
2162 grep_info.isam_p_indx, term, strlen(term),
2163 flags, 1, term_type,rset_nmem,
2164 kc, kc->scope, 0, reg_type, 0 /* hits_limit */,
2165 0 /* term_ref_id_str */);
2166 grep_info_delete(&grep_info);
2171 ZEBRA_RES rpn_search_xpath(ZebraHandle zh,
2172 oid_value attributeSet,
2173 int num_bases, char **basenames,
2174 NMEM stream, const char *rank_type, RSET rset,
2175 int xpath_len, struct xpath_location_step *xpath,
2178 struct rset_key_control *kc)
2180 oid_value curAttributeSet = attributeSet;
2190 yaz_log(YLOG_DEBUG, "xpath len=%d", xpath_len);
2191 for (i = 0; i<xpath_len; i++)
2193 yaz_log(log_level_rpn, "XPATH %d %s", i, xpath[i].part);
2197 curAttributeSet = VAL_IDXPATH;
2207 a[@attr = value]/b[@other = othervalue]
2209 /e/@a val range(e/,range(@a,freetext(w,1015,val),@a),e/)
2210 /a/b val range(b/a/,freetext(w,1016,val),b/a/)
2211 /a/b/@c val range(b/a/,range(@c,freetext(w,1016,val),@c),b/a/)
2212 /a/b[@c = y] val range(b/a/,freetext(w,1016,val),b/a/,@c = y)
2213 /a[@c = y]/b val range(a/,range(b/a/,freetext(w,1016,val),b/a/),a/,@c = y)
2214 /a[@c = x]/b[@c = y] range(a/,range(b/a/,freetext(w,1016,val),b/a/,@c = y),a/,@c = x)
2218 dict_grep_cmap (zh->reg->dict, 0, 0);
2220 for (base_no = 0; base_no < num_bases; base_no++)
2222 int level = xpath_len;
2225 if (zebraExplain_curDatabase (zh->reg->zei, basenames[base_no]))
2227 zebra_setError(zh, YAZ_BIB1_DATABASE_UNAVAILABLE,
2228 basenames[base_no]);
2232 while (--level >= 0)
2234 char xpath_rev[128];
2236 RSET rset_start_tag = 0, rset_end_tag = 0, rset_attr = 0;
2240 for (i = level; i >= 1; --i)
2242 const char *cp = xpath[i].part;
2248 memcpy (xpath_rev + len, "[^/]*", 5);
2251 else if (*cp == ' ')
2254 xpath_rev[len++] = 1;
2255 xpath_rev[len++] = ' ';
2259 xpath_rev[len++] = *cp;
2260 xpath_rev[len++] = '/';
2262 else if (i == 1) /* // case */
2264 xpath_rev[len++] = '.';
2265 xpath_rev[len++] = '*';
2270 if (xpath[level].predicate &&
2271 xpath[level].predicate->which == XPATH_PREDICATE_RELATION &&
2272 xpath[level].predicate->u.relation.name[0])
2274 WRBUF wbuf = wrbuf_alloc();
2275 wrbuf_puts(wbuf, xpath[level].predicate->u.relation.name+1);
2276 if (xpath[level].predicate->u.relation.value)
2278 const char *cp = xpath[level].predicate->u.relation.value;
2279 wrbuf_putc(wbuf, '=');
2283 if (strchr(REGEX_CHARS, *cp))
2284 wrbuf_putc(wbuf, '\\');
2285 wrbuf_putc(wbuf, *cp);
2289 wrbuf_puts(wbuf, "");
2290 rset_attr = xpath_trunc(
2291 zh, stream, '0', wrbuf_buf(wbuf), 3,
2292 curAttributeSet, rset_nmem, kc);
2293 wrbuf_free(wbuf, 1);
2300 yaz_log(log_level_rpn, "xpath_rev (%d) = %s", level, xpath_rev);
2301 if (strlen(xpath_rev))
2303 rset_start_tag = xpath_trunc(zh, stream, '0',
2304 xpath_rev, 1, curAttributeSet, rset_nmem, kc);
2306 rset_end_tag = xpath_trunc(zh, stream, '0',
2307 xpath_rev, 2, curAttributeSet, rset_nmem, kc);
2309 rset = rsbetween_create(rset_nmem, kc, kc->scope,
2310 rset_start_tag, rset,
2311 rset_end_tag, rset_attr);
2320 static ZEBRA_RES rpn_search_APT(ZebraHandle zh, Z_AttributesPlusTerm *zapt,
2321 oid_value attributeSet, NMEM stream,
2322 Z_SortKeySpecList *sort_sequence,
2323 int num_bases, char **basenames,
2326 struct rset_key_control *kc)
2328 ZEBRA_RES res = ZEBRA_OK;
2330 char *search_type = NULL;
2331 char rank_type[128];
2334 char termz[IT_MAX_WORD+1];
2337 struct xpath_location_step xpath[10];
2341 log_level_rpn = yaz_log_module_level("rpn");
2344 zebra_maps_attr(zh->reg->zebra_maps, zapt, ®_id, &search_type,
2345 rank_type, &complete_flag, &sort_flag);
2347 yaz_log(YLOG_DEBUG, "reg_id=%c", reg_id);
2348 yaz_log(YLOG_DEBUG, "complete_flag=%d", complete_flag);
2349 yaz_log(YLOG_DEBUG, "search_type=%s", search_type);
2350 yaz_log(YLOG_DEBUG, "rank_type=%s", rank_type);
2352 if (zapt_term_to_utf8(zh, zapt, termz) == ZEBRA_FAIL)
2356 return rpn_sort_spec(zh, zapt, attributeSet, stream, sort_sequence,
2357 rank_type, rset_nmem, rset, kc);
2358 /* consider if an X-Path query is used */
2359 xpath_len = parse_xpath(zh, zapt, attributeSet, xpath, 10, stream);
2362 xpath_use = 1016; /* searching for element by default */
2363 if (xpath[xpath_len-1].part[0] == '@')
2364 xpath_use = 1015; /* last step an attribute .. */
2367 /* search using one of the various search type strategies
2368 termz is our UTF-8 search term
2369 attributeSet is top-level default attribute set
2370 stream is ODR for search
2371 reg_id is the register type
2372 complete_flag is 1 for complete subfield, 0 for incomplete
2373 xpath_use is use-attribute to be used for X-Path search, 0 for none
2375 if (!strcmp(search_type, "phrase"))
2377 res = rpn_search_APT_phrase(zh, zapt, termz, attributeSet, stream,
2378 reg_id, complete_flag, rank_type,
2380 num_bases, basenames, rset_nmem,
2383 else if (!strcmp(search_type, "and-list"))
2385 res = rpn_search_APT_and_list(zh, zapt, termz, attributeSet, stream,
2386 reg_id, complete_flag, rank_type,
2388 num_bases, basenames, rset_nmem,
2391 else if (!strcmp(search_type, "or-list"))
2393 res = rpn_search_APT_or_list(zh, zapt, termz, attributeSet, stream,
2394 reg_id, complete_flag, rank_type,
2396 num_bases, basenames, rset_nmem,
2399 else if (!strcmp(search_type, "local"))
2401 res = rpn_search_APT_local(zh, zapt, termz, attributeSet, stream,
2402 rank_type, rset_nmem, rset, kc);
2404 else if (!strcmp(search_type, "numeric"))
2406 res = rpn_search_APT_numeric(zh, zapt, termz, attributeSet, stream,
2407 reg_id, complete_flag, rank_type,
2409 num_bases, basenames, rset_nmem,
2414 zebra_setError(zh, YAZ_BIB1_UNSUPP_STRUCTURE_ATTRIBUTE, 0);
2417 if (res != ZEBRA_OK)
2421 return rpn_search_xpath(zh, attributeSet, num_bases, basenames,
2422 stream, rank_type, *rset,
2423 xpath_len, xpath, rset_nmem, rset, kc);
2426 static ZEBRA_RES rpn_search_structure(ZebraHandle zh, Z_RPNStructure *zs,
2427 oid_value attributeSet,
2428 NMEM stream, NMEM rset_nmem,
2429 Z_SortKeySpecList *sort_sequence,
2430 int num_bases, char **basenames,
2431 RSET **result_sets, int *num_result_sets,
2432 Z_Operator *parent_op,
2433 struct rset_key_control *kc);
2435 ZEBRA_RES rpn_search_top(ZebraHandle zh, Z_RPNStructure *zs,
2436 oid_value attributeSet,
2437 NMEM stream, NMEM rset_nmem,
2438 Z_SortKeySpecList *sort_sequence,
2439 int num_bases, char **basenames,
2442 RSET *result_sets = 0;
2443 int num_result_sets = 0;
2445 struct rset_key_control *kc = zebra_key_control_create(zh);
2447 res = rpn_search_structure(zh, zs, attributeSet,
2450 num_bases, basenames,
2451 &result_sets, &num_result_sets,
2452 0 /* no parent op */,
2454 if (res != ZEBRA_OK)
2457 for (i = 0; i<num_result_sets; i++)
2458 rset_delete(result_sets[i]);
2463 assert(num_result_sets == 1);
2464 assert(result_sets);
2465 assert(*result_sets);
2466 *result_set = *result_sets;
2472 ZEBRA_RES rpn_search_structure(ZebraHandle zh, Z_RPNStructure *zs,
2473 oid_value attributeSet,
2474 NMEM stream, NMEM rset_nmem,
2475 Z_SortKeySpecList *sort_sequence,
2476 int num_bases, char **basenames,
2477 RSET **result_sets, int *num_result_sets,
2478 Z_Operator *parent_op,
2479 struct rset_key_control *kc)
2481 *num_result_sets = 0;
2482 if (zs->which == Z_RPNStructure_complex)
2485 Z_Operator *zop = zs->u.complex->roperator;
2486 RSET *result_sets_l = 0;
2487 int num_result_sets_l = 0;
2488 RSET *result_sets_r = 0;
2489 int num_result_sets_r = 0;
2491 res = rpn_search_structure(zh, zs->u.complex->s1,
2492 attributeSet, stream, rset_nmem,
2494 num_bases, basenames,
2495 &result_sets_l, &num_result_sets_l,
2497 if (res != ZEBRA_OK)
2500 for (i = 0; i<num_result_sets_l; i++)
2501 rset_delete(result_sets_l[i]);
2504 res = rpn_search_structure(zh, zs->u.complex->s2,
2505 attributeSet, stream, rset_nmem,
2507 num_bases, basenames,
2508 &result_sets_r, &num_result_sets_r,
2510 if (res != ZEBRA_OK)
2513 for (i = 0; i<num_result_sets_l; i++)
2514 rset_delete(result_sets_l[i]);
2515 for (i = 0; i<num_result_sets_r; i++)
2516 rset_delete(result_sets_r[i]);
2520 /* make a new list of result for all children */
2521 *num_result_sets = num_result_sets_l + num_result_sets_r;
2522 *result_sets = nmem_malloc(stream, *num_result_sets *
2523 sizeof(**result_sets));
2524 memcpy(*result_sets, result_sets_l,
2525 num_result_sets_l * sizeof(**result_sets));
2526 memcpy(*result_sets + num_result_sets_l, result_sets_r,
2527 num_result_sets_r * sizeof(**result_sets));
2529 if (!parent_op || parent_op->which != zop->which
2530 || (zop->which != Z_Operator_and &&
2531 zop->which != Z_Operator_or))
2533 /* parent node different from this one (or non-present) */
2534 /* we must combine result sets now */
2538 case Z_Operator_and:
2539 rset = rsmulti_and_create(rset_nmem, kc,
2541 *num_result_sets, *result_sets);
2544 rset = rsmulti_or_create(rset_nmem, kc,
2545 kc->scope, 0, /* termid */
2546 *num_result_sets, *result_sets);
2548 case Z_Operator_and_not:
2549 rset = rsbool_create_not(rset_nmem, kc,
2554 case Z_Operator_prox:
2555 if (zop->u.prox->which != Z_ProximityOperator_known)
2558 YAZ_BIB1_UNSUPP_PROX_UNIT_CODE,
2562 if (*zop->u.prox->u.known != Z_ProxUnit_word)
2564 zebra_setError_zint(zh,
2565 YAZ_BIB1_UNSUPP_PROX_UNIT_CODE,
2566 *zop->u.prox->u.known);
2571 rset = rsprox_create(rset_nmem, kc,
2573 *num_result_sets, *result_sets,
2574 *zop->u.prox->ordered,
2575 (!zop->u.prox->exclusion ?
2576 0 : *zop->u.prox->exclusion),
2577 *zop->u.prox->relationType,
2578 *zop->u.prox->distance );
2582 zebra_setError(zh, YAZ_BIB1_OPERATOR_UNSUPP, 0);
2585 *num_result_sets = 1;
2586 *result_sets = nmem_malloc(stream, *num_result_sets *
2587 sizeof(**result_sets));
2588 (*result_sets)[0] = rset;
2591 else if (zs->which == Z_RPNStructure_simple)
2596 if (zs->u.simple->which == Z_Operand_APT)
2598 yaz_log(YLOG_DEBUG, "rpn_search_APT");
2599 res = rpn_search_APT(zh, zs->u.simple->u.attributesPlusTerm,
2600 attributeSet, stream, sort_sequence,
2601 num_bases, basenames, rset_nmem, &rset,
2603 if (res != ZEBRA_OK)
2606 else if (zs->u.simple->which == Z_Operand_resultSetId)
2608 yaz_log(YLOG_DEBUG, "rpn_search_ref");
2609 rset = resultSetRef(zh, zs->u.simple->u.resultSetId);
2613 YAZ_BIB1_SPECIFIED_RESULT_SET_DOES_NOT_EXIST,
2614 zs->u.simple->u.resultSetId);
2621 zebra_setError(zh, YAZ_BIB1_UNSUPP_SEARCH, 0);
2624 *num_result_sets = 1;
2625 *result_sets = nmem_malloc(stream, *num_result_sets *
2626 sizeof(**result_sets));
2627 (*result_sets)[0] = rset;
2631 zebra_setError(zh, YAZ_BIB1_UNSUPP_SEARCH, 0);
2637 struct scan_info_entry {
2643 struct scan_info_entry *list;
2649 static int scan_handle (char *name, const char *info, int pos, void *client)
2651 int len_prefix, idx;
2652 struct scan_info *scan_info = (struct scan_info *) client;
2654 len_prefix = strlen(scan_info->prefix);
2655 if (memcmp (name, scan_info->prefix, len_prefix))
2658 idx = scan_info->after - pos + scan_info->before;
2664 scan_info->list[idx].term = (char *)
2665 odr_malloc(scan_info->odr, strlen(name + len_prefix)+1);
2666 strcpy(scan_info->list[idx].term, name + len_prefix);
2667 assert (*info == sizeof(ISAM_P));
2668 memcpy (&scan_info->list[idx].isam_p, info+1, sizeof(ISAM_P));
2672 void zebra_term_untrans_iconv(ZebraHandle zh, NMEM stream, int reg_type,
2673 char **dst, const char *src)
2675 char term_src[IT_MAX_WORD];
2676 char term_dst[IT_MAX_WORD];
2678 zebra_term_untrans (zh, reg_type, term_src, src);
2680 if (zh->iconv_from_utf8 != 0)
2683 char *inbuf = term_src;
2684 size_t inleft = strlen(term_src);
2685 char *outbuf = term_dst;
2686 size_t outleft = sizeof(term_dst)-1;
2689 ret = yaz_iconv (zh->iconv_from_utf8, &inbuf, &inleft,
2691 if (ret == (size_t)(-1))
2694 len = outbuf - term_dst;
2695 *dst = nmem_malloc(stream, len + 1);
2697 memcpy (*dst, term_dst, len);
2701 *dst = nmem_strdup(stream, term_src);
2704 static void count_set(ZebraHandle zh, RSET rset, zint *count)
2710 yaz_log(YLOG_DEBUG, "count_set");
2712 rset->hits_limit = zh->approx_limit;
2715 rfd = rset_open(rset, RSETF_READ);
2716 while (rset_read(rfd, &key,0 /* never mind terms */))
2718 if (key.mem[0] != psysno)
2720 psysno = key.mem[0];
2721 if (rfd->counted_items >= rset->hits_limit)
2726 *count = rset->hits_count;
2729 ZEBRA_RES rpn_scan(ZebraHandle zh, ODR stream, Z_AttributesPlusTerm *zapt,
2730 oid_value attributeset,
2731 int num_bases, char **basenames,
2732 int *position, int *num_entries, ZebraScanEntry **list,
2733 int *is_partial, RSET limit_set, int return_zero)
2736 int pos = *position;
2737 int num = *num_entries;
2741 char termz[IT_MAX_WORD+20];
2744 const char *use_string = 0;
2745 struct scan_info *scan_info_array;
2746 ZebraScanEntry *glist;
2747 int ords[32], ord_no = 0;
2750 int bases_ok = 0; /* no of databases with OK attribute */
2751 int errCode = 0; /* err code (if any is not OK) */
2752 char *errString = 0; /* addinfo */
2755 char *search_type = NULL;
2756 char rank_type[128];
2759 NMEM rset_nmem = NULL;
2760 struct rset_key_control *kc = 0;
2765 if (attributeset == VAL_NONE)
2766 attributeset = VAL_BIB1;
2771 int termset_value_numeric;
2772 const char *termset_value_string;
2773 attr_init(&termset, zapt, 8);
2774 termset_value_numeric =
2775 attr_find_ex(&termset, NULL, &termset_value_string);
2776 if (termset_value_numeric != -1)
2779 const char *termset_name = 0;
2781 if (termset_value_numeric != -2)
2784 sprintf(resname, "%d", termset_value_numeric);
2785 termset_name = resname;
2788 termset_name = termset_value_string;
2790 limit_set = resultSetRef (zh, termset_name);
2794 yaz_log(YLOG_DEBUG, "position = %d, num = %d set=%d",
2795 pos, num, attributeset);
2797 attr_init(&use, zapt, 1);
2798 use_value = attr_find_ex(&use, &attributeset, &use_string);
2800 if (zebra_maps_attr(zh->reg->zebra_maps, zapt, ®_id, &search_type,
2801 rank_type, &complete_flag, &sort_flag))
2804 zebra_setError(zh, YAZ_BIB1_UNSUPP_ATTRIBUTE_TYPE, 0);
2807 yaz_log(YLOG_DEBUG, "use_value = %d", use_value);
2809 if (use_value == -1)
2811 for (base_no = 0; base_no < num_bases && ord_no < 32; base_no++)
2813 data1_local_attribute *local_attr;
2817 if (zebraExplain_curDatabase (zh->reg->zei, basenames[base_no]))
2819 zebra_setError(zh, YAZ_BIB1_DATABASE_UNAVAILABLE,
2820 basenames[base_no]);
2826 (ord = zebraExplain_lookup_attr_str(zh->reg->zei, reg_id,
2829 /* we have a match for a raw string attribute */
2831 ords[ord_no++] = ord;
2832 attp.local_attributes = 0; /* no more attributes */
2838 if ((r = att_getentbyatt (zh, &attp, attributeset, use_value,
2841 yaz_log(YLOG_DEBUG, "att_getentbyatt fail. set=%d use=%d",
2842 attributeset, use_value);
2845 errCode = YAZ_BIB1_UNSUPP_USE_ATTRIBUTE;
2847 zebra_setError(zh, YAZ_BIB1_UNSUPP_USE_ATTRIBUTE,
2850 zebra_setError_zint(zh, YAZ_BIB1_UNSUPP_USE_ATTRIBUTE,
2855 zebra_setError(zh, YAZ_BIB1_UNSUPP_ATTRIBUTE_SET, 0);
2861 for (local_attr = attp.local_attributes; local_attr && ord_no < 32;
2862 local_attr = local_attr->next)
2864 ord = zebraExplain_lookup_attr_su(zh->reg->zei, reg_id,
2865 attp.attset_ordinal,
2868 ords[ord_no++] = ord;
2871 if (!bases_ok && errCode)
2873 zebra_setError(zh, errCode, errString);
2882 /* prepare dictionary scanning */
2894 yaz_log(YLOG_DEBUG, "rpn_scan pos=%d num=%d before=%d "
2895 "after=%d before+after=%d",
2896 pos, num, before, after, before+after);
2897 scan_info_array = (struct scan_info *)
2898 odr_malloc(stream, ord_no * sizeof(*scan_info_array));
2899 for (i = 0; i < ord_no; i++)
2901 int j, prefix_len = 0;
2902 int before_tmp = before, after_tmp = after;
2903 struct scan_info *scan_info = scan_info_array + i;
2904 struct rpn_char_map_info rcmi;
2906 rpn_char_map_prepare (zh->reg, reg_id, &rcmi);
2908 scan_info->before = before;
2909 scan_info->after = after;
2910 scan_info->odr = stream;
2912 scan_info->list = (struct scan_info_entry *)
2913 odr_malloc(stream, (before+after) * sizeof(*scan_info->list));
2914 for (j = 0; j<before+after; j++)
2915 scan_info->list[j].term = NULL;
2917 prefix_len += key_SU_encode (ords[i], termz + prefix_len);
2919 termz[prefix_len++] = reg_id;
2921 termz[prefix_len] = 0;
2922 strcpy(scan_info->prefix, termz);
2924 if (trans_scan_term(zh, zapt, termz+prefix_len, reg_id) == ZEBRA_FAIL)
2927 dict_scan(zh->reg->dict, termz, &before_tmp, &after_tmp,
2928 scan_info, scan_handle);
2930 glist = (ZebraScanEntry *)
2931 odr_malloc(stream, (before+after)*sizeof(*glist));
2933 rset_nmem = nmem_create();
2934 kc = zebra_key_control_create(zh);
2936 /* consider terms after main term */
2937 for (i = 0; i < ord_no; i++)
2941 for (i = 0; i<after; i++)
2944 const char *mterm = NULL;
2947 int lo = i + pos-1; /* offset in result list */
2949 /* find: j0 is the first of the minimal values */
2950 for (j = 0; j < ord_no; j++)
2952 if (ptr[j] < before+after && ptr[j] >= 0 &&
2953 (tst = scan_info_array[j].list[ptr[j]].term) &&
2954 (!mterm || strcmp (tst, mterm) < 0))
2961 break; /* no value found, stop */
2963 /* get result set for first one , but only if it's within bounds */
2966 /* get result set for first term */
2967 zebra_term_untrans_iconv(zh, stream->mem, reg_id,
2968 &glist[lo].term, mterm);
2969 rset = rset_trunc(zh, &scan_info_array[j0].list[ptr[j0]].isam_p, 1,
2970 glist[lo].term, strlen(glist[lo].term),
2971 NULL, 0, zapt->term->which, rset_nmem,
2972 kc, kc->scope, 0, reg_id, 0 /* hits_limit */,
2973 0 /* term_ref_id_str */);
2975 ptr[j0]++; /* move index for this set .. */
2976 /* get result set for remaining scan terms */
2977 for (j = j0+1; j<ord_no; j++)
2979 if (ptr[j] < before+after && ptr[j] >= 0 &&
2980 (tst = scan_info_array[j].list[ptr[j]].term) &&
2981 !strcmp (tst, mterm))
2990 zh, &scan_info_array[j].list[ptr[j]].isam_p, 1,
2992 strlen(glist[lo].term), NULL, 0,
2993 zapt->term->which,rset_nmem,
2994 kc, kc->scope, 0, reg_id, 0 /* hits_limit */,
2995 0 /* term_ref_id_str */ );
2996 rset = rsmulti_or_create(rset_nmem, kc,
2997 kc->scope, 0 /* termid */,
3006 /* merge with limit_set if given */
3011 rsets[1] = rset_dup(limit_set);
3013 rset = rsmulti_and_create(rset_nmem, kc,
3018 count_set(zh, rset, &count);
3019 glist[lo].occurrences = count;
3025 *num_entries -= (after-i);
3027 if (*num_entries < 0)
3030 nmem_destroy(rset_nmem);
3035 /* consider terms before main term */
3036 for (i = 0; i<ord_no; i++)
3039 for (i = 0; i<before; i++)
3042 const char *mterm = NULL;
3045 int lo = before-1-i; /* offset in result list */
3048 for (j = 0; j <ord_no; j++)
3050 if (ptr[j] < before && ptr[j] >= 0 &&
3051 (tst = scan_info_array[j].list[before-1-ptr[j]].term) &&
3052 (!mterm || strcmp (tst, mterm) > 0))
3061 zebra_term_untrans_iconv(zh, stream->mem, reg_id,
3062 &glist[lo].term, mterm);
3065 (zh, &scan_info_array[j0].list[before-1-ptr[j0]].isam_p, 1,
3066 glist[lo].term, strlen(glist[lo].term),
3067 NULL, 0, zapt->term->which, rset_nmem,
3068 kc, kc->scope, 0, reg_id, 0 /* hits_limit */,
3069 0 /* term_ref_id_str */);
3073 for (j = j0+1; j<ord_no; j++)
3075 if (ptr[j] < before && ptr[j] >= 0 &&
3076 (tst = scan_info_array[j].list[before-1-ptr[j]].term) &&
3077 !strcmp (tst, mterm))
3082 rsets[1] = rset_trunc(
3084 &scan_info_array[j].list[before-1-ptr[j]].isam_p, 1,
3086 strlen(glist[lo].term), NULL, 0,
3087 zapt->term->which, rset_nmem,
3088 kc, kc->scope, 0, reg_id, 0 /* hits_limit */,
3089 0 /* term_ref_id_str */);
3090 rset = rsmulti_or_create(rset_nmem, kc,
3091 kc->scope, 0 /* termid */, 2, rsets);
3100 rsets[1] = rset_dup(limit_set);
3102 rset = rsmulti_and_create(rset_nmem, kc,
3103 kc->scope, 2, rsets);
3105 count_set(zh, rset, &count);
3106 glist[lo].occurrences = count;
3110 nmem_destroy(rset_nmem);
3117 if (*num_entries <= 0)
3124 *list = glist + i; /* list is set to first 'real' entry */
3126 yaz_log(YLOG_DEBUG, "position = %d, num_entries = %d",
3127 *position, *num_entries);