1 /* $Id: zrpn.c,v 1.212 2006-05-10 08:13:23 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, 0);
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];
1242 if (ord_len > init_pos)
1249 term_dict[prefix_len++] = ')';
1250 term_dict[prefix_len] = '\0';
1252 switch (truncation_value)
1254 case -1: /* not specified */
1255 case 100: /* do not truncate */
1256 if (!string_relation (zh, zapt, &termp, term_dict,
1258 reg_type, space_split, term_dst,
1263 zebra_setError(zh, relation_error, 0);
1270 case 1: /* right truncation */
1271 term_dict[j++] = '(';
1272 if (!term_100(zh->reg->zebra_maps, reg_type,
1273 &termp, term_dict + j, space_split, term_dst))
1278 strcat(term_dict, ".*)");
1280 case 2: /* keft truncation */
1281 term_dict[j++] = '('; term_dict[j++] = '.'; term_dict[j++] = '*';
1282 if (!term_100(zh->reg->zebra_maps, reg_type,
1283 &termp, term_dict + j, space_split, term_dst))
1288 strcat(term_dict, ")");
1290 case 3: /* left&right truncation */
1291 term_dict[j++] = '('; term_dict[j++] = '.'; term_dict[j++] = '*';
1292 if (!term_100(zh->reg->zebra_maps, reg_type,
1293 &termp, term_dict + j, space_split, term_dst))
1298 strcat(term_dict, ".*)");
1300 case 101: /* process # in term */
1301 term_dict[j++] = '(';
1302 if (!term_101(zh->reg->zebra_maps, reg_type,
1303 &termp, term_dict + j, space_split, term_dst))
1308 strcat(term_dict, ")");
1310 case 102: /* Regexp-1 */
1311 term_dict[j++] = '(';
1312 if (!term_102(zh->reg->zebra_maps, reg_type,
1313 &termp, term_dict + j, space_split, term_dst))
1318 strcat(term_dict, ")");
1320 case 103: /* Regexp-2 */
1322 term_dict[j++] = '(';
1323 if (!term_103(zh->reg->zebra_maps, reg_type,
1324 &termp, term_dict + j, ®ex_range,
1325 space_split, term_dst))
1330 strcat(term_dict, ")");
1332 case 104: /* process # and ! in term */
1333 term_dict[j++] = '(';
1334 if (!term_104(zh->reg->zebra_maps, reg_type,
1335 &termp, term_dict + j, space_split, term_dst))
1340 strcat(term_dict, ")");
1342 case 105: /* process * and ! in term */
1343 term_dict[j++] = '(';
1344 if (!term_105(zh->reg->zebra_maps, reg_type,
1345 &termp, term_dict + j, space_split, term_dst, 1))
1350 strcat(term_dict, ")");
1352 case 106: /* process * and ! in term */
1353 term_dict[j++] = '(';
1354 if (!term_105(zh->reg->zebra_maps, reg_type,
1355 &termp, term_dict + j, space_split, term_dst, 0))
1360 strcat(term_dict, ")");
1363 zebra_setError_zint(zh,
1364 YAZ_BIB1_UNSUPP_TRUNCATION_ATTRIBUTE,
1371 const char *input = term_dict + prefix_len;
1372 esc_str(buf, sizeof(buf), input, strlen(input));
1376 yaz_log(log_level_rpn, "dict_lookup_grep: %s", term_dict+prefix_len);
1377 r = dict_lookup_grep(zh->reg->dict, term_dict, regex_range,
1378 grep_info, &max_pos, init_pos,
1381 yaz_log(YLOG_WARN, "dict_lookup_grep fail %d", r);
1387 yaz_log(YLOG_DEBUG, "%d positions", grep_info->isam_p_indx);
1392 /* convert APT search term to UTF8 */
1393 static ZEBRA_RES zapt_term_to_utf8(ZebraHandle zh, Z_AttributesPlusTerm *zapt,
1397 Z_Term *term = zapt->term;
1399 switch (term->which)
1401 case Z_Term_general:
1402 if (zh->iconv_to_utf8 != 0)
1404 char *inbuf = (char *) term->u.general->buf;
1405 size_t inleft = term->u.general->len;
1406 char *outbuf = termz;
1407 size_t outleft = IT_MAX_WORD-1;
1410 ret = yaz_iconv(zh->iconv_to_utf8, &inbuf, &inleft,
1412 if (ret == (size_t)(-1))
1414 ret = yaz_iconv(zh->iconv_to_utf8, 0, 0, 0, 0);
1417 YAZ_BIB1_QUERY_TERM_INCLUDES_CHARS_THAT_DO_NOT_TRANSLATE_INTO_,
1425 sizez = term->u.general->len;
1426 if (sizez > IT_MAX_WORD-1)
1427 sizez = IT_MAX_WORD-1;
1428 memcpy (termz, term->u.general->buf, sizez);
1429 termz[sizez] = '\0';
1432 case Z_Term_characterString:
1433 sizez = strlen(term->u.characterString);
1434 if (sizez > IT_MAX_WORD-1)
1435 sizez = IT_MAX_WORD-1;
1436 memcpy (termz, term->u.characterString, sizez);
1437 termz[sizez] = '\0';
1440 zebra_setError(zh, YAZ_BIB1_UNSUPP_CODED_VALUE_FOR_TERM, 0);
1446 /* convert APT SCAN term to internal cmap */
1447 static ZEBRA_RES trans_scan_term(ZebraHandle zh, Z_AttributesPlusTerm *zapt,
1448 char *termz, int reg_type)
1450 char termz0[IT_MAX_WORD];
1452 if (zapt_term_to_utf8(zh, zapt, termz0) == ZEBRA_FAIL)
1453 return ZEBRA_FAIL; /* error */
1457 const char *cp = (const char *) termz0;
1458 const char *cp_end = cp + strlen(cp);
1461 const char *space_map = NULL;
1464 while ((len = (cp_end - cp)) > 0)
1466 map = zebra_maps_input(zh->reg->zebra_maps, reg_type, &cp, len, 0);
1467 if (**map == *CHR_SPACE)
1472 for (src = space_map; *src; src++)
1475 for (src = *map; *src; src++)
1484 static void grep_info_delete(struct grep_info *grep_info)
1487 xfree(grep_info->term_no);
1489 xfree(grep_info->isam_p_buf);
1492 static ZEBRA_RES grep_info_prepare(ZebraHandle zh,
1493 Z_AttributesPlusTerm *zapt,
1494 struct grep_info *grep_info,
1498 int termset_value_numeric;
1499 const char *termset_value_string;
1502 grep_info->term_no = 0;
1504 grep_info->isam_p_size = 0;
1505 grep_info->isam_p_buf = NULL;
1507 grep_info->reg_type = reg_type;
1508 grep_info->termset = 0;
1512 attr_init(&termset, zapt, 8);
1513 termset_value_numeric =
1514 attr_find_ex(&termset, NULL, &termset_value_string);
1515 if (termset_value_numeric != -1)
1518 const char *termset_name = 0;
1519 if (termset_value_numeric != -2)
1522 sprintf(resname, "%d", termset_value_numeric);
1523 termset_name = resname;
1526 termset_name = termset_value_string;
1527 yaz_log(log_level_rpn, "creating termset set %s", termset_name);
1528 grep_info->termset = resultSetAdd(zh, termset_name, 1);
1529 if (!grep_info->termset)
1531 zebra_setError(zh, YAZ_BIB1_ILLEGAL_RESULT_SET_NAME, termset_name);
1539 \brief Create result set(s) for list of terms
1540 \param zh Zebra Handle
1541 \param termz term as used in query but converted to UTF-8
1542 \param attributeSet default attribute set
1543 \param stream memory for result
1544 \param reg_type register type ('w', 'p',..)
1545 \param complete_flag whether it's phrases or not
1546 \param rank_type term flags for ranking
1547 \param xpath_use use attribute for X-Path (-1 for no X-path)
1548 \param num_bases number of databases
1549 \param basenames array of databases
1550 \param rset_mem memory for result sets
1551 \param result_sets output result set for each term in list (output)
1552 \param number number of output result sets
1553 \param kc rset key control to be used for created result sets
1555 static ZEBRA_RES term_list_trunc(ZebraHandle zh,
1556 Z_AttributesPlusTerm *zapt,
1558 oid_value attributeSet,
1560 int reg_type, int complete_flag,
1561 const char *rank_type, int xpath_use,
1562 int num_bases, char **basenames,
1564 RSET **result_sets, int *num_result_sets,
1565 struct rset_key_control *kc)
1567 char term_dst[IT_MAX_WORD+1];
1568 struct grep_info grep_info;
1569 const char *termp = termz;
1572 *num_result_sets = 0;
1574 if (grep_info_prepare(zh, zapt, &grep_info, reg_type) == ZEBRA_FAIL)
1580 if (alloc_sets == *num_result_sets)
1583 RSET *rnew = (RSET *) nmem_malloc(stream, (alloc_sets+add) *
1586 memcpy(rnew, *result_sets, alloc_sets * sizeof(*rnew));
1587 alloc_sets = alloc_sets + add;
1588 *result_sets = rnew;
1590 res = term_trunc(zh, zapt, &termp, attributeSet,
1592 reg_type, complete_flag,
1593 num_bases, basenames,
1594 term_dst, rank_type,
1595 xpath_use, rset_nmem,
1596 &(*result_sets)[*num_result_sets],
1598 if (res != ZEBRA_OK)
1601 for (i = 0; i < *num_result_sets; i++)
1602 rset_delete((*result_sets)[i]);
1603 grep_info_delete (&grep_info);
1606 if ((*result_sets)[*num_result_sets] == 0)
1608 (*num_result_sets)++;
1610 grep_info_delete(&grep_info);
1614 static ZEBRA_RES rpn_search_APT_phrase(ZebraHandle zh,
1615 Z_AttributesPlusTerm *zapt,
1616 const char *termz_org,
1617 oid_value attributeSet,
1619 int reg_type, int complete_flag,
1620 const char *rank_type, int xpath_use,
1621 int num_bases, char **basenames,
1624 struct rset_key_control *kc)
1626 RSET *result_sets = 0;
1627 int num_result_sets = 0;
1629 term_list_trunc(zh, zapt, termz_org, attributeSet,
1630 stream, reg_type, complete_flag,
1631 rank_type, xpath_use,
1632 num_bases, basenames,
1634 &result_sets, &num_result_sets, kc);
1635 if (res != ZEBRA_OK)
1637 if (num_result_sets == 0)
1638 *rset = rsnull_create (rset_nmem, kc, 0);
1639 else if (num_result_sets == 1)
1640 *rset = result_sets[0];
1642 *rset = rsprox_create(rset_nmem, kc, kc->scope,
1643 num_result_sets, result_sets,
1644 1 /* ordered */, 0 /* exclusion */,
1645 3 /* relation */, 1 /* distance */);
1651 static ZEBRA_RES rpn_search_APT_or_list(ZebraHandle zh,
1652 Z_AttributesPlusTerm *zapt,
1653 const char *termz_org,
1654 oid_value attributeSet,
1656 int reg_type, int complete_flag,
1657 const char *rank_type,
1659 int num_bases, char **basenames,
1662 struct rset_key_control *kc)
1664 RSET *result_sets = 0;
1665 int num_result_sets = 0;
1667 term_list_trunc(zh, zapt, termz_org, attributeSet,
1668 stream, reg_type, complete_flag,
1669 rank_type, xpath_use,
1670 num_bases, basenames,
1672 &result_sets, &num_result_sets, kc);
1673 if (res != ZEBRA_OK)
1675 if (num_result_sets == 0)
1676 *rset = rsnull_create (rset_nmem, kc, 0);
1677 else if (num_result_sets == 1)
1678 *rset = result_sets[0];
1680 *rset = rsmulti_or_create(rset_nmem, kc, kc->scope, 0 /* termid */,
1681 num_result_sets, result_sets);
1687 static ZEBRA_RES rpn_search_APT_and_list(ZebraHandle zh,
1688 Z_AttributesPlusTerm *zapt,
1689 const char *termz_org,
1690 oid_value attributeSet,
1692 int reg_type, int complete_flag,
1693 const char *rank_type,
1695 int num_bases, char **basenames,
1698 struct rset_key_control *kc)
1700 RSET *result_sets = 0;
1701 int num_result_sets = 0;
1703 term_list_trunc(zh, zapt, termz_org, attributeSet,
1704 stream, reg_type, complete_flag,
1705 rank_type, xpath_use,
1706 num_bases, basenames,
1708 &result_sets, &num_result_sets,
1710 if (res != ZEBRA_OK)
1712 if (num_result_sets == 0)
1713 *rset = rsnull_create (rset_nmem, kc, 0);
1714 else if (num_result_sets == 1)
1715 *rset = result_sets[0];
1717 *rset = rsmulti_and_create(rset_nmem, kc, kc->scope,
1718 num_result_sets, result_sets);
1724 static int numeric_relation(ZebraHandle zh, Z_AttributesPlusTerm *zapt,
1725 const char **term_sub,
1727 oid_value attributeSet,
1728 struct grep_info *grep_info,
1738 char *term_tmp = term_dict + strlen(term_dict);
1741 attr_init(&relation, zapt, 2);
1742 relation_value = attr_find(&relation, NULL);
1744 yaz_log(log_level_rpn, "numeric relation value=%d", relation_value);
1746 if (!term_100(zh->reg->zebra_maps, reg_type, term_sub, term_tmp, 1,
1749 term_value = atoi (term_tmp);
1750 switch (relation_value)
1753 yaz_log(log_level_rpn, "Relation <");
1754 gen_regular_rel(term_tmp, term_value-1, 1);
1757 yaz_log(log_level_rpn, "Relation <=");
1758 gen_regular_rel(term_tmp, term_value, 1);
1761 yaz_log(log_level_rpn, "Relation >=");
1762 gen_regular_rel(term_tmp, term_value, 0);
1765 yaz_log(log_level_rpn, "Relation >");
1766 gen_regular_rel(term_tmp, term_value+1, 0);
1770 yaz_log(log_level_rpn, "Relation =");
1771 sprintf(term_tmp, "(0*%d)", term_value);
1774 *error_code = YAZ_BIB1_UNSUPP_RELATION_ATTRIBUTE;
1777 yaz_log(log_level_rpn, "dict_lookup_grep: %s", term_tmp);
1778 r = dict_lookup_grep(zh->reg->dict, term_dict, 0, grep_info, max_pos,
1781 yaz_log(YLOG_WARN, "dict_lookup_grep fail, rel = gt: %d", r);
1782 yaz_log(log_level_rpn, "%d positions", grep_info->isam_p_indx);
1786 static ZEBRA_RES numeric_term(ZebraHandle zh, Z_AttributesPlusTerm *zapt,
1787 const char **term_sub,
1788 oid_value attributeSet,
1789 struct grep_info *grep_info,
1790 int reg_type, int complete_flag,
1791 int num_bases, char **basenames,
1792 char *term_dst, int xpath_use, NMEM stream)
1794 char term_dict[2*IT_MAX_WORD+2];
1798 const char *use_string = 0;
1799 oid_value curAttributeSet = attributeSet;
1801 struct rpn_char_map_info rcmi;
1803 int bases_ok = 0; /* no of databases with OK attribute */
1805 rpn_char_map_prepare (zh->reg, reg_type, &rcmi);
1806 attr_init(&use, zapt, 1);
1807 use_value = attr_find_ex(&use, &curAttributeSet, &use_string);
1809 if (use_value == -1)
1812 for (base_no = 0; base_no < num_bases; base_no++)
1815 data1_local_attribute id_xpath_attr;
1816 data1_local_attribute *local_attr;
1817 int max_pos, prefix_len = 0;
1818 int relation_error = 0;
1821 if (use_value == -2) /* string attribute (assume IDXPATH/any) */
1823 use_value = xpath_use;
1824 attp.local_attributes = &id_xpath_attr;
1825 attp.attset_ordinal = VAL_IDXPATH;
1826 id_xpath_attr.next = 0;
1827 id_xpath_attr.local = use_value;
1829 else if (curAttributeSet == VAL_IDXPATH)
1831 attp.local_attributes = &id_xpath_attr;
1832 attp.attset_ordinal = VAL_IDXPATH;
1833 id_xpath_attr.next = 0;
1834 id_xpath_attr.local = use_value;
1838 if ((r = att_getentbyatt (zh, &attp, curAttributeSet, use_value,
1841 yaz_log(YLOG_DEBUG, "att_getentbyatt fail. set=%d use=%d r=%d",
1842 curAttributeSet, use_value, r);
1847 YAZ_BIB1_UNSUPP_USE_ATTRIBUTE,
1850 zebra_setError_zint(zh, YAZ_BIB1_UNSUPP_USE_ATTRIBUTE,
1854 zebra_setError(zh, YAZ_BIB1_UNSUPP_ATTRIBUTE_SET, 0);
1858 if (zebraExplain_curDatabase (zh->reg->zei, basenames[base_no]))
1860 zebra_setError(zh, YAZ_BIB1_DATABASE_UNAVAILABLE,
1861 basenames[base_no]);
1864 for (local_attr = attp.local_attributes; local_attr;
1865 local_attr = local_attr->next)
1871 ord = zebraExplain_lookup_attr_su(zh->reg->zei,
1873 attp.attset_ordinal,
1878 term_dict[prefix_len++] = '|';
1880 term_dict[prefix_len++] = '(';
1882 ord_len = key_SU_encode (ord, ord_buf);
1883 for (i = 0; i<ord_len; i++)
1885 term_dict[prefix_len++] = 1;
1886 term_dict[prefix_len++] = ord_buf[i];
1891 zebra_setError_zint(zh, YAZ_BIB1_UNSUPP_USE_ATTRIBUTE, use_value);
1895 term_dict[prefix_len++] = ')';
1896 term_dict[prefix_len] = '\0';
1897 if (!numeric_relation(zh, zapt, &termp, term_dict,
1898 attributeSet, grep_info, &max_pos, reg_type,
1899 term_dst, &relation_error))
1903 zebra_setError(zh, relation_error, 0);
1913 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;
1937 zint hits_limit_value;
1938 const char *term_ref_id_str = 0;
1940 term_limits_APT(zh, zapt, &hits_limit_value, &term_ref_id_str, stream);
1942 yaz_log(log_level_rpn, "APT_numeric t='%s'", termz);
1943 if (grep_info_prepare(zh, zapt, &grep_info, reg_type) == ZEBRA_FAIL)
1947 if (alloc_sets == num_result_sets)
1950 RSET *rnew = (RSET *) nmem_malloc(stream, (alloc_sets+add) *
1953 memcpy(rnew, result_sets, alloc_sets * sizeof(*rnew));
1954 alloc_sets = alloc_sets + add;
1957 yaz_log(YLOG_DEBUG, "APT_numeric termp=%s", termp);
1958 grep_info.isam_p_indx = 0;
1959 res = numeric_term(zh, zapt, &termp, attributeSet, &grep_info,
1960 reg_type, complete_flag, num_bases, basenames,
1961 term_dst, xpath_use,
1963 if (res == ZEBRA_FAIL || termp == 0)
1965 yaz_log(YLOG_DEBUG, "term: %s", term_dst);
1966 result_sets[num_result_sets] =
1967 rset_trunc(zh, grep_info.isam_p_buf,
1968 grep_info.isam_p_indx, term_dst,
1969 strlen(term_dst), rank_type,
1970 0 /* preserve position */,
1971 zapt->term->which, rset_nmem,
1972 kc, kc->scope, 0, reg_type,
1975 if (!result_sets[num_result_sets])
1979 grep_info_delete(&grep_info);
1983 for (i = 0; i<num_result_sets; i++)
1984 rset_delete(result_sets[i]);
1987 if (num_result_sets == 0)
1988 *rset = rsnull_create(rset_nmem, kc, 0);
1989 if (num_result_sets == 1)
1990 *rset = result_sets[0];
1992 *rset = rsmulti_and_create(rset_nmem, kc, kc->scope,
1993 num_result_sets, result_sets);
1999 static ZEBRA_RES rpn_search_APT_local(ZebraHandle zh,
2000 Z_AttributesPlusTerm *zapt,
2002 oid_value attributeSet,
2004 const char *rank_type, NMEM rset_nmem,
2006 struct rset_key_control *kc)
2011 *rset = rstemp_create(rset_nmem, kc, kc->scope,
2012 res_get (zh->res, "setTmpDir"),0 );
2013 rsfd = rset_open(*rset, RSETF_WRITE);
2021 rset_write (rsfd, &key);
2026 static ZEBRA_RES rpn_sort_spec(ZebraHandle zh, Z_AttributesPlusTerm *zapt,
2027 oid_value attributeSet, NMEM stream,
2028 Z_SortKeySpecList *sort_sequence,
2029 const char *rank_type,
2032 struct rset_key_control *kc)
2035 int sort_relation_value;
2036 AttrType sort_relation_type;
2043 attr_init(&sort_relation_type, zapt, 7);
2044 sort_relation_value = attr_find(&sort_relation_type, &attributeSet);
2046 if (!sort_sequence->specs)
2048 sort_sequence->num_specs = 10;
2049 sort_sequence->specs = (Z_SortKeySpec **)
2050 nmem_malloc(stream, sort_sequence->num_specs *
2051 sizeof(*sort_sequence->specs));
2052 for (i = 0; i<sort_sequence->num_specs; i++)
2053 sort_sequence->specs[i] = 0;
2055 if (zapt->term->which != Z_Term_general)
2058 i = atoi_n ((char *) zapt->term->u.general->buf,
2059 zapt->term->u.general->len);
2060 if (i >= sort_sequence->num_specs)
2062 sprintf(termz, "%d", i);
2064 oe.proto = PROTO_Z3950;
2065 oe.oclass = CLASS_ATTSET;
2066 oe.value = attributeSet;
2067 if (!oid_ent_to_oid (&oe, oid))
2070 sks = (Z_SortKeySpec *) nmem_malloc(stream, sizeof(*sks));
2071 sks->sortElement = (Z_SortElement *)
2072 nmem_malloc(stream, sizeof(*sks->sortElement));
2073 sks->sortElement->which = Z_SortElement_generic;
2074 sk = sks->sortElement->u.generic = (Z_SortKey *)
2075 nmem_malloc(stream, sizeof(*sk));
2076 sk->which = Z_SortKey_sortAttributes;
2077 sk->u.sortAttributes = (Z_SortAttributes *)
2078 nmem_malloc(stream, sizeof(*sk->u.sortAttributes));
2080 sk->u.sortAttributes->id = oid;
2081 sk->u.sortAttributes->list = zapt->attributes;
2083 sks->sortRelation = (int *)
2084 nmem_malloc(stream, sizeof(*sks->sortRelation));
2085 if (sort_relation_value == 1)
2086 *sks->sortRelation = Z_SortKeySpec_ascending;
2087 else if (sort_relation_value == 2)
2088 *sks->sortRelation = Z_SortKeySpec_descending;
2090 *sks->sortRelation = Z_SortKeySpec_ascending;
2092 sks->caseSensitivity = (int *)
2093 nmem_malloc(stream, sizeof(*sks->caseSensitivity));
2094 *sks->caseSensitivity = 0;
2096 sks->which = Z_SortKeySpec_null;
2097 sks->u.null = odr_nullval ();
2098 sort_sequence->specs[i] = sks;
2099 *rset = rsnull_create (rset_nmem, kc, 0);
2104 static int parse_xpath(ZebraHandle zh, Z_AttributesPlusTerm *zapt,
2105 oid_value attributeSet,
2106 struct xpath_location_step *xpath, int max, NMEM mem)
2108 oid_value curAttributeSet = attributeSet;
2110 const char *use_string = 0;
2112 attr_init(&use, zapt, 1);
2113 attr_find_ex(&use, &curAttributeSet, &use_string);
2115 if (!use_string || *use_string != '/')
2118 return zebra_parse_xpath_str(use_string, xpath, max, mem);
2123 static RSET xpath_trunc(ZebraHandle zh, NMEM stream,
2124 int reg_type, const char *term, int use,
2125 oid_value curAttributeSet, NMEM rset_nmem,
2126 struct rset_key_control *kc)
2129 struct grep_info grep_info;
2130 char term_dict[2048];
2133 int ord = zebraExplain_lookup_attr_su(zh->reg->zei, reg_type,
2134 curAttributeSet, use);
2135 int ord_len, i, r, max_pos;
2136 int term_type = Z_Term_characterString;
2137 const char *flags = "void";
2139 if (grep_info_prepare(zh, 0 /* zapt */, &grep_info, '0') == ZEBRA_FAIL)
2140 return rsnull_create(rset_nmem, kc, 0);
2143 return rsnull_create(rset_nmem, kc, 0);
2145 term_dict[prefix_len++] = '|';
2147 term_dict[prefix_len++] = '(';
2149 ord_len = key_SU_encode (ord, ord_buf);
2150 for (i = 0; i<ord_len; i++)
2152 term_dict[prefix_len++] = 1;
2153 term_dict[prefix_len++] = ord_buf[i];
2155 term_dict[prefix_len++] = ')';
2156 strcpy(term_dict+prefix_len, term);
2158 grep_info.isam_p_indx = 0;
2159 r = dict_lookup_grep(zh->reg->dict, term_dict, 0,
2160 &grep_info, &max_pos, 0, grep_handle);
2161 yaz_log(YLOG_DEBUG, "%s %d positions", term,
2162 grep_info.isam_p_indx);
2163 rset = rset_trunc(zh, grep_info.isam_p_buf,
2164 grep_info.isam_p_indx, term, strlen(term),
2165 flags, 1, term_type,rset_nmem,
2166 kc, kc->scope, 0, reg_type, 0 /* hits_limit */,
2167 0 /* term_ref_id_str */);
2168 grep_info_delete(&grep_info);
2173 ZEBRA_RES rpn_search_xpath(ZebraHandle zh,
2174 oid_value attributeSet,
2175 int num_bases, char **basenames,
2176 NMEM stream, const char *rank_type, RSET rset,
2177 int xpath_len, struct xpath_location_step *xpath,
2180 struct rset_key_control *kc)
2182 oid_value curAttributeSet = attributeSet;
2192 yaz_log(YLOG_DEBUG, "xpath len=%d", xpath_len);
2193 for (i = 0; i<xpath_len; i++)
2195 yaz_log(log_level_rpn, "XPATH %d %s", i, xpath[i].part);
2199 curAttributeSet = VAL_IDXPATH;
2209 a[@attr = value]/b[@other = othervalue]
2211 /e/@a val range(e/,range(@a,freetext(w,1015,val),@a),e/)
2212 /a/b val range(b/a/,freetext(w,1016,val),b/a/)
2213 /a/b/@c val range(b/a/,range(@c,freetext(w,1016,val),@c),b/a/)
2214 /a/b[@c = y] val range(b/a/,freetext(w,1016,val),b/a/,@c = y)
2215 /a[@c = y]/b val range(a/,range(b/a/,freetext(w,1016,val),b/a/),a/,@c = y)
2216 /a[@c = x]/b[@c = y] range(a/,range(b/a/,freetext(w,1016,val),b/a/,@c = y),a/,@c = x)
2220 dict_grep_cmap (zh->reg->dict, 0, 0);
2222 for (base_no = 0; base_no < num_bases; base_no++)
2224 int level = xpath_len;
2227 if (zebraExplain_curDatabase (zh->reg->zei, basenames[base_no]))
2229 zebra_setError(zh, YAZ_BIB1_DATABASE_UNAVAILABLE,
2230 basenames[base_no]);
2234 while (--level >= 0)
2236 char xpath_rev[128];
2238 RSET rset_start_tag = 0, rset_end_tag = 0, rset_attr = 0;
2242 for (i = level; i >= 1; --i)
2244 const char *cp = xpath[i].part;
2250 memcpy (xpath_rev + len, "[^/]*", 5);
2253 else if (*cp == ' ')
2256 xpath_rev[len++] = 1;
2257 xpath_rev[len++] = ' ';
2261 xpath_rev[len++] = *cp;
2262 xpath_rev[len++] = '/';
2264 else if (i == 1) /* // case */
2266 xpath_rev[len++] = '.';
2267 xpath_rev[len++] = '*';
2272 if (xpath[level].predicate &&
2273 xpath[level].predicate->which == XPATH_PREDICATE_RELATION &&
2274 xpath[level].predicate->u.relation.name[0])
2276 WRBUF wbuf = wrbuf_alloc();
2277 wrbuf_puts(wbuf, xpath[level].predicate->u.relation.name+1);
2278 if (xpath[level].predicate->u.relation.value)
2280 const char *cp = xpath[level].predicate->u.relation.value;
2281 wrbuf_putc(wbuf, '=');
2285 if (strchr(REGEX_CHARS, *cp))
2286 wrbuf_putc(wbuf, '\\');
2287 wrbuf_putc(wbuf, *cp);
2291 wrbuf_puts(wbuf, "");
2292 rset_attr = xpath_trunc(
2293 zh, stream, '0', wrbuf_buf(wbuf), 3,
2294 curAttributeSet, rset_nmem, kc);
2295 wrbuf_free(wbuf, 1);
2302 yaz_log(log_level_rpn, "xpath_rev (%d) = %s", level, xpath_rev);
2303 if (strlen(xpath_rev))
2305 rset_start_tag = xpath_trunc(zh, stream, '0',
2306 xpath_rev, 1, curAttributeSet, rset_nmem, kc);
2308 rset_end_tag = xpath_trunc(zh, stream, '0',
2309 xpath_rev, 2, curAttributeSet, rset_nmem, kc);
2311 rset = rsbetween_create(rset_nmem, kc, kc->scope,
2312 rset_start_tag, rset,
2313 rset_end_tag, rset_attr);
2322 static ZEBRA_RES rpn_search_APT(ZebraHandle zh, Z_AttributesPlusTerm *zapt,
2323 oid_value attributeSet, NMEM stream,
2324 Z_SortKeySpecList *sort_sequence,
2325 int num_bases, char **basenames,
2328 struct rset_key_control *kc)
2330 ZEBRA_RES res = ZEBRA_OK;
2332 char *search_type = NULL;
2333 char rank_type[128];
2336 char termz[IT_MAX_WORD+1];
2339 struct xpath_location_step xpath[10];
2343 log_level_rpn = yaz_log_module_level("rpn");
2346 zebra_maps_attr(zh->reg->zebra_maps, zapt, ®_id, &search_type,
2347 rank_type, &complete_flag, &sort_flag);
2349 yaz_log(YLOG_DEBUG, "reg_id=%c", reg_id);
2350 yaz_log(YLOG_DEBUG, "complete_flag=%d", complete_flag);
2351 yaz_log(YLOG_DEBUG, "search_type=%s", search_type);
2352 yaz_log(YLOG_DEBUG, "rank_type=%s", rank_type);
2354 if (zapt_term_to_utf8(zh, zapt, termz) == ZEBRA_FAIL)
2358 return rpn_sort_spec(zh, zapt, attributeSet, stream, sort_sequence,
2359 rank_type, rset_nmem, rset, kc);
2360 /* consider if an X-Path query is used */
2361 xpath_len = parse_xpath(zh, zapt, attributeSet, xpath, 10, stream);
2364 xpath_use = 1016; /* searching for element by default */
2365 if (xpath[xpath_len-1].part[0] == '@')
2366 xpath_use = 1015; /* last step an attribute .. */
2369 /* search using one of the various search type strategies
2370 termz is our UTF-8 search term
2371 attributeSet is top-level default attribute set
2372 stream is ODR for search
2373 reg_id is the register type
2374 complete_flag is 1 for complete subfield, 0 for incomplete
2375 xpath_use is use-attribute to be used for X-Path search, 0 for none
2377 if (!strcmp(search_type, "phrase"))
2379 res = rpn_search_APT_phrase(zh, zapt, termz, attributeSet, stream,
2380 reg_id, complete_flag, rank_type,
2382 num_bases, basenames, rset_nmem,
2385 else if (!strcmp(search_type, "and-list"))
2387 res = rpn_search_APT_and_list(zh, zapt, termz, attributeSet, stream,
2388 reg_id, complete_flag, rank_type,
2390 num_bases, basenames, rset_nmem,
2393 else if (!strcmp(search_type, "or-list"))
2395 res = rpn_search_APT_or_list(zh, zapt, termz, attributeSet, stream,
2396 reg_id, complete_flag, rank_type,
2398 num_bases, basenames, rset_nmem,
2401 else if (!strcmp(search_type, "local"))
2403 res = rpn_search_APT_local(zh, zapt, termz, attributeSet, stream,
2404 rank_type, rset_nmem, rset, kc);
2406 else if (!strcmp(search_type, "numeric"))
2408 res = rpn_search_APT_numeric(zh, zapt, termz, attributeSet, stream,
2409 reg_id, complete_flag, rank_type,
2411 num_bases, basenames, rset_nmem,
2416 zebra_setError(zh, YAZ_BIB1_UNSUPP_STRUCTURE_ATTRIBUTE, 0);
2419 if (res != ZEBRA_OK)
2423 return rpn_search_xpath(zh, attributeSet, num_bases, basenames,
2424 stream, rank_type, *rset,
2425 xpath_len, xpath, rset_nmem, rset, kc);
2428 static ZEBRA_RES rpn_search_structure(ZebraHandle zh, Z_RPNStructure *zs,
2429 oid_value attributeSet,
2430 NMEM stream, NMEM rset_nmem,
2431 Z_SortKeySpecList *sort_sequence,
2432 int num_bases, char **basenames,
2433 RSET **result_sets, int *num_result_sets,
2434 Z_Operator *parent_op,
2435 struct rset_key_control *kc);
2437 ZEBRA_RES rpn_search_top(ZebraHandle zh, Z_RPNStructure *zs,
2438 oid_value attributeSet,
2439 NMEM stream, NMEM rset_nmem,
2440 Z_SortKeySpecList *sort_sequence,
2441 int num_bases, char **basenames,
2444 RSET *result_sets = 0;
2445 int num_result_sets = 0;
2447 struct rset_key_control *kc = zebra_key_control_create(zh);
2449 res = rpn_search_structure(zh, zs, attributeSet,
2452 num_bases, basenames,
2453 &result_sets, &num_result_sets,
2454 0 /* no parent op */,
2456 if (res != ZEBRA_OK)
2459 for (i = 0; i<num_result_sets; i++)
2460 rset_delete(result_sets[i]);
2465 assert(num_result_sets == 1);
2466 assert(result_sets);
2467 assert(*result_sets);
2468 *result_set = *result_sets;
2474 ZEBRA_RES rpn_search_structure(ZebraHandle zh, Z_RPNStructure *zs,
2475 oid_value attributeSet,
2476 NMEM stream, NMEM rset_nmem,
2477 Z_SortKeySpecList *sort_sequence,
2478 int num_bases, char **basenames,
2479 RSET **result_sets, int *num_result_sets,
2480 Z_Operator *parent_op,
2481 struct rset_key_control *kc)
2483 *num_result_sets = 0;
2484 if (zs->which == Z_RPNStructure_complex)
2487 Z_Operator *zop = zs->u.complex->roperator;
2488 RSET *result_sets_l = 0;
2489 int num_result_sets_l = 0;
2490 RSET *result_sets_r = 0;
2491 int num_result_sets_r = 0;
2493 res = rpn_search_structure(zh, zs->u.complex->s1,
2494 attributeSet, stream, rset_nmem,
2496 num_bases, basenames,
2497 &result_sets_l, &num_result_sets_l,
2499 if (res != ZEBRA_OK)
2502 for (i = 0; i<num_result_sets_l; i++)
2503 rset_delete(result_sets_l[i]);
2506 res = rpn_search_structure(zh, zs->u.complex->s2,
2507 attributeSet, stream, rset_nmem,
2509 num_bases, basenames,
2510 &result_sets_r, &num_result_sets_r,
2512 if (res != ZEBRA_OK)
2515 for (i = 0; i<num_result_sets_l; i++)
2516 rset_delete(result_sets_l[i]);
2517 for (i = 0; i<num_result_sets_r; i++)
2518 rset_delete(result_sets_r[i]);
2522 /* make a new list of result for all children */
2523 *num_result_sets = num_result_sets_l + num_result_sets_r;
2524 *result_sets = nmem_malloc(stream, *num_result_sets *
2525 sizeof(**result_sets));
2526 memcpy(*result_sets, result_sets_l,
2527 num_result_sets_l * sizeof(**result_sets));
2528 memcpy(*result_sets + num_result_sets_l, result_sets_r,
2529 num_result_sets_r * sizeof(**result_sets));
2531 if (!parent_op || parent_op->which != zop->which
2532 || (zop->which != Z_Operator_and &&
2533 zop->which != Z_Operator_or))
2535 /* parent node different from this one (or non-present) */
2536 /* we must combine result sets now */
2540 case Z_Operator_and:
2541 rset = rsmulti_and_create(rset_nmem, kc,
2543 *num_result_sets, *result_sets);
2546 rset = rsmulti_or_create(rset_nmem, kc,
2547 kc->scope, 0, /* termid */
2548 *num_result_sets, *result_sets);
2550 case Z_Operator_and_not:
2551 rset = rsbool_create_not(rset_nmem, kc,
2556 case Z_Operator_prox:
2557 if (zop->u.prox->which != Z_ProximityOperator_known)
2560 YAZ_BIB1_UNSUPP_PROX_UNIT_CODE,
2564 if (*zop->u.prox->u.known != Z_ProxUnit_word)
2566 zebra_setError_zint(zh,
2567 YAZ_BIB1_UNSUPP_PROX_UNIT_CODE,
2568 *zop->u.prox->u.known);
2573 rset = rsprox_create(rset_nmem, kc,
2575 *num_result_sets, *result_sets,
2576 *zop->u.prox->ordered,
2577 (!zop->u.prox->exclusion ?
2578 0 : *zop->u.prox->exclusion),
2579 *zop->u.prox->relationType,
2580 *zop->u.prox->distance );
2584 zebra_setError(zh, YAZ_BIB1_OPERATOR_UNSUPP, 0);
2587 *num_result_sets = 1;
2588 *result_sets = nmem_malloc(stream, *num_result_sets *
2589 sizeof(**result_sets));
2590 (*result_sets)[0] = rset;
2593 else if (zs->which == Z_RPNStructure_simple)
2598 if (zs->u.simple->which == Z_Operand_APT)
2600 yaz_log(YLOG_DEBUG, "rpn_search_APT");
2601 res = rpn_search_APT(zh, zs->u.simple->u.attributesPlusTerm,
2602 attributeSet, stream, sort_sequence,
2603 num_bases, basenames, rset_nmem, &rset,
2605 if (res != ZEBRA_OK)
2608 else if (zs->u.simple->which == Z_Operand_resultSetId)
2610 yaz_log(YLOG_DEBUG, "rpn_search_ref");
2611 rset = resultSetRef(zh, zs->u.simple->u.resultSetId);
2615 YAZ_BIB1_SPECIFIED_RESULT_SET_DOES_NOT_EXIST,
2616 zs->u.simple->u.resultSetId);
2623 zebra_setError(zh, YAZ_BIB1_UNSUPP_SEARCH, 0);
2626 *num_result_sets = 1;
2627 *result_sets = nmem_malloc(stream, *num_result_sets *
2628 sizeof(**result_sets));
2629 (*result_sets)[0] = rset;
2633 zebra_setError(zh, YAZ_BIB1_UNSUPP_SEARCH, 0);
2639 struct scan_info_entry {
2645 struct scan_info_entry *list;
2651 static int scan_handle (char *name, const char *info, int pos, void *client)
2653 int len_prefix, idx;
2654 struct scan_info *scan_info = (struct scan_info *) client;
2656 len_prefix = strlen(scan_info->prefix);
2657 if (memcmp (name, scan_info->prefix, len_prefix))
2660 idx = scan_info->after - pos + scan_info->before;
2666 scan_info->list[idx].term = (char *)
2667 odr_malloc(scan_info->odr, strlen(name + len_prefix)+1);
2668 strcpy(scan_info->list[idx].term, name + len_prefix);
2669 assert (*info == sizeof(ISAM_P));
2670 memcpy (&scan_info->list[idx].isam_p, info+1, sizeof(ISAM_P));
2674 void zebra_term_untrans_iconv(ZebraHandle zh, NMEM stream, int reg_type,
2675 char **dst, const char *src)
2677 char term_src[IT_MAX_WORD];
2678 char term_dst[IT_MAX_WORD];
2680 zebra_term_untrans (zh, reg_type, term_src, src);
2682 if (zh->iconv_from_utf8 != 0)
2685 char *inbuf = term_src;
2686 size_t inleft = strlen(term_src);
2687 char *outbuf = term_dst;
2688 size_t outleft = sizeof(term_dst)-1;
2691 ret = yaz_iconv (zh->iconv_from_utf8, &inbuf, &inleft,
2693 if (ret == (size_t)(-1))
2696 len = outbuf - term_dst;
2697 *dst = nmem_malloc(stream, len + 1);
2699 memcpy (*dst, term_dst, len);
2703 *dst = nmem_strdup(stream, term_src);
2706 static void count_set(ZebraHandle zh, RSET rset, zint *count)
2712 yaz_log(YLOG_DEBUG, "count_set");
2714 rset->hits_limit = zh->approx_limit;
2717 rfd = rset_open(rset, RSETF_READ);
2718 while (rset_read(rfd, &key,0 /* never mind terms */))
2720 if (key.mem[0] != psysno)
2722 psysno = key.mem[0];
2723 if (rfd->counted_items >= rset->hits_limit)
2728 *count = rset->hits_count;
2731 ZEBRA_RES rpn_scan(ZebraHandle zh, ODR stream, Z_AttributesPlusTerm *zapt,
2732 oid_value attributeset,
2733 int num_bases, char **basenames,
2734 int *position, int *num_entries, ZebraScanEntry **list,
2735 int *is_partial, RSET limit_set, int return_zero)
2738 int pos = *position;
2739 int num = *num_entries;
2743 char termz[IT_MAX_WORD+20];
2746 const char *use_string = 0;
2747 struct scan_info *scan_info_array;
2748 ZebraScanEntry *glist;
2749 int ords[32], ord_no = 0;
2752 int bases_ok = 0; /* no of databases with OK attribute */
2753 int errCode = 0; /* err code (if any is not OK) */
2754 char *errString = 0; /* addinfo */
2757 char *search_type = NULL;
2758 char rank_type[128];
2761 NMEM rset_nmem = NULL;
2762 struct rset_key_control *kc = 0;
2767 if (attributeset == VAL_NONE)
2768 attributeset = VAL_BIB1;
2773 int termset_value_numeric;
2774 const char *termset_value_string;
2775 attr_init(&termset, zapt, 8);
2776 termset_value_numeric =
2777 attr_find_ex(&termset, NULL, &termset_value_string);
2778 if (termset_value_numeric != -1)
2781 const char *termset_name = 0;
2783 if (termset_value_numeric != -2)
2786 sprintf(resname, "%d", termset_value_numeric);
2787 termset_name = resname;
2790 termset_name = termset_value_string;
2792 limit_set = resultSetRef (zh, termset_name);
2796 yaz_log(YLOG_DEBUG, "position = %d, num = %d set=%d",
2797 pos, num, attributeset);
2799 attr_init(&use, zapt, 1);
2800 use_value = attr_find_ex(&use, &attributeset, &use_string);
2802 if (zebra_maps_attr(zh->reg->zebra_maps, zapt, ®_id, &search_type,
2803 rank_type, &complete_flag, &sort_flag))
2806 zebra_setError(zh, YAZ_BIB1_UNSUPP_ATTRIBUTE_TYPE, 0);
2809 yaz_log(YLOG_DEBUG, "use_value = %d", use_value);
2811 if (use_value == -1)
2813 for (base_no = 0; base_no < num_bases && ord_no < 32; base_no++)
2815 data1_local_attribute *local_attr;
2819 if (zebraExplain_curDatabase (zh->reg->zei, basenames[base_no]))
2821 zebra_setError(zh, YAZ_BIB1_DATABASE_UNAVAILABLE,
2822 basenames[base_no]);
2828 (ord = zebraExplain_lookup_attr_str(zh->reg->zei, reg_id,
2831 /* we have a match for a raw string attribute */
2833 ords[ord_no++] = ord;
2834 attp.local_attributes = 0; /* no more attributes */
2840 if ((r = att_getentbyatt (zh, &attp, attributeset, use_value,
2843 yaz_log(YLOG_DEBUG, "att_getentbyatt fail. set=%d use=%d",
2844 attributeset, use_value);
2847 errCode = YAZ_BIB1_UNSUPP_USE_ATTRIBUTE;
2849 zebra_setError(zh, YAZ_BIB1_UNSUPP_USE_ATTRIBUTE,
2852 zebra_setError_zint(zh, YAZ_BIB1_UNSUPP_USE_ATTRIBUTE,
2857 zebra_setError(zh, YAZ_BIB1_UNSUPP_ATTRIBUTE_SET, 0);
2863 for (local_attr = attp.local_attributes; local_attr && ord_no < 32;
2864 local_attr = local_attr->next)
2866 ord = zebraExplain_lookup_attr_su(zh->reg->zei, reg_id,
2867 attp.attset_ordinal,
2870 ords[ord_no++] = ord;
2873 if (!bases_ok && errCode)
2875 zebra_setError(zh, errCode, errString);
2884 /* prepare dictionary scanning */
2896 yaz_log(YLOG_DEBUG, "rpn_scan pos=%d num=%d before=%d "
2897 "after=%d before+after=%d",
2898 pos, num, before, after, before+after);
2899 scan_info_array = (struct scan_info *)
2900 odr_malloc(stream, ord_no * sizeof(*scan_info_array));
2901 for (i = 0; i < ord_no; i++)
2903 int j, prefix_len = 0;
2904 int before_tmp = before, after_tmp = after;
2905 struct scan_info *scan_info = scan_info_array + i;
2906 struct rpn_char_map_info rcmi;
2908 rpn_char_map_prepare (zh->reg, reg_id, &rcmi);
2910 scan_info->before = before;
2911 scan_info->after = after;
2912 scan_info->odr = stream;
2914 scan_info->list = (struct scan_info_entry *)
2915 odr_malloc(stream, (before+after) * sizeof(*scan_info->list));
2916 for (j = 0; j<before+after; j++)
2917 scan_info->list[j].term = NULL;
2919 prefix_len += key_SU_encode (ords[i], termz + prefix_len);
2920 termz[prefix_len] = 0;
2921 strcpy(scan_info->prefix, termz);
2923 if (trans_scan_term(zh, zapt, termz+prefix_len, reg_id) == ZEBRA_FAIL)
2926 dict_scan(zh->reg->dict, termz, &before_tmp, &after_tmp,
2927 scan_info, scan_handle);
2929 glist = (ZebraScanEntry *)
2930 odr_malloc(stream, (before+after)*sizeof(*glist));
2932 rset_nmem = nmem_create();
2933 kc = zebra_key_control_create(zh);
2935 /* consider terms after main term */
2936 for (i = 0; i < ord_no; i++)
2940 for (i = 0; i<after; i++)
2943 const char *mterm = NULL;
2946 int lo = i + pos-1; /* offset in result list */
2948 /* find: j0 is the first of the minimal values */
2949 for (j = 0; j < ord_no; j++)
2951 if (ptr[j] < before+after && ptr[j] >= 0 &&
2952 (tst = scan_info_array[j].list[ptr[j]].term) &&
2953 (!mterm || strcmp (tst, mterm) < 0))
2960 break; /* no value found, stop */
2962 /* get result set for first one , but only if it's within bounds */
2965 /* get result set for first term */
2966 zebra_term_untrans_iconv(zh, stream->mem, reg_id,
2967 &glist[lo].term, mterm);
2968 rset = rset_trunc(zh, &scan_info_array[j0].list[ptr[j0]].isam_p, 1,
2969 glist[lo].term, strlen(glist[lo].term),
2970 NULL, 0, zapt->term->which, rset_nmem,
2971 kc, kc->scope, 0, reg_id, 0 /* hits_limit */,
2972 0 /* term_ref_id_str */);
2974 ptr[j0]++; /* move index for this set .. */
2975 /* get result set for remaining scan terms */
2976 for (j = j0+1; j<ord_no; j++)
2978 if (ptr[j] < before+after && ptr[j] >= 0 &&
2979 (tst = scan_info_array[j].list[ptr[j]].term) &&
2980 !strcmp (tst, mterm))
2989 zh, &scan_info_array[j].list[ptr[j]].isam_p, 1,
2991 strlen(glist[lo].term), NULL, 0,
2992 zapt->term->which,rset_nmem,
2993 kc, kc->scope, 0, reg_id, 0 /* hits_limit */,
2994 0 /* term_ref_id_str */ );
2995 rset = rsmulti_or_create(rset_nmem, kc,
2996 kc->scope, 0 /* termid */,
3005 /* merge with limit_set if given */
3010 rsets[1] = rset_dup(limit_set);
3012 rset = rsmulti_and_create(rset_nmem, kc,
3017 count_set(zh, rset, &count);
3018 glist[lo].occurrences = count;
3024 *num_entries -= (after-i);
3026 if (*num_entries < 0)
3029 nmem_destroy(rset_nmem);
3034 /* consider terms before main term */
3035 for (i = 0; i<ord_no; i++)
3038 for (i = 0; i<before; i++)
3041 const char *mterm = NULL;
3044 int lo = before-1-i; /* offset in result list */
3047 for (j = 0; j <ord_no; j++)
3049 if (ptr[j] < before && ptr[j] >= 0 &&
3050 (tst = scan_info_array[j].list[before-1-ptr[j]].term) &&
3051 (!mterm || strcmp (tst, mterm) > 0))
3060 zebra_term_untrans_iconv(zh, stream->mem, reg_id,
3061 &glist[lo].term, mterm);
3064 (zh, &scan_info_array[j0].list[before-1-ptr[j0]].isam_p, 1,
3065 glist[lo].term, strlen(glist[lo].term),
3066 NULL, 0, zapt->term->which, rset_nmem,
3067 kc, kc->scope, 0, reg_id, 0 /* hits_limit */,
3068 0 /* term_ref_id_str */);
3072 for (j = j0+1; j<ord_no; j++)
3074 if (ptr[j] < before && ptr[j] >= 0 &&
3075 (tst = scan_info_array[j].list[before-1-ptr[j]].term) &&
3076 !strcmp (tst, mterm))
3081 rsets[1] = rset_trunc(
3083 &scan_info_array[j].list[before-1-ptr[j]].isam_p, 1,
3085 strlen(glist[lo].term), NULL, 0,
3086 zapt->term->which, rset_nmem,
3087 kc, kc->scope, 0, reg_id, 0 /* hits_limit */,
3088 0 /* term_ref_id_str */);
3089 rset = rsmulti_or_create(rset_nmem, kc,
3090 kc->scope, 0 /* termid */, 2, rsets);
3099 rsets[1] = rset_dup(limit_set);
3101 rset = rsmulti_and_create(rset_nmem, kc,
3102 kc->scope, 2, rsets);
3104 count_set(zh, rset, &count);
3105 glist[lo].occurrences = count;
3109 nmem_destroy(rset_nmem);
3116 if (*num_entries <= 0)
3123 *list = glist + i; /* list is set to first 'real' entry */
3125 yaz_log(YLOG_DEBUG, "position = %d, num_entries = %d",
3126 *position, *num_entries);
3133 * indent-tabs-mode: nil
3135 * vim: shiftwidth=4 tabstop=8 expandtab