YAZ 5.35.1
rpn2solr.c
Go to the documentation of this file.
1/* This file is part of the YAZ toolkit.
2 * Copyright (C) Index Data
3 * See the file LICENSE for details.
4 */
9#if HAVE_CONFIG_H
10#include <config.h>
11#endif
12
13#include <assert.h>
14#include <stdlib.h>
15#include <string.h>
16#include <yaz/rpn2solr.h>
17#include <yaz/xmalloc.h>
18#include <yaz/diagbib1.h>
19#include <yaz/z-core.h>
20#include <yaz/wrbuf.h>
21
22static const char *lookup_index_from_string_attr(Z_AttributeList *attributes)
23{
24 int j;
25 int server_choice = 1;
26 for (j = 0; j < attributes->num_attributes; j++)
27 {
28 Z_AttributeElement *ae = attributes->attributes[j];
29 if (*ae->attributeType == 1) /* use attribute */
30 {
32 {
34 int i;
35 for (i = 0; i < ca->num_list; i++)
36 {
37 Z_StringOrNumeric *son = ca->list[i];
39 return son->u.string;
40 }
41 }
42 server_choice = 0; /* not serverChoice because we have use attr */
43 }
44 }
45 if (server_choice)
46 return "cql.serverChoice";
47 return 0;
48}
49
50static const char *lookup_relation_index_from_attr(Z_AttributeList *attributes)
51{
52 int j;
53 for (j = 0; j < attributes->num_attributes; j++)
54 {
55 Z_AttributeElement *ae = attributes->attributes[j];
56 if (*ae->attributeType == 2) /* relation attribute */
57 {
59 {
60 /* Only support for numeric relation */
61 Odr_int *relation = ae->value.numeric;
62 /* map this numeric to representation in SOLR */
63 switch (*relation)
64 {
65 /* Unsure on whether this is the relation attribute constants? */
67 return "<";
69 return "le";
71 return ":";
73 return "ge";
75 return ">";
77 return 0;
78 case 100:
79 /* phonetic is not implemented */
80 return 0;
81 case 101:
82 /* stem is not not implemented */
83 return 0;
84 case 102:
85 /* relevance is supported in SOLR, but not implemented yet */
86 return 0;
87 default:
88 /* Invalid relation */
89 return 0;
90 }
91 }
92 else {
93 /* Can we have a complex relation value?
94 Should we implement something?
95 */
96 }
97 }
98 }
99 return ":";
100}
101
103 Z_AttributesPlusTerm **p_apt1,
104 Z_AttributesPlusTerm **p_apt2)
105{
106 Z_Operator *op = q->roperator;
107 if (op->which == Z_Operator_and &&
110 q->s1->u.simple->which == Z_Operand_APT &&
111 q->s2->u.simple->which == Z_Operand_APT)
112 {
115 const char *i1 = solr_lookup_reverse(ct, "index.", apt1->attributes);
116 const char *i2 = solr_lookup_reverse(ct, "index.", apt2->attributes);
117 const char *rel1 = solr_lookup_reverse(ct, "relation.",
118 apt1->attributes);
119 const char *rel2 = solr_lookup_reverse(ct, "relation.",
120 apt2->attributes);
121 if (!rel1)
123 if (!rel2)
125 if (!i1)
127 if (!i2)
129 if (i1 && i2 && !strcmp(i1, i2) && rel1 && rel2)
130 {
131 if ((rel1[0] == '>' || rel1[0] == 'g') &&
132 (rel2[0] == '<' || rel2[0] == 'l'))
133 {
134 *p_apt1 = apt1;
135 *p_apt2 = apt2;
136 return 1;
137 }
138 if ((rel2[0] == '>' || rel2[0] == 'g') &&
139 (rel1[0] == '<' || rel1[0] == 'l'))
140 {
141 *p_apt1 = apt2;
142 *p_apt2 = apt1;
143 return 1;
144 }
145 }
146 }
147 return 0;
148}
149
151 Z_AttributeList *attributes, WRBUF w)
152{
153 const char *index = solr_lookup_reverse(ct, "index.", attributes);
154 const char *structure = solr_lookup_reverse(ct, "structure.", attributes);
155
156 /* if no real match, try string attribute */
157 if (!index)
158 index = lookup_index_from_string_attr(attributes);
159 if (!index)
161 /* for serverChoice we omit index+relation+structure */
162 if (strcmp(index, "cql.serverChoice"))
163 {
164 wrbuf_puts(w, index);
165 wrbuf_puts(w, ":");
166 if (structure)
167 {
168 if (strcmp(structure, "*"))
169 {
170 wrbuf_puts(w, "/");
171 wrbuf_puts(w, structure);
172 wrbuf_puts(w, " ");
173 }
174 }
175 }
176 return 0;
177}
178
180{
181 int j;
182 Z_AttributeList *attributes = apt->attributes;
183 for (j = 0; j < attributes->num_attributes; j++)
184 {
185 Z_AttributeElement *ae = attributes->attributes[j];
186 if (*ae->attributeType == 5) /* truncation attribute */
187 {
189 {
190 return *(ae->value.numeric);
191 }
192 else if (ae->which == Z_AttributeValue_complex) {
193 ;
194 /* Complex: Shouldn't happen */
195 }
196 }
197 }
198 /* No truncation given */
199 return 0;
200}
201
202#define SOLR_SPECIAL "+-&|!(){}[]^\"~*?:\\"
203
204static int emit_term(solr_transform_t ct, WRBUF w, Z_Term *term, Odr_int trunc)
205{
206 size_t lterm = 0;
207 const char *sterm = 0;
208 switch (term->which)
209 {
210 case Z_Term_general:
211 lterm = term->u.general->len;
212 sterm = (const char *) term->u.general->buf;
213 break;
214 case Z_Term_numeric:
216 break;
218 sterm = term->u.characterString;
219 lterm = strlen(sterm);
220 break;
221 default:
223 }
224
225 if (sterm)
226 {
227 size_t i;
228 int must_quote = 0;
229
230 if (lterm == 0)
231 must_quote = 1;
232 else
233 {
234 for (i = 0 ; i < lterm; i++)
235 if (sterm[i] == ' ')
236 must_quote = 1;
237 }
238 if (must_quote)
239 wrbuf_puts(w, "\"");
240 if (trunc == 2 || trunc == 3)
241 wrbuf_puts(w, "*");
242 for (i = 0 ; i < lterm; i++)
243 {
244 if (sterm[i] == '\\' && i < lterm - 1)
245 {
246 i++;
247 if (strchr(SOLR_SPECIAL, sterm[i]))
248 wrbuf_putc(w, '\\');
249 wrbuf_putc(w, sterm[i]);
250 }
251 else if (sterm[i] == '?' && trunc == 104)
252 {
253 wrbuf_putc(w, '*');
254 }
255 else if (sterm[i] == '#' && trunc == 104)
256 {
257 wrbuf_putc(w, '?');
258 }
259 else if (strchr(SOLR_SPECIAL, sterm[i]))
260 {
261 wrbuf_putc(w, '\\');
262 wrbuf_putc(w, sterm[i]);
263 }
264 else
265 wrbuf_putc(w, sterm[i]);
266 }
267 if (trunc == 1 || trunc == 3)
268 wrbuf_puts(w, "*");
269 if (must_quote)
270 wrbuf_puts(w, "\"");
271 }
272 return 0;
273}
274
276 void (*pr)(const char *buf, void *client_data),
277 void *client_data,
280 {
281 int ret = 0;
282 Z_Term *term = apt->term;
283 Odr_int trunc = get_truncation(apt);
284 const char *relation2 = 0;
285 const char *relation1 = solr_lookup_reverse(ct, "relation.",
286 apt->attributes);
287 /* Attempt to fix bug #2978: Look for a relation attribute */
288 if (!relation1)
290 if (!relation1)
291 {
293 }
294 if (apt2)
295 {
296 relation2 = solr_lookup_reverse(ct, "relation.",
297 apt2->attributes);
298 if (!relation2)
300 }
301 wrbuf_rewind(w);
302 ret = rpn2solr_attr(ct, apt->attributes, w);
303 if (ret)
304 return ret;
305 if ((trunc >= 0 && trunc <= 3) || trunc == 100 || trunc == 104)
306 ;
307 else
308 {
310 }
311
312 if (!relation1)
313 ret = emit_term(ct, w, term, trunc);
314 else if (relation1[0] == '<' || relation1[0] == 'l')
315 {
316 wrbuf_puts(w, "[* TO ");
317 ret = emit_term(ct, w, term, trunc);
318 if (!strcmp(relation1, "le") || !strcmp(relation1, "<="))
319 wrbuf_puts(w, "]");
320 else
321 wrbuf_puts(w, "}");
322 }
323 else if (relation1[0] == '>' || relation1[0] == 'g')
324 {
325 if (!strcmp(relation1, ">=") || !strcmp(relation1, "ge"))
326 wrbuf_puts(w, "[");
327 else
328 wrbuf_puts(w, "{");
329 ret = emit_term(ct, w, term, trunc);
330 wrbuf_puts(w, " TO ");
331 if (apt2)
332 {
333 emit_term(ct, w, apt2->term, 0);
334 if (!relation2 || !strcmp(relation2, "<=") ||
335 !strcmp(relation2, "le"))
336 wrbuf_puts(w, "]");
337 else
338 wrbuf_puts(w, "}");
339 }
340 else
341 wrbuf_puts(w, "*]");
342 }
343 else
344 ret = emit_term(ct, w, term, trunc);
345 if (ret == 0)
346 pr(wrbuf_cstr(w), client_data);
347 return ret;
348 }
349
350
352 void (*pr)(const char *buf, void *client_data),
353 void *client_data,
354 Z_RPNStructure *q, int nested,
355 WRBUF w)
356{
358 {
359 if (q->u.simple->which != Z_Operand_APT)
361 else
362 return rpn2solr_simple(ct, pr, client_data,
363 q->u.simple->u.attributesPlusTerm, w, 0);
364 }
365 else
366 {
367 Z_Operator *op = q->u.complex->roperator;
368 Z_AttributesPlusTerm *apt1, *apt2;
369 int r;
370
371 if (check_range(ct, q->u.complex, &apt1, &apt2))
372 return rpn2solr_simple(ct, pr, client_data, apt1, w, apt2);
373 if (nested)
374 pr("(", client_data);
375
376 r = rpn2solr_structure(ct, pr, client_data, q->u.complex->s1, 1, w);
377 if (r)
378 return r;
379 switch (op->which)
380 {
381 case Z_Operator_and:
382 pr(" AND ", client_data);
383 break;
384 case Z_Operator_or:
385 pr(" OR ", client_data);
386 break;
388 pr(" AND NOT ", client_data);
389 break;
390 case Z_Operator_prox:
392 }
393 r = rpn2solr_structure(ct, pr, client_data, q->u.complex->s2, 1, w);
394 if (nested)
395 pr(")", client_data);
396 return r;
397 }
398}
399
401 WRBUF addinfo,
402 void (*pr)(const char *buf, void *client_data),
403 void *client_data,
404 Z_RPNQuery *q)
405{
406 int r = rpn2solr_structure(ct, pr, client_data, q->RPNStructure,
407 /* nested*/ 0, addinfo);
408 if (!r)
409 wrbuf_rewind(addinfo);
410 return r;
411}
412
414 void (*pr)(const char *buf, void *client_data),
415 void *client_data,
416 Z_RPNQuery *q)
417{
418 WRBUF w = wrbuf_alloc();
419 int r = solr_transform_rpn2solr_stream_r(ct, w, pr, client_data, q);
420 if (r)
422 wrbuf_destroy(w);
423 return r;
424}
425
432
433/*
434 * Local variables:
435 * c-basic-offset: 4
436 * c-file-style: "Stroustrup"
437 * indent-tabs-mode: nil
438 * End:
439 * vim: shiftwidth=4 tabstop=8 expandtab
440 */
441
Diagnostics: Generated by csvtodiag.tcl from ./bib1.csv.
#define YAZ_BIB1_UNSUPP_TRUNCATION_ATTRIBUTE
Definition diagbib1.h:64
#define YAZ_BIB1_UNSUPP_USE_ATTRIBUTE
Definition diagbib1.h:58
#define YAZ_BIB1_UNSUPP_RELATION_ATTRIBUTE
Definition diagbib1.h:61
#define YAZ_BIB1_RESULT_SET_UNSUPP_AS_A_SEARCH_TERM
Definition diagbib1.h:28
#define YAZ_BIB1_TERM_TYPE_UNSUPP
Definition diagbib1.h:104
#define YAZ_BIB1_UNSUPP_SEARCH
Definition diagbib1.h:13
#define ODR_INT_PRINTF
Definition odr.h:49
nmem_int_t Odr_int
Definition odr.h:47
static const char * lookup_relation_index_from_attr(Z_AttributeList *attributes)
Definition rpn2solr.c:50
static int check_range(solr_transform_t ct, Z_Complex *q, Z_AttributesPlusTerm **p_apt1, Z_AttributesPlusTerm **p_apt2)
Definition rpn2solr.c:102
int solr_transform_rpn2solr_wrbuf(solr_transform_t ct, WRBUF w, Z_RPNQuery *q)
transforms RPN query to SOLR WRBUF
Definition rpn2solr.c:426
static int rpn2solr_simple(solr_transform_t ct, void(*pr)(const char *buf, void *client_data), void *client_data, Z_AttributesPlusTerm *apt, WRBUF w, Z_AttributesPlusTerm *apt2)
Definition rpn2solr.c:275
#define SOLR_SPECIAL
Definition rpn2solr.c:202
static const char * lookup_index_from_string_attr(Z_AttributeList *attributes)
Definition rpn2solr.c:22
static int rpn2solr_structure(solr_transform_t ct, void(*pr)(const char *buf, void *client_data), void *client_data, Z_RPNStructure *q, int nested, WRBUF w)
Definition rpn2solr.c:351
static int emit_term(solr_transform_t ct, WRBUF w, Z_Term *term, Odr_int trunc)
Definition rpn2solr.c:204
int solr_transform_rpn2solr_stream_r(solr_transform_t ct, WRBUF addinfo, void(*pr)(const char *buf, void *client_data), void *client_data, Z_RPNQuery *q)
transforms RPN query to SOLR output stream (re-entrant)
Definition rpn2solr.c:400
static Odr_int get_truncation(Z_AttributesPlusTerm *apt)
Definition rpn2solr.c:179
static int rpn2solr_attr(solr_transform_t ct, Z_AttributeList *attributes, WRBUF w)
Definition rpn2solr.c:150
int solr_transform_rpn2solr_stream(solr_transform_t ct, void(*pr)(const char *buf, void *client_data), void *client_data, Z_RPNQuery *q)
transforms RPN query to SOLR output stream (NOT re-entrant)
Definition rpn2solr.c:413
Header for RPN to SOLR tranform.
const char * solr_lookup_reverse(solr_transform_t ct, const char *category, Z_AttributeList *attributes)
find a pattern that has a subset of attributes
void solr_transform_set_error(solr_transform_t ct, int error, const char *addinfo)
sets error and addinfo for transform
union Z_AttributeElement::@50 value
Odr_int * attributeType
Definition z-core.h:581
Z_ComplexAttribute * complex
Definition z-core.h:585
Odr_int * numeric
Definition z-core.h:584
int num_attributes
Definition z-core.h:532
Z_AttributeElement ** attributes
Definition z-core.h:533
Z_AttributeList * attributes
Definition z-core.h:522
Z_StringOrNumeric ** list
Definition z-core.h:574
Z_RPNStructure * s2
Definition z-core.h:495
Z_Operator * roperator
Definition z-core.h:496
Z_RPNStructure * s1
Definition z-core.h:494
union Z_Operand::@47 u
int which
Definition z-core.h:510
Z_AttributesPlusTerm * attributesPlusTerm
Definition z-core.h:512
int which
Definition z-core.h:559
Z_RPNStructure * RPNStructure
Definition z-core.h:490
Z_Complex * complex
Definition z-core.h:503
union Z_RPNStructure::@46 u
Z_Operand * simple
Definition z-core.h:502
union Z_StringOrNumeric::@72 u
Z_InternationalString * string
Definition z-core.h:1321
Odr_oct * general
Definition z-core.h:539
union Z_Term::@48 u
Z_InternationalString * characterString
Definition z-core.h:541
int which
Definition z-core.h:537
Odr_int * numeric
Definition z-core.h:540
int len
Definition odr.h:102
char * buf
Definition odr.h:101
string buffer
Definition wrbuf.h:43
void wrbuf_destroy(WRBUF b)
destroy WRBUF and its buffer
Definition wrbuf.c:38
const char * wrbuf_cstr(WRBUF b)
returns WRBUF content as C-string
Definition wrbuf.c:299
void wrbuf_rewind(WRBUF b)
empty WRBUF content (length of buffer set to 0)
Definition wrbuf.c:47
WRBUF wrbuf_alloc(void)
construct WRBUF
Definition wrbuf.c:25
void wrbuf_printf(WRBUF b, const char *fmt,...)
writes printf result to WRBUF
Definition wrbuf.c:189
void wrbuf_vp_puts(const char *buf, void *client_data)
appends C-string to WRBUF - void pointer variant
Definition wrbuf.c:94
void wrbuf_puts(WRBUF b, const char *buf)
appends C-string to WRBUF
Definition wrbuf.c:89
Header for WRBUF (growing buffer)
#define wrbuf_putc(b, c)
Definition wrbuf.h:287
#define wrbuf_len(b)
Definition wrbuf.h:269
Header for memory handling functions.
ASN.1 Module Z39-50-APDU-1995.
#define Z_AttributeValue_numeric
Definition z-core.h:586
#define Z_Operator_and_not
Definition z-core.h:567
#define Z_Operator_or
Definition z-core.h:566
#define Z_Term_characterString
Definition z-core.h:549
#define Z_ProximityOperator_Prox_lessThanOrEqual
Definition z-core.h:596
#define Z_Operand_APT
Definition z-core.h:515
#define Z_AttributeValue_complex
Definition z-core.h:587
#define Z_Term_general
Definition z-core.h:547
#define Z_StringOrNumeric_string
Definition z-core.h:1323
#define Z_Operator_prox
Definition z-core.h:568
#define Z_Operator_and
Definition z-core.h:565
#define Z_ProximityOperator_Prox_lessThan
Definition z-core.h:595
#define Z_Term_numeric
Definition z-core.h:548
#define Z_RPNStructure_simple
Definition z-core.h:504
#define Z_ProximityOperator_Prox_equal
Definition z-core.h:597
#define Z_ProximityOperator_Prox_greaterThan
Definition z-core.h:599
#define Z_ProximityOperator_Prox_greaterThanOrEqual
Definition z-core.h:598
#define Z_ProximityOperator_Prox_notEqual
Definition z-core.h:600