Fix sample PQF
[yaz-moved-to-github.git] / zutil / logrpn.c
1 /*
2  * Copyright (C) 1995-2003, Index Data
3  * All rights reserved.
4  *
5  * $Id: logrpn.c,v 1.11 2003-02-27 19:56:00 adam Exp $
6  */
7 #include <stdio.h>
8
9 #include <yaz/log.h>
10 #include <yaz/logrpn.h>
11
12 static const char *relToStr(int v)
13 {
14     const char *str = 0;
15     switch (v)
16     {
17     case 1: str = "Less than"; break;
18     case 2: str = "Less than or equal"; break;
19     case 3: str = "Equal"; break;
20     case 4: str = "Greater or equal"; break;
21     case 5: str = "Greater than"; break;
22     case 6: str = "Not equal"; break;
23     case 100: str = "Phonetic"; break;
24     case 101: str = "Stem"; break;
25     case 102: str = "Relevance"; break;
26     case 103: str = "AlwaysMatches"; break;
27     }
28     return str;
29 }
30 static void attrStr (int type, int value, enum oid_value ast, char *str)
31 {
32     const char *rstr;
33     *str = '\0';
34     switch (ast)
35     {
36     case VAL_BIB1:
37     case VAL_EXP1:
38     case VAL_GILS:
39         switch (type)
40         {
41         case 1:
42             sprintf (str, "use");
43             break;
44         case 2:
45             rstr = relToStr(value);
46             if (rstr)
47                 sprintf (str, "relation=%s", rstr);
48             else
49                 sprintf (str, "relation=%d", value);
50             break;
51         case 3:
52             switch (value)
53             {
54             case 1:
55                 sprintf (str, "position=First in field");
56                 break;
57             case 2:
58                 sprintf (str, "position=First in any subfield");
59                 break;
60             case 3:
61                 sprintf (str, "position=Any position in field");
62                 break;
63             default:
64                 sprintf (str, "position");
65             }
66             break;
67         case 4:
68             switch (value)
69             {
70             case 1:
71                 sprintf (str, "structure=Phrase");
72                 break;
73             case 2:
74                 sprintf (str, "structure=Word");
75                 break;
76             case 3:
77                 sprintf (str, "structure=Key");
78                 break;
79             case 4:
80                 sprintf (str, "structure=Year");
81                 break;
82             case 5:
83                 sprintf (str, "structure=Date");
84                 break;
85             case 6:
86                 sprintf (str, "structure=Word list");
87                 break;
88             case 100:
89                 sprintf (str, "structure=Date (un)");
90                 break;
91             case 101:
92                 sprintf (str, "structure=Name (norm)");
93                 break;
94             case 102:
95                 sprintf (str, "structure=Name (un)");
96                 break;
97             case 103:
98                 sprintf (str, "structure=Structure");
99                 break;
100             case 104:
101                 sprintf (str, "structure=urx");
102                 break;
103             case 105:
104                 sprintf (str, "structure=free-form-text");
105                 break;
106             case 106:
107                 sprintf (str, "structure=document-text");
108                 break;
109             case 107:
110                 sprintf (str, "structure=local-number");
111                 break;
112             case 108:
113                 sprintf (str, "structure=string");
114                 break;
115             case 109:
116                 sprintf (str, "structure=numeric string");
117                 break;
118             default:
119                 sprintf (str, "structure");
120             }
121             break;
122         case 5:
123             switch (value)
124             {
125             case 1:
126                 sprintf (str, "truncation=Right");
127                 break;
128             case 2:
129                 sprintf (str, "truncation=Left");
130                 break;
131             case 3:
132                 sprintf (str, "truncation=Left&right");
133                 break;
134             case 100:
135                 sprintf (str, "truncation=Do not truncate");
136                 break;
137             case 101:
138                 sprintf (str, "truncation=Process #");
139                 break;
140             case 102:
141                 sprintf (str, "truncation=re-1");
142                 break;
143             case 103:
144                 sprintf (str, "truncation=re-2");
145                 break;
146             case 104:
147                 sprintf (str, "truncation=CCL");
148                 break;
149             default:
150                 sprintf (str, "truncation");
151             }
152             break;
153         case 6:
154             switch (value)
155             {
156             case 1:
157                 sprintf (str, "completeness=Incomplete subfield");
158                 break;
159             case 2:
160                 sprintf (str, "completeness=Complete subfield");
161                 break;
162             case 3:
163                 sprintf (str, "completeness=Complete field");
164                 break;
165             default:
166                 sprintf (str, "completeness");
167             }
168             break;
169         }
170         break;
171     default:
172         break;
173     }
174     if (*str)
175         sprintf (str + strlen(str), " (%d=%d)", type, value);
176     else
177         sprintf (str, "%d=%d", type, value);
178 }
179
180 /*
181  * zlog_attributes: print attributes of term
182  */
183 static void zlog_attributes (Z_AttributesPlusTerm *t, int level,
184                              enum oid_value ast)
185 {
186     int of, i;
187     char str[80];
188     int num_attributes = t->attributes->num_attributes;
189     
190     for (of = 0; of < num_attributes; of++)
191     {
192         const char *attset_name = "";
193         Z_AttributeElement *element;
194         element = t->attributes->attributes[of];
195         if (element->attributeSet)
196         {
197             oident *attrset;
198             attrset = oid_getentbyoid (element->attributeSet);
199             attset_name = attrset->desc;
200         }
201         switch (element->which) 
202         {
203         case Z_AttributeValue_numeric:
204             attrStr (*element->attributeType,
205                      *element->value.numeric, ast, str);
206             yaz_log (LOG_LOG, "%*.0s%s %s", level, "", attset_name, str);
207             break;
208         case Z_AttributeValue_complex:
209             yaz_log (LOG_LOG, "%*.0s%s attributeType=%d complex",
210                   level, "", attset_name, *element->attributeType);
211             for (i = 0; i<element->value.complex->num_list; i++)
212             {
213                 if (element->value.complex->list[i]->which ==
214                     Z_StringOrNumeric_string)
215                     yaz_log (LOG_LOG, "%*.0s  string: '%s'", level, "",
216                              element->value.complex->list[i]->u.string);
217                 else if (element->value.complex->list[i]->which ==
218                          Z_StringOrNumeric_numeric)
219                     yaz_log (LOG_LOG, "%*.0s  numeric: '%d'", level, "",
220                              *element->value.complex->list[i]->u.numeric);
221             }
222             break;
223         default:
224             yaz_log (LOG_LOG, "%.*s%s attribute unknown",
225                      level, "", attset_name);
226         }
227     }
228 }
229
230 static void zlog_structure (Z_RPNStructure *zs, int level, enum oid_value ast)
231 {
232     if (zs->which == Z_RPNStructure_complex)
233     {
234         Z_Operator *op = zs->u.complex->roperator;
235         const char *rstr = 0;
236         const char *unit = "private";
237         switch (op->which)
238         {
239         case Z_Operator_and:
240             yaz_log (LOG_LOG, "%*.0s and", level, "");
241             break;
242         case Z_Operator_or:
243             yaz_log (LOG_LOG, "%*.0s or", level, "");
244             break;
245         case Z_Operator_and_not:
246             yaz_log (LOG_LOG, "%*.0s and-not", level, "");
247             break;
248         case Z_Operator_prox:
249             if (op->u.prox->which == Z_ProximityOperator_known)
250             {
251                 switch(*op->u.prox->u.known)
252                 {
253                 case Z_ProxUnit_character: unit = "character"; break;
254                 case Z_ProxUnit_word: unit = "word"; break;
255                 case Z_ProxUnit_sentence: unit = "sentence"; break;
256                 case Z_ProxUnit_paragraph: unit = "paragraph"; break;
257                 case Z_ProxUnit_section: unit = "section"; break;
258                 case Z_ProxUnit_chapter: unit = "chapter"; break;
259                 case Z_ProxUnit_document: unit = "document"; break;
260                 case Z_ProxUnit_element: unit = "element"; break;
261                 case Z_ProxUnit_subelement: unit = "subelement"; break;
262                 case Z_ProxUnit_elementType: unit = "elementType"; break;
263                 case Z_ProxUnit_byte: unit = "byte"; break;
264                 default: unit = "unknown"; break;
265                 }
266             }
267             rstr = relToStr(*op->u.prox->relationType);
268             yaz_log (LOG_LOG, "%*.0s prox excl=%s dist=%d order=%s "
269                      "rel=%s unit=%s",
270                      level, "", op->u.prox->exclusion ?
271                      (*op->u.prox->exclusion ? "T" : "F") : "N", 
272                      *op->u.prox->distance,
273                      *op->u.prox->ordered ? "T" : "F",
274                      rstr ? rstr : "unknown",
275                      unit);
276             break;
277         default:
278             yaz_log (LOG_LOG, "%*.0s unknown complex", level, "");
279             return;
280         }
281         zlog_structure (zs->u.complex->s1, level+2, ast);
282         zlog_structure (zs->u.complex->s2, level+2, ast);
283     }
284     else if (zs->which == Z_RPNStructure_simple)
285     {
286         if (zs->u.simple->which == Z_Operand_APT)
287         {
288             Z_AttributesPlusTerm *zapt = zs->u.simple->u.attributesPlusTerm;
289
290             switch (zapt->term->which)
291             {
292             case Z_Term_general:
293                 yaz_log (LOG_LOG, "%*.0s term '%.*s' (general)", level, "",
294                          zapt->term->u.general->len,
295                          zapt->term->u.general->buf);
296                 break;
297             case Z_Term_characterString:
298                 yaz_log (LOG_LOG, "%*.0s term '%s' (string)", level, "",
299                          zapt->term->u.characterString);
300                 break;
301             case Z_Term_numeric:
302                 yaz_log (LOG_LOG, "%*.0s term '%d' (numeric)", level, "",
303                          *zapt->term->u.numeric);
304                 break;
305             case Z_Term_null:
306                 yaz_log (LOG_LOG, "%*.0s term (null)", level, "");
307                 break;
308             default:
309                 yaz_log (LOG_LOG, "%*.0s term (not general)", level, "");
310             }
311             zlog_attributes (zapt, level+2, ast);
312         }
313         else if (zs->u.simple->which == Z_Operand_resultSetId)
314         {
315             yaz_log (LOG_LOG, "%*.0s set '%s'", level, "",
316                      zs->u.simple->u.resultSetId);
317         }
318         else
319             yaz_log (LOG_LOG, "%*.0s unknown simple structure", level, "");
320     }
321     else
322         yaz_log (LOG_LOG, "%*.0s unknown structure", level, "");
323 }
324
325 void log_rpn_query (Z_RPNQuery *rpn)
326 {
327     oident *attrset;
328     enum oid_value ast;
329     
330     attrset = oid_getentbyoid (rpn->attributeSetId);
331     if (attrset)
332     {
333         ast = attrset->value;
334         yaz_log (LOG_LOG, "RPN query. Type: %s", attrset->desc);
335     } 
336     else
337     {
338         ast = VAL_NONE;
339         yaz_log (LOG_LOG, "RPN query. Unknown type");
340     }
341     zlog_structure (rpn->RPNStructure, 0, ast);
342 }
343
344 void log_scan_term (Z_AttributesPlusTerm *zapt, oid_value ast)
345 {
346     int level = 0;
347     if (zapt->term->which == Z_Term_general) 
348     {
349         yaz_log (LOG_LOG, "%*.0s term '%.*s' (general)", level, "",
350                  zapt->term->u.general->len, zapt->term->u.general->buf);
351     }
352     else
353         yaz_log (LOG_LOG, "%*.0s term (not general)", level, "");
354     zlog_attributes (zapt, level+2, ast);
355 }
356
357 void yaz_log_zquery (Z_Query *q)
358 {
359     switch (q->which)
360     {
361     case Z_Query_type_1: case Z_Query_type_101:
362         log_rpn_query (q->u.type_1);
363         break;
364     case Z_Query_type_104:
365         if (q->u.type_104->which == Z_External_CQL)
366             yaz_log (LOG_LOG, "CQL: %s", q->u.type_104->u.cql);
367     }
368 }