X-Git-Url: http://git.indexdata.com/?a=blobdiff_plain;f=index%2Fzrpn.c;h=a1eb701e2e06e63b5bc363383ea9b49123a8ef19;hb=732e272a6d35533ccc89f4ccab0ea8069097b8a1;hp=0f05b2dfe9894cf5d9495d34214f7d92be8d90c7;hpb=ac66787b71dd244e895a262a82b2a4944f8fea6b;p=idzebra-moved-to-github.git diff --git a/index/zrpn.c b/index/zrpn.c index 0f05b2d..a1eb701 100644 --- a/index/zrpn.c +++ b/index/zrpn.c @@ -1,10 +1,26 @@ -/* - * Copyright (C) 1995-2002, Index Data - * All rights reserved. - * Sebastian Hammer, Adam Dickmeiss - * - * $Id: zrpn.c,v 1.109 2002-02-18 11:46:58 adam Exp $ - */ +/* $Id: zrpn.c,v 1.132 2003-03-31 22:14:18 adam Exp $ + Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002,2003 + Index Data Aps + +This file is part of the Zebra server. + +Zebra is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 2, or (at your option) any later +version. + +Zebra is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with Zebra; see the file LICENSE.zebra. If not, write to the +Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA +02111-1307, USA. +*/ + + #include #include #ifdef WIN32 @@ -14,58 +30,66 @@ #endif #include -#include "zserver.h" +#include "index.h" +#include #include #include #include #include +#include struct rpn_char_map_info { ZebraMaps zm; int reg_type; }; +typedef struct { + int type; + int major; + int minor; + Z_AttributesPlusTerm *zapt; +} AttrType; + + static const char **rpn_char_map_handler (void *vp, const char **from, int len) { struct rpn_char_map_info *p = (struct rpn_char_map_info *) vp; - return zebra_maps_input (p->zm, p->reg_type, from, len); + const char **out = zebra_maps_input (p->zm, p->reg_type, from, len); +#if 0 + if (out && *out) + { + const char *outp = *out; + yaz_log (LOG_LOG, "---"); + while (*outp) + { + yaz_log (LOG_LOG, "%02X", *outp); + outp++; + } + } +#endif + return out; } -static void rpn_char_map_prepare (ZebraHandle zh, int reg_type, +static void rpn_char_map_prepare (struct zebra_register *reg, int reg_type, struct rpn_char_map_info *map_info) { - map_info->zm = zh->service->zebra_maps; + map_info->zm = reg->zebra_maps; map_info->reg_type = reg_type; - dict_grep_cmap (zh->service->dict, map_info, rpn_char_map_handler); + dict_grep_cmap (reg->dict, map_info, rpn_char_map_handler); } -typedef struct { - int type; - int major; - int minor; - Z_AttributesPlusTerm *zapt; -} AttrType; - static int attr_find_ex (AttrType *src, oid_value *attributeSetP, const char **string_value) { int num_attributes; -#ifdef ASN_COMPILED num_attributes = src->zapt->attributes->num_attributes; -#else - num_attributes = src->zapt->num_attributes; -#endif while (src->major < num_attributes) { Z_AttributeElement *element; -#ifdef ASN_COMPILED element = src->zapt->attributes->attributes[src->major]; -#else - element = src->zapt->attributeList[src->major]; -#endif if (src->type == *element->attributeType) { switch (element->which) @@ -84,17 +108,17 @@ static int attr_find_ex (AttrType *src, oid_value *attributeSetP, case Z_AttributeValue_complex: if (src->minor >= element->value.complex->num_list) break; + if (element->attributeSet && attributeSetP) + { + oident *attrset; + + attrset = oid_getentbyoid (element->attributeSet); + *attributeSetP = attrset->value; + } if (element->value.complex->list[src->minor]->which == Z_StringOrNumeric_numeric) { ++(src->minor); - if (element->attributeSet && attributeSetP) - { - oident *attrset; - - attrset = oid_getentbyoid (element->attributeSet); - *attributeSetP = attrset->value; - } return *element->value.complex->list[src->minor-1]->u.numeric; } @@ -150,17 +174,18 @@ struct grep_info { static void term_untrans (ZebraHandle zh, int reg_type, char *dst, const char *src) { + int len = 0; while (*src) { - const char *cp = zebra_maps_output (zh->service->zebra_maps, + const char *cp = zebra_maps_output (zh->reg->zebra_maps, reg_type, &src); - if (!cp) - *dst++ = *src++; + if (!cp && len < IT_MAX_WORD-1) + dst[len++] = *src++; else - while (*cp) - *dst++ = *cp++; + while (*cp && len < IT_MAX_WORD-1) + dst[len++] = *cp++; } - *dst = '\0'; + dst[len] = '\0'; } static void add_isam_p (const char *name, const char *info, @@ -203,13 +228,13 @@ static void add_isam_p (const char *name, const char *info, { const char *db; int set, use; - char term_tmp[512]; + char term_tmp[IT_MAX_WORD]; int su_code = 0; int len = key_SU_decode (&su_code, name); term_untrans (p->zh, p->reg_type, term_tmp, name+len+1); logf (LOG_LOG, "grep: %d %c %s", su_code, name[len], term_tmp); - zebraExplain_lookup_ord (p->zh->service->zei, + zebraExplain_lookup_ord (p->zh->reg->zei, su_code, &db, &set, &use); logf (LOG_LOG, "grep: set=%d use=%d db=%s", set, use, db); @@ -249,6 +274,8 @@ static int term_pre (ZebraMaps zebra_maps, int reg_type, const char **src, return *s0; } +#define REGEX_CHARS " []()|.*+?!" + /* term_100: handle term, where trunc=none (no operators at all) */ static int term_100 (ZebraMaps zebra_maps, int reg_type, const char **src, char *dst, int space_split, @@ -286,7 +313,7 @@ static int term_100 (ZebraMaps zebra_maps, int reg_type, { /* reload last space */ while (space_start < space_end) { - if (!isalnum (*space_start) && *space_start != '-') + if (strchr (REGEX_CHARS, *space_start)) dst[i++] = '\\'; dst_term[j++] = *space_start; dst[i++] = *space_start++; @@ -298,7 +325,7 @@ static int term_100 (ZebraMaps zebra_maps, int reg_type, /* add non-space char */ while (s1 < s0) { - if (!isalnum (*s1) && *s1 != '-') + if (strchr(REGEX_CHARS, *s1)) dst[i++] = '\\'; dst_term[j++] = *s1; dst[i++] = *s1++; @@ -339,7 +366,7 @@ static int term_101 (ZebraMaps zebra_maps, int reg_type, break; while (s1 < s0) { - if (!isalnum (*s1)) + if (strchr(REGEX_CHARS, *s1)) dst[i++] = '\\'; dst_term[j++] = *s1; dst[i++] = *s1++; @@ -388,7 +415,7 @@ static int term_103 (ZebraMaps zebra_maps, int reg_type, const char **src, break; while (s1 < s0) { - if (!isalnum (*s1)) + if (strchr(REGEX_CHARS, *s1)) dst[i++] = '\\'; dst_term[j++] = *s1; dst[i++] = *s1++; @@ -420,18 +447,43 @@ static int term_104 (ZebraMaps zebra_maps, int reg_type, int i = 0; int j = 0; - if (!term_pre (zebra_maps, reg_type, src, "#!", "#!")) + if (!term_pre (zebra_maps, reg_type, src, "?*#", "?*#")) return 0; s0 = *src; while (*s0) { - if (*s0 == '#') + if (*s0 == '?') + { + dst_term[j++] = *s0++; + if (*s0 >= '0' && *s0 <= '9') + { + int limit = 0; + while (*s0 >= '0' && *s0 <= '9') + { + limit = limit * 10 + (*s0 - '0'); + dst_term[j++] = *s0++; + } + if (limit > 20) + limit = 20; + while (--limit >= 0) + { + dst[i++] = '.'; + dst[i++] = '?'; + } + } + else + { + dst[i++] = '.'; + dst[i++] = '*'; + } + } + else if (*s0 == '*') { dst[i++] = '.'; dst[i++] = '*'; dst_term[j++] = *s0++; } - else if (*s0 == '!') + else if (*s0 == '#') { dst[i++] = '.'; dst_term[j++] = *s0++; @@ -443,7 +495,7 @@ static int term_104 (ZebraMaps zebra_maps, int reg_type, break; while (s1 < s0) { - if (!isalnum (*s1)) + if (strchr(REGEX_CHARS, *s1)) dst[i++] = '\\'; dst_term[j++] = *s1; dst[i++] = *s1++; @@ -489,7 +541,7 @@ static int term_105 (ZebraMaps zebra_maps, int reg_type, break; while (s1 < s0) { - if (!isalnum (*s1)) + if (strchr(REGEX_CHARS, *s1)) dst[i++] = '\\'; dst_term[j++] = *s1; dst[i++] = *s1++; @@ -656,7 +708,7 @@ static int string_relation (ZebraHandle zh, Z_AttributesPlusTerm *zapt, switch (relation_value) { case 1: - if (!term_100 (zh->service->zebra_maps, reg_type, + if (!term_100 (zh->reg->zebra_maps, reg_type, term_sub, term_component, space_split, term_dst)) return 0; @@ -686,7 +738,7 @@ static int string_relation (ZebraHandle zh, Z_AttributesPlusTerm *zapt, *term_tmp = '\0'; break; case 2: - if (!term_100 (zh->service->zebra_maps, reg_type, + if (!term_100 (zh->reg->zebra_maps, reg_type, term_sub, term_component, space_split, term_dst)) return 0; @@ -717,7 +769,7 @@ static int string_relation (ZebraHandle zh, Z_AttributesPlusTerm *zapt, *term_tmp = '\0'; break; case 5: - if (!term_100 (zh->service->zebra_maps, reg_type, + if (!term_100 (zh->reg->zebra_maps, reg_type, term_sub, term_component, space_split, term_dst)) return 0; logf (LOG_DEBUG, "Relation >"); @@ -749,7 +801,7 @@ static int string_relation (ZebraHandle zh, Z_AttributesPlusTerm *zapt, *term_tmp = '\0'; break; case 4: - if (!term_100 (zh->service->zebra_maps, reg_type, term_sub, + if (!term_100 (zh->reg->zebra_maps, reg_type, term_sub, term_component, space_split, term_dst)) return 0; logf (LOG_DEBUG, "Relation >="); @@ -786,7 +838,7 @@ static int string_relation (ZebraHandle zh, Z_AttributesPlusTerm *zapt, case 3: default: logf (LOG_DEBUG, "Relation ="); - if (!term_100 (zh->service->zebra_maps, reg_type, term_sub, + if (!term_100 (zh->reg->zebra_maps, reg_type, term_sub, term_component, space_split, term_dst)) return 0; strcat (term_tmp, "("); @@ -797,12 +849,44 @@ static int string_relation (ZebraHandle zh, Z_AttributesPlusTerm *zapt, } static int string_term (ZebraHandle zh, Z_AttributesPlusTerm *zapt, - const char **term_sub, - oid_value attributeSet, NMEM stream, - struct grep_info *grep_info, - int reg_type, int complete_flag, - int num_bases, char **basenames, - char *term_dst) + const char **term_sub, + oid_value attributeSet, NMEM stream, + struct grep_info *grep_info, + int reg_type, int complete_flag, + int num_bases, char **basenames, + char *term_dst, int xpath_use); + +static RSET term_trunc (ZebraHandle zh, Z_AttributesPlusTerm *zapt, + const char **term_sub, + oid_value attributeSet, NMEM stream, + struct grep_info *grep_info, + int reg_type, int complete_flag, + int num_bases, char **basenames, + char *term_dst, + const char *rank_type, int xpath_use) +{ + int r; + grep_info->isam_p_indx = 0; + r = string_term (zh, zapt, term_sub, attributeSet, stream, grep_info, + reg_type, complete_flag, num_bases, basenames, + term_dst, xpath_use); + if (r < 1) + return 0; + logf (LOG_DEBUG, "term: %s", term_dst); + return rset_trunc (zh, grep_info->isam_p_buf, + grep_info->isam_p_indx, term_dst, + strlen(term_dst), rank_type, 1 /* preserve pos */, + zapt->term->which); +} + + +static int string_term (ZebraHandle zh, Z_AttributesPlusTerm *zapt, + const char **term_sub, + oid_value attributeSet, NMEM stream, + struct grep_info *grep_info, + int reg_type, int complete_flag, + int num_bases, char **basenames, + char *term_dst, int xpath_use) { char term_dict[2*IT_MAX_WORD+4000]; int j, r, base_no; @@ -810,93 +894,114 @@ static int string_term (ZebraHandle zh, Z_AttributesPlusTerm *zapt, int truncation_value; AttrType use; int use_value; + const char *use_string = 0; oid_value curAttributeSet = attributeSet; const char *termp; struct rpn_char_map_info rcmi; int space_split = complete_flag ? 0 : 1; - rpn_char_map_prepare (zh, reg_type, &rcmi); + rpn_char_map_prepare (zh->reg, reg_type, &rcmi); attr_init (&use, zapt, 1); - use_value = attr_find (&use, &curAttributeSet); + use_value = attr_find_ex (&use, &curAttributeSet, &use_string); logf (LOG_DEBUG, "string_term, use value %d", use_value); attr_init (&truncation, zapt, 5); truncation_value = attr_find (&truncation, NULL); logf (LOG_DEBUG, "truncation value %d", truncation_value); - if (use_value == -1) + if (use_value == -1) /* no attribute - assumy "any" */ use_value = 1016; - for (base_no = 0; base_no < num_bases; base_no++) { attent attp; + data1_local_attribute id_xpath_attr; data1_local_attribute *local_attr; int max_pos, prefix_len = 0; termp = *term_sub; - if ((r=att_getentbyatt (zh, &attp, curAttributeSet, use_value))) - { - logf (LOG_DEBUG, "att_getentbyatt fail. set=%d use=%d r=%d", - curAttributeSet, use_value, r); - if (r == -1) - { - char val_str[32]; - sprintf (val_str, "%d", use_value); - zh->errCode = 114; - zh->errString = nmem_strdup (stream, val_str); - } - else - { - int oid[OID_SIZE]; - struct oident oident; - - oident.proto = PROTO_Z3950; - oident.oclass = CLASS_ATTSET; - oident.value = curAttributeSet; - oid_ent_to_oid (&oident, oid); - zh->errCode = 121; - zh->errString = nmem_strdup (stream, oident.desc); - } - return -1; - } - if (zebraExplain_curDatabase (zh->service->zei, basenames[base_no])) + if (zebraExplain_curDatabase (zh->reg->zei, basenames[base_no])) { zh->errCode = 109; /* Database unavailable */ zh->errString = basenames[base_no]; return -1; } + if (use_value == -2) /* string attribute (assume IDXPATH/any) */ + { + use_value = xpath_use; + attp.local_attributes = &id_xpath_attr; + attp.attset_ordinal = VAL_IDXPATH; + id_xpath_attr.next = 0; + id_xpath_attr.local = use_value; + } + else if (curAttributeSet == VAL_IDXPATH) + { + attp.local_attributes = &id_xpath_attr; + attp.attset_ordinal = VAL_IDXPATH; + id_xpath_attr.next = 0; + id_xpath_attr.local = use_value; + } + else + { + if ((r=att_getentbyatt (zh, &attp, curAttributeSet, use_value))) + { + logf (LOG_DEBUG, "att_getentbyatt fail. set=%d use=%d r=%d", + curAttributeSet, use_value, r); + if (r == -1) + { + /* set was found, but value wasn't defined */ + char val_str[32]; + sprintf (val_str, "%d", use_value); + zh->errCode = 114; + zh->errString = nmem_strdup (stream, val_str); + } + else + { + int oid[OID_SIZE]; + struct oident oident; + + oident.proto = PROTO_Z3950; + oident.oclass = CLASS_ATTSET; + oident.value = curAttributeSet; + oid_ent_to_oid (&oident, oid); + + zh->errCode = 121; + zh->errString = nmem_strdup (stream, oident.desc); + } + return -1; + } + } for (local_attr = attp.local_attributes; local_attr; local_attr = local_attr->next) { int ord; - char ord_buf[32]; - int i, ord_len; - - ord = zebraExplain_lookupSU (zh->service->zei, attp.attset_ordinal, - local_attr->local); + char ord_buf[32]; + int i, ord_len; + + ord = zebraExplain_lookupSU (zh->reg->zei, attp.attset_ordinal, + local_attr->local); if (ord < 0) continue; if (prefix_len) term_dict[prefix_len++] = '|'; else term_dict[prefix_len++] = '('; - - ord_len = key_SU_encode (ord, ord_buf); - for (i = 0; ierrCode = 114; - zh->errString = nmem_strdup (stream, val_str); + char val_str[32]; + sprintf (val_str, "%d", use_value); + zh->errCode = 114; + zh->errString = nmem_strdup (stream, val_str); return -1; } - term_dict[prefix_len++] = ')'; + term_dict[prefix_len++] = ')'; term_dict[prefix_len++] = 1; term_dict[prefix_len++] = reg_type; logf (LOG_DEBUG, "reg_type = %d", term_dict[prefix_len-1]); @@ -910,60 +1015,60 @@ static int string_term (ZebraHandle zh, Z_AttributesPlusTerm *zapt, attributeSet, reg_type, space_split, term_dst)) return 0; - logf (LOG_DEBUG, "dict_lookup_grep: %s", term_dict+prefix_len); - r = dict_lookup_grep (zh->service->dict, term_dict, 0, + logf (LOG_LOG, "dict_lookup_grep: %s", term_dict+prefix_len); + r = dict_lookup_grep (zh->reg->dict, term_dict, 0, grep_info, &max_pos, 0, grep_handle); if (r) - logf (LOG_WARN, "dict_lookup_grep fail, rel=gt: %d", r); + logf (LOG_WARN, "dict_lookup_grep fail %d", r); break; case 1: /* right truncation */ term_dict[j++] = '('; - if (!term_100 (zh->service->zebra_maps, reg_type, + if (!term_100 (zh->reg->zebra_maps, reg_type, &termp, term_dict + j, space_split, term_dst)) return 0; strcat (term_dict, ".*)"); - dict_lookup_grep (zh->service->dict, term_dict, 0, grep_info, + dict_lookup_grep (zh->reg->dict, term_dict, 0, grep_info, &max_pos, 0, grep_handle); break; case 2: /* keft truncation */ term_dict[j++] = '('; term_dict[j++] = '.'; term_dict[j++] = '*'; - if (!term_100 (zh->service->zebra_maps, reg_type, + if (!term_100 (zh->reg->zebra_maps, reg_type, &termp, term_dict + j, space_split, term_dst)) return 0; strcat (term_dict, ")"); - dict_lookup_grep (zh->service->dict, term_dict, 0, grep_info, + dict_lookup_grep (zh->reg->dict, term_dict, 0, grep_info, &max_pos, 0, grep_handle); break; case 3: /* left&right truncation */ term_dict[j++] = '('; term_dict[j++] = '.'; term_dict[j++] = '*'; - if (!term_100 (zh->service->zebra_maps, reg_type, + if (!term_100 (zh->reg->zebra_maps, reg_type, &termp, term_dict + j, space_split, term_dst)) return 0; strcat (term_dict, ".*)"); - dict_lookup_grep (zh->service->dict, term_dict, 0, grep_info, + dict_lookup_grep (zh->reg->dict, term_dict, 0, grep_info, &max_pos, 0, grep_handle); break; zh->errCode = 120; return -1; case 101: /* process # in term */ term_dict[j++] = '('; - if (!term_101 (zh->service->zebra_maps, reg_type, + if (!term_101 (zh->reg->zebra_maps, reg_type, &termp, term_dict + j, space_split, term_dst)) return 0; strcat (term_dict, ")"); - r = dict_lookup_grep (zh->service->dict, term_dict, 0, grep_info, + r = dict_lookup_grep (zh->reg->dict, term_dict, 0, grep_info, &max_pos, 0, grep_handle); if (r) logf (LOG_WARN, "dict_lookup_grep err, trunc=#: %d", r); break; case 102: /* Regexp-1 */ term_dict[j++] = '('; - if (!term_102 (zh->service->zebra_maps, reg_type, + if (!term_102 (zh->reg->zebra_maps, reg_type, &termp, term_dict + j, space_split, term_dst)) return 0; strcat (term_dict, ")"); logf (LOG_DEBUG, "Regexp-1 tolerance=%d", r); - r = dict_lookup_grep (zh->service->dict, term_dict, 0, grep_info, + r = dict_lookup_grep (zh->reg->dict, term_dict, 0, grep_info, &max_pos, 0, grep_handle); if (r) logf (LOG_WARN, "dict_lookup_grep err, trunc=regular: %d", @@ -972,12 +1077,12 @@ static int string_term (ZebraHandle zh, Z_AttributesPlusTerm *zapt, case 103: /* Regexp-2 */ r = 1; term_dict[j++] = '('; - if (!term_103 (zh->service->zebra_maps, reg_type, + if (!term_103 (zh->reg->zebra_maps, reg_type, &termp, term_dict + j, &r, space_split, term_dst)) return 0; strcat (term_dict, ")"); logf (LOG_DEBUG, "Regexp-2 tolerance=%d", r); - r = dict_lookup_grep (zh->service->dict, term_dict, r, grep_info, + r = dict_lookup_grep (zh->reg->dict, term_dict, r, grep_info, &max_pos, 2, grep_handle); if (r) logf (LOG_WARN, "dict_lookup_grep err, trunc=eregular: %d", @@ -985,33 +1090,33 @@ static int string_term (ZebraHandle zh, Z_AttributesPlusTerm *zapt, break; case 104: /* process # and ! in term */ term_dict[j++] = '('; - if (!term_104 (zh->service->zebra_maps, reg_type, + if (!term_104 (zh->reg->zebra_maps, reg_type, &termp, term_dict + j, space_split, term_dst)) return 0; strcat (term_dict, ")"); - r = dict_lookup_grep (zh->service->dict, term_dict, 0, grep_info, + r = dict_lookup_grep (zh->reg->dict, term_dict, 0, grep_info, &max_pos, 0, grep_handle); if (r) logf (LOG_WARN, "dict_lookup_grep err, trunc=#/!: %d", r); break; case 105: /* process * and ! in term */ term_dict[j++] = '('; - if (!term_105 (zh->service->zebra_maps, reg_type, + if (!term_105 (zh->reg->zebra_maps, reg_type, &termp, term_dict + j, space_split, term_dst, 1)) return 0; strcat (term_dict, ")"); - r = dict_lookup_grep (zh->service->dict, term_dict, 0, grep_info, + r = dict_lookup_grep (zh->reg->dict, term_dict, 0, grep_info, &max_pos, 0, grep_handle); if (r) logf (LOG_WARN, "dict_lookup_grep err, trunc=*/!: %d", r); break; case 106: /* process * and ! in term */ term_dict[j++] = '('; - if (!term_105 (zh->service->zebra_maps, reg_type, + if (!term_105 (zh->reg->zebra_maps, reg_type, &termp, term_dict + j, space_split, term_dst, 0)) return 0; strcat (term_dict, ")"); - r = dict_lookup_grep (zh->service->dict, term_dict, 0, grep_info, + r = dict_lookup_grep (zh->reg->dict, term_dict, 0, grep_info, &max_pos, 0, grep_handle); if (r) logf (LOG_WARN, "dict_lookup_grep err, trunc=*/!: %d", r); @@ -1023,47 +1128,94 @@ static int string_term (ZebraHandle zh, Z_AttributesPlusTerm *zapt, return 1; } -static void trans_term (ZebraHandle zh, Z_AttributesPlusTerm *zapt, - char *termz) + +/* convert APT search term to UTF8 */ +static int zapt_term_to_utf8 (ZebraHandle zh, Z_AttributesPlusTerm *zapt, + char *termz) { size_t sizez; Z_Term *term = zapt->term; - sizez = term->u.general->len; - if (sizez > IT_MAX_WORD-1) - sizez = IT_MAX_WORD-1; - memcpy (termz, term->u.general->buf, sizez); - termz[sizez] = '\0'; + switch (term->which) + { + case Z_Term_general: + if (zh->iconv_to_utf8 != 0) + { + char *inbuf = term->u.general->buf; + size_t inleft = term->u.general->len; + char *outbuf = termz; + size_t outleft = IT_MAX_WORD-1; + size_t ret; + + ret = yaz_iconv(zh->iconv_to_utf8, &inbuf, &inleft, + &outbuf, &outleft); + if (ret == (size_t)(-1)) + { + ret = yaz_iconv(zh->iconv_to_utf8, 0, 0, 0, 0); + zh->errCode = 125; + return -1; + } + *outbuf = 0; + } + else + { + sizez = term->u.general->len; + if (sizez > IT_MAX_WORD-1) + sizez = IT_MAX_WORD-1; + memcpy (termz, term->u.general->buf, sizez); + termz[sizez] = '\0'; + } + break; + case Z_Term_characterString: + sizez = strlen(term->u.characterString); + if (sizez > IT_MAX_WORD-1) + sizez = IT_MAX_WORD-1; + memcpy (termz, term->u.characterString, sizez); + termz[sizez] = '\0'; + break; + default: + zh->errCode = 124; + return -1; + } + return 0; } -static void trans_scan_term (ZebraHandle zh, Z_AttributesPlusTerm *zapt, - char *termz, int reg_type) +/* convert APT SCAN term to internal cmap */ +static int trans_scan_term (ZebraHandle zh, Z_AttributesPlusTerm *zapt, + char *termz, int reg_type) { - Z_Term *term = zapt->term; - const char **map; - const char *cp = (const char *) term->u.general->buf; - const char *cp_end = cp + term->u.general->len; - const char *src; - int i = 0; - const char *space_map = NULL; - int len; - - while ((len = (cp_end - cp)) > 0) + char termz0[IT_MAX_WORD]; + + if (zapt_term_to_utf8(zh, zapt, termz0)) + return -1; /* error */ + else { - map = zebra_maps_input (zh->service->zebra_maps, reg_type, &cp, len); - if (**map == *CHR_SPACE) - space_map = *map; - else + const char **map; + const char *cp = (const char *) termz0; + const char *cp_end = cp + strlen(cp); + const char *src; + int i = 0; + const char *space_map = NULL; + int len; + + while ((len = (cp_end - cp)) > 0) { - if (i && space_map) - for (src = space_map; *src; src++) + map = zebra_maps_input (zh->reg->zebra_maps, reg_type, &cp, len); + if (**map == *CHR_SPACE) + space_map = *map; + else + { + if (i && space_map) + for (src = space_map; *src; src++) + termz[i++] = *src; + space_map = NULL; + for (src = *map; *src; src++) termz[i++] = *src; - space_map = NULL; - for (src = *map; *src; src++) - termz[i++] = *src; + } } + termz[i] = '\0'; } - termz[i] = '\0'; + return 0; } static RSET rpn_prox (ZebraHandle zh, RSET *rset, int rset_no, @@ -1078,6 +1230,7 @@ static RSET rpn_prox (ZebraHandle zh, RSET *rset, int rset_no, int length_prox_term = 0; int min_nn = 10000000; int term_index; + int term_type = Z_Term_characterString; const char *flags = NULL; rsfd = (RSFD *) xmalloc (sizeof(*rsfd)*rset_no); @@ -1103,6 +1256,12 @@ static RSET rpn_prox (ZebraHandle zh, RSET *rset, int rset_no, if (min_nn > rset[i]->rset_terms[j]->nn) min_nn = rset[i]->rset_terms[j]->nn; flags = nflags; + term_type = rset[i]->rset_terms[j]->type; + + /* only if all term types are of type characterString .. */ + /* the resulting term is of that type */ + if (term_type != Z_Term_characterString) + term_type = Z_Term_general; } } for (i = 0; inn = 0; result = rset_create (rset_kind_null, &parms); } @@ -1134,13 +1293,14 @@ static RSET rpn_prox (ZebraHandle zh, RSET *rset, int rset_no, RSFD rsfd_result; parms.rset_term = rset_term_create (prox_term, length_prox_term, - flags); + flags, term_type); parms.rset_term->nn = min_nn; + parms.cmp = key_compare_it; parms.key_size = sizeof (struct it_key); - parms.temp_path = res_get (zh->service->res, "setTmpDir"); + parms.temp_path = res_get (zh->res, "setTmpDir"); result = rset_create (rset_kind_temp, &parms); rsfd_result = rset_open (result, RSETF_WRITE); - + while (*more) { for (i = 1; inn = min_nn; + parms.cmp = key_compare_it; parms.key_size = sizeof (struct it_key); - parms.temp_path = res_get (zh->service->res, "setTmpDir"); + parms.temp_path = res_get (zh->res, "setTmpDir"); result = rset_create (rset_kind_temp, &parms); rsfd_result = rset_open (result, RSETF_WRITE); @@ -1271,7 +1433,7 @@ static RSET rpn_prox (ZebraHandle zh, RSET *rset, int rset_no, rset_null_parms parms; parms.rset_term = rset_term_create (prox_term, length_prox_term, - flags); + flags, term_type); parms.rset_term->nn = 0; result = rset_create (rset_kind_null, &parms); } @@ -1319,7 +1481,7 @@ char *normalize_term(ZebraHandle zh, Z_AttributesPlusTerm *zapt, break; } if (ex_list) - wrbuf = zebra_replace(zh->service->zebra_maps, reg_id, ex_list, + wrbuf = zebra_replace(zh->reg->zebra_maps, reg_id, ex_list, termz, strlen(termz)); if (!wrbuf) return nmem_strdup(stream, termz); @@ -1332,6 +1494,14 @@ char *normalize_term(ZebraHandle zh, Z_AttributesPlusTerm *zapt, } } +static void grep_info_delete (struct grep_info *grep_info) +{ +#ifdef TERM_COUNT + xfree(grep_info->term_no); +#endif + xfree (grep_info->isam_p_buf); +} + static int grep_info_prepare (ZebraHandle zh, Z_AttributesPlusTerm *zapt, struct grep_info *grep_info, @@ -1351,6 +1521,8 @@ static int grep_info_prepare (ZebraHandle zh, grep_info->reg_type = reg_type; grep_info->termset = 0; + if (!zapt) + return 0; attr_init (&termset, zapt, 8); termset_value_numeric = attr_find_ex (&termset, NULL, &termset_value_string); @@ -1385,44 +1557,40 @@ static RSET rpn_search_APT_phrase (ZebraHandle zh, oid_value attributeSet, NMEM stream, int reg_type, int complete_flag, - const char *rank_type, + const char *rank_type, int xpath_use, int num_bases, char **basenames) { char term_dst[IT_MAX_WORD+1]; RSET rset[60], result; - int i, r, rset_no = 0; + int i, rset_no = 0; struct grep_info grep_info; char *termz = normalize_term(zh, zapt, termz_org, stream, reg_type); const char *termp = termz; + *term_dst = 0; if (grep_info_prepare (zh, zapt, &grep_info, reg_type, stream)) return 0; while (1) { logf (LOG_DEBUG, "APT_phrase termp=%s", termp); - grep_info.isam_p_indx = 0; - r = string_term (zh, zapt, &termp, attributeSet, stream, &grep_info, - reg_type, complete_flag, num_bases, basenames, - term_dst); - if (r < 1) + rset[rset_no] = term_trunc (zh, zapt, &termp, attributeSet, + stream, &grep_info, + reg_type, complete_flag, + num_bases, basenames, + term_dst, rank_type, + xpath_use); + if (!rset[rset_no]) break; - logf (LOG_DEBUG, "term: %s", term_dst); - rset[rset_no] = rset_trunc (zh, grep_info.isam_p_buf, - grep_info.isam_p_indx, term_dst, - strlen(term_dst), rank_type); - assert (rset[rset_no]); if (++rset_no >= (int) (sizeof(rset)/sizeof(*rset))) break; } -#ifdef TERM_COUNT - xfree(grep_info.term_no); -#endif - xfree (grep_info.isam_p_buf); + grep_info_delete (&grep_info); if (rset_no == 0) { rset_null_parms parms; - parms.rset_term = rset_term_create (term_dst, -1, rank_type); + parms.rset_term = rset_term_create (termz, -1, rank_type, + zapt->term->which); return rset_create (rset_kind_null, &parms); } else if (rset_no == 1) @@ -1440,11 +1608,12 @@ static RSET rpn_search_APT_or_list (ZebraHandle zh, NMEM stream, int reg_type, int complete_flag, const char *rank_type, + int xpath_use, int num_bases, char **basenames) { char term_dst[IT_MAX_WORD+1]; RSET rset[60], result; - int i, r, rset_no = 0; + int i, rset_no = 0; struct grep_info grep_info; char *termz = normalize_term(zh, zapt, termz_org, stream, reg_type); const char *termp = termz; @@ -1454,29 +1623,24 @@ static RSET rpn_search_APT_or_list (ZebraHandle zh, while (1) { logf (LOG_DEBUG, "APT_or_list termp=%s", termp); - grep_info.isam_p_indx = 0; - r = string_term (zh, zapt, &termp, attributeSet, stream, &grep_info, - reg_type, complete_flag, num_bases, basenames, - term_dst); - if (r < 1) + rset[rset_no] = term_trunc (zh, zapt, &termp, attributeSet, + stream, &grep_info, + reg_type, complete_flag, + num_bases, basenames, + term_dst, rank_type, + xpath_use); + if (!rset[rset_no]) break; - logf (LOG_DEBUG, "term: %s", term_dst); - rset[rset_no] = rset_trunc (zh, grep_info.isam_p_buf, - grep_info.isam_p_indx, term_dst, - strlen(term_dst), rank_type); - assert (rset[rset_no]); if (++rset_no >= (int) (sizeof(rset)/sizeof(*rset))) break; } -#ifdef TERM_COUNT - xfree(grep_info.term_no); -#endif - xfree (grep_info.isam_p_buf); + grep_info_delete (&grep_info); if (rset_no == 0) { rset_null_parms parms; - parms.rset_term = rset_term_create (term_dst, -1, rank_type); + parms.rset_term = rset_term_create (termz, -1, rank_type, + zapt->term->which); return rset_create (rset_kind_null, &parms); } result = rset[0]; @@ -1499,12 +1663,13 @@ static RSET rpn_search_APT_and_list (ZebraHandle zh, oid_value attributeSet, NMEM stream, int reg_type, int complete_flag, - const char *rank_type, + const char *rank_type, + int xpath_use, int num_bases, char **basenames) { char term_dst[IT_MAX_WORD+1]; RSET rset[60], result; - int i, r, rset_no = 0; + int i, rset_no = 0; struct grep_info grep_info; char *termz = normalize_term(zh, zapt, termz_org, stream, reg_type); const char *termp = termz; @@ -1514,29 +1679,25 @@ static RSET rpn_search_APT_and_list (ZebraHandle zh, while (1) { logf (LOG_DEBUG, "APT_and_list termp=%s", termp); - grep_info.isam_p_indx = 0; - r = string_term (zh, zapt, &termp, attributeSet, stream, &grep_info, - reg_type, complete_flag, num_bases, basenames, - term_dst); - if (r < 1) + rset[rset_no] = term_trunc (zh, zapt, &termp, attributeSet, + stream, &grep_info, + reg_type, complete_flag, + num_bases, basenames, + term_dst, rank_type, + xpath_use); + if (!rset[rset_no]) break; - logf (LOG_DEBUG, "term: %s", term_dst); - rset[rset_no] = rset_trunc (zh, grep_info.isam_p_buf, - grep_info.isam_p_indx, term_dst, - strlen(term_dst), rank_type); assert (rset[rset_no]); if (++rset_no >= (int) (sizeof(rset)/sizeof(*rset))) break; } -#ifdef TERM_COUNT - xfree(grep_info.term_no); -#endif - xfree (grep_info.isam_p_buf); + grep_info_delete (&grep_info); if (rset_no == 0) { rset_null_parms parms; - parms.rset_term = rset_term_create (term_dst, -1, rank_type); + parms.rset_term = rset_term_create (termz, -1, rank_type, + zapt->term->which); return rset_create (rset_kind_null, &parms); } result = rset[0]; @@ -1573,7 +1734,7 @@ static int numeric_relation (ZebraHandle zh, Z_AttributesPlusTerm *zapt, logf (LOG_DEBUG, "numeric relation value=%d", relation_value); - if (!term_100 (zh->service->zebra_maps, reg_type, term_sub, term_tmp, 1, + if (!term_100 (zh->reg->zebra_maps, reg_type, term_sub, term_tmp, 1, term_dst)) return 0; term_value = atoi (term_tmp); @@ -1601,7 +1762,7 @@ static int numeric_relation (ZebraHandle zh, Z_AttributesPlusTerm *zapt, sprintf (term_tmp, "(0*%d)", term_value); } logf (LOG_DEBUG, "dict_lookup_grep: %s", term_tmp); - r = dict_lookup_grep (zh->service->dict, term_dict, 0, grep_info, max_pos, + r = dict_lookup_grep (zh->reg->dict, term_dict, 0, grep_info, max_pos, 0, grep_handle); if (r) logf (LOG_WARN, "dict_lookup_grep fail, rel=gt: %d", r); @@ -1614,20 +1775,20 @@ static int numeric_term (ZebraHandle zh, Z_AttributesPlusTerm *zapt, oid_value attributeSet, struct grep_info *grep_info, int reg_type, int complete_flag, int num_bases, char **basenames, - char *term_dst) + char *term_dst, int xpath_use, NMEM stream) { char term_dict[2*IT_MAX_WORD+2]; int r, base_no; AttrType use; int use_value; + const char *use_string = 0; oid_value curAttributeSet = attributeSet; const char *termp; struct rpn_char_map_info rcmi; - rpn_char_map_prepare (zh, reg_type, &rcmi); + rpn_char_map_prepare (zh->reg, reg_type, &rcmi); attr_init (&use, zapt, 1); - use_value = attr_find (&use, &curAttributeSet); - logf (LOG_DEBUG, "numeric_term, use value %d", use_value); + use_value = attr_find_ex (&use, &curAttributeSet, &use_string); if (use_value == -1) use_value = 1016; @@ -1635,21 +1796,45 @@ static int numeric_term (ZebraHandle zh, Z_AttributesPlusTerm *zapt, for (base_no = 0; base_no < num_bases; base_no++) { attent attp; + data1_local_attribute id_xpath_attr; data1_local_attribute *local_attr; int max_pos, prefix_len = 0; termp = *term_sub; - if ((r=att_getentbyatt (zh, &attp, curAttributeSet, use_value))) + if (use_value == -2) /* string attribute (assume IDXPATH/any) */ { - logf (LOG_DEBUG, "att_getentbyatt fail. set=%d use=%d r=%d", - curAttributeSet, use_value, r); - if (r == -1) - zh->errCode = 114; - else - zh->errCode = 121; - return -1; + use_value = xpath_use; + attp.local_attributes = &id_xpath_attr; + attp.attset_ordinal = VAL_IDXPATH; + id_xpath_attr.next = 0; + id_xpath_attr.local = use_value; } - if (zebraExplain_curDatabase (zh->service->zei, basenames[base_no])) + else if (curAttributeSet == VAL_IDXPATH) + { + attp.local_attributes = &id_xpath_attr; + attp.attset_ordinal = VAL_IDXPATH; + id_xpath_attr.next = 0; + id_xpath_attr.local = use_value; + } + else + { + if ((r=att_getentbyatt (zh, &attp, curAttributeSet, use_value))) + { + logf (LOG_DEBUG, "att_getentbyatt fail. set=%d use=%d r=%d", + curAttributeSet, use_value, r); + if (r == -1) + { + char val_str[32]; + sprintf (val_str, "%d", use_value); + zh->errString = nmem_strdup (stream, val_str); + zh->errCode = 114; + } + else + zh->errCode = 121; + return -1; + } + } + if (zebraExplain_curDatabase (zh->reg->zei, basenames[base_no])) { zh->errCode = 109; /* Database unavailable */ zh->errString = basenames[base_no]; @@ -1662,7 +1847,7 @@ static int numeric_term (ZebraHandle zh, Z_AttributesPlusTerm *zapt, char ord_buf[32]; int i, ord_len; - ord = zebraExplain_lookupSU (zh->service->zei, attp.attset_ordinal, + ord = zebraExplain_lookupSU (zh->reg->zei, attp.attset_ordinal, local_attr->local); if (ord < 0) continue; @@ -1680,7 +1865,10 @@ static int numeric_term (ZebraHandle zh, Z_AttributesPlusTerm *zapt, } if (!prefix_len) { + char val_str[32]; + sprintf (val_str, "%d", use_value); zh->errCode = 114; + zh->errString = nmem_strdup (stream, val_str); return -1; } term_dict[prefix_len++] = ')'; @@ -1704,7 +1892,7 @@ static RSET rpn_search_APT_numeric (ZebraHandle zh, oid_value attributeSet, NMEM stream, int reg_type, int complete_flag, - const char *rank_type, + const char *rank_type, int xpath_use, int num_bases, char **basenames) { char term_dst[IT_MAX_WORD+1]; @@ -1721,26 +1909,27 @@ static RSET rpn_search_APT_numeric (ZebraHandle zh, grep_info.isam_p_indx = 0; r = numeric_term (zh, zapt, &termp, attributeSet, &grep_info, reg_type, complete_flag, num_bases, basenames, - term_dst); + term_dst, xpath_use, + stream); if (r < 1) break; logf (LOG_DEBUG, "term: %s", term_dst); rset[rset_no] = rset_trunc (zh, grep_info.isam_p_buf, grep_info.isam_p_indx, term_dst, - strlen(term_dst), rank_type); + strlen(term_dst), rank_type, + 0 /* preserve position */, + zapt->term->which); assert (rset[rset_no]); if (++rset_no >= (int) (sizeof(rset)/sizeof(*rset))) break; } -#ifdef TERM_COUNT - xfree(grep_info.term_no); -#endif - xfree (grep_info.isam_p_buf); + grep_info_delete (&grep_info); if (rset_no == 0) { rset_null_parms parms; - parms.rset_term = rset_term_create (term_dst, -1, rank_type); + parms.rset_term = rset_term_create (term_dst, -1, rank_type, + zapt->term->which); return rset_create (rset_kind_null, &parms); } result = rset[0]; @@ -1768,9 +1957,11 @@ static RSET rpn_search_APT_local (ZebraHandle zh, Z_AttributesPlusTerm *zapt, struct it_key key; rset_temp_parms parms; - parms.rset_term = rset_term_create (termz, -1, rank_type); + parms.rset_term = rset_term_create (termz, -1, rank_type, + zapt->term->which); + parms.cmp = key_compare_it; parms.key_size = sizeof (struct it_key); - parms.temp_path = res_get (zh->service->res, "setTmpDir"); + parms.temp_path = res_get (zh->res, "setTmpDir"); result = rset_create (rset_kind_temp, &parms); rsfd = rset_open (result, RSETF_WRITE); @@ -1799,6 +1990,7 @@ static RSET rpn_sort_spec (ZebraHandle zh, Z_AttributesPlusTerm *zapt, Z_AttributeElement *ae; int oid[OID_SIZE]; oident oe; + char termz[20]; attr_init (&sort_relation_type, zapt, 7); sort_relation_value = attr_find (&sort_relation_type, &attributeSet); @@ -1822,6 +2014,7 @@ static RSET rpn_sort_spec (ZebraHandle zh, Z_AttributesPlusTerm *zapt, zapt->term->u.general->len); if (i >= sort_sequence->num_specs) i = 0; + sprintf (termz, "%d", i); oe.proto = PROTO_Z3950; oe.oclass = CLASS_ATTSET; @@ -1869,19 +2062,265 @@ static RSET rpn_sort_spec (ZebraHandle zh, Z_AttributesPlusTerm *zapt, nmem_malloc (stream, sizeof(*sks->caseSensitivity)); *sks->caseSensitivity = 0; -#ifdef ASN_COMPILED sks->which = Z_SortKeySpec_null; sks->u.null = odr_nullval (); -#else - sks->missingValueAction = 0; -#endif - sort_sequence->specs[i] = sks; - parms.rset_term = rset_term_create ("", -1, rank_type); + parms.rset_term = rset_term_create (termz, -1, rank_type, + zapt->term->which); return rset_create (rset_kind_null, &parms); } +/* pop - moved to xpath.c */ +#if 0 + +struct xpath_predicate { + int which; + union { +#define XPATH_PREDICATE_RELATION 1 + struct { + char *name; + char *op; + char *value; + } relation; +#define XPATH_PREDICATE_BOOLEAN 2 + struct { + const char *op; + struct xpath_predicate *left; + struct xpath_predicate *right; + } boolean; + } u; +}; + +struct xpath_location_step { + char *part; + struct xpath_predicate *predicate; +}; + +#endif + +static int parse_xpath(ZebraHandle zh, Z_AttributesPlusTerm *zapt, + oid_value attributeSet, + struct xpath_location_step *xpath, int max, NMEM mem) +{ + oid_value curAttributeSet = attributeSet; + AttrType use; + const char *use_string = 0; + + attr_init (&use, zapt, 1); + attr_find_ex (&use, &curAttributeSet, &use_string); + + if (!use_string || *use_string != '/') + return -1; + + return zebra_parse_xpath_str(use_string, xpath, max, mem); +} + + + +static RSET xpath_trunc(ZebraHandle zh, NMEM stream, + int reg_type, const char *term, int use, + oid_value curAttributeSet) +{ + RSET rset; + struct grep_info grep_info; + char term_dict[2048]; + char ord_buf[32]; + int prefix_len = 0; + int ord = zebraExplain_lookupSU (zh->reg->zei, curAttributeSet, use); + int ord_len, i, r, max_pos; + int term_type = Z_Term_characterString; + const char *flags = "void"; + + if (grep_info_prepare (zh, 0 /* zapt */, &grep_info, '0', stream)) + { + rset_null_parms parms; + + parms.rset_term = rset_term_create (term, strlen(term), + flags, term_type); + parms.rset_term->nn = 0; + return rset_create (rset_kind_null, &parms); + } + + if (ord < 0) + { + rset_null_parms parms; + + parms.rset_term = rset_term_create (term, strlen(term), + flags, term_type); + parms.rset_term->nn = 0; + return rset_create (rset_kind_null, &parms); + } + if (prefix_len) + term_dict[prefix_len++] = '|'; + else + term_dict[prefix_len++] = '('; + + ord_len = key_SU_encode (ord, ord_buf); + for (i = 0; ireg->dict, term_dict, 0, + &grep_info, &max_pos, 0, grep_handle); + yaz_log (LOG_LOG, "%s %d positions", term, + grep_info.isam_p_indx); + rset = rset_trunc (zh, grep_info.isam_p_buf, + grep_info.isam_p_indx, term, strlen(term), + flags, 1, term_type); + grep_info_delete (&grep_info); + return rset; +} + +static RSET rpn_search_xpath (ZebraHandle zh, + oid_value attributeSet, + int num_bases, char **basenames, + NMEM stream, const char *rank_type, RSET rset, + int xpath_len, struct xpath_location_step *xpath) +{ + oid_value curAttributeSet = attributeSet; + int base_no; + int i; + + if (xpath_len < 0) + return rset; + + yaz_log (LOG_LOG, "len=%d", xpath_len); + for (i = 0; i a/.* + //a/b -> b/a/.* + /a -> a/ + /a/b -> b/a/ + + / -> none + + a[@attr=value]/b[@other=othervalue] + + /e/@a val range(e/,range(@a,freetext(w,1015,val),@a),e/) + /a/b val range(b/a/,freetext(w,1016,val),b/a/) + /a/b/@c val range(b/a/,range(@c,freetext(w,1016,val),@c),b/a/) + /a/b[@c=y] val range(b/a/,freetext(w,1016,val),b/a/,@c=y) + /a[@c=y]/b val range(a/,range(b/a/,freetext(w,1016,val),b/a/),a/,@c=y) + /a[@c=x]/b[@c=y] range(a/,range(b/a/,freetext(w,1016,val),b/a/,@c=y),a/,@c=x) + + */ + + dict_grep_cmap (zh->reg->dict, 0, 0); + + for (base_no = 0; base_no < num_bases; base_no++) + { + int level = xpath_len; + int first_path = 1; + + if (zebraExplain_curDatabase (zh->reg->zei, basenames[base_no])) + { + zh->errCode = 109; /* Database unavailable */ + zh->errString = basenames[base_no]; + return rset; + } + while (--level >= 0) + { + char xpath_rev[128]; + int i, len; + rset_between_parms parms; + RSET rset_start_tag = 0, rset_end_tag = 0, rset_attr = 0; + + *xpath_rev = 0; + len = 0; + for (i = level; i >= 1; --i) + { + const char *cp = xpath[i].part; + if (*cp) + { + for (;*cp; cp++) + if (*cp == '*') + { + memcpy (xpath_rev + len, "[^/]*", 5); + len += 5; + } + else if (*cp == ' ') + { + + xpath_rev[len++] = 1; + xpath_rev[len++] = ' '; + } + + else + xpath_rev[len++] = *cp; + xpath_rev[len++] = '/'; + } + else if (i == 1) /* // case */ + { + xpath_rev[len++] = '.'; + xpath_rev[len++] = '*'; + } + } + xpath_rev[len] = 0; + + if (xpath[level].predicate && + xpath[level].predicate->which == XPATH_PREDICATE_RELATION && + xpath[level].predicate->u.relation.name[0]) + { + char predicate_str[128]; + + strcpy (predicate_str, + xpath[level].predicate->u.relation.name+1); + if (xpath[level].predicate->u.relation.value) + { + strcat (predicate_str, "="); + strcat (predicate_str, + xpath[level].predicate->u.relation.value); + } + rset_attr = xpath_trunc ( + zh, stream, '0', predicate_str, 3, curAttributeSet); + } + else + { + if (!first_path) + continue; + } + yaz_log (LOG_LOG, "xpath_rev (%d) = %s", level, xpath_rev); + if (strlen(xpath_rev)) + { + rset_start_tag = xpath_trunc(zh, stream, + '0', xpath_rev, 1, curAttributeSet); + + rset_end_tag = xpath_trunc(zh, stream, + '0', xpath_rev, 2, curAttributeSet); + + parms.key_size = sizeof(struct it_key); + parms.cmp = key_compare_it; + parms.rset_l = rset_start_tag; + parms.rset_m = rset; + parms.rset_r = rset_end_tag; + parms.rset_attr = rset_attr; + parms.printer = key_print_it; + rset = rset_create (rset_kind_between, &parms); + } + first_path = 0; + } + } + + return rset; +} + + static RSET rpn_search_APT (ZebraHandle zh, Z_AttributesPlusTerm *zapt, oid_value attributeSet, NMEM stream, @@ -1894,8 +2333,12 @@ static RSET rpn_search_APT (ZebraHandle zh, Z_AttributesPlusTerm *zapt, int complete_flag; int sort_flag; char termz[IT_MAX_WORD+1]; + RSET rset = 0; + int xpath_len; + int xpath_use = 0; + struct xpath_location_step xpath[10]; - zebra_maps_attr (zh->service->zebra_maps, zapt, ®_id, &search_type, + zebra_maps_attr (zh->reg->zebra_maps, zapt, ®_id, &search_type, rank_type, &complete_flag, &sort_flag); logf (LOG_DEBUG, "reg_id=%c", reg_id); @@ -1903,48 +2346,61 @@ static RSET rpn_search_APT (ZebraHandle zh, Z_AttributesPlusTerm *zapt, logf (LOG_DEBUG, "search_type=%s", search_type); logf (LOG_DEBUG, "rank_type=%s", rank_type); - if (zapt->term->which != Z_Term_general) - { - zh->errCode = 124; - return NULL; - } - trans_term (zh, zapt, termz); + if (zapt_term_to_utf8(zh, zapt, termz)) + return 0; if (sort_flag) return rpn_sort_spec (zh, zapt, attributeSet, stream, sort_sequence, rank_type); + xpath_len = parse_xpath(zh, zapt, attributeSet, xpath, 10, stream); + if (xpath_len >= 0) + { + xpath_use = 1016; + if (xpath[xpath_len-1].part[0] == '@') + xpath_use = 1015; + } if (!strcmp (search_type, "phrase")) { - return rpn_search_APT_phrase (zh, zapt, termz, attributeSet, stream, + rset = rpn_search_APT_phrase (zh, zapt, termz, attributeSet, stream, reg_id, complete_flag, rank_type, + xpath_use, num_bases, basenames); } else if (!strcmp (search_type, "and-list")) { - return rpn_search_APT_and_list (zh, zapt, termz, attributeSet, stream, + rset = rpn_search_APT_and_list (zh, zapt, termz, attributeSet, stream, reg_id, complete_flag, rank_type, + xpath_use, num_bases, basenames); } else if (!strcmp (search_type, "or-list")) { - return rpn_search_APT_or_list (zh, zapt, termz, attributeSet, stream, + rset = rpn_search_APT_or_list (zh, zapt, termz, attributeSet, stream, reg_id, complete_flag, rank_type, + xpath_use, num_bases, basenames); } else if (!strcmp (search_type, "local")) { - return rpn_search_APT_local (zh, zapt, termz, attributeSet, stream, + rset = rpn_search_APT_local (zh, zapt, termz, attributeSet, stream, rank_type); } else if (!strcmp (search_type, "numeric")) { - return rpn_search_APT_numeric (zh, zapt, termz, attributeSet, stream, + rset = rpn_search_APT_numeric (zh, zapt, termz, attributeSet, stream, reg_id, complete_flag, rank_type, + xpath_use, num_bases, basenames); } - zh->errCode = 118; - return NULL; + else if (!strcmp (search_type, "always")) + { + rset = 0; + } + else + zh->errCode = 118; + return rpn_search_xpath (zh, attributeSet, num_bases, basenames, + stream, rank_type, rset, xpath_len, xpath); } static RSET rpn_search_structure (ZebraHandle zh, Z_RPNStructure *zs, @@ -1988,21 +2444,11 @@ static RSET rpn_search_structure (ZebraHandle zh, Z_RPNStructure *zs, r = rset_create (rset_kind_not, &bool_parms); break; case Z_Operator_prox: -#ifdef ASN_COMPILED if (zop->u.prox->which != Z_ProximityOperator_known) { zh->errCode = 132; return NULL; } -#else - if (zop->u.prox->which != Z_ProxCode_known) - { - zh->errCode = 132; - return NULL; - } -#endif - -#ifdef ASN_COMPILED if (*zop->u.prox->u.known != Z_ProxUnit_word) { char *val = (char *) nmem_malloc (stream, 16); @@ -2011,16 +2457,6 @@ static RSET rpn_search_structure (ZebraHandle zh, Z_RPNStructure *zs, sprintf (val, "%d", *zop->u.prox->u.known); return NULL; } -#else - if (*zop->u.prox->proximityUnitCode != Z_ProxUnit_word) - { - char *val = (char *) nmem_malloc (stream, 16); - zh->errCode = 132; - zh->errString = val; - sprintf (val, "%d", *zop->u.prox->proximityUnitCode); - return NULL; - } -#endif else { RSET rsets[2]; @@ -2064,6 +2500,8 @@ static RSET rpn_search_structure (ZebraHandle zh, Z_RPNStructure *zs, nmem_strdup (stream, zs->u.simple->u.resultSetId); return 0; } + else + rset_dup(r); } else { @@ -2166,12 +2604,33 @@ static int scan_handle (char *name, const char *info, int pos, void *client) static void scan_term_untrans (ZebraHandle zh, NMEM stream, int reg_type, char **dst, const char *src) { - char term_dst[1024]; + char term_src[IT_MAX_WORD]; + char term_dst[IT_MAX_WORD]; - term_untrans (zh, reg_type, term_dst, src); - - *dst = (char *) nmem_malloc (stream, strlen(term_dst)+1); - strcpy (*dst, term_dst); + term_untrans (zh, reg_type, term_src, src); + + if (zh->iconv_from_utf8 != 0) + { + int len; + char *inbuf = term_src; + size_t inleft = strlen(term_src); + char *outbuf = term_dst; + size_t outleft = sizeof(term_dst)-1; + size_t ret; + + ret = yaz_iconv (zh->iconv_from_utf8, &inbuf, &inleft, + &outbuf, &outleft); + if (ret == (size_t)(-1)) + len = 0; + else + len = outbuf - term_dst; + *dst = nmem_malloc (stream, len + 1); + if (len > 0) + memcpy (*dst, term_dst, len); + (*dst)[len] = '\0'; + } + else + *dst = nmem_strdup (stream, term_src); } static void count_set (RSET r, int *count) @@ -2203,7 +2662,7 @@ void rpn_scan (ZebraHandle zh, ODR stream, Z_AttributesPlusTerm *zapt, oid_value attributeset, int num_bases, char **basenames, int *position, int *num_entries, ZebraScanEntry **list, - int *is_partial) + int *is_partial, RSET limit_set, int return_zero) { int i; int pos = *position; @@ -2224,18 +2683,45 @@ void rpn_scan (ZebraHandle zh, ODR stream, Z_AttributesPlusTerm *zapt, char rank_type[128]; int complete_flag; int sort_flag; + *list = 0; if (attributeset == VAL_NONE) attributeset = VAL_BIB1; + if (!limit_set) + { + AttrType termset; + int termset_value_numeric; + const char *termset_value_string; + attr_init (&termset, zapt, 8); + termset_value_numeric = + attr_find_ex (&termset, NULL, &termset_value_string); + if (termset_value_numeric != -1) + { + char resname[32]; + const char *termset_name = 0; + + if (termset_value_numeric != -2) + { + + sprintf (resname, "%d", termset_value_numeric); + termset_name = resname; + } + else + termset_name = termset_value_string; + + limit_set = resultSetRef (zh, termset_name); + } + } + yaz_log (LOG_DEBUG, "position = %d, num = %d set=%d", pos, num, attributeset); attr_init (&use, zapt, 1); use_value = attr_find (&use, &attributeset); - if (zebra_maps_attr (zh->service->zebra_maps, zapt, ®_id, &search_type, + if (zebra_maps_attr (zh->reg->zebra_maps, zapt, ®_id, &search_type, rank_type, &complete_flag, &sort_flag)) { *num_entries = 0; @@ -2257,13 +2743,18 @@ void rpn_scan (ZebraHandle zh, ODR stream, Z_AttributesPlusTerm *zapt, logf (LOG_DEBUG, "att_getentbyatt fail. set=%d use=%d", attributeset, use_value); if (r == -1) - zh->errCode = 114; + { + char val_str[32]; + sprintf (val_str, "%d", use_value); + zh->errCode = 114; + zh->errString = odr_strdup (stream, val_str); + } else zh->errCode = 121; *num_entries = 0; return; } - if (zebraExplain_curDatabase (zh->service->zei, basenames[base_no])) + if (zebraExplain_curDatabase (zh->reg->zei, basenames[base_no])) { zh->errString = basenames[base_no]; zh->errCode = 109; /* Database unavailable */ @@ -2275,7 +2766,7 @@ void rpn_scan (ZebraHandle zh, ODR stream, Z_AttributesPlusTerm *zapt, { int ord; - ord = zebraExplain_lookupSU (zh->service->zei, attp.attset_ordinal, + ord = zebraExplain_lookupSU (zh->reg->zei, attp.attset_ordinal, local_attr->local); if (ord > 0) ords[ord_no++] = ord; @@ -2299,7 +2790,7 @@ void rpn_scan (ZebraHandle zh, ODR stream, Z_AttributesPlusTerm *zapt, struct scan_info *scan_info = scan_info_array + i; struct rpn_char_map_info rcmi; - rpn_char_map_prepare (zh, reg_id, &rcmi); + rpn_char_map_prepare (zh->reg, reg_id, &rcmi); scan_info->before = before; scan_info->after = after; @@ -2315,9 +2806,10 @@ void rpn_scan (ZebraHandle zh, ODR stream, Z_AttributesPlusTerm *zapt, termz[prefix_len] = 0; strcpy (scan_info->prefix, termz); - trans_scan_term (zh, zapt, termz+prefix_len, reg_id); + if (trans_scan_term (zh, zapt, termz+prefix_len, reg_id)) + return ; - dict_scan (zh->service->dict, termz, &before_tmp, &after_tmp, + dict_scan (zh->reg->dict, termz, &before_tmp, &after_tmp, scan_info, scan_handle); } glist = (ZebraScanEntry *) @@ -2351,7 +2843,7 @@ void rpn_scan (ZebraHandle zh, ODR stream, Z_AttributesPlusTerm *zapt, &glist[i+before].term, mterm); rset = rset_trunc (zh, &scan_info_array[j0].list[ptr[j0]].isam_p, 1, glist[i+before].term, strlen(glist[i+before].term), - NULL); + NULL, 0, zapt->term->which); ptr[j0]++; for (j = j0+1; jterm->which); bool_parms.key_size = sizeof(struct it_key); bool_parms.cmp = key_compare_it; @@ -2378,6 +2871,17 @@ void rpn_scan (ZebraHandle zh, ODR stream, Z_AttributesPlusTerm *zapt, ptr[j]++; } } + if (limit_set) + { + rset_bool_parms bool_parms; + + bool_parms.key_size = sizeof(struct it_key); + bool_parms.cmp = key_compare_it; + bool_parms.rset_l = rset; + bool_parms.rset_r = rset_dup(limit_set); + + rset = rset_create (rset_kind_and, &bool_parms); + } count_set (rset, &glist[i+before].occurrences); rset_delete (rset); } @@ -2417,7 +2921,7 @@ void rpn_scan (ZebraHandle zh, ODR stream, Z_AttributesPlusTerm *zapt, rset = rset_trunc (zh, &scan_info_array[j0].list[before-1-ptr[j0]].isam_p, 1, glist[before-1-i].term, strlen(glist[before-1-i].term), - NULL); + NULL, 0, zapt->term->which); ptr[j0]++; @@ -2433,7 +2937,8 @@ void rpn_scan (ZebraHandle zh, ODR stream, Z_AttributesPlusTerm *zapt, rset2 = rset_trunc (zh, &scan_info_array[j].list[before-1-ptr[j]].isam_p, 1, glist[before-1-i].term, - strlen(glist[before-1-i].term), NULL); + strlen(glist[before-1-i].term), NULL, 0, + zapt->term->which); bool_parms.key_size = sizeof(struct it_key); bool_parms.cmp = key_compare_it; @@ -2445,6 +2950,17 @@ void rpn_scan (ZebraHandle zh, ODR stream, Z_AttributesPlusTerm *zapt, ptr[j]++; } } + if (limit_set) + { + rset_bool_parms bool_parms; + + bool_parms.key_size = sizeof(struct it_key); + bool_parms.cmp = key_compare_it; + bool_parms.rset_l = rset; + bool_parms.rset_r = rset_dup(limit_set); + + rset = rset_create (rset_kind_and, &bool_parms); + } count_set (rset, &glist[before-1-i].occurrences); rset_delete (rset); }