1 /* $Id: zrpn.c,v 1.201 2005-06-22 19:42:38 adam Exp $
2 Copyright (C) 1995-2005
5 This file is part of the Zebra server.
7 Zebra is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
12 Zebra is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 You should have received a copy of the GNU General Public License
18 along with Zebra; see the file LICENSE.zebra. If not, write to the
19 Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
33 #include <yaz/diagbib1.h>
35 #include <zebra_xpath.h>
40 struct rpn_char_map_info
51 Z_AttributesPlusTerm *zapt;
54 static int log_level_set = 0;
55 static int log_level_rpn = 0;
57 static const char **rpn_char_map_handler(void *vp, const char **from, int len)
59 struct rpn_char_map_info *p = (struct rpn_char_map_info *) vp;
60 const char **out = zebra_maps_input(p->zm, p->reg_type, from, len, 0);
64 const char *outp = *out;
65 yaz_log(YLOG_LOG, "---");
68 yaz_log(YLOG_LOG, "%02X", *outp);
76 static void rpn_char_map_prepare(struct zebra_register *reg, int reg_type,
77 struct rpn_char_map_info *map_info)
79 map_info->zm = reg->zebra_maps;
80 map_info->reg_type = reg_type;
81 dict_grep_cmap(reg->dict, map_info, rpn_char_map_handler);
84 static int attr_find_ex(AttrType *src, oid_value *attributeSetP,
85 const char **string_value)
89 num_attributes = src->zapt->attributes->num_attributes;
90 while (src->major < num_attributes)
92 Z_AttributeElement *element;
94 element = src->zapt->attributes->attributes[src->major];
95 if (src->type == *element->attributeType)
97 switch (element->which)
99 case Z_AttributeValue_numeric:
101 if (element->attributeSet && attributeSetP)
105 attrset = oid_getentbyoid(element->attributeSet);
106 *attributeSetP = attrset->value;
108 return *element->value.numeric;
110 case Z_AttributeValue_complex:
111 if (src->minor >= element->value.complex->num_list)
113 if (element->attributeSet && attributeSetP)
117 attrset = oid_getentbyoid(element->attributeSet);
118 *attributeSetP = attrset->value;
120 if (element->value.complex->list[src->minor]->which ==
121 Z_StringOrNumeric_numeric)
125 *element->value.complex->list[src->minor-1]->u.numeric;
127 else if (element->value.complex->list[src->minor]->which ==
128 Z_StringOrNumeric_string)
134 element->value.complex->list[src->minor-1]->u.string;
148 static int attr_find(AttrType *src, oid_value *attributeSetP)
150 return attr_find_ex(src, attributeSetP, 0);
153 static void attr_init(AttrType *src, Z_AttributesPlusTerm *zapt,
176 void zebra_term_untrans(ZebraHandle zh, int reg_type,
177 char *dst, const char *src)
182 const char *cp = zebra_maps_output(zh->reg->zebra_maps,
184 if (!cp && len < IT_MAX_WORD-1)
187 while (*cp && len < IT_MAX_WORD-1)
193 static void add_isam_p(const char *name, const char *info,
198 log_level_rpn = yaz_log_module_level("rpn");
201 if (p->isam_p_indx == p->isam_p_size)
203 ISAM_P *new_isam_p_buf;
207 p->isam_p_size = 2*p->isam_p_size + 100;
208 new_isam_p_buf = (ISAM_P *) xmalloc(sizeof(*new_isam_p_buf) *
212 memcpy(new_isam_p_buf, p->isam_p_buf,
213 p->isam_p_indx * sizeof(*p->isam_p_buf));
214 xfree(p->isam_p_buf);
216 p->isam_p_buf = new_isam_p_buf;
219 new_term_no = (int *) xmalloc(sizeof(*new_term_no) * p->isam_p_size);
222 memcpy(new_term_no, p->isam_p_buf,
223 p->isam_p_indx * sizeof(*p->term_no));
226 p->term_no = new_term_no;
229 assert(*info == sizeof(*p->isam_p_buf));
230 memcpy(p->isam_p_buf + p->isam_p_indx, info+1, sizeof(*p->isam_p_buf));
237 char term_tmp[IT_MAX_WORD];
239 int len = key_SU_decode (&su_code, name);
241 zebra_term_untrans (p->zh, p->reg_type, term_tmp, name+len+1);
242 yaz_log(log_level_rpn, "grep: %d %c %s", su_code, name[len], term_tmp);
243 zebraExplain_lookup_ord (p->zh->reg->zei,
244 su_code, &db, &set, &use);
245 yaz_log(log_level_rpn, "grep: set=%d use=%d db=%s", set, use, db);
247 resultSetAddTerm(p->zh, p->termset, name[len], db,
254 static int grep_handle(char *name, const char *info, void *p)
256 add_isam_p(name, info, (struct grep_info *) p);
260 static int term_pre(ZebraMaps zebra_maps, int reg_type, const char **src,
261 const char *ct1, const char *ct2, int first)
263 const char *s1, *s0 = *src;
266 /* skip white space */
269 if (ct1 && strchr(ct1, *s0))
271 if (ct2 && strchr(ct2, *s0))
274 map = zebra_maps_input(zebra_maps, reg_type, &s1, strlen(s1), first);
275 if (**map != *CHR_SPACE)
284 static void esc_str(char *out_buf, int out_size,
285 const char *in_buf, int in_size)
291 assert(out_size > 20);
293 for (k = 0; k<in_size; k++)
295 int c = in_buf[k] & 0xff;
297 if (c < 32 || c > 126)
301 sprintf(out_buf +strlen(out_buf), "%02X:%c ", c, pc);
302 if (strlen(out_buf) > out_size-20)
304 strcat(out_buf, "..");
310 #define REGEX_CHARS " []()|.*+?!"
312 /* term_100: handle term, where trunc = none(no operators at all) */
313 static int term_100(ZebraMaps zebra_maps, int reg_type,
314 const char **src, char *dst, int space_split,
322 const char *space_start = 0;
323 const char *space_end = 0;
325 if (!term_pre(zebra_maps, reg_type, src, NULL, NULL, !space_split))
332 map = zebra_maps_search(zebra_maps, reg_type, &s0, strlen(s0),
336 if (**map == *CHR_SPACE)
339 else /* complete subfield only. */
341 if (**map == *CHR_SPACE)
342 { /* save space mapping for later .. */
347 else if (space_start)
348 { /* reload last space */
349 while (space_start < space_end)
351 if (strchr(REGEX_CHARS, *space_start))
353 dst_term[j++] = *space_start;
354 dst[i++] = *space_start++;
357 space_start = space_end = 0;
360 /* add non-space char */
361 memcpy(dst_term+j, s1, s0 - s1);
367 if (strchr(REGEX_CHARS, *s1))
375 esc_str(tmpbuf, sizeof(tmpbuf), map[0], strlen(map[0]));
377 strcpy(dst + i, map[0]);
387 /* term_101: handle term, where trunc = Process # */
388 static int term_101(ZebraMaps zebra_maps, int reg_type,
389 const char **src, char *dst, int space_split,
397 if (!term_pre(zebra_maps, reg_type, src, "#", "#", !space_split))
406 dst_term[j++] = *s0++;
412 map = zebra_maps_search(zebra_maps, reg_type, &s0, strlen(s0),
414 if (space_split && **map == *CHR_SPACE)
417 /* add non-space char */
418 memcpy(dst_term+j, s1, s0 - s1);
424 if (strchr(REGEX_CHARS, *s1))
432 esc_str(tmpbuf, sizeof(tmpbuf), map[0], strlen(map[0]));
434 strcpy(dst + i, map[0]);
440 dst_term[j++] = '\0';
445 /* term_103: handle term, where trunc = re-2 (regular expressions) */
446 static int term_103(ZebraMaps zebra_maps, int reg_type, const char **src,
447 char *dst, int *errors, int space_split,
455 if (!term_pre(zebra_maps, reg_type, src, "^\\()[].*+?|", "(", !space_split))
458 if (errors && *s0 == '+' && s0[1] && s0[2] == '+' && s0[3] &&
459 isdigit(((const unsigned char *)s0)[1]))
461 *errors = s0[1] - '0';
468 if (strchr("^\\()[].*+?|-", *s0))
477 map = zebra_maps_search(zebra_maps, reg_type, &s0, strlen(s0),
479 if (space_split && **map == *CHR_SPACE)
482 /* add non-space char */
483 memcpy(dst_term+j, s1, s0 - s1);
489 if (strchr(REGEX_CHARS, *s1))
497 esc_str(tmpbuf, sizeof(tmpbuf), map[0], strlen(map[0]));
499 strcpy(dst + i, map[0]);
511 /* term_103: handle term, where trunc = re-1 (regular expressions) */
512 static int term_102(ZebraMaps zebra_maps, int reg_type, const char **src,
513 char *dst, int space_split, char *dst_term)
515 return term_103(zebra_maps, reg_type, src, dst, NULL, space_split,
520 /* term_104: handle term, where trunc = Process # and ! */
521 static int term_104(ZebraMaps zebra_maps, int reg_type,
522 const char **src, char *dst, int space_split,
530 if (!term_pre(zebra_maps, reg_type, src, "?*#", "?*#", !space_split))
537 dst_term[j++] = *s0++;
538 if (*s0 >= '0' && *s0 <= '9')
541 while (*s0 >= '0' && *s0 <= '9')
543 limit = limit * 10 + (*s0 - '0');
544 dst_term[j++] = *s0++;
564 dst_term[j++] = *s0++;
569 dst_term[j++] = *s0++;
575 map = zebra_maps_search(zebra_maps, reg_type, &s0, strlen(s0),
577 if (space_split && **map == *CHR_SPACE)
580 /* add non-space char */
581 memcpy(dst_term+j, s1, s0 - s1);
587 if (strchr(REGEX_CHARS, *s1))
595 esc_str(tmpbuf, sizeof(tmpbuf), map[0], strlen(map[0]));
597 strcpy(dst + i, map[0]);
603 dst_term[j++] = '\0';
608 /* term_105/106: handle term, where trunc = Process * and ! and right trunc */
609 static int term_105(ZebraMaps zebra_maps, int reg_type,
610 const char **src, char *dst, int space_split,
611 char *dst_term, int right_truncate)
618 if (!term_pre(zebra_maps, reg_type, src, "*!", "*!", !space_split))
627 dst_term[j++] = *s0++;
632 dst_term[j++] = *s0++;
638 map = zebra_maps_search(zebra_maps, reg_type, &s0, strlen(s0),
640 if (space_split && **map == *CHR_SPACE)
643 /* add non-space char */
644 memcpy(dst_term+j, s1, s0 - s1);
650 if (strchr(REGEX_CHARS, *s1))
658 esc_str(tmpbuf, sizeof(tmpbuf), map[0], strlen(map[0]));
660 strcpy(dst + i, map[0]);
672 dst_term[j++] = '\0';
678 /* gen_regular_rel - generate regular expression from relation
679 * val: border value (inclusive)
680 * islt: 1 if <=; 0 if >=.
682 static void gen_regular_rel(char *dst, int val, int islt)
689 yaz_log(YLOG_DEBUG, "gen_regular_rel. val=%d, islt=%d", val, islt);
693 strcpy(dst, "(-[0-9]+|(");
701 strcpy(dst, "([0-9]+|-(");
713 sprintf(numstr, "%d", val);
714 for (w = strlen(numstr); --w >= 0; pos++)
733 strcpy(dst + dst_p, numstr);
734 dst_p = strlen(dst) - pos - 1;
762 for (i = 0; i<pos; i++)
775 /* match everything less than 10^(pos-1) */
777 for (i = 1; i<pos; i++)
778 strcat(dst, "[0-9]?");
782 /* match everything greater than 10^pos */
783 for (i = 0; i <= pos; i++)
784 strcat(dst, "[0-9]");
785 strcat(dst, "[0-9]*");
790 void string_rel_add_char(char **term_p, const char *src, int *indx)
792 if (src[*indx] == '\\')
793 *(*term_p)++ = src[(*indx)++];
794 *(*term_p)++ = src[(*indx)++];
798 * > abc ([b-].*|a[c-].*|ab[d-].*|abc.+)
799 * ([^-a].*|a[^-b].*ab[^-c].*|abc.+)
800 * >= abc ([b-].*|a[c-].*|ab[c-].*)
801 * ([^-a].*|a[^-b].*|ab[c-].*)
802 * < abc ([-0].*|a[-a].*|ab[-b].*)
803 * ([^a-].*|a[^b-].*|ab[^c-].*)
804 * <= abc ([-0].*|a[-a].*|ab[-b].*|abc)
805 * ([^a-].*|a[^b-].*|ab[^c-].*|abc)
807 static int string_relation(ZebraHandle zh, Z_AttributesPlusTerm *zapt,
808 const char **term_sub, char *term_dict,
809 oid_value attributeSet,
810 int reg_type, int space_split, char *term_dst,
816 char *term_tmp = term_dict + strlen(term_dict);
817 char term_component[2*IT_MAX_WORD+20];
819 attr_init(&relation, zapt, 2);
820 relation_value = attr_find(&relation, NULL);
823 yaz_log(YLOG_DEBUG, "string relation value=%d", relation_value);
824 switch (relation_value)
827 if (!term_100(zh->reg->zebra_maps, reg_type,
828 term_sub, term_component,
829 space_split, term_dst))
831 yaz_log(log_level_rpn, "Relation <");
834 for (i = 0; term_component[i]; )
841 string_rel_add_char(&term_tmp, term_component, &j);
846 string_rel_add_char(&term_tmp, term_component, &i);
853 if ((term_tmp - term_dict) > IT_MAX_WORD)
860 if (!term_100(zh->reg->zebra_maps, reg_type,
861 term_sub, term_component,
862 space_split, term_dst))
864 yaz_log(log_level_rpn, "Relation <=");
867 for (i = 0; term_component[i]; )
872 string_rel_add_char(&term_tmp, term_component, &j);
876 string_rel_add_char(&term_tmp, term_component, &i);
885 if ((term_tmp - term_dict) > IT_MAX_WORD)
888 for (i = 0; term_component[i]; )
889 string_rel_add_char(&term_tmp, term_component, &i);
894 if (!term_100 (zh->reg->zebra_maps, reg_type,
895 term_sub, term_component, space_split, term_dst))
897 yaz_log(log_level_rpn, "Relation >");
900 for (i = 0; term_component[i];)
905 string_rel_add_char(&term_tmp, term_component, &j);
910 string_rel_add_char(&term_tmp, term_component, &i);
918 if ((term_tmp - term_dict) > IT_MAX_WORD)
921 for (i = 0; term_component[i];)
922 string_rel_add_char(&term_tmp, term_component, &i);
929 if (!term_100(zh->reg->zebra_maps, reg_type, term_sub,
930 term_component, space_split, term_dst))
932 yaz_log(log_level_rpn, "Relation >=");
935 for (i = 0; term_component[i];)
942 string_rel_add_char(&term_tmp, term_component, &j);
945 if (term_component[i+1])
949 string_rel_add_char(&term_tmp, term_component, &i);
953 string_rel_add_char(&term_tmp, term_component, &i);
960 if ((term_tmp - term_dict) > IT_MAX_WORD)
969 yaz_log(log_level_rpn, "Relation =");
970 if (!term_100(zh->reg->zebra_maps, reg_type, term_sub,
971 term_component, space_split, term_dst))
973 strcat(term_tmp, "(");
974 strcat(term_tmp, term_component);
975 strcat(term_tmp, ")");
978 *error_code = YAZ_BIB1_UNSUPP_RELATION_ATTRIBUTE;
984 static ZEBRA_RES string_term(ZebraHandle zh, Z_AttributesPlusTerm *zapt,
985 const char **term_sub,
986 oid_value attributeSet, NMEM stream,
987 struct grep_info *grep_info,
988 int reg_type, int complete_flag,
989 int num_bases, char **basenames,
990 char *term_dst, int xpath_use,
991 struct ord_list **ol);
993 static ZEBRA_RES term_limits_APT(ZebraHandle zh,
994 Z_AttributesPlusTerm *zapt,
995 zint *hits_limit_value,
996 const char **term_ref_id_str)
998 AttrType term_ref_id_attr;
999 AttrType hits_limit_attr;
1001 attr_init(&hits_limit_attr, zapt, 9);
1002 *hits_limit_value = attr_find(&hits_limit_attr, NULL);
1004 attr_init(&term_ref_id_attr, zapt, 10);
1005 attr_find_ex(&term_ref_id_attr, NULL, term_ref_id_str);
1007 /* no limit given ? */
1008 if (*hits_limit_value == -1)
1009 if (*term_ref_id_str)
1011 /* use global if term_ref is present */
1012 *hits_limit_value = zh->approx_limit;
1016 /* no counting if term_ref is not present */
1017 *hits_limit_value = 0;
1019 else if (*hits_limit_value == 0)
1021 /* 0 is the same as global limit */
1022 *hits_limit_value = zh->approx_limit;
1024 yaz_log(YLOG_LOG, "term_limits_APT ref_id=%s limit=" ZINT_FORMAT,
1025 *term_ref_id_str ? *term_ref_id_str : "none",
1030 static ZEBRA_RES term_trunc(ZebraHandle zh,
1031 Z_AttributesPlusTerm *zapt,
1032 const char **term_sub,
1033 oid_value attributeSet, NMEM stream,
1034 struct grep_info *grep_info,
1035 int reg_type, int complete_flag,
1036 int num_bases, char **basenames,
1038 const char *rank_type, int xpath_use,
1041 struct rset_key_control *kc)
1044 struct ord_list *ol;
1045 zint hits_limit_value;
1046 const char *term_ref_id_str = 0;
1049 term_limits_APT(zh, zapt, &hits_limit_value, &term_ref_id_str);
1050 grep_info->isam_p_indx = 0;
1051 res = string_term(zh, zapt, term_sub, attributeSet, stream, grep_info,
1052 reg_type, complete_flag, num_bases, basenames,
1053 term_dst, xpath_use, &ol);
1054 if (res != ZEBRA_OK)
1056 if (!*term_sub) /* no more terms ? */
1058 yaz_log(log_level_rpn, "term: %s", term_dst);
1059 *rset = rset_trunc(zh, grep_info->isam_p_buf,
1060 grep_info->isam_p_indx, term_dst,
1061 strlen(term_dst), rank_type, 1 /* preserve pos */,
1062 zapt->term->which, rset_nmem,
1063 kc, kc->scope, ol, reg_type, hits_limit_value,
1070 static char *nmem_strdup_i(NMEM nmem, int v)
1073 sprintf(val_str, "%d", v);
1074 return nmem_strdup(nmem, val_str);
1077 static ZEBRA_RES string_term(ZebraHandle zh, Z_AttributesPlusTerm *zapt,
1078 const char **term_sub,
1079 oid_value attributeSet, NMEM stream,
1080 struct grep_info *grep_info,
1081 int reg_type, int complete_flag,
1082 int num_bases, char **basenames,
1083 char *term_dst, int xpath_use,
1084 struct ord_list **ol)
1086 char term_dict[2*IT_MAX_WORD+4000];
1088 AttrType truncation;
1089 int truncation_value;
1092 const char *use_string = 0;
1093 oid_value curAttributeSet = attributeSet;
1095 struct rpn_char_map_info rcmi;
1096 int space_split = complete_flag ? 0 : 1;
1098 int bases_ok = 0; /* no of databases with OK attribute */
1099 int errCode = 0; /* err code (if any is not OK) */
1100 char *errString = 0; /* addinfo */
1103 *ol = ord_list_create(stream);
1105 rpn_char_map_prepare (zh->reg, reg_type, &rcmi);
1106 attr_init(&use, zapt, 1);
1107 use_value = attr_find_ex(&use, &curAttributeSet, &use_string);
1108 yaz_log(log_level_rpn, "string_term, use value %d", use_value);
1109 attr_init(&truncation, zapt, 5);
1110 truncation_value = attr_find(&truncation, NULL);
1111 yaz_log(log_level_rpn, "truncation value %d", truncation_value);
1113 if (use_value == -1) /* no attribute - assumy "any" */
1115 for (base_no = 0; base_no < num_bases; base_no++)
1119 int regex_range = 0;
1122 data1_local_attribute id_xpath_attr;
1123 data1_local_attribute *local_attr;
1124 int max_pos, prefix_len = 0;
1129 if (zebraExplain_curDatabase (zh->reg->zei, basenames[base_no]))
1131 zebra_setError(zh, YAZ_BIB1_DATABASE_UNAVAILABLE,
1132 basenames[base_no]);
1135 if (xpath_use > 0 && use_value == -2)
1137 /* xpath mode and we have a string attribute */
1138 attp.local_attributes = &id_xpath_attr;
1139 attp.attset_ordinal = VAL_IDXPATH;
1140 id_xpath_attr.next = 0;
1142 use_value = xpath_use; /* xpath_use as use-attribute now */
1143 id_xpath_attr.local = use_value;
1145 else if (curAttributeSet == VAL_IDXPATH && use_value >= 0)
1147 /* X-Path attribute, use numeric value directly */
1148 attp.local_attributes = &id_xpath_attr;
1149 attp.attset_ordinal = VAL_IDXPATH;
1150 id_xpath_attr.next = 0;
1151 id_xpath_attr.local = use_value;
1153 else if (use_string &&
1154 (ord = zebraExplain_lookup_attr_str(zh->reg->zei,
1157 /* we have a match for a raw string attribute */
1162 term_dict[prefix_len++] = '|';
1164 term_dict[prefix_len++] = '(';
1166 ord_len = key_SU_encode (ord, ord_buf);
1167 for (i = 0; i<ord_len; i++)
1169 term_dict[prefix_len++] = 1;
1170 term_dict[prefix_len++] = ord_buf[i];
1172 attp.local_attributes = 0; /* no more attributes */
1173 *ol = ord_list_append(stream, *ol, ord);
1177 /* lookup in the .att files . Allow string as well */
1178 if ((r = att_getentbyatt (zh, &attp, curAttributeSet, use_value,
1181 yaz_log(YLOG_DEBUG, "att_getentbyatt fail. set=%d use=%d r=%d",
1182 curAttributeSet, use_value, r);
1185 /* set was found, but value wasn't defined */
1186 errCode = YAZ_BIB1_UNSUPP_USE_ATTRIBUTE;
1188 errString = nmem_strdup(stream, use_string);
1190 errString = nmem_strdup_i (stream, use_value);
1195 struct oident oident;
1197 oident.proto = PROTO_Z3950;
1198 oident.oclass = CLASS_ATTSET;
1199 oident.value = curAttributeSet;
1200 oid_ent_to_oid (&oident, oid);
1202 errCode = YAZ_BIB1_UNSUPP_ATTRIBUTE_SET;
1203 errString = nmem_strdup(stream, oident.desc);
1208 for (local_attr = attp.local_attributes; local_attr;
1209 local_attr = local_attr->next)
1214 ord = zebraExplain_lookup_attr_su(zh->reg->zei,
1215 attp.attset_ordinal,
1219 *ol = ord_list_append(stream, *ol, ord);
1221 term_dict[prefix_len++] = '|';
1223 term_dict[prefix_len++] = '(';
1225 ord_len = key_SU_encode (ord, ord_buf);
1226 for (i = 0; i<ord_len; i++)
1228 term_dict[prefix_len++] = 1;
1229 term_dict[prefix_len++] = ord_buf[i];
1236 term_dict[prefix_len++] = ')';
1237 term_dict[prefix_len++] = 1;
1238 term_dict[prefix_len++] = reg_type;
1239 yaz_log(log_level_rpn, "reg_type = %d", term_dict[prefix_len-1]);
1240 term_dict[prefix_len] = '\0';
1242 switch (truncation_value)
1244 case -1: /* not specified */
1245 case 100: /* do not truncate */
1246 if (!string_relation (zh, zapt, &termp, term_dict,
1248 reg_type, space_split, term_dst,
1253 zebra_setError(zh, relation_error, 0);
1260 case 1: /* right truncation */
1261 term_dict[j++] = '(';
1262 if (!term_100(zh->reg->zebra_maps, reg_type,
1263 &termp, term_dict + j, space_split, term_dst))
1268 strcat(term_dict, ".*)");
1270 case 2: /* keft truncation */
1271 term_dict[j++] = '('; term_dict[j++] = '.'; 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 3: /* left&right 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 101: /* process # in term */
1291 term_dict[j++] = '(';
1292 if (!term_101(zh->reg->zebra_maps, reg_type,
1293 &termp, term_dict + j, space_split, term_dst))
1298 strcat(term_dict, ")");
1300 case 102: /* Regexp-1 */
1301 term_dict[j++] = '(';
1302 if (!term_102(zh->reg->zebra_maps, reg_type,
1303 &termp, term_dict + j, space_split, term_dst))
1308 strcat(term_dict, ")");
1310 case 103: /* Regexp-2 */
1312 term_dict[j++] = '(';
1314 if (!term_103(zh->reg->zebra_maps, reg_type,
1315 &termp, term_dict + j, ®ex_range,
1316 space_split, term_dst))
1321 strcat(term_dict, ")");
1323 case 104: /* process # and ! in term */
1324 term_dict[j++] = '(';
1325 if (!term_104(zh->reg->zebra_maps, reg_type,
1326 &termp, term_dict + j, space_split, term_dst))
1331 strcat(term_dict, ")");
1333 case 105: /* process * and ! in term */
1334 term_dict[j++] = '(';
1335 if (!term_105(zh->reg->zebra_maps, reg_type,
1336 &termp, term_dict + j, space_split, term_dst, 1))
1341 strcat(term_dict, ")");
1343 case 106: /* process * and ! in term */
1344 term_dict[j++] = '(';
1345 if (!term_105(zh->reg->zebra_maps, reg_type,
1346 &termp, term_dict + j, space_split, term_dst, 0))
1351 strcat(term_dict, ")");
1354 zebra_setError_zint(zh,
1355 YAZ_BIB1_UNSUPP_TRUNCATION_ATTRIBUTE,
1362 const char *input = term_dict + prefix_len;
1363 esc_str(buf, sizeof(buf), input, strlen(input));
1367 yaz_log(log_level_rpn, "dict_lookup_grep: %s", term_dict+prefix_len);
1368 r = dict_lookup_grep(zh->reg->dict, term_dict, regex_range,
1369 grep_info, &max_pos, init_pos,
1372 yaz_log(YLOG_WARN, "dict_lookup_grep fail %d", r);
1377 zebra_setError(zh, errCode, errString);
1381 yaz_log(YLOG_DEBUG, "%d positions", grep_info->isam_p_indx);
1386 /* convert APT search term to UTF8 */
1387 static ZEBRA_RES zapt_term_to_utf8(ZebraHandle zh, Z_AttributesPlusTerm *zapt,
1391 Z_Term *term = zapt->term;
1393 switch (term->which)
1395 case Z_Term_general:
1396 if (zh->iconv_to_utf8 != 0)
1398 char *inbuf = term->u.general->buf;
1399 size_t inleft = term->u.general->len;
1400 char *outbuf = termz;
1401 size_t outleft = IT_MAX_WORD-1;
1404 ret = yaz_iconv(zh->iconv_to_utf8, &inbuf, &inleft,
1406 if (ret == (size_t)(-1))
1408 ret = yaz_iconv(zh->iconv_to_utf8, 0, 0, 0, 0);
1411 YAZ_BIB1_QUERY_TERM_INCLUDES_CHARS_THAT_DO_NOT_TRANSLATE_INTO_,
1419 sizez = term->u.general->len;
1420 if (sizez > IT_MAX_WORD-1)
1421 sizez = IT_MAX_WORD-1;
1422 memcpy (termz, term->u.general->buf, sizez);
1423 termz[sizez] = '\0';
1426 case Z_Term_characterString:
1427 sizez = strlen(term->u.characterString);
1428 if (sizez > IT_MAX_WORD-1)
1429 sizez = IT_MAX_WORD-1;
1430 memcpy (termz, term->u.characterString, sizez);
1431 termz[sizez] = '\0';
1434 zebra_setError(zh, YAZ_BIB1_UNSUPP_CODED_VALUE_FOR_TERM, 0);
1440 /* convert APT SCAN term to internal cmap */
1441 static ZEBRA_RES trans_scan_term(ZebraHandle zh, Z_AttributesPlusTerm *zapt,
1442 char *termz, int reg_type)
1444 char termz0[IT_MAX_WORD];
1446 if (zapt_term_to_utf8(zh, zapt, termz0) == ZEBRA_FAIL)
1447 return ZEBRA_FAIL; /* error */
1451 const char *cp = (const char *) termz0;
1452 const char *cp_end = cp + strlen(cp);
1455 const char *space_map = NULL;
1458 while ((len = (cp_end - cp)) > 0)
1460 map = zebra_maps_input(zh->reg->zebra_maps, reg_type, &cp, len, 0);
1461 if (**map == *CHR_SPACE)
1466 for (src = space_map; *src; src++)
1469 for (src = *map; *src; src++)
1478 static void grep_info_delete(struct grep_info *grep_info)
1481 xfree(grep_info->term_no);
1483 xfree(grep_info->isam_p_buf);
1486 static ZEBRA_RES grep_info_prepare(ZebraHandle zh,
1487 Z_AttributesPlusTerm *zapt,
1488 struct grep_info *grep_info,
1492 int termset_value_numeric;
1493 const char *termset_value_string;
1496 grep_info->term_no = 0;
1498 grep_info->isam_p_size = 0;
1499 grep_info->isam_p_buf = NULL;
1501 grep_info->reg_type = reg_type;
1502 grep_info->termset = 0;
1506 attr_init(&termset, zapt, 8);
1507 termset_value_numeric =
1508 attr_find_ex(&termset, NULL, &termset_value_string);
1509 if (termset_value_numeric != -1)
1512 const char *termset_name = 0;
1513 if (termset_value_numeric != -2)
1516 sprintf(resname, "%d", termset_value_numeric);
1517 termset_name = resname;
1520 termset_name = termset_value_string;
1521 yaz_log(log_level_rpn, "creating termset set %s", termset_name);
1522 grep_info->termset = resultSetAdd(zh, termset_name, 1);
1523 if (!grep_info->termset)
1525 zebra_setError(zh, YAZ_BIB1_ILLEGAL_RESULT_SET_NAME, termset_name);
1533 \brief Create result set(s) for list of terms
1534 \param zh Zebra Handle
1535 \param termz term as used in query but converted to UTF-8
1536 \param attributeSet default attribute set
1537 \param stream memory for result
1538 \param reg_type register type ('w', 'p',..)
1539 \param complete_flag whether it's phrases or not
1540 \param rank_type term flags for ranking
1541 \param xpath_use use attribute for X-Path (-1 for no X-path)
1542 \param num_bases number of databases
1543 \param basenames array of databases
1544 \param rset_mem memory for result sets
1545 \param result_sets output result set for each term in list (output)
1546 \param number number of output result sets
1547 \param kc rset key control to be used for created result sets
1549 static ZEBRA_RES term_list_trunc(ZebraHandle zh,
1550 Z_AttributesPlusTerm *zapt,
1552 oid_value attributeSet,
1554 int reg_type, int complete_flag,
1555 const char *rank_type, int xpath_use,
1556 int num_bases, char **basenames,
1558 RSET **result_sets, int *num_result_sets,
1559 struct rset_key_control *kc)
1561 char term_dst[IT_MAX_WORD+1];
1562 struct grep_info grep_info;
1563 const char *termp = termz;
1566 *num_result_sets = 0;
1568 if (grep_info_prepare(zh, zapt, &grep_info, reg_type) == ZEBRA_FAIL)
1574 if (alloc_sets == *num_result_sets)
1577 RSET *rnew = (RSET *) nmem_malloc(stream, (alloc_sets+add) *
1580 memcpy(rnew, *result_sets, alloc_sets * sizeof(*rnew));
1581 alloc_sets = alloc_sets + add;
1582 *result_sets = rnew;
1584 res = term_trunc(zh, zapt, &termp, attributeSet,
1586 reg_type, complete_flag,
1587 num_bases, basenames,
1588 term_dst, rank_type,
1589 xpath_use, rset_nmem,
1590 &(*result_sets)[*num_result_sets],
1592 if (res != ZEBRA_OK)
1595 for (i = 0; i < *num_result_sets; i++)
1596 rset_delete((*result_sets)[i]);
1597 grep_info_delete (&grep_info);
1600 if ((*result_sets)[*num_result_sets] == 0)
1602 (*num_result_sets)++;
1604 grep_info_delete(&grep_info);
1608 static ZEBRA_RES rpn_search_APT_phrase(ZebraHandle zh,
1609 Z_AttributesPlusTerm *zapt,
1610 const char *termz_org,
1611 oid_value attributeSet,
1613 int reg_type, int complete_flag,
1614 const char *rank_type, int xpath_use,
1615 int num_bases, char **basenames,
1618 struct rset_key_control *kc)
1620 RSET *result_sets = 0;
1621 int num_result_sets = 0;
1623 term_list_trunc(zh, zapt, termz_org, attributeSet,
1624 stream, reg_type, complete_flag,
1625 rank_type, xpath_use,
1626 num_bases, basenames,
1628 &result_sets, &num_result_sets, kc);
1629 if (res != ZEBRA_OK)
1631 if (num_result_sets == 0)
1632 *rset = rsnull_create (rset_nmem, kc, 0);
1633 else if (num_result_sets == 1)
1634 *rset = result_sets[0];
1636 *rset = rsprox_create(rset_nmem, kc, kc->scope,
1637 num_result_sets, result_sets,
1638 1 /* ordered */, 0 /* exclusion */,
1639 3 /* relation */, 1 /* distance */);
1645 static ZEBRA_RES rpn_search_APT_or_list(ZebraHandle zh,
1646 Z_AttributesPlusTerm *zapt,
1647 const char *termz_org,
1648 oid_value attributeSet,
1650 int reg_type, int complete_flag,
1651 const char *rank_type,
1653 int num_bases, char **basenames,
1656 struct rset_key_control *kc)
1658 RSET *result_sets = 0;
1659 int num_result_sets = 0;
1661 term_list_trunc(zh, zapt, termz_org, attributeSet,
1662 stream, reg_type, complete_flag,
1663 rank_type, xpath_use,
1664 num_bases, basenames,
1666 &result_sets, &num_result_sets, kc);
1667 if (res != ZEBRA_OK)
1669 if (num_result_sets == 0)
1670 *rset = rsnull_create (rset_nmem, kc, 0);
1671 else if (num_result_sets == 1)
1672 *rset = result_sets[0];
1674 *rset = rsmulti_or_create(rset_nmem, kc, kc->scope, 0 /* termid */,
1675 num_result_sets, result_sets);
1681 static ZEBRA_RES rpn_search_APT_and_list(ZebraHandle zh,
1682 Z_AttributesPlusTerm *zapt,
1683 const char *termz_org,
1684 oid_value attributeSet,
1686 int reg_type, int complete_flag,
1687 const char *rank_type,
1689 int num_bases, char **basenames,
1692 struct rset_key_control *kc)
1694 RSET *result_sets = 0;
1695 int num_result_sets = 0;
1697 term_list_trunc(zh, zapt, termz_org, attributeSet,
1698 stream, reg_type, complete_flag,
1699 rank_type, xpath_use,
1700 num_bases, basenames,
1702 &result_sets, &num_result_sets,
1704 if (res != ZEBRA_OK)
1706 if (num_result_sets == 0)
1707 *rset = rsnull_create (rset_nmem, kc, 0);
1708 else if (num_result_sets == 1)
1709 *rset = result_sets[0];
1711 *rset = rsmulti_and_create(rset_nmem, kc, kc->scope,
1712 num_result_sets, result_sets);
1718 static int numeric_relation(ZebraHandle zh, Z_AttributesPlusTerm *zapt,
1719 const char **term_sub,
1721 oid_value attributeSet,
1722 struct grep_info *grep_info,
1732 char *term_tmp = term_dict + strlen(term_dict);
1735 attr_init(&relation, zapt, 2);
1736 relation_value = attr_find(&relation, NULL);
1738 yaz_log(log_level_rpn, "numeric relation value=%d", relation_value);
1740 if (!term_100(zh->reg->zebra_maps, reg_type, term_sub, term_tmp, 1,
1743 term_value = atoi (term_tmp);
1744 switch (relation_value)
1747 yaz_log(log_level_rpn, "Relation <");
1748 gen_regular_rel(term_tmp, term_value-1, 1);
1751 yaz_log(log_level_rpn, "Relation <=");
1752 gen_regular_rel(term_tmp, term_value, 1);
1755 yaz_log(log_level_rpn, "Relation >=");
1756 gen_regular_rel(term_tmp, term_value, 0);
1759 yaz_log(log_level_rpn, "Relation >");
1760 gen_regular_rel(term_tmp, term_value+1, 0);
1764 yaz_log(log_level_rpn, "Relation =");
1765 sprintf(term_tmp, "(0*%d)", term_value);
1768 *error_code = YAZ_BIB1_UNSUPP_RELATION_ATTRIBUTE;
1771 yaz_log(log_level_rpn, "dict_lookup_grep: %s", term_tmp);
1772 r = dict_lookup_grep(zh->reg->dict, term_dict, 0, grep_info, max_pos,
1775 yaz_log(YLOG_WARN, "dict_lookup_grep fail, rel = gt: %d", r);
1776 yaz_log(log_level_rpn, "%d positions", grep_info->isam_p_indx);
1780 static ZEBRA_RES numeric_term(ZebraHandle zh, Z_AttributesPlusTerm *zapt,
1781 const char **term_sub,
1782 oid_value attributeSet,
1783 struct grep_info *grep_info,
1784 int reg_type, int complete_flag,
1785 int num_bases, char **basenames,
1786 char *term_dst, int xpath_use, NMEM stream)
1788 char term_dict[2*IT_MAX_WORD+2];
1792 const char *use_string = 0;
1793 oid_value curAttributeSet = attributeSet;
1795 struct rpn_char_map_info rcmi;
1797 int bases_ok = 0; /* no of databases with OK attribute */
1798 int errCode = 0; /* err code (if any is not OK) */
1799 char *errString = 0; /* addinfo */
1801 rpn_char_map_prepare (zh->reg, reg_type, &rcmi);
1802 attr_init(&use, zapt, 1);
1803 use_value = attr_find_ex(&use, &curAttributeSet, &use_string);
1805 if (use_value == -1)
1808 for (base_no = 0; base_no < num_bases; base_no++)
1811 data1_local_attribute id_xpath_attr;
1812 data1_local_attribute *local_attr;
1813 int max_pos, prefix_len = 0;
1814 int relation_error = 0;
1817 if (use_value == -2) /* string attribute (assume IDXPATH/any) */
1819 use_value = xpath_use;
1820 attp.local_attributes = &id_xpath_attr;
1821 attp.attset_ordinal = VAL_IDXPATH;
1822 id_xpath_attr.next = 0;
1823 id_xpath_attr.local = use_value;
1825 else if (curAttributeSet == VAL_IDXPATH)
1827 attp.local_attributes = &id_xpath_attr;
1828 attp.attset_ordinal = VAL_IDXPATH;
1829 id_xpath_attr.next = 0;
1830 id_xpath_attr.local = use_value;
1834 if ((r = att_getentbyatt (zh, &attp, curAttributeSet, use_value,
1837 yaz_log(YLOG_DEBUG, "att_getentbyatt fail. set=%d use=%d r=%d",
1838 curAttributeSet, use_value, r);
1841 errCode = YAZ_BIB1_UNSUPP_USE_ATTRIBUTE;
1843 errString = nmem_strdup(stream, use_string);
1845 errString = nmem_strdup_i (stream, use_value);
1848 errCode = YAZ_BIB1_UNSUPP_ATTRIBUTE_SET;
1852 if (zebraExplain_curDatabase (zh->reg->zei, basenames[base_no]))
1854 zebra_setError(zh, YAZ_BIB1_DATABASE_UNAVAILABLE,
1855 basenames[base_no]);
1858 for (local_attr = attp.local_attributes; local_attr;
1859 local_attr = local_attr->next)
1865 ord = zebraExplain_lookup_attr_su(zh->reg->zei,
1866 attp.attset_ordinal,
1871 term_dict[prefix_len++] = '|';
1873 term_dict[prefix_len++] = '(';
1875 ord_len = key_SU_encode (ord, ord_buf);
1876 for (i = 0; i<ord_len; i++)
1878 term_dict[prefix_len++] = 1;
1879 term_dict[prefix_len++] = ord_buf[i];
1884 zebra_setError_zint(zh, YAZ_BIB1_UNSUPP_USE_ATTRIBUTE, use_value);
1888 term_dict[prefix_len++] = ')';
1889 term_dict[prefix_len++] = 1;
1890 term_dict[prefix_len++] = reg_type;
1891 yaz_log(YLOG_DEBUG, "reg_type = %d", term_dict[prefix_len-1]);
1892 term_dict[prefix_len] = '\0';
1893 if (!numeric_relation(zh, zapt, &termp, term_dict,
1894 attributeSet, grep_info, &max_pos, reg_type,
1895 term_dst, &relation_error))
1899 zebra_setError(zh, relation_error, 0);
1908 zebra_setError(zh, errCode, errString);
1912 yaz_log(YLOG_DEBUG, "%d positions", grep_info->isam_p_indx);
1917 static ZEBRA_RES rpn_search_APT_numeric(ZebraHandle zh,
1918 Z_AttributesPlusTerm *zapt,
1920 oid_value attributeSet,
1922 int reg_type, int complete_flag,
1923 const char *rank_type, int xpath_use,
1924 int num_bases, char **basenames,
1927 struct rset_key_control *kc)
1929 char term_dst[IT_MAX_WORD+1];
1930 const char *termp = termz;
1931 RSET *result_sets = 0;
1932 int num_result_sets = 0;
1934 struct grep_info grep_info;
1936 zint hits_limit_value;
1937 const char *term_ref_id_str = 0;
1939 term_limits_APT(zh, zapt, &hits_limit_value, &term_ref_id_str);
1941 yaz_log(log_level_rpn, "APT_numeric t='%s'", termz);
1942 if (grep_info_prepare(zh, zapt, &grep_info, reg_type) == ZEBRA_FAIL)
1946 if (alloc_sets == num_result_sets)
1949 RSET *rnew = (RSET *) nmem_malloc(stream, (alloc_sets+add) *
1952 memcpy(rnew, result_sets, alloc_sets * sizeof(*rnew));
1953 alloc_sets = alloc_sets + add;
1956 yaz_log(YLOG_DEBUG, "APT_numeric termp=%s", termp);
1957 grep_info.isam_p_indx = 0;
1958 res = numeric_term(zh, zapt, &termp, attributeSet, &grep_info,
1959 reg_type, complete_flag, num_bases, basenames,
1960 term_dst, xpath_use,
1962 if (res == ZEBRA_FAIL || termp == 0)
1964 yaz_log(YLOG_DEBUG, "term: %s", term_dst);
1965 result_sets[num_result_sets] =
1966 rset_trunc(zh, grep_info.isam_p_buf,
1967 grep_info.isam_p_indx, term_dst,
1968 strlen(term_dst), rank_type,
1969 0 /* preserve position */,
1970 zapt->term->which, rset_nmem,
1971 kc, kc->scope, 0, reg_type,
1974 if (!result_sets[num_result_sets])
1978 grep_info_delete(&grep_info);
1982 for (i = 0; i<num_result_sets; i++)
1983 rset_delete(result_sets[i]);
1986 if (num_result_sets == 0)
1987 *rset = rsnull_create(rset_nmem, kc, 0);
1988 if (num_result_sets == 1)
1989 *rset = result_sets[0];
1991 *rset = rsmulti_and_create(rset_nmem, kc, kc->scope,
1992 num_result_sets, result_sets);
1998 static ZEBRA_RES rpn_search_APT_local(ZebraHandle zh,
1999 Z_AttributesPlusTerm *zapt,
2001 oid_value attributeSet,
2003 const char *rank_type, NMEM rset_nmem,
2005 struct rset_key_control *kc)
2010 *rset = rstemp_create(rset_nmem, kc, kc->scope,
2011 res_get (zh->res, "setTmpDir"),0 );
2012 rsfd = rset_open(*rset, RSETF_WRITE);
2020 rset_write (rsfd, &key);
2025 static ZEBRA_RES rpn_sort_spec(ZebraHandle zh, Z_AttributesPlusTerm *zapt,
2026 oid_value attributeSet, NMEM stream,
2027 Z_SortKeySpecList *sort_sequence,
2028 const char *rank_type,
2031 struct rset_key_control *kc)
2034 int sort_relation_value;
2035 AttrType sort_relation_type;
2042 attr_init(&sort_relation_type, zapt, 7);
2043 sort_relation_value = attr_find(&sort_relation_type, &attributeSet);
2045 if (!sort_sequence->specs)
2047 sort_sequence->num_specs = 10;
2048 sort_sequence->specs = (Z_SortKeySpec **)
2049 nmem_malloc(stream, sort_sequence->num_specs *
2050 sizeof(*sort_sequence->specs));
2051 for (i = 0; i<sort_sequence->num_specs; i++)
2052 sort_sequence->specs[i] = 0;
2054 if (zapt->term->which != Z_Term_general)
2057 i = atoi_n ((char *) zapt->term->u.general->buf,
2058 zapt->term->u.general->len);
2059 if (i >= sort_sequence->num_specs)
2061 sprintf(termz, "%d", i);
2063 oe.proto = PROTO_Z3950;
2064 oe.oclass = CLASS_ATTSET;
2065 oe.value = attributeSet;
2066 if (!oid_ent_to_oid (&oe, oid))
2069 sks = (Z_SortKeySpec *) nmem_malloc(stream, sizeof(*sks));
2070 sks->sortElement = (Z_SortElement *)
2071 nmem_malloc(stream, sizeof(*sks->sortElement));
2072 sks->sortElement->which = Z_SortElement_generic;
2073 sk = sks->sortElement->u.generic = (Z_SortKey *)
2074 nmem_malloc(stream, sizeof(*sk));
2075 sk->which = Z_SortKey_sortAttributes;
2076 sk->u.sortAttributes = (Z_SortAttributes *)
2077 nmem_malloc(stream, sizeof(*sk->u.sortAttributes));
2079 sk->u.sortAttributes->id = oid;
2080 sk->u.sortAttributes->list = zapt->attributes;
2082 sks->sortRelation = (int *)
2083 nmem_malloc(stream, sizeof(*sks->sortRelation));
2084 if (sort_relation_value == 1)
2085 *sks->sortRelation = Z_SortKeySpec_ascending;
2086 else if (sort_relation_value == 2)
2087 *sks->sortRelation = Z_SortKeySpec_descending;
2089 *sks->sortRelation = Z_SortKeySpec_ascending;
2091 sks->caseSensitivity = (int *)
2092 nmem_malloc(stream, sizeof(*sks->caseSensitivity));
2093 *sks->caseSensitivity = 0;
2095 sks->which = Z_SortKeySpec_null;
2096 sks->u.null = odr_nullval ();
2097 sort_sequence->specs[i] = sks;
2098 *rset = rsnull_create (rset_nmem, kc, 0);
2103 static int parse_xpath(ZebraHandle zh, Z_AttributesPlusTerm *zapt,
2104 oid_value attributeSet,
2105 struct xpath_location_step *xpath, int max, NMEM mem)
2107 oid_value curAttributeSet = attributeSet;
2109 const char *use_string = 0;
2111 attr_init(&use, zapt, 1);
2112 attr_find_ex(&use, &curAttributeSet, &use_string);
2114 if (!use_string || *use_string != '/')
2117 return zebra_parse_xpath_str(use_string, xpath, max, mem);
2122 static RSET xpath_trunc(ZebraHandle zh, NMEM stream,
2123 int reg_type, const char *term, int use,
2124 oid_value curAttributeSet, NMEM rset_nmem,
2125 struct rset_key_control *kc)
2128 struct grep_info grep_info;
2129 char term_dict[2048];
2132 int ord = zebraExplain_lookup_attr_su(zh->reg->zei, curAttributeSet, use);
2133 int ord_len, i, r, max_pos;
2134 int term_type = Z_Term_characterString;
2135 const char *flags = "void";
2137 if (grep_info_prepare(zh, 0 /* zapt */, &grep_info, '0') == ZEBRA_FAIL)
2138 return rsnull_create(rset_nmem, kc, 0);
2141 return rsnull_create(rset_nmem, kc, 0);
2143 term_dict[prefix_len++] = '|';
2145 term_dict[prefix_len++] = '(';
2147 ord_len = key_SU_encode (ord, ord_buf);
2148 for (i = 0; i<ord_len; i++)
2150 term_dict[prefix_len++] = 1;
2151 term_dict[prefix_len++] = ord_buf[i];
2153 term_dict[prefix_len++] = ')';
2154 term_dict[prefix_len++] = 1;
2155 term_dict[prefix_len++] = reg_type;
2157 strcpy(term_dict+prefix_len, term);
2159 grep_info.isam_p_indx = 0;
2160 r = dict_lookup_grep(zh->reg->dict, term_dict, 0,
2161 &grep_info, &max_pos, 0, grep_handle);
2162 yaz_log(YLOG_DEBUG, "%s %d positions", term,
2163 grep_info.isam_p_indx);
2164 rset = rset_trunc(zh, grep_info.isam_p_buf,
2165 grep_info.isam_p_indx, term, strlen(term),
2166 flags, 1, term_type,rset_nmem,
2167 kc, kc->scope, 0, reg_type, 0 /* hits_limit */,
2168 0 /* term_ref_id_str */);
2169 grep_info_delete(&grep_info);
2174 ZEBRA_RES rpn_search_xpath(ZebraHandle zh,
2175 oid_value attributeSet,
2176 int num_bases, char **basenames,
2177 NMEM stream, const char *rank_type, RSET rset,
2178 int xpath_len, struct xpath_location_step *xpath,
2181 struct rset_key_control *kc)
2183 oid_value curAttributeSet = attributeSet;
2193 yaz_log(YLOG_DEBUG, "xpath len=%d", xpath_len);
2194 for (i = 0; i<xpath_len; i++)
2196 yaz_log(log_level_rpn, "XPATH %d %s", i, xpath[i].part);
2200 curAttributeSet = VAL_IDXPATH;
2210 a[@attr = value]/b[@other = othervalue]
2212 /e/@a val range(e/,range(@a,freetext(w,1015,val),@a),e/)
2213 /a/b val range(b/a/,freetext(w,1016,val),b/a/)
2214 /a/b/@c val range(b/a/,range(@c,freetext(w,1016,val),@c),b/a/)
2215 /a/b[@c = y] val range(b/a/,freetext(w,1016,val),b/a/,@c = y)
2216 /a[@c = y]/b val range(a/,range(b/a/,freetext(w,1016,val),b/a/),a/,@c = y)
2217 /a[@c = x]/b[@c = y] range(a/,range(b/a/,freetext(w,1016,val),b/a/,@c = y),a/,@c = x)
2221 dict_grep_cmap (zh->reg->dict, 0, 0);
2223 for (base_no = 0; base_no < num_bases; base_no++)
2225 int level = xpath_len;
2228 if (zebraExplain_curDatabase (zh->reg->zei, basenames[base_no]))
2230 zebra_setError(zh, YAZ_BIB1_DATABASE_UNAVAILABLE,
2231 basenames[base_no]);
2235 while (--level >= 0)
2237 char xpath_rev[128];
2239 RSET rset_start_tag = 0, rset_end_tag = 0, rset_attr = 0;
2243 for (i = level; i >= 1; --i)
2245 const char *cp = xpath[i].part;
2251 memcpy (xpath_rev + len, "[^/]*", 5);
2254 else if (*cp == ' ')
2257 xpath_rev[len++] = 1;
2258 xpath_rev[len++] = ' ';
2262 xpath_rev[len++] = *cp;
2263 xpath_rev[len++] = '/';
2265 else if (i == 1) /* // case */
2267 xpath_rev[len++] = '.';
2268 xpath_rev[len++] = '*';
2273 if (xpath[level].predicate &&
2274 xpath[level].predicate->which == XPATH_PREDICATE_RELATION &&
2275 xpath[level].predicate->u.relation.name[0])
2277 WRBUF wbuf = wrbuf_alloc();
2278 wrbuf_puts(wbuf, xpath[level].predicate->u.relation.name+1);
2279 if (xpath[level].predicate->u.relation.value)
2281 const char *cp = xpath[level].predicate->u.relation.value;
2282 wrbuf_putc(wbuf, '=');
2286 if (strchr(REGEX_CHARS, *cp))
2287 wrbuf_putc(wbuf, '\\');
2288 wrbuf_putc(wbuf, *cp);
2292 wrbuf_puts(wbuf, "");
2293 rset_attr = xpath_trunc(
2294 zh, stream, '0', wrbuf_buf(wbuf), 3,
2295 curAttributeSet, rset_nmem, kc);
2296 wrbuf_free(wbuf, 1);
2303 yaz_log(log_level_rpn, "xpath_rev (%d) = %s", level, xpath_rev);
2304 if (strlen(xpath_rev))
2306 rset_start_tag = xpath_trunc(zh, stream, '0',
2307 xpath_rev, 1, curAttributeSet, rset_nmem, kc);
2309 rset_end_tag = xpath_trunc(zh, stream, '0',
2310 xpath_rev, 2, curAttributeSet, rset_nmem, kc);
2312 rset = rsbetween_create(rset_nmem, kc, kc->scope,
2313 rset_start_tag, rset,
2314 rset_end_tag, rset_attr);
2323 static ZEBRA_RES rpn_search_APT(ZebraHandle zh, Z_AttributesPlusTerm *zapt,
2324 oid_value attributeSet, NMEM stream,
2325 Z_SortKeySpecList *sort_sequence,
2326 int num_bases, char **basenames,
2329 struct rset_key_control *kc)
2331 ZEBRA_RES res = ZEBRA_OK;
2333 char *search_type = NULL;
2334 char rank_type[128];
2337 char termz[IT_MAX_WORD+1];
2340 struct xpath_location_step xpath[10];
2344 log_level_rpn = yaz_log_module_level("rpn");
2347 zebra_maps_attr(zh->reg->zebra_maps, zapt, ®_id, &search_type,
2348 rank_type, &complete_flag, &sort_flag);
2350 yaz_log(YLOG_DEBUG, "reg_id=%c", reg_id);
2351 yaz_log(YLOG_DEBUG, "complete_flag=%d", complete_flag);
2352 yaz_log(YLOG_DEBUG, "search_type=%s", search_type);
2353 yaz_log(YLOG_DEBUG, "rank_type=%s", rank_type);
2355 if (zapt_term_to_utf8(zh, zapt, termz) == ZEBRA_FAIL)
2359 return rpn_sort_spec(zh, zapt, attributeSet, stream, sort_sequence,
2360 rank_type, rset_nmem, rset, kc);
2361 /* consider if an X-Path query is used */
2362 xpath_len = parse_xpath(zh, zapt, attributeSet, xpath, 10, stream);
2365 xpath_use = 1016; /* searching for element by default */
2366 if (xpath[xpath_len-1].part[0] == '@')
2367 xpath_use = 1015; /* last step an attribute .. */
2370 /* search using one of the various search type strategies
2371 termz is our UTF-8 search term
2372 attributeSet is top-level default attribute set
2373 stream is ODR for search
2374 reg_id is the register type
2375 complete_flag is 1 for complete subfield, 0 for incomplete
2376 xpath_use is use-attribute to be used for X-Path search, 0 for none
2378 if (!strcmp(search_type, "phrase"))
2380 res = rpn_search_APT_phrase(zh, zapt, termz, attributeSet, stream,
2381 reg_id, complete_flag, rank_type,
2383 num_bases, basenames, rset_nmem,
2386 else if (!strcmp(search_type, "and-list"))
2388 res = rpn_search_APT_and_list(zh, zapt, termz, attributeSet, stream,
2389 reg_id, complete_flag, rank_type,
2391 num_bases, basenames, rset_nmem,
2394 else if (!strcmp(search_type, "or-list"))
2396 res = rpn_search_APT_or_list(zh, zapt, termz, attributeSet, stream,
2397 reg_id, complete_flag, rank_type,
2399 num_bases, basenames, rset_nmem,
2402 else if (!strcmp(search_type, "local"))
2404 res = rpn_search_APT_local(zh, zapt, termz, attributeSet, stream,
2405 rank_type, rset_nmem, rset, kc);
2407 else if (!strcmp(search_type, "numeric"))
2409 res = rpn_search_APT_numeric(zh, zapt, termz, attributeSet, stream,
2410 reg_id, complete_flag, rank_type,
2412 num_bases, basenames, rset_nmem,
2417 zebra_setError(zh, YAZ_BIB1_UNSUPP_STRUCTURE_ATTRIBUTE, 0);
2420 if (res != ZEBRA_OK)
2424 return rpn_search_xpath(zh, attributeSet, num_bases, basenames,
2425 stream, rank_type, *rset,
2426 xpath_len, xpath, rset_nmem, rset, kc);
2429 static ZEBRA_RES rpn_search_structure(ZebraHandle zh, Z_RPNStructure *zs,
2430 oid_value attributeSet,
2431 NMEM stream, NMEM rset_nmem,
2432 Z_SortKeySpecList *sort_sequence,
2433 int num_bases, char **basenames,
2434 RSET **result_sets, int *num_result_sets,
2435 Z_Operator *parent_op,
2436 struct rset_key_control *kc);
2438 ZEBRA_RES rpn_search_top(ZebraHandle zh, Z_RPNStructure *zs,
2439 oid_value attributeSet,
2440 NMEM stream, NMEM rset_nmem,
2441 Z_SortKeySpecList *sort_sequence,
2442 int num_bases, char **basenames,
2445 RSET *result_sets = 0;
2446 int num_result_sets = 0;
2448 struct rset_key_control *kc = zebra_key_control_create(zh);
2450 res = rpn_search_structure(zh, zs, attributeSet,
2453 num_bases, basenames,
2454 &result_sets, &num_result_sets,
2455 0 /* no parent op */,
2457 if (res != ZEBRA_OK)
2460 for (i = 0; i<num_result_sets; i++)
2461 rset_delete(result_sets[i]);
2466 assert(num_result_sets == 1);
2467 assert(result_sets);
2468 assert(*result_sets);
2469 *result_set = *result_sets;
2475 ZEBRA_RES rpn_search_structure(ZebraHandle zh, Z_RPNStructure *zs,
2476 oid_value attributeSet,
2477 NMEM stream, NMEM rset_nmem,
2478 Z_SortKeySpecList *sort_sequence,
2479 int num_bases, char **basenames,
2480 RSET **result_sets, int *num_result_sets,
2481 Z_Operator *parent_op,
2482 struct rset_key_control *kc)
2484 *num_result_sets = 0;
2485 if (zs->which == Z_RPNStructure_complex)
2488 Z_Operator *zop = zs->u.complex->roperator;
2489 RSET *result_sets_l = 0;
2490 int num_result_sets_l = 0;
2491 RSET *result_sets_r = 0;
2492 int num_result_sets_r = 0;
2494 res = rpn_search_structure(zh, zs->u.complex->s1,
2495 attributeSet, stream, rset_nmem,
2497 num_bases, basenames,
2498 &result_sets_l, &num_result_sets_l,
2500 if (res != ZEBRA_OK)
2503 for (i = 0; i<num_result_sets_l; i++)
2504 rset_delete(result_sets_l[i]);
2507 res = rpn_search_structure(zh, zs->u.complex->s2,
2508 attributeSet, stream, rset_nmem,
2510 num_bases, basenames,
2511 &result_sets_r, &num_result_sets_r,
2513 if (res != ZEBRA_OK)
2516 for (i = 0; i<num_result_sets_l; i++)
2517 rset_delete(result_sets_l[i]);
2518 for (i = 0; i<num_result_sets_r; i++)
2519 rset_delete(result_sets_r[i]);
2523 /* make a new list of result for all children */
2524 *num_result_sets = num_result_sets_l + num_result_sets_r;
2525 *result_sets = nmem_malloc(stream, *num_result_sets *
2526 sizeof(**result_sets));
2527 memcpy(*result_sets, result_sets_l,
2528 num_result_sets_l * sizeof(**result_sets));
2529 memcpy(*result_sets + num_result_sets_l, result_sets_r,
2530 num_result_sets_r * sizeof(**result_sets));
2532 if (!parent_op || parent_op->which != zop->which
2533 || (zop->which != Z_Operator_and &&
2534 zop->which != Z_Operator_or))
2536 /* parent node different from this one (or non-present) */
2537 /* we must combine result sets now */
2541 case Z_Operator_and:
2542 rset = rsmulti_and_create(rset_nmem, kc,
2544 *num_result_sets, *result_sets);
2547 rset = rsmulti_or_create(rset_nmem, kc,
2548 kc->scope, 0, /* termid */
2549 *num_result_sets, *result_sets);
2551 case Z_Operator_and_not:
2552 rset = rsbool_create_not(rset_nmem, kc,
2557 case Z_Operator_prox:
2558 if (zop->u.prox->which != Z_ProximityOperator_known)
2561 YAZ_BIB1_UNSUPP_PROX_UNIT_CODE,
2565 if (*zop->u.prox->u.known != Z_ProxUnit_word)
2567 zebra_setError_zint(zh,
2568 YAZ_BIB1_UNSUPP_PROX_UNIT_CODE,
2569 *zop->u.prox->u.known);
2574 rset = rsprox_create(rset_nmem, kc,
2576 *num_result_sets, *result_sets,
2577 *zop->u.prox->ordered,
2578 (!zop->u.prox->exclusion ?
2579 0 : *zop->u.prox->exclusion),
2580 *zop->u.prox->relationType,
2581 *zop->u.prox->distance );
2585 zebra_setError(zh, YAZ_BIB1_OPERATOR_UNSUPP, 0);
2588 *num_result_sets = 1;
2589 *result_sets = nmem_malloc(stream, *num_result_sets *
2590 sizeof(**result_sets));
2591 (*result_sets)[0] = rset;
2594 else if (zs->which == Z_RPNStructure_simple)
2599 if (zs->u.simple->which == Z_Operand_APT)
2601 yaz_log(YLOG_DEBUG, "rpn_search_APT");
2602 res = rpn_search_APT(zh, zs->u.simple->u.attributesPlusTerm,
2603 attributeSet, stream, sort_sequence,
2604 num_bases, basenames, rset_nmem, &rset,
2606 if (res != ZEBRA_OK)
2609 else if (zs->u.simple->which == Z_Operand_resultSetId)
2611 yaz_log(YLOG_DEBUG, "rpn_search_ref");
2612 rset = resultSetRef(zh, zs->u.simple->u.resultSetId);
2616 YAZ_BIB1_SPECIFIED_RESULT_SET_DOES_NOT_EXIST,
2617 zs->u.simple->u.resultSetId);
2624 zebra_setError(zh, YAZ_BIB1_UNSUPP_SEARCH, 0);
2627 *num_result_sets = 1;
2628 *result_sets = nmem_malloc(stream, *num_result_sets *
2629 sizeof(**result_sets));
2630 (*result_sets)[0] = rset;
2634 zebra_setError(zh, YAZ_BIB1_UNSUPP_SEARCH, 0);
2640 struct scan_info_entry {
2646 struct scan_info_entry *list;
2652 static int scan_handle (char *name, const char *info, int pos, void *client)
2654 int len_prefix, idx;
2655 struct scan_info *scan_info = (struct scan_info *) client;
2657 len_prefix = strlen(scan_info->prefix);
2658 if (memcmp (name, scan_info->prefix, len_prefix))
2661 idx = scan_info->after - pos + scan_info->before;
2667 scan_info->list[idx].term = (char *)
2668 odr_malloc(scan_info->odr, strlen(name + len_prefix)+1);
2669 strcpy(scan_info->list[idx].term, name + len_prefix);
2670 assert (*info == sizeof(ISAM_P));
2671 memcpy (&scan_info->list[idx].isam_p, info+1, sizeof(ISAM_P));
2675 void zebra_term_untrans_iconv(ZebraHandle zh, NMEM stream, int reg_type,
2676 char **dst, const char *src)
2678 char term_src[IT_MAX_WORD];
2679 char term_dst[IT_MAX_WORD];
2681 zebra_term_untrans (zh, reg_type, term_src, src);
2683 if (zh->iconv_from_utf8 != 0)
2686 char *inbuf = term_src;
2687 size_t inleft = strlen(term_src);
2688 char *outbuf = term_dst;
2689 size_t outleft = sizeof(term_dst)-1;
2692 ret = yaz_iconv (zh->iconv_from_utf8, &inbuf, &inleft,
2694 if (ret == (size_t)(-1))
2697 len = outbuf - term_dst;
2698 *dst = nmem_malloc(stream, len + 1);
2700 memcpy (*dst, term_dst, len);
2704 *dst = nmem_strdup(stream, term_src);
2707 static void count_set(ZebraHandle zh, RSET rset, zint *count)
2713 yaz_log(YLOG_DEBUG, "count_set");
2715 rset->hits_limit = zh->approx_limit;
2718 rfd = rset_open(rset, RSETF_READ);
2719 while (rset_read(rfd, &key,0 /* never mind terms */))
2721 if (key.mem[0] != psysno)
2723 psysno = key.mem[0];
2724 if (rfd->counted_items >= rset->hits_limit)
2729 *count = rset->hits_count;
2732 ZEBRA_RES rpn_scan(ZebraHandle zh, ODR stream, Z_AttributesPlusTerm *zapt,
2733 oid_value attributeset,
2734 int num_bases, char **basenames,
2735 int *position, int *num_entries, ZebraScanEntry **list,
2736 int *is_partial, RSET limit_set, int return_zero)
2739 int pos = *position;
2740 int num = *num_entries;
2744 char termz[IT_MAX_WORD+20];
2747 const char *use_string = 0;
2748 struct scan_info *scan_info_array;
2749 ZebraScanEntry *glist;
2750 int ords[32], ord_no = 0;
2753 int bases_ok = 0; /* no of databases with OK attribute */
2754 int errCode = 0; /* err code (if any is not OK) */
2755 char *errString = 0; /* addinfo */
2758 char *search_type = NULL;
2759 char rank_type[128];
2762 NMEM rset_nmem = NULL;
2763 struct rset_key_control *kc = 0;
2768 if (attributeset == VAL_NONE)
2769 attributeset = VAL_BIB1;
2774 int termset_value_numeric;
2775 const char *termset_value_string;
2776 attr_init(&termset, zapt, 8);
2777 termset_value_numeric =
2778 attr_find_ex(&termset, NULL, &termset_value_string);
2779 if (termset_value_numeric != -1)
2782 const char *termset_name = 0;
2784 if (termset_value_numeric != -2)
2787 sprintf(resname, "%d", termset_value_numeric);
2788 termset_name = resname;
2791 termset_name = termset_value_string;
2793 limit_set = resultSetRef (zh, termset_name);
2797 yaz_log(YLOG_DEBUG, "position = %d, num = %d set=%d",
2798 pos, num, attributeset);
2800 attr_init(&use, zapt, 1);
2801 use_value = attr_find_ex(&use, &attributeset, &use_string);
2803 if (zebra_maps_attr(zh->reg->zebra_maps, zapt, ®_id, &search_type,
2804 rank_type, &complete_flag, &sort_flag))
2807 zebra_setError(zh, YAZ_BIB1_UNSUPP_ATTRIBUTE_TYPE, 0);
2810 yaz_log(YLOG_DEBUG, "use_value = %d", use_value);
2812 if (use_value == -1)
2814 for (base_no = 0; base_no < num_bases && ord_no < 32; base_no++)
2816 data1_local_attribute *local_attr;
2820 if (zebraExplain_curDatabase (zh->reg->zei, basenames[base_no]))
2822 zebra_setError(zh, YAZ_BIB1_DATABASE_UNAVAILABLE,
2823 basenames[base_no]);
2829 (ord = zebraExplain_lookup_attr_str(zh->reg->zei,
2832 /* we have a match for a raw string attribute */
2834 ords[ord_no++] = ord;
2835 attp.local_attributes = 0; /* no more attributes */
2841 if ((r = att_getentbyatt (zh, &attp, attributeset, use_value,
2844 yaz_log(YLOG_DEBUG, "att_getentbyatt fail. set=%d use=%d",
2845 attributeset, use_value);
2848 errCode = YAZ_BIB1_UNSUPP_USE_ATTRIBUTE;
2850 zebra_setError(zh, YAZ_BIB1_UNSUPP_USE_ATTRIBUTE,
2853 zebra_setError_zint(zh, YAZ_BIB1_UNSUPP_USE_ATTRIBUTE,
2858 zebra_setError(zh, YAZ_BIB1_UNSUPP_ATTRIBUTE_SET, 0);
2864 for (local_attr = attp.local_attributes; local_attr && ord_no < 32;
2865 local_attr = local_attr->next)
2867 ord = zebraExplain_lookup_attr_su(zh->reg->zei,
2868 attp.attset_ordinal,
2871 ords[ord_no++] = ord;
2874 if (!bases_ok && errCode)
2876 zebra_setError(zh, errCode, errString);
2885 /* prepare dictionary scanning */
2897 yaz_log(YLOG_DEBUG, "rpn_scan pos=%d num=%d before=%d "
2898 "after=%d before+after=%d",
2899 pos, num, before, after, before+after);
2900 scan_info_array = (struct scan_info *)
2901 odr_malloc(stream, ord_no * sizeof(*scan_info_array));
2902 for (i = 0; i < ord_no; i++)
2904 int j, prefix_len = 0;
2905 int before_tmp = before, after_tmp = after;
2906 struct scan_info *scan_info = scan_info_array + i;
2907 struct rpn_char_map_info rcmi;
2909 rpn_char_map_prepare (zh->reg, reg_id, &rcmi);
2911 scan_info->before = before;
2912 scan_info->after = after;
2913 scan_info->odr = stream;
2915 scan_info->list = (struct scan_info_entry *)
2916 odr_malloc(stream, (before+after) * sizeof(*scan_info->list));
2917 for (j = 0; j<before+after; j++)
2918 scan_info->list[j].term = NULL;
2920 prefix_len += key_SU_encode (ords[i], termz + prefix_len);
2921 termz[prefix_len++] = reg_id;
2922 termz[prefix_len] = 0;
2923 strcpy(scan_info->prefix, termz);
2925 if (trans_scan_term(zh, zapt, termz+prefix_len, reg_id) == ZEBRA_FAIL)
2928 dict_scan(zh->reg->dict, termz, &before_tmp, &after_tmp,
2929 scan_info, scan_handle);
2931 glist = (ZebraScanEntry *)
2932 odr_malloc(stream, (before+after)*sizeof(*glist));
2934 rset_nmem = nmem_create();
2935 kc = zebra_key_control_create(zh);
2937 /* consider terms after main term */
2938 for (i = 0; i < ord_no; i++)
2942 for (i = 0; i<after; i++)
2945 const char *mterm = NULL;
2948 int lo = i + pos-1; /* offset in result list */
2950 /* find: j0 is the first of the minimal values */
2951 for (j = 0; j < ord_no; j++)
2953 if (ptr[j] < before+after && ptr[j] >= 0 &&
2954 (tst = scan_info_array[j].list[ptr[j]].term) &&
2955 (!mterm || strcmp (tst, mterm) < 0))
2962 break; /* no value found, stop */
2964 /* get result set for first one , but only if it's within bounds */
2967 /* get result set for first term */
2968 zebra_term_untrans_iconv(zh, stream->mem, reg_id,
2969 &glist[lo].term, mterm);
2970 rset = rset_trunc(zh, &scan_info_array[j0].list[ptr[j0]].isam_p, 1,
2971 glist[lo].term, strlen(glist[lo].term),
2972 NULL, 0, zapt->term->which, rset_nmem,
2973 kc, kc->scope, 0, reg_id, 0 /* hits_limit */,
2974 0 /* term_ref_id_str */);
2976 ptr[j0]++; /* move index for this set .. */
2977 /* get result set for remaining scan terms */
2978 for (j = j0+1; j<ord_no; j++)
2980 if (ptr[j] < before+after && ptr[j] >= 0 &&
2981 (tst = scan_info_array[j].list[ptr[j]].term) &&
2982 !strcmp (tst, mterm))
2991 zh, &scan_info_array[j].list[ptr[j]].isam_p, 1,
2993 strlen(glist[lo].term), NULL, 0,
2994 zapt->term->which,rset_nmem,
2995 kc, kc->scope, 0, reg_id, 0 /* hits_limit */,
2996 0 /* term_ref_id_str */ );
2997 rset = rsmulti_or_create(rset_nmem, kc,
2998 kc->scope, 0 /* termid */,
3007 /* merge with limit_set if given */
3012 rsets[1] = rset_dup(limit_set);
3014 rset = rsmulti_and_create(rset_nmem, kc,
3019 count_set(zh, rset, &count);
3020 glist[lo].occurrences = count;
3026 *num_entries -= (after-i);
3028 if (*num_entries < 0)
3031 nmem_destroy(rset_nmem);
3036 /* consider terms before main term */
3037 for (i = 0; i<ord_no; i++)
3040 for (i = 0; i<before; i++)
3043 const char *mterm = NULL;
3046 int lo = before-1-i; /* offset in result list */
3049 for (j = 0; j <ord_no; j++)
3051 if (ptr[j] < before && ptr[j] >= 0 &&
3052 (tst = scan_info_array[j].list[before-1-ptr[j]].term) &&
3053 (!mterm || strcmp (tst, mterm) > 0))
3062 zebra_term_untrans_iconv(zh, stream->mem, reg_id,
3063 &glist[lo].term, mterm);
3066 (zh, &scan_info_array[j0].list[before-1-ptr[j0]].isam_p, 1,
3067 glist[lo].term, strlen(glist[lo].term),
3068 NULL, 0, zapt->term->which, rset_nmem,
3069 kc, kc->scope, 0, reg_id, 0 /* hits_limit */,
3070 0 /* term_ref_id_str */);
3074 for (j = j0+1; j<ord_no; j++)
3076 if (ptr[j] < before && ptr[j] >= 0 &&
3077 (tst = scan_info_array[j].list[before-1-ptr[j]].term) &&
3078 !strcmp (tst, mterm))
3083 rsets[1] = rset_trunc(
3085 &scan_info_array[j].list[before-1-ptr[j]].isam_p, 1,
3087 strlen(glist[lo].term), NULL, 0,
3088 zapt->term->which, rset_nmem,
3089 kc, kc->scope, 0, reg_id, 0 /* hits_limit */,
3090 0 /* term_ref_id_str */);
3091 rset = rsmulti_or_create(rset_nmem, kc,
3092 kc->scope, 0 /* termid */, 2, rsets);
3101 rsets[1] = rset_dup(limit_set);
3103 rset = rsmulti_and_create(rset_nmem, kc,
3104 kc->scope, 2, rsets);
3106 count_set(zh, rset, &count);
3107 glist[lo].occurrences = count;
3111 nmem_destroy(rset_nmem);
3118 if (*num_entries <= 0)
3125 *list = glist + i; /* list is set to first 'real' entry */
3127 yaz_log(YLOG_DEBUG, "position = %d, num_entries = %d",
3128 *position, *num_entries);