1 /* $Id: zrpn.c,v 1.206 2005-11-02 11:43:26 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 != -1)
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++] = ')';
1245 term_dict[prefix_len++] = 1;
1246 term_dict[prefix_len++] = reg_type;
1247 yaz_log(log_level_rpn, "reg_type = %d", term_dict[prefix_len-1]);
1249 term_dict[prefix_len] = '\0';
1251 switch (truncation_value)
1253 case -1: /* not specified */
1254 case 100: /* do not truncate */
1255 if (!string_relation (zh, zapt, &termp, term_dict,
1257 reg_type, space_split, term_dst,
1262 zebra_setError(zh, relation_error, 0);
1269 case 1: /* right truncation */
1270 term_dict[j++] = '(';
1271 if (!term_100(zh->reg->zebra_maps, reg_type,
1272 &termp, term_dict + j, space_split, term_dst))
1277 strcat(term_dict, ".*)");
1279 case 2: /* keft truncation */
1280 term_dict[j++] = '('; term_dict[j++] = '.'; term_dict[j++] = '*';
1281 if (!term_100(zh->reg->zebra_maps, reg_type,
1282 &termp, term_dict + j, space_split, term_dst))
1287 strcat(term_dict, ")");
1289 case 3: /* left&right truncation */
1290 term_dict[j++] = '('; term_dict[j++] = '.'; term_dict[j++] = '*';
1291 if (!term_100(zh->reg->zebra_maps, reg_type,
1292 &termp, term_dict + j, space_split, term_dst))
1297 strcat(term_dict, ".*)");
1299 case 101: /* process # in term */
1300 term_dict[j++] = '(';
1301 if (!term_101(zh->reg->zebra_maps, reg_type,
1302 &termp, term_dict + j, space_split, term_dst))
1307 strcat(term_dict, ")");
1309 case 102: /* Regexp-1 */
1310 term_dict[j++] = '(';
1311 if (!term_102(zh->reg->zebra_maps, reg_type,
1312 &termp, term_dict + j, space_split, term_dst))
1317 strcat(term_dict, ")");
1319 case 103: /* Regexp-2 */
1321 term_dict[j++] = '(';
1323 if (!term_103(zh->reg->zebra_maps, reg_type,
1324 &termp, term_dict + j, ®ex_range,
1325 space_split, term_dst))
1330 strcat(term_dict, ")");
1332 case 104: /* process # and ! in term */
1333 term_dict[j++] = '(';
1334 if (!term_104(zh->reg->zebra_maps, reg_type,
1335 &termp, term_dict + j, space_split, term_dst))
1340 strcat(term_dict, ")");
1342 case 105: /* process * and ! in term */
1343 term_dict[j++] = '(';
1344 if (!term_105(zh->reg->zebra_maps, reg_type,
1345 &termp, term_dict + j, space_split, term_dst, 1))
1350 strcat(term_dict, ")");
1352 case 106: /* process * and ! in term */
1353 term_dict[j++] = '(';
1354 if (!term_105(zh->reg->zebra_maps, reg_type,
1355 &termp, term_dict + j, space_split, term_dst, 0))
1360 strcat(term_dict, ")");
1363 zebra_setError_zint(zh,
1364 YAZ_BIB1_UNSUPP_TRUNCATION_ATTRIBUTE,
1371 const char *input = term_dict + prefix_len;
1372 esc_str(buf, sizeof(buf), input, strlen(input));
1376 yaz_log(log_level_rpn, "dict_lookup_grep: %s", term_dict+prefix_len);
1377 r = dict_lookup_grep(zh->reg->dict, term_dict, regex_range,
1378 grep_info, &max_pos, init_pos,
1381 yaz_log(YLOG_WARN, "dict_lookup_grep fail %d", r);
1387 yaz_log(YLOG_DEBUG, "%d positions", grep_info->isam_p_indx);
1392 /* convert APT search term to UTF8 */
1393 static ZEBRA_RES zapt_term_to_utf8(ZebraHandle zh, Z_AttributesPlusTerm *zapt,
1397 Z_Term *term = zapt->term;
1399 switch (term->which)
1401 case Z_Term_general:
1402 if (zh->iconv_to_utf8 != 0)
1404 char *inbuf = (char *) term->u.general->buf;
1405 size_t inleft = term->u.general->len;
1406 char *outbuf = termz;
1407 size_t outleft = IT_MAX_WORD-1;
1410 ret = yaz_iconv(zh->iconv_to_utf8, &inbuf, &inleft,
1412 if (ret == (size_t)(-1))
1414 ret = yaz_iconv(zh->iconv_to_utf8, 0, 0, 0, 0);
1417 YAZ_BIB1_QUERY_TERM_INCLUDES_CHARS_THAT_DO_NOT_TRANSLATE_INTO_,
1425 sizez = term->u.general->len;
1426 if (sizez > IT_MAX_WORD-1)
1427 sizez = IT_MAX_WORD-1;
1428 memcpy (termz, term->u.general->buf, sizez);
1429 termz[sizez] = '\0';
1432 case Z_Term_characterString:
1433 sizez = strlen(term->u.characterString);
1434 if (sizez > IT_MAX_WORD-1)
1435 sizez = IT_MAX_WORD-1;
1436 memcpy (termz, term->u.characterString, sizez);
1437 termz[sizez] = '\0';
1440 zebra_setError(zh, YAZ_BIB1_UNSUPP_CODED_VALUE_FOR_TERM, 0);
1446 /* convert APT SCAN term to internal cmap */
1447 static ZEBRA_RES trans_scan_term(ZebraHandle zh, Z_AttributesPlusTerm *zapt,
1448 char *termz, int reg_type)
1450 char termz0[IT_MAX_WORD];
1452 if (zapt_term_to_utf8(zh, zapt, termz0) == ZEBRA_FAIL)
1453 return ZEBRA_FAIL; /* error */
1457 const char *cp = (const char *) termz0;
1458 const char *cp_end = cp + strlen(cp);
1461 const char *space_map = NULL;
1464 while ((len = (cp_end - cp)) > 0)
1466 map = zebra_maps_input(zh->reg->zebra_maps, reg_type, &cp, len, 0);
1467 if (**map == *CHR_SPACE)
1472 for (src = space_map; *src; src++)
1475 for (src = *map; *src; src++)
1484 static void grep_info_delete(struct grep_info *grep_info)
1487 xfree(grep_info->term_no);
1489 xfree(grep_info->isam_p_buf);
1492 static ZEBRA_RES grep_info_prepare(ZebraHandle zh,
1493 Z_AttributesPlusTerm *zapt,
1494 struct grep_info *grep_info,
1498 int termset_value_numeric;
1499 const char *termset_value_string;
1502 grep_info->term_no = 0;
1504 grep_info->isam_p_size = 0;
1505 grep_info->isam_p_buf = NULL;
1507 grep_info->reg_type = reg_type;
1508 grep_info->termset = 0;
1512 attr_init(&termset, zapt, 8);
1513 termset_value_numeric =
1514 attr_find_ex(&termset, NULL, &termset_value_string);
1515 if (termset_value_numeric != -1)
1518 const char *termset_name = 0;
1519 if (termset_value_numeric != -2)
1522 sprintf(resname, "%d", termset_value_numeric);
1523 termset_name = resname;
1526 termset_name = termset_value_string;
1527 yaz_log(log_level_rpn, "creating termset set %s", termset_name);
1528 grep_info->termset = resultSetAdd(zh, termset_name, 1);
1529 if (!grep_info->termset)
1531 zebra_setError(zh, YAZ_BIB1_ILLEGAL_RESULT_SET_NAME, termset_name);
1539 \brief Create result set(s) for list of terms
1540 \param zh Zebra Handle
1541 \param termz term as used in query but converted to UTF-8
1542 \param attributeSet default attribute set
1543 \param stream memory for result
1544 \param reg_type register type ('w', 'p',..)
1545 \param complete_flag whether it's phrases or not
1546 \param rank_type term flags for ranking
1547 \param xpath_use use attribute for X-Path (-1 for no X-path)
1548 \param num_bases number of databases
1549 \param basenames array of databases
1550 \param rset_mem memory for result sets
1551 \param result_sets output result set for each term in list (output)
1552 \param number number of output result sets
1553 \param kc rset key control to be used for created result sets
1555 static ZEBRA_RES term_list_trunc(ZebraHandle zh,
1556 Z_AttributesPlusTerm *zapt,
1558 oid_value attributeSet,
1560 int reg_type, int complete_flag,
1561 const char *rank_type, int xpath_use,
1562 int num_bases, char **basenames,
1564 RSET **result_sets, int *num_result_sets,
1565 struct rset_key_control *kc)
1567 char term_dst[IT_MAX_WORD+1];
1568 struct grep_info grep_info;
1569 const char *termp = termz;
1572 *num_result_sets = 0;
1574 if (grep_info_prepare(zh, zapt, &grep_info, reg_type) == ZEBRA_FAIL)
1580 if (alloc_sets == *num_result_sets)
1583 RSET *rnew = (RSET *) nmem_malloc(stream, (alloc_sets+add) *
1586 memcpy(rnew, *result_sets, alloc_sets * sizeof(*rnew));
1587 alloc_sets = alloc_sets + add;
1588 *result_sets = rnew;
1590 res = term_trunc(zh, zapt, &termp, attributeSet,
1592 reg_type, complete_flag,
1593 num_bases, basenames,
1594 term_dst, rank_type,
1595 xpath_use, rset_nmem,
1596 &(*result_sets)[*num_result_sets],
1598 if (res != ZEBRA_OK)
1601 for (i = 0; i < *num_result_sets; i++)
1602 rset_delete((*result_sets)[i]);
1603 grep_info_delete (&grep_info);
1606 if ((*result_sets)[*num_result_sets] == 0)
1608 (*num_result_sets)++;
1610 grep_info_delete(&grep_info);
1614 static ZEBRA_RES rpn_search_APT_phrase(ZebraHandle zh,
1615 Z_AttributesPlusTerm *zapt,
1616 const char *termz_org,
1617 oid_value attributeSet,
1619 int reg_type, int complete_flag,
1620 const char *rank_type, int xpath_use,
1621 int num_bases, char **basenames,
1624 struct rset_key_control *kc)
1626 RSET *result_sets = 0;
1627 int num_result_sets = 0;
1629 term_list_trunc(zh, zapt, termz_org, attributeSet,
1630 stream, reg_type, complete_flag,
1631 rank_type, xpath_use,
1632 num_bases, basenames,
1634 &result_sets, &num_result_sets, kc);
1635 if (res != ZEBRA_OK)
1637 if (num_result_sets == 0)
1638 *rset = rsnull_create (rset_nmem, kc, 0);
1639 else if (num_result_sets == 1)
1640 *rset = result_sets[0];
1642 *rset = rsprox_create(rset_nmem, kc, kc->scope,
1643 num_result_sets, result_sets,
1644 1 /* ordered */, 0 /* exclusion */,
1645 3 /* relation */, 1 /* distance */);
1651 static ZEBRA_RES rpn_search_APT_or_list(ZebraHandle zh,
1652 Z_AttributesPlusTerm *zapt,
1653 const char *termz_org,
1654 oid_value attributeSet,
1656 int reg_type, int complete_flag,
1657 const char *rank_type,
1659 int num_bases, char **basenames,
1662 struct rset_key_control *kc)
1664 RSET *result_sets = 0;
1665 int num_result_sets = 0;
1667 term_list_trunc(zh, zapt, termz_org, attributeSet,
1668 stream, reg_type, complete_flag,
1669 rank_type, xpath_use,
1670 num_bases, basenames,
1672 &result_sets, &num_result_sets, kc);
1673 if (res != ZEBRA_OK)
1675 if (num_result_sets == 0)
1676 *rset = rsnull_create (rset_nmem, kc, 0);
1677 else if (num_result_sets == 1)
1678 *rset = result_sets[0];
1680 *rset = rsmulti_or_create(rset_nmem, kc, kc->scope, 0 /* termid */,
1681 num_result_sets, result_sets);
1687 static ZEBRA_RES rpn_search_APT_and_list(ZebraHandle zh,
1688 Z_AttributesPlusTerm *zapt,
1689 const char *termz_org,
1690 oid_value attributeSet,
1692 int reg_type, int complete_flag,
1693 const char *rank_type,
1695 int num_bases, char **basenames,
1698 struct rset_key_control *kc)
1700 RSET *result_sets = 0;
1701 int num_result_sets = 0;
1703 term_list_trunc(zh, zapt, termz_org, attributeSet,
1704 stream, reg_type, complete_flag,
1705 rank_type, xpath_use,
1706 num_bases, basenames,
1708 &result_sets, &num_result_sets,
1710 if (res != ZEBRA_OK)
1712 if (num_result_sets == 0)
1713 *rset = rsnull_create (rset_nmem, kc, 0);
1714 else if (num_result_sets == 1)
1715 *rset = result_sets[0];
1717 *rset = rsmulti_and_create(rset_nmem, kc, kc->scope,
1718 num_result_sets, result_sets);
1724 static int numeric_relation(ZebraHandle zh, Z_AttributesPlusTerm *zapt,
1725 const char **term_sub,
1727 oid_value attributeSet,
1728 struct grep_info *grep_info,
1738 char *term_tmp = term_dict + strlen(term_dict);
1741 attr_init(&relation, zapt, 2);
1742 relation_value = attr_find(&relation, NULL);
1744 yaz_log(log_level_rpn, "numeric relation value=%d", relation_value);
1746 if (!term_100(zh->reg->zebra_maps, reg_type, term_sub, term_tmp, 1,
1749 term_value = atoi (term_tmp);
1750 switch (relation_value)
1753 yaz_log(log_level_rpn, "Relation <");
1754 gen_regular_rel(term_tmp, term_value-1, 1);
1757 yaz_log(log_level_rpn, "Relation <=");
1758 gen_regular_rel(term_tmp, term_value, 1);
1761 yaz_log(log_level_rpn, "Relation >=");
1762 gen_regular_rel(term_tmp, term_value, 0);
1765 yaz_log(log_level_rpn, "Relation >");
1766 gen_regular_rel(term_tmp, term_value+1, 0);
1770 yaz_log(log_level_rpn, "Relation =");
1771 sprintf(term_tmp, "(0*%d)", term_value);
1774 *error_code = YAZ_BIB1_UNSUPP_RELATION_ATTRIBUTE;
1777 yaz_log(log_level_rpn, "dict_lookup_grep: %s", term_tmp);
1778 r = dict_lookup_grep(zh->reg->dict, term_dict, 0, grep_info, max_pos,
1781 yaz_log(YLOG_WARN, "dict_lookup_grep fail, rel = gt: %d", r);
1782 yaz_log(log_level_rpn, "%d positions", grep_info->isam_p_indx);
1786 static ZEBRA_RES numeric_term(ZebraHandle zh, Z_AttributesPlusTerm *zapt,
1787 const char **term_sub,
1788 oid_value attributeSet,
1789 struct grep_info *grep_info,
1790 int reg_type, int complete_flag,
1791 int num_bases, char **basenames,
1792 char *term_dst, int xpath_use, NMEM stream)
1794 char term_dict[2*IT_MAX_WORD+2];
1798 const char *use_string = 0;
1799 oid_value curAttributeSet = attributeSet;
1801 struct rpn_char_map_info rcmi;
1803 int bases_ok = 0; /* no of databases with OK attribute */
1805 rpn_char_map_prepare (zh->reg, reg_type, &rcmi);
1806 attr_init(&use, zapt, 1);
1807 use_value = attr_find_ex(&use, &curAttributeSet, &use_string);
1809 if (use_value == -1)
1812 for (base_no = 0; base_no < num_bases; base_no++)
1815 data1_local_attribute id_xpath_attr;
1816 data1_local_attribute *local_attr;
1817 int max_pos, prefix_len = 0;
1818 int relation_error = 0;
1821 if (use_value == -2) /* string attribute (assume IDXPATH/any) */
1823 use_value = xpath_use;
1824 attp.local_attributes = &id_xpath_attr;
1825 attp.attset_ordinal = VAL_IDXPATH;
1826 id_xpath_attr.next = 0;
1827 id_xpath_attr.local = use_value;
1829 else if (curAttributeSet == VAL_IDXPATH)
1831 attp.local_attributes = &id_xpath_attr;
1832 attp.attset_ordinal = VAL_IDXPATH;
1833 id_xpath_attr.next = 0;
1834 id_xpath_attr.local = use_value;
1838 if ((r = att_getentbyatt (zh, &attp, curAttributeSet, use_value,
1841 yaz_log(YLOG_DEBUG, "att_getentbyatt fail. set=%d use=%d r=%d",
1842 curAttributeSet, use_value, r);
1847 YAZ_BIB1_UNSUPP_USE_ATTRIBUTE,
1850 zebra_setError_zint(zh, YAZ_BIB1_UNSUPP_USE_ATTRIBUTE,
1854 zebra_setError(zh, YAZ_BIB1_UNSUPP_ATTRIBUTE_SET, 0);
1858 if (zebraExplain_curDatabase (zh->reg->zei, basenames[base_no]))
1860 zebra_setError(zh, YAZ_BIB1_DATABASE_UNAVAILABLE,
1861 basenames[base_no]);
1864 for (local_attr = attp.local_attributes; local_attr;
1865 local_attr = local_attr->next)
1871 ord = zebraExplain_lookup_attr_su(zh->reg->zei,
1873 attp.attset_ordinal,
1878 term_dict[prefix_len++] = '|';
1880 term_dict[prefix_len++] = '(';
1882 ord_len = key_SU_encode (ord, ord_buf);
1883 for (i = 0; i<ord_len; i++)
1885 term_dict[prefix_len++] = 1;
1886 term_dict[prefix_len++] = ord_buf[i];
1891 zebra_setError_zint(zh, YAZ_BIB1_UNSUPP_USE_ATTRIBUTE, use_value);
1895 term_dict[prefix_len++] = ')';
1897 term_dict[prefix_len++] = 1;
1898 term_dict[prefix_len++] = reg_type;
1899 yaz_log(YLOG_DEBUG, "reg_type = %d", term_dict[prefix_len-1]);
1901 term_dict[prefix_len] = '\0';
1902 if (!numeric_relation(zh, zapt, &termp, term_dict,
1903 attributeSet, grep_info, &max_pos, reg_type,
1904 term_dst, &relation_error))
1908 zebra_setError(zh, relation_error, 0);
1918 yaz_log(YLOG_DEBUG, "%d positions", grep_info->isam_p_indx);
1923 static ZEBRA_RES rpn_search_APT_numeric(ZebraHandle zh,
1924 Z_AttributesPlusTerm *zapt,
1926 oid_value attributeSet,
1928 int reg_type, int complete_flag,
1929 const char *rank_type, int xpath_use,
1930 int num_bases, char **basenames,
1933 struct rset_key_control *kc)
1935 char term_dst[IT_MAX_WORD+1];
1936 const char *termp = termz;
1937 RSET *result_sets = 0;
1938 int num_result_sets = 0;
1940 struct grep_info grep_info;
1942 zint hits_limit_value;
1943 const char *term_ref_id_str = 0;
1945 term_limits_APT(zh, zapt, &hits_limit_value, &term_ref_id_str, stream);
1947 yaz_log(log_level_rpn, "APT_numeric t='%s'", termz);
1948 if (grep_info_prepare(zh, zapt, &grep_info, reg_type) == ZEBRA_FAIL)
1952 if (alloc_sets == num_result_sets)
1955 RSET *rnew = (RSET *) nmem_malloc(stream, (alloc_sets+add) *
1958 memcpy(rnew, result_sets, alloc_sets * sizeof(*rnew));
1959 alloc_sets = alloc_sets + add;
1962 yaz_log(YLOG_DEBUG, "APT_numeric termp=%s", termp);
1963 grep_info.isam_p_indx = 0;
1964 res = numeric_term(zh, zapt, &termp, attributeSet, &grep_info,
1965 reg_type, complete_flag, num_bases, basenames,
1966 term_dst, xpath_use,
1968 if (res == ZEBRA_FAIL || termp == 0)
1970 yaz_log(YLOG_DEBUG, "term: %s", term_dst);
1971 result_sets[num_result_sets] =
1972 rset_trunc(zh, grep_info.isam_p_buf,
1973 grep_info.isam_p_indx, term_dst,
1974 strlen(term_dst), rank_type,
1975 0 /* preserve position */,
1976 zapt->term->which, rset_nmem,
1977 kc, kc->scope, 0, reg_type,
1980 if (!result_sets[num_result_sets])
1984 grep_info_delete(&grep_info);
1988 for (i = 0; i<num_result_sets; i++)
1989 rset_delete(result_sets[i]);
1992 if (num_result_sets == 0)
1993 *rset = rsnull_create(rset_nmem, kc, 0);
1994 if (num_result_sets == 1)
1995 *rset = result_sets[0];
1997 *rset = rsmulti_and_create(rset_nmem, kc, kc->scope,
1998 num_result_sets, result_sets);
2004 static ZEBRA_RES rpn_search_APT_local(ZebraHandle zh,
2005 Z_AttributesPlusTerm *zapt,
2007 oid_value attributeSet,
2009 const char *rank_type, NMEM rset_nmem,
2011 struct rset_key_control *kc)
2016 *rset = rstemp_create(rset_nmem, kc, kc->scope,
2017 res_get (zh->res, "setTmpDir"),0 );
2018 rsfd = rset_open(*rset, RSETF_WRITE);
2026 rset_write (rsfd, &key);
2031 static ZEBRA_RES rpn_sort_spec(ZebraHandle zh, Z_AttributesPlusTerm *zapt,
2032 oid_value attributeSet, NMEM stream,
2033 Z_SortKeySpecList *sort_sequence,
2034 const char *rank_type,
2037 struct rset_key_control *kc)
2040 int sort_relation_value;
2041 AttrType sort_relation_type;
2048 attr_init(&sort_relation_type, zapt, 7);
2049 sort_relation_value = attr_find(&sort_relation_type, &attributeSet);
2051 if (!sort_sequence->specs)
2053 sort_sequence->num_specs = 10;
2054 sort_sequence->specs = (Z_SortKeySpec **)
2055 nmem_malloc(stream, sort_sequence->num_specs *
2056 sizeof(*sort_sequence->specs));
2057 for (i = 0; i<sort_sequence->num_specs; i++)
2058 sort_sequence->specs[i] = 0;
2060 if (zapt->term->which != Z_Term_general)
2063 i = atoi_n ((char *) zapt->term->u.general->buf,
2064 zapt->term->u.general->len);
2065 if (i >= sort_sequence->num_specs)
2067 sprintf(termz, "%d", i);
2069 oe.proto = PROTO_Z3950;
2070 oe.oclass = CLASS_ATTSET;
2071 oe.value = attributeSet;
2072 if (!oid_ent_to_oid (&oe, oid))
2075 sks = (Z_SortKeySpec *) nmem_malloc(stream, sizeof(*sks));
2076 sks->sortElement = (Z_SortElement *)
2077 nmem_malloc(stream, sizeof(*sks->sortElement));
2078 sks->sortElement->which = Z_SortElement_generic;
2079 sk = sks->sortElement->u.generic = (Z_SortKey *)
2080 nmem_malloc(stream, sizeof(*sk));
2081 sk->which = Z_SortKey_sortAttributes;
2082 sk->u.sortAttributes = (Z_SortAttributes *)
2083 nmem_malloc(stream, sizeof(*sk->u.sortAttributes));
2085 sk->u.sortAttributes->id = oid;
2086 sk->u.sortAttributes->list = zapt->attributes;
2088 sks->sortRelation = (int *)
2089 nmem_malloc(stream, sizeof(*sks->sortRelation));
2090 if (sort_relation_value == 1)
2091 *sks->sortRelation = Z_SortKeySpec_ascending;
2092 else if (sort_relation_value == 2)
2093 *sks->sortRelation = Z_SortKeySpec_descending;
2095 *sks->sortRelation = Z_SortKeySpec_ascending;
2097 sks->caseSensitivity = (int *)
2098 nmem_malloc(stream, sizeof(*sks->caseSensitivity));
2099 *sks->caseSensitivity = 0;
2101 sks->which = Z_SortKeySpec_null;
2102 sks->u.null = odr_nullval ();
2103 sort_sequence->specs[i] = sks;
2104 *rset = rsnull_create (rset_nmem, kc, 0);
2109 static int parse_xpath(ZebraHandle zh, Z_AttributesPlusTerm *zapt,
2110 oid_value attributeSet,
2111 struct xpath_location_step *xpath, int max, NMEM mem)
2113 oid_value curAttributeSet = attributeSet;
2115 const char *use_string = 0;
2117 attr_init(&use, zapt, 1);
2118 attr_find_ex(&use, &curAttributeSet, &use_string);
2120 if (!use_string || *use_string != '/')
2123 return zebra_parse_xpath_str(use_string, xpath, max, mem);
2128 static RSET xpath_trunc(ZebraHandle zh, NMEM stream,
2129 int reg_type, const char *term, int use,
2130 oid_value curAttributeSet, NMEM rset_nmem,
2131 struct rset_key_control *kc)
2134 struct grep_info grep_info;
2135 char term_dict[2048];
2138 int ord = zebraExplain_lookup_attr_su(zh->reg->zei, reg_type,
2139 curAttributeSet, use);
2140 int ord_len, i, r, max_pos;
2141 int term_type = Z_Term_characterString;
2142 const char *flags = "void";
2144 if (grep_info_prepare(zh, 0 /* zapt */, &grep_info, '0') == ZEBRA_FAIL)
2145 return rsnull_create(rset_nmem, kc, 0);
2148 return rsnull_create(rset_nmem, kc, 0);
2150 term_dict[prefix_len++] = '|';
2152 term_dict[prefix_len++] = '(';
2154 ord_len = key_SU_encode (ord, ord_buf);
2155 for (i = 0; i<ord_len; i++)
2157 term_dict[prefix_len++] = 1;
2158 term_dict[prefix_len++] = ord_buf[i];
2160 term_dict[prefix_len++] = ')';
2162 term_dict[prefix_len++] = 1;
2163 term_dict[prefix_len++] = reg_type;
2165 strcpy(term_dict+prefix_len, term);
2167 grep_info.isam_p_indx = 0;
2168 r = dict_lookup_grep(zh->reg->dict, term_dict, 0,
2169 &grep_info, &max_pos, 0, grep_handle);
2170 yaz_log(YLOG_DEBUG, "%s %d positions", term,
2171 grep_info.isam_p_indx);
2172 rset = rset_trunc(zh, grep_info.isam_p_buf,
2173 grep_info.isam_p_indx, term, strlen(term),
2174 flags, 1, term_type,rset_nmem,
2175 kc, kc->scope, 0, reg_type, 0 /* hits_limit */,
2176 0 /* term_ref_id_str */);
2177 grep_info_delete(&grep_info);
2182 ZEBRA_RES rpn_search_xpath(ZebraHandle zh,
2183 oid_value attributeSet,
2184 int num_bases, char **basenames,
2185 NMEM stream, const char *rank_type, RSET rset,
2186 int xpath_len, struct xpath_location_step *xpath,
2189 struct rset_key_control *kc)
2191 oid_value curAttributeSet = attributeSet;
2201 yaz_log(YLOG_DEBUG, "xpath len=%d", xpath_len);
2202 for (i = 0; i<xpath_len; i++)
2204 yaz_log(log_level_rpn, "XPATH %d %s", i, xpath[i].part);
2208 curAttributeSet = VAL_IDXPATH;
2218 a[@attr = value]/b[@other = othervalue]
2220 /e/@a val range(e/,range(@a,freetext(w,1015,val),@a),e/)
2221 /a/b val range(b/a/,freetext(w,1016,val),b/a/)
2222 /a/b/@c val range(b/a/,range(@c,freetext(w,1016,val),@c),b/a/)
2223 /a/b[@c = y] val range(b/a/,freetext(w,1016,val),b/a/,@c = y)
2224 /a[@c = y]/b val range(a/,range(b/a/,freetext(w,1016,val),b/a/),a/,@c = y)
2225 /a[@c = x]/b[@c = y] range(a/,range(b/a/,freetext(w,1016,val),b/a/,@c = y),a/,@c = x)
2229 dict_grep_cmap (zh->reg->dict, 0, 0);
2231 for (base_no = 0; base_no < num_bases; base_no++)
2233 int level = xpath_len;
2236 if (zebraExplain_curDatabase (zh->reg->zei, basenames[base_no]))
2238 zebra_setError(zh, YAZ_BIB1_DATABASE_UNAVAILABLE,
2239 basenames[base_no]);
2243 while (--level >= 0)
2245 char xpath_rev[128];
2247 RSET rset_start_tag = 0, rset_end_tag = 0, rset_attr = 0;
2251 for (i = level; i >= 1; --i)
2253 const char *cp = xpath[i].part;
2259 memcpy (xpath_rev + len, "[^/]*", 5);
2262 else if (*cp == ' ')
2265 xpath_rev[len++] = 1;
2266 xpath_rev[len++] = ' ';
2270 xpath_rev[len++] = *cp;
2271 xpath_rev[len++] = '/';
2273 else if (i == 1) /* // case */
2275 xpath_rev[len++] = '.';
2276 xpath_rev[len++] = '*';
2281 if (xpath[level].predicate &&
2282 xpath[level].predicate->which == XPATH_PREDICATE_RELATION &&
2283 xpath[level].predicate->u.relation.name[0])
2285 WRBUF wbuf = wrbuf_alloc();
2286 wrbuf_puts(wbuf, xpath[level].predicate->u.relation.name+1);
2287 if (xpath[level].predicate->u.relation.value)
2289 const char *cp = xpath[level].predicate->u.relation.value;
2290 wrbuf_putc(wbuf, '=');
2294 if (strchr(REGEX_CHARS, *cp))
2295 wrbuf_putc(wbuf, '\\');
2296 wrbuf_putc(wbuf, *cp);
2300 wrbuf_puts(wbuf, "");
2301 rset_attr = xpath_trunc(
2302 zh, stream, '0', wrbuf_buf(wbuf), 3,
2303 curAttributeSet, rset_nmem, kc);
2304 wrbuf_free(wbuf, 1);
2311 yaz_log(log_level_rpn, "xpath_rev (%d) = %s", level, xpath_rev);
2312 if (strlen(xpath_rev))
2314 rset_start_tag = xpath_trunc(zh, stream, '0',
2315 xpath_rev, 1, curAttributeSet, rset_nmem, kc);
2317 rset_end_tag = xpath_trunc(zh, stream, '0',
2318 xpath_rev, 2, curAttributeSet, rset_nmem, kc);
2320 rset = rsbetween_create(rset_nmem, kc, kc->scope,
2321 rset_start_tag, rset,
2322 rset_end_tag, rset_attr);
2331 static ZEBRA_RES rpn_search_APT(ZebraHandle zh, Z_AttributesPlusTerm *zapt,
2332 oid_value attributeSet, NMEM stream,
2333 Z_SortKeySpecList *sort_sequence,
2334 int num_bases, char **basenames,
2337 struct rset_key_control *kc)
2339 ZEBRA_RES res = ZEBRA_OK;
2341 char *search_type = NULL;
2342 char rank_type[128];
2345 char termz[IT_MAX_WORD+1];
2348 struct xpath_location_step xpath[10];
2352 log_level_rpn = yaz_log_module_level("rpn");
2355 zebra_maps_attr(zh->reg->zebra_maps, zapt, ®_id, &search_type,
2356 rank_type, &complete_flag, &sort_flag);
2358 yaz_log(YLOG_DEBUG, "reg_id=%c", reg_id);
2359 yaz_log(YLOG_DEBUG, "complete_flag=%d", complete_flag);
2360 yaz_log(YLOG_DEBUG, "search_type=%s", search_type);
2361 yaz_log(YLOG_DEBUG, "rank_type=%s", rank_type);
2363 if (zapt_term_to_utf8(zh, zapt, termz) == ZEBRA_FAIL)
2367 return rpn_sort_spec(zh, zapt, attributeSet, stream, sort_sequence,
2368 rank_type, rset_nmem, rset, kc);
2369 /* consider if an X-Path query is used */
2370 xpath_len = parse_xpath(zh, zapt, attributeSet, xpath, 10, stream);
2373 xpath_use = 1016; /* searching for element by default */
2374 if (xpath[xpath_len-1].part[0] == '@')
2375 xpath_use = 1015; /* last step an attribute .. */
2378 /* search using one of the various search type strategies
2379 termz is our UTF-8 search term
2380 attributeSet is top-level default attribute set
2381 stream is ODR for search
2382 reg_id is the register type
2383 complete_flag is 1 for complete subfield, 0 for incomplete
2384 xpath_use is use-attribute to be used for X-Path search, 0 for none
2386 if (!strcmp(search_type, "phrase"))
2388 res = rpn_search_APT_phrase(zh, zapt, termz, attributeSet, stream,
2389 reg_id, complete_flag, rank_type,
2391 num_bases, basenames, rset_nmem,
2394 else if (!strcmp(search_type, "and-list"))
2396 res = rpn_search_APT_and_list(zh, zapt, termz, attributeSet, stream,
2397 reg_id, complete_flag, rank_type,
2399 num_bases, basenames, rset_nmem,
2402 else if (!strcmp(search_type, "or-list"))
2404 res = rpn_search_APT_or_list(zh, zapt, termz, attributeSet, stream,
2405 reg_id, complete_flag, rank_type,
2407 num_bases, basenames, rset_nmem,
2410 else if (!strcmp(search_type, "local"))
2412 res = rpn_search_APT_local(zh, zapt, termz, attributeSet, stream,
2413 rank_type, rset_nmem, rset, kc);
2415 else if (!strcmp(search_type, "numeric"))
2417 res = rpn_search_APT_numeric(zh, zapt, termz, attributeSet, stream,
2418 reg_id, complete_flag, rank_type,
2420 num_bases, basenames, rset_nmem,
2425 zebra_setError(zh, YAZ_BIB1_UNSUPP_STRUCTURE_ATTRIBUTE, 0);
2428 if (res != ZEBRA_OK)
2432 return rpn_search_xpath(zh, attributeSet, num_bases, basenames,
2433 stream, rank_type, *rset,
2434 xpath_len, xpath, rset_nmem, rset, kc);
2437 static ZEBRA_RES rpn_search_structure(ZebraHandle zh, Z_RPNStructure *zs,
2438 oid_value attributeSet,
2439 NMEM stream, NMEM rset_nmem,
2440 Z_SortKeySpecList *sort_sequence,
2441 int num_bases, char **basenames,
2442 RSET **result_sets, int *num_result_sets,
2443 Z_Operator *parent_op,
2444 struct rset_key_control *kc);
2446 ZEBRA_RES rpn_search_top(ZebraHandle zh, Z_RPNStructure *zs,
2447 oid_value attributeSet,
2448 NMEM stream, NMEM rset_nmem,
2449 Z_SortKeySpecList *sort_sequence,
2450 int num_bases, char **basenames,
2453 RSET *result_sets = 0;
2454 int num_result_sets = 0;
2456 struct rset_key_control *kc = zebra_key_control_create(zh);
2458 res = rpn_search_structure(zh, zs, attributeSet,
2461 num_bases, basenames,
2462 &result_sets, &num_result_sets,
2463 0 /* no parent op */,
2465 if (res != ZEBRA_OK)
2468 for (i = 0; i<num_result_sets; i++)
2469 rset_delete(result_sets[i]);
2474 assert(num_result_sets == 1);
2475 assert(result_sets);
2476 assert(*result_sets);
2477 *result_set = *result_sets;
2483 ZEBRA_RES rpn_search_structure(ZebraHandle zh, Z_RPNStructure *zs,
2484 oid_value attributeSet,
2485 NMEM stream, NMEM rset_nmem,
2486 Z_SortKeySpecList *sort_sequence,
2487 int num_bases, char **basenames,
2488 RSET **result_sets, int *num_result_sets,
2489 Z_Operator *parent_op,
2490 struct rset_key_control *kc)
2492 *num_result_sets = 0;
2493 if (zs->which == Z_RPNStructure_complex)
2496 Z_Operator *zop = zs->u.complex->roperator;
2497 RSET *result_sets_l = 0;
2498 int num_result_sets_l = 0;
2499 RSET *result_sets_r = 0;
2500 int num_result_sets_r = 0;
2502 res = rpn_search_structure(zh, zs->u.complex->s1,
2503 attributeSet, stream, rset_nmem,
2505 num_bases, basenames,
2506 &result_sets_l, &num_result_sets_l,
2508 if (res != ZEBRA_OK)
2511 for (i = 0; i<num_result_sets_l; i++)
2512 rset_delete(result_sets_l[i]);
2515 res = rpn_search_structure(zh, zs->u.complex->s2,
2516 attributeSet, stream, rset_nmem,
2518 num_bases, basenames,
2519 &result_sets_r, &num_result_sets_r,
2521 if (res != ZEBRA_OK)
2524 for (i = 0; i<num_result_sets_l; i++)
2525 rset_delete(result_sets_l[i]);
2526 for (i = 0; i<num_result_sets_r; i++)
2527 rset_delete(result_sets_r[i]);
2531 /* make a new list of result for all children */
2532 *num_result_sets = num_result_sets_l + num_result_sets_r;
2533 *result_sets = nmem_malloc(stream, *num_result_sets *
2534 sizeof(**result_sets));
2535 memcpy(*result_sets, result_sets_l,
2536 num_result_sets_l * sizeof(**result_sets));
2537 memcpy(*result_sets + num_result_sets_l, result_sets_r,
2538 num_result_sets_r * sizeof(**result_sets));
2540 if (!parent_op || parent_op->which != zop->which
2541 || (zop->which != Z_Operator_and &&
2542 zop->which != Z_Operator_or))
2544 /* parent node different from this one (or non-present) */
2545 /* we must combine result sets now */
2549 case Z_Operator_and:
2550 rset = rsmulti_and_create(rset_nmem, kc,
2552 *num_result_sets, *result_sets);
2555 rset = rsmulti_or_create(rset_nmem, kc,
2556 kc->scope, 0, /* termid */
2557 *num_result_sets, *result_sets);
2559 case Z_Operator_and_not:
2560 rset = rsbool_create_not(rset_nmem, kc,
2565 case Z_Operator_prox:
2566 if (zop->u.prox->which != Z_ProximityOperator_known)
2569 YAZ_BIB1_UNSUPP_PROX_UNIT_CODE,
2573 if (*zop->u.prox->u.known != Z_ProxUnit_word)
2575 zebra_setError_zint(zh,
2576 YAZ_BIB1_UNSUPP_PROX_UNIT_CODE,
2577 *zop->u.prox->u.known);
2582 rset = rsprox_create(rset_nmem, kc,
2584 *num_result_sets, *result_sets,
2585 *zop->u.prox->ordered,
2586 (!zop->u.prox->exclusion ?
2587 0 : *zop->u.prox->exclusion),
2588 *zop->u.prox->relationType,
2589 *zop->u.prox->distance );
2593 zebra_setError(zh, YAZ_BIB1_OPERATOR_UNSUPP, 0);
2596 *num_result_sets = 1;
2597 *result_sets = nmem_malloc(stream, *num_result_sets *
2598 sizeof(**result_sets));
2599 (*result_sets)[0] = rset;
2602 else if (zs->which == Z_RPNStructure_simple)
2607 if (zs->u.simple->which == Z_Operand_APT)
2609 yaz_log(YLOG_DEBUG, "rpn_search_APT");
2610 res = rpn_search_APT(zh, zs->u.simple->u.attributesPlusTerm,
2611 attributeSet, stream, sort_sequence,
2612 num_bases, basenames, rset_nmem, &rset,
2614 if (res != ZEBRA_OK)
2617 else if (zs->u.simple->which == Z_Operand_resultSetId)
2619 yaz_log(YLOG_DEBUG, "rpn_search_ref");
2620 rset = resultSetRef(zh, zs->u.simple->u.resultSetId);
2624 YAZ_BIB1_SPECIFIED_RESULT_SET_DOES_NOT_EXIST,
2625 zs->u.simple->u.resultSetId);
2632 zebra_setError(zh, YAZ_BIB1_UNSUPP_SEARCH, 0);
2635 *num_result_sets = 1;
2636 *result_sets = nmem_malloc(stream, *num_result_sets *
2637 sizeof(**result_sets));
2638 (*result_sets)[0] = rset;
2642 zebra_setError(zh, YAZ_BIB1_UNSUPP_SEARCH, 0);
2648 struct scan_info_entry {
2654 struct scan_info_entry *list;
2660 static int scan_handle (char *name, const char *info, int pos, void *client)
2662 int len_prefix, idx;
2663 struct scan_info *scan_info = (struct scan_info *) client;
2665 len_prefix = strlen(scan_info->prefix);
2666 if (memcmp (name, scan_info->prefix, len_prefix))
2669 idx = scan_info->after - pos + scan_info->before;
2675 scan_info->list[idx].term = (char *)
2676 odr_malloc(scan_info->odr, strlen(name + len_prefix)+1);
2677 strcpy(scan_info->list[idx].term, name + len_prefix);
2678 assert (*info == sizeof(ISAM_P));
2679 memcpy (&scan_info->list[idx].isam_p, info+1, sizeof(ISAM_P));
2683 void zebra_term_untrans_iconv(ZebraHandle zh, NMEM stream, int reg_type,
2684 char **dst, const char *src)
2686 char term_src[IT_MAX_WORD];
2687 char term_dst[IT_MAX_WORD];
2689 zebra_term_untrans (zh, reg_type, term_src, src);
2691 if (zh->iconv_from_utf8 != 0)
2694 char *inbuf = term_src;
2695 size_t inleft = strlen(term_src);
2696 char *outbuf = term_dst;
2697 size_t outleft = sizeof(term_dst)-1;
2700 ret = yaz_iconv (zh->iconv_from_utf8, &inbuf, &inleft,
2702 if (ret == (size_t)(-1))
2705 len = outbuf - term_dst;
2706 *dst = nmem_malloc(stream, len + 1);
2708 memcpy (*dst, term_dst, len);
2712 *dst = nmem_strdup(stream, term_src);
2715 static void count_set(ZebraHandle zh, RSET rset, zint *count)
2721 yaz_log(YLOG_DEBUG, "count_set");
2723 rset->hits_limit = zh->approx_limit;
2726 rfd = rset_open(rset, RSETF_READ);
2727 while (rset_read(rfd, &key,0 /* never mind terms */))
2729 if (key.mem[0] != psysno)
2731 psysno = key.mem[0];
2732 if (rfd->counted_items >= rset->hits_limit)
2737 *count = rset->hits_count;
2740 ZEBRA_RES rpn_scan(ZebraHandle zh, ODR stream, Z_AttributesPlusTerm *zapt,
2741 oid_value attributeset,
2742 int num_bases, char **basenames,
2743 int *position, int *num_entries, ZebraScanEntry **list,
2744 int *is_partial, RSET limit_set, int return_zero)
2747 int pos = *position;
2748 int num = *num_entries;
2752 char termz[IT_MAX_WORD+20];
2755 const char *use_string = 0;
2756 struct scan_info *scan_info_array;
2757 ZebraScanEntry *glist;
2758 int ords[32], ord_no = 0;
2761 int bases_ok = 0; /* no of databases with OK attribute */
2762 int errCode = 0; /* err code (if any is not OK) */
2763 char *errString = 0; /* addinfo */
2766 char *search_type = NULL;
2767 char rank_type[128];
2770 NMEM rset_nmem = NULL;
2771 struct rset_key_control *kc = 0;
2776 if (attributeset == VAL_NONE)
2777 attributeset = VAL_BIB1;
2782 int termset_value_numeric;
2783 const char *termset_value_string;
2784 attr_init(&termset, zapt, 8);
2785 termset_value_numeric =
2786 attr_find_ex(&termset, NULL, &termset_value_string);
2787 if (termset_value_numeric != -1)
2790 const char *termset_name = 0;
2792 if (termset_value_numeric != -2)
2795 sprintf(resname, "%d", termset_value_numeric);
2796 termset_name = resname;
2799 termset_name = termset_value_string;
2801 limit_set = resultSetRef (zh, termset_name);
2805 yaz_log(YLOG_DEBUG, "position = %d, num = %d set=%d",
2806 pos, num, attributeset);
2808 attr_init(&use, zapt, 1);
2809 use_value = attr_find_ex(&use, &attributeset, &use_string);
2811 if (zebra_maps_attr(zh->reg->zebra_maps, zapt, ®_id, &search_type,
2812 rank_type, &complete_flag, &sort_flag))
2815 zebra_setError(zh, YAZ_BIB1_UNSUPP_ATTRIBUTE_TYPE, 0);
2818 yaz_log(YLOG_DEBUG, "use_value = %d", use_value);
2820 if (use_value == -1)
2822 for (base_no = 0; base_no < num_bases && ord_no < 32; base_no++)
2824 data1_local_attribute *local_attr;
2828 if (zebraExplain_curDatabase (zh->reg->zei, basenames[base_no]))
2830 zebra_setError(zh, YAZ_BIB1_DATABASE_UNAVAILABLE,
2831 basenames[base_no]);
2837 (ord = zebraExplain_lookup_attr_str(zh->reg->zei, reg_id,
2840 /* we have a match for a raw string attribute */
2842 ords[ord_no++] = ord;
2843 attp.local_attributes = 0; /* no more attributes */
2849 if ((r = att_getentbyatt (zh, &attp, attributeset, use_value,
2852 yaz_log(YLOG_DEBUG, "att_getentbyatt fail. set=%d use=%d",
2853 attributeset, use_value);
2856 errCode = YAZ_BIB1_UNSUPP_USE_ATTRIBUTE;
2858 zebra_setError(zh, YAZ_BIB1_UNSUPP_USE_ATTRIBUTE,
2861 zebra_setError_zint(zh, YAZ_BIB1_UNSUPP_USE_ATTRIBUTE,
2866 zebra_setError(zh, YAZ_BIB1_UNSUPP_ATTRIBUTE_SET, 0);
2872 for (local_attr = attp.local_attributes; local_attr && ord_no < 32;
2873 local_attr = local_attr->next)
2875 ord = zebraExplain_lookup_attr_su(zh->reg->zei, reg_id,
2876 attp.attset_ordinal,
2879 ords[ord_no++] = ord;
2882 if (!bases_ok && errCode)
2884 zebra_setError(zh, errCode, errString);
2893 /* prepare dictionary scanning */
2905 yaz_log(YLOG_DEBUG, "rpn_scan pos=%d num=%d before=%d "
2906 "after=%d before+after=%d",
2907 pos, num, before, after, before+after);
2908 scan_info_array = (struct scan_info *)
2909 odr_malloc(stream, ord_no * sizeof(*scan_info_array));
2910 for (i = 0; i < ord_no; i++)
2912 int j, prefix_len = 0;
2913 int before_tmp = before, after_tmp = after;
2914 struct scan_info *scan_info = scan_info_array + i;
2915 struct rpn_char_map_info rcmi;
2917 rpn_char_map_prepare (zh->reg, reg_id, &rcmi);
2919 scan_info->before = before;
2920 scan_info->after = after;
2921 scan_info->odr = stream;
2923 scan_info->list = (struct scan_info_entry *)
2924 odr_malloc(stream, (before+after) * sizeof(*scan_info->list));
2925 for (j = 0; j<before+after; j++)
2926 scan_info->list[j].term = NULL;
2928 prefix_len += key_SU_encode (ords[i], termz + prefix_len);
2930 termz[prefix_len++] = reg_id;
2932 termz[prefix_len] = 0;
2933 strcpy(scan_info->prefix, termz);
2935 if (trans_scan_term(zh, zapt, termz+prefix_len, reg_id) == ZEBRA_FAIL)
2938 dict_scan(zh->reg->dict, termz, &before_tmp, &after_tmp,
2939 scan_info, scan_handle);
2941 glist = (ZebraScanEntry *)
2942 odr_malloc(stream, (before+after)*sizeof(*glist));
2944 rset_nmem = nmem_create();
2945 kc = zebra_key_control_create(zh);
2947 /* consider terms after main term */
2948 for (i = 0; i < ord_no; i++)
2952 for (i = 0; i<after; i++)
2955 const char *mterm = NULL;
2958 int lo = i + pos-1; /* offset in result list */
2960 /* find: j0 is the first of the minimal values */
2961 for (j = 0; j < ord_no; j++)
2963 if (ptr[j] < before+after && ptr[j] >= 0 &&
2964 (tst = scan_info_array[j].list[ptr[j]].term) &&
2965 (!mterm || strcmp (tst, mterm) < 0))
2972 break; /* no value found, stop */
2974 /* get result set for first one , but only if it's within bounds */
2977 /* get result set for first term */
2978 zebra_term_untrans_iconv(zh, stream->mem, reg_id,
2979 &glist[lo].term, mterm);
2980 rset = rset_trunc(zh, &scan_info_array[j0].list[ptr[j0]].isam_p, 1,
2981 glist[lo].term, strlen(glist[lo].term),
2982 NULL, 0, zapt->term->which, rset_nmem,
2983 kc, kc->scope, 0, reg_id, 0 /* hits_limit */,
2984 0 /* term_ref_id_str */);
2986 ptr[j0]++; /* move index for this set .. */
2987 /* get result set for remaining scan terms */
2988 for (j = j0+1; j<ord_no; j++)
2990 if (ptr[j] < before+after && ptr[j] >= 0 &&
2991 (tst = scan_info_array[j].list[ptr[j]].term) &&
2992 !strcmp (tst, mterm))
3001 zh, &scan_info_array[j].list[ptr[j]].isam_p, 1,
3003 strlen(glist[lo].term), NULL, 0,
3004 zapt->term->which,rset_nmem,
3005 kc, kc->scope, 0, reg_id, 0 /* hits_limit */,
3006 0 /* term_ref_id_str */ );
3007 rset = rsmulti_or_create(rset_nmem, kc,
3008 kc->scope, 0 /* termid */,
3017 /* merge with limit_set if given */
3022 rsets[1] = rset_dup(limit_set);
3024 rset = rsmulti_and_create(rset_nmem, kc,
3029 count_set(zh, rset, &count);
3030 glist[lo].occurrences = count;
3036 *num_entries -= (after-i);
3038 if (*num_entries < 0)
3041 nmem_destroy(rset_nmem);
3046 /* consider terms before main term */
3047 for (i = 0; i<ord_no; i++)
3050 for (i = 0; i<before; i++)
3053 const char *mterm = NULL;
3056 int lo = before-1-i; /* offset in result list */
3059 for (j = 0; j <ord_no; j++)
3061 if (ptr[j] < before && ptr[j] >= 0 &&
3062 (tst = scan_info_array[j].list[before-1-ptr[j]].term) &&
3063 (!mterm || strcmp (tst, mterm) > 0))
3072 zebra_term_untrans_iconv(zh, stream->mem, reg_id,
3073 &glist[lo].term, mterm);
3076 (zh, &scan_info_array[j0].list[before-1-ptr[j0]].isam_p, 1,
3077 glist[lo].term, strlen(glist[lo].term),
3078 NULL, 0, zapt->term->which, rset_nmem,
3079 kc, kc->scope, 0, reg_id, 0 /* hits_limit */,
3080 0 /* term_ref_id_str */);
3084 for (j = j0+1; j<ord_no; j++)
3086 if (ptr[j] < before && ptr[j] >= 0 &&
3087 (tst = scan_info_array[j].list[before-1-ptr[j]].term) &&
3088 !strcmp (tst, mterm))
3093 rsets[1] = rset_trunc(
3095 &scan_info_array[j].list[before-1-ptr[j]].isam_p, 1,
3097 strlen(glist[lo].term), NULL, 0,
3098 zapt->term->which, rset_nmem,
3099 kc, kc->scope, 0, reg_id, 0 /* hits_limit */,
3100 0 /* term_ref_id_str */);
3101 rset = rsmulti_or_create(rset_nmem, kc,
3102 kc->scope, 0 /* termid */, 2, rsets);
3111 rsets[1] = rset_dup(limit_set);
3113 rset = rsmulti_and_create(rset_nmem, kc,
3114 kc->scope, 2, rsets);
3116 count_set(zh, rset, &count);
3117 glist[lo].occurrences = count;
3121 nmem_destroy(rset_nmem);
3128 if (*num_entries <= 0)
3135 *list = glist + i; /* list is set to first 'real' entry */
3137 yaz_log(YLOG_DEBUG, "position = %d, num_entries = %d",
3138 *position, *num_entries);