Improvements to aggregation code and fucntion library
[com/gs-lite.git] / src / ftacmp / schemaparser.cc
1 /* ------------------------------------------------
2 Copyright 2014 AT&T Intellectual Property
3    Licensed under the Apache License, Version 2.0 (the "License");
4    you may not use this file except in compliance with the License.
5    You may obtain a copy of the License at
6
7      http://www.apache.org/licenses/LICENSE-2.0
8
9    Unless required by applicable law or agreed to in writing, software
10    distributed under the License is distributed on an "AS IS" BASIS,
11    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12    See the License for the specific language governing permissions and
13    limitations under the License.
14  ------------------------------------------- */
15
16 #include"schemaparser_impl.h"
17 #include"schemaparser.h"
18 #include <string>
19 #include "parse_fta.h"
20 #include "parse_schema.h"
21 #include"generate_utils.h"
22
23 #include"host_tuple.h"
24 #include"lapp.h"
25
26 #include <stdlib.h>
27 #include <stdio.h>
28 #include <string.h>
29
30
31 //              Interface to FTA definition lexer and parser ...
32
33 extern int FtaParserparse(void);
34 extern FILE *FtaParserin;
35 extern int FtaParserdebug;
36
37 //                      This will need to be moved to a parse_fta.cc file.
38 fta_parse_t *fta_parse_result;
39 var_defs_t *fta_parse_defines;
40
41
42
43 using namespace std;
44 extern int errno;
45
46 static gs_int8_t tmpstr[20000];                 // for returning const char* values.
47
48 vector<query_rep *> schema_list;        //      The schemas parsed thus far.
49
50 /////////////////////////////////////////////////////////////
51 ///                                     Version functions
52
53 static gs_int32_t curr_version = 4;
54 static gs_int32_t accepted_versions[] = { 4, 3, 2, 1, 0 };              // must end with zero.
55
56 gs_int32_t get_schemaparser_version(){ return curr_version; }
57
58 gs_int32_t *get_schemaparser_accepted_versions(){return accepted_versions;}
59
60 gs_int32_t schemaparser_accepts_version(gs_int32_t v){
61         int i;
62         for(i=0;accepted_versions[i]>0;++i){
63                 if(accepted_versions[i] == v) return 1;
64         }
65         return 0;
66 }
67
68
69 /////////////////////////////////////////////////////////////////////
70 ////////////            Utility Functions
71
72 /*
73 int fta_field_size(int dt, int *is_udef){
74         switch(dt){
75         case INT_TYPE:
76                 return(sizeof(int));
77         case UINT_TYPE:
78         case USHORT_TYPE:
79         case BOOL_TYPE:
80                 return(sizeof(unsigned int));
81         case ULLONG_TYPE:
82                 return(sizeof(unsigned long long int));
83         case LLONG_TYPE:
84                 return(sizeof(long long int));
85         case FLOAT_TYPE:
86                 return(sizeof(double));
87         case TIMEVAL_TYPE:
88                 return(sizeof(timeval));
89         case VSTR_TYPE:
90                 return(sizeof(vstring));
91         default:
92                 *is_udef = 1;
93                 return(0);
94         }
95         return(0);
96 };
97 */
98
99
100 /////////////////////////////////////////////////////////////
101 ///                     Interface fcns
102
103
104 ////////////            Schema management
105
106 static gs_schemahandle_t ftaschema_parse(int prot_ok);
107
108 gs_schemahandle_t ftaschema_parse_string(gs_csp_t f){
109                         // prot_ok is by default false in schemaparser.h
110
111           fta_parse_result = new fta_parse_t();
112           gs_sp_t schema = strdup(f);
113
114 //        FtaParserin = f;
115           FtaParser_setstringinput(schema);
116
117           if(FtaParserparse()){
118                 fprintf(stderr,"FTA parse failed.\n");
119                 free (schema);
120                 return(-1);
121           }
122           free (schema);
123
124           return ftaschema_parse(false);
125 }
126 gs_schemahandle_t ftaschema_parse_string_prot(gs_csp_t f){
127                         // prot_ok is by default false in schemaparser.h
128
129           fta_parse_result = new fta_parse_t();
130           gs_sp_t schema = strdup(f);
131
132 //        FtaParserin = f;
133           FtaParser_setstringinput(schema);
134
135           if(FtaParserparse()){
136                 fprintf(stderr,"FTA parse failed.\n");
137                 free (schema);
138                 return(-1);
139           }
140           free (schema);
141
142           return ftaschema_parse(true);
143 }
144
145 gs_schemahandle_t ftaschema_parse_file(FILE *f){
146                         // prot_ok is by default false in schemaparser.h
147
148           fta_parse_result = new fta_parse_t();
149
150 //        FtaParserin = f;
151           FtaParser_setfileinput(f);
152
153           if(FtaParserparse()){
154                 fprintf(stderr,"FTA parse failed.\n");
155                 return(-1);
156           }
157
158           return ftaschema_parse(false);
159 }
160 gs_schemahandle_t ftaschema_parse_file_prot(FILE *f){
161                         // prot_ok is by default false in schemaparser.h
162
163           fta_parse_result = new fta_parse_t();
164
165 //        FtaParserin = f;
166           FtaParser_setfileinput(f);
167
168           if(FtaParserparse()){
169                 fprintf(stderr,"FTA parse failed.\n");
170                 return(-1);
171           }
172
173           return ftaschema_parse(true);
174 }
175
176
177
178
179
180 static gs_schemahandle_t ftaschema_parse(int prot_ok){
181
182         if(fta_parse_result->parse_type != STREAM_PARSE){
183                 if(!(fta_parse_result->parse_type == TABLE_PARSE && prot_ok!=0)){
184                         fprintf(stderr,"ERROR, input is not a stream file.\n");
185                         return(-1);
186                 }
187         }
188
189
190 //                      Get the tuple information.
191           if(fta_parse_result->tables->size() != 1){
192                 fprintf(stderr,"ERROR parsing schema file: %d tables, expecting 1.\n",
193                         fta_parse_result->tables->size() );
194                 return(-1);
195           }
196
197           string table_name = fta_parse_result->tables->get_table_name(0);
198           vector<field_entry *> tuple_flds = fta_parse_result->tables->get_fields(table_name);
199           int n_tuples = tuple_flds.size();
200
201 //                      get the parameter info.
202           int n_params = 0;
203           string query_name = table_name;
204           vector<var_pair_t *> query_params;
205           if(fta_parse_result->fta_parse_tree){
206                 query_params = fta_parse_result->fta_parse_tree->query_params;
207                 n_params = query_params.size();
208
209 //                      Get the query name
210                 if(fta_parse_result->fta_parse_tree->nmap.count("query_name") == 0){
211                         fprintf(stderr,"WARNING: query name is empty. using default_query.\n");
212                         query_name = "default_query";
213                 }else{
214                         query_name = fta_parse_result->fta_parse_tree->nmap["query_name"];
215                 }
216
217                 if(query_name != table_name){
218                         fprintf(stderr,"WARNING table name (%s) is different than query name (%s).\n",
219                                 table_name.c_str(), query_name.c_str() );
220                 }
221
222           }
223
224 //                      Construct the query representation.
225
226           query_rep *qrep = new query_rep(query_name, n_tuples, n_params);
227
228 //                      Pack the tuple information.
229           int fi;
230           for(fi=0;fi<n_tuples;++fi){
231                 if((qrep->set_field_info(fi,tuple_flds[fi])) == UNDEFINED_TYPE){
232                         fprintf(stderr,"ERROR tuple field %s (number %d) has undefined type %s.\n",
233                                 tuple_flds[fi]->get_name().c_str(), fi, tuple_flds[fi]->get_type().c_str());
234                 }
235           }
236           if(qrep->finalize_field_info()){
237                 fprintf(stderr,"ERROR undefined type in tuple.\n");
238                 return(-1);
239           }
240
241 //                      Pack the param info
242           int pi;
243           for(pi=0;pi<n_params;++pi){
244                 if((qrep->set_param_info(pi, query_params[pi])) == UNDEFINED_TYPE){
245                         fprintf(stderr,"ERROR parameter %s (number %d) has undefined type %s.\n",
246                                 query_params[pi]->name.c_str(), pi, query_params[pi]->val.c_str());
247                 }
248           }
249           if(qrep->finalize_param_info()){
250                 fprintf(stderr,"ERROR undefined type in parameter block.\n");
251                 return(-1);
252           }
253
254 //                      finish up
255
256         schema_list.push_back(qrep);
257
258         return(schema_list.size()-1);
259 }
260
261
262 /*                      Release memory used by the schema representation.
263                         return non-zero on error.
264 */
265 //                      Currently, do nothing.  I'll need to
266 //                      systematically plug memory leaks and write destructors
267 //                      to make implementing this function worth while.
268 gs_int32_t ftaschema_free(gs_schemahandle_t sh){
269         return(0);
270 }
271
272
273 /* name of fta schema null terminated */
274 /* Returns NULL if sh is out of bounds. */
275 /* NO ALLOCATION IS PERFORMED!   Must treat result as const. */
276 gs_sp_t ftaschema_name(gs_schemahandle_t sh){
277         if(sh < 0 || sh >= schema_list.size()){
278                 return(NULL);
279         }
280         strcpy(tmpstr,schema_list[sh]->name.c_str());
281         return(tmpstr);
282 }
283
284
285 /////////////           Tuple management
286
287
288 /* number of entries in a tuple */
289 /* Return -1 if the schema handle is out of range.      */
290 gs_int32_t ftaschema_tuple_len(gs_schemahandle_t sh){
291         if(sh < 0 || sh >= schema_list.size()){
292                 return(-1);
293         }
294         return(schema_list[sh]->field_info.size());
295 }
296
297 /* field entry name */
298 /* Returns NULL if sh or index is out of bounds.        */
299 /* NO ALLOCATION IS PERFORMED!   Must treat result as const. */
300 gs_sp_t ftaschema_field_name(gs_schemahandle_t sh, gs_uint32_t index){
301         if(sh < 0 || sh >= schema_list.size()){
302                 return(NULL);
303         }
304         if(index >= schema_list[sh]->field_info.size()){
305                 return(NULL);
306         }
307         strcpy(tmpstr,schema_list[sh]->field_info[index].field_name.c_str());
308         return( tmpstr);
309 }
310
311 /*                      Direct tuple access functions.
312 */
313 gs_uint32_t fta_unpack_uint(void *data, gs_int32_t len, gs_uint32_t offset, gs_int32_t *problem){
314         gs_uint32_t retval;
315         if(offset+sizeof(gs_uint32_t) > len){
316                 *problem = 1;
317                 return(0);
318         }
319         memcpy(&retval, ((gs_sp_t)data)+offset, sizeof(gs_uint32_t));
320 //      return(htonl(retval));
321         return(retval);
322 }
323 gs_uint32_t fta_unpack_uint_nocheck(void *data, gs_uint32_t offset){
324         gs_uint32_t retval;
325         memcpy(&retval, ((gs_sp_t)data)+offset, sizeof(gs_uint32_t));
326         return(retval);
327 }
328
329 gs_uint32_t fta_unpack_ushort(void *data, gs_int32_t len, gs_uint32_t offset, gs_int32_t *problem){
330         gs_uint32_t retval;
331         if(offset+sizeof(gs_uint32_t) > len){
332                 *problem = 1;
333                 return(0);
334         }
335         memcpy(&retval, ((gs_sp_t)data)+offset, sizeof(gs_uint32_t));
336 //      return(htonl(retval));
337         return(retval);
338 }
339 gs_uint32_t fta_unpack_ushort_nocheck(void *data, gs_uint32_t offset){
340         gs_uint32_t retval;
341         memcpy(&retval, ((gs_sp_t)data)+offset, sizeof(gs_uint32_t));
342         return(retval);
343 }
344
345 gs_uint32_t fta_unpack_bool(void *data, gs_int32_t len, gs_uint32_t offset, gs_int32_t *problem){
346         gs_uint32_t retval;
347         if(offset+sizeof(gs_uint32_t) > len){
348                 *problem = 1;
349                 return(0);
350         }
351         memcpy(&retval, ((gs_sp_t)data)+offset, sizeof(gs_uint32_t));
352 //      return(htonl(retval));
353         return(retval);
354 }
355 gs_uint32_t fta_unpack_bool_nocheck(void *data, gs_uint32_t offset){
356         gs_uint32_t retval;
357         memcpy(&retval, ((gs_sp_t)data)+offset, sizeof(gs_uint32_t));
358 //      return(htonl(retval));
359         return(retval);
360 }
361
362 gs_int32_t fta_unpack_int(void *data, gs_int32_t len, gs_uint32_t offset, gs_int32_t *problem){
363         gs_int32_t retval;
364         if(offset+sizeof(gs_int32_t) > len){
365                 *problem = 1;
366                 return(0);
367         }
368         memcpy(&retval, ((gs_sp_t)data)+offset, sizeof(gs_int32_t));
369 //      return(htonl(retval));
370         return(retval);
371 }
372 gs_int32_t fta_unpack_int_nocheck(void *data, gs_uint32_t offset){
373         gs_int32_t retval;
374         memcpy(&retval, ((gs_sp_t)data)+offset, sizeof(gs_int32_t));
375         return(retval);
376 }
377
378 gs_uint64_t fta_unpack_ullong(void *data, gs_int32_t len, gs_uint32_t offset, gs_int32_t *problem){
379         gs_uint64_t retval;
380         if(offset+sizeof(gs_uint64_t) > len){
381                 *problem = 1;
382                 return(0);
383         }
384         memcpy(&retval, ((gs_sp_t)data)+offset, sizeof(gs_uint64_t));
385 //      return(htonll(retval));
386         return(retval);
387 }
388 gs_uint64_t fta_unpack_ullong_nocheck(void *data, gs_uint32_t offset){
389         gs_uint64_t retval;
390         memcpy(&retval, ((gs_sp_t)data)+offset, sizeof(gs_uint64_t));
391         return(retval);
392 }
393
394 gs_int64_t fta_unpack_llong(void *data, gs_int32_t len, gs_uint32_t offset, gs_int32_t *problem){
395         gs_int64_t retval;
396         if(offset+sizeof( gs_int64_t) > len){
397                 *problem = 1;
398                 return(0);
399         }
400         memcpy(&retval, ((gs_sp_t)data)+offset, sizeof(gs_int64_t));
401 //      return(htonl(retval));
402         return(retval);
403 }
404 gs_int64_t fta_unpack_llong_nocheck(void *data, gs_uint32_t offset){
405         gs_int64_t retval;
406         memcpy(&retval, ((gs_sp_t)data)+offset, sizeof(gs_int64_t));
407         return(retval);
408 }
409
410 gs_float_t fta_unpack_float(void *data, gs_int32_t len, gs_uint32_t offset, gs_int32_t *problem){
411         gs_float_t retval;
412         if(offset+sizeof( gs_float_t) > len){
413                 *problem = 1;
414                 return(0.0);
415         }
416         memcpy(&retval, ((gs_sp_t)data)+offset, sizeof(gs_float_t));
417 //      return(ntohf(retval));
418         return(retval);
419 }
420 gs_float_t fta_unpack_float_nocheck(void *data, gs_uint32_t offset){
421         gs_float_t retval;
422         memcpy(&retval, ((gs_sp_t)data)+offset, sizeof(gs_float_t));
423         return(retval);
424 }
425
426 timeval fta_unpack_timeval(void *data, gs_int32_t len, gs_uint32_t offset, gs_int32_t *problem){
427         timeval retval;
428         if(offset+sizeof( timeval) > len){
429                 *problem = 1;
430                 return(retval);
431         }
432         memcpy(&retval, ((gs_sp_t)data)+offset, sizeof(timeval));
433 //      retval.tv_sec = htonl(retval.tv_sec);
434 //      retval.tv_usec = htonl(retval.tv_usec);
435         retval.tv_sec = retval.tv_sec;
436         retval.tv_usec = retval.tv_usec;
437         return(retval);
438 }
439 timeval fta_unpack_timeval_nocheck(void *data, gs_uint32_t offset){
440         timeval retval;
441         memcpy(&retval, ((gs_sp_t)data)+offset, sizeof(timeval));
442         retval.tv_sec = retval.tv_sec;
443         retval.tv_usec = retval.tv_usec;
444         return(retval);
445 }
446
447 vstring fta_unpack_vstr(void *data,  gs_int32_t len, gs_uint32_t offset, gs_int32_t *problem){
448         vstring retval;
449         vstring32 unpack_s;
450
451         if(offset+sizeof( vstring32) > len){
452                 *problem = 1;
453                 return(retval);
454         }
455
456         memcpy(&unpack_s, ((gs_sp_t)data)+offset, sizeof(vstring32));
457
458 //      retval.length = htonl(unpack_s.length);
459 //      unpack_s.offset = htonl(unpack_s.offset);
460         retval.length = unpack_s.length;
461         unpack_s.offset = unpack_s.offset;
462         retval.reserved = SHALLOW_COPY;
463
464         if(unpack_s.offset + retval.length > len){
465                 *problem = 1;
466                 return(retval);
467         }
468         retval.offset = (gs_p_t)data + unpack_s.offset;
469         return(retval);
470 }
471
472 gs_sp_t fta_unpack_fstring(void *data,  gs_int32_t len, gs_uint32_t offset, gs_int32_t *problem){
473         return( (gs_sp_t)(data)+offset);
474 }
475
476 struct hfta_ipv6_str fta_unpack_ipv6(void *data,  gs_int32_t len, gs_uint32_t offset, gs_int32_t *problem){
477         struct hfta_ipv6_str retval;
478         if(offset+sizeof(hfta_ipv6_str) > len){
479                 *problem = 1;
480                 return(retval);
481         }
482         memcpy(&retval, ((gs_sp_t)data)+offset, sizeof(hfta_ipv6_str));
483 //              htonl(retval.v[0]);
484 //              htonl(retval.v[1]);
485 //              htonl(retval.v[2]);
486 //              htonl(retval.v[3]);
487         return(retval);
488 }
489 struct hfta_ipv6_str fta_unpack_ipv6_nocheck(void *data, gs_uint32_t offset){
490         struct hfta_ipv6_str retval;
491         memcpy(&retval, ((gs_sp_t)data)+offset, sizeof(hfta_ipv6_str));
492         return(retval);
493 }
494
495
496 /*
497                 Direct tuple access functions, but no ntoh xform.
498 */
499 gs_uint32_t fta_unpack_uint_noxf(void *data,  gs_int32_t len, gs_uint32_t offset, gs_int32_t *problem){
500         gs_uint32_t retval;
501         if(offset+sizeof(gs_uint32_t) > len){
502                 *problem = 1;
503                 return(0);
504         }
505         memcpy(&retval, ((gs_sp_t)data)+offset, sizeof(gs_uint32_t));
506         return(retval);
507 }
508 gs_uint32_t fta_unpack_uint_noxf_nocheck(void *data, gs_uint32_t offset){
509         gs_uint32_t retval;
510         memcpy(&retval, ((gs_sp_t)data)+offset, sizeof(gs_uint32_t));
511         return(retval);
512 }
513
514 gs_uint32_t fta_unpack_ushort_noxf(void *data,  gs_int32_t len, gs_uint32_t offset, gs_int32_t *problem){
515         gs_uint32_t retval;
516         if(offset+sizeof(gs_uint32_t) > len){
517                 *problem = 1;
518                 return(0);
519         }
520         memcpy(&retval, ((gs_sp_t)data)+offset, sizeof(gs_uint32_t));
521         return(retval);
522 }
523 gs_uint32_t fta_unpack_ushort_noxf_nocheck(void *data, gs_uint32_t offset){
524         gs_uint32_t retval;
525         memcpy(&retval, ((gs_sp_t)data)+offset, sizeof(gs_uint32_t));
526         return(retval);
527 }
528
529 gs_uint32_t fta_unpack_bool_noxf(void *data,  gs_int32_t len, gs_uint32_t offset, gs_int32_t *problem){
530         gs_uint32_t retval;
531         if(offset+sizeof(gs_uint32_t) > len){
532                 *problem = 1;
533                 return(0);
534         }
535         memcpy(&retval, ((gs_sp_t)data)+offset, sizeof(gs_uint32_t));
536         return(retval);
537 }
538 gs_uint32_t fta_unpack_bool_noxf_nocheck(void *data, gs_uint32_t offset){
539         gs_uint32_t retval;
540         memcpy(&retval, ((gs_sp_t)data)+offset, sizeof(gs_uint32_t));
541         return(retval);
542 }
543
544 gs_int32_t fta_unpack_int_noxf(void *data,  gs_int32_t len, gs_uint32_t offset, gs_int32_t *problem){
545         gs_int32_t retval;
546         if(offset+sizeof(gs_int32_t) > len){
547                 *problem = 1;
548                 return(0);
549         }
550         memcpy(&retval, ((gs_sp_t)data)+offset, sizeof(gs_int32_t));
551         return(retval);
552 }
553 gs_int32_t fta_unpack_int_noxf_nocheck(void *data, gs_uint32_t offset){
554         gs_int32_t retval;
555         memcpy(&retval, ((gs_sp_t)data)+offset, sizeof(gs_int32_t));
556         return(retval);
557 }
558
559 gs_uint64_t fta_unpack_ullong_noxf(void *data,  gs_int32_t len, gs_uint32_t offset, gs_int32_t *problem){
560         gs_int64_t retval;
561         if(offset+sizeof( gs_uint64_t) > len){
562                 *problem = 1;
563                 return(0);
564         }
565         memcpy(&retval, ((gs_sp_t)data)+offset, sizeof(gs_uint64_t));
566         return(retval);
567 }
568 gs_uint64_t fta_unpack_ullong_noxf_nocheck(void *data, gs_uint32_t offset){
569         gs_uint64_t retval;
570         memcpy(&retval, ((gs_sp_t)data)+offset, sizeof(gs_uint64_t));
571         return(retval);
572 }
573
574 gs_int64_t fta_unpack_llong_noxf(void *data,  gs_int32_t len, gs_uint32_t offset, gs_int32_t *problem){
575         gs_int64_t retval;
576         if(offset+sizeof( gs_int64_t) > len){
577                 *problem = 1;
578                 return(0);
579         }
580         memcpy(&retval, ((gs_sp_t)data)+offset, sizeof(gs_int64_t));
581         return(retval);
582 }
583 gs_int64_t fta_unpack_llong_noxf_nocheck(void *data, gs_uint32_t offset){
584         gs_int64_t retval;
585         memcpy(&retval, ((gs_sp_t)data)+offset, sizeof(gs_int64_t));
586         return(retval);
587 }
588
589 gs_float_t fta_unpack_float_noxf(void *data,  gs_int32_t len, gs_uint32_t offset, gs_int32_t *problem){
590         gs_float_t retval;
591         if(offset+sizeof( gs_float_t) > len){
592                 *problem = 1;
593                 return(0.0);
594         }
595         memcpy(&retval, ((gs_sp_t)data)+offset, sizeof(gs_float_t));
596         return(retval);
597 }
598 gs_float_t fta_unpack_float_noxf_nocheck(void *data, gs_uint32_t offset){
599         gs_float_t retval;
600         memcpy(&retval, ((gs_sp_t)data)+offset, sizeof(gs_float_t));
601         return(retval);
602 }
603
604 timeval fta_unpack_timeval_noxf_nocheck(void *data, gs_uint32_t offset){
605         timeval retval;
606         memcpy(&retval, ((gs_sp_t)data)+offset, sizeof(timeval));
607         return(retval);
608 }
609
610 vstring fta_unpack_vstr_noxf(void *data,  gs_int32_t len, gs_uint32_t offset, gs_int32_t *problem){
611         vstring retval;
612         vstring32 unpack_s;
613
614         if(offset+sizeof( vstring32) > len){
615                 *problem = 1;
616                 return(retval);
617         }
618
619         memcpy(&unpack_s, ((gs_sp_t)data)+offset, sizeof(vstring32));
620
621         retval.length = unpack_s.length;
622         retval.reserved = SHALLOW_COPY;
623
624         if(unpack_s.offset + unpack_s.length > len){
625                 *problem = 1;
626                 return(retval);
627         }
628         retval.offset = (gs_p_t)data + unpack_s.offset;
629         return(retval);
630 }
631
632 gs_sp_t fta_unpack_fstring_noxf(void *data,  gs_int32_t len, gs_uint32_t offset, gs_int32_t *problem){
633         return( (gs_sp_t)(data)+offset);
634 }
635
636 struct hfta_ipv6_str fta_unpack_ipv6_noxf_nocheck(void *data, gs_uint32_t offset){
637         struct hfta_ipv6_str retval;
638         memcpy(&retval, ((gs_sp_t)data)+offset, sizeof(hfta_ipv6_str));
639         return(retval);
640 }
641
642
643 /* returns fields offset by name        */
644 /* if sh is out of bounds, or if fieldname is not the name of a field,
645    or len is too small,
646    return value is -1
647 */
648 gs_int32_t ftaschema_get_field_offset_by_name(gs_schemahandle_t sh, gs_csp_t fieldname){
649         if(sh < 0 || sh >= schema_list.size()){
650                         return(-1);
651         }
652
653         int f;
654         for(f=0;f<schema_list[sh]->field_info.size();++f){
655                 if(strcmp(fieldname, schema_list[sh]->field_info[f].field_name.c_str()) == 0)
656                         return(schema_list[sh]->field_info[f].offset);
657         }
658
659 //              Nothing found
660         return(-1);
661
662 }
663 /* field offset by index, return -1 if sh or idx is out-of-bounds */
664 gs_int32_t ftaschema_get_field_offset_by_index(gs_schemahandle_t sh, gs_int32_t idx){
665         if(sh < 0 || sh >= schema_list.size()){
666                         return(-1);
667         }
668         if(idx < 0 || idx >= schema_list[sh]->field_info.size()){
669                         return(-1);
670         }
671
672         return(schema_list[sh]->field_info[idx].offset);
673
674 }
675
676
677 /* returns fields type by name  */
678 /* if sh is out of bounds, or if fieldname is not the name of a field,
679    or len is too small,
680    return value is UNDEFINED_TYPE
681 */
682 gs_int32_t ftaschema_get_field_type_by_name(gs_schemahandle_t sh, gs_csp_t fieldname){
683         if(sh < 0 || sh >= schema_list.size()){
684                         return(UNDEFINED_TYPE);
685         }
686
687         int f;
688         for(f=0;f<schema_list[sh]->field_info.size();++f){
689                 if(strcmp(fieldname, schema_list[sh]->field_info[f].field_name.c_str()) == 0)
690                 return(schema_list[sh]->field_info[f].pdt->type_indicator());
691         }
692
693 //              Nothing found
694         return( UNDEFINED_TYPE);
695 }
696 /* field type by index, rteturn value is UNDEFINED_TYPE if sh or idx 
697  * is out of bounds
698 */
699 gs_int32_t ftaschema_get_field_type_by_index(gs_schemahandle_t sh, gs_int32_t idx){
700         if(sh < 0 || sh >= schema_list.size()){
701                         return(UNDEFINED_TYPE);
702         }
703         if(idx < 0 || idx >= schema_list[sh]->field_info.size()){
704                         return(UNDEFINED_TYPE);
705         }
706
707         return(schema_list[sh]->field_info[idx].pdt->type_indicator());
708 }
709
710
711 /* returns tuple value based on name */
712 /* if sh is out of bounds, or if fieldname is not the name of a field,
713    or len is too small,
714    return value is of type UNDEFINED_TYPE
715 */
716 access_result ftaschema_get_field_by_name(gs_schemahandle_t sh, gs_csp_t fieldname,
717                                           void * data, gs_uint32_t len){
718         access_result retval;
719         retval.field_data_type = UNDEFINED_TYPE;
720
721         if(sh < 0 || sh >= schema_list.size()){
722                         return(retval);
723         }
724
725         int f;
726         for(f=0;f<schema_list[sh]->field_info.size();++f){
727                 if(strcmp(fieldname, schema_list[sh]->field_info[f].field_name.c_str()) == 0)
728                         return(ftaschema_get_field_by_index(sh,f,data,len));
729         }
730
731 //              Nothing found
732         return(retval);
733
734 }
735
736 /* return tuple value by index */
737 /* if sh is out of bounds, or if fieldname is not the name of a field,
738    or len is too small,
739    return value is of type UNDEFINED_TYPE
740 */
741 access_result ftaschema_get_field_by_index(gs_schemahandle_t sh, gs_uint32_t index,
742                                           void * data, gs_uint32_t len){
743         access_result retval;
744         retval.field_data_type = UNDEFINED_TYPE;
745         gs_int32_t problem = 0;
746
747         if(sh < 0 || sh >= schema_list.size()){
748                         return(retval);
749         }
750         if(index >= schema_list[sh]->field_info.size()){
751                 return(retval);
752         }
753
754         switch(schema_list[sh]->field_info[index].pdt->get_type()){
755         case u_int_t:
756                 retval.r.ui = fta_unpack_uint(data,  len,
757                         schema_list[sh]->field_info[index].offset, &problem);
758                 if(!problem) retval.field_data_type = UINT_TYPE;
759                 break;
760         case ip_t:
761                 retval.r.ui = fta_unpack_uint(data,  len,
762                         schema_list[sh]->field_info[index].offset, &problem);
763                 if(!problem) retval.field_data_type = IP_TYPE;
764                 break;
765         case int_t:
766                 retval.r.i = fta_unpack_int(data,  len,
767                         schema_list[sh]->field_info[index].offset, &problem);
768                 if(!problem) retval.field_data_type = INT_TYPE;
769                 break;
770         case u_llong_t:
771                 retval.r.ul = fta_unpack_ullong(data,  len,
772                         schema_list[sh]->field_info[index].offset, &problem);
773                 if(!problem) retval.field_data_type = ULLONG_TYPE;
774                 break;
775         case llong_t:
776                 retval.r.l = fta_unpack_llong(data,  len,
777                         schema_list[sh]->field_info[index].offset, &problem);
778                 if(!problem) retval.field_data_type = LLONG_TYPE;
779                 break;
780         case u_short_t:
781                 retval.r.ui = fta_unpack_ushort(data,  len,
782                         schema_list[sh]->field_info[index].offset, &problem);
783                 if(!problem) retval.field_data_type = USHORT_TYPE;
784                 break;
785         case floating_t:
786                 retval.r.f = fta_unpack_float(data,  len,
787                         schema_list[sh]->field_info[index].offset, &problem);
788                 if(!problem) retval.field_data_type = FLOAT_TYPE;
789                 break;
790         case bool_t:
791                 retval.r.ui = fta_unpack_bool(data,  len,
792                         schema_list[sh]->field_info[index].offset, &problem);
793                 if(!problem) retval.field_data_type = BOOL_TYPE;
794                 break;
795         case v_str_t:
796                 retval.r.vs = fta_unpack_vstr(data,  len,
797                         schema_list[sh]->field_info[index].offset, &problem);
798                 if(!problem) retval.field_data_type = VSTR_TYPE;
799                 break;
800         case fstring_t:
801                 retval.r.fs.data = fta_unpack_fstring(data,  len,
802                         schema_list[sh]->field_info[index].offset, &problem);
803                 retval.r.fs.size = schema_list[sh]->field_info[index].pdt->type_size();
804                 if(!problem) retval.field_data_type = FSTRING_TYPE;
805         case timeval_t:
806                 retval.r.t = fta_unpack_timeval(data,  len,
807                         schema_list[sh]->field_info[index].offset, &problem);
808                 if(!problem) retval.field_data_type = TIMEVAL_TYPE;
809                 break;
810         case ipv6_t:
811                 retval.r.ip6 = fta_unpack_ipv6(data,  len,
812                         schema_list[sh]->field_info[index].offset, &problem);
813                 if(!problem) retval.field_data_type = IPV6_TYPE;
814                 break;
815         case undefined_t:
816                 break;
817         }
818         return(retval);
819 }
820
821
822 //              Get location of eof, temporal-tuple metadata.
823 gs_int32_t ftaschema_get_tuple_metadata_offset(gs_schemahandle_t sh){
824         if(sh < 0 || sh >= schema_list.size())
825                 return 0;               // probably need to return a error instead of just telling its not eof tuple
826
827         return ( schema_list[sh]->min_tuple_size);
828 }
829
830
831 /* checks whether tuple is temporal
832   return value 1 indicates that tuple istemporal, 0 - not temporal
833 */
834 gs_int32_t ftaschema_is_temporal_tuple(gs_schemahandle_t sh, void *data) {
835
836         if(sh < 0 || sh >= schema_list.size())
837                 return 0;               // probably need to return a error instead of just telling its not temporal
838
839         return (*((gs_sp_t)data + schema_list[sh]->min_tuple_size) == TEMPORAL_TUPLE);
840 }
841 //inline gs_int32_t ftaschema_is_temporal_tuple_offset(int metadata_offset, void *data) {
842 //      return (*((gs_sp_t)data + metadata_offset) == TEMPORAL_TUPLE);
843 //}
844
845
846
847 /* checks whether tuple is special end-of_file tuple
848   return value 1 indicates that tuple is eof_tuple, 0 - otherwise
849 */
850 gs_int32_t ftaschema_is_eof_tuple(gs_schemahandle_t sh, void *data) {
851         if(sh < 0 || sh >= schema_list.size())
852                 return 0;               // probably need to return a error instead of just telling its not eof tuple
853
854         return (*((gs_sp_t)data + schema_list[sh]->min_tuple_size) == EOF_TUPLE);
855
856 }
857 inline gs_int32_t ftaschema_is_eof_tuple_offset(int metadata_offset, void *data) {
858         return (*((gs_sp_t)data + metadata_offset) == EOF_TUPLE);
859 }
860
861
862 /* extracts the trace from the temporal tuple
863   return value 0 indicates success, non-zero - error
864 */
865 gs_int32_t ftaschema_get_trace(gs_schemahandle_t sh, void* data, gs_int32_t len,
866         gs_uint64_t* trace_id, gs_uint32_t* sz, fta_stat** trace ) {
867
868         if(sh < 0 || sh >= schema_list.size() || *((gs_sp_t)data + schema_list[sh]->min_tuple_size) != TEMPORAL_TUPLE)
869                 return 1;
870
871         memcpy(trace_id, (gs_sp_t)data + schema_list[sh]->min_tuple_size + sizeof(gs_int8_t), sizeof(gs_uint64_t));
872         *trace = (fta_stat*)((gs_sp_t)data + schema_list[sh]->min_tuple_size + sizeof(gs_int8_t) + sizeof(gs_uint64_t));
873         *sz = (len - schema_list[sh]->min_tuple_size - sizeof(gs_int8_t)- sizeof(gs_uint64_t)) / sizeof(fta_stat);
874
875         return 0;
876 }
877
878
879 ////////////    Param block management
880
881 /* number of parameters */
882 /*      Return -1 if sh is out of bounds        */
883 gs_int32_t ftaschema_parameter_len(gs_schemahandle_t sh){
884         if(sh < 0 || sh >= schema_list.size()){
885                 return(-1);
886         }
887         return(schema_list[sh]->param_info.size());
888 }
889
890 /* parameter entry name */
891 /*      Return NULL if sh or index is out of bounds.    */
892 /*      NO COPYING IS PERFORMED */
893 gs_sp_t ftaschema_parameter_name(gs_schemahandle_t sh, gs_uint32_t index){
894         if(sh < 0 || sh >= schema_list.size()){
895                 return(NULL);
896         }
897     if(index >= schema_list[sh]->param_info.size()){
898         return(NULL);
899     }
900         strcpy(tmpstr,schema_list[sh]->param_info[index].param_name.c_str());
901     return(tmpstr);
902 }
903
904 /* set parameter value for parameter handle */
905 /*      Pass in the parameter in its char string representation. */
906 /*  Return value is -1 on error, else 0 */
907 gs_int32_t ftaschema_setparam_by_name(gs_schemahandle_t sh, gs_sp_t param_name,
908                                gs_sp_t param_val, gs_int32_t len){
909         if(sh < 0 || sh >= schema_list.size()){
910                         return(-1);
911         }
912
913         int f;
914         for(f=0;f<schema_list[sh]->param_info.size();++f){
915                 if(strcmp(param_name, schema_list[sh]->param_info[f].param_name.c_str()) == 0)
916                         return(ftaschema_setparam_by_index(sh,f,param_val,len));
917         }
918
919 //              not found
920         return(-1);
921 }
922
923 /* set parameter value for parameter handle */
924 /*      Pass in the parameter in its char string representation. */
925 /*  Return value is -1 on error, else 0 */
926 gs_int32_t ftaschema_setparam_by_index(gs_schemahandle_t sh, gs_int32_t index,
927                                 gs_sp_t param_val, gs_int32_t len){
928
929     void *tmp_ptr;
930         unsigned int ui,d1,d2,d3,d4;
931         int i;
932         unsigned long long int ulli;
933         long long int lli;
934         double f;
935
936
937         if(sh < 0 || sh >= schema_list.size()){
938                 return(-1);
939         }
940     if(index >= schema_list[sh]->param_info.size()){
941         return(-1);
942     }
943
944     param_block_info *pb = &(schema_list[sh]->param_info[index]);
945         switch(pb->pdt->get_type()){
946                 case int_t:
947                         if(sscanf(param_val,"%d",&i) == 1){
948                                 pb->value.r.i=i;
949                                 pb->value_set = true;
950                                 return(0);
951                         }else
952                                 return(-1);
953                         break;
954                 case u_int_t:
955                 case u_short_t:
956                 case bool_t:
957                         if(sscanf(param_val,"%u",&ui) == 1){
958                                 pb->value.r.ui=ui;
959                                 pb->value_set = true;
960                                 return(0);
961                         }else
962                                 return(-1);
963                         break;
964                 case ip_t:
965                         if(sscanf(param_val,"%d.%d.%d.%d",&d1,&d2,&d3,&d4) == 4){
966                                 pb->value.r.ui = (d1 << 24)+(d2 << 16)+(d3 << 8)+d4;
967                                 pb->value_set = true;
968                                 return(0);
969                         }else
970                                 return(-1);
971                 case u_llong_t:
972                         if(sscanf(param_val,"%llu",&ulli) == 1){
973                                 pb->value.r.ul=ulli;
974                                 pb->value_set = true;
975                                 return(0);
976                         }else
977                                 return(-1);
978                         break;
979                 case llong_t:
980                         if(sscanf(param_val,"%lld",&lli) == 1){
981                                 pb->value.r.l=lli;
982                                 pb->value_set = true;
983                                 return(0);
984                         }else
985                                 return(-1);
986                         break;
987                 case floating_t:
988                         if(sscanf(param_val,"%lf",&f) == 1){
989                                 pb->value.r.f=f;
990                                 pb->value_set = true;
991                                 return(0);
992                         }else
993                                 return(-1);
994                         break;
995                 case timeval_t:
996                         if(sscanf(param_val,"(%d,%d)",&d1, &d2) == 2){
997                                 pb->value.r.t.tv_sec = d1;
998                                 pb->value.r.t.tv_usec = d2;
999                                 pb->value_set = true;
1000                                 return(0);
1001                         }else
1002                                 return(-1);
1003                         break;
1004                 case v_str_t:
1005                         if(pb->value.r.vs.offset != 0){
1006                                 tmp_ptr = (void *)(pb->value.r.vs.offset);
1007                                 free(tmp_ptr);
1008                         }
1009                         tmp_ptr = malloc(len);
1010                         pb->value.r.vs.offset = (gs_p_t)tmp_ptr;
1011                         memcpy(tmp_ptr,param_val, len);
1012                         pb->value.r.vs.length = len;
1013 //                      pb->value.r.vs.reserved = 0;
1014                         pb->value.r.vs.reserved = INTERNAL;
1015                         pb->value_set = true;
1016                         return(0);
1017                         break;
1018                 case fstring_t:
1019                         fprintf(stderr,"ERROR, fstring parameters not supported, use vstring.\n");
1020                         exit(1);
1021                         break;
1022                 case ipv6_t:
1023                         fprintf(stderr,"ERROR, ipv6_t parameters not supported.\n");
1024                         exit(1);
1025                         break;
1026                 case undefined_t:
1027                         fprintf(stderr,"INTERNAL ERROR undefined_t type in ftaschema_setparam_by_index\n");
1028                         exit(1);
1029                 default:
1030                         fprintf(stderr,"INTERNAL ERROR unknown type in ftaschema_setparam_by_index\n");
1031                         exit(1);
1032         }
1033
1034         return(-1);
1035 }
1036
1037 gs_int32_t ftaschema_create_param_block(gs_schemahandle_t sh, void ** block, gs_int32_t * size){
1038         if(sh < 0 || sh >= schema_list.size()){
1039                 return(-1);
1040         }
1041
1042         *size = schema_list[sh]->min_param_size;
1043         int p;
1044
1045         for(p=0;p<schema_list[sh]->param_info.size();++p){
1046                 if(! schema_list[sh]->param_info[p].value_set) return 1;
1047
1048                 switch(schema_list[sh]->param_info[p].pdt->get_type()){
1049                 case v_str_t:
1050                         *size += schema_list[sh]->param_info[p].value.r.vs.length;
1051                         break;
1052                 case fstring_t:
1053                         fprintf(stderr,"ERROR, fstring parameters not supported, use vstring.\n");
1054                         exit(1);
1055                         break;
1056                 case undefined_t:
1057                         return(-1);
1058                         break;
1059                 default:
1060                         break;
1061                 }
1062         }
1063
1064         *block = malloc(*size);
1065         if(*block == NULL) return(-1);
1066
1067         int data_pos = schema_list[sh]->min_param_size;
1068
1069         gs_int32_t tmp_int;
1070         gs_uint32_t tmp_uint;
1071         gs_int64_t tmp_ll;
1072         gs_uint64_t tmp_ull;
1073         gs_float_t tmp_f;
1074         timeval tmp_tv;
1075         vstring32 tmp_vstr;
1076         void *tmp_ptr;
1077
1078         for(p=0;p<schema_list[sh]->param_info.size();++p){
1079                 param_block_info *pb = &(schema_list[sh]->param_info[p]);
1080                 switch(pb->pdt->get_type()){
1081                         case int_t:
1082 //                              tmp_int = htonl(pb->value.r.i);
1083                                 tmp_int = pb->value.r.i;
1084                                 memcpy(((gs_sp_t)(*block))+pb->offset,&tmp_int,sizeof(gs_int32_t));
1085                                 break;
1086                         case u_int_t:
1087                         case u_short_t:
1088                         case bool_t:
1089                         case ip_t:
1090 //                              tmp_uint = htonl(pb->value.r.ui);
1091                                 tmp_uint = pb->value.r.ui;
1092                                 memcpy(((gs_sp_t)(*block))+pb->offset,&tmp_uint,sizeof(gs_uint32_t));
1093                                 break;
1094                         case u_llong_t:
1095 //                              tmp_ull = htonll(pb->value.r.ul);
1096                                 tmp_ull = pb->value.r.ul;
1097                                 memcpy(((gs_sp_t)(*block))+pb->offset,&tmp_ull,sizeof(gs_uint64_t));
1098                                 break;
1099                         case llong_t:
1100 //                              tmp_ll = htonll(pb->value.r.l);
1101                                 tmp_ll = pb->value.r.l;
1102                                 memcpy(((gs_sp_t)(*block))+pb->offset,&tmp_ll,sizeof(gs_int64_t));
1103                                 break;
1104                         case floating_t:
1105 //                              tmp_f = ntohf(pb->value.r.f);
1106                                 tmp_f = pb->value.r.f;
1107                                 memcpy(((gs_sp_t)(*block))+pb->offset,&tmp_f,sizeof(gs_float_t));
1108                                 break;
1109                         case timeval_t:
1110 //                              tmp_tv.tv_sec = htonl(pb->value.r.t.tv_sec);
1111 //                              tmp_tv.tv_usec = htonl(pb->value.r.t.tv_usec);
1112                                 tmp_tv.tv_sec = pb->value.r.t.tv_sec;
1113                                 tmp_tv.tv_usec =pb->value.r.t.tv_usec;
1114                                 memcpy(((gs_sp_t)(*block))+pb->offset,&tmp_tv,sizeof(timeval));
1115                                 break;
1116                         case v_str_t:
1117 //                              tmp_vstr.offset = htonl(data_pos);
1118 //                              tmp_vstr.length = htonl(pb->value.r.vs.length);
1119                                 tmp_vstr.offset = data_pos;
1120                                 tmp_vstr.length = pb->value.r.vs.length;
1121 //                              tmp_vstr.reserved = htonl(pb->value.r.vs.reserved);
1122 //                              tmp_vstr.reserved = htonl(PACKED);
1123                                 tmp_vstr.reserved = PACKED;
1124                                 memcpy(((gs_sp_t)(*block))+pb->offset,&tmp_vstr,sizeof(vstring32));
1125                                 tmp_ptr = (void *)(pb->value.r.vs.offset);
1126                                 memcpy(((gs_sp_t)(*block))+data_pos, tmp_ptr, pb->value.r.vs.length);
1127                                 data_pos += pb->value.r.vs.length;
1128                                 break;
1129                 case fstring_t:
1130                         fprintf(stderr,"ERROR, fstring parameters not supported, use vstring.\n");
1131                         exit(1);
1132                         break;
1133                 case ipv6_t:
1134                         fprintf(stderr,"ERROR, ipv6_t parameters not supported.\n");
1135                         exit(1);
1136                         break;
1137                 case undefined_t:
1138                         fprintf(stderr,"INTERNAL ERROR undefined_t type in ftaschema_setparam_by_index\n");
1139                         exit(1);
1140                 default:
1141                         fprintf(stderr,"INTERNAL ERROR unknown type in ftaschema_create_param_block\n");
1142                         exit(1);
1143                 }
1144         }
1145         return(0);
1146
1147 }
1148
1149
1150 ///////////////////////////////////////////////////////////////
1151 //              Diagnostic functions
1152
1153 void ftaschema_debugdump(gs_int32_t handle){
1154         if(handle<0){
1155                 printf("ftaschema_debugdump: handle is negative.\n");
1156                 return;
1157         }
1158         if(handle >= schema_list.size()){
1159                 printf("ftaschema_debugdump: handle out of bounds (%d, max is %lu)\n",
1160                                 handle, schema_list.size());
1161         }
1162
1163         query_rep *q = schema_list[handle];
1164
1165         printf("Handle is %d, query name is <%s>\n",handle,q->name.c_str());
1166         printf("Output tuple has %lu fields:\n",q->field_info.size());
1167         int f;
1168         for(f=0;f<q->field_info.size();++f){
1169                 printf("\t%s (%s) : %d\n",q->field_info[f].field_name.c_str(),
1170                         (q->field_info[f].pdt->get_type_str()).c_str(),
1171                         q->field_info[f].offset
1172                         );
1173         }
1174         printf("Min tuple size is %d\n\n",q->min_tuple_size);
1175         printf("Param block is:\n");
1176         int p;
1177         for(p=0;p<q->param_info.size();++p){
1178                 printf("\t%s (%s) : %d\n",q->param_info[p].param_name.c_str(),
1179                         (q->param_info[p].pdt->get_type_str()).c_str(),
1180                         q->param_info[p].offset
1181                         );
1182         }
1183         printf("Min param block size is %d\n\n",q->min_param_size);
1184
1185
1186
1187 }
1188
1189