1 /* $Id: zrpn.c,v 1.209 2006-02-20 12:38:42 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,
186 if (len < IT_MAX_WORD-1)
191 while (*cp && len < IT_MAX_WORD-1)
197 static void add_isam_p(const char *name, const char *info,
202 log_level_rpn = yaz_log_module_level("rpn");
205 if (p->isam_p_indx == p->isam_p_size)
207 ISAM_P *new_isam_p_buf;
211 p->isam_p_size = 2*p->isam_p_size + 100;
212 new_isam_p_buf = (ISAM_P *) xmalloc(sizeof(*new_isam_p_buf) *
216 memcpy(new_isam_p_buf, p->isam_p_buf,
217 p->isam_p_indx * sizeof(*p->isam_p_buf));
218 xfree(p->isam_p_buf);
220 p->isam_p_buf = new_isam_p_buf;
223 new_term_no = (int *) xmalloc(sizeof(*new_term_no) * p->isam_p_size);
226 memcpy(new_term_no, p->isam_p_buf,
227 p->isam_p_indx * sizeof(*p->term_no));
230 p->term_no = new_term_no;
233 assert(*info == sizeof(*p->isam_p_buf));
234 memcpy(p->isam_p_buf + p->isam_p_indx, info+1, sizeof(*p->isam_p_buf));
241 char term_tmp[IT_MAX_WORD];
243 int len = key_SU_decode (&ord, (const unsigned char *) name);
245 zebra_term_untrans (p->zh, p->reg_type, term_tmp, name+len+1);
246 yaz_log(log_level_rpn, "grep: %d %c %s", ord, name[len], term_tmp);
247 zebraExplain_lookup_ord (p->zh->reg->zei,
248 ord, 0 /* index_type */, &db, &set, &use);
249 yaz_log(log_level_rpn, "grep: set=%d use=%d db=%s", set, use, db);
251 resultSetAddTerm(p->zh, p->termset, name[len], db,
258 static int grep_handle(char *name, const char *info, void *p)
260 add_isam_p(name, info, (struct grep_info *) p);
264 static int term_pre(ZebraMaps zebra_maps, int reg_type, const char **src,
265 const char *ct1, const char *ct2, int first)
267 const char *s1, *s0 = *src;
270 /* skip white space */
273 if (ct1 && strchr(ct1, *s0))
275 if (ct2 && strchr(ct2, *s0))
278 map = zebra_maps_input(zebra_maps, reg_type, &s1, strlen(s1), first);
279 if (**map != *CHR_SPACE)
288 static void esc_str(char *out_buf, int out_size,
289 const char *in_buf, int in_size)
295 assert(out_size > 20);
297 for (k = 0; k<in_size; k++)
299 int c = in_buf[k] & 0xff;
301 if (c < 32 || c > 126)
305 sprintf(out_buf +strlen(out_buf), "%02X:%c ", c, pc);
306 if (strlen(out_buf) > out_size-20)
308 strcat(out_buf, "..");
314 #define REGEX_CHARS " []()|.*+?!"
316 /* term_100: handle term, where trunc = none(no operators at all) */
317 static int term_100(ZebraMaps zebra_maps, int reg_type,
318 const char **src, char *dst, int space_split,
326 const char *space_start = 0;
327 const char *space_end = 0;
329 if (!term_pre(zebra_maps, reg_type, src, NULL, NULL, !space_split))
336 map = zebra_maps_search(zebra_maps, reg_type, &s0, strlen(s0),
340 if (**map == *CHR_SPACE)
343 else /* complete subfield only. */
345 if (**map == *CHR_SPACE)
346 { /* save space mapping for later .. */
351 else if (space_start)
352 { /* reload last space */
353 while (space_start < space_end)
355 if (strchr(REGEX_CHARS, *space_start))
357 dst_term[j++] = *space_start;
358 dst[i++] = *space_start++;
361 space_start = space_end = 0;
364 /* add non-space char */
365 memcpy(dst_term+j, s1, s0 - s1);
371 if (strchr(REGEX_CHARS, *s1))
379 esc_str(tmpbuf, sizeof(tmpbuf), map[0], strlen(map[0]));
381 strcpy(dst + i, map[0]);
391 /* term_101: handle term, where trunc = Process # */
392 static int term_101(ZebraMaps zebra_maps, int reg_type,
393 const char **src, char *dst, int space_split,
401 if (!term_pre(zebra_maps, reg_type, src, "#", "#", !space_split))
410 dst_term[j++] = *s0++;
416 map = zebra_maps_search(zebra_maps, reg_type, &s0, strlen(s0),
418 if (space_split && **map == *CHR_SPACE)
421 /* add non-space char */
422 memcpy(dst_term+j, s1, s0 - s1);
428 if (strchr(REGEX_CHARS, *s1))
436 esc_str(tmpbuf, sizeof(tmpbuf), map[0], strlen(map[0]));
438 strcpy(dst + i, map[0]);
444 dst_term[j++] = '\0';
449 /* term_103: handle term, where trunc = re-2 (regular expressions) */
450 static int term_103(ZebraMaps zebra_maps, int reg_type, const char **src,
451 char *dst, int *errors, int space_split,
459 if (!term_pre(zebra_maps, reg_type, src, "^\\()[].*+?|", "(", !space_split))
462 if (errors && *s0 == '+' && s0[1] && s0[2] == '+' && s0[3] &&
463 isdigit(((const unsigned char *)s0)[1]))
465 *errors = s0[1] - '0';
472 if (strchr("^\\()[].*+?|-", *s0))
481 map = zebra_maps_search(zebra_maps, reg_type, &s0, strlen(s0),
483 if (space_split && **map == *CHR_SPACE)
486 /* add non-space char */
487 memcpy(dst_term+j, s1, s0 - s1);
493 if (strchr(REGEX_CHARS, *s1))
501 esc_str(tmpbuf, sizeof(tmpbuf), map[0], strlen(map[0]));
503 strcpy(dst + i, map[0]);
515 /* term_103: handle term, where trunc = re-1 (regular expressions) */
516 static int term_102(ZebraMaps zebra_maps, int reg_type, const char **src,
517 char *dst, int space_split, char *dst_term)
519 return term_103(zebra_maps, reg_type, src, dst, NULL, space_split,
524 /* term_104: handle term, where trunc = Process # and ! */
525 static int term_104(ZebraMaps zebra_maps, int reg_type,
526 const char **src, char *dst, int space_split,
534 if (!term_pre(zebra_maps, reg_type, src, "?*#", "?*#", !space_split))
541 dst_term[j++] = *s0++;
542 if (*s0 >= '0' && *s0 <= '9')
545 while (*s0 >= '0' && *s0 <= '9')
547 limit = limit * 10 + (*s0 - '0');
548 dst_term[j++] = *s0++;
568 dst_term[j++] = *s0++;
573 dst_term[j++] = *s0++;
579 map = zebra_maps_search(zebra_maps, reg_type, &s0, strlen(s0),
581 if (space_split && **map == *CHR_SPACE)
584 /* add non-space char */
585 memcpy(dst_term+j, s1, s0 - s1);
591 if (strchr(REGEX_CHARS, *s1))
599 esc_str(tmpbuf, sizeof(tmpbuf), map[0], strlen(map[0]));
601 strcpy(dst + i, map[0]);
607 dst_term[j++] = '\0';
612 /* term_105/106: handle term, where trunc = Process * and ! and right trunc */
613 static int term_105(ZebraMaps zebra_maps, int reg_type,
614 const char **src, char *dst, int space_split,
615 char *dst_term, int right_truncate)
622 if (!term_pre(zebra_maps, reg_type, src, "*!", "*!", !space_split))
631 dst_term[j++] = *s0++;
636 dst_term[j++] = *s0++;
642 map = zebra_maps_search(zebra_maps, reg_type, &s0, strlen(s0),
644 if (space_split && **map == *CHR_SPACE)
647 /* add non-space char */
648 memcpy(dst_term+j, s1, s0 - s1);
654 if (strchr(REGEX_CHARS, *s1))
662 esc_str(tmpbuf, sizeof(tmpbuf), map[0], strlen(map[0]));
664 strcpy(dst + i, map[0]);
676 dst_term[j++] = '\0';
682 /* gen_regular_rel - generate regular expression from relation
683 * val: border value (inclusive)
684 * islt: 1 if <=; 0 if >=.
686 static void gen_regular_rel(char *dst, int val, int islt)
693 yaz_log(YLOG_DEBUG, "gen_regular_rel. val=%d, islt=%d", val, islt);
697 strcpy(dst, "(-[0-9]+|(");
705 strcpy(dst, "([0-9]+|-(");
717 sprintf(numstr, "%d", val);
718 for (w = strlen(numstr); --w >= 0; pos++)
737 strcpy(dst + dst_p, numstr);
738 dst_p = strlen(dst) - pos - 1;
766 for (i = 0; i<pos; i++)
779 /* match everything less than 10^(pos-1) */
781 for (i = 1; i<pos; i++)
782 strcat(dst, "[0-9]?");
786 /* match everything greater than 10^pos */
787 for (i = 0; i <= pos; i++)
788 strcat(dst, "[0-9]");
789 strcat(dst, "[0-9]*");
794 void string_rel_add_char(char **term_p, const char *src, int *indx)
796 if (src[*indx] == '\\')
797 *(*term_p)++ = src[(*indx)++];
798 *(*term_p)++ = src[(*indx)++];
802 * > abc ([b-].*|a[c-].*|ab[d-].*|abc.+)
803 * ([^-a].*|a[^-b].*ab[^-c].*|abc.+)
804 * >= abc ([b-].*|a[c-].*|ab[c-].*)
805 * ([^-a].*|a[^-b].*|ab[c-].*)
806 * < abc ([-0].*|a[-a].*|ab[-b].*)
807 * ([^a-].*|a[^b-].*|ab[^c-].*)
808 * <= abc ([-0].*|a[-a].*|ab[-b].*|abc)
809 * ([^a-].*|a[^b-].*|ab[^c-].*|abc)
811 static int string_relation(ZebraHandle zh, Z_AttributesPlusTerm *zapt,
812 const char **term_sub, char *term_dict,
813 oid_value attributeSet,
814 int reg_type, int space_split, char *term_dst,
820 char *term_tmp = term_dict + strlen(term_dict);
821 char term_component[2*IT_MAX_WORD+20];
823 attr_init(&relation, zapt, 2);
824 relation_value = attr_find(&relation, NULL);
827 yaz_log(YLOG_DEBUG, "string relation value=%d", relation_value);
828 switch (relation_value)
831 if (!term_100(zh->reg->zebra_maps, reg_type,
832 term_sub, term_component,
833 space_split, term_dst))
835 yaz_log(log_level_rpn, "Relation <");
838 for (i = 0; term_component[i]; )
845 string_rel_add_char(&term_tmp, term_component, &j);
850 string_rel_add_char(&term_tmp, term_component, &i);
857 if ((term_tmp - term_dict) > IT_MAX_WORD)
864 if (!term_100(zh->reg->zebra_maps, reg_type,
865 term_sub, term_component,
866 space_split, term_dst))
868 yaz_log(log_level_rpn, "Relation <=");
871 for (i = 0; term_component[i]; )
876 string_rel_add_char(&term_tmp, term_component, &j);
880 string_rel_add_char(&term_tmp, term_component, &i);
889 if ((term_tmp - term_dict) > IT_MAX_WORD)
892 for (i = 0; term_component[i]; )
893 string_rel_add_char(&term_tmp, term_component, &i);
898 if (!term_100 (zh->reg->zebra_maps, reg_type,
899 term_sub, term_component, space_split, term_dst))
901 yaz_log(log_level_rpn, "Relation >");
904 for (i = 0; term_component[i];)
909 string_rel_add_char(&term_tmp, term_component, &j);
914 string_rel_add_char(&term_tmp, term_component, &i);
922 if ((term_tmp - term_dict) > IT_MAX_WORD)
925 for (i = 0; term_component[i];)
926 string_rel_add_char(&term_tmp, term_component, &i);
933 if (!term_100(zh->reg->zebra_maps, reg_type, term_sub,
934 term_component, space_split, term_dst))
936 yaz_log(log_level_rpn, "Relation >=");
939 for (i = 0; term_component[i];)
946 string_rel_add_char(&term_tmp, term_component, &j);
949 if (term_component[i+1])
953 string_rel_add_char(&term_tmp, term_component, &i);
957 string_rel_add_char(&term_tmp, term_component, &i);
964 if ((term_tmp - term_dict) > IT_MAX_WORD)
973 yaz_log(log_level_rpn, "Relation =");
974 if (!term_100(zh->reg->zebra_maps, reg_type, term_sub,
975 term_component, space_split, term_dst))
977 strcat(term_tmp, "(");
978 strcat(term_tmp, term_component);
979 strcat(term_tmp, ")");
982 *error_code = YAZ_BIB1_UNSUPP_RELATION_ATTRIBUTE;
988 static ZEBRA_RES string_term(ZebraHandle zh, Z_AttributesPlusTerm *zapt,
989 const char **term_sub,
990 oid_value attributeSet, NMEM stream,
991 struct grep_info *grep_info,
992 int reg_type, int complete_flag,
993 int num_bases, char **basenames,
994 char *term_dst, int xpath_use,
995 struct ord_list **ol);
997 static ZEBRA_RES term_limits_APT(ZebraHandle zh,
998 Z_AttributesPlusTerm *zapt,
999 zint *hits_limit_value,
1000 const char **term_ref_id_str,
1003 AttrType term_ref_id_attr;
1004 AttrType hits_limit_attr;
1005 int term_ref_id_int;
1007 attr_init(&hits_limit_attr, zapt, 9);
1008 *hits_limit_value = attr_find(&hits_limit_attr, NULL);
1010 attr_init(&term_ref_id_attr, zapt, 10);
1011 term_ref_id_int = attr_find_ex(&term_ref_id_attr, NULL, term_ref_id_str);
1012 if (term_ref_id_int >= 0)
1014 char *res = nmem_malloc(nmem, 20);
1015 sprintf(res, "%d", term_ref_id_int);
1016 *term_ref_id_str = res;
1019 /* no limit given ? */
1020 if (*hits_limit_value == -1)
1022 if (*term_ref_id_str)
1024 /* use global if term_ref is present */
1025 *hits_limit_value = zh->approx_limit;
1029 /* no counting if term_ref is not present */
1030 *hits_limit_value = 0;
1033 else if (*hits_limit_value == 0)
1035 /* 0 is the same as global limit */
1036 *hits_limit_value = zh->approx_limit;
1038 yaz_log(YLOG_DEBUG, "term_limits_APT ref_id=%s limit=" ZINT_FORMAT,
1039 *term_ref_id_str ? *term_ref_id_str : "none",
1044 static ZEBRA_RES term_trunc(ZebraHandle zh,
1045 Z_AttributesPlusTerm *zapt,
1046 const char **term_sub,
1047 oid_value attributeSet, NMEM stream,
1048 struct grep_info *grep_info,
1049 int reg_type, int complete_flag,
1050 int num_bases, char **basenames,
1052 const char *rank_type, int xpath_use,
1055 struct rset_key_control *kc)
1058 struct ord_list *ol;
1059 zint hits_limit_value;
1060 const char *term_ref_id_str = 0;
1063 term_limits_APT(zh, zapt, &hits_limit_value, &term_ref_id_str,
1065 grep_info->isam_p_indx = 0;
1066 res = string_term(zh, zapt, term_sub, attributeSet, stream, grep_info,
1067 reg_type, complete_flag, num_bases, basenames,
1068 term_dst, xpath_use, &ol);
1069 if (res != ZEBRA_OK)
1071 if (!*term_sub) /* no more terms ? */
1073 yaz_log(log_level_rpn, "term: %s", term_dst);
1074 *rset = rset_trunc(zh, grep_info->isam_p_buf,
1075 grep_info->isam_p_indx, term_dst,
1076 strlen(term_dst), rank_type, 1 /* preserve pos */,
1077 zapt->term->which, rset_nmem,
1078 kc, kc->scope, ol, reg_type, hits_limit_value,
1085 static ZEBRA_RES string_term(ZebraHandle zh, Z_AttributesPlusTerm *zapt,
1086 const char **term_sub,
1087 oid_value attributeSet, NMEM stream,
1088 struct grep_info *grep_info,
1089 int reg_type, int complete_flag,
1090 int num_bases, char **basenames,
1091 char *term_dst, int xpath_use,
1092 struct ord_list **ol)
1094 char term_dict[2*IT_MAX_WORD+4000];
1096 AttrType truncation;
1097 int truncation_value;
1100 const char *use_string = 0;
1101 oid_value curAttributeSet = attributeSet;
1103 struct rpn_char_map_info rcmi;
1104 int space_split = complete_flag ? 0 : 1;
1106 int bases_ok = 0; /* no of databases with OK attribute */
1108 *ol = ord_list_create(stream);
1110 rpn_char_map_prepare (zh->reg, reg_type, &rcmi);
1111 attr_init(&use, zapt, 1);
1112 use_value = attr_find_ex(&use, &curAttributeSet, &use_string);
1113 yaz_log(log_level_rpn, "string_term, use value %d", use_value);
1114 attr_init(&truncation, zapt, 5);
1115 truncation_value = attr_find(&truncation, NULL);
1116 yaz_log(log_level_rpn, "truncation value %d", truncation_value);
1118 if (use_value == -1) /* no attribute - assumy "any" */
1120 for (base_no = 0; base_no < num_bases; base_no++)
1124 int regex_range = 0;
1127 data1_local_attribute id_xpath_attr;
1128 data1_local_attribute *local_attr;
1129 int max_pos, prefix_len = 0;
1134 if (zebraExplain_curDatabase (zh->reg->zei, basenames[base_no]))
1136 zebra_setError(zh, YAZ_BIB1_DATABASE_UNAVAILABLE,
1137 basenames[base_no]);
1140 if (xpath_use > 0 && use_value == -2)
1142 /* xpath mode and we have a string attribute */
1143 attp.local_attributes = &id_xpath_attr;
1144 attp.attset_ordinal = VAL_IDXPATH;
1145 id_xpath_attr.next = 0;
1147 use_value = xpath_use; /* xpath_use as use-attribute now */
1148 id_xpath_attr.local = use_value;
1150 else if (curAttributeSet == VAL_IDXPATH && use_value >= 0)
1152 /* X-Path attribute, use numeric value directly */
1153 attp.local_attributes = &id_xpath_attr;
1154 attp.attset_ordinal = VAL_IDXPATH;
1155 id_xpath_attr.next = 0;
1156 id_xpath_attr.local = use_value;
1158 else if (use_string &&
1159 (ord = zebraExplain_lookup_attr_str(zh->reg->zei,
1163 /* we have a match for a raw string attribute */
1168 term_dict[prefix_len++] = '|';
1170 term_dict[prefix_len++] = '(';
1172 ord_len = key_SU_encode (ord, ord_buf);
1173 for (i = 0; i<ord_len; i++)
1175 term_dict[prefix_len++] = 1;
1176 term_dict[prefix_len++] = ord_buf[i];
1178 attp.local_attributes = 0; /* no more attributes */
1179 *ol = ord_list_append(stream, *ol, ord);
1183 /* lookup in the .att files . Allow string as well */
1184 if ((r = att_getentbyatt (zh, &attp, curAttributeSet, use_value,
1187 yaz_log(YLOG_DEBUG, "att_getentbyatt fail. set=%d use=%d r=%d",
1188 curAttributeSet, use_value, r);
1191 /* set was found, but value wasn't defined */
1194 YAZ_BIB1_UNSUPP_USE_ATTRIBUTE,
1197 zebra_setError_zint(zh, YAZ_BIB1_UNSUPP_USE_ATTRIBUTE,
1203 struct oident oident;
1205 oident.proto = PROTO_Z3950;
1206 oident.oclass = CLASS_ATTSET;
1207 oident.value = curAttributeSet;
1208 oid_ent_to_oid (&oident, oid);
1211 YAZ_BIB1_UNSUPP_ATTRIBUTE_SET,
1218 for (local_attr = attp.local_attributes; local_attr;
1219 local_attr = local_attr->next)
1224 ord = zebraExplain_lookup_attr_su(zh->reg->zei,
1226 attp.attset_ordinal,
1230 *ol = ord_list_append(stream, *ol, ord);
1232 term_dict[prefix_len++] = '|';
1234 term_dict[prefix_len++] = '(';
1236 ord_len = key_SU_encode (ord, ord_buf);
1237 for (i = 0; i<ord_len; i++)
1239 term_dict[prefix_len++] = 1;
1240 term_dict[prefix_len++] = ord_buf[i];
1247 term_dict[prefix_len++] = ')';
1248 term_dict[prefix_len] = '\0';
1250 switch (truncation_value)
1252 case -1: /* not specified */
1253 case 100: /* do not truncate */
1254 if (!string_relation (zh, zapt, &termp, term_dict,
1256 reg_type, space_split, term_dst,
1261 zebra_setError(zh, relation_error, 0);
1268 case 1: /* right truncation */
1269 term_dict[j++] = '(';
1270 if (!term_100(zh->reg->zebra_maps, reg_type,
1271 &termp, term_dict + j, space_split, term_dst))
1276 strcat(term_dict, ".*)");
1278 case 2: /* keft truncation */
1279 term_dict[j++] = '('; term_dict[j++] = '.'; term_dict[j++] = '*';
1280 if (!term_100(zh->reg->zebra_maps, reg_type,
1281 &termp, term_dict + j, space_split, term_dst))
1286 strcat(term_dict, ")");
1288 case 3: /* left&right truncation */
1289 term_dict[j++] = '('; term_dict[j++] = '.'; term_dict[j++] = '*';
1290 if (!term_100(zh->reg->zebra_maps, reg_type,
1291 &termp, term_dict + j, space_split, term_dst))
1296 strcat(term_dict, ".*)");
1298 case 101: /* process # in term */
1299 term_dict[j++] = '(';
1300 if (!term_101(zh->reg->zebra_maps, reg_type,
1301 &termp, term_dict + j, space_split, term_dst))
1306 strcat(term_dict, ")");
1308 case 102: /* Regexp-1 */
1309 term_dict[j++] = '(';
1310 if (!term_102(zh->reg->zebra_maps, reg_type,
1311 &termp, term_dict + j, space_split, term_dst))
1316 strcat(term_dict, ")");
1318 case 103: /* Regexp-2 */
1320 term_dict[j++] = '(';
1322 if (!term_103(zh->reg->zebra_maps, reg_type,
1323 &termp, term_dict + j, ®ex_range,
1324 space_split, term_dst))
1329 strcat(term_dict, ")");
1331 case 104: /* process # and ! in term */
1332 term_dict[j++] = '(';
1333 if (!term_104(zh->reg->zebra_maps, reg_type,
1334 &termp, term_dict + j, space_split, term_dst))
1339 strcat(term_dict, ")");
1341 case 105: /* process * and ! in term */
1342 term_dict[j++] = '(';
1343 if (!term_105(zh->reg->zebra_maps, reg_type,
1344 &termp, term_dict + j, space_split, term_dst, 1))
1349 strcat(term_dict, ")");
1351 case 106: /* process * and ! in term */
1352 term_dict[j++] = '(';
1353 if (!term_105(zh->reg->zebra_maps, reg_type,
1354 &termp, term_dict + j, space_split, term_dst, 0))
1359 strcat(term_dict, ")");
1362 zebra_setError_zint(zh,
1363 YAZ_BIB1_UNSUPP_TRUNCATION_ATTRIBUTE,
1370 const char *input = term_dict + prefix_len;
1371 esc_str(buf, sizeof(buf), input, strlen(input));
1375 yaz_log(log_level_rpn, "dict_lookup_grep: %s", term_dict+prefix_len);
1376 r = dict_lookup_grep(zh->reg->dict, term_dict, regex_range,
1377 grep_info, &max_pos, init_pos,
1380 yaz_log(YLOG_WARN, "dict_lookup_grep fail %d", r);
1386 yaz_log(YLOG_DEBUG, "%d positions", grep_info->isam_p_indx);
1391 /* convert APT search term to UTF8 */
1392 static ZEBRA_RES zapt_term_to_utf8(ZebraHandle zh, Z_AttributesPlusTerm *zapt,
1396 Z_Term *term = zapt->term;
1398 switch (term->which)
1400 case Z_Term_general:
1401 if (zh->iconv_to_utf8 != 0)
1403 char *inbuf = (char *) term->u.general->buf;
1404 size_t inleft = term->u.general->len;
1405 char *outbuf = termz;
1406 size_t outleft = IT_MAX_WORD-1;
1409 ret = yaz_iconv(zh->iconv_to_utf8, &inbuf, &inleft,
1411 if (ret == (size_t)(-1))
1413 ret = yaz_iconv(zh->iconv_to_utf8, 0, 0, 0, 0);
1416 YAZ_BIB1_QUERY_TERM_INCLUDES_CHARS_THAT_DO_NOT_TRANSLATE_INTO_,
1424 sizez = term->u.general->len;
1425 if (sizez > IT_MAX_WORD-1)
1426 sizez = IT_MAX_WORD-1;
1427 memcpy (termz, term->u.general->buf, sizez);
1428 termz[sizez] = '\0';
1431 case Z_Term_characterString:
1432 sizez = strlen(term->u.characterString);
1433 if (sizez > IT_MAX_WORD-1)
1434 sizez = IT_MAX_WORD-1;
1435 memcpy (termz, term->u.characterString, sizez);
1436 termz[sizez] = '\0';
1439 zebra_setError(zh, YAZ_BIB1_UNSUPP_CODED_VALUE_FOR_TERM, 0);
1445 /* convert APT SCAN term to internal cmap */
1446 static ZEBRA_RES trans_scan_term(ZebraHandle zh, Z_AttributesPlusTerm *zapt,
1447 char *termz, int reg_type)
1449 char termz0[IT_MAX_WORD];
1451 if (zapt_term_to_utf8(zh, zapt, termz0) == ZEBRA_FAIL)
1452 return ZEBRA_FAIL; /* error */
1456 const char *cp = (const char *) termz0;
1457 const char *cp_end = cp + strlen(cp);
1460 const char *space_map = NULL;
1463 while ((len = (cp_end - cp)) > 0)
1465 map = zebra_maps_input(zh->reg->zebra_maps, reg_type, &cp, len, 0);
1466 if (**map == *CHR_SPACE)
1471 for (src = space_map; *src; src++)
1474 for (src = *map; *src; src++)
1483 static void grep_info_delete(struct grep_info *grep_info)
1486 xfree(grep_info->term_no);
1488 xfree(grep_info->isam_p_buf);
1491 static ZEBRA_RES grep_info_prepare(ZebraHandle zh,
1492 Z_AttributesPlusTerm *zapt,
1493 struct grep_info *grep_info,
1497 int termset_value_numeric;
1498 const char *termset_value_string;
1501 grep_info->term_no = 0;
1503 grep_info->isam_p_size = 0;
1504 grep_info->isam_p_buf = NULL;
1506 grep_info->reg_type = reg_type;
1507 grep_info->termset = 0;
1511 attr_init(&termset, zapt, 8);
1512 termset_value_numeric =
1513 attr_find_ex(&termset, NULL, &termset_value_string);
1514 if (termset_value_numeric != -1)
1517 const char *termset_name = 0;
1518 if (termset_value_numeric != -2)
1521 sprintf(resname, "%d", termset_value_numeric);
1522 termset_name = resname;
1525 termset_name = termset_value_string;
1526 yaz_log(log_level_rpn, "creating termset set %s", termset_name);
1527 grep_info->termset = resultSetAdd(zh, termset_name, 1);
1528 if (!grep_info->termset)
1530 zebra_setError(zh, YAZ_BIB1_ILLEGAL_RESULT_SET_NAME, termset_name);
1538 \brief Create result set(s) for list of terms
1539 \param zh Zebra Handle
1540 \param termz term as used in query but converted to UTF-8
1541 \param attributeSet default attribute set
1542 \param stream memory for result
1543 \param reg_type register type ('w', 'p',..)
1544 \param complete_flag whether it's phrases or not
1545 \param rank_type term flags for ranking
1546 \param xpath_use use attribute for X-Path (-1 for no X-path)
1547 \param num_bases number of databases
1548 \param basenames array of databases
1549 \param rset_mem memory for result sets
1550 \param result_sets output result set for each term in list (output)
1551 \param number number of output result sets
1552 \param kc rset key control to be used for created result sets
1554 static ZEBRA_RES term_list_trunc(ZebraHandle zh,
1555 Z_AttributesPlusTerm *zapt,
1557 oid_value attributeSet,
1559 int reg_type, int complete_flag,
1560 const char *rank_type, int xpath_use,
1561 int num_bases, char **basenames,
1563 RSET **result_sets, int *num_result_sets,
1564 struct rset_key_control *kc)
1566 char term_dst[IT_MAX_WORD+1];
1567 struct grep_info grep_info;
1568 const char *termp = termz;
1571 *num_result_sets = 0;
1573 if (grep_info_prepare(zh, zapt, &grep_info, reg_type) == ZEBRA_FAIL)
1579 if (alloc_sets == *num_result_sets)
1582 RSET *rnew = (RSET *) nmem_malloc(stream, (alloc_sets+add) *
1585 memcpy(rnew, *result_sets, alloc_sets * sizeof(*rnew));
1586 alloc_sets = alloc_sets + add;
1587 *result_sets = rnew;
1589 res = term_trunc(zh, zapt, &termp, attributeSet,
1591 reg_type, complete_flag,
1592 num_bases, basenames,
1593 term_dst, rank_type,
1594 xpath_use, rset_nmem,
1595 &(*result_sets)[*num_result_sets],
1597 if (res != ZEBRA_OK)
1600 for (i = 0; i < *num_result_sets; i++)
1601 rset_delete((*result_sets)[i]);
1602 grep_info_delete (&grep_info);
1605 if ((*result_sets)[*num_result_sets] == 0)
1607 (*num_result_sets)++;
1609 grep_info_delete(&grep_info);
1613 static ZEBRA_RES rpn_search_APT_phrase(ZebraHandle zh,
1614 Z_AttributesPlusTerm *zapt,
1615 const char *termz_org,
1616 oid_value attributeSet,
1618 int reg_type, int complete_flag,
1619 const char *rank_type, int xpath_use,
1620 int num_bases, char **basenames,
1623 struct rset_key_control *kc)
1625 RSET *result_sets = 0;
1626 int num_result_sets = 0;
1628 term_list_trunc(zh, zapt, termz_org, attributeSet,
1629 stream, reg_type, complete_flag,
1630 rank_type, xpath_use,
1631 num_bases, basenames,
1633 &result_sets, &num_result_sets, kc);
1634 if (res != ZEBRA_OK)
1636 if (num_result_sets == 0)
1637 *rset = rsnull_create (rset_nmem, kc, 0);
1638 else if (num_result_sets == 1)
1639 *rset = result_sets[0];
1641 *rset = rsprox_create(rset_nmem, kc, kc->scope,
1642 num_result_sets, result_sets,
1643 1 /* ordered */, 0 /* exclusion */,
1644 3 /* relation */, 1 /* distance */);
1650 static ZEBRA_RES rpn_search_APT_or_list(ZebraHandle zh,
1651 Z_AttributesPlusTerm *zapt,
1652 const char *termz_org,
1653 oid_value attributeSet,
1655 int reg_type, int complete_flag,
1656 const char *rank_type,
1658 int num_bases, char **basenames,
1661 struct rset_key_control *kc)
1663 RSET *result_sets = 0;
1664 int num_result_sets = 0;
1666 term_list_trunc(zh, zapt, termz_org, attributeSet,
1667 stream, reg_type, complete_flag,
1668 rank_type, xpath_use,
1669 num_bases, basenames,
1671 &result_sets, &num_result_sets, kc);
1672 if (res != ZEBRA_OK)
1674 if (num_result_sets == 0)
1675 *rset = rsnull_create (rset_nmem, kc, 0);
1676 else if (num_result_sets == 1)
1677 *rset = result_sets[0];
1679 *rset = rsmulti_or_create(rset_nmem, kc, kc->scope, 0 /* termid */,
1680 num_result_sets, result_sets);
1686 static ZEBRA_RES rpn_search_APT_and_list(ZebraHandle zh,
1687 Z_AttributesPlusTerm *zapt,
1688 const char *termz_org,
1689 oid_value attributeSet,
1691 int reg_type, int complete_flag,
1692 const char *rank_type,
1694 int num_bases, char **basenames,
1697 struct rset_key_control *kc)
1699 RSET *result_sets = 0;
1700 int num_result_sets = 0;
1702 term_list_trunc(zh, zapt, termz_org, attributeSet,
1703 stream, reg_type, complete_flag,
1704 rank_type, xpath_use,
1705 num_bases, basenames,
1707 &result_sets, &num_result_sets,
1709 if (res != ZEBRA_OK)
1711 if (num_result_sets == 0)
1712 *rset = rsnull_create (rset_nmem, kc, 0);
1713 else if (num_result_sets == 1)
1714 *rset = result_sets[0];
1716 *rset = rsmulti_and_create(rset_nmem, kc, kc->scope,
1717 num_result_sets, result_sets);
1723 static int numeric_relation(ZebraHandle zh, Z_AttributesPlusTerm *zapt,
1724 const char **term_sub,
1726 oid_value attributeSet,
1727 struct grep_info *grep_info,
1737 char *term_tmp = term_dict + strlen(term_dict);
1740 attr_init(&relation, zapt, 2);
1741 relation_value = attr_find(&relation, NULL);
1743 yaz_log(log_level_rpn, "numeric relation value=%d", relation_value);
1745 if (!term_100(zh->reg->zebra_maps, reg_type, term_sub, term_tmp, 1,
1748 term_value = atoi (term_tmp);
1749 switch (relation_value)
1752 yaz_log(log_level_rpn, "Relation <");
1753 gen_regular_rel(term_tmp, term_value-1, 1);
1756 yaz_log(log_level_rpn, "Relation <=");
1757 gen_regular_rel(term_tmp, term_value, 1);
1760 yaz_log(log_level_rpn, "Relation >=");
1761 gen_regular_rel(term_tmp, term_value, 0);
1764 yaz_log(log_level_rpn, "Relation >");
1765 gen_regular_rel(term_tmp, term_value+1, 0);
1769 yaz_log(log_level_rpn, "Relation =");
1770 sprintf(term_tmp, "(0*%d)", term_value);
1773 *error_code = YAZ_BIB1_UNSUPP_RELATION_ATTRIBUTE;
1776 yaz_log(log_level_rpn, "dict_lookup_grep: %s", term_tmp);
1777 r = dict_lookup_grep(zh->reg->dict, term_dict, 0, grep_info, max_pos,
1780 yaz_log(YLOG_WARN, "dict_lookup_grep fail, rel = gt: %d", r);
1781 yaz_log(log_level_rpn, "%d positions", grep_info->isam_p_indx);
1785 static ZEBRA_RES numeric_term(ZebraHandle zh, Z_AttributesPlusTerm *zapt,
1786 const char **term_sub,
1787 oid_value attributeSet,
1788 struct grep_info *grep_info,
1789 int reg_type, int complete_flag,
1790 int num_bases, char **basenames,
1791 char *term_dst, int xpath_use, NMEM stream)
1793 char term_dict[2*IT_MAX_WORD+2];
1797 const char *use_string = 0;
1798 oid_value curAttributeSet = attributeSet;
1800 struct rpn_char_map_info rcmi;
1802 int bases_ok = 0; /* no of databases with OK attribute */
1804 rpn_char_map_prepare (zh->reg, reg_type, &rcmi);
1805 attr_init(&use, zapt, 1);
1806 use_value = attr_find_ex(&use, &curAttributeSet, &use_string);
1808 if (use_value == -1)
1811 for (base_no = 0; base_no < num_bases; base_no++)
1814 data1_local_attribute id_xpath_attr;
1815 data1_local_attribute *local_attr;
1816 int max_pos, prefix_len = 0;
1817 int relation_error = 0;
1820 if (use_value == -2) /* string attribute (assume IDXPATH/any) */
1822 use_value = xpath_use;
1823 attp.local_attributes = &id_xpath_attr;
1824 attp.attset_ordinal = VAL_IDXPATH;
1825 id_xpath_attr.next = 0;
1826 id_xpath_attr.local = use_value;
1828 else if (curAttributeSet == VAL_IDXPATH)
1830 attp.local_attributes = &id_xpath_attr;
1831 attp.attset_ordinal = VAL_IDXPATH;
1832 id_xpath_attr.next = 0;
1833 id_xpath_attr.local = use_value;
1837 if ((r = att_getentbyatt (zh, &attp, curAttributeSet, use_value,
1840 yaz_log(YLOG_DEBUG, "att_getentbyatt fail. set=%d use=%d r=%d",
1841 curAttributeSet, use_value, r);
1846 YAZ_BIB1_UNSUPP_USE_ATTRIBUTE,
1849 zebra_setError_zint(zh, YAZ_BIB1_UNSUPP_USE_ATTRIBUTE,
1853 zebra_setError(zh, YAZ_BIB1_UNSUPP_ATTRIBUTE_SET, 0);
1857 if (zebraExplain_curDatabase (zh->reg->zei, basenames[base_no]))
1859 zebra_setError(zh, YAZ_BIB1_DATABASE_UNAVAILABLE,
1860 basenames[base_no]);
1863 for (local_attr = attp.local_attributes; local_attr;
1864 local_attr = local_attr->next)
1870 ord = zebraExplain_lookup_attr_su(zh->reg->zei,
1872 attp.attset_ordinal,
1877 term_dict[prefix_len++] = '|';
1879 term_dict[prefix_len++] = '(';
1881 ord_len = key_SU_encode (ord, ord_buf);
1882 for (i = 0; i<ord_len; i++)
1884 term_dict[prefix_len++] = 1;
1885 term_dict[prefix_len++] = ord_buf[i];
1890 zebra_setError_zint(zh, YAZ_BIB1_UNSUPP_USE_ATTRIBUTE, use_value);
1894 term_dict[prefix_len++] = ')';
1895 term_dict[prefix_len] = '\0';
1896 if (!numeric_relation(zh, zapt, &termp, term_dict,
1897 attributeSet, grep_info, &max_pos, reg_type,
1898 term_dst, &relation_error))
1902 zebra_setError(zh, relation_error, 0);
1912 yaz_log(YLOG_DEBUG, "%d positions", grep_info->isam_p_indx);
1917 static ZEBRA_RES rpn_search_APT_numeric(ZebraHandle zh,
1918 Z_AttributesPlusTerm *zapt,
1920 oid_value attributeSet,
1922 int reg_type, int complete_flag,
1923 const char *rank_type, int xpath_use,
1924 int num_bases, char **basenames,
1927 struct rset_key_control *kc)
1929 char term_dst[IT_MAX_WORD+1];
1930 const char *termp = termz;
1931 RSET *result_sets = 0;
1932 int num_result_sets = 0;
1934 struct grep_info grep_info;
1936 zint hits_limit_value;
1937 const char *term_ref_id_str = 0;
1939 term_limits_APT(zh, zapt, &hits_limit_value, &term_ref_id_str, stream);
1941 yaz_log(log_level_rpn, "APT_numeric t='%s'", termz);
1942 if (grep_info_prepare(zh, zapt, &grep_info, reg_type) == ZEBRA_FAIL)
1946 if (alloc_sets == num_result_sets)
1949 RSET *rnew = (RSET *) nmem_malloc(stream, (alloc_sets+add) *
1952 memcpy(rnew, result_sets, alloc_sets * sizeof(*rnew));
1953 alloc_sets = alloc_sets + add;
1956 yaz_log(YLOG_DEBUG, "APT_numeric termp=%s", termp);
1957 grep_info.isam_p_indx = 0;
1958 res = numeric_term(zh, zapt, &termp, attributeSet, &grep_info,
1959 reg_type, complete_flag, num_bases, basenames,
1960 term_dst, xpath_use,
1962 if (res == ZEBRA_FAIL || termp == 0)
1964 yaz_log(YLOG_DEBUG, "term: %s", term_dst);
1965 result_sets[num_result_sets] =
1966 rset_trunc(zh, grep_info.isam_p_buf,
1967 grep_info.isam_p_indx, term_dst,
1968 strlen(term_dst), rank_type,
1969 0 /* preserve position */,
1970 zapt->term->which, rset_nmem,
1971 kc, kc->scope, 0, reg_type,
1974 if (!result_sets[num_result_sets])
1978 grep_info_delete(&grep_info);
1982 for (i = 0; i<num_result_sets; i++)
1983 rset_delete(result_sets[i]);
1986 if (num_result_sets == 0)
1987 *rset = rsnull_create(rset_nmem, kc, 0);
1988 if (num_result_sets == 1)
1989 *rset = result_sets[0];
1991 *rset = rsmulti_and_create(rset_nmem, kc, kc->scope,
1992 num_result_sets, result_sets);
1998 static ZEBRA_RES rpn_search_APT_local(ZebraHandle zh,
1999 Z_AttributesPlusTerm *zapt,
2001 oid_value attributeSet,
2003 const char *rank_type, NMEM rset_nmem,
2005 struct rset_key_control *kc)
2010 *rset = rstemp_create(rset_nmem, kc, kc->scope,
2011 res_get (zh->res, "setTmpDir"),0 );
2012 rsfd = rset_open(*rset, RSETF_WRITE);
2020 rset_write (rsfd, &key);
2025 static ZEBRA_RES rpn_sort_spec(ZebraHandle zh, Z_AttributesPlusTerm *zapt,
2026 oid_value attributeSet, NMEM stream,
2027 Z_SortKeySpecList *sort_sequence,
2028 const char *rank_type,
2031 struct rset_key_control *kc)
2034 int sort_relation_value;
2035 AttrType sort_relation_type;
2042 attr_init(&sort_relation_type, zapt, 7);
2043 sort_relation_value = attr_find(&sort_relation_type, &attributeSet);
2045 if (!sort_sequence->specs)
2047 sort_sequence->num_specs = 10;
2048 sort_sequence->specs = (Z_SortKeySpec **)
2049 nmem_malloc(stream, sort_sequence->num_specs *
2050 sizeof(*sort_sequence->specs));
2051 for (i = 0; i<sort_sequence->num_specs; i++)
2052 sort_sequence->specs[i] = 0;
2054 if (zapt->term->which != Z_Term_general)
2057 i = atoi_n ((char *) zapt->term->u.general->buf,
2058 zapt->term->u.general->len);
2059 if (i >= sort_sequence->num_specs)
2061 sprintf(termz, "%d", i);
2063 oe.proto = PROTO_Z3950;
2064 oe.oclass = CLASS_ATTSET;
2065 oe.value = attributeSet;
2066 if (!oid_ent_to_oid (&oe, oid))
2069 sks = (Z_SortKeySpec *) nmem_malloc(stream, sizeof(*sks));
2070 sks->sortElement = (Z_SortElement *)
2071 nmem_malloc(stream, sizeof(*sks->sortElement));
2072 sks->sortElement->which = Z_SortElement_generic;
2073 sk = sks->sortElement->u.generic = (Z_SortKey *)
2074 nmem_malloc(stream, sizeof(*sk));
2075 sk->which = Z_SortKey_sortAttributes;
2076 sk->u.sortAttributes = (Z_SortAttributes *)
2077 nmem_malloc(stream, sizeof(*sk->u.sortAttributes));
2079 sk->u.sortAttributes->id = oid;
2080 sk->u.sortAttributes->list = zapt->attributes;
2082 sks->sortRelation = (int *)
2083 nmem_malloc(stream, sizeof(*sks->sortRelation));
2084 if (sort_relation_value == 1)
2085 *sks->sortRelation = Z_SortKeySpec_ascending;
2086 else if (sort_relation_value == 2)
2087 *sks->sortRelation = Z_SortKeySpec_descending;
2089 *sks->sortRelation = Z_SortKeySpec_ascending;
2091 sks->caseSensitivity = (int *)
2092 nmem_malloc(stream, sizeof(*sks->caseSensitivity));
2093 *sks->caseSensitivity = 0;
2095 sks->which = Z_SortKeySpec_null;
2096 sks->u.null = odr_nullval ();
2097 sort_sequence->specs[i] = sks;
2098 *rset = rsnull_create (rset_nmem, kc, 0);
2103 static int parse_xpath(ZebraHandle zh, Z_AttributesPlusTerm *zapt,
2104 oid_value attributeSet,
2105 struct xpath_location_step *xpath, int max, NMEM mem)
2107 oid_value curAttributeSet = attributeSet;
2109 const char *use_string = 0;
2111 attr_init(&use, zapt, 1);
2112 attr_find_ex(&use, &curAttributeSet, &use_string);
2114 if (!use_string || *use_string != '/')
2117 return zebra_parse_xpath_str(use_string, xpath, max, mem);
2122 static RSET xpath_trunc(ZebraHandle zh, NMEM stream,
2123 int reg_type, const char *term, int use,
2124 oid_value curAttributeSet, NMEM rset_nmem,
2125 struct rset_key_control *kc)
2128 struct grep_info grep_info;
2129 char term_dict[2048];
2132 int ord = zebraExplain_lookup_attr_su(zh->reg->zei, reg_type,
2133 curAttributeSet, use);
2134 int ord_len, i, r, max_pos;
2135 int term_type = Z_Term_characterString;
2136 const char *flags = "void";
2138 if (grep_info_prepare(zh, 0 /* zapt */, &grep_info, '0') == ZEBRA_FAIL)
2139 return rsnull_create(rset_nmem, kc, 0);
2142 return rsnull_create(rset_nmem, kc, 0);
2144 term_dict[prefix_len++] = '|';
2146 term_dict[prefix_len++] = '(';
2148 ord_len = key_SU_encode (ord, ord_buf);
2149 for (i = 0; i<ord_len; i++)
2151 term_dict[prefix_len++] = 1;
2152 term_dict[prefix_len++] = ord_buf[i];
2154 term_dict[prefix_len++] = ')';
2155 strcpy(term_dict+prefix_len, term);
2157 grep_info.isam_p_indx = 0;
2158 r = dict_lookup_grep(zh->reg->dict, term_dict, 0,
2159 &grep_info, &max_pos, 0, grep_handle);
2160 yaz_log(YLOG_DEBUG, "%s %d positions", term,
2161 grep_info.isam_p_indx);
2162 rset = rset_trunc(zh, grep_info.isam_p_buf,
2163 grep_info.isam_p_indx, term, strlen(term),
2164 flags, 1, term_type,rset_nmem,
2165 kc, kc->scope, 0, reg_type, 0 /* hits_limit */,
2166 0 /* term_ref_id_str */);
2167 grep_info_delete(&grep_info);
2172 ZEBRA_RES rpn_search_xpath(ZebraHandle zh,
2173 oid_value attributeSet,
2174 int num_bases, char **basenames,
2175 NMEM stream, const char *rank_type, RSET rset,
2176 int xpath_len, struct xpath_location_step *xpath,
2179 struct rset_key_control *kc)
2181 oid_value curAttributeSet = attributeSet;
2191 yaz_log(YLOG_DEBUG, "xpath len=%d", xpath_len);
2192 for (i = 0; i<xpath_len; i++)
2194 yaz_log(log_level_rpn, "XPATH %d %s", i, xpath[i].part);
2198 curAttributeSet = VAL_IDXPATH;
2208 a[@attr = value]/b[@other = othervalue]
2210 /e/@a val range(e/,range(@a,freetext(w,1015,val),@a),e/)
2211 /a/b val range(b/a/,freetext(w,1016,val),b/a/)
2212 /a/b/@c val range(b/a/,range(@c,freetext(w,1016,val),@c),b/a/)
2213 /a/b[@c = y] val range(b/a/,freetext(w,1016,val),b/a/,@c = y)
2214 /a[@c = y]/b val range(a/,range(b/a/,freetext(w,1016,val),b/a/),a/,@c = y)
2215 /a[@c = x]/b[@c = y] range(a/,range(b/a/,freetext(w,1016,val),b/a/,@c = y),a/,@c = x)
2219 dict_grep_cmap (zh->reg->dict, 0, 0);
2221 for (base_no = 0; base_no < num_bases; base_no++)
2223 int level = xpath_len;
2226 if (zebraExplain_curDatabase (zh->reg->zei, basenames[base_no]))
2228 zebra_setError(zh, YAZ_BIB1_DATABASE_UNAVAILABLE,
2229 basenames[base_no]);
2233 while (--level >= 0)
2235 char xpath_rev[128];
2237 RSET rset_start_tag = 0, rset_end_tag = 0, rset_attr = 0;
2241 for (i = level; i >= 1; --i)
2243 const char *cp = xpath[i].part;
2249 memcpy (xpath_rev + len, "[^/]*", 5);
2252 else if (*cp == ' ')
2255 xpath_rev[len++] = 1;
2256 xpath_rev[len++] = ' ';
2260 xpath_rev[len++] = *cp;
2261 xpath_rev[len++] = '/';
2263 else if (i == 1) /* // case */
2265 xpath_rev[len++] = '.';
2266 xpath_rev[len++] = '*';
2271 if (xpath[level].predicate &&
2272 xpath[level].predicate->which == XPATH_PREDICATE_RELATION &&
2273 xpath[level].predicate->u.relation.name[0])
2275 WRBUF wbuf = wrbuf_alloc();
2276 wrbuf_puts(wbuf, xpath[level].predicate->u.relation.name+1);
2277 if (xpath[level].predicate->u.relation.value)
2279 const char *cp = xpath[level].predicate->u.relation.value;
2280 wrbuf_putc(wbuf, '=');
2284 if (strchr(REGEX_CHARS, *cp))
2285 wrbuf_putc(wbuf, '\\');
2286 wrbuf_putc(wbuf, *cp);
2290 wrbuf_puts(wbuf, "");
2291 rset_attr = xpath_trunc(
2292 zh, stream, '0', wrbuf_buf(wbuf), 3,
2293 curAttributeSet, rset_nmem, kc);
2294 wrbuf_free(wbuf, 1);
2301 yaz_log(log_level_rpn, "xpath_rev (%d) = %s", level, xpath_rev);
2302 if (strlen(xpath_rev))
2304 rset_start_tag = xpath_trunc(zh, stream, '0',
2305 xpath_rev, 1, curAttributeSet, rset_nmem, kc);
2307 rset_end_tag = xpath_trunc(zh, stream, '0',
2308 xpath_rev, 2, curAttributeSet, rset_nmem, kc);
2310 rset = rsbetween_create(rset_nmem, kc, kc->scope,
2311 rset_start_tag, rset,
2312 rset_end_tag, rset_attr);
2321 static ZEBRA_RES rpn_search_APT(ZebraHandle zh, Z_AttributesPlusTerm *zapt,
2322 oid_value attributeSet, NMEM stream,
2323 Z_SortKeySpecList *sort_sequence,
2324 int num_bases, char **basenames,
2327 struct rset_key_control *kc)
2329 ZEBRA_RES res = ZEBRA_OK;
2331 char *search_type = NULL;
2332 char rank_type[128];
2335 char termz[IT_MAX_WORD+1];
2338 struct xpath_location_step xpath[10];
2342 log_level_rpn = yaz_log_module_level("rpn");
2345 zebra_maps_attr(zh->reg->zebra_maps, zapt, ®_id, &search_type,
2346 rank_type, &complete_flag, &sort_flag);
2348 yaz_log(YLOG_DEBUG, "reg_id=%c", reg_id);
2349 yaz_log(YLOG_DEBUG, "complete_flag=%d", complete_flag);
2350 yaz_log(YLOG_DEBUG, "search_type=%s", search_type);
2351 yaz_log(YLOG_DEBUG, "rank_type=%s", rank_type);
2353 if (zapt_term_to_utf8(zh, zapt, termz) == ZEBRA_FAIL)
2357 return rpn_sort_spec(zh, zapt, attributeSet, stream, sort_sequence,
2358 rank_type, rset_nmem, rset, kc);
2359 /* consider if an X-Path query is used */
2360 xpath_len = parse_xpath(zh, zapt, attributeSet, xpath, 10, stream);
2363 xpath_use = 1016; /* searching for element by default */
2364 if (xpath[xpath_len-1].part[0] == '@')
2365 xpath_use = 1015; /* last step an attribute .. */
2368 /* search using one of the various search type strategies
2369 termz is our UTF-8 search term
2370 attributeSet is top-level default attribute set
2371 stream is ODR for search
2372 reg_id is the register type
2373 complete_flag is 1 for complete subfield, 0 for incomplete
2374 xpath_use is use-attribute to be used for X-Path search, 0 for none
2376 if (!strcmp(search_type, "phrase"))
2378 res = rpn_search_APT_phrase(zh, zapt, termz, attributeSet, stream,
2379 reg_id, complete_flag, rank_type,
2381 num_bases, basenames, rset_nmem,
2384 else if (!strcmp(search_type, "and-list"))
2386 res = rpn_search_APT_and_list(zh, zapt, termz, attributeSet, stream,
2387 reg_id, complete_flag, rank_type,
2389 num_bases, basenames, rset_nmem,
2392 else if (!strcmp(search_type, "or-list"))
2394 res = rpn_search_APT_or_list(zh, zapt, termz, attributeSet, stream,
2395 reg_id, complete_flag, rank_type,
2397 num_bases, basenames, rset_nmem,
2400 else if (!strcmp(search_type, "local"))
2402 res = rpn_search_APT_local(zh, zapt, termz, attributeSet, stream,
2403 rank_type, rset_nmem, rset, kc);
2405 else if (!strcmp(search_type, "numeric"))
2407 res = rpn_search_APT_numeric(zh, zapt, termz, attributeSet, stream,
2408 reg_id, complete_flag, rank_type,
2410 num_bases, basenames, rset_nmem,
2415 zebra_setError(zh, YAZ_BIB1_UNSUPP_STRUCTURE_ATTRIBUTE, 0);
2418 if (res != ZEBRA_OK)
2422 return rpn_search_xpath(zh, attributeSet, num_bases, basenames,
2423 stream, rank_type, *rset,
2424 xpath_len, xpath, rset_nmem, rset, kc);
2427 static ZEBRA_RES rpn_search_structure(ZebraHandle zh, Z_RPNStructure *zs,
2428 oid_value attributeSet,
2429 NMEM stream, NMEM rset_nmem,
2430 Z_SortKeySpecList *sort_sequence,
2431 int num_bases, char **basenames,
2432 RSET **result_sets, int *num_result_sets,
2433 Z_Operator *parent_op,
2434 struct rset_key_control *kc);
2436 ZEBRA_RES rpn_search_top(ZebraHandle zh, Z_RPNStructure *zs,
2437 oid_value attributeSet,
2438 NMEM stream, NMEM rset_nmem,
2439 Z_SortKeySpecList *sort_sequence,
2440 int num_bases, char **basenames,
2443 RSET *result_sets = 0;
2444 int num_result_sets = 0;
2446 struct rset_key_control *kc = zebra_key_control_create(zh);
2448 res = rpn_search_structure(zh, zs, attributeSet,
2451 num_bases, basenames,
2452 &result_sets, &num_result_sets,
2453 0 /* no parent op */,
2455 if (res != ZEBRA_OK)
2458 for (i = 0; i<num_result_sets; i++)
2459 rset_delete(result_sets[i]);
2464 assert(num_result_sets == 1);
2465 assert(result_sets);
2466 assert(*result_sets);
2467 *result_set = *result_sets;
2473 ZEBRA_RES rpn_search_structure(ZebraHandle zh, Z_RPNStructure *zs,
2474 oid_value attributeSet,
2475 NMEM stream, NMEM rset_nmem,
2476 Z_SortKeySpecList *sort_sequence,
2477 int num_bases, char **basenames,
2478 RSET **result_sets, int *num_result_sets,
2479 Z_Operator *parent_op,
2480 struct rset_key_control *kc)
2482 *num_result_sets = 0;
2483 if (zs->which == Z_RPNStructure_complex)
2486 Z_Operator *zop = zs->u.complex->roperator;
2487 RSET *result_sets_l = 0;
2488 int num_result_sets_l = 0;
2489 RSET *result_sets_r = 0;
2490 int num_result_sets_r = 0;
2492 res = rpn_search_structure(zh, zs->u.complex->s1,
2493 attributeSet, stream, rset_nmem,
2495 num_bases, basenames,
2496 &result_sets_l, &num_result_sets_l,
2498 if (res != ZEBRA_OK)
2501 for (i = 0; i<num_result_sets_l; i++)
2502 rset_delete(result_sets_l[i]);
2505 res = rpn_search_structure(zh, zs->u.complex->s2,
2506 attributeSet, stream, rset_nmem,
2508 num_bases, basenames,
2509 &result_sets_r, &num_result_sets_r,
2511 if (res != ZEBRA_OK)
2514 for (i = 0; i<num_result_sets_l; i++)
2515 rset_delete(result_sets_l[i]);
2516 for (i = 0; i<num_result_sets_r; i++)
2517 rset_delete(result_sets_r[i]);
2521 /* make a new list of result for all children */
2522 *num_result_sets = num_result_sets_l + num_result_sets_r;
2523 *result_sets = nmem_malloc(stream, *num_result_sets *
2524 sizeof(**result_sets));
2525 memcpy(*result_sets, result_sets_l,
2526 num_result_sets_l * sizeof(**result_sets));
2527 memcpy(*result_sets + num_result_sets_l, result_sets_r,
2528 num_result_sets_r * sizeof(**result_sets));
2530 if (!parent_op || parent_op->which != zop->which
2531 || (zop->which != Z_Operator_and &&
2532 zop->which != Z_Operator_or))
2534 /* parent node different from this one (or non-present) */
2535 /* we must combine result sets now */
2539 case Z_Operator_and:
2540 rset = rsmulti_and_create(rset_nmem, kc,
2542 *num_result_sets, *result_sets);
2545 rset = rsmulti_or_create(rset_nmem, kc,
2546 kc->scope, 0, /* termid */
2547 *num_result_sets, *result_sets);
2549 case Z_Operator_and_not:
2550 rset = rsbool_create_not(rset_nmem, kc,
2555 case Z_Operator_prox:
2556 if (zop->u.prox->which != Z_ProximityOperator_known)
2559 YAZ_BIB1_UNSUPP_PROX_UNIT_CODE,
2563 if (*zop->u.prox->u.known != Z_ProxUnit_word)
2565 zebra_setError_zint(zh,
2566 YAZ_BIB1_UNSUPP_PROX_UNIT_CODE,
2567 *zop->u.prox->u.known);
2572 rset = rsprox_create(rset_nmem, kc,
2574 *num_result_sets, *result_sets,
2575 *zop->u.prox->ordered,
2576 (!zop->u.prox->exclusion ?
2577 0 : *zop->u.prox->exclusion),
2578 *zop->u.prox->relationType,
2579 *zop->u.prox->distance );
2583 zebra_setError(zh, YAZ_BIB1_OPERATOR_UNSUPP, 0);
2586 *num_result_sets = 1;
2587 *result_sets = nmem_malloc(stream, *num_result_sets *
2588 sizeof(**result_sets));
2589 (*result_sets)[0] = rset;
2592 else if (zs->which == Z_RPNStructure_simple)
2597 if (zs->u.simple->which == Z_Operand_APT)
2599 yaz_log(YLOG_DEBUG, "rpn_search_APT");
2600 res = rpn_search_APT(zh, zs->u.simple->u.attributesPlusTerm,
2601 attributeSet, stream, sort_sequence,
2602 num_bases, basenames, rset_nmem, &rset,
2604 if (res != ZEBRA_OK)
2607 else if (zs->u.simple->which == Z_Operand_resultSetId)
2609 yaz_log(YLOG_DEBUG, "rpn_search_ref");
2610 rset = resultSetRef(zh, zs->u.simple->u.resultSetId);
2614 YAZ_BIB1_SPECIFIED_RESULT_SET_DOES_NOT_EXIST,
2615 zs->u.simple->u.resultSetId);
2622 zebra_setError(zh, YAZ_BIB1_UNSUPP_SEARCH, 0);
2625 *num_result_sets = 1;
2626 *result_sets = nmem_malloc(stream, *num_result_sets *
2627 sizeof(**result_sets));
2628 (*result_sets)[0] = rset;
2632 zebra_setError(zh, YAZ_BIB1_UNSUPP_SEARCH, 0);
2638 struct scan_info_entry {
2644 struct scan_info_entry *list;
2650 static int scan_handle (char *name, const char *info, int pos, void *client)
2652 int len_prefix, idx;
2653 struct scan_info *scan_info = (struct scan_info *) client;
2655 len_prefix = strlen(scan_info->prefix);
2656 if (memcmp (name, scan_info->prefix, len_prefix))
2659 idx = scan_info->after - pos + scan_info->before;
2665 scan_info->list[idx].term = (char *)
2666 odr_malloc(scan_info->odr, strlen(name + len_prefix)+1);
2667 strcpy(scan_info->list[idx].term, name + len_prefix);
2668 assert (*info == sizeof(ISAM_P));
2669 memcpy (&scan_info->list[idx].isam_p, info+1, sizeof(ISAM_P));
2673 void zebra_term_untrans_iconv(ZebraHandle zh, NMEM stream, int reg_type,
2674 char **dst, const char *src)
2676 char term_src[IT_MAX_WORD];
2677 char term_dst[IT_MAX_WORD];
2679 zebra_term_untrans (zh, reg_type, term_src, src);
2681 if (zh->iconv_from_utf8 != 0)
2684 char *inbuf = term_src;
2685 size_t inleft = strlen(term_src);
2686 char *outbuf = term_dst;
2687 size_t outleft = sizeof(term_dst)-1;
2690 ret = yaz_iconv (zh->iconv_from_utf8, &inbuf, &inleft,
2692 if (ret == (size_t)(-1))
2695 len = outbuf - term_dst;
2696 *dst = nmem_malloc(stream, len + 1);
2698 memcpy (*dst, term_dst, len);
2702 *dst = nmem_strdup(stream, term_src);
2705 static void count_set(ZebraHandle zh, RSET rset, zint *count)
2711 yaz_log(YLOG_DEBUG, "count_set");
2713 rset->hits_limit = zh->approx_limit;
2716 rfd = rset_open(rset, RSETF_READ);
2717 while (rset_read(rfd, &key,0 /* never mind terms */))
2719 if (key.mem[0] != psysno)
2721 psysno = key.mem[0];
2722 if (rfd->counted_items >= rset->hits_limit)
2727 *count = rset->hits_count;
2730 ZEBRA_RES rpn_scan(ZebraHandle zh, ODR stream, Z_AttributesPlusTerm *zapt,
2731 oid_value attributeset,
2732 int num_bases, char **basenames,
2733 int *position, int *num_entries, ZebraScanEntry **list,
2734 int *is_partial, RSET limit_set, int return_zero)
2737 int pos = *position;
2738 int num = *num_entries;
2742 char termz[IT_MAX_WORD+20];
2745 const char *use_string = 0;
2746 struct scan_info *scan_info_array;
2747 ZebraScanEntry *glist;
2748 int ords[32], ord_no = 0;
2751 int bases_ok = 0; /* no of databases with OK attribute */
2752 int errCode = 0; /* err code (if any is not OK) */
2753 char *errString = 0; /* addinfo */
2756 char *search_type = NULL;
2757 char rank_type[128];
2760 NMEM rset_nmem = NULL;
2761 struct rset_key_control *kc = 0;
2766 if (attributeset == VAL_NONE)
2767 attributeset = VAL_BIB1;
2772 int termset_value_numeric;
2773 const char *termset_value_string;
2774 attr_init(&termset, zapt, 8);
2775 termset_value_numeric =
2776 attr_find_ex(&termset, NULL, &termset_value_string);
2777 if (termset_value_numeric != -1)
2780 const char *termset_name = 0;
2782 if (termset_value_numeric != -2)
2785 sprintf(resname, "%d", termset_value_numeric);
2786 termset_name = resname;
2789 termset_name = termset_value_string;
2791 limit_set = resultSetRef (zh, termset_name);
2795 yaz_log(YLOG_DEBUG, "position = %d, num = %d set=%d",
2796 pos, num, attributeset);
2798 attr_init(&use, zapt, 1);
2799 use_value = attr_find_ex(&use, &attributeset, &use_string);
2801 if (zebra_maps_attr(zh->reg->zebra_maps, zapt, ®_id, &search_type,
2802 rank_type, &complete_flag, &sort_flag))
2805 zebra_setError(zh, YAZ_BIB1_UNSUPP_ATTRIBUTE_TYPE, 0);
2808 yaz_log(YLOG_DEBUG, "use_value = %d", use_value);
2810 if (use_value == -1)
2812 for (base_no = 0; base_no < num_bases && ord_no < 32; base_no++)
2814 data1_local_attribute *local_attr;
2818 if (zebraExplain_curDatabase (zh->reg->zei, basenames[base_no]))
2820 zebra_setError(zh, YAZ_BIB1_DATABASE_UNAVAILABLE,
2821 basenames[base_no]);
2827 (ord = zebraExplain_lookup_attr_str(zh->reg->zei, reg_id,
2830 /* we have a match for a raw string attribute */
2832 ords[ord_no++] = ord;
2833 attp.local_attributes = 0; /* no more attributes */
2839 if ((r = att_getentbyatt (zh, &attp, attributeset, use_value,
2842 yaz_log(YLOG_DEBUG, "att_getentbyatt fail. set=%d use=%d",
2843 attributeset, use_value);
2846 errCode = YAZ_BIB1_UNSUPP_USE_ATTRIBUTE;
2848 zebra_setError(zh, YAZ_BIB1_UNSUPP_USE_ATTRIBUTE,
2851 zebra_setError_zint(zh, YAZ_BIB1_UNSUPP_USE_ATTRIBUTE,
2856 zebra_setError(zh, YAZ_BIB1_UNSUPP_ATTRIBUTE_SET, 0);
2862 for (local_attr = attp.local_attributes; local_attr && ord_no < 32;
2863 local_attr = local_attr->next)
2865 ord = zebraExplain_lookup_attr_su(zh->reg->zei, reg_id,
2866 attp.attset_ordinal,
2869 ords[ord_no++] = ord;
2872 if (!bases_ok && errCode)
2874 zebra_setError(zh, errCode, errString);
2883 /* prepare dictionary scanning */
2895 yaz_log(YLOG_DEBUG, "rpn_scan pos=%d num=%d before=%d "
2896 "after=%d before+after=%d",
2897 pos, num, before, after, before+after);
2898 scan_info_array = (struct scan_info *)
2899 odr_malloc(stream, ord_no * sizeof(*scan_info_array));
2900 for (i = 0; i < ord_no; i++)
2902 int j, prefix_len = 0;
2903 int before_tmp = before, after_tmp = after;
2904 struct scan_info *scan_info = scan_info_array + i;
2905 struct rpn_char_map_info rcmi;
2907 rpn_char_map_prepare (zh->reg, reg_id, &rcmi);
2909 scan_info->before = before;
2910 scan_info->after = after;
2911 scan_info->odr = stream;
2913 scan_info->list = (struct scan_info_entry *)
2914 odr_malloc(stream, (before+after) * sizeof(*scan_info->list));
2915 for (j = 0; j<before+after; j++)
2916 scan_info->list[j].term = NULL;
2918 prefix_len += key_SU_encode (ords[i], termz + prefix_len);
2919 termz[prefix_len] = 0;
2920 strcpy(scan_info->prefix, termz);
2922 if (trans_scan_term(zh, zapt, termz+prefix_len, reg_id) == ZEBRA_FAIL)
2925 dict_scan(zh->reg->dict, termz, &before_tmp, &after_tmp,
2926 scan_info, scan_handle);
2928 glist = (ZebraScanEntry *)
2929 odr_malloc(stream, (before+after)*sizeof(*glist));
2931 rset_nmem = nmem_create();
2932 kc = zebra_key_control_create(zh);
2934 /* consider terms after main term */
2935 for (i = 0; i < ord_no; i++)
2939 for (i = 0; i<after; i++)
2942 const char *mterm = NULL;
2945 int lo = i + pos-1; /* offset in result list */
2947 /* find: j0 is the first of the minimal values */
2948 for (j = 0; j < ord_no; j++)
2950 if (ptr[j] < before+after && ptr[j] >= 0 &&
2951 (tst = scan_info_array[j].list[ptr[j]].term) &&
2952 (!mterm || strcmp (tst, mterm) < 0))
2959 break; /* no value found, stop */
2961 /* get result set for first one , but only if it's within bounds */
2964 /* get result set for first term */
2965 zebra_term_untrans_iconv(zh, stream->mem, reg_id,
2966 &glist[lo].term, mterm);
2967 rset = rset_trunc(zh, &scan_info_array[j0].list[ptr[j0]].isam_p, 1,
2968 glist[lo].term, strlen(glist[lo].term),
2969 NULL, 0, zapt->term->which, rset_nmem,
2970 kc, kc->scope, 0, reg_id, 0 /* hits_limit */,
2971 0 /* term_ref_id_str */);
2973 ptr[j0]++; /* move index for this set .. */
2974 /* get result set for remaining scan terms */
2975 for (j = j0+1; j<ord_no; j++)
2977 if (ptr[j] < before+after && ptr[j] >= 0 &&
2978 (tst = scan_info_array[j].list[ptr[j]].term) &&
2979 !strcmp (tst, mterm))
2988 zh, &scan_info_array[j].list[ptr[j]].isam_p, 1,
2990 strlen(glist[lo].term), NULL, 0,
2991 zapt->term->which,rset_nmem,
2992 kc, kc->scope, 0, reg_id, 0 /* hits_limit */,
2993 0 /* term_ref_id_str */ );
2994 rset = rsmulti_or_create(rset_nmem, kc,
2995 kc->scope, 0 /* termid */,
3004 /* merge with limit_set if given */
3009 rsets[1] = rset_dup(limit_set);
3011 rset = rsmulti_and_create(rset_nmem, kc,
3016 count_set(zh, rset, &count);
3017 glist[lo].occurrences = count;
3023 *num_entries -= (after-i);
3025 if (*num_entries < 0)
3028 nmem_destroy(rset_nmem);
3033 /* consider terms before main term */
3034 for (i = 0; i<ord_no; i++)
3037 for (i = 0; i<before; i++)
3040 const char *mterm = NULL;
3043 int lo = before-1-i; /* offset in result list */
3046 for (j = 0; j <ord_no; j++)
3048 if (ptr[j] < before && ptr[j] >= 0 &&
3049 (tst = scan_info_array[j].list[before-1-ptr[j]].term) &&
3050 (!mterm || strcmp (tst, mterm) > 0))
3059 zebra_term_untrans_iconv(zh, stream->mem, reg_id,
3060 &glist[lo].term, mterm);
3063 (zh, &scan_info_array[j0].list[before-1-ptr[j0]].isam_p, 1,
3064 glist[lo].term, strlen(glist[lo].term),
3065 NULL, 0, zapt->term->which, rset_nmem,
3066 kc, kc->scope, 0, reg_id, 0 /* hits_limit */,
3067 0 /* term_ref_id_str */);
3071 for (j = j0+1; j<ord_no; j++)
3073 if (ptr[j] < before && ptr[j] >= 0 &&
3074 (tst = scan_info_array[j].list[before-1-ptr[j]].term) &&
3075 !strcmp (tst, mterm))
3080 rsets[1] = rset_trunc(
3082 &scan_info_array[j].list[before-1-ptr[j]].isam_p, 1,
3084 strlen(glist[lo].term), NULL, 0,
3085 zapt->term->which, rset_nmem,
3086 kc, kc->scope, 0, reg_id, 0 /* hits_limit */,
3087 0 /* term_ref_id_str */);
3088 rset = rsmulti_or_create(rset_nmem, kc,
3089 kc->scope, 0 /* termid */, 2, rsets);
3098 rsets[1] = rset_dup(limit_set);
3100 rset = rsmulti_and_create(rset_nmem, kc,
3101 kc->scope, 2, rsets);
3103 count_set(zh, rset, &count);
3104 glist[lo].occurrences = count;
3108 nmem_destroy(rset_nmem);
3115 if (*num_entries <= 0)
3122 *list = glist + i; /* list is set to first 'real' entry */
3124 yaz_log(YLOG_DEBUG, "position = %d, num_entries = %d",
3125 *position, *num_entries);