Add new udafs and RMR support to gsprintconsole_ves
[com/gs-lite.git] / src / ftacmp / parse_fta.h
1 /* ------------------------------------------------
2 Copyright 2020 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 #ifndef _FTA_PARSE_H_INCLUDED__
16 #define _FTA_PARSE_H_INCLUDED__
17
18 #include<stdio.h>
19 #include<ctype.h>
20
21         int yyparse();
22         void yyerror(char *s);
23         int yylex();
24 extern int flex_fta_lineno, flex_fta_ch;
25
26 /*              Interface to FTA Parser         */
27 void FtaParser_setfileinput(FILE *f);
28 void FtaParser_setstringinput(char *s);
29
30
31 /*              Get type defines.       */
32 #include"type_objects.h"
33 #include"literal_types.h"
34 #include"type_indicators.h"
35
36 #include <string>
37 #include <vector>
38 #include <map>
39 #include <math.h>
40 #include <string>
41 #include <stdio.h>
42 #include <stdlib.h>
43
44
45 //              colref_t::is_equivalent needs to understand the schema
46 #include"parse_schema.h"
47 class colref_t;
48
49
50
51 class var_pair_t{
52 public:
53   std::string name;
54   std::string val;
55
56   var_pair_t(char *n, char *v){
57         name=n; val=v;
58 //printf("NEW var_pair_t(%s, %s)\n",n,v);
59         };
60
61   var_pair_t(const std::string n, const std::string v){
62         name=n; val=v;
63         };
64 };
65
66 typedef std::map< std::string, std::string > ss_map;
67
68 class var_defs_t{
69 private:
70         std::vector<var_pair_t *> namevec;
71
72 public:
73         var_defs_t(var_pair_t *vp){
74                 namevec.push_back(vp);
75         };
76
77         var_defs_t *add_var_pair(var_pair_t *vp){
78                 namevec.push_back(vp);
79                 return(this);
80         };
81
82         std::vector<var_pair_t *> get_nvec(){return namevec;};
83
84         int size(){return namevec.size();};
85
86         int find_name(std::string n){
87                 int i;
88                 for(i=0;i<namevec.size();i++){
89                         if(namevec[i]->name == n)
90                                 return i;
91                 }
92                 return -1;
93         }
94         std::string get_name(int i){
95                 if(i>=0 && i<namevec.size()){
96                         return(namevec[i]->name);
97                 }else{
98                         return("");
99                 }
100         }
101
102         std::string get_def(int i){
103                 if(i>=0 && i<namevec.size()){
104                         return(namevec[i]->val);
105                 }else{
106                         return("");
107                 }
108         }
109
110         std::string dump(){
111                 int i;
112                 std::string ret;
113                 for(i=0;i<namevec.size();++i){
114                         ret += "\t"+namevec[i]->name+" = "+namevec[i]->val+"\n";
115                 }
116                 return ret;
117         }
118
119 };
120
121
122
123
124 //              literal type constants are defined in literal_types.h
125 //              (must share this info with type_objects.h)
126
127 //              Represents a literal, as expected
128 //              NOTE: this class contains some code generation methods.
129
130 class literal_t{
131 private:
132
133 public:
134         std::string lstring;            /* literal value */
135         short int ltype;                        /* literal type */
136         int lineno, charno;
137
138         int complex_literal_id; // if this literal has a complex constructor,
139                                                         // there is a function which constructs it)
140                                                         //set to the idx in the complex literal
141                                                         // table.  (Must store this here (instead of in SE)
142                                                         // because of bare literals in the IN predicate).
143
144
145         literal_t(std::string v){
146                 lstring = v;
147                 ltype = LITERAL_STRING;
148                 complex_literal_id = -1;
149                 lineno = flex_fta_lineno; charno = flex_fta_ch;
150         }
151         static literal_t *make_define_literal(const char *s, var_defs_t *d){
152                 int i;
153                 i=d->find_name(s);
154                 if(i<0){
155                         fprintf(stderr,"ERROR at line %d, char %d; DEFINE'd literal %s referenced but not in DEFINE block.\n",flex_fta_lineno, flex_fta_ch, s);
156                         exit(1);
157                 }
158                 return new literal_t(d->get_def(i));
159         }
160
161         literal_t(const char *lit, int t){lstring = lit; ltype = t;
162                 lineno = flex_fta_lineno; charno = flex_fta_ch;
163                 complex_literal_id = -1;
164
165 //              For some datatypes we need to modify literal so make a copy of the string
166                 char v[100];
167                 strcpy(v, lit);
168
169 //                      Remove UL, ULL suffix from INT constants.
170                 if(ltype == LITERAL_INT || ltype == LITERAL_LONGINT){
171                         int i;
172                         int len=strlen(v);
173                         for(i=0;i<len;++i){
174                                 if(v[i] == 'U') v[i] = '\0';
175                         }
176                         lstring = v;
177                 }
178
179 //                      HEX and LONGHEX must be converted to uint (long long uint)
180                 if(ltype == LITERAL_HEX){
181                         char *c,ltmpstr[100];
182                         unsigned long tmp_l;
183                         for(c=v; (*c)!='\0';++c){
184                                 if(! ( ((*c) >= '0' && (*c) <= '9') || (tolower(*c) >= 'a' && tolower(*c) <= 'f') ) ){
185                                         fprintf(stderr,"Syntax Error, line=%d, character=%d.  The literal %s is not a HEX constant.\n",
186                                                 lineno, charno, v);
187                                         exit(1);
188                                 }
189                         }
190                         sscanf(v,"%lx",&tmp_l);
191                         sprintf(ltmpstr,"%lu",tmp_l);
192                         lstring = ltmpstr;
193                         ltype = LITERAL_INT;
194                 }
195                 if(ltype == LITERAL_LONGHEX){
196                         char *c,ltmpstr[100];
197                         unsigned long long tmp_ll;
198                         for(c=v; (*c)!='\0';++c){
199                                 if(! ( ((*c) >= '0' && (*c) <= '9') || (tolower(*c) >= 'a' && tolower(*c) <= 'f') ) ){
200                                         fprintf(stderr,"Syntax Error, line=%d, character=%d.  The literal %s is not a LHEX constant.\n",
201                                                 lineno, charno, v);
202                                         exit(1);
203                                 }
204                         }
205                         sscanf(v,"%llx",&tmp_ll);
206                         sprintf(ltmpstr,"%llu",tmp_ll);
207                         lstring = ltmpstr;
208                         ltype = LITERAL_LONGINT;
209                 }
210 //                      Convert IP to uint
211                 if(ltype == LITERAL_IP){
212                         char ltmpstr[100];
213                         unsigned int o1,o2,o3,o4,tmp_l;
214                         if(sscanf(v,"%u.%u.%u.%u",&o1,&o2,&o3,&o4) != 4){
215                                         fprintf(stderr,"Syntax Error, line=%d, character=%d.  The literal %s is not an IP constant.\n",
216                                                 lineno, charno, v);
217                                         exit(1);
218                         }
219                         if( (o1>255) || (o2>255) || (o3>255) || (o4>255) ){
220                                         fprintf(stderr,"Syntax Error, line=%d, character=%d.  The literal %s is not an IP constant.\n",
221                                                 lineno, charno, v);
222                                         exit(1);
223                         }
224                         tmp_l = (o1<<24)+(o2<<16)+(o3<<8)+o4;
225                         sprintf(ltmpstr,"%u",tmp_l);
226                         lstring = ltmpstr;
227                         ltype = LITERAL_IP;
228                 }
229         };
230
231 //                      used to create literals with a default or initial value.
232         literal_t(int type_indicator){
233                 lineno=-1; charno=-1;
234                 complex_literal_id = -1;
235
236                 switch(type_indicator){
237                 case UINT_TYPE:
238                 case INT_TYPE:
239                 case USHORT_TYPE:
240                         ltype = LITERAL_INT;
241                         lstring = "0";
242                         break;
243                 case ULLONG_TYPE:
244                 case LLONG_TYPE:
245                         ltype = LITERAL_LONGINT;
246                         lstring = "0";
247                         break;
248                 case FLOAT_TYPE:
249                         ltype = LITERAL_FLOAT;
250                         lstring = "0.0";
251                         break;
252                 case BOOL_TYPE:
253                         ltype = LITERAL_BOOL;
254                         lstring = "FALSE";
255                         break;
256                 case VSTR_TYPE:
257                         ltype = LITERAL_STRING;
258                         lstring = ""; complex_literal_id = 0; // unregistred complex lit
259                         break;
260                 case TIMEVAL_TYPE:
261                         ltype = LITERAL_TIMEVAL;
262                         lstring = "0.0";
263                         break;
264                 case IPV6_TYPE:
265                         ltype = LITERAL_IPV6;
266                         lstring = "0000:0000:0000:0000:0000:0000:0000:0000";
267                         complex_literal_id = 0; // unregistered complex literal
268                         break;
269                 case IP_TYPE:
270                         ltype = LITERAL_IP;
271                         lstring = "0";
272                         break;
273                 default:
274                         ltype = LITERAL_UDEF;
275                         lstring=" INTERNAL ERROR, UNKNOWN TYPE INDICATOR IN literal_t::literal_t(int) ";
276                 }
277         };
278
279         std::string to_string(){return lstring;};
280
281         int get_type(){return ltype;    };
282         int get_lineno(){return lineno; };
283         int get_charno(){return charno; };
284
285         bool is_equivalent(literal_t *l2){
286                 if(ltype != l2->ltype)
287                         return(false);
288                 if(lstring != l2->lstring)
289                         return(false);
290
291                 return(true);
292         };
293
294 //                      Internal function to unescape control characters.
295         static std::string gsqlstr_to_cstr(std::string s){
296                 std::string retval;
297                 unsigned char c, prev_c='\0';
298                 int i;
299
300                 for(i=0;i<s.size();++i){
301                         c = s[i];
302                         if(c=='\''){            // || c=='\\'
303                                 if(prev_c==c){
304                                         retval += c;
305                                         prev_c = '\0';
306                                 }else{
307                                         prev_c=c;
308                                 }
309                                 continue;
310                         }
311
312                         retval += c;
313                         prev_c = c;
314                 }
315
316                 return retval;
317         }
318
319
320
321         std::string to_hfta_C_code(std::string param){
322                 std::string retval;
323                 double tmp_f;
324                 int secs, millisecs;
325                 char tmpstr[100];
326
327                 switch(ltype){
328                 case LITERAL_STRING:
329                         retval.append(this->hfta_constructor_name() );
330                         retval.append("("+param+",\"");
331                         retval.append(gsqlstr_to_cstr(lstring));
332                         retval.append("\")");
333                         return(retval);
334                 case LITERAL_INT:
335                 case LITERAL_IP:
336                         return("((gs_uint32_t)"+lstring+")");
337                 case LITERAL_LONGINT:
338                         return("((gs_uint64_t)"+lstring+")");
339                 case LITERAL_FLOAT:
340                         return(lstring);
341 //              case LITERAL_HEX:
342 //                      return("0x"+lstring);
343                 case LITERAL_BOOL:
344                         if(lstring == "TRUE"){
345                                 return("1");
346                         }else{
347                                 return("0");
348                         }
349                 case LITERAL_TIMEVAL:
350                         retval.append(this->hfta_constructor_name() );
351                         tmp_f = atof(lstring.c_str());
352                         secs = (int)floor(tmp_f);
353                         millisecs = (int) rint((tmp_f - secs)*1000);
354                         sprintf(tmpstr,"(%d, %d)",secs,millisecs);
355                         retval.append(tmpstr);
356                         return(retval);
357                 case LITERAL_IPV6:
358                         retval = this->hfta_constructor_name();
359                         retval += "("+param+",\""+lstring+"\")";
360                         return retval;
361                 }
362
363                 return("ERROR UNKNOWN LITERAL");
364         };
365
366
367 ///                     for LFTA code generation
368         std::string to_C_code(std::string param){
369                 std::string retval;
370                 double tmp_f;
371                 int secs, millisecs;
372                 char tmpstr[100];
373
374                 switch(ltype){
375                 case LITERAL_STRING:
376                         retval = this->constructor_name()+"("+param+",\""+gsqlstr_to_cstr(lstring)+"\")";
377                         return(retval);
378                 case LITERAL_INT:
379                 case LITERAL_IP:
380                         return("((gs_uint32_t)"+lstring+")");
381                 case LITERAL_LONGINT:
382                         return("((gs_uint64_t)"+lstring+")");
383                 case LITERAL_FLOAT:
384                         return(lstring);
385 //              case LITERAL_HEX:
386 //                      return("0x"+lstring);
387                 case LITERAL_BOOL:
388                         if(lstring == "TRUE"){
389                                 return("1");
390                         }else{
391                                 return("0");
392                         }
393                 case LITERAL_IPV6:
394                         retval = this->constructor_name()+"("+param+",\""+lstring+"\")";
395                         return(retval);
396                 case LITERAL_TIMEVAL:
397                         retval.append(this->constructor_name() );
398                         tmp_f = atof(lstring.c_str());
399                         secs = (int)floor(tmp_f);
400                         millisecs = (int) rint((tmp_f - secs)*1000);
401                         sprintf(tmpstr,"(%d, %d)",secs,millisecs);
402                         retval.append(tmpstr);
403                         return(retval);
404                 }
405
406                 return("ERROR UNKNOWN LITERAL");
407         };
408
409
410         std::string to_query_string(){
411                 std::string retval;
412
413                 switch(ltype){
414                 case LITERAL_IP:
415                 {
416                         unsigned int v;
417                         sscanf(lstring.c_str(),"%u",&v);
418                         int d1 = v & 0xff;
419                         int d2 = (v & 0xff00) >> 8;
420                         int d3 = (v & 0xff0000) >> 16;
421                         int d4 = (v & 0xff000000) >> 24;
422                         char ret[200];
423                         sprintf(ret,"IP_VAL'%u.%u.%u.%u'",d4,d3,d2,d1);
424                         return ret;
425                 }
426                 case LITERAL_STRING:
427                         retval = "'"+lstring+"'";
428                         return(retval);
429                 case LITERAL_INT:
430                 case LITERAL_FLOAT:
431                 case LITERAL_TIMEVAL:
432                 case LITERAL_IPV6:
433                 case LITERAL_BOOL:
434                         return(lstring);
435                 case LITERAL_LONGINT:
436                         return(lstring+"ULL");
437                 }
438
439                 return("ERROR UNKNOWN LITERAL in literal_t::to_query_string");
440         };
441
442 //              TODO : Use definition files instead of hardwiring these.
443
444 //              constructor in LFTA code
445         std::string constructor_name(){
446
447                 switch(ltype){
448                 case LITERAL_TIMEVAL:
449                         return("Timeval_Constructor");
450                 case LITERAL_IPV6:
451                         return("Ipv6_Constructor");
452                 case LITERAL_STRING:
453                         return("str_constructor");
454                 case LITERAL_INT:
455                 case LITERAL_IP:
456                 case LITERAL_LONGINT:
457                 case LITERAL_BOOL:
458                 case LITERAL_FLOAT:
459                         return("");
460                 }
461                 return("ERROR UNKNOWN LITERAL");
462         };
463
464         std::string hfta_constructor_name(){
465
466                 switch(ltype){
467                 case LITERAL_TIMEVAL:
468                         return("HFTA_Timeval_Constructor");
469                 case LITERAL_IPV6:
470                         return("HFTA_Ipv6_Constructor");
471                 case LITERAL_STRING:
472                         return("Vstring_Constructor");
473                 case LITERAL_INT:
474                 case LITERAL_IP:
475                 case LITERAL_LONGINT:
476                 case LITERAL_BOOL:
477                 case LITERAL_FLOAT:
478                         return("");
479                 }
480                 return("ERROR UNKNOWN LITERAL");
481         };
482
483         std::string hfta_empty_literal_name(){
484
485                 switch(ltype){
486                 case LITERAL_TIMEVAL:
487                         return("EmptyTimeval");
488                 case LITERAL_IPV6:
489                         return("EmptyIp6");
490                 case LITERAL_STRING:
491                         return("EmptyString");
492                 }
493                 return("ERROR_NOT_A_COMPLEX_LITERAL");
494         };
495
496
497         void set_cpx_lit_ref(int g){complex_literal_id = g;     };
498         int get_cpx_lit_ref(){return (complex_literal_id );     };
499         bool is_cpx_lit(){return(complex_literal_id  >= 0);     };
500
501 };
502
503
504 /*
505                 A (null terminated) list of literals.
506                 Used for the IN clause
507 */
508
509 class literal_list_t{
510 private:
511
512 public:
513         std::vector<literal_t *> lit_list;
514         int lineno, charno;
515
516         literal_list_t(literal_t *l){
517                 lit_list.push_back(l);
518                 lineno = flex_fta_lineno; charno = flex_fta_ch;
519         };
520
521         literal_list_t(std::vector<literal_t *> lvec){
522                 lineno = charno = 0;
523                 lit_list = lvec;
524         };
525
526         literal_list_t *append_literal(literal_t *l){
527                 lit_list.push_back(l);
528                 return(this);
529         };
530
531         std::string to_string(){
532                 int i;
533                 std::string retval;
534                 for(i=0;i<lit_list.size();i++){
535                         if(i>0) retval.append(", ");
536                         retval.append(lit_list[i]->to_query_string());
537                 }
538             return(retval);
539         };
540
541         std::vector<literal_t *> get_literal_vector(){return(lit_list);};
542
543 };
544
545
546 class string_t{
547 public:
548         std::string val;
549         string_t(char *s){
550                 val = s;
551         }
552         string_t *append(char *s){
553                 val += s;
554                 return this;
555         }
556         string_t *append(char *sep, char *s){
557                 val += sep;
558                 val += s;
559                 return this;
560         }
561         const char *c_str(){
562                 return val.c_str();
563         }
564 };
565
566 //              A tablevar is a data source in a GSQL query.
567 //              Every column ref must be bound to a tablevar,
568 //              either explicitly or via imputation.
569
570
571 class tablevar_t{
572 public:
573 //              A tablevar is a variable which binds to a named data source.
574 //              the variable name might be explicit in the query, or it might be
575 //              implicit in which case the variable name is imputed.  In either case
576 //              the variable name is set via the set_range_var method.
577 //
578 //              The data source is the name of either a STREAM or a PROTOCOL.
579 //              All STREAMS are unique, but a PROTOCOL must be bound to an
580 //              interface.  If the interface is not given, it is imputed to be
581 //              the default interface.
582
583         std::string machine;
584         std::string interface;
585         std::string schema_name;
586         std::string variable_name;
587         std::string udop_alias;         // record UDOP ID for of UDOP
588                                                                 // for use by cluster manager
589
590         int schema_ref;         // index of the table in the schema (table_list)
591         int opview_idx;         // index in list of operator views (if any)
592         bool iface_is_query;    // true if iface resolves to query
593                                                         // instead of specific interface.
594
595         int properties;         // inner (0) or outer (1) join;
596                                                 // labeled using FROM clause,
597                                                 // determines join algorithm.
598
599         int lineno, charno;
600
601         tablevar_t(){ opview_idx = -1; schema_ref=-1; iface_is_query = false;
602                                 lineno=-1; charno=-1;};
603         tablevar_t(const char *t){schema_name=t;  interface="";
604                 opview_idx = -1; schema_ref = -1;
605                 variable_name=""; properties = 0;
606                 iface_is_query = false;
607                 lineno = flex_fta_lineno; charno = flex_fta_ch;};
608
609         tablevar_t(const char *i, const char *s, int iq){interface=i; schema_name=s;
610                 opview_idx = -1; schema_ref = -1;
611                 variable_name=""; properties = 0;
612                 if(iq) iface_is_query = true; else iface_is_query = false;
613                 lineno = flex_fta_lineno; charno = flex_fta_ch;};
614
615         tablevar_t(const char *m, const char *i, const char *s){
616                 machine = m; interface=i; schema_name=s;
617                 opview_idx = -1; schema_ref = -1;
618                 variable_name=""; properties = 0;
619                 iface_is_query = false;
620                 lineno = flex_fta_lineno; charno = flex_fta_ch;};
621
622         tablevar_t *duplicate(){
623                 tablevar_t *ret = new tablevar_t();
624                 ret->lineno = lineno; ret->charno = charno;
625                 ret->schema_ref = schema_ref;
626                 ret->opview_idx = opview_idx;
627                 ret->machine = machine;
628                 ret->interface = interface;
629                 ret->schema_name = schema_name;
630                 ret->variable_name = variable_name;
631                 ret->properties = properties;
632                 ret->iface_is_query = iface_is_query;
633                 return(ret);
634         };
635
636         tablevar_t *set_range_var(const char *r){
637                 variable_name = r;
638                 return(this);
639         };
640         tablevar_t *set_range_var(std::string r){
641                 variable_name = r;
642                 return(this);
643         };
644
645         void set_schema(std::string s){schema_name = s;};
646         void set_interface(std::string i){interface=i;};
647         void set_machine(std::string m){machine = m;};
648         void set_udop_alias(std::string u){udop_alias = u;};
649
650         void set_schema_ref(int r){schema_ref = r;};
651         int get_schema_ref(){return schema_ref;};
652
653         void set_opview_idx(int i){opview_idx = i;};
654         int get_opview_idx(){return opview_idx;};
655
656         void set_property(int p){properties = p;};
657         int get_property(){return properties;};
658
659         bool get_ifq(){return iface_is_query;};
660     void set_ifq(bool b){iface_is_query = b;};
661
662         std::string to_string(){
663                 std::string retval;
664
665                 if(machine != "" && !iface_is_query)
666                         retval += "'"+machine+"'.";
667                 if(interface != ""){
668                         if(iface_is_query){
669                          retval += '['+interface+"].";
670                         }else{
671                          retval += interface+".";
672                         }
673                 }
674                 retval += schema_name;
675                 if(variable_name != "") retval+=" "+variable_name;
676
677                 return(retval);
678         };
679
680         std::string get_schema_name(){return schema_name;};
681         void set_schema_name(std::string n){schema_name=n;}; // DUPLICATE with set_shema
682         std::string get_var_name(){return variable_name;};
683         std::string get_interface(){return interface;};
684         std::string get_machine(){return machine;};
685         std::string get_udop_alias(){return udop_alias;};
686
687         int get_lineno(){return(lineno);        };
688         int get_charno(){return(charno);        };
689
690 };
691
692 #define INNER_JOIN_PROPERTY 0
693 #define LEFT_OUTER_JOIN_PROPERTY 1
694 #define RIGHT_OUTER_JOIN_PROPERTY 2
695 #define OUTER_JOIN_PROPERTY 3
696 #define WATCHLIST_JOIN_PROPERTY 4
697 #define FILTER_JOIN_PROPERTY 5
698
699 //              tablevar_list_t is the list of tablevars in a FROM clause
700
701 struct tablevar_list_t{
702 public:
703         std::vector<tablevar_t *> tlist;
704         int properties;
705         int lineno, charno;
706 //              For filter join
707         colref_t *temporal_var;
708         unsigned int temporal_range;
709
710         tablevar_list_t(){properties = -1; temporal_var = NULL;}
711         tablevar_list_t(tablevar_t *t){tlist.push_back(t); properties=-1; temporal_var = NULL;
712                 lineno = flex_fta_lineno; charno = flex_fta_ch;};
713         tablevar_list_t(std::vector<tablevar_t *> t){tlist = t; properties=-1; temporal_var = NULL;
714                 lineno = 0; charno = 0;};
715
716         tablevar_list_t *duplicate(){
717                 tablevar_list_t *ret = new tablevar_list_t();
718                 ret->lineno = lineno; ret->charno = charno;
719                 ret->properties = properties;
720                 ret->temporal_var = temporal_var;
721                 ret->temporal_range = temporal_range;
722                 int i;
723                 for(i=0;i<tlist.size();++i){
724                         ret->append_table(tlist[i]->duplicate());
725                 }
726                 return(ret);
727         }
728
729
730
731         tablevar_list_t *append_table(tablevar_t *t){
732                 tlist.push_back(t);
733                 return(this);
734         };
735
736         std::string to_string(){
737                 int i;
738                 std::string retval;
739
740                 for(i=0;i<tlist.size();i++){
741                         if(i>0) retval.append(", ");
742                         retval.append(tlist[i]->to_string());
743                 }
744                 return(retval);
745         };
746
747         std::vector<tablevar_t *> get_table_list(){return(tlist);       };
748
749         std::vector<std::string> get_table_names(){
750                 std::vector<std::string> ret;
751                 int t;
752                 for(t=0;t<tlist.size();++t){
753                         std::string tbl_name = tlist[t]->get_schema_name();
754                         ret.push_back(tbl_name);
755                 }
756                 return(ret);
757         }
758
759         std::vector<std::string> get_src_tbls(table_list *Schema){
760                 std::vector<std::string> ret;
761                 int t, sq;
762                 for(t=0;t<tlist.size();++t){
763                         std::string tbl_name = tlist[t]->get_schema_name();
764                         int sid = Schema->find_tbl(tbl_name);
765                         if(sid < 0){ ret.push_back(tbl_name);
766                         }else
767                         if(Schema->get_schema_type(sid) != OPERATOR_VIEW_SCHEMA){
768                                 ret.push_back(tbl_name);
769                         }else{
770                                 std::vector<subquery_spec *> sqspec = Schema->get_subqueryspecs(sid);
771                                 for(sq=0;sq<sqspec.size();++sq){
772                                         ret.push_back(sqspec[sq]->name);
773                                 }
774                         }
775                 }
776                 return(ret);
777         };
778
779         int size(){
780                 return tlist.size();
781         };
782
783 //              Some accessor functions.
784
785         std::vector<std::string> get_schema_names(){
786                 int i;
787                 std::vector<std::string > retval;
788                 for(i=0;i<tlist.size();i++){
789                         retval.push_back(tlist[i]->get_schema_name());
790                 }
791                 return(retval);
792         }
793
794         std::vector<int> get_schema_refs(){
795                 int i;
796                 std::vector<int> retval;
797                 for(i=0;i<tlist.size();i++){
798                         retval.push_back(tlist[i]->get_schema_ref());
799                 }
800                 return(retval);
801         }
802
803
804         int get_schema_ref(int i){
805                 if(i<0 || i>=tlist.size()) return(-1);
806                 return tlist[i]->get_schema_ref();
807         };
808
809         std::string get_tablevar_name(int i){
810                 if(i<0 || i>=tlist.size()) return("");
811                 return tlist[i]->get_var_name();
812         };
813
814         void set_properties(int p){properties = p;};
815         int get_properties(){return properties;};
816
817         void set_colref(colref_t *c){temporal_var = c;};
818         void set_temporal_range(unsigned int t){temporal_range = t;};
819         void set_temporal_range(const char *t){temporal_range= atoi(t);};
820         colref_t *get_colref(){return temporal_var;};
821         unsigned int get_temporal_range(){return temporal_range;};
822
823 };
824
825 //                      A reference to an interface parameter.
826 //                      (I need to be able to record the source
827 //                       tablevar, else this would be a lot simpler).
828 class ifpref_t{
829 public:
830         std::string tablevar;
831         std::string pname;
832         int tablevar_ref;
833         int lineno, charno;
834
835         ifpref_t(const char *p){
836                 tablevar="";
837                 pname = p;
838                 tablevar_ref = -1;
839                 lineno = flex_fta_lineno; charno = flex_fta_ch;
840         };
841
842         ifpref_t(const char *t, const char *p){
843                 tablevar=t;
844                 pname = p;
845                 tablevar_ref = -1;
846                 lineno = flex_fta_lineno; charno = flex_fta_ch;
847         };
848
849         void set_tablevar_ref(int i){tablevar_ref = i;};
850         int get_tablevar_ref(){return tablevar_ref;};
851         std::string get_tablevar(){return tablevar;}
852         void set_tablevar(std::string t){tablevar = t;};
853         std::string get_pname(){return pname;}
854         std::string to_string(){
855                 std::string ret;
856                 if(tablevar != "")
857                         ret += tablevar + ".";
858                 ret += "@"+pname;
859                 return ret;
860         };
861         bool is_equivalent(ifpref_t *i){
862                 return (tablevar_ref == i->tablevar_ref) && (pname == i->pname);
863         };
864 };
865
866
867
868
869 //                      A representation of a reference to a field of a
870 //                      stream (or table).  This reference must be bound
871 //                      to a particular schema (schema_ref) and to a
872 //                      particular table variable in the FROM clause (tablevar_ref)
873 //                      If the column reference was generated by the parser,
874 //                      it will contain some binding text wich might need
875 //                      interpretation to do the actual binding.
876 class colref_t{
877 public:
878         std::string interface;          // specified interface, if any.
879         std::string table_name;         // specified table name or range var, if any.
880         std::string field;                      // field name
881         bool default_table;                     // true iff. no table or range var given.
882         int schema_ref;                         // ID of the source schema.
883         int tablevar_ref;                       // ID of the tablevar (in FROM clause).
884         int lineno, charno;
885
886         colref_t(const char *f){
887                 field = f; default_table = true;
888                 schema_ref = -1; tablevar_ref = -1;
889                 lineno = flex_fta_lineno; charno = flex_fta_ch;
890         };
891
892         colref_t(const char *t, const char *f){
893                 table_name = t; field=f; default_table = false;
894                 schema_ref = -1; tablevar_ref = -1;
895                 lineno = flex_fta_lineno; charno = flex_fta_ch;
896         };
897
898         colref_t(const char *i, const char *t, const char *f){
899                 interface=i;
900                 table_name = t; field=f; default_table = false;
901                 schema_ref = -1; tablevar_ref = -1;
902                 lineno = flex_fta_lineno; charno = flex_fta_ch;
903         };
904
905         colref_t *duplicate(){
906                 colref_t *retval = new colref_t(interface.c_str(), table_name.c_str(), field.c_str());
907                 retval->schema_ref = schema_ref;
908                 retval->tablevar_ref = tablevar_ref;
909                 retval->lineno = lineno;
910                 retval->charno = charno;
911                 retval->default_table = default_table;
912                 return(retval);
913         }
914
915         std::string to_string(){
916                 if(default_table){
917                         return field;
918                 }else{
919                         if(interface != "") return(interface+"."+table_name+"."+field);
920                         return(table_name + "." + field);
921                 }
922         };
923
924         std::string to_query_string(){
925                 if(default_table){
926                         return field;
927                 }else{
928                         if(interface != "") return(interface+"."+table_name+"."+field);
929                         if(table_name != "") return(table_name + "." + field);
930                         return(field);
931                 }
932         };
933
934         int get_lineno(){return lineno; };
935         int get_charno(){return charno; };
936
937         bool uses_default_table(){return default_table; };
938
939         std::string get_field(){return(field);  };
940         void set_field(std::string f){field=f;};
941         std::string get_table_name(){return(table_name);};
942         std::string get_interface(){return(interface);};
943         void set_table_name(std::string t){table_name = t; default_table=false;};
944         void set_interface(std::string i){interface=i;};
945
946         int get_schema_ref(){return schema_ref;}
947         void set_schema_ref(int s){schema_ref = s;};
948         int get_tablevar_ref(){return tablevar_ref;}
949         void set_tablevar_ref(int s){tablevar_ref = s;};
950
951 //                      Should equivalence be based on tablevar_ref or schema_ref?
952         bool is_equivalent(colref_t *c2){
953                 if(schema_ref == c2->schema_ref){
954                         return(field == c2->field);
955                 }
956                 return(false);
957         };
958
959         bool is_equivalent_base(colref_t *c2, table_list *Schema){
960                 if(Schema->get_basetbl_name(schema_ref,field) ==
961                    Schema->get_basetbl_name(c2->schema_ref,c2->field)){
962                         return(field == c2->field);
963                 }
964                 return(false);
965         };
966 };
967
968 class colref_list_t{
969 public:
970         std::vector<colref_t *> clist;
971
972 //      colref_list_t(){};
973
974         colref_list_t(colref_t *c){
975                 clist.push_back(c);
976         }
977
978         colref_list_t *append(colref_t *c){
979                 clist.push_back(c);
980                 return this;
981         }
982
983         std::vector<colref_t *> get_clist(){
984                 return clist;
985         }
986 };
987
988
989
990
991
992
993 /*
994                 A tree containing a scalar expression.
995                         Used for
996                                 atom : a parameter or a literal
997                                 scalar_exp (see the scalar_exp: rule in emf.l for details)
998                                 function_ref (a function that has a value, e.g. an aggregate
999                                                                 function).
1000                 operator_type defines the contents of the node.  If its a non-terminal,
1001                 then op has a meaning and defines the operation.  See the list of
1002                 #define'd constants following the structure definition.
1003
1004
1005 */
1006
1007 #define SE_LITERAL 1
1008 #define SE_PARAM 2
1009 #define SE_COLREF 3
1010 #define SE_UNARY_OP 4
1011 #define SE_BINARY_OP 5
1012 #define SE_AGGR_STAR 6
1013 #define SE_AGGR_SE 7
1014 #define SE_FUNC 8
1015 #define SE_IFACE_PARAM 9
1016
1017
1018 class scalarexp_t{
1019 public:
1020         int operator_type;
1021         std::string op;
1022         union{
1023                 scalarexp_t *scalarp;
1024                 literal_t *litp;
1025                 colref_t *colref;
1026                 ifpref_t *ifp;
1027         } lhs;
1028         union{
1029                 scalarexp_t *scalarp;
1030         } rhs;
1031         std::vector<scalarexp_t *> param_list;
1032
1033 //              SE node decorations -- results of query analysis.
1034         data_type *dt;
1035         int gb_ref;                             // set to the gb attr tbl ref, else -1
1036         int aggr_id;                    // set to the aggr tbl ref, else -1
1037         int fcn_id;                             // external function table ref, else -1
1038         int partial_ref;                // partial fcn table ref, else -1
1039         int fcn_cache_ref;              // function cache ref, else -1
1040         int handle_ref;                 // Entry in pass-by-handle parameter table, else -1.
1041                                                         // (might be a literal or a query param).
1042         bool is_superagg;               // true if is aggregate and associated with supergroup.
1043         std::string storage_state;      // storage state of stateful fcn,
1044                                                                 // empty o'wise.
1045
1046         int lineno, charno;
1047
1048         void default_init(){
1049                 operator_type = 0;
1050                 gb_ref = -1; aggr_id = -1;      fcn_id = -1;
1051                 partial_ref = -1; fcn_cache_ref=-1;
1052                 handle_ref = -1;
1053                 dt = NULL; lineno = flex_fta_lineno; charno = flex_fta_ch;
1054                 is_superagg = false;
1055                 };
1056
1057         scalarexp_t(){
1058                 default_init();};
1059
1060         scalarexp_t(colref_t *c){
1061                 default_init();
1062                 operator_type = SE_COLREF;
1063                 lhs.colref = c;
1064         };
1065
1066         scalarexp_t(literal_t *l){
1067                 default_init();
1068                 operator_type = SE_LITERAL;
1069                 lhs.litp = l;
1070         };
1071
1072         void convert_to_literal(literal_t *l){
1073 //              default_init();
1074                 if(operator_type != SE_IFACE_PARAM){
1075                         fprintf(stderr,"INTERNAL ERROR in literal_t::convert_to_literal, operator type isn't SE_IFACE_PARAM.\n");
1076                         exit(1);
1077                 }
1078                 operator_type = SE_LITERAL;
1079                 lhs.litp = l;
1080         }
1081
1082         scalarexp_t(const char *o, scalarexp_t *operand){
1083                 default_init();
1084                 operator_type = SE_UNARY_OP;
1085                 op = o;
1086                 lhs.scalarp = operand;
1087         };
1088
1089         scalarexp_t(const char *o, scalarexp_t *l_op, scalarexp_t *r_op){
1090                 default_init();
1091                 operator_type = SE_BINARY_OP;
1092                 op = o;
1093                 lhs.scalarp = l_op;
1094                 rhs.scalarp = r_op;
1095         };
1096
1097         scalarexp_t(const char *o, std::vector<scalarexp_t *> op_list){
1098                 default_init();
1099                 operator_type = SE_FUNC;
1100                 op = o;
1101                 param_list = op_list;
1102         };
1103
1104         static scalarexp_t *make_paramless_fcn(const char *o){
1105                 scalarexp_t *ret = new scalarexp_t();
1106                 ret->operator_type = SE_FUNC;
1107                 ret->op = o;
1108                 return(ret);
1109         };
1110
1111         static scalarexp_t *make_star_aggr(const char *ag){
1112                 scalarexp_t *ret = new scalarexp_t();
1113                 ret->operator_type = SE_AGGR_STAR;
1114                 ret->op = ag;
1115                 return(ret);
1116         };
1117
1118         static scalarexp_t *make_se_aggr(const char *ag, scalarexp_t *l_op){
1119                 scalarexp_t *ret = new scalarexp_t();
1120                 ret->operator_type = SE_AGGR_SE;
1121                 ret->op = ag;
1122                 ret->lhs.scalarp = l_op;
1123                 return(ret);
1124         };
1125
1126         static scalarexp_t *make_param_reference(const char *param){
1127                 scalarexp_t *ret = new scalarexp_t();
1128                 ret->operator_type = SE_PARAM;
1129                 ret->op = param;
1130                 return(ret);
1131         };
1132
1133         static scalarexp_t *make_iface_param_reference(ifpref_t *i){
1134                 scalarexp_t *ret = new scalarexp_t();
1135                 ret->operator_type = SE_IFACE_PARAM;
1136                 ret->lhs.ifp = i;
1137                 return(ret);
1138         };
1139
1140
1141         std::string to_string(){
1142                 if(operator_type == SE_COLREF){
1143                         return lhs.colref->to_string();
1144                 }
1145                 if(operator_type == SE_LITERAL){
1146                         return lhs.litp->to_string();
1147                 }
1148                 if(operator_type == SE_UNARY_OP){
1149                         return op + " (" + lhs.scalarp->to_string() + ")";
1150                 }
1151                 if(operator_type == SE_BINARY_OP){
1152                         return "(" + lhs.scalarp->to_string() + " " + op + " " + rhs.scalarp->to_string() + ")";
1153                 }
1154                 return("");
1155         };
1156
1157         scalarexp_t *get_left_se(){return lhs.scalarp;  };
1158         scalarexp_t *get_right_se(){return rhs.scalarp; };
1159         int get_operator_type(){return operator_type;   };
1160         std::string & get_op(){return op;       };
1161         std::string & get_param_name(){return op;       };
1162 //      std::string & get_iface_param_name(){return op; };
1163         colref_t *get_colref(){return lhs.colref;       };
1164         ifpref_t *get_ifpref(){return lhs.ifp;  };
1165         literal_t *get_literal(){return lhs.litp;       };
1166
1167         int get_lineno(){return lineno; };
1168         int get_charno(){return charno; };
1169
1170         void set_data_type(data_type *d){dt=d;  };
1171         data_type *get_data_type(){return dt;   };
1172         void reset_temporal(){if(dt!=NULL) dt->reset_temporal();}
1173
1174         void set_gb_ref(int g){gb_ref = g;      };
1175         int get_gb_ref(){return (gb_ref);       };
1176         bool is_gb(){return(gb_ref >= 0);       };
1177
1178         void set_aggr_id(int a){aggr_id = a;};
1179         int get_aggr_ref(){return(aggr_id);     };
1180
1181         void set_storage_state(std::string s){storage_state = s;};
1182         std::string get_storage_state(){return storage_state;};
1183
1184         std::vector<scalarexp_t *> get_operands(){return param_list;};
1185         void set_fcn_id(int f){fcn_id = f;      };
1186         int get_fcn_id(){return fcn_id; };
1187
1188         void set_partial_ref(int p){partial_ref = p;    };
1189         int get_partial_ref(){return partial_ref;       };
1190         bool is_partial(){return partial_ref >= 0;      };
1191
1192         void set_fcncache_ref(int p){fcn_cache_ref = p; };
1193         int get_fcncache_ref(){return fcn_cache_ref;    };
1194         bool is_fcncached(){return fcn_cache_ref >= 0;  };
1195
1196         void set_handle_ref(int tf){handle_ref = tf;    };
1197         int get_handle_ref(){return handle_ref; };
1198         bool is_handle_ref(){return handle_ref>=0;      };
1199
1200         void set_superaggr(bool b){is_superagg=b;};
1201         bool is_superaggr(){return is_superagg;};
1202
1203         void use_decorations_of(scalarexp_t *se){
1204                 if(se->get_data_type() != NULL)
1205                         dt = se->get_data_type()->duplicate();
1206                 gb_ref = se->gb_ref;
1207                 aggr_id = se->aggr_id;
1208                 fcn_id = se->fcn_id;
1209                 partial_ref = se->partial_ref;
1210                 handle_ref = se->handle_ref;
1211                 lineno = se->lineno;
1212                 charno = se->charno;
1213                 is_superagg = se->is_superagg;
1214         };
1215 };
1216
1217
1218 /*
1219                 A (null terminated) list of scalar expressions.
1220                 Used for
1221                         selection, scalar_exp_commalist
1222 */
1223
1224 class se_list_t{
1225 public:
1226         std::vector<scalarexp_t *> se_list;
1227         int lineno, charno;
1228
1229         se_list_t(scalarexp_t *s){se_list.push_back(s);
1230                 lineno = flex_fta_lineno; charno = flex_fta_ch;};
1231
1232         se_list_t *append(scalarexp_t *s){
1233                         se_list.push_back(s);
1234                         return(this);
1235         };
1236
1237         std::string to_string(){
1238                 int i;
1239                 std::string retval;
1240                 for(i=0;i<se_list.size();i++){
1241                         if(i>0) retval.append(", ");
1242                         retval.append(se_list[i]->to_string());
1243                 }
1244                 return(retval);
1245         };
1246
1247         std::vector<scalarexp_t *> get_se_list(){return se_list;        };
1248
1249
1250 };
1251
1252 /*
1253                 select_commalist : collect some additional info about
1254                 the selected things -- mostly the name.
1255 */
1256
1257 struct select_element{
1258         scalarexp_t *se;
1259         std::string name;
1260
1261         select_element(){se=NULL; name="";};
1262         select_element(scalarexp_t *s){se=s; name="";};
1263         select_element(scalarexp_t *s, std::string n){se=s; name=n;};
1264 };
1265
1266 class select_list_t{
1267 public:
1268         std::vector<select_element *> select_list;
1269         int lineno, charno;
1270
1271         select_list_t(){lineno = -1; charno = -1;};
1272         select_list_t(scalarexp_t *s){select_list.push_back(new select_element(s));
1273                 lineno = flex_fta_lineno; charno = flex_fta_ch;};
1274         select_list_t(scalarexp_t *s, std::string n){
1275                 select_list.push_back(new select_element(s,n));
1276                 lineno = flex_fta_lineno; charno = flex_fta_ch;
1277         };
1278         select_list_t *append(scalarexp_t *s){
1279                         select_list.push_back(new select_element(s));
1280                         return(this);
1281         };
1282         select_list_t *append(scalarexp_t *s, std::string n){
1283                         select_list.push_back(new select_element(s,n));
1284                         return(this);
1285         };
1286
1287         std::string to_string(){
1288                 int i;
1289                 std::string retval;
1290                 for(i=0;i<select_list.size();i++){
1291                         if(i>0) retval.append(", ");
1292                         retval.append(select_list[i]->se->to_string());
1293                         if(select_list[i]->name != "")
1294                                 retval += " AS " + select_list[i]->name;
1295
1296                 }
1297                 return(retval);
1298         };
1299
1300         std::vector<select_element *> get_select_list(){return select_list;     };
1301         std::vector<scalarexp_t *> get_select_se_list(){
1302                 std::vector<scalarexp_t *> ret;
1303                 int i;
1304                 for(i=0; i<select_list.size();++i) ret.push_back(select_list[i]->se);
1305                 return ret;
1306         };
1307 };
1308
1309
1310
1311 #define GB_COLREF 1
1312 #define GB_COMPUTED 2
1313
1314 class gb_t{
1315 public:
1316         std::string name;
1317         std::string table;
1318         std::string interface;
1319         scalarexp_t *def;
1320         int type;
1321         int lineno, charno;
1322
1323         gb_t(const char *field_name){
1324                 interface="";
1325                 name = field_name; table=""; def=NULL; type=GB_COLREF;
1326                 lineno = flex_fta_lineno; charno = flex_fta_ch;
1327         };
1328
1329         gb_t(const char *table_name, const char *field_name){
1330                 interface="";
1331                 name = field_name; table=""; def=NULL; type=GB_COLREF;
1332                 lineno = flex_fta_lineno; charno = flex_fta_ch;
1333         };
1334
1335         gb_t(const char *iface, const char *table_name, const char *field_name){
1336                 interface=iface;
1337                 name = field_name; table=""; def=NULL; type=GB_COLREF;
1338                 lineno = flex_fta_lineno; charno = flex_fta_ch;
1339         };
1340
1341         gb_t( scalarexp_t *s, const char *gname){
1342                 name = gname; table = ""; def = s; type = GB_COMPUTED;
1343                 lineno = flex_fta_lineno; charno = flex_fta_ch;
1344         };
1345
1346         std::string to_string(){
1347                 std::string retval;
1348                 if(type == GB_COLREF){
1349                         if(table != ""){
1350                                 retval = table;
1351                                 retval.append(".");
1352                         }
1353                         retval.append(name);
1354                 }
1355                 if(type == GB_COMPUTED){
1356                         retval = "(scalarexp) AS ";
1357                         retval.append(name);
1358                 }
1359                 return(retval);
1360         };
1361
1362         gb_t *duplicate();
1363
1364 };
1365
1366 /*
1367                 A (null terminated) list of group by attributes
1368 */
1369
1370 class gb_list_t{
1371 public:
1372         std::vector<gb_t *> gb_list;
1373         int lineno, charno;
1374
1375         gb_list_t(gb_t *g){gb_list.push_back(g);
1376                 lineno = flex_fta_lineno; charno = flex_fta_ch;};
1377
1378         gb_list_t *append(gb_t *s){
1379                         gb_list.push_back(s);
1380                         return(this);
1381         };
1382         gb_list_t(int l, int c) : lineno(l), charno(c){ }
1383
1384         std::string to_string(){
1385                 int i;
1386                 std::string retval;
1387                 for(i=0;i<gb_list.size();i++){
1388                         if(i>0) retval.append(", ");
1389                         retval.append(gb_list[i]->to_string());
1390                 }
1391                 return(retval);
1392         };
1393
1394         std::vector<gb_t *> get_gb_list(){return gb_list;       };
1395
1396         gb_list_t *duplicate(){
1397                 gb_list_t *ret = new gb_list_t(lineno, charno);
1398                 int i;
1399                 for(i=0;i<gb_list.size();++i){
1400                         ret->append(gb_list[i]->duplicate());
1401                 }
1402
1403                 return ret;
1404         }
1405
1406
1407 };
1408
1409 class list_of_gb_list_t{
1410 public:
1411         std::vector<gb_list_t *> gb_lists;
1412
1413         list_of_gb_list_t(gb_list_t *gl){
1414                 gb_lists.push_back(gl);
1415         }
1416
1417         list_of_gb_list_t *append(gb_list_t *gl){
1418                 gb_lists.push_back(gl);
1419                 return this;
1420         }
1421 };
1422
1423
1424 enum extended_gb_type {no_egb_type, gb_egb_type, rollup_egb_type,
1425                         cube_egb_type, gsets_egb_type};
1426 class extended_gb_t{
1427 public:
1428
1429         extended_gb_type type;
1430         gb_t *gb;
1431         std::vector<gb_list_t *> gb_lists;
1432
1433         extended_gb_t(){
1434                 gb = NULL;
1435                 type = no_egb_type;
1436         }
1437
1438         ~extended_gb_t(){
1439         }
1440
1441         static extended_gb_t *create_from_gb(gb_t *g){
1442                 extended_gb_t *ret  = new extended_gb_t();
1443                 ret->type = gb_egb_type;
1444                 ret->gb = g;
1445                 return ret;
1446         }
1447
1448         static extended_gb_t *extended_create_from_rollup(gb_list_t *gl){
1449                 extended_gb_t *ret  = new extended_gb_t();
1450                 ret->type = rollup_egb_type;
1451                 ret->gb_lists.push_back(gl);
1452                 return ret;
1453         }
1454
1455         static extended_gb_t *extended_create_from_cube(gb_list_t *gl){
1456                 extended_gb_t *ret  = new extended_gb_t();
1457                 ret->type = cube_egb_type;
1458                 ret->gb_lists.push_back(gl);
1459                 return ret;
1460         }
1461
1462         static extended_gb_t *extended_create_from_gsets(list_of_gb_list_t *lgl){
1463                 extended_gb_t *ret  = new extended_gb_t();
1464                 ret->type = gsets_egb_type;
1465                 ret->gb_lists = lgl->gb_lists;
1466                 return ret;
1467         }
1468
1469         extended_gb_t *duplicate(){
1470                 extended_gb_t *ret = new extended_gb_t();
1471                 ret->type = type;
1472                 if(gb != NULL)
1473                         ret->gb = gb->duplicate();
1474                 int i;
1475                 for(i=0;i<gb_lists.size();++i){
1476                         ret->gb_lists.push_back(gb_lists[i]->duplicate());
1477                 }
1478                 return ret;
1479         }
1480
1481
1482         std::string to_string(){
1483                 std::string ret;
1484                 int i;
1485
1486                 switch(type){
1487                 case no_egb_type:
1488                         return "Error, undefined extended gb type.";
1489                 case gb_egb_type:
1490                         return gb->to_string();
1491                 case rollup_egb_type:
1492                         return "ROLLUP("+gb_lists[0]->to_string()+")";
1493                 case cube_egb_type:
1494                         return "CUBE("+gb_lists[0]->to_string()+")";
1495                 case gsets_egb_type:
1496                         ret = "GROUPING_SETS(";
1497                         for(i=0;i<gb_lists.size();++i){
1498                                 if(i>0) ret+=", ";
1499                                 ret += "(" +gb_lists[i]->to_string()+")";
1500                         }
1501                         ret += ")";
1502                         return ret;
1503                 default:
1504                         break;
1505                 }
1506                 return "Error, unknown extended gb type.";
1507         }
1508
1509 };
1510
1511 class extended_gb_list_t{
1512 public:
1513         std::vector<extended_gb_t *> gb_list;
1514         int lineno, charno;
1515
1516         extended_gb_list_t(extended_gb_t *g){gb_list.push_back(g);
1517                 lineno = flex_fta_lineno; charno = flex_fta_ch;};
1518
1519         extended_gb_list_t *append(extended_gb_t *s){
1520                         gb_list.push_back(s);
1521                         return(this);
1522         };
1523
1524         std::string to_string(){
1525                 int i;
1526                 std::string retval;
1527                 for(i=0;i<gb_list.size();i++){
1528                         if(i>0) retval.append(", ");
1529                         retval.append(gb_list[i]->to_string());
1530                 }
1531                 return(retval);
1532         };
1533
1534         std::vector<extended_gb_t *> get_gb_list(){return gb_list;      };
1535 };
1536
1537
1538
1539 /*
1540                 A predicate tree.  Structure is similar to
1541                 a scalar expression tree but the type is always boolean.
1542                 Used by
1543                         opt_where_clause, where_clause, opt_having_clause,
1544                         search_condition, predicate, comparison_predicate, repl_predicate
1545 */
1546
1547 #define PRED_COMPARE 1
1548 #define PRED_UNARY_OP 2
1549 #define PRED_BINARY_OP 3
1550 #define PRED_FUNC 4
1551 #define PRED_IN 5
1552
1553 class  predicate_t{
1554 public:
1555         int operator_type;
1556         std::string op;
1557         union {
1558                 predicate_t *predp;
1559                 scalarexp_t *sexp;
1560         }lhs;
1561         union {
1562                 predicate_t *predp;
1563                 scalarexp_t *sexp;
1564                 literal_list_t *ll;
1565         }rhs;
1566         std::vector<scalarexp_t *> param_list;  /// pred fcn params
1567         int fcn_id;                                                             /// external pred fcn id
1568         int combinable_ref;
1569         bool is_sampling_fcn;
1570         int lineno, charno;
1571
1572         predicate_t(scalarexp_t *s, literal_list_t *litl){
1573                 operator_type = PRED_IN;
1574                 op = "in";
1575                 lhs.sexp = s;
1576                 rhs.ll = litl;
1577                 fcn_id = -1;
1578                 combinable_ref = -1;
1579                 lineno = flex_fta_lineno; charno = flex_fta_ch;
1580         };
1581
1582         predicate_t(scalarexp_t *s, std::vector<literal_t *> litv){
1583                 operator_type = PRED_IN;
1584                 op = "in";
1585                 lhs.sexp = s;
1586                 rhs.ll = new literal_list_t(litv);
1587                 fcn_id = -1;
1588                 combinable_ref = -1;
1589                 lineno = flex_fta_lineno; charno = flex_fta_ch;
1590         };
1591
1592
1593         predicate_t(scalarexp_t *l_op, const char *o, scalarexp_t *r_op){
1594                 operator_type = PRED_COMPARE;
1595                 op = o;
1596                 lhs.sexp = l_op;
1597                 rhs.sexp = r_op;
1598                 fcn_id = -1;
1599                 combinable_ref = -1;
1600                 lineno = flex_fta_lineno; charno = flex_fta_ch;
1601         };
1602
1603         predicate_t(const char *o, predicate_t *p){
1604                 operator_type = PRED_UNARY_OP;
1605                 op = o;
1606                 lhs.predp = p;
1607                 fcn_id = -1;
1608                 combinable_ref = -1;
1609                 lineno = flex_fta_lineno; charno = flex_fta_ch;
1610         };
1611
1612         predicate_t(const char *o, predicate_t *l_p, predicate_t *r_p){
1613                 operator_type = PRED_BINARY_OP;
1614                 op = o;
1615                 lhs.predp = l_p;
1616                 rhs.predp = r_p;
1617                 fcn_id = -1;
1618                 combinable_ref = -1;
1619                 lineno = flex_fta_lineno; charno = flex_fta_ch;
1620         };
1621
1622         predicate_t(const char *o, std::vector<scalarexp_t *> op_list){
1623                 operator_type = PRED_FUNC;
1624                 op = o;
1625                 param_list = op_list;
1626                 fcn_id = -1;
1627                 combinable_ref = -1;
1628                 lineno = flex_fta_lineno; charno = flex_fta_ch;
1629         };
1630
1631         predicate_t(const char *o){
1632                 op = o;
1633                 fcn_id = -1;
1634                 combinable_ref = -1;
1635                 lineno = flex_fta_lineno; charno = flex_fta_ch;
1636         };
1637
1638
1639         static predicate_t *make_paramless_fcn_predicate(const char *o){
1640                 predicate_t *ret = new predicate_t(o);
1641                 ret->operator_type = PRED_FUNC;
1642                 ret->fcn_id = -1;
1643                 ret->combinable_ref = -1;
1644                 return(ret);
1645         };
1646
1647         std::string to_string(){
1648                 if(operator_type == PRED_IN){
1649                         return( lhs.sexp->to_string() + " " + op + " [ " + rhs.ll->to_string() +" ]");
1650                 }
1651                 if(operator_type == PRED_COMPARE){
1652                         return( lhs.sexp->to_string() + " " + op + " " + rhs.sexp->to_string() );
1653                 }
1654                 if(operator_type == PRED_UNARY_OP){
1655                         return( op + " (" + lhs.predp->to_string() + ")" );
1656                 }
1657                 if(operator_type == PRED_BINARY_OP){
1658                         return( "(" + lhs.predp->to_string() + " " + op + " " + rhs.predp->to_string() + ")" );
1659                 }
1660                 if(operator_type == PRED_FUNC){
1661                         std::string ret = op + "[ ";
1662                         int i;
1663                         for(i=0;i<param_list.size();++i){
1664                                 if(i>0) ret += ", ";
1665                                 ret += param_list[i]->to_string();
1666                         }
1667                         ret += "] ";
1668                         return(ret);
1669                 }
1670                 return("");
1671         };
1672
1673         std::vector<scalarexp_t *> get_op_list(){return param_list;     };
1674         int get_operator_type(){return operator_type;   };
1675         std::string get_op(){return op; };
1676         int get_lineno(){return lineno; };
1677         int get_charno(){return charno; };
1678         int get_combinable_ref(){return combinable_ref;}
1679         void set_combinable_ref(int f){combinable_ref = f;};
1680         predicate_t *get_left_pr(){return(lhs.predp);   };
1681         predicate_t *get_right_pr(){return(rhs.predp);  };
1682         scalarexp_t *get_left_se(){return(lhs.sexp);    };
1683         scalarexp_t *get_right_se(){return(rhs.sexp);   };
1684         std::vector<literal_t *> get_lit_vec(){return(rhs.ll->get_literal_vector());            };
1685
1686         void swap_scalar_operands(){
1687                 if(operator_type != PRED_COMPARE){
1688                         fprintf(stderr,"INTERNAL ERROR: swap_scalar_operands called on predicate of type %d\n",operator_type);
1689                         exit(1);
1690                 }
1691                 scalarexp_t *tmp;
1692                 tmp = lhs.sexp; lhs.sexp = rhs.sexp; rhs.sexp = tmp;
1693                 if(op == ">"){op = "<"; return;}
1694                 if(op == ">="){op = "<="; return;}
1695                 if(op == "<"){op = ">"; return;}
1696                 if(op == "<="){op = ">="; return;}
1697         };
1698         void set_fcn_id(int i){fcn_id = i;};
1699         int get_fcn_id(){return fcn_id;};
1700
1701
1702 };
1703
1704
1705 /*
1706                 A structure that holds the components of a query.
1707                 This is the root type.
1708                 Used by manipulative_statement, select_statement, table_exp
1709 */
1710
1711 #define SELECT_QUERY 1
1712 #define MERGE_QUERY 2
1713 #define WATCHLIST_QUERY 3
1714
1715 class table_exp_t{
1716 public:
1717   int query_type;                                       // roughly, the type of the query.
1718   ss_map nmap;                                          //      DEFINE block
1719   std::vector<var_pair_t *> query_params;       // PARAM block (uninterpreted)
1720   select_list_t *sl;                                    // SELECT
1721   tablevar_list_t *fm;                                  // FROM
1722   predicate_t *wh;                                      // WHERE
1723   predicate_t *hv;                                      // HAVING
1724   predicate_t *cleaning_when;           // CLEANING WHEN
1725   predicate_t *cleaning_by;                     // CLEANING BY
1726   predicate_t *closing_when;            // CLOSING WHEN
1727   std::vector<extended_gb_t *> gb;                      // GROUP BY
1728   std::vector<colref_t *> mergevars;            // merge colrefs.
1729   std::vector<colref_t *> supergb;      // supergroup.
1730   scalarexp_t *slack;                           // merge slack
1731
1732   field_entry_list * fel;                       //  List of watchlist fields
1733
1734   bool exernal_visible;                         // true iff. it can be subscribed to.
1735   int lineno, charno;
1736
1737
1738   table_exp_t(tablevar_list_t *f, predicate_t *p, extended_gb_list_t *g, colref_list_t *sg, predicate_t *h, predicate_t *cw, predicate_t *cb, predicate_t *closew)
1739                 {fm = f; wh = p; hv = h;
1740                 cleaning_when = cw; cleaning_by = cb;
1741                 closing_when = closew;
1742                 if(g != NULL)
1743                         gb = g->gb_list;
1744                 if(sg != NULL)
1745                         supergb = sg->get_clist();
1746                 slack = NULL;
1747                 query_type = SELECT_QUERY;
1748                 exernal_visible = true;
1749                 lineno = flex_fta_lineno; charno = flex_fta_ch;
1750         };
1751
1752   table_exp_t(colref_list_t *mv, tablevar_list_t *f)
1753                 {fm = f; mergevars=mv->get_clist();
1754                  slack = NULL;
1755                 query_type = MERGE_QUERY;
1756                 exernal_visible = true;
1757                 lineno = flex_fta_lineno; charno = flex_fta_ch;
1758         };
1759
1760   table_exp_t(colref_list_t *mv, scalarexp_t *sl, tablevar_list_t *f)
1761                 {fm = f; mergevars=mv->get_clist();
1762                  slack = sl;
1763                 query_type = MERGE_QUERY;
1764                 exernal_visible = true;
1765                 lineno = flex_fta_lineno; charno = flex_fta_ch;
1766         };
1767
1768 //                      Figure out the temporal merge field at analyze_fta time.
1769         static table_exp_t *make_deferred_merge(std::vector<std::string> src_tbls){
1770                 table_exp_t *ret = new table_exp_t();
1771                 ret->query_type = MERGE_QUERY;
1772                 ret->fm = new tablevar_list_t();
1773                 int t;
1774                 for(t=0;t<src_tbls.size();++t){
1775                         ret->fm->append_table(new tablevar_t(src_tbls[t].c_str()));
1776                 }
1777                 ret->lineno = 0; ret->charno = 0;
1778                 return ret;
1779         }
1780
1781 //              For externally-defined watchlist
1782         static table_exp_t *make_watchlist_tbl(field_entry_list *fel_){
1783                 table_exp_t *ret = new table_exp_t();
1784                 ret->query_type = WATCHLIST_QUERY;
1785                 ret->fel = fel_;
1786                 ret->sl=NULL;
1787                 ret->fm= new tablevar_list_t(); // generic analyses need the fm clause
1788                 ret->wh=NULL;
1789                 ret->hv=NULL;
1790                 ret->cleaning_when=NULL;
1791                 ret->cleaning_by=NULL;
1792                 ret->closing_when=NULL;
1793                 ret->slack=NULL;
1794                 ret->exernal_visible = true;
1795                 ret->lineno = flex_fta_lineno; ret->charno = flex_fta_ch;
1796         };
1797
1798
1799
1800         table_exp_t(){
1801                 fm = NULL; sl = NULL; wh=NULL; hv=NULL;
1802                 slack = NULL;
1803                 cleaning_when=NULL; cleaning_by = NULL;
1804                 closing_when = NULL;
1805                 exernal_visible = true;
1806         };
1807
1808   table_exp_t *add_selection(select_list_t *s){
1809           sl = s;
1810           return(this);
1811         };
1812
1813         void add_nmap(var_defs_t *vd){
1814                 int n;
1815                 if(vd != NULL){
1816                         for(n=0;n<vd->size();++n){
1817                                 nmap[vd->get_name(n)] = vd->get_def(n);
1818 //printf("Adding (%s, %s) to name map.\n",vd->get_name(n).c_str(), vd->get_def(n).c_str());
1819                         }
1820                 }
1821         };
1822
1823         void add_param_list(var_defs_t *vd){
1824                 int n;
1825                 if(vd != NULL){
1826                         query_params = vd->get_nvec();
1827                 }
1828         };
1829
1830
1831         std::string to_string(){
1832                 std::string retval;
1833                 if(sl != NULL){
1834                         retval.append("Select " + sl->to_string() + "\n");
1835                 }
1836                 if(fm != NULL){
1837                         retval.append("From " + fm->to_string() + "\n");
1838                 }
1839                 if(wh != NULL){
1840                         retval.append("Where "+ wh->to_string() + "\n");
1841                 }
1842                 if(hv != NULL){
1843                         retval.append("Having "+hv->to_string() + "\n");
1844                 }
1845                 return(retval);
1846                 };
1847
1848         tablevar_list_t *get_from(){return fm;  };
1849         select_list_t *get_select(){return sl;  };
1850         std::vector<select_element *> get_sl_vec(){return sl->get_select_list();        };
1851         predicate_t *get_where(){return wh;     };
1852         predicate_t *get_having(){return hv;    };
1853         predicate_t *get_cleaning_by(){return cleaning_by;      };
1854         predicate_t *get_cleaning_when(){return cleaning_when;  };
1855         predicate_t *get_closing_when(){return closing_when;    };
1856         std::vector<extended_gb_t *> get_groupby(){return(gb);  };
1857     std::vector<colref_t *> get_supergb(){return supergb;};
1858
1859         ss_map get_name_map(){return nmap;};
1860
1861         bool name_exists(std::string nm){
1862                 return(nmap.count(nm) > 0);
1863         };
1864
1865         std::string get_val_of_name(std::string nm){
1866                 if(nmap.count(nm) == 0) return("");
1867                 else return nmap[nm];
1868         };
1869
1870         void set_val_of_name(const std::string n, const std::string v){
1871                 nmap[n]=v;
1872         }
1873
1874         void set_visible(bool v){exernal_visible=v;};
1875         bool get_visible(){return exernal_visible;};
1876 };
1877
1878 struct query_list_t{
1879         std::vector<table_exp_t *> qlist;
1880
1881         query_list_t(table_exp_t *t){
1882                 qlist.push_back(t);
1883         };
1884         query_list_t *append(table_exp_t *t){
1885                 qlist.push_back(t);
1886                 return(this);
1887         };
1888 };
1889
1890
1891 #define TABLE_PARSE 1
1892 #define QUERY_PARSE 2
1893 #define STREAM_PARSE 3
1894
1895 struct fta_parse_t{
1896         query_list_t *parse_tree_list;
1897         table_exp_t *fta_parse_tree;
1898         table_list *tables;
1899         int parse_type;
1900 };
1901
1902
1903
1904
1905
1906         extern table_exp_t *fta_parse_tree;
1907
1908
1909
1910
1911
1912 #endif
1913