1 /* $Id: zrpn.c,v 1.197 2005-06-07 14:53:39 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
32 #include <yaz/diagbib1.h>
34 #include <zebra_xpath.h>
39 struct rpn_char_map_info
50 Z_AttributesPlusTerm *zapt;
53 static int log_level_set = 0;
54 static int log_level_rpn = 0;
56 static const char **rpn_char_map_handler(void *vp, const char **from, int len)
58 struct rpn_char_map_info *p = (struct rpn_char_map_info *) vp;
59 const char **out = zebra_maps_input(p->zm, p->reg_type, from, len, 0);
63 const char *outp = *out;
64 yaz_log(YLOG_LOG, "---");
67 yaz_log(YLOG_LOG, "%02X", *outp);
75 static void rpn_char_map_prepare(struct zebra_register *reg, int reg_type,
76 struct rpn_char_map_info *map_info)
78 map_info->zm = reg->zebra_maps;
79 map_info->reg_type = reg_type;
80 dict_grep_cmap(reg->dict, map_info, rpn_char_map_handler);
83 static int attr_find_ex(AttrType *src, oid_value *attributeSetP,
84 const char **string_value)
88 num_attributes = src->zapt->attributes->num_attributes;
89 while (src->major < num_attributes)
91 Z_AttributeElement *element;
93 element = src->zapt->attributes->attributes[src->major];
94 if (src->type == *element->attributeType)
96 switch (element->which)
98 case Z_AttributeValue_numeric:
100 if (element->attributeSet && attributeSetP)
104 attrset = oid_getentbyoid(element->attributeSet);
105 *attributeSetP = attrset->value;
107 return *element->value.numeric;
109 case Z_AttributeValue_complex:
110 if (src->minor >= element->value.complex->num_list)
112 if (element->attributeSet && attributeSetP)
116 attrset = oid_getentbyoid(element->attributeSet);
117 *attributeSetP = attrset->value;
119 if (element->value.complex->list[src->minor]->which ==
120 Z_StringOrNumeric_numeric)
124 *element->value.complex->list[src->minor-1]->u.numeric;
126 else if (element->value.complex->list[src->minor]->which ==
127 Z_StringOrNumeric_string)
133 element->value.complex->list[src->minor-1]->u.string;
147 static int attr_find(AttrType *src, oid_value *attributeSetP)
149 return attr_find_ex(src, attributeSetP, 0);
152 static void attr_init(AttrType *src, Z_AttributesPlusTerm *zapt,
175 void zebra_term_untrans(ZebraHandle zh, int reg_type,
176 char *dst, const char *src)
181 const char *cp = zebra_maps_output(zh->reg->zebra_maps,
183 if (!cp && len < IT_MAX_WORD-1)
186 while (*cp && len < IT_MAX_WORD-1)
192 static void add_isam_p(const char *name, const char *info,
197 log_level_rpn = yaz_log_module_level("rpn");
200 if (p->isam_p_indx == p->isam_p_size)
202 ISAM_P *new_isam_p_buf;
206 p->isam_p_size = 2*p->isam_p_size + 100;
207 new_isam_p_buf = (ISAM_P *) xmalloc(sizeof(*new_isam_p_buf) *
211 memcpy(new_isam_p_buf, p->isam_p_buf,
212 p->isam_p_indx * sizeof(*p->isam_p_buf));
213 xfree(p->isam_p_buf);
215 p->isam_p_buf = new_isam_p_buf;
218 new_term_no = (int *) xmalloc(sizeof(*new_term_no) * p->isam_p_size);
221 memcpy(new_term_no, p->isam_p_buf,
222 p->isam_p_indx * sizeof(*p->term_no));
225 p->term_no = new_term_no;
228 assert(*info == sizeof(*p->isam_p_buf));
229 memcpy(p->isam_p_buf + p->isam_p_indx, info+1, sizeof(*p->isam_p_buf));
236 char term_tmp[IT_MAX_WORD];
238 int len = key_SU_decode (&su_code, name);
240 zebra_term_untrans (p->zh, p->reg_type, term_tmp, name+len+1);
241 yaz_log(log_level_rpn, "grep: %d %c %s", su_code, name[len], term_tmp);
242 zebraExplain_lookup_ord (p->zh->reg->zei,
243 su_code, &db, &set, &use);
244 yaz_log(log_level_rpn, "grep: set=%d use=%d db=%s", set, use, db);
246 resultSetAddTerm(p->zh, p->termset, name[len], db,
253 static int grep_handle(char *name, const char *info, void *p)
255 add_isam_p(name, info, (struct grep_info *) p);
259 static int term_pre(ZebraMaps zebra_maps, int reg_type, const char **src,
260 const char *ct1, const char *ct2, int first)
262 const char *s1, *s0 = *src;
265 /* skip white space */
268 if (ct1 && strchr(ct1, *s0))
270 if (ct2 && strchr(ct2, *s0))
273 map = zebra_maps_input(zebra_maps, reg_type, &s1, strlen(s1), first);
274 if (**map != *CHR_SPACE)
283 static void esc_str(char *out_buf, int out_size,
284 const char *in_buf, int in_size)
290 assert(out_size > 20);
292 for (k = 0; k<in_size; k++)
294 int c = in_buf[k] & 0xff;
296 if (c < 32 || c > 126)
300 sprintf(out_buf +strlen(out_buf), "%02X:%c ", c, pc);
301 if (strlen(out_buf) > out_size-20)
303 strcat(out_buf, "..");
309 #define REGEX_CHARS " []()|.*+?!"
311 /* term_100: handle term, where trunc = none(no operators at all) */
312 static int term_100(ZebraMaps zebra_maps, int reg_type,
313 const char **src, char *dst, int space_split,
321 const char *space_start = 0;
322 const char *space_end = 0;
324 if (!term_pre(zebra_maps, reg_type, src, NULL, NULL, !space_split))
331 map = zebra_maps_search(zebra_maps, reg_type, &s0, strlen(s0),
335 if (**map == *CHR_SPACE)
338 else /* complete subfield only. */
340 if (**map == *CHR_SPACE)
341 { /* save space mapping for later .. */
346 else if (space_start)
347 { /* reload last space */
348 while (space_start < space_end)
350 if (strchr(REGEX_CHARS, *space_start))
352 dst_term[j++] = *space_start;
353 dst[i++] = *space_start++;
356 space_start = space_end = 0;
359 /* add non-space char */
360 memcpy(dst_term+j, s1, s0 - s1);
366 if (strchr(REGEX_CHARS, *s1))
374 esc_str(tmpbuf, sizeof(tmpbuf), map[0], strlen(map[0]));
376 strcpy(dst + i, map[0]);
386 /* term_101: handle term, where trunc = Process # */
387 static int term_101(ZebraMaps zebra_maps, int reg_type,
388 const char **src, char *dst, int space_split,
396 if (!term_pre(zebra_maps, reg_type, src, "#", "#", !space_split))
405 dst_term[j++] = *s0++;
411 map = zebra_maps_search(zebra_maps, reg_type, &s0, strlen(s0),
413 if (space_split && **map == *CHR_SPACE)
416 /* add non-space char */
417 memcpy(dst_term+j, s1, s0 - s1);
423 if (strchr(REGEX_CHARS, *s1))
431 esc_str(tmpbuf, sizeof(tmpbuf), map[0], strlen(map[0]));
433 strcpy(dst + i, map[0]);
439 dst_term[j++] = '\0';
444 /* term_103: handle term, where trunc = re-2 (regular expressions) */
445 static int term_103(ZebraMaps zebra_maps, int reg_type, const char **src,
446 char *dst, int *errors, int space_split,
454 if (!term_pre(zebra_maps, reg_type, src, "^\\()[].*+?|", "(", !space_split))
457 if (errors && *s0 == '+' && s0[1] && s0[2] == '+' && s0[3] &&
458 isdigit(((const unsigned char *)s0)[1]))
460 *errors = s0[1] - '0';
467 if (strchr("^\\()[].*+?|-", *s0))
476 map = zebra_maps_search(zebra_maps, reg_type, &s0, strlen(s0),
478 if (space_split && **map == *CHR_SPACE)
481 /* add non-space char */
482 memcpy(dst_term+j, s1, s0 - s1);
488 if (strchr(REGEX_CHARS, *s1))
496 esc_str(tmpbuf, sizeof(tmpbuf), map[0], strlen(map[0]));
498 strcpy(dst + i, map[0]);
510 /* term_103: handle term, where trunc = re-1 (regular expressions) */
511 static int term_102(ZebraMaps zebra_maps, int reg_type, const char **src,
512 char *dst, int space_split, char *dst_term)
514 return term_103(zebra_maps, reg_type, src, dst, NULL, space_split,
519 /* term_104: handle term, where trunc = Process # and ! */
520 static int term_104(ZebraMaps zebra_maps, int reg_type,
521 const char **src, char *dst, int space_split,
529 if (!term_pre(zebra_maps, reg_type, src, "?*#", "?*#", !space_split))
536 dst_term[j++] = *s0++;
537 if (*s0 >= '0' && *s0 <= '9')
540 while (*s0 >= '0' && *s0 <= '9')
542 limit = limit * 10 + (*s0 - '0');
543 dst_term[j++] = *s0++;
563 dst_term[j++] = *s0++;
568 dst_term[j++] = *s0++;
574 map = zebra_maps_search(zebra_maps, reg_type, &s0, strlen(s0),
576 if (space_split && **map == *CHR_SPACE)
579 /* add non-space char */
580 memcpy(dst_term+j, s1, s0 - s1);
586 if (strchr(REGEX_CHARS, *s1))
594 esc_str(tmpbuf, sizeof(tmpbuf), map[0], strlen(map[0]));
596 strcpy(dst + i, map[0]);
602 dst_term[j++] = '\0';
607 /* term_105/106: handle term, where trunc = Process * and ! and right trunc */
608 static int term_105(ZebraMaps zebra_maps, int reg_type,
609 const char **src, char *dst, int space_split,
610 char *dst_term, int right_truncate)
617 if (!term_pre(zebra_maps, reg_type, src, "*!", "*!", !space_split))
626 dst_term[j++] = *s0++;
631 dst_term[j++] = *s0++;
637 map = zebra_maps_search(zebra_maps, reg_type, &s0, strlen(s0),
639 if (space_split && **map == *CHR_SPACE)
642 /* add non-space char */
643 memcpy(dst_term+j, s1, s0 - s1);
649 if (strchr(REGEX_CHARS, *s1))
657 esc_str(tmpbuf, sizeof(tmpbuf), map[0], strlen(map[0]));
659 strcpy(dst + i, map[0]);
671 dst_term[j++] = '\0';
677 /* gen_regular_rel - generate regular expression from relation
678 * val: border value (inclusive)
679 * islt: 1 if <=; 0 if >=.
681 static void gen_regular_rel(char *dst, int val, int islt)
688 yaz_log(YLOG_DEBUG, "gen_regular_rel. val=%d, islt=%d", val, islt);
692 strcpy(dst, "(-[0-9]+|(");
700 strcpy(dst, "([0-9]+|-(");
712 sprintf(numstr, "%d", val);
713 for (w = strlen(numstr); --w >= 0; pos++)
732 strcpy(dst + dst_p, numstr);
733 dst_p = strlen(dst) - pos - 1;
761 for (i = 0; i<pos; i++)
774 /* match everything less than 10^(pos-1) */
776 for (i = 1; i<pos; i++)
777 strcat(dst, "[0-9]?");
781 /* match everything greater than 10^pos */
782 for (i = 0; i <= pos; i++)
783 strcat(dst, "[0-9]");
784 strcat(dst, "[0-9]*");
789 void string_rel_add_char(char **term_p, const char *src, int *indx)
791 if (src[*indx] == '\\')
792 *(*term_p)++ = src[(*indx)++];
793 *(*term_p)++ = src[(*indx)++];
797 * > abc ([b-].*|a[c-].*|ab[d-].*|abc.+)
798 * ([^-a].*|a[^-b].*ab[^-c].*|abc.+)
799 * >= abc ([b-].*|a[c-].*|ab[c-].*)
800 * ([^-a].*|a[^-b].*|ab[c-].*)
801 * < abc ([-0].*|a[-a].*|ab[-b].*)
802 * ([^a-].*|a[^b-].*|ab[^c-].*)
803 * <= abc ([-0].*|a[-a].*|ab[-b].*|abc)
804 * ([^a-].*|a[^b-].*|ab[^c-].*|abc)
806 static int string_relation(ZebraHandle zh, Z_AttributesPlusTerm *zapt,
807 const char **term_sub, char *term_dict,
808 oid_value attributeSet,
809 int reg_type, int space_split, char *term_dst,
815 char *term_tmp = term_dict + strlen(term_dict);
816 char term_component[2*IT_MAX_WORD+20];
818 attr_init(&relation, zapt, 2);
819 relation_value = attr_find(&relation, NULL);
822 yaz_log(YLOG_DEBUG, "string relation value=%d", relation_value);
823 switch (relation_value)
826 if (!term_100(zh->reg->zebra_maps, reg_type,
827 term_sub, term_component,
828 space_split, term_dst))
830 yaz_log(log_level_rpn, "Relation <");
833 for (i = 0; term_component[i]; )
840 string_rel_add_char(&term_tmp, term_component, &j);
845 string_rel_add_char(&term_tmp, term_component, &i);
852 if ((term_tmp - term_dict) > IT_MAX_WORD)
859 if (!term_100(zh->reg->zebra_maps, reg_type,
860 term_sub, term_component,
861 space_split, term_dst))
863 yaz_log(log_level_rpn, "Relation <=");
866 for (i = 0; term_component[i]; )
871 string_rel_add_char(&term_tmp, term_component, &j);
875 string_rel_add_char(&term_tmp, term_component, &i);
884 if ((term_tmp - term_dict) > IT_MAX_WORD)
887 for (i = 0; term_component[i]; )
888 string_rel_add_char(&term_tmp, term_component, &i);
893 if (!term_100 (zh->reg->zebra_maps, reg_type,
894 term_sub, term_component, space_split, term_dst))
896 yaz_log(log_level_rpn, "Relation >");
899 for (i = 0; term_component[i];)
904 string_rel_add_char(&term_tmp, term_component, &j);
909 string_rel_add_char(&term_tmp, term_component, &i);
917 if ((term_tmp - term_dict) > IT_MAX_WORD)
920 for (i = 0; term_component[i];)
921 string_rel_add_char(&term_tmp, term_component, &i);
928 if (!term_100(zh->reg->zebra_maps, reg_type, term_sub,
929 term_component, space_split, term_dst))
931 yaz_log(log_level_rpn, "Relation >=");
934 for (i = 0; term_component[i];)
941 string_rel_add_char(&term_tmp, term_component, &j);
944 if (term_component[i+1])
948 string_rel_add_char(&term_tmp, term_component, &i);
952 string_rel_add_char(&term_tmp, term_component, &i);
959 if ((term_tmp - term_dict) > IT_MAX_WORD)
968 yaz_log(log_level_rpn, "Relation =");
969 if (!term_100(zh->reg->zebra_maps, reg_type, term_sub,
970 term_component, space_split, term_dst))
972 strcat(term_tmp, "(");
973 strcat(term_tmp, term_component);
974 strcat(term_tmp, ")");
977 *error_code = YAZ_BIB1_UNSUPP_RELATION_ATTRIBUTE;
983 static ZEBRA_RES string_term(ZebraHandle zh, Z_AttributesPlusTerm *zapt,
984 const char **term_sub,
985 oid_value attributeSet, NMEM stream,
986 struct grep_info *grep_info,
987 int reg_type, int complete_flag,
988 int num_bases, char **basenames,
989 char *term_dst, int xpath_use,
990 struct ord_list **ol);
992 static ZEBRA_RES term_trunc(ZebraHandle zh,
993 Z_AttributesPlusTerm *zapt,
994 const char **term_sub,
995 oid_value attributeSet, NMEM stream,
996 struct grep_info *grep_info,
997 int reg_type, int complete_flag,
998 int num_bases, char **basenames,
1000 const char *rank_type, int xpath_use,
1003 struct rset_key_control *kc)
1006 struct ord_list *ol;
1008 grep_info->isam_p_indx = 0;
1009 res = string_term(zh, zapt, term_sub, attributeSet, stream, grep_info,
1010 reg_type, complete_flag, num_bases, basenames,
1011 term_dst, xpath_use, &ol);
1012 if (res != ZEBRA_OK)
1014 if (!*term_sub) /* no more terms ? */
1016 yaz_log(log_level_rpn, "term: %s", term_dst);
1017 *rset = rset_trunc(zh, grep_info->isam_p_buf,
1018 grep_info->isam_p_indx, term_dst,
1019 strlen(term_dst), rank_type, 1 /* preserve pos */,
1020 zapt->term->which, rset_nmem,
1021 kc, kc->scope, ol, reg_type);
1027 static char *nmem_strdup_i(NMEM nmem, int v)
1030 sprintf(val_str, "%d", v);
1031 return nmem_strdup(nmem, val_str);
1034 static ZEBRA_RES string_term(ZebraHandle zh, Z_AttributesPlusTerm *zapt,
1035 const char **term_sub,
1036 oid_value attributeSet, NMEM stream,
1037 struct grep_info *grep_info,
1038 int reg_type, int complete_flag,
1039 int num_bases, char **basenames,
1040 char *term_dst, int xpath_use,
1041 struct ord_list **ol)
1043 char term_dict[2*IT_MAX_WORD+4000];
1045 AttrType truncation;
1046 int truncation_value;
1049 const char *use_string = 0;
1050 oid_value curAttributeSet = attributeSet;
1052 struct rpn_char_map_info rcmi;
1053 int space_split = complete_flag ? 0 : 1;
1055 int bases_ok = 0; /* no of databases with OK attribute */
1056 int errCode = 0; /* err code (if any is not OK) */
1057 char *errString = 0; /* addinfo */
1060 *ol = ord_list_create(stream);
1062 rpn_char_map_prepare (zh->reg, reg_type, &rcmi);
1063 attr_init(&use, zapt, 1);
1064 use_value = attr_find_ex(&use, &curAttributeSet, &use_string);
1065 yaz_log(log_level_rpn, "string_term, use value %d", use_value);
1066 attr_init(&truncation, zapt, 5);
1067 truncation_value = attr_find(&truncation, NULL);
1068 yaz_log(log_level_rpn, "truncation value %d", truncation_value);
1070 if (use_value == -1) /* no attribute - assumy "any" */
1072 for (base_no = 0; base_no < num_bases; base_no++)
1076 int regex_range = 0;
1079 data1_local_attribute id_xpath_attr;
1080 data1_local_attribute *local_attr;
1081 int max_pos, prefix_len = 0;
1086 if (zebraExplain_curDatabase (zh->reg->zei, basenames[base_no]))
1088 zebra_setError(zh, YAZ_BIB1_DATABASE_UNAVAILABLE,
1089 basenames[base_no]);
1092 if (xpath_use > 0 && use_value == -2)
1094 /* xpath mode and we have a string attribute */
1095 attp.local_attributes = &id_xpath_attr;
1096 attp.attset_ordinal = VAL_IDXPATH;
1097 id_xpath_attr.next = 0;
1099 use_value = xpath_use; /* xpath_use as use-attribute now */
1100 id_xpath_attr.local = use_value;
1102 else if (curAttributeSet == VAL_IDXPATH && use_value >= 0)
1104 /* X-Path attribute, use numeric value directly */
1105 attp.local_attributes = &id_xpath_attr;
1106 attp.attset_ordinal = VAL_IDXPATH;
1107 id_xpath_attr.next = 0;
1108 id_xpath_attr.local = use_value;
1110 else if (use_string &&
1111 (ord = zebraExplain_lookup_attr_str(zh->reg->zei,
1114 /* we have a match for a raw string attribute */
1119 term_dict[prefix_len++] = '|';
1121 term_dict[prefix_len++] = '(';
1123 ord_len = key_SU_encode (ord, ord_buf);
1124 for (i = 0; i<ord_len; i++)
1126 term_dict[prefix_len++] = 1;
1127 term_dict[prefix_len++] = ord_buf[i];
1129 attp.local_attributes = 0; /* no more attributes */
1130 *ol = ord_list_append(stream, *ol, ord);
1134 /* lookup in the .att files . Allow string as well */
1135 if ((r = att_getentbyatt (zh, &attp, curAttributeSet, use_value,
1138 yaz_log(YLOG_DEBUG, "att_getentbyatt fail. set=%d use=%d r=%d",
1139 curAttributeSet, use_value, r);
1142 /* set was found, but value wasn't defined */
1143 errCode = YAZ_BIB1_UNSUPP_USE_ATTRIBUTE;
1145 errString = nmem_strdup(stream, use_string);
1147 errString = nmem_strdup_i (stream, use_value);
1152 struct oident oident;
1154 oident.proto = PROTO_Z3950;
1155 oident.oclass = CLASS_ATTSET;
1156 oident.value = curAttributeSet;
1157 oid_ent_to_oid (&oident, oid);
1159 errCode = YAZ_BIB1_UNSUPP_ATTRIBUTE_SET;
1160 errString = nmem_strdup(stream, oident.desc);
1165 for (local_attr = attp.local_attributes; local_attr;
1166 local_attr = local_attr->next)
1171 ord = zebraExplain_lookup_attr_su(zh->reg->zei,
1172 attp.attset_ordinal,
1176 *ol = ord_list_append(stream, *ol, ord);
1178 term_dict[prefix_len++] = '|';
1180 term_dict[prefix_len++] = '(';
1182 ord_len = key_SU_encode (ord, ord_buf);
1183 for (i = 0; i<ord_len; i++)
1185 term_dict[prefix_len++] = 1;
1186 term_dict[prefix_len++] = ord_buf[i];
1193 term_dict[prefix_len++] = ')';
1194 term_dict[prefix_len++] = 1;
1195 term_dict[prefix_len++] = reg_type;
1196 yaz_log(log_level_rpn, "reg_type = %d", term_dict[prefix_len-1]);
1197 term_dict[prefix_len] = '\0';
1199 switch (truncation_value)
1201 case -1: /* not specified */
1202 case 100: /* do not truncate */
1203 if (!string_relation (zh, zapt, &termp, term_dict,
1205 reg_type, space_split, term_dst,
1210 zebra_setError(zh, relation_error, 0);
1217 case 1: /* right truncation */
1218 term_dict[j++] = '(';
1219 if (!term_100(zh->reg->zebra_maps, reg_type,
1220 &termp, term_dict + j, space_split, term_dst))
1225 strcat(term_dict, ".*)");
1227 case 2: /* keft truncation */
1228 term_dict[j++] = '('; term_dict[j++] = '.'; term_dict[j++] = '*';
1229 if (!term_100(zh->reg->zebra_maps, reg_type,
1230 &termp, term_dict + j, space_split, term_dst))
1235 strcat(term_dict, ")");
1237 case 3: /* left&right truncation */
1238 term_dict[j++] = '('; term_dict[j++] = '.'; term_dict[j++] = '*';
1239 if (!term_100(zh->reg->zebra_maps, reg_type,
1240 &termp, term_dict + j, space_split, term_dst))
1245 strcat(term_dict, ".*)");
1247 case 101: /* process # in term */
1248 term_dict[j++] = '(';
1249 if (!term_101(zh->reg->zebra_maps, reg_type,
1250 &termp, term_dict + j, space_split, term_dst))
1255 strcat(term_dict, ")");
1257 case 102: /* Regexp-1 */
1258 term_dict[j++] = '(';
1259 if (!term_102(zh->reg->zebra_maps, reg_type,
1260 &termp, term_dict + j, space_split, term_dst))
1265 strcat(term_dict, ")");
1267 case 103: /* Regexp-2 */
1269 term_dict[j++] = '(';
1271 if (!term_103(zh->reg->zebra_maps, reg_type,
1272 &termp, term_dict + j, ®ex_range,
1273 space_split, term_dst))
1278 strcat(term_dict, ")");
1280 case 104: /* process # and ! in term */
1281 term_dict[j++] = '(';
1282 if (!term_104(zh->reg->zebra_maps, reg_type,
1283 &termp, term_dict + j, space_split, term_dst))
1288 strcat(term_dict, ")");
1290 case 105: /* process * and ! in term */
1291 term_dict[j++] = '(';
1292 if (!term_105(zh->reg->zebra_maps, reg_type,
1293 &termp, term_dict + j, space_split, term_dst, 1))
1298 strcat(term_dict, ")");
1300 case 106: /* process * and ! in term */
1301 term_dict[j++] = '(';
1302 if (!term_105(zh->reg->zebra_maps, reg_type,
1303 &termp, term_dict + j, space_split, term_dst, 0))
1308 strcat(term_dict, ")");
1311 zebra_setError_zint(zh,
1312 YAZ_BIB1_UNSUPP_TRUNCATION_ATTRIBUTE,
1319 const char *input = term_dict + prefix_len;
1320 esc_str(buf, sizeof(buf), input, strlen(input));
1324 yaz_log(log_level_rpn, "dict_lookup_grep: %s", term_dict+prefix_len);
1325 r = dict_lookup_grep(zh->reg->dict, term_dict, regex_range,
1326 grep_info, &max_pos, init_pos,
1329 yaz_log(YLOG_WARN, "dict_lookup_grep fail %d", r);
1334 zebra_setError(zh, errCode, errString);
1338 yaz_log(YLOG_DEBUG, "%d positions", grep_info->isam_p_indx);
1343 /* convert APT search term to UTF8 */
1344 static ZEBRA_RES zapt_term_to_utf8(ZebraHandle zh, Z_AttributesPlusTerm *zapt,
1348 Z_Term *term = zapt->term;
1350 switch (term->which)
1352 case Z_Term_general:
1353 if (zh->iconv_to_utf8 != 0)
1355 char *inbuf = term->u.general->buf;
1356 size_t inleft = term->u.general->len;
1357 char *outbuf = termz;
1358 size_t outleft = IT_MAX_WORD-1;
1361 ret = yaz_iconv(zh->iconv_to_utf8, &inbuf, &inleft,
1363 if (ret == (size_t)(-1))
1365 ret = yaz_iconv(zh->iconv_to_utf8, 0, 0, 0, 0);
1368 YAZ_BIB1_QUERY_TERM_INCLUDES_CHARS_THAT_DO_NOT_TRANSLATE_INTO_,
1376 sizez = term->u.general->len;
1377 if (sizez > IT_MAX_WORD-1)
1378 sizez = IT_MAX_WORD-1;
1379 memcpy (termz, term->u.general->buf, sizez);
1380 termz[sizez] = '\0';
1383 case Z_Term_characterString:
1384 sizez = strlen(term->u.characterString);
1385 if (sizez > IT_MAX_WORD-1)
1386 sizez = IT_MAX_WORD-1;
1387 memcpy (termz, term->u.characterString, sizez);
1388 termz[sizez] = '\0';
1391 zebra_setError(zh, YAZ_BIB1_UNSUPP_CODED_VALUE_FOR_TERM, 0);
1397 /* convert APT SCAN term to internal cmap */
1398 static ZEBRA_RES trans_scan_term(ZebraHandle zh, Z_AttributesPlusTerm *zapt,
1399 char *termz, int reg_type)
1401 char termz0[IT_MAX_WORD];
1403 if (zapt_term_to_utf8(zh, zapt, termz0) == ZEBRA_FAIL)
1404 return ZEBRA_FAIL; /* error */
1408 const char *cp = (const char *) termz0;
1409 const char *cp_end = cp + strlen(cp);
1412 const char *space_map = NULL;
1415 while ((len = (cp_end - cp)) > 0)
1417 map = zebra_maps_input(zh->reg->zebra_maps, reg_type, &cp, len, 0);
1418 if (**map == *CHR_SPACE)
1423 for (src = space_map; *src; src++)
1426 for (src = *map; *src; src++)
1435 char *normalize_term(ZebraHandle zh, Z_AttributesPlusTerm *zapt,
1436 const char *termz, NMEM stream, unsigned reg_id)
1439 AttrType truncation;
1440 int truncation_value;
1443 attr_init(&truncation, zapt, 5);
1444 truncation_value = attr_find(&truncation, NULL);
1446 switch (truncation_value)
1466 wrbuf = zebra_replace(zh->reg->zebra_maps, reg_id, ex_list,
1467 termz, strlen(termz));
1469 return nmem_strdup(stream, termz);
1472 char *buf = (char*) nmem_malloc(stream, wrbuf_len(wrbuf)+1);
1473 memcpy (buf, wrbuf_buf(wrbuf), wrbuf_len(wrbuf));
1474 buf[wrbuf_len(wrbuf)] = '\0';
1479 static void grep_info_delete(struct grep_info *grep_info)
1482 xfree(grep_info->term_no);
1484 xfree(grep_info->isam_p_buf);
1487 static ZEBRA_RES grep_info_prepare(ZebraHandle zh,
1488 Z_AttributesPlusTerm *zapt,
1489 struct grep_info *grep_info,
1493 int termset_value_numeric;
1494 const char *termset_value_string;
1497 grep_info->term_no = 0;
1499 grep_info->isam_p_size = 0;
1500 grep_info->isam_p_buf = NULL;
1502 grep_info->reg_type = reg_type;
1503 grep_info->termset = 0;
1507 attr_init(&termset, zapt, 8);
1508 termset_value_numeric =
1509 attr_find_ex(&termset, NULL, &termset_value_string);
1510 if (termset_value_numeric != -1)
1513 const char *termset_name = 0;
1514 if (termset_value_numeric != -2)
1517 sprintf(resname, "%d", termset_value_numeric);
1518 termset_name = resname;
1521 termset_name = termset_value_string;
1522 yaz_log(log_level_rpn, "creating termset set %s", termset_name);
1523 grep_info->termset = resultSetAdd(zh, termset_name, 1);
1524 if (!grep_info->termset)
1526 zebra_setError(zh, YAZ_BIB1_ILLEGAL_RESULT_SET_NAME, termset_name);
1534 \brief Create result set(s) for list of terms
1535 \param zh Zebra Handle
1536 \param termz_org term as used in query but converted to UTF-8
1537 \param attributeSet default attribute set
1538 \param stream memory for result
1539 \param reg_type register type ('w', 'p',..)
1540 \param complete_flag whether it's phrases or not
1541 \param rank_type term flags for ranking
1542 \param xpath_use use attribute for X-Path (-1 for no X-path)
1543 \param num_bases number of databases
1544 \param basenames array of databases
1545 \param rset_mem memory for result sets
1546 \param result_sets output result set for each term in list (output)
1547 \param number number of output result sets
1548 \param kc rset key control to be used for created result sets
1550 static ZEBRA_RES term_list_trunc(ZebraHandle zh,
1551 Z_AttributesPlusTerm *zapt,
1552 const char *termz_org,
1553 oid_value attributeSet,
1555 int reg_type, int complete_flag,
1556 const char *rank_type, int xpath_use,
1557 int num_bases, char **basenames,
1559 RSET **result_sets, int *num_result_sets,
1560 struct rset_key_control *kc)
1562 char term_dst[IT_MAX_WORD+1];
1563 struct grep_info grep_info;
1564 char *termz = normalize_term(zh, zapt, termz_org, stream, reg_type);
1565 const char *termp = termz;
1568 *num_result_sets = 0;
1570 if (grep_info_prepare(zh, zapt, &grep_info, reg_type) == ZEBRA_FAIL)
1576 if (alloc_sets == *num_result_sets)
1579 RSET *rnew = (RSET *) nmem_malloc(stream, (alloc_sets+add) *
1582 memcpy(rnew, *result_sets, alloc_sets * sizeof(*rnew));
1583 alloc_sets = alloc_sets + add;
1584 *result_sets = rnew;
1586 res = term_trunc(zh, zapt, &termp, attributeSet,
1588 reg_type, complete_flag,
1589 num_bases, basenames,
1590 term_dst, rank_type,
1591 xpath_use, rset_nmem,
1592 &(*result_sets)[*num_result_sets],
1594 if (res != ZEBRA_OK)
1597 for (i = 0; i < *num_result_sets; i++)
1598 rset_delete((*result_sets)[i]);
1599 grep_info_delete (&grep_info);
1602 if ((*result_sets)[*num_result_sets] == 0)
1604 (*num_result_sets)++;
1606 grep_info_delete(&grep_info);
1610 static ZEBRA_RES rpn_search_APT_phrase(ZebraHandle zh,
1611 Z_AttributesPlusTerm *zapt,
1612 const char *termz_org,
1613 oid_value attributeSet,
1615 int reg_type, int complete_flag,
1616 const char *rank_type, int xpath_use,
1617 int num_bases, char **basenames,
1620 struct rset_key_control *kc)
1622 RSET *result_sets = 0;
1623 int num_result_sets = 0;
1625 term_list_trunc(zh, zapt, termz_org, attributeSet,
1626 stream, reg_type, complete_flag,
1627 rank_type, xpath_use,
1628 num_bases, basenames,
1630 &result_sets, &num_result_sets, kc);
1631 if (res != ZEBRA_OK)
1633 if (num_result_sets == 0)
1634 *rset = rsnull_create (rset_nmem, kc, 0);
1635 else if (num_result_sets == 1)
1636 *rset = result_sets[0];
1638 *rset = rsprox_create(rset_nmem, kc, kc->scope,
1639 num_result_sets, result_sets,
1640 1 /* ordered */, 0 /* exclusion */,
1641 3 /* relation */, 1 /* distance */);
1647 static ZEBRA_RES rpn_search_APT_or_list(ZebraHandle zh,
1648 Z_AttributesPlusTerm *zapt,
1649 const char *termz_org,
1650 oid_value attributeSet,
1652 int reg_type, int complete_flag,
1653 const char *rank_type,
1655 int num_bases, char **basenames,
1658 struct rset_key_control *kc)
1660 RSET *result_sets = 0;
1661 int num_result_sets = 0;
1663 term_list_trunc(zh, zapt, termz_org, attributeSet,
1664 stream, reg_type, complete_flag,
1665 rank_type, xpath_use,
1666 num_bases, basenames,
1668 &result_sets, &num_result_sets, kc);
1669 if (res != ZEBRA_OK)
1671 if (num_result_sets == 0)
1672 *rset = rsnull_create (rset_nmem, kc, 0);
1673 else if (num_result_sets == 1)
1674 *rset = result_sets[0];
1676 *rset = rsmulti_or_create(rset_nmem, kc, kc->scope, 0 /* termid */,
1677 num_result_sets, result_sets);
1683 static ZEBRA_RES rpn_search_APT_and_list(ZebraHandle zh,
1684 Z_AttributesPlusTerm *zapt,
1685 const char *termz_org,
1686 oid_value attributeSet,
1688 int reg_type, int complete_flag,
1689 const char *rank_type,
1691 int num_bases, char **basenames,
1694 struct rset_key_control *kc)
1696 RSET *result_sets = 0;
1697 int num_result_sets = 0;
1699 term_list_trunc(zh, zapt, termz_org, attributeSet,
1700 stream, reg_type, complete_flag,
1701 rank_type, xpath_use,
1702 num_bases, basenames,
1704 &result_sets, &num_result_sets,
1706 if (res != ZEBRA_OK)
1708 if (num_result_sets == 0)
1709 *rset = rsnull_create (rset_nmem, kc, 0);
1710 else if (num_result_sets == 1)
1711 *rset = result_sets[0];
1713 *rset = rsmulti_and_create(rset_nmem, kc, kc->scope,
1714 num_result_sets, result_sets);
1720 static int numeric_relation(ZebraHandle zh, Z_AttributesPlusTerm *zapt,
1721 const char **term_sub,
1723 oid_value attributeSet,
1724 struct grep_info *grep_info,
1734 char *term_tmp = term_dict + strlen(term_dict);
1737 attr_init(&relation, zapt, 2);
1738 relation_value = attr_find(&relation, NULL);
1740 yaz_log(log_level_rpn, "numeric relation value=%d", relation_value);
1742 if (!term_100(zh->reg->zebra_maps, reg_type, term_sub, term_tmp, 1,
1745 term_value = atoi (term_tmp);
1746 switch (relation_value)
1749 yaz_log(log_level_rpn, "Relation <");
1750 gen_regular_rel(term_tmp, term_value-1, 1);
1753 yaz_log(log_level_rpn, "Relation <=");
1754 gen_regular_rel(term_tmp, term_value, 1);
1757 yaz_log(log_level_rpn, "Relation >=");
1758 gen_regular_rel(term_tmp, term_value, 0);
1761 yaz_log(log_level_rpn, "Relation >");
1762 gen_regular_rel(term_tmp, term_value+1, 0);
1766 yaz_log(log_level_rpn, "Relation =");
1767 sprintf(term_tmp, "(0*%d)", term_value);
1770 *error_code = YAZ_BIB1_UNSUPP_RELATION_ATTRIBUTE;
1773 yaz_log(log_level_rpn, "dict_lookup_grep: %s", term_tmp);
1774 r = dict_lookup_grep(zh->reg->dict, term_dict, 0, grep_info, max_pos,
1777 yaz_log(YLOG_WARN, "dict_lookup_grep fail, rel = gt: %d", r);
1778 yaz_log(log_level_rpn, "%d positions", grep_info->isam_p_indx);
1782 static ZEBRA_RES numeric_term(ZebraHandle zh, Z_AttributesPlusTerm *zapt,
1783 const char **term_sub,
1784 oid_value attributeSet,
1785 struct grep_info *grep_info,
1786 int reg_type, int complete_flag,
1787 int num_bases, char **basenames,
1788 char *term_dst, int xpath_use, NMEM stream)
1790 char term_dict[2*IT_MAX_WORD+2];
1794 const char *use_string = 0;
1795 oid_value curAttributeSet = attributeSet;
1797 struct rpn_char_map_info rcmi;
1799 int bases_ok = 0; /* no of databases with OK attribute */
1800 int errCode = 0; /* err code (if any is not OK) */
1801 char *errString = 0; /* addinfo */
1803 rpn_char_map_prepare (zh->reg, reg_type, &rcmi);
1804 attr_init(&use, zapt, 1);
1805 use_value = attr_find_ex(&use, &curAttributeSet, &use_string);
1807 if (use_value == -1)
1810 for (base_no = 0; base_no < num_bases; base_no++)
1813 data1_local_attribute id_xpath_attr;
1814 data1_local_attribute *local_attr;
1815 int max_pos, prefix_len = 0;
1816 int relation_error = 0;
1819 if (use_value == -2) /* string attribute (assume IDXPATH/any) */
1821 use_value = xpath_use;
1822 attp.local_attributes = &id_xpath_attr;
1823 attp.attset_ordinal = VAL_IDXPATH;
1824 id_xpath_attr.next = 0;
1825 id_xpath_attr.local = use_value;
1827 else if (curAttributeSet == VAL_IDXPATH)
1829 attp.local_attributes = &id_xpath_attr;
1830 attp.attset_ordinal = VAL_IDXPATH;
1831 id_xpath_attr.next = 0;
1832 id_xpath_attr.local = use_value;
1836 if ((r = att_getentbyatt (zh, &attp, curAttributeSet, use_value,
1839 yaz_log(YLOG_DEBUG, "att_getentbyatt fail. set=%d use=%d r=%d",
1840 curAttributeSet, use_value, r);
1843 errCode = YAZ_BIB1_UNSUPP_USE_ATTRIBUTE;
1845 errString = nmem_strdup(stream, use_string);
1847 errString = nmem_strdup_i (stream, use_value);
1850 errCode = YAZ_BIB1_UNSUPP_ATTRIBUTE_SET;
1854 if (zebraExplain_curDatabase (zh->reg->zei, basenames[base_no]))
1856 zebra_setError(zh, YAZ_BIB1_DATABASE_UNAVAILABLE,
1857 basenames[base_no]);
1860 for (local_attr = attp.local_attributes; local_attr;
1861 local_attr = local_attr->next)
1867 ord = zebraExplain_lookup_attr_su(zh->reg->zei,
1868 attp.attset_ordinal,
1873 term_dict[prefix_len++] = '|';
1875 term_dict[prefix_len++] = '(';
1877 ord_len = key_SU_encode (ord, ord_buf);
1878 for (i = 0; i<ord_len; i++)
1880 term_dict[prefix_len++] = 1;
1881 term_dict[prefix_len++] = ord_buf[i];
1886 zebra_setError_zint(zh, YAZ_BIB1_UNSUPP_USE_ATTRIBUTE, use_value);
1890 term_dict[prefix_len++] = ')';
1891 term_dict[prefix_len++] = 1;
1892 term_dict[prefix_len++] = reg_type;
1893 yaz_log(YLOG_DEBUG, "reg_type = %d", term_dict[prefix_len-1]);
1894 term_dict[prefix_len] = '\0';
1895 if (!numeric_relation(zh, zapt, &termp, term_dict,
1896 attributeSet, grep_info, &max_pos, reg_type,
1897 term_dst, &relation_error))
1901 zebra_setError(zh, relation_error, 0);
1910 zebra_setError(zh, errCode, errString);
1914 yaz_log(YLOG_DEBUG, "%d positions", grep_info->isam_p_indx);
1918 static ZEBRA_RES rpn_search_APT_numeric(ZebraHandle zh,
1919 Z_AttributesPlusTerm *zapt,
1921 oid_value attributeSet,
1923 int reg_type, int complete_flag,
1924 const char *rank_type, int xpath_use,
1925 int num_bases, char **basenames,
1928 struct rset_key_control *kc)
1930 char term_dst[IT_MAX_WORD+1];
1931 const char *termp = termz;
1932 RSET *result_sets = 0;
1933 int num_result_sets = 0;
1935 struct grep_info grep_info;
1938 yaz_log(log_level_rpn, "APT_numeric t='%s'", termz);
1939 if (grep_info_prepare(zh, zapt, &grep_info, reg_type) == ZEBRA_FAIL)
1943 if (alloc_sets == num_result_sets)
1946 RSET *rnew = (RSET *) nmem_malloc(stream, (alloc_sets+add) *
1949 memcpy(rnew, result_sets, alloc_sets * sizeof(*rnew));
1950 alloc_sets = alloc_sets + add;
1953 yaz_log(YLOG_DEBUG, "APT_numeric termp=%s", termp);
1954 grep_info.isam_p_indx = 0;
1955 res = numeric_term(zh, zapt, &termp, attributeSet, &grep_info,
1956 reg_type, complete_flag, num_bases, basenames,
1957 term_dst, xpath_use,
1959 if (res == ZEBRA_FAIL || termp == 0)
1961 yaz_log(YLOG_DEBUG, "term: %s", term_dst);
1962 result_sets[num_result_sets] =
1963 rset_trunc(zh, grep_info.isam_p_buf,
1964 grep_info.isam_p_indx, term_dst,
1965 strlen(term_dst), rank_type,
1966 0 /* preserve position */,
1967 zapt->term->which, rset_nmem,
1968 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, curAttributeSet, use);
2128 int ord_len, i, r, max_pos;
2129 int term_type = Z_Term_characterString;
2130 const char *flags = "void";
2132 if (grep_info_prepare(zh, 0 /* zapt */, &grep_info, '0') == ZEBRA_FAIL)
2133 return rsnull_create(rset_nmem, kc, 0);
2136 return rsnull_create(rset_nmem, kc, 0);
2138 term_dict[prefix_len++] = '|';
2140 term_dict[prefix_len++] = '(';
2142 ord_len = key_SU_encode (ord, ord_buf);
2143 for (i = 0; i<ord_len; i++)
2145 term_dict[prefix_len++] = 1;
2146 term_dict[prefix_len++] = ord_buf[i];
2148 term_dict[prefix_len++] = ')';
2149 term_dict[prefix_len++] = 1;
2150 term_dict[prefix_len++] = reg_type;
2152 strcpy(term_dict+prefix_len, term);
2154 grep_info.isam_p_indx = 0;
2155 r = dict_lookup_grep(zh->reg->dict, term_dict, 0,
2156 &grep_info, &max_pos, 0, grep_handle);
2157 yaz_log(YLOG_DEBUG, "%s %d positions", term,
2158 grep_info.isam_p_indx);
2159 rset = rset_trunc(zh, grep_info.isam_p_buf,
2160 grep_info.isam_p_indx, term, strlen(term),
2161 flags, 1, term_type,rset_nmem,
2162 kc, kc->scope, 0, reg_type);
2163 grep_info_delete(&grep_info);
2168 ZEBRA_RES rpn_search_xpath(ZebraHandle zh,
2169 oid_value attributeSet,
2170 int num_bases, char **basenames,
2171 NMEM stream, const char *rank_type, RSET rset,
2172 int xpath_len, struct xpath_location_step *xpath,
2175 struct rset_key_control *kc)
2177 oid_value curAttributeSet = attributeSet;
2187 yaz_log(YLOG_DEBUG, "xpath len=%d", xpath_len);
2188 for (i = 0; i<xpath_len; i++)
2190 yaz_log(log_level_rpn, "XPATH %d %s", i, xpath[i].part);
2194 curAttributeSet = VAL_IDXPATH;
2204 a[@attr = value]/b[@other = othervalue]
2206 /e/@a val range(e/,range(@a,freetext(w,1015,val),@a),e/)
2207 /a/b val range(b/a/,freetext(w,1016,val),b/a/)
2208 /a/b/@c val range(b/a/,range(@c,freetext(w,1016,val),@c),b/a/)
2209 /a/b[@c = y] val range(b/a/,freetext(w,1016,val),b/a/,@c = y)
2210 /a[@c = y]/b val range(a/,range(b/a/,freetext(w,1016,val),b/a/),a/,@c = y)
2211 /a[@c = x]/b[@c = y] range(a/,range(b/a/,freetext(w,1016,val),b/a/,@c = y),a/,@c = x)
2215 dict_grep_cmap (zh->reg->dict, 0, 0);
2217 for (base_no = 0; base_no < num_bases; base_no++)
2219 int level = xpath_len;
2222 if (zebraExplain_curDatabase (zh->reg->zei, basenames[base_no]))
2224 zebra_setError(zh, YAZ_BIB1_DATABASE_UNAVAILABLE,
2225 basenames[base_no]);
2229 while (--level >= 0)
2231 char xpath_rev[128];
2233 RSET rset_start_tag = 0, rset_end_tag = 0, rset_attr = 0;
2237 for (i = level; i >= 1; --i)
2239 const char *cp = xpath[i].part;
2245 memcpy (xpath_rev + len, "[^/]*", 5);
2248 else if (*cp == ' ')
2251 xpath_rev[len++] = 1;
2252 xpath_rev[len++] = ' ';
2256 xpath_rev[len++] = *cp;
2257 xpath_rev[len++] = '/';
2259 else if (i == 1) /* // case */
2261 xpath_rev[len++] = '.';
2262 xpath_rev[len++] = '*';
2267 if (xpath[level].predicate &&
2268 xpath[level].predicate->which == XPATH_PREDICATE_RELATION &&
2269 xpath[level].predicate->u.relation.name[0])
2271 WRBUF wbuf = wrbuf_alloc();
2272 wrbuf_puts(wbuf, xpath[level].predicate->u.relation.name+1);
2273 if (xpath[level].predicate->u.relation.value)
2275 const char *cp = xpath[level].predicate->u.relation.value;
2276 wrbuf_putc(wbuf, '=');
2280 if (strchr(REGEX_CHARS, *cp))
2281 wrbuf_putc(wbuf, '\\');
2282 wrbuf_putc(wbuf, *cp);
2286 wrbuf_puts(wbuf, "");
2287 rset_attr = xpath_trunc(
2288 zh, stream, '0', wrbuf_buf(wbuf), 3,
2289 curAttributeSet, rset_nmem, kc);
2290 wrbuf_free(wbuf, 1);
2297 yaz_log(log_level_rpn, "xpath_rev (%d) = %s", level, xpath_rev);
2298 if (strlen(xpath_rev))
2300 rset_start_tag = xpath_trunc(zh, stream, '0',
2301 xpath_rev, 1, curAttributeSet, rset_nmem, kc);
2303 rset_end_tag = xpath_trunc(zh, stream, '0',
2304 xpath_rev, 2, curAttributeSet, rset_nmem, kc);
2306 rset = rsbetween_create(rset_nmem, kc, kc->scope,
2307 rset_start_tag, rset,
2308 rset_end_tag, rset_attr);
2317 static ZEBRA_RES rpn_search_APT(ZebraHandle zh, Z_AttributesPlusTerm *zapt,
2318 oid_value attributeSet, NMEM stream,
2319 Z_SortKeySpecList *sort_sequence,
2320 int num_bases, char **basenames,
2323 struct rset_key_control *kc)
2325 ZEBRA_RES res = ZEBRA_OK;
2327 char *search_type = NULL;
2328 char rank_type[128];
2331 char termz[IT_MAX_WORD+1];
2334 struct xpath_location_step xpath[10];
2338 log_level_rpn = yaz_log_module_level("rpn");
2341 zebra_maps_attr(zh->reg->zebra_maps, zapt, ®_id, &search_type,
2342 rank_type, &complete_flag, &sort_flag);
2344 yaz_log(YLOG_DEBUG, "reg_id=%c", reg_id);
2345 yaz_log(YLOG_DEBUG, "complete_flag=%d", complete_flag);
2346 yaz_log(YLOG_DEBUG, "search_type=%s", search_type);
2347 yaz_log(YLOG_DEBUG, "rank_type=%s", rank_type);
2349 if (zapt_term_to_utf8(zh, zapt, termz) == ZEBRA_FAIL)
2353 return rpn_sort_spec(zh, zapt, attributeSet, stream, sort_sequence,
2354 rank_type, rset_nmem, rset, kc);
2355 /* consider if an X-Path query is used */
2356 xpath_len = parse_xpath(zh, zapt, attributeSet, xpath, 10, stream);
2359 xpath_use = 1016; /* searching for element by default */
2360 if (xpath[xpath_len-1].part[0] == '@')
2361 xpath_use = 1015; /* last step an attribute .. */
2364 /* search using one of the various search type strategies
2365 termz is our UTF-8 search term
2366 attributeSet is top-level default attribute set
2367 stream is ODR for search
2368 reg_id is the register type
2369 complete_flag is 1 for complete subfield, 0 for incomplete
2370 xpath_use is use-attribute to be used for X-Path search, 0 for none
2372 if (!strcmp(search_type, "phrase"))
2374 res = rpn_search_APT_phrase(zh, zapt, termz, attributeSet, stream,
2375 reg_id, complete_flag, rank_type,
2377 num_bases, basenames, rset_nmem,
2380 else if (!strcmp(search_type, "and-list"))
2382 res = rpn_search_APT_and_list(zh, zapt, termz, attributeSet, stream,
2383 reg_id, complete_flag, rank_type,
2385 num_bases, basenames, rset_nmem,
2388 else if (!strcmp(search_type, "or-list"))
2390 res = rpn_search_APT_or_list(zh, zapt, termz, attributeSet, stream,
2391 reg_id, complete_flag, rank_type,
2393 num_bases, basenames, rset_nmem,
2396 else if (!strcmp(search_type, "local"))
2398 res = rpn_search_APT_local(zh, zapt, termz, attributeSet, stream,
2399 rank_type, rset_nmem, rset, kc);
2401 else if (!strcmp(search_type, "numeric"))
2403 res = rpn_search_APT_numeric(zh, zapt, termz, attributeSet, stream,
2404 reg_id, complete_flag, rank_type,
2406 num_bases, basenames, rset_nmem,
2411 zebra_setError(zh, YAZ_BIB1_UNSUPP_STRUCTURE_ATTRIBUTE, 0);
2414 if (res != ZEBRA_OK)
2418 return rpn_search_xpath(zh, attributeSet, num_bases, basenames,
2419 stream, rank_type, *rset,
2420 xpath_len, xpath, rset_nmem, rset, kc);
2423 static ZEBRA_RES rpn_search_structure(ZebraHandle zh, Z_RPNStructure *zs,
2424 oid_value attributeSet,
2425 NMEM stream, NMEM rset_nmem,
2426 Z_SortKeySpecList *sort_sequence,
2427 int num_bases, char **basenames,
2428 RSET **result_sets, int *num_result_sets,
2429 Z_Operator *parent_op,
2430 struct rset_key_control *kc);
2432 ZEBRA_RES rpn_search_top(ZebraHandle zh, Z_RPNStructure *zs,
2433 oid_value attributeSet,
2434 NMEM stream, NMEM rset_nmem,
2435 Z_SortKeySpecList *sort_sequence,
2436 int num_bases, char **basenames,
2439 RSET *result_sets = 0;
2440 int num_result_sets = 0;
2442 struct rset_key_control *kc = zebra_key_control_create(zh);
2444 res = rpn_search_structure(zh, zs, attributeSet,
2447 num_bases, basenames,
2448 &result_sets, &num_result_sets,
2449 0 /* no parent op */,
2451 if (res != ZEBRA_OK)
2454 for (i = 0; i<num_result_sets; i++)
2455 rset_delete(result_sets[i]);
2460 assert(num_result_sets == 1);
2461 assert(result_sets);
2462 assert(*result_sets);
2463 *result_set = *result_sets;
2469 ZEBRA_RES rpn_search_structure(ZebraHandle zh, Z_RPNStructure *zs,
2470 oid_value attributeSet,
2471 NMEM stream, NMEM rset_nmem,
2472 Z_SortKeySpecList *sort_sequence,
2473 int num_bases, char **basenames,
2474 RSET **result_sets, int *num_result_sets,
2475 Z_Operator *parent_op,
2476 struct rset_key_control *kc)
2478 *num_result_sets = 0;
2479 if (zs->which == Z_RPNStructure_complex)
2482 Z_Operator *zop = zs->u.complex->roperator;
2483 RSET *result_sets_l = 0;
2484 int num_result_sets_l = 0;
2485 RSET *result_sets_r = 0;
2486 int num_result_sets_r = 0;
2488 res = rpn_search_structure(zh, zs->u.complex->s1,
2489 attributeSet, stream, rset_nmem,
2491 num_bases, basenames,
2492 &result_sets_l, &num_result_sets_l,
2494 if (res != ZEBRA_OK)
2497 for (i = 0; i<num_result_sets_l; i++)
2498 rset_delete(result_sets_l[i]);
2501 res = rpn_search_structure(zh, zs->u.complex->s2,
2502 attributeSet, stream, rset_nmem,
2504 num_bases, basenames,
2505 &result_sets_r, &num_result_sets_r,
2507 if (res != ZEBRA_OK)
2510 for (i = 0; i<num_result_sets_l; i++)
2511 rset_delete(result_sets_l[i]);
2512 for (i = 0; i<num_result_sets_r; i++)
2513 rset_delete(result_sets_r[i]);
2517 /* make a new list of result for all children */
2518 *num_result_sets = num_result_sets_l + num_result_sets_r;
2519 *result_sets = nmem_malloc(stream, *num_result_sets *
2520 sizeof(**result_sets));
2521 memcpy(*result_sets, result_sets_l,
2522 num_result_sets_l * sizeof(**result_sets));
2523 memcpy(*result_sets + num_result_sets_l, result_sets_r,
2524 num_result_sets_r * sizeof(**result_sets));
2526 if (!parent_op || parent_op->which != zop->which
2527 || (zop->which != Z_Operator_and &&
2528 zop->which != Z_Operator_or))
2530 /* parent node different from this one (or non-present) */
2531 /* we must combine result sets now */
2535 case Z_Operator_and:
2536 rset = rsmulti_and_create(rset_nmem, kc,
2538 *num_result_sets, *result_sets);
2541 rset = rsmulti_or_create(rset_nmem, kc,
2542 kc->scope, 0, /* termid */
2543 *num_result_sets, *result_sets);
2545 case Z_Operator_and_not:
2546 rset = rsbool_create_not(rset_nmem, kc,
2551 case Z_Operator_prox:
2552 if (zop->u.prox->which != Z_ProximityOperator_known)
2555 YAZ_BIB1_UNSUPP_PROX_UNIT_CODE,
2559 if (*zop->u.prox->u.known != Z_ProxUnit_word)
2561 zebra_setError_zint(zh,
2562 YAZ_BIB1_UNSUPP_PROX_UNIT_CODE,
2563 *zop->u.prox->u.known);
2568 rset = rsprox_create(rset_nmem, kc,
2570 *num_result_sets, *result_sets,
2571 *zop->u.prox->ordered,
2572 (!zop->u.prox->exclusion ?
2573 0 : *zop->u.prox->exclusion),
2574 *zop->u.prox->relationType,
2575 *zop->u.prox->distance );
2579 zebra_setError(zh, YAZ_BIB1_OPERATOR_UNSUPP, 0);
2582 *num_result_sets = 1;
2583 *result_sets = nmem_malloc(stream, *num_result_sets *
2584 sizeof(**result_sets));
2585 (*result_sets)[0] = rset;
2588 else if (zs->which == Z_RPNStructure_simple)
2593 if (zs->u.simple->which == Z_Operand_APT)
2595 yaz_log(YLOG_DEBUG, "rpn_search_APT");
2596 res = rpn_search_APT(zh, zs->u.simple->u.attributesPlusTerm,
2597 attributeSet, stream, sort_sequence,
2598 num_bases, basenames, rset_nmem, &rset,
2600 if (res != ZEBRA_OK)
2603 else if (zs->u.simple->which == Z_Operand_resultSetId)
2605 yaz_log(YLOG_DEBUG, "rpn_search_ref");
2606 rset = resultSetRef(zh, zs->u.simple->u.resultSetId);
2610 YAZ_BIB1_SPECIFIED_RESULT_SET_DOES_NOT_EXIST,
2611 zs->u.simple->u.resultSetId);
2618 zebra_setError(zh, YAZ_BIB1_UNSUPP_SEARCH, 0);
2621 *num_result_sets = 1;
2622 *result_sets = nmem_malloc(stream, *num_result_sets *
2623 sizeof(**result_sets));
2624 (*result_sets)[0] = rset;
2628 zebra_setError(zh, YAZ_BIB1_UNSUPP_SEARCH, 0);
2634 struct scan_info_entry {
2640 struct scan_info_entry *list;
2646 static int scan_handle (char *name, const char *info, int pos, void *client)
2648 int len_prefix, idx;
2649 struct scan_info *scan_info = (struct scan_info *) client;
2651 len_prefix = strlen(scan_info->prefix);
2652 if (memcmp (name, scan_info->prefix, len_prefix))
2655 idx = scan_info->after - pos + scan_info->before;
2661 scan_info->list[idx].term = (char *)
2662 odr_malloc(scan_info->odr, strlen(name + len_prefix)+1);
2663 strcpy(scan_info->list[idx].term, name + len_prefix);
2664 assert (*info == sizeof(ISAM_P));
2665 memcpy (&scan_info->list[idx].isam_p, info+1, sizeof(ISAM_P));
2669 void zebra_term_untrans_iconv(ZebraHandle zh, NMEM stream, int reg_type,
2670 char **dst, const char *src)
2672 char term_src[IT_MAX_WORD];
2673 char term_dst[IT_MAX_WORD];
2675 zebra_term_untrans (zh, reg_type, term_src, src);
2677 if (zh->iconv_from_utf8 != 0)
2680 char *inbuf = term_src;
2681 size_t inleft = strlen(term_src);
2682 char *outbuf = term_dst;
2683 size_t outleft = sizeof(term_dst)-1;
2686 ret = yaz_iconv (zh->iconv_from_utf8, &inbuf, &inleft,
2688 if (ret == (size_t)(-1))
2691 len = outbuf - term_dst;
2692 *dst = nmem_malloc(stream, len + 1);
2694 memcpy (*dst, term_dst, len);
2698 *dst = nmem_strdup(stream, term_src);
2701 static void count_set (RSET r, int *count)
2708 yaz_log(YLOG_DEBUG, "count_set");
2711 rfd = rset_open (r, RSETF_READ);
2712 while (rset_read (rfd, &key,0 /* never mind terms */))
2714 if (key.mem[0] != psysno)
2716 psysno = key.mem[0];
2722 yaz_log(YLOG_DEBUG, "%d keys, %d records", kno, *count);
2725 ZEBRA_RES rpn_scan(ZebraHandle zh, ODR stream, Z_AttributesPlusTerm *zapt,
2726 oid_value attributeset,
2727 int num_bases, char **basenames,
2728 int *position, int *num_entries, ZebraScanEntry **list,
2729 int *is_partial, RSET limit_set, int return_zero)
2732 int pos = *position;
2733 int num = *num_entries;
2737 char termz[IT_MAX_WORD+20];
2740 const char *use_string = 0;
2741 struct scan_info *scan_info_array;
2742 ZebraScanEntry *glist;
2743 int ords[32], ord_no = 0;
2746 int bases_ok = 0; /* no of databases with OK attribute */
2747 int errCode = 0; /* err code (if any is not OK) */
2748 char *errString = 0; /* addinfo */
2751 char *search_type = NULL;
2752 char rank_type[128];
2755 NMEM rset_nmem = NULL;
2756 struct rset_key_control *kc = 0;
2761 if (attributeset == VAL_NONE)
2762 attributeset = VAL_BIB1;
2767 int termset_value_numeric;
2768 const char *termset_value_string;
2769 attr_init(&termset, zapt, 8);
2770 termset_value_numeric =
2771 attr_find_ex(&termset, NULL, &termset_value_string);
2772 if (termset_value_numeric != -1)
2775 const char *termset_name = 0;
2777 if (termset_value_numeric != -2)
2780 sprintf(resname, "%d", termset_value_numeric);
2781 termset_name = resname;
2784 termset_name = termset_value_string;
2786 limit_set = resultSetRef (zh, termset_name);
2790 yaz_log(YLOG_DEBUG, "position = %d, num = %d set=%d",
2791 pos, num, attributeset);
2793 attr_init(&use, zapt, 1);
2794 use_value = attr_find_ex(&use, &attributeset, &use_string);
2796 if (zebra_maps_attr(zh->reg->zebra_maps, zapt, ®_id, &search_type,
2797 rank_type, &complete_flag, &sort_flag))
2800 zebra_setError(zh, YAZ_BIB1_UNSUPP_ATTRIBUTE_TYPE, 0);
2803 yaz_log(YLOG_DEBUG, "use_value = %d", use_value);
2805 if (use_value == -1)
2807 for (base_no = 0; base_no < num_bases && ord_no < 32; base_no++)
2809 data1_local_attribute *local_attr;
2813 if (zebraExplain_curDatabase (zh->reg->zei, basenames[base_no]))
2815 zebra_setError(zh, YAZ_BIB1_DATABASE_UNAVAILABLE,
2816 basenames[base_no]);
2822 (ord = zebraExplain_lookup_attr_str(zh->reg->zei,
2825 /* we have a match for a raw string attribute */
2827 ords[ord_no++] = ord;
2828 attp.local_attributes = 0; /* no more attributes */
2834 if ((r = att_getentbyatt (zh, &attp, attributeset, use_value,
2837 yaz_log(YLOG_DEBUG, "att_getentbyatt fail. set=%d use=%d",
2838 attributeset, use_value);
2841 errCode = YAZ_BIB1_UNSUPP_USE_ATTRIBUTE;
2843 zebra_setError(zh, YAZ_BIB1_UNSUPP_USE_ATTRIBUTE,
2846 zebra_setError_zint(zh, YAZ_BIB1_UNSUPP_USE_ATTRIBUTE,
2851 zebra_setError(zh, YAZ_BIB1_UNSUPP_ATTRIBUTE_SET, 0);
2857 for (local_attr = attp.local_attributes; local_attr && ord_no < 32;
2858 local_attr = local_attr->next)
2860 ord = zebraExplain_lookup_attr_su(zh->reg->zei,
2861 attp.attset_ordinal,
2864 ords[ord_no++] = ord;
2867 if (!bases_ok && errCode)
2869 zebra_setError(zh, errCode, errString);
2878 /* prepare dictionary scanning */
2890 yaz_log(YLOG_DEBUG, "rpn_scan pos=%d num=%d before=%d "
2891 "after=%d before+after=%d",
2892 pos, num, before, after, before+after);
2893 scan_info_array = (struct scan_info *)
2894 odr_malloc(stream, ord_no * sizeof(*scan_info_array));
2895 for (i = 0; i < ord_no; i++)
2897 int j, prefix_len = 0;
2898 int before_tmp = before, after_tmp = after;
2899 struct scan_info *scan_info = scan_info_array + i;
2900 struct rpn_char_map_info rcmi;
2902 rpn_char_map_prepare (zh->reg, reg_id, &rcmi);
2904 scan_info->before = before;
2905 scan_info->after = after;
2906 scan_info->odr = stream;
2908 scan_info->list = (struct scan_info_entry *)
2909 odr_malloc(stream, (before+after) * sizeof(*scan_info->list));
2910 for (j = 0; j<before+after; j++)
2911 scan_info->list[j].term = NULL;
2913 prefix_len += key_SU_encode (ords[i], termz + prefix_len);
2914 termz[prefix_len++] = reg_id;
2915 termz[prefix_len] = 0;
2916 strcpy(scan_info->prefix, termz);
2918 if (trans_scan_term(zh, zapt, termz+prefix_len, reg_id) == ZEBRA_FAIL)
2921 dict_scan(zh->reg->dict, termz, &before_tmp, &after_tmp,
2922 scan_info, scan_handle);
2924 glist = (ZebraScanEntry *)
2925 odr_malloc(stream, (before+after)*sizeof(*glist));
2927 rset_nmem = nmem_create();
2928 kc = zebra_key_control_create(zh);
2930 /* consider terms after main term */
2931 for (i = 0; i < ord_no; i++)
2935 for (i = 0; i<after; i++)
2938 const char *mterm = NULL;
2941 int lo = i + pos-1; /* offset in result list */
2943 /* find: j0 is the first of the minimal values */
2944 for (j = 0; j < ord_no; j++)
2946 if (ptr[j] < before+after && ptr[j] >= 0 &&
2947 (tst = scan_info_array[j].list[ptr[j]].term) &&
2948 (!mterm || strcmp (tst, mterm) < 0))
2955 break; /* no value found, stop */
2957 /* get result set for first one , but only if it's within bounds */
2960 /* get result set for first term */
2961 zebra_term_untrans_iconv(zh, stream->mem, reg_id,
2962 &glist[lo].term, mterm);
2963 rset = rset_trunc(zh, &scan_info_array[j0].list[ptr[j0]].isam_p, 1,
2964 glist[lo].term, strlen(glist[lo].term),
2965 NULL, 0, zapt->term->which, rset_nmem,
2966 kc, kc->scope, 0, reg_id);
2968 ptr[j0]++; /* move index for this set .. */
2969 /* get result set for remaining scan terms */
2970 for (j = j0+1; j<ord_no; j++)
2972 if (ptr[j] < before+after && ptr[j] >= 0 &&
2973 (tst = scan_info_array[j].list[ptr[j]].term) &&
2974 !strcmp (tst, mterm))
2983 zh, &scan_info_array[j].list[ptr[j]].isam_p, 1,
2985 strlen(glist[lo].term), NULL, 0,
2986 zapt->term->which,rset_nmem,
2987 kc, kc->scope, 0, reg_id);
2988 rset = rsmulti_or_create(rset_nmem, kc,
2989 kc->scope, 0 /* termid */,
2997 /* merge with limit_set if given */
3002 rsets[1] = rset_dup(limit_set);
3004 rset = rsmulti_and_create(rset_nmem, kc,
3009 count_set(rset, &glist[lo].occurrences);
3015 *num_entries -= (after-i);
3017 if (*num_entries < 0)
3020 nmem_destroy(rset_nmem);
3025 /* consider terms before main term */
3026 for (i = 0; i<ord_no; i++)
3029 for (i = 0; i<before; i++)
3032 const char *mterm = NULL;
3035 int lo = before-1-i; /* offset in result list */
3037 for (j = 0; j <ord_no; j++)
3039 if (ptr[j] < before && ptr[j] >= 0 &&
3040 (tst = scan_info_array[j].list[before-1-ptr[j]].term) &&
3041 (!mterm || strcmp (tst, mterm) > 0))
3050 zebra_term_untrans_iconv(zh, stream->mem, reg_id,
3051 &glist[lo].term, mterm);
3054 (zh, &scan_info_array[j0].list[before-1-ptr[j0]].isam_p, 1,
3055 glist[lo].term, strlen(glist[lo].term),
3056 NULL, 0, zapt->term->which, rset_nmem,
3057 kc, kc->scope, 0, reg_id);
3061 for (j = j0+1; j<ord_no; j++)
3063 if (ptr[j] < before && ptr[j] >= 0 &&
3064 (tst = scan_info_array[j].list[before-1-ptr[j]].term) &&
3065 !strcmp (tst, mterm))
3070 rsets[1] = rset_trunc(
3072 &scan_info_array[j].list[before-1-ptr[j]].isam_p, 1,
3074 strlen(glist[lo].term), NULL, 0,
3075 zapt->term->which, rset_nmem,
3076 kc, kc->scope, 0, reg_id);
3077 rset = rsmulti_or_create(rset_nmem, kc,
3078 kc->scope, 0 /* termid */, 2, rsets);
3087 rsets[1] = rset_dup(limit_set);
3089 rset = rsmulti_and_create(rset_nmem, kc,
3090 kc->scope, 2, rsets);
3092 count_set (rset, &glist[lo].occurrences);
3096 nmem_destroy(rset_nmem);
3103 if (*num_entries <= 0)
3110 *list = glist + i; /* list is set to first 'real' entry */
3112 yaz_log(YLOG_DEBUG, "position = %d, num_entries = %d",
3113 *position, *num_entries);