1 /* $Id: zrpn.c,v 1.213 2006-05-17 17:46:45 adam Exp $
2 Copyright (C) 1995-2006
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)
976 yaz_log(log_level_rpn, "Relation =");
977 if (!term_100(zh->reg->zebra_maps, reg_type, term_sub,
978 term_component, space_split, term_dst))
980 strcat(term_tmp, "(");
981 strcat(term_tmp, term_component);
982 strcat(term_tmp, ")");
985 *error_code = YAZ_BIB1_UNSUPP_RELATION_ATTRIBUTE;
991 static ZEBRA_RES string_term(ZebraHandle zh, Z_AttributesPlusTerm *zapt,
992 const char **term_sub,
993 oid_value attributeSet, NMEM stream,
994 struct grep_info *grep_info,
995 int reg_type, int complete_flag,
996 int num_bases, char **basenames,
997 char *term_dst, int xpath_use,
998 struct ord_list **ol);
1000 static ZEBRA_RES term_limits_APT(ZebraHandle zh,
1001 Z_AttributesPlusTerm *zapt,
1002 zint *hits_limit_value,
1003 const char **term_ref_id_str,
1006 AttrType term_ref_id_attr;
1007 AttrType hits_limit_attr;
1008 int term_ref_id_int;
1010 attr_init(&hits_limit_attr, zapt, 9);
1011 *hits_limit_value = attr_find(&hits_limit_attr, NULL);
1013 attr_init(&term_ref_id_attr, zapt, 10);
1014 term_ref_id_int = attr_find_ex(&term_ref_id_attr, NULL, term_ref_id_str);
1015 if (term_ref_id_int >= 0)
1017 char *res = nmem_malloc(nmem, 20);
1018 sprintf(res, "%d", term_ref_id_int);
1019 *term_ref_id_str = res;
1022 /* no limit given ? */
1023 if (*hits_limit_value == -1)
1025 if (*term_ref_id_str)
1027 /* use global if term_ref is present */
1028 *hits_limit_value = zh->approx_limit;
1032 /* no counting if term_ref is not present */
1033 *hits_limit_value = 0;
1036 else if (*hits_limit_value == 0)
1038 /* 0 is the same as global limit */
1039 *hits_limit_value = zh->approx_limit;
1041 yaz_log(YLOG_DEBUG, "term_limits_APT ref_id=%s limit=" ZINT_FORMAT,
1042 *term_ref_id_str ? *term_ref_id_str : "none",
1047 static ZEBRA_RES term_trunc(ZebraHandle zh,
1048 Z_AttributesPlusTerm *zapt,
1049 const char **term_sub,
1050 oid_value attributeSet, NMEM stream,
1051 struct grep_info *grep_info,
1052 int reg_type, int complete_flag,
1053 int num_bases, char **basenames,
1055 const char *rank_type, int xpath_use,
1058 struct rset_key_control *kc)
1061 struct ord_list *ol;
1062 zint hits_limit_value;
1063 const char *term_ref_id_str = 0;
1066 term_limits_APT(zh, zapt, &hits_limit_value, &term_ref_id_str,
1068 grep_info->isam_p_indx = 0;
1069 res = string_term(zh, zapt, term_sub, attributeSet, stream, grep_info,
1070 reg_type, complete_flag, num_bases, basenames,
1071 term_dst, xpath_use, &ol);
1072 if (res != ZEBRA_OK)
1074 if (!*term_sub) /* no more terms ? */
1076 yaz_log(log_level_rpn, "term: %s", term_dst);
1077 *rset = rset_trunc(zh, grep_info->isam_p_buf,
1078 grep_info->isam_p_indx, term_dst,
1079 strlen(term_dst), rank_type, 1 /* preserve pos */,
1080 zapt->term->which, rset_nmem,
1081 kc, kc->scope, ol, reg_type, hits_limit_value,
1088 static ZEBRA_RES string_term(ZebraHandle zh, Z_AttributesPlusTerm *zapt,
1089 const char **term_sub,
1090 oid_value attributeSet, NMEM stream,
1091 struct grep_info *grep_info,
1092 int reg_type, int complete_flag,
1093 int num_bases, char **basenames,
1094 char *term_dst, int xpath_use,
1095 struct ord_list **ol)
1097 char term_dict[2*IT_MAX_WORD+4000];
1099 AttrType truncation;
1100 int truncation_value;
1103 const char *use_string = 0;
1104 oid_value curAttributeSet = attributeSet;
1106 struct rpn_char_map_info rcmi;
1107 int space_split = complete_flag ? 0 : 1;
1109 int bases_ok = 0; /* no of databases with OK attribute */
1111 *ol = ord_list_create(stream);
1113 rpn_char_map_prepare (zh->reg, reg_type, &rcmi);
1114 attr_init(&use, zapt, 1);
1115 use_value = attr_find_ex(&use, &curAttributeSet, &use_string);
1116 yaz_log(log_level_rpn, "string_term, use value %d", use_value);
1117 attr_init(&truncation, zapt, 5);
1118 truncation_value = attr_find(&truncation, NULL);
1119 yaz_log(log_level_rpn, "truncation value %d", truncation_value);
1121 if (use_value == -1) /* no attribute - assumy "any" */
1123 for (base_no = 0; base_no < num_bases; base_no++)
1127 int regex_range = 0;
1130 data1_local_attribute id_xpath_attr;
1131 data1_local_attribute *local_attr;
1132 int max_pos, prefix_len = 0;
1137 if (zebraExplain_curDatabase (zh->reg->zei, basenames[base_no]))
1139 zebra_setError(zh, YAZ_BIB1_DATABASE_UNAVAILABLE,
1140 basenames[base_no]);
1143 if (xpath_use > 0 && use_value == -2)
1145 /* xpath mode and we have a string attribute */
1146 attp.local_attributes = &id_xpath_attr;
1147 attp.attset_ordinal = VAL_IDXPATH;
1148 id_xpath_attr.next = 0;
1150 use_value = xpath_use; /* xpath_use as use-attribute now */
1151 id_xpath_attr.local = use_value;
1153 else if (curAttributeSet == VAL_IDXPATH && use_value >= 0)
1155 /* X-Path attribute, use numeric value directly */
1156 attp.local_attributes = &id_xpath_attr;
1157 attp.attset_ordinal = VAL_IDXPATH;
1158 id_xpath_attr.next = 0;
1159 id_xpath_attr.local = use_value;
1161 else if (use_string &&
1162 (ord = zebraExplain_lookup_attr_str(zh->reg->zei,
1166 /* we have a match for a raw string attribute */
1171 term_dict[prefix_len++] = '|';
1173 term_dict[prefix_len++] = '(';
1175 ord_len = key_SU_encode (ord, ord_buf);
1176 for (i = 0; i<ord_len; i++)
1178 term_dict[prefix_len++] = 1;
1179 term_dict[prefix_len++] = ord_buf[i];
1181 attp.local_attributes = 0; /* no more attributes */
1182 *ol = ord_list_append(stream, *ol, ord);
1186 /* lookup in the .att files . Allow string as well */
1187 if ((r = att_getentbyatt (zh, &attp, curAttributeSet, use_value,
1190 yaz_log(YLOG_DEBUG, "att_getentbyatt fail. set=%d use=%d r=%d",
1191 curAttributeSet, use_value, r);
1194 /* set was found, but value wasn't defined */
1197 YAZ_BIB1_UNSUPP_USE_ATTRIBUTE,
1200 zebra_setError_zint(zh, YAZ_BIB1_UNSUPP_USE_ATTRIBUTE,
1206 struct oident oident;
1208 oident.proto = PROTO_Z3950;
1209 oident.oclass = CLASS_ATTSET;
1210 oident.value = curAttributeSet;
1211 oid_ent_to_oid (&oident, oid);
1214 YAZ_BIB1_UNSUPP_ATTRIBUTE_SET,
1221 for (local_attr = attp.local_attributes; local_attr;
1222 local_attr = local_attr->next)
1227 ord = zebraExplain_lookup_attr_su(zh->reg->zei,
1229 attp.attset_ordinal,
1233 *ol = ord_list_append(stream, *ol, ord);
1235 term_dict[prefix_len++] = '|';
1237 term_dict[prefix_len++] = '(';
1239 ord_len = key_SU_encode (ord, ord_buf);
1240 for (i = 0; i<ord_len; i++)
1242 term_dict[prefix_len++] = 1;
1243 term_dict[prefix_len++] = ord_buf[i];
1245 if (ord_len > init_pos)
1252 term_dict[prefix_len++] = ')';
1253 term_dict[prefix_len] = '\0';
1255 switch (truncation_value)
1257 case -1: /* not specified */
1258 case 100: /* do not truncate */
1259 if (!string_relation (zh, zapt, &termp, term_dict,
1261 reg_type, space_split, term_dst,
1266 zebra_setError(zh, relation_error, 0);
1273 case 1: /* right truncation */
1274 term_dict[j++] = '(';
1275 if (!term_100(zh->reg->zebra_maps, reg_type,
1276 &termp, term_dict + j, space_split, term_dst))
1281 strcat(term_dict, ".*)");
1283 case 2: /* keft truncation */
1284 term_dict[j++] = '('; term_dict[j++] = '.'; term_dict[j++] = '*';
1285 if (!term_100(zh->reg->zebra_maps, reg_type,
1286 &termp, term_dict + j, space_split, term_dst))
1291 strcat(term_dict, ")");
1293 case 3: /* left&right truncation */
1294 term_dict[j++] = '('; term_dict[j++] = '.'; term_dict[j++] = '*';
1295 if (!term_100(zh->reg->zebra_maps, reg_type,
1296 &termp, term_dict + j, space_split, term_dst))
1301 strcat(term_dict, ".*)");
1303 case 101: /* process # in term */
1304 term_dict[j++] = '(';
1305 if (!term_101(zh->reg->zebra_maps, reg_type,
1306 &termp, term_dict + j, space_split, term_dst))
1311 strcat(term_dict, ")");
1313 case 102: /* Regexp-1 */
1314 term_dict[j++] = '(';
1315 if (!term_102(zh->reg->zebra_maps, reg_type,
1316 &termp, term_dict + j, space_split, term_dst))
1321 strcat(term_dict, ")");
1323 case 103: /* Regexp-2 */
1325 term_dict[j++] = '(';
1326 if (!term_103(zh->reg->zebra_maps, reg_type,
1327 &termp, term_dict + j, ®ex_range,
1328 space_split, term_dst))
1333 strcat(term_dict, ")");
1335 case 104: /* process # and ! in term */
1336 term_dict[j++] = '(';
1337 if (!term_104(zh->reg->zebra_maps, reg_type,
1338 &termp, term_dict + j, space_split, term_dst))
1343 strcat(term_dict, ")");
1345 case 105: /* process * and ! in term */
1346 term_dict[j++] = '(';
1347 if (!term_105(zh->reg->zebra_maps, reg_type,
1348 &termp, term_dict + j, space_split, term_dst, 1))
1353 strcat(term_dict, ")");
1355 case 106: /* process * and ! in term */
1356 term_dict[j++] = '(';
1357 if (!term_105(zh->reg->zebra_maps, reg_type,
1358 &termp, term_dict + j, space_split, term_dst, 0))
1363 strcat(term_dict, ")");
1366 zebra_setError_zint(zh,
1367 YAZ_BIB1_UNSUPP_TRUNCATION_ATTRIBUTE,
1374 const char *input = term_dict + prefix_len;
1375 esc_str(buf, sizeof(buf), input, strlen(input));
1379 yaz_log(log_level_rpn, "dict_lookup_grep: %s", term_dict+prefix_len);
1380 r = dict_lookup_grep(zh->reg->dict, term_dict, regex_range,
1381 grep_info, &max_pos, init_pos,
1384 yaz_log(YLOG_WARN, "dict_lookup_grep fail %d", r);
1390 yaz_log(YLOG_DEBUG, "%d positions", grep_info->isam_p_indx);
1395 /* convert APT search term to UTF8 */
1396 static ZEBRA_RES zapt_term_to_utf8(ZebraHandle zh, Z_AttributesPlusTerm *zapt,
1400 Z_Term *term = zapt->term;
1402 switch (term->which)
1404 case Z_Term_general:
1405 if (zh->iconv_to_utf8 != 0)
1407 char *inbuf = (char *) term->u.general->buf;
1408 size_t inleft = term->u.general->len;
1409 char *outbuf = termz;
1410 size_t outleft = IT_MAX_WORD-1;
1413 ret = yaz_iconv(zh->iconv_to_utf8, &inbuf, &inleft,
1415 if (ret == (size_t)(-1))
1417 ret = yaz_iconv(zh->iconv_to_utf8, 0, 0, 0, 0);
1420 YAZ_BIB1_QUERY_TERM_INCLUDES_CHARS_THAT_DO_NOT_TRANSLATE_INTO_,
1428 sizez = term->u.general->len;
1429 if (sizez > IT_MAX_WORD-1)
1430 sizez = IT_MAX_WORD-1;
1431 memcpy (termz, term->u.general->buf, sizez);
1432 termz[sizez] = '\0';
1435 case Z_Term_characterString:
1436 sizez = strlen(term->u.characterString);
1437 if (sizez > IT_MAX_WORD-1)
1438 sizez = IT_MAX_WORD-1;
1439 memcpy (termz, term->u.characterString, sizez);
1440 termz[sizez] = '\0';
1443 zebra_setError(zh, YAZ_BIB1_UNSUPP_CODED_VALUE_FOR_TERM, 0);
1449 /* convert APT SCAN term to internal cmap */
1450 static ZEBRA_RES trans_scan_term(ZebraHandle zh, Z_AttributesPlusTerm *zapt,
1451 char *termz, int reg_type)
1453 char termz0[IT_MAX_WORD];
1455 if (zapt_term_to_utf8(zh, zapt, termz0) == ZEBRA_FAIL)
1456 return ZEBRA_FAIL; /* error */
1460 const char *cp = (const char *) termz0;
1461 const char *cp_end = cp + strlen(cp);
1464 const char *space_map = NULL;
1467 while ((len = (cp_end - cp)) > 0)
1469 map = zebra_maps_input(zh->reg->zebra_maps, reg_type, &cp, len, 0);
1470 if (**map == *CHR_SPACE)
1475 for (src = space_map; *src; src++)
1478 for (src = *map; *src; src++)
1487 static void grep_info_delete(struct grep_info *grep_info)
1490 xfree(grep_info->term_no);
1492 xfree(grep_info->isam_p_buf);
1495 static ZEBRA_RES grep_info_prepare(ZebraHandle zh,
1496 Z_AttributesPlusTerm *zapt,
1497 struct grep_info *grep_info,
1501 int termset_value_numeric;
1502 const char *termset_value_string;
1505 grep_info->term_no = 0;
1507 grep_info->isam_p_size = 0;
1508 grep_info->isam_p_buf = NULL;
1510 grep_info->reg_type = reg_type;
1511 grep_info->termset = 0;
1515 attr_init(&termset, zapt, 8);
1516 termset_value_numeric =
1517 attr_find_ex(&termset, NULL, &termset_value_string);
1518 if (termset_value_numeric != -1)
1521 const char *termset_name = 0;
1522 if (termset_value_numeric != -2)
1525 sprintf(resname, "%d", termset_value_numeric);
1526 termset_name = resname;
1529 termset_name = termset_value_string;
1530 yaz_log(log_level_rpn, "creating termset set %s", termset_name);
1531 grep_info->termset = resultSetAdd(zh, termset_name, 1);
1532 if (!grep_info->termset)
1534 zebra_setError(zh, YAZ_BIB1_ILLEGAL_RESULT_SET_NAME, termset_name);
1542 \brief Create result set(s) for list of terms
1543 \param zh Zebra Handle
1544 \param termz term as used in query but converted to UTF-8
1545 \param attributeSet default attribute set
1546 \param stream memory for result
1547 \param reg_type register type ('w', 'p',..)
1548 \param complete_flag whether it's phrases or not
1549 \param rank_type term flags for ranking
1550 \param xpath_use use attribute for X-Path (-1 for no X-path)
1551 \param num_bases number of databases
1552 \param basenames array of databases
1553 \param rset_mem memory for result sets
1554 \param result_sets output result set for each term in list (output)
1555 \param number number of output result sets
1556 \param kc rset key control to be used for created result sets
1558 static ZEBRA_RES term_list_trunc(ZebraHandle zh,
1559 Z_AttributesPlusTerm *zapt,
1561 oid_value attributeSet,
1563 int reg_type, int complete_flag,
1564 const char *rank_type, int xpath_use,
1565 int num_bases, char **basenames,
1567 RSET **result_sets, int *num_result_sets,
1568 struct rset_key_control *kc)
1570 char term_dst[IT_MAX_WORD+1];
1571 struct grep_info grep_info;
1572 const char *termp = termz;
1574 int empty_term = *termz ? 0 : 1;
1577 *num_result_sets = 0;
1579 if (grep_info_prepare(zh, zapt, &grep_info, reg_type) == ZEBRA_FAIL)
1585 if (alloc_sets == *num_result_sets)
1588 RSET *rnew = (RSET *) nmem_malloc(stream, (alloc_sets+add) *
1591 memcpy(rnew, *result_sets, alloc_sets * sizeof(*rnew));
1592 alloc_sets = alloc_sets + add;
1593 *result_sets = rnew;
1595 res = term_trunc(zh, zapt, &termp, attributeSet,
1597 reg_type, complete_flag,
1598 num_bases, basenames,
1599 term_dst, rank_type,
1600 xpath_use, rset_nmem,
1601 &(*result_sets)[*num_result_sets],
1603 if (res != ZEBRA_OK)
1606 for (i = 0; i < *num_result_sets; i++)
1607 rset_delete((*result_sets)[i]);
1608 grep_info_delete (&grep_info);
1611 if ((*result_sets)[*num_result_sets] == 0)
1613 (*num_result_sets)++;
1620 grep_info_delete(&grep_info);
1624 static ZEBRA_RES rpn_search_APT_phrase(ZebraHandle zh,
1625 Z_AttributesPlusTerm *zapt,
1626 const char *termz_org,
1627 oid_value attributeSet,
1629 int reg_type, int complete_flag,
1630 const char *rank_type, int xpath_use,
1631 int num_bases, char **basenames,
1634 struct rset_key_control *kc)
1636 RSET *result_sets = 0;
1637 int num_result_sets = 0;
1639 term_list_trunc(zh, zapt, termz_org, attributeSet,
1640 stream, reg_type, complete_flag,
1641 rank_type, xpath_use,
1642 num_bases, basenames,
1644 &result_sets, &num_result_sets, kc);
1645 if (res != ZEBRA_OK)
1647 if (num_result_sets == 0)
1648 *rset = rsnull_create (rset_nmem, kc, 0);
1649 else if (num_result_sets == 1)
1650 *rset = result_sets[0];
1652 *rset = rsprox_create(rset_nmem, kc, kc->scope,
1653 num_result_sets, result_sets,
1654 1 /* ordered */, 0 /* exclusion */,
1655 3 /* relation */, 1 /* distance */);
1661 static ZEBRA_RES rpn_search_APT_or_list(ZebraHandle zh,
1662 Z_AttributesPlusTerm *zapt,
1663 const char *termz_org,
1664 oid_value attributeSet,
1666 int reg_type, int complete_flag,
1667 const char *rank_type,
1669 int num_bases, char **basenames,
1672 struct rset_key_control *kc)
1674 RSET *result_sets = 0;
1675 int num_result_sets = 0;
1677 term_list_trunc(zh, zapt, termz_org, attributeSet,
1678 stream, reg_type, complete_flag,
1679 rank_type, xpath_use,
1680 num_bases, basenames,
1682 &result_sets, &num_result_sets, kc);
1683 if (res != ZEBRA_OK)
1685 if (num_result_sets == 0)
1686 *rset = rsnull_create (rset_nmem, kc, 0);
1687 else if (num_result_sets == 1)
1688 *rset = result_sets[0];
1690 *rset = rsmulti_or_create(rset_nmem, kc, kc->scope, 0 /* termid */,
1691 num_result_sets, result_sets);
1697 static ZEBRA_RES rpn_search_APT_and_list(ZebraHandle zh,
1698 Z_AttributesPlusTerm *zapt,
1699 const char *termz_org,
1700 oid_value attributeSet,
1702 int reg_type, int complete_flag,
1703 const char *rank_type,
1705 int num_bases, char **basenames,
1708 struct rset_key_control *kc)
1710 RSET *result_sets = 0;
1711 int num_result_sets = 0;
1713 term_list_trunc(zh, zapt, termz_org, attributeSet,
1714 stream, reg_type, complete_flag,
1715 rank_type, xpath_use,
1716 num_bases, basenames,
1718 &result_sets, &num_result_sets,
1720 if (res != ZEBRA_OK)
1722 if (num_result_sets == 0)
1723 *rset = rsnull_create (rset_nmem, kc, 0);
1724 else if (num_result_sets == 1)
1725 *rset = result_sets[0];
1727 *rset = rsmulti_and_create(rset_nmem, kc, kc->scope,
1728 num_result_sets, result_sets);
1734 static int numeric_relation(ZebraHandle zh, Z_AttributesPlusTerm *zapt,
1735 const char **term_sub,
1737 oid_value attributeSet,
1738 struct grep_info *grep_info,
1748 char *term_tmp = term_dict + strlen(term_dict);
1751 attr_init(&relation, zapt, 2);
1752 relation_value = attr_find(&relation, NULL);
1754 yaz_log(log_level_rpn, "numeric relation value=%d", relation_value);
1756 if (!term_100(zh->reg->zebra_maps, reg_type, term_sub, term_tmp, 1,
1759 term_value = atoi (term_tmp);
1760 switch (relation_value)
1763 yaz_log(log_level_rpn, "Relation <");
1764 gen_regular_rel(term_tmp, term_value-1, 1);
1767 yaz_log(log_level_rpn, "Relation <=");
1768 gen_regular_rel(term_tmp, term_value, 1);
1771 yaz_log(log_level_rpn, "Relation >=");
1772 gen_regular_rel(term_tmp, term_value, 0);
1775 yaz_log(log_level_rpn, "Relation >");
1776 gen_regular_rel(term_tmp, term_value+1, 0);
1780 yaz_log(log_level_rpn, "Relation =");
1781 sprintf(term_tmp, "(0*%d)", term_value);
1784 *error_code = YAZ_BIB1_UNSUPP_RELATION_ATTRIBUTE;
1787 yaz_log(log_level_rpn, "dict_lookup_grep: %s", term_tmp);
1788 r = dict_lookup_grep(zh->reg->dict, term_dict, 0, grep_info, max_pos,
1791 yaz_log(YLOG_WARN, "dict_lookup_grep fail, rel = gt: %d", r);
1792 yaz_log(log_level_rpn, "%d positions", grep_info->isam_p_indx);
1796 static ZEBRA_RES numeric_term(ZebraHandle zh, Z_AttributesPlusTerm *zapt,
1797 const char **term_sub,
1798 oid_value attributeSet,
1799 struct grep_info *grep_info,
1800 int reg_type, int complete_flag,
1801 int num_bases, char **basenames,
1802 char *term_dst, int xpath_use, NMEM stream)
1804 char term_dict[2*IT_MAX_WORD+2];
1808 const char *use_string = 0;
1809 oid_value curAttributeSet = attributeSet;
1811 struct rpn_char_map_info rcmi;
1813 int bases_ok = 0; /* no of databases with OK attribute */
1815 rpn_char_map_prepare (zh->reg, reg_type, &rcmi);
1816 attr_init(&use, zapt, 1);
1817 use_value = attr_find_ex(&use, &curAttributeSet, &use_string);
1819 if (use_value == -1)
1822 for (base_no = 0; base_no < num_bases; base_no++)
1825 data1_local_attribute id_xpath_attr;
1826 data1_local_attribute *local_attr;
1827 int max_pos, prefix_len = 0;
1828 int relation_error = 0;
1831 if (use_value == -2) /* string attribute (assume IDXPATH/any) */
1833 use_value = xpath_use;
1834 attp.local_attributes = &id_xpath_attr;
1835 attp.attset_ordinal = VAL_IDXPATH;
1836 id_xpath_attr.next = 0;
1837 id_xpath_attr.local = use_value;
1839 else if (curAttributeSet == VAL_IDXPATH)
1841 attp.local_attributes = &id_xpath_attr;
1842 attp.attset_ordinal = VAL_IDXPATH;
1843 id_xpath_attr.next = 0;
1844 id_xpath_attr.local = use_value;
1848 if ((r = att_getentbyatt (zh, &attp, curAttributeSet, use_value,
1851 yaz_log(YLOG_DEBUG, "att_getentbyatt fail. set=%d use=%d r=%d",
1852 curAttributeSet, use_value, r);
1857 YAZ_BIB1_UNSUPP_USE_ATTRIBUTE,
1860 zebra_setError_zint(zh, YAZ_BIB1_UNSUPP_USE_ATTRIBUTE,
1864 zebra_setError(zh, YAZ_BIB1_UNSUPP_ATTRIBUTE_SET, 0);
1868 if (zebraExplain_curDatabase (zh->reg->zei, basenames[base_no]))
1870 zebra_setError(zh, YAZ_BIB1_DATABASE_UNAVAILABLE,
1871 basenames[base_no]);
1874 for (local_attr = attp.local_attributes; local_attr;
1875 local_attr = local_attr->next)
1881 ord = zebraExplain_lookup_attr_su(zh->reg->zei,
1883 attp.attset_ordinal,
1888 term_dict[prefix_len++] = '|';
1890 term_dict[prefix_len++] = '(';
1892 ord_len = key_SU_encode (ord, ord_buf);
1893 for (i = 0; i<ord_len; i++)
1895 term_dict[prefix_len++] = 1;
1896 term_dict[prefix_len++] = ord_buf[i];
1901 zebra_setError_zint(zh, YAZ_BIB1_UNSUPP_USE_ATTRIBUTE, use_value);
1905 term_dict[prefix_len++] = ')';
1906 term_dict[prefix_len] = '\0';
1907 if (!numeric_relation(zh, zapt, &termp, term_dict,
1908 attributeSet, grep_info, &max_pos, reg_type,
1909 term_dst, &relation_error))
1913 zebra_setError(zh, relation_error, 0);
1923 yaz_log(YLOG_DEBUG, "%d positions", grep_info->isam_p_indx);
1928 static ZEBRA_RES rpn_search_APT_numeric(ZebraHandle zh,
1929 Z_AttributesPlusTerm *zapt,
1931 oid_value attributeSet,
1933 int reg_type, int complete_flag,
1934 const char *rank_type, int xpath_use,
1935 int num_bases, char **basenames,
1938 struct rset_key_control *kc)
1940 char term_dst[IT_MAX_WORD+1];
1941 const char *termp = termz;
1942 RSET *result_sets = 0;
1943 int num_result_sets = 0;
1945 struct grep_info grep_info;
1947 zint hits_limit_value;
1948 const char *term_ref_id_str = 0;
1950 term_limits_APT(zh, zapt, &hits_limit_value, &term_ref_id_str, stream);
1952 yaz_log(log_level_rpn, "APT_numeric t='%s'", termz);
1953 if (grep_info_prepare(zh, zapt, &grep_info, reg_type) == ZEBRA_FAIL)
1957 if (alloc_sets == num_result_sets)
1960 RSET *rnew = (RSET *) nmem_malloc(stream, (alloc_sets+add) *
1963 memcpy(rnew, result_sets, alloc_sets * sizeof(*rnew));
1964 alloc_sets = alloc_sets + add;
1967 yaz_log(YLOG_DEBUG, "APT_numeric termp=%s", termp);
1968 grep_info.isam_p_indx = 0;
1969 res = numeric_term(zh, zapt, &termp, attributeSet, &grep_info,
1970 reg_type, complete_flag, num_bases, basenames,
1971 term_dst, xpath_use,
1973 if (res == ZEBRA_FAIL || termp == 0)
1975 yaz_log(YLOG_DEBUG, "term: %s", term_dst);
1976 result_sets[num_result_sets] =
1977 rset_trunc(zh, grep_info.isam_p_buf,
1978 grep_info.isam_p_indx, term_dst,
1979 strlen(term_dst), rank_type,
1980 0 /* preserve position */,
1981 zapt->term->which, rset_nmem,
1982 kc, kc->scope, 0, reg_type,
1985 if (!result_sets[num_result_sets])
1989 grep_info_delete(&grep_info);
1993 for (i = 0; i<num_result_sets; i++)
1994 rset_delete(result_sets[i]);
1997 if (num_result_sets == 0)
1998 *rset = rsnull_create(rset_nmem, kc, 0);
1999 if (num_result_sets == 1)
2000 *rset = result_sets[0];
2002 *rset = rsmulti_and_create(rset_nmem, kc, kc->scope,
2003 num_result_sets, result_sets);
2009 static ZEBRA_RES rpn_search_APT_local(ZebraHandle zh,
2010 Z_AttributesPlusTerm *zapt,
2012 oid_value attributeSet,
2014 const char *rank_type, NMEM rset_nmem,
2016 struct rset_key_control *kc)
2021 *rset = rstemp_create(rset_nmem, kc, kc->scope,
2022 res_get (zh->res, "setTmpDir"),0 );
2023 rsfd = rset_open(*rset, RSETF_WRITE);
2031 rset_write (rsfd, &key);
2036 static ZEBRA_RES rpn_sort_spec(ZebraHandle zh, Z_AttributesPlusTerm *zapt,
2037 oid_value attributeSet, NMEM stream,
2038 Z_SortKeySpecList *sort_sequence,
2039 const char *rank_type,
2042 struct rset_key_control *kc)
2045 int sort_relation_value;
2046 AttrType sort_relation_type;
2053 attr_init(&sort_relation_type, zapt, 7);
2054 sort_relation_value = attr_find(&sort_relation_type, &attributeSet);
2056 if (!sort_sequence->specs)
2058 sort_sequence->num_specs = 10;
2059 sort_sequence->specs = (Z_SortKeySpec **)
2060 nmem_malloc(stream, sort_sequence->num_specs *
2061 sizeof(*sort_sequence->specs));
2062 for (i = 0; i<sort_sequence->num_specs; i++)
2063 sort_sequence->specs[i] = 0;
2065 if (zapt->term->which != Z_Term_general)
2068 i = atoi_n ((char *) zapt->term->u.general->buf,
2069 zapt->term->u.general->len);
2070 if (i >= sort_sequence->num_specs)
2072 sprintf(termz, "%d", i);
2074 oe.proto = PROTO_Z3950;
2075 oe.oclass = CLASS_ATTSET;
2076 oe.value = attributeSet;
2077 if (!oid_ent_to_oid (&oe, oid))
2080 sks = (Z_SortKeySpec *) nmem_malloc(stream, sizeof(*sks));
2081 sks->sortElement = (Z_SortElement *)
2082 nmem_malloc(stream, sizeof(*sks->sortElement));
2083 sks->sortElement->which = Z_SortElement_generic;
2084 sk = sks->sortElement->u.generic = (Z_SortKey *)
2085 nmem_malloc(stream, sizeof(*sk));
2086 sk->which = Z_SortKey_sortAttributes;
2087 sk->u.sortAttributes = (Z_SortAttributes *)
2088 nmem_malloc(stream, sizeof(*sk->u.sortAttributes));
2090 sk->u.sortAttributes->id = oid;
2091 sk->u.sortAttributes->list = zapt->attributes;
2093 sks->sortRelation = (int *)
2094 nmem_malloc(stream, sizeof(*sks->sortRelation));
2095 if (sort_relation_value == 1)
2096 *sks->sortRelation = Z_SortKeySpec_ascending;
2097 else if (sort_relation_value == 2)
2098 *sks->sortRelation = Z_SortKeySpec_descending;
2100 *sks->sortRelation = Z_SortKeySpec_ascending;
2102 sks->caseSensitivity = (int *)
2103 nmem_malloc(stream, sizeof(*sks->caseSensitivity));
2104 *sks->caseSensitivity = 0;
2106 sks->which = Z_SortKeySpec_null;
2107 sks->u.null = odr_nullval ();
2108 sort_sequence->specs[i] = sks;
2109 *rset = rsnull_create (rset_nmem, kc, 0);
2114 static int parse_xpath(ZebraHandle zh, Z_AttributesPlusTerm *zapt,
2115 oid_value attributeSet,
2116 struct xpath_location_step *xpath, int max, NMEM mem)
2118 oid_value curAttributeSet = attributeSet;
2120 const char *use_string = 0;
2122 attr_init(&use, zapt, 1);
2123 attr_find_ex(&use, &curAttributeSet, &use_string);
2125 if (!use_string || *use_string != '/')
2128 return zebra_parse_xpath_str(use_string, xpath, max, mem);
2133 static RSET xpath_trunc(ZebraHandle zh, NMEM stream,
2134 int reg_type, const char *term, int use,
2135 oid_value curAttributeSet, NMEM rset_nmem,
2136 struct rset_key_control *kc)
2139 struct grep_info grep_info;
2140 char term_dict[2048];
2143 int ord = zebraExplain_lookup_attr_su(zh->reg->zei, reg_type,
2144 curAttributeSet, use);
2145 int ord_len, i, r, max_pos;
2146 int term_type = Z_Term_characterString;
2147 const char *flags = "void";
2149 if (grep_info_prepare(zh, 0 /* zapt */, &grep_info, '0') == ZEBRA_FAIL)
2150 return rsnull_create(rset_nmem, kc, 0);
2153 return rsnull_create(rset_nmem, kc, 0);
2155 term_dict[prefix_len++] = '|';
2157 term_dict[prefix_len++] = '(';
2159 ord_len = key_SU_encode (ord, ord_buf);
2160 for (i = 0; i<ord_len; i++)
2162 term_dict[prefix_len++] = 1;
2163 term_dict[prefix_len++] = ord_buf[i];
2165 term_dict[prefix_len++] = ')';
2166 strcpy(term_dict+prefix_len, term);
2168 grep_info.isam_p_indx = 0;
2169 r = dict_lookup_grep(zh->reg->dict, term_dict, 0,
2170 &grep_info, &max_pos, 0, grep_handle);
2171 yaz_log(YLOG_DEBUG, "%s %d positions", term,
2172 grep_info.isam_p_indx);
2173 rset = rset_trunc(zh, grep_info.isam_p_buf,
2174 grep_info.isam_p_indx, term, strlen(term),
2175 flags, 1, term_type,rset_nmem,
2176 kc, kc->scope, 0, reg_type, 0 /* hits_limit */,
2177 0 /* term_ref_id_str */);
2178 grep_info_delete(&grep_info);
2183 ZEBRA_RES rpn_search_xpath(ZebraHandle zh,
2184 oid_value attributeSet,
2185 int num_bases, char **basenames,
2186 NMEM stream, const char *rank_type, RSET rset,
2187 int xpath_len, struct xpath_location_step *xpath,
2190 struct rset_key_control *kc)
2192 oid_value curAttributeSet = attributeSet;
2202 yaz_log(YLOG_DEBUG, "xpath len=%d", xpath_len);
2203 for (i = 0; i<xpath_len; i++)
2205 yaz_log(log_level_rpn, "XPATH %d %s", i, xpath[i].part);
2209 curAttributeSet = VAL_IDXPATH;
2219 a[@attr = value]/b[@other = othervalue]
2221 /e/@a val range(e/,range(@a,freetext(w,1015,val),@a),e/)
2222 /a/b val range(b/a/,freetext(w,1016,val),b/a/)
2223 /a/b/@c val range(b/a/,range(@c,freetext(w,1016,val),@c),b/a/)
2224 /a/b[@c = y] val range(b/a/,freetext(w,1016,val),b/a/,@c = y)
2225 /a[@c = y]/b val range(a/,range(b/a/,freetext(w,1016,val),b/a/),a/,@c = y)
2226 /a[@c = x]/b[@c = y] range(a/,range(b/a/,freetext(w,1016,val),b/a/,@c = y),a/,@c = x)
2230 dict_grep_cmap (zh->reg->dict, 0, 0);
2232 for (base_no = 0; base_no < num_bases; base_no++)
2234 int level = xpath_len;
2237 if (zebraExplain_curDatabase (zh->reg->zei, basenames[base_no]))
2239 zebra_setError(zh, YAZ_BIB1_DATABASE_UNAVAILABLE,
2240 basenames[base_no]);
2244 while (--level >= 0)
2246 char xpath_rev[128];
2248 RSET rset_start_tag = 0, rset_end_tag = 0, rset_attr = 0;
2252 for (i = level; i >= 1; --i)
2254 const char *cp = xpath[i].part;
2260 memcpy (xpath_rev + len, "[^/]*", 5);
2263 else if (*cp == ' ')
2266 xpath_rev[len++] = 1;
2267 xpath_rev[len++] = ' ';
2271 xpath_rev[len++] = *cp;
2272 xpath_rev[len++] = '/';
2274 else if (i == 1) /* // case */
2276 xpath_rev[len++] = '.';
2277 xpath_rev[len++] = '*';
2282 if (xpath[level].predicate &&
2283 xpath[level].predicate->which == XPATH_PREDICATE_RELATION &&
2284 xpath[level].predicate->u.relation.name[0])
2286 WRBUF wbuf = wrbuf_alloc();
2287 wrbuf_puts(wbuf, xpath[level].predicate->u.relation.name+1);
2288 if (xpath[level].predicate->u.relation.value)
2290 const char *cp = xpath[level].predicate->u.relation.value;
2291 wrbuf_putc(wbuf, '=');
2295 if (strchr(REGEX_CHARS, *cp))
2296 wrbuf_putc(wbuf, '\\');
2297 wrbuf_putc(wbuf, *cp);
2301 wrbuf_puts(wbuf, "");
2302 rset_attr = xpath_trunc(
2303 zh, stream, '0', wrbuf_buf(wbuf), 3,
2304 curAttributeSet, rset_nmem, kc);
2305 wrbuf_free(wbuf, 1);
2312 yaz_log(log_level_rpn, "xpath_rev (%d) = %s", level, xpath_rev);
2313 if (strlen(xpath_rev))
2315 rset_start_tag = xpath_trunc(zh, stream, '0',
2316 xpath_rev, 1, curAttributeSet, rset_nmem, kc);
2318 rset_end_tag = xpath_trunc(zh, stream, '0',
2319 xpath_rev, 2, curAttributeSet, rset_nmem, kc);
2321 rset = rsbetween_create(rset_nmem, kc, kc->scope,
2322 rset_start_tag, rset,
2323 rset_end_tag, rset_attr);
2332 static ZEBRA_RES rpn_search_APT(ZebraHandle zh, Z_AttributesPlusTerm *zapt,
2333 oid_value attributeSet, NMEM stream,
2334 Z_SortKeySpecList *sort_sequence,
2335 int num_bases, char **basenames,
2338 struct rset_key_control *kc)
2340 ZEBRA_RES res = ZEBRA_OK;
2342 char *search_type = NULL;
2343 char rank_type[128];
2346 char termz[IT_MAX_WORD+1];
2349 struct xpath_location_step xpath[10];
2353 log_level_rpn = yaz_log_module_level("rpn");
2356 zebra_maps_attr(zh->reg->zebra_maps, zapt, ®_id, &search_type,
2357 rank_type, &complete_flag, &sort_flag);
2359 yaz_log(YLOG_DEBUG, "reg_id=%c", reg_id);
2360 yaz_log(YLOG_DEBUG, "complete_flag=%d", complete_flag);
2361 yaz_log(YLOG_DEBUG, "search_type=%s", search_type);
2362 yaz_log(YLOG_DEBUG, "rank_type=%s", rank_type);
2364 if (zapt_term_to_utf8(zh, zapt, termz) == ZEBRA_FAIL)
2368 return rpn_sort_spec(zh, zapt, attributeSet, stream, sort_sequence,
2369 rank_type, rset_nmem, rset, kc);
2370 /* consider if an X-Path query is used */
2371 xpath_len = parse_xpath(zh, zapt, attributeSet, xpath, 10, stream);
2374 xpath_use = 1016; /* searching for element by default */
2375 if (xpath[xpath_len-1].part[0] == '@')
2376 xpath_use = 1015; /* last step an attribute .. */
2379 /* search using one of the various search type strategies
2380 termz is our UTF-8 search term
2381 attributeSet is top-level default attribute set
2382 stream is ODR for search
2383 reg_id is the register type
2384 complete_flag is 1 for complete subfield, 0 for incomplete
2385 xpath_use is use-attribute to be used for X-Path search, 0 for none
2387 if (!strcmp(search_type, "phrase"))
2389 res = rpn_search_APT_phrase(zh, zapt, termz, attributeSet, stream,
2390 reg_id, complete_flag, rank_type,
2392 num_bases, basenames, rset_nmem,
2395 else if (!strcmp(search_type, "and-list"))
2397 res = rpn_search_APT_and_list(zh, zapt, termz, attributeSet, stream,
2398 reg_id, complete_flag, rank_type,
2400 num_bases, basenames, rset_nmem,
2403 else if (!strcmp(search_type, "or-list"))
2405 res = rpn_search_APT_or_list(zh, zapt, termz, attributeSet, stream,
2406 reg_id, complete_flag, rank_type,
2408 num_bases, basenames, rset_nmem,
2411 else if (!strcmp(search_type, "local"))
2413 res = rpn_search_APT_local(zh, zapt, termz, attributeSet, stream,
2414 rank_type, rset_nmem, rset, kc);
2416 else if (!strcmp(search_type, "numeric"))
2418 res = rpn_search_APT_numeric(zh, zapt, termz, attributeSet, stream,
2419 reg_id, complete_flag, rank_type,
2421 num_bases, basenames, rset_nmem,
2424 else if (!strcmp(search_type, "always"))
2427 res = rpn_search_APT_phrase(zh, zapt, termz, attributeSet, stream,
2428 reg_id, complete_flag, rank_type,
2430 num_bases, basenames, rset_nmem,
2435 zebra_setError(zh, YAZ_BIB1_UNSUPP_STRUCTURE_ATTRIBUTE, 0);
2438 if (res != ZEBRA_OK)
2442 return rpn_search_xpath(zh, attributeSet, num_bases, basenames,
2443 stream, rank_type, *rset,
2444 xpath_len, xpath, rset_nmem, rset, kc);
2447 static ZEBRA_RES rpn_search_structure(ZebraHandle zh, Z_RPNStructure *zs,
2448 oid_value attributeSet,
2449 NMEM stream, NMEM rset_nmem,
2450 Z_SortKeySpecList *sort_sequence,
2451 int num_bases, char **basenames,
2452 RSET **result_sets, int *num_result_sets,
2453 Z_Operator *parent_op,
2454 struct rset_key_control *kc);
2456 ZEBRA_RES rpn_search_top(ZebraHandle zh, Z_RPNStructure *zs,
2457 oid_value attributeSet,
2458 NMEM stream, NMEM rset_nmem,
2459 Z_SortKeySpecList *sort_sequence,
2460 int num_bases, char **basenames,
2463 RSET *result_sets = 0;
2464 int num_result_sets = 0;
2466 struct rset_key_control *kc = zebra_key_control_create(zh);
2468 res = rpn_search_structure(zh, zs, attributeSet,
2471 num_bases, basenames,
2472 &result_sets, &num_result_sets,
2473 0 /* no parent op */,
2475 if (res != ZEBRA_OK)
2478 for (i = 0; i<num_result_sets; i++)
2479 rset_delete(result_sets[i]);
2484 assert(num_result_sets == 1);
2485 assert(result_sets);
2486 assert(*result_sets);
2487 *result_set = *result_sets;
2493 ZEBRA_RES rpn_search_structure(ZebraHandle zh, Z_RPNStructure *zs,
2494 oid_value attributeSet,
2495 NMEM stream, NMEM rset_nmem,
2496 Z_SortKeySpecList *sort_sequence,
2497 int num_bases, char **basenames,
2498 RSET **result_sets, int *num_result_sets,
2499 Z_Operator *parent_op,
2500 struct rset_key_control *kc)
2502 *num_result_sets = 0;
2503 if (zs->which == Z_RPNStructure_complex)
2506 Z_Operator *zop = zs->u.complex->roperator;
2507 RSET *result_sets_l = 0;
2508 int num_result_sets_l = 0;
2509 RSET *result_sets_r = 0;
2510 int num_result_sets_r = 0;
2512 res = rpn_search_structure(zh, zs->u.complex->s1,
2513 attributeSet, stream, rset_nmem,
2515 num_bases, basenames,
2516 &result_sets_l, &num_result_sets_l,
2518 if (res != ZEBRA_OK)
2521 for (i = 0; i<num_result_sets_l; i++)
2522 rset_delete(result_sets_l[i]);
2525 res = rpn_search_structure(zh, zs->u.complex->s2,
2526 attributeSet, stream, rset_nmem,
2528 num_bases, basenames,
2529 &result_sets_r, &num_result_sets_r,
2531 if (res != ZEBRA_OK)
2534 for (i = 0; i<num_result_sets_l; i++)
2535 rset_delete(result_sets_l[i]);
2536 for (i = 0; i<num_result_sets_r; i++)
2537 rset_delete(result_sets_r[i]);
2541 /* make a new list of result for all children */
2542 *num_result_sets = num_result_sets_l + num_result_sets_r;
2543 *result_sets = nmem_malloc(stream, *num_result_sets *
2544 sizeof(**result_sets));
2545 memcpy(*result_sets, result_sets_l,
2546 num_result_sets_l * sizeof(**result_sets));
2547 memcpy(*result_sets + num_result_sets_l, result_sets_r,
2548 num_result_sets_r * sizeof(**result_sets));
2550 if (!parent_op || parent_op->which != zop->which
2551 || (zop->which != Z_Operator_and &&
2552 zop->which != Z_Operator_or))
2554 /* parent node different from this one (or non-present) */
2555 /* we must combine result sets now */
2559 case Z_Operator_and:
2560 rset = rsmulti_and_create(rset_nmem, kc,
2562 *num_result_sets, *result_sets);
2565 rset = rsmulti_or_create(rset_nmem, kc,
2566 kc->scope, 0, /* termid */
2567 *num_result_sets, *result_sets);
2569 case Z_Operator_and_not:
2570 rset = rsbool_create_not(rset_nmem, kc,
2575 case Z_Operator_prox:
2576 if (zop->u.prox->which != Z_ProximityOperator_known)
2579 YAZ_BIB1_UNSUPP_PROX_UNIT_CODE,
2583 if (*zop->u.prox->u.known != Z_ProxUnit_word)
2585 zebra_setError_zint(zh,
2586 YAZ_BIB1_UNSUPP_PROX_UNIT_CODE,
2587 *zop->u.prox->u.known);
2592 rset = rsprox_create(rset_nmem, kc,
2594 *num_result_sets, *result_sets,
2595 *zop->u.prox->ordered,
2596 (!zop->u.prox->exclusion ?
2597 0 : *zop->u.prox->exclusion),
2598 *zop->u.prox->relationType,
2599 *zop->u.prox->distance );
2603 zebra_setError(zh, YAZ_BIB1_OPERATOR_UNSUPP, 0);
2606 *num_result_sets = 1;
2607 *result_sets = nmem_malloc(stream, *num_result_sets *
2608 sizeof(**result_sets));
2609 (*result_sets)[0] = rset;
2612 else if (zs->which == Z_RPNStructure_simple)
2617 if (zs->u.simple->which == Z_Operand_APT)
2619 yaz_log(YLOG_DEBUG, "rpn_search_APT");
2620 res = rpn_search_APT(zh, zs->u.simple->u.attributesPlusTerm,
2621 attributeSet, stream, sort_sequence,
2622 num_bases, basenames, rset_nmem, &rset,
2624 if (res != ZEBRA_OK)
2627 else if (zs->u.simple->which == Z_Operand_resultSetId)
2629 yaz_log(YLOG_DEBUG, "rpn_search_ref");
2630 rset = resultSetRef(zh, zs->u.simple->u.resultSetId);
2634 YAZ_BIB1_SPECIFIED_RESULT_SET_DOES_NOT_EXIST,
2635 zs->u.simple->u.resultSetId);
2642 zebra_setError(zh, YAZ_BIB1_UNSUPP_SEARCH, 0);
2645 *num_result_sets = 1;
2646 *result_sets = nmem_malloc(stream, *num_result_sets *
2647 sizeof(**result_sets));
2648 (*result_sets)[0] = rset;
2652 zebra_setError(zh, YAZ_BIB1_UNSUPP_SEARCH, 0);
2658 struct scan_info_entry {
2664 struct scan_info_entry *list;
2670 static int scan_handle (char *name, const char *info, int pos, void *client)
2672 int len_prefix, idx;
2673 struct scan_info *scan_info = (struct scan_info *) client;
2675 len_prefix = strlen(scan_info->prefix);
2676 if (memcmp (name, scan_info->prefix, len_prefix))
2679 idx = scan_info->after - pos + scan_info->before;
2685 scan_info->list[idx].term = (char *)
2686 odr_malloc(scan_info->odr, strlen(name + len_prefix)+1);
2687 strcpy(scan_info->list[idx].term, name + len_prefix);
2688 assert (*info == sizeof(ISAM_P));
2689 memcpy (&scan_info->list[idx].isam_p, info+1, sizeof(ISAM_P));
2693 void zebra_term_untrans_iconv(ZebraHandle zh, NMEM stream, int reg_type,
2694 char **dst, const char *src)
2696 char term_src[IT_MAX_WORD];
2697 char term_dst[IT_MAX_WORD];
2699 zebra_term_untrans (zh, reg_type, term_src, src);
2701 if (zh->iconv_from_utf8 != 0)
2704 char *inbuf = term_src;
2705 size_t inleft = strlen(term_src);
2706 char *outbuf = term_dst;
2707 size_t outleft = sizeof(term_dst)-1;
2710 ret = yaz_iconv (zh->iconv_from_utf8, &inbuf, &inleft,
2712 if (ret == (size_t)(-1))
2715 len = outbuf - term_dst;
2716 *dst = nmem_malloc(stream, len + 1);
2718 memcpy (*dst, term_dst, len);
2722 *dst = nmem_strdup(stream, term_src);
2725 static void count_set(ZebraHandle zh, RSET rset, zint *count)
2731 yaz_log(YLOG_DEBUG, "count_set");
2733 rset->hits_limit = zh->approx_limit;
2736 rfd = rset_open(rset, RSETF_READ);
2737 while (rset_read(rfd, &key,0 /* never mind terms */))
2739 if (key.mem[0] != psysno)
2741 psysno = key.mem[0];
2742 if (rfd->counted_items >= rset->hits_limit)
2747 *count = rset->hits_count;
2750 ZEBRA_RES rpn_scan(ZebraHandle zh, ODR stream, Z_AttributesPlusTerm *zapt,
2751 oid_value attributeset,
2752 int num_bases, char **basenames,
2753 int *position, int *num_entries, ZebraScanEntry **list,
2754 int *is_partial, RSET limit_set, int return_zero)
2757 int pos = *position;
2758 int num = *num_entries;
2762 char termz[IT_MAX_WORD+20];
2765 const char *use_string = 0;
2766 struct scan_info *scan_info_array;
2767 ZebraScanEntry *glist;
2768 int ords[32], ord_no = 0;
2771 int bases_ok = 0; /* no of databases with OK attribute */
2772 int errCode = 0; /* err code (if any is not OK) */
2773 char *errString = 0; /* addinfo */
2776 char *search_type = NULL;
2777 char rank_type[128];
2780 NMEM rset_nmem = NULL;
2781 struct rset_key_control *kc = 0;
2786 if (attributeset == VAL_NONE)
2787 attributeset = VAL_BIB1;
2792 int termset_value_numeric;
2793 const char *termset_value_string;
2794 attr_init(&termset, zapt, 8);
2795 termset_value_numeric =
2796 attr_find_ex(&termset, NULL, &termset_value_string);
2797 if (termset_value_numeric != -1)
2800 const char *termset_name = 0;
2802 if (termset_value_numeric != -2)
2805 sprintf(resname, "%d", termset_value_numeric);
2806 termset_name = resname;
2809 termset_name = termset_value_string;
2811 limit_set = resultSetRef (zh, termset_name);
2815 yaz_log(YLOG_DEBUG, "position = %d, num = %d set=%d",
2816 pos, num, attributeset);
2818 attr_init(&use, zapt, 1);
2819 use_value = attr_find_ex(&use, &attributeset, &use_string);
2821 if (zebra_maps_attr(zh->reg->zebra_maps, zapt, ®_id, &search_type,
2822 rank_type, &complete_flag, &sort_flag))
2825 zebra_setError(zh, YAZ_BIB1_UNSUPP_ATTRIBUTE_TYPE, 0);
2828 yaz_log(YLOG_DEBUG, "use_value = %d", use_value);
2830 if (use_value == -1)
2832 for (base_no = 0; base_no < num_bases && ord_no < 32; base_no++)
2834 data1_local_attribute *local_attr;
2838 if (zebraExplain_curDatabase (zh->reg->zei, basenames[base_no]))
2840 zebra_setError(zh, YAZ_BIB1_DATABASE_UNAVAILABLE,
2841 basenames[base_no]);
2847 (ord = zebraExplain_lookup_attr_str(zh->reg->zei, reg_id,
2850 /* we have a match for a raw string attribute */
2852 ords[ord_no++] = ord;
2853 attp.local_attributes = 0; /* no more attributes */
2859 if ((r = att_getentbyatt (zh, &attp, attributeset, use_value,
2862 yaz_log(YLOG_DEBUG, "att_getentbyatt fail. set=%d use=%d",
2863 attributeset, use_value);
2866 errCode = YAZ_BIB1_UNSUPP_USE_ATTRIBUTE;
2868 zebra_setError(zh, YAZ_BIB1_UNSUPP_USE_ATTRIBUTE,
2871 zebra_setError_zint(zh, YAZ_BIB1_UNSUPP_USE_ATTRIBUTE,
2876 zebra_setError(zh, YAZ_BIB1_UNSUPP_ATTRIBUTE_SET, 0);
2882 for (local_attr = attp.local_attributes; local_attr && ord_no < 32;
2883 local_attr = local_attr->next)
2885 ord = zebraExplain_lookup_attr_su(zh->reg->zei, reg_id,
2886 attp.attset_ordinal,
2889 ords[ord_no++] = ord;
2892 if (!bases_ok && errCode)
2894 zebra_setError(zh, errCode, errString);
2903 /* prepare dictionary scanning */
2915 yaz_log(YLOG_DEBUG, "rpn_scan pos=%d num=%d before=%d "
2916 "after=%d before+after=%d",
2917 pos, num, before, after, before+after);
2918 scan_info_array = (struct scan_info *)
2919 odr_malloc(stream, ord_no * sizeof(*scan_info_array));
2920 for (i = 0; i < ord_no; i++)
2922 int j, prefix_len = 0;
2923 int before_tmp = before, after_tmp = after;
2924 struct scan_info *scan_info = scan_info_array + i;
2925 struct rpn_char_map_info rcmi;
2927 rpn_char_map_prepare (zh->reg, reg_id, &rcmi);
2929 scan_info->before = before;
2930 scan_info->after = after;
2931 scan_info->odr = stream;
2933 scan_info->list = (struct scan_info_entry *)
2934 odr_malloc(stream, (before+after) * sizeof(*scan_info->list));
2935 for (j = 0; j<before+after; j++)
2936 scan_info->list[j].term = NULL;
2938 prefix_len += key_SU_encode (ords[i], termz + prefix_len);
2939 termz[prefix_len] = 0;
2940 strcpy(scan_info->prefix, termz);
2942 if (trans_scan_term(zh, zapt, termz+prefix_len, reg_id) == ZEBRA_FAIL)
2945 dict_scan(zh->reg->dict, termz, &before_tmp, &after_tmp,
2946 scan_info, scan_handle);
2948 glist = (ZebraScanEntry *)
2949 odr_malloc(stream, (before+after)*sizeof(*glist));
2951 rset_nmem = nmem_create();
2952 kc = zebra_key_control_create(zh);
2954 /* consider terms after main term */
2955 for (i = 0; i < ord_no; i++)
2959 for (i = 0; i<after; i++)
2962 const char *mterm = NULL;
2965 int lo = i + pos-1; /* offset in result list */
2967 /* find: j0 is the first of the minimal values */
2968 for (j = 0; j < ord_no; j++)
2970 if (ptr[j] < before+after && ptr[j] >= 0 &&
2971 (tst = scan_info_array[j].list[ptr[j]].term) &&
2972 (!mterm || strcmp (tst, mterm) < 0))
2979 break; /* no value found, stop */
2981 /* get result set for first one , but only if it's within bounds */
2984 /* get result set for first term */
2985 zebra_term_untrans_iconv(zh, stream->mem, reg_id,
2986 &glist[lo].term, mterm);
2987 rset = rset_trunc(zh, &scan_info_array[j0].list[ptr[j0]].isam_p, 1,
2988 glist[lo].term, strlen(glist[lo].term),
2989 NULL, 0, zapt->term->which, rset_nmem,
2990 kc, kc->scope, 0, reg_id, 0 /* hits_limit */,
2991 0 /* term_ref_id_str */);
2993 ptr[j0]++; /* move index for this set .. */
2994 /* get result set for remaining scan terms */
2995 for (j = j0+1; j<ord_no; j++)
2997 if (ptr[j] < before+after && ptr[j] >= 0 &&
2998 (tst = scan_info_array[j].list[ptr[j]].term) &&
2999 !strcmp (tst, mterm))
3008 zh, &scan_info_array[j].list[ptr[j]].isam_p, 1,
3010 strlen(glist[lo].term), NULL, 0,
3011 zapt->term->which,rset_nmem,
3012 kc, kc->scope, 0, reg_id, 0 /* hits_limit */,
3013 0 /* term_ref_id_str */ );
3014 rset = rsmulti_or_create(rset_nmem, kc,
3015 kc->scope, 0 /* termid */,
3024 /* merge with limit_set if given */
3029 rsets[1] = rset_dup(limit_set);
3031 rset = rsmulti_and_create(rset_nmem, kc,
3036 count_set(zh, rset, &count);
3037 glist[lo].occurrences = count;
3043 *num_entries -= (after-i);
3045 if (*num_entries < 0)
3048 nmem_destroy(rset_nmem);
3053 /* consider terms before main term */
3054 for (i = 0; i<ord_no; i++)
3057 for (i = 0; i<before; i++)
3060 const char *mterm = NULL;
3063 int lo = before-1-i; /* offset in result list */
3066 for (j = 0; j <ord_no; j++)
3068 if (ptr[j] < before && ptr[j] >= 0 &&
3069 (tst = scan_info_array[j].list[before-1-ptr[j]].term) &&
3070 (!mterm || strcmp (tst, mterm) > 0))
3079 zebra_term_untrans_iconv(zh, stream->mem, reg_id,
3080 &glist[lo].term, mterm);
3083 (zh, &scan_info_array[j0].list[before-1-ptr[j0]].isam_p, 1,
3084 glist[lo].term, strlen(glist[lo].term),
3085 NULL, 0, zapt->term->which, rset_nmem,
3086 kc, kc->scope, 0, reg_id, 0 /* hits_limit */,
3087 0 /* term_ref_id_str */);
3091 for (j = j0+1; j<ord_no; j++)
3093 if (ptr[j] < before && ptr[j] >= 0 &&
3094 (tst = scan_info_array[j].list[before-1-ptr[j]].term) &&
3095 !strcmp (tst, mterm))
3100 rsets[1] = rset_trunc(
3102 &scan_info_array[j].list[before-1-ptr[j]].isam_p, 1,
3104 strlen(glist[lo].term), NULL, 0,
3105 zapt->term->which, rset_nmem,
3106 kc, kc->scope, 0, reg_id, 0 /* hits_limit */,
3107 0 /* term_ref_id_str */);
3108 rset = rsmulti_or_create(rset_nmem, kc,
3109 kc->scope, 0 /* termid */, 2, rsets);
3118 rsets[1] = rset_dup(limit_set);
3120 rset = rsmulti_and_create(rset_nmem, kc,
3121 kc->scope, 2, rsets);
3123 count_set(zh, rset, &count);
3124 glist[lo].occurrences = count;
3128 nmem_destroy(rset_nmem);
3135 if (*num_entries <= 0)
3142 *list = glist + i; /* list is set to first 'real' entry */
3144 yaz_log(YLOG_DEBUG, "position = %d, num_entries = %d",
3145 *position, *num_entries);
3152 * indent-tabs-mode: nil
3154 * vim: shiftwidth=4 tabstop=8 expandtab