3b20af37b89b94624548f272f9392ce74d5916d6
[com/gs-lite.git] / src / ftacmp / parse_fta.h
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 #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 FILTER_JOIN_PROPERTY 4
697
698 //              tablevar_list_t is the list of tablevars in a FROM clause
699
700 struct tablevar_list_t{
701 public:
702         std::vector<tablevar_t *> tlist;
703         int properties;
704         int lineno, charno;
705 //              For filter join
706         colref_t *temporal_var;
707         unsigned int temporal_range;
708
709         tablevar_list_t(){properties = -1; temporal_var = NULL;}
710         tablevar_list_t(tablevar_t *t){tlist.push_back(t); properties=-1; temporal_var = NULL;
711                 lineno = flex_fta_lineno; charno = flex_fta_ch;};
712         tablevar_list_t(std::vector<tablevar_t *> t){tlist = t; properties=-1; temporal_var = NULL;
713                 lineno = 0; charno = 0;};
714
715         tablevar_list_t *duplicate(){
716                 tablevar_list_t *ret = new tablevar_list_t();
717                 ret->lineno = lineno; ret->charno = charno;
718                 ret->properties = properties;
719                 ret->temporal_var = temporal_var;
720                 ret->temporal_range = temporal_range;
721                 int i;
722                 for(i=0;i<tlist.size();++i){
723                         ret->append_table(tlist[i]->duplicate());
724                 }
725                 return(ret);
726         }
727
728
729
730         tablevar_list_t *append_table(tablevar_t *t){
731                 tlist.push_back(t);
732                 return(this);
733         };
734
735         std::string to_string(){
736                 int i;
737                 std::string retval;
738
739                 for(i=0;i<tlist.size();i++){
740                         if(i>0) retval.append(", ");
741                         retval.append(tlist[i]->to_string());
742                 }
743                 return(retval);
744         };
745
746         std::vector<tablevar_t *> get_table_list(){return(tlist);       };
747
748         std::vector<std::string> get_table_names(){
749                 std::vector<std::string> ret;
750                 int t;
751                 for(t=0;t<tlist.size();++t){
752                         std::string tbl_name = tlist[t]->get_schema_name();
753                         ret.push_back(tbl_name);
754                 }
755                 return(ret);
756         }
757
758         std::vector<std::string> get_src_tbls(table_list *Schema){
759                 std::vector<std::string> ret;
760                 int t, sq;
761                 for(t=0;t<tlist.size();++t){
762                         std::string tbl_name = tlist[t]->get_schema_name();
763                         int sid = Schema->find_tbl(tbl_name);
764                         if(sid < 0){ ret.push_back(tbl_name);
765                         }else
766                         if(Schema->get_schema_type(sid) != OPERATOR_VIEW_SCHEMA){
767                                 ret.push_back(tbl_name);
768                         }else{
769                                 std::vector<subquery_spec *> sqspec = Schema->get_subqueryspecs(sid);
770                                 for(sq=0;sq<sqspec.size();++sq){
771                                         ret.push_back(sqspec[sq]->name);
772                                 }
773                         }
774                 }
775                 return(ret);
776         };
777
778         int size(){
779                 return tlist.size();
780         };
781
782 //              Some accessor functions.
783
784         std::vector<std::string> get_schema_names(){
785                 int i;
786                 std::vector<std::string > retval;
787                 for(i=0;i<tlist.size();i++){
788                         retval.push_back(tlist[i]->get_schema_name());
789                 }
790                 return(retval);
791         }
792
793         std::vector<int> get_schema_refs(){
794                 int i;
795                 std::vector<int> retval;
796                 for(i=0;i<tlist.size();i++){
797                         retval.push_back(tlist[i]->get_schema_ref());
798                 }
799                 return(retval);
800         }
801
802
803         int get_schema_ref(int i){
804                 if(i<0 || i>=tlist.size()) return(-1);
805                 return tlist[i]->get_schema_ref();
806         };
807
808         std::string get_tablevar_name(int i){
809                 if(i<0 || i>=tlist.size()) return("");
810                 return tlist[i]->get_var_name();
811         };
812
813         void set_properties(int p){properties = p;};
814         int get_properties(){return properties;};
815
816         void set_colref(colref_t *c){temporal_var = c;};
817         void set_temporal_range(unsigned int t){temporal_range = t;};
818         void set_temporal_range(const char *t){temporal_range= atoi(t);};
819         colref_t *get_colref(){return temporal_var;};
820         unsigned int get_temporal_range(){return temporal_range;};
821
822 };
823
824 //                      A reference to an interface parameter.
825 //                      (I need to be able to record the source
826 //                       tablevar, else this would be a lot simpler).
827 class ifpref_t{
828 public:
829         std::string tablevar;
830         std::string pname;
831         int tablevar_ref;
832         int lineno, charno;
833
834         ifpref_t(const char *p){
835                 tablevar="";
836                 pname = p;
837                 tablevar_ref = -1;
838                 lineno = flex_fta_lineno; charno = flex_fta_ch;
839         };
840
841         ifpref_t(const char *t, const char *p){
842                 tablevar=t;
843                 pname = p;
844                 tablevar_ref = -1;
845                 lineno = flex_fta_lineno; charno = flex_fta_ch;
846         };
847
848         void set_tablevar_ref(int i){tablevar_ref = i;};
849         int get_tablevar_ref(){return tablevar_ref;};
850         std::string get_tablevar(){return tablevar;}
851         void set_tablevar(std::string t){tablevar = t;};
852         std::string get_pname(){return pname;}
853         std::string to_string(){
854                 std::string ret;
855                 if(tablevar != "")
856                         ret += tablevar + ".";
857                 ret += "@"+pname;
858                 return ret;
859         };
860         bool is_equivalent(ifpref_t *i){
861                 return (tablevar_ref == i->tablevar_ref) && (pname == i->pname);
862         };
863 };
864
865
866
867
868 //                      A representation of a reference to a field of a
869 //                      stream (or table).  This reference must be bound
870 //                      to a particular schema (schema_ref) and to a
871 //                      particular table variable in the FROM clause (tablevar_ref)
872 //                      If the column reference was generated by the parser,
873 //                      it will contain some binding text wich might need
874 //                      interpretation to do the actual binding.
875 class colref_t{
876 public:
877         std::string interface;          // specified interface, if any.
878         std::string table_name;         // specified table name or range var, if any.
879         std::string field;                      // field name
880         bool default_table;                     // true iff. no table or range var given.
881         int schema_ref;                         // ID of the source schema.
882         int tablevar_ref;                       // ID of the tablevar (in FROM clause).
883         int lineno, charno;
884
885         colref_t(const char *f){
886                 field = f; default_table = true;
887                 schema_ref = -1; tablevar_ref = -1;
888                 lineno = flex_fta_lineno; charno = flex_fta_ch;
889         };
890
891         colref_t(const char *t, const char *f){
892                 table_name = t; field=f; default_table = false;
893                 schema_ref = -1; tablevar_ref = -1;
894                 lineno = flex_fta_lineno; charno = flex_fta_ch;
895         };
896
897         colref_t(const char *i, const char *t, const char *f){
898                 interface=i;
899                 table_name = t; field=f; default_table = false;
900                 schema_ref = -1; tablevar_ref = -1;
901                 lineno = flex_fta_lineno; charno = flex_fta_ch;
902         };
903
904         colref_t *duplicate(){
905                 colref_t *retval = new colref_t(interface.c_str(), table_name.c_str(), field.c_str());
906                 retval->schema_ref = schema_ref;
907                 retval->tablevar_ref = tablevar_ref;
908                 retval->lineno = lineno;
909                 retval->charno = charno;
910                 retval->default_table = default_table;
911                 return(retval);
912         }
913
914         std::string to_string(){
915                 if(default_table){
916                         return field;
917                 }else{
918                         if(interface != "") return(interface+"."+table_name+"."+field);
919                         return(table_name + "." + field);
920                 }
921         };
922
923         std::string to_query_string(){
924                 if(default_table){
925                         return field;
926                 }else{
927                         if(interface != "") return(interface+"."+table_name+"."+field);
928                         if(table_name != "") return(table_name + "." + field);
929                         return(field);
930                 }
931         };
932
933         int get_lineno(){return lineno; };
934         int get_charno(){return charno; };
935
936         bool uses_default_table(){return default_table; };
937
938         std::string get_field(){return(field);  };
939         void set_field(std::string f){field=f;};
940         std::string get_table_name(){return(table_name);};
941         std::string get_interface(){return(interface);};
942         void set_table_name(std::string t){table_name = t; default_table=false;};
943         void set_interface(std::string i){interface=i;};
944
945         int get_schema_ref(){return schema_ref;}
946         void set_schema_ref(int s){schema_ref = s;};
947         int get_tablevar_ref(){return tablevar_ref;}
948         void set_tablevar_ref(int s){tablevar_ref = s;};
949
950 //                      Should equivalence be based on tablevar_ref or schema_ref?
951         bool is_equivalent(colref_t *c2){
952                 if(schema_ref == c2->schema_ref){
953                         return(field == c2->field);
954                 }
955                 return(false);
956         };
957
958         bool is_equivalent_base(colref_t *c2, table_list *Schema){
959                 if(Schema->get_basetbl_name(schema_ref,field) ==
960                    Schema->get_basetbl_name(c2->schema_ref,c2->field)){
961                         return(field == c2->field);
962                 }
963                 return(false);
964         };
965 };
966
967 class colref_list_t{
968 public:
969         std::vector<colref_t *> clist;
970
971 //      colref_list_t(){};
972
973         colref_list_t(colref_t *c){
974                 clist.push_back(c);
975         }
976
977         colref_list_t *append(colref_t *c){
978                 clist.push_back(c);
979                 return this;
980         }
981
982         std::vector<colref_t *> get_clist(){
983                 return clist;
984         }
985 };
986
987
988
989
990
991
992 /*
993                 A tree containing a scalar expression.
994                         Used for
995                                 atom : a parameter or a literal
996                                 scalar_exp (see the scalar_exp: rule in emf.l for details)
997                                 function_ref (a function that has a value, e.g. an aggregate
998                                                                 function).
999                 operator_type defines the contents of the node.  If its a non-terminal,
1000                 then op has a meaning and defines the operation.  See the list of
1001                 #define'd constants following the structure definition.
1002
1003
1004 */
1005
1006 #define SE_LITERAL 1
1007 #define SE_PARAM 2
1008 #define SE_COLREF 3
1009 #define SE_UNARY_OP 4
1010 #define SE_BINARY_OP 5
1011 #define SE_AGGR_STAR 6
1012 #define SE_AGGR_SE 7
1013 #define SE_FUNC 8
1014 #define SE_IFACE_PARAM 9
1015
1016
1017 class scalarexp_t{
1018 public:
1019         int operator_type;
1020         std::string op;
1021         union{
1022                 scalarexp_t *scalarp;
1023                 literal_t *litp;
1024                 colref_t *colref;
1025                 ifpref_t *ifp;
1026         } lhs;
1027         union{
1028                 scalarexp_t *scalarp;
1029         } rhs;
1030         std::vector<scalarexp_t *> param_list;
1031
1032 //              SE node decorations -- results of query analysis.
1033         data_type *dt;
1034         int gb_ref;                             // set to the gb attr tbl ref, else -1
1035         int aggr_id;                    // set to the aggr tbl ref, else -1
1036         int fcn_id;                             // external function table ref, else -1
1037         int partial_ref;                // partial fcn table ref, else -1
1038         int fcn_cache_ref;              // function cache ref, else -1
1039         int handle_ref;                 // Entry in pass-by-handle parameter table, else -1.
1040                                                         // (might be a literal or a query param).
1041         bool is_superagg;               // true if is aggregate and associated with supergroup.
1042         std::string storage_state;      // storage state of stateful fcn,
1043                                                                 // empty o'wise.
1044
1045         int lineno, charno;
1046
1047         void default_init(){
1048                 operator_type = 0;
1049                 gb_ref = -1; aggr_id = -1;      fcn_id = -1;
1050                 partial_ref = -1; fcn_cache_ref=-1;
1051                 handle_ref = -1;
1052                 dt = NULL; lineno = flex_fta_lineno; charno = flex_fta_ch;
1053                 is_superagg = false;
1054                 };
1055
1056         scalarexp_t(){
1057                 default_init();};
1058
1059         scalarexp_t(colref_t *c){
1060                 default_init();
1061                 operator_type = SE_COLREF;
1062                 lhs.colref = c;
1063         };
1064
1065         scalarexp_t(literal_t *l){
1066                 default_init();
1067                 operator_type = SE_LITERAL;
1068                 lhs.litp = l;
1069         };
1070
1071         void convert_to_literal(literal_t *l){
1072 //              default_init();
1073                 if(operator_type != SE_IFACE_PARAM){
1074                         fprintf(stderr,"INTERNAL ERROR in literal_t::convert_to_literal, operator type isn't SE_IFACE_PARAM.\n");
1075                         exit(1);
1076                 }
1077                 operator_type = SE_LITERAL;
1078                 lhs.litp = l;
1079         }
1080
1081         scalarexp_t(const char *o, scalarexp_t *operand){
1082                 default_init();
1083                 operator_type = SE_UNARY_OP;
1084                 op = o;
1085                 lhs.scalarp = operand;
1086         };
1087
1088         scalarexp_t(const char *o, scalarexp_t *l_op, scalarexp_t *r_op){
1089                 default_init();
1090                 operator_type = SE_BINARY_OP;
1091                 op = o;
1092                 lhs.scalarp = l_op;
1093                 rhs.scalarp = r_op;
1094         };
1095
1096         scalarexp_t(const char *o, std::vector<scalarexp_t *> op_list){
1097                 default_init();
1098                 operator_type = SE_FUNC;
1099                 op = o;
1100                 param_list = op_list;
1101         };
1102
1103         static scalarexp_t *make_paramless_fcn(const char *o){
1104                 scalarexp_t *ret = new scalarexp_t();
1105                 ret->operator_type = SE_FUNC;
1106                 ret->op = o;
1107                 return(ret);
1108         };
1109
1110         static scalarexp_t *make_star_aggr(const char *ag){
1111                 scalarexp_t *ret = new scalarexp_t();
1112                 ret->operator_type = SE_AGGR_STAR;
1113                 ret->op = ag;
1114                 return(ret);
1115         };
1116
1117         static scalarexp_t *make_se_aggr(const char *ag, scalarexp_t *l_op){
1118                 scalarexp_t *ret = new scalarexp_t();
1119                 ret->operator_type = SE_AGGR_SE;
1120                 ret->op = ag;
1121                 ret->lhs.scalarp = l_op;
1122                 return(ret);
1123         };
1124
1125         static scalarexp_t *make_param_reference(const char *param){
1126                 scalarexp_t *ret = new scalarexp_t();
1127                 ret->operator_type = SE_PARAM;
1128                 ret->op = param;
1129                 return(ret);
1130         };
1131
1132         static scalarexp_t *make_iface_param_reference(ifpref_t *i){
1133                 scalarexp_t *ret = new scalarexp_t();
1134                 ret->operator_type = SE_IFACE_PARAM;
1135                 ret->lhs.ifp = i;
1136                 return(ret);
1137         };
1138
1139
1140         std::string to_string(){
1141                 if(operator_type == SE_COLREF){
1142                         return lhs.colref->to_string();
1143                 }
1144                 if(operator_type == SE_LITERAL){
1145                         return lhs.litp->to_string();
1146                 }
1147                 if(operator_type == SE_UNARY_OP){
1148                         return op + " (" + lhs.scalarp->to_string() + ")";
1149                 }
1150                 if(operator_type == SE_BINARY_OP){
1151                         return "(" + lhs.scalarp->to_string() + " " + op + " " + rhs.scalarp->to_string() + ")";
1152                 }
1153                 return("");
1154         };
1155
1156         scalarexp_t *get_left_se(){return lhs.scalarp;  };
1157         scalarexp_t *get_right_se(){return rhs.scalarp; };
1158         int get_operator_type(){return operator_type;   };
1159         std::string & get_op(){return op;       };
1160         std::string & get_param_name(){return op;       };
1161 //      std::string & get_iface_param_name(){return op; };
1162         colref_t *get_colref(){return lhs.colref;       };
1163         ifpref_t *get_ifpref(){return lhs.ifp;  };
1164         literal_t *get_literal(){return lhs.litp;       };
1165
1166         int get_lineno(){return lineno; };
1167         int get_charno(){return charno; };
1168
1169         void set_data_type(data_type *d){dt=d;  };
1170         data_type *get_data_type(){return dt;   };
1171         void reset_temporal(){if(dt!=NULL) dt->reset_temporal();}
1172
1173         void set_gb_ref(int g){gb_ref = g;      };
1174         int get_gb_ref(){return (gb_ref);       };
1175         bool is_gb(){return(gb_ref >= 0);       };
1176
1177         void set_aggr_id(int a){aggr_id = a;};
1178         int get_aggr_ref(){return(aggr_id);     };
1179
1180         void set_storage_state(std::string s){storage_state = s;};
1181         std::string get_storage_state(){return storage_state;};
1182
1183         std::vector<scalarexp_t *> get_operands(){return param_list;};
1184         void set_fcn_id(int f){fcn_id = f;      };
1185         int get_fcn_id(){return fcn_id; };
1186
1187         void set_partial_ref(int p){partial_ref = p;    };
1188         int get_partial_ref(){return partial_ref;       };
1189         bool is_partial(){return partial_ref >= 0;      };
1190
1191         void set_fcncache_ref(int p){fcn_cache_ref = p; };
1192         int get_fcncache_ref(){return fcn_cache_ref;    };
1193         bool is_fcncached(){return fcn_cache_ref >= 0;  };
1194
1195         void set_handle_ref(int tf){handle_ref = tf;    };
1196         int get_handle_ref(){return handle_ref; };
1197         bool is_handle_ref(){return handle_ref>=0;      };
1198
1199         void set_superaggr(bool b){is_superagg=b;};
1200         bool is_superaggr(){return is_superagg;};
1201
1202         void use_decorations_of(scalarexp_t *se){
1203                 if(se->get_data_type() != NULL)
1204                         dt = se->get_data_type()->duplicate();
1205                 gb_ref = se->gb_ref;
1206                 aggr_id = se->aggr_id;
1207                 fcn_id = se->fcn_id;
1208                 partial_ref = se->partial_ref;
1209                 handle_ref = se->handle_ref;
1210                 lineno = se->lineno;
1211                 charno = se->charno;
1212                 is_superagg = se->is_superagg;
1213         };
1214 };
1215
1216
1217 /*
1218                 A (null terminated) list of scalar expressions.
1219                 Used for
1220                         selection, scalar_exp_commalist
1221 */
1222
1223 class se_list_t{
1224 public:
1225         std::vector<scalarexp_t *> se_list;
1226         int lineno, charno;
1227
1228         se_list_t(scalarexp_t *s){se_list.push_back(s);
1229                 lineno = flex_fta_lineno; charno = flex_fta_ch;};
1230
1231         se_list_t *append(scalarexp_t *s){
1232                         se_list.push_back(s);
1233                         return(this);
1234         };
1235
1236         std::string to_string(){
1237                 int i;
1238                 std::string retval;
1239                 for(i=0;i<se_list.size();i++){
1240                         if(i>0) retval.append(", ");
1241                         retval.append(se_list[i]->to_string());
1242                 }
1243                 return(retval);
1244         };
1245
1246         std::vector<scalarexp_t *> get_se_list(){return se_list;        };
1247
1248
1249 };
1250
1251 /*
1252                 select_commalist : collect some additional info about
1253                 the selected things -- mostly the name.
1254 */
1255
1256 struct select_element{
1257         scalarexp_t *se;
1258         std::string name;
1259
1260         select_element(){se=NULL; name="";};
1261         select_element(scalarexp_t *s){se=s; name="";};
1262         select_element(scalarexp_t *s, std::string n){se=s; name=n;};
1263 };
1264
1265 class select_list_t{
1266 public:
1267         std::vector<select_element *> select_list;
1268         int lineno, charno;
1269
1270         select_list_t(){lineno = -1; charno = -1;};
1271         select_list_t(scalarexp_t *s){select_list.push_back(new select_element(s));
1272                 lineno = flex_fta_lineno; charno = flex_fta_ch;};
1273         select_list_t(scalarexp_t *s, std::string n){
1274                 select_list.push_back(new select_element(s,n));
1275                 lineno = flex_fta_lineno; charno = flex_fta_ch;
1276         };
1277         select_list_t *append(scalarexp_t *s){
1278                         select_list.push_back(new select_element(s));
1279                         return(this);
1280         };
1281         select_list_t *append(scalarexp_t *s, std::string n){
1282                         select_list.push_back(new select_element(s,n));
1283                         return(this);
1284         };
1285
1286         std::string to_string(){
1287                 int i;
1288                 std::string retval;
1289                 for(i=0;i<select_list.size();i++){
1290                         if(i>0) retval.append(", ");
1291                         retval.append(select_list[i]->se->to_string());
1292                         if(select_list[i]->name != "")
1293                                 retval += " AS " + select_list[i]->name;
1294
1295                 }
1296                 return(retval);
1297         };
1298
1299         std::vector<select_element *> get_select_list(){return select_list;     };
1300         std::vector<scalarexp_t *> get_select_se_list(){
1301                 std::vector<scalarexp_t *> ret;
1302                 int i;
1303                 for(i=0; i<select_list.size();++i) ret.push_back(select_list[i]->se);
1304                 return ret;
1305         };
1306 };
1307
1308
1309
1310 #define GB_COLREF 1
1311 #define GB_COMPUTED 2
1312
1313 class gb_t{
1314 public:
1315         std::string name;
1316         std::string table;
1317         std::string interface;
1318         scalarexp_t *def;
1319         int type;
1320         int lineno, charno;
1321
1322         gb_t(const char *field_name){
1323                 interface="";
1324                 name = field_name; table=""; def=NULL; type=GB_COLREF;
1325                 lineno = flex_fta_lineno; charno = flex_fta_ch;
1326         };
1327
1328         gb_t(const char *table_name, const char *field_name){
1329                 interface="";
1330                 name = field_name; table=""; def=NULL; type=GB_COLREF;
1331                 lineno = flex_fta_lineno; charno = flex_fta_ch;
1332         };
1333
1334         gb_t(const char *iface, const char *table_name, const char *field_name){
1335                 interface=iface;
1336                 name = field_name; table=""; def=NULL; type=GB_COLREF;
1337                 lineno = flex_fta_lineno; charno = flex_fta_ch;
1338         };
1339
1340         gb_t( scalarexp_t *s, const char *gname){
1341                 name = gname; table = ""; def = s; type = GB_COMPUTED;
1342                 lineno = flex_fta_lineno; charno = flex_fta_ch;
1343         };
1344
1345         std::string to_string(){
1346                 std::string retval;
1347                 if(type == GB_COLREF){
1348                         if(table != ""){
1349                                 retval = table;
1350                                 retval.append(".");
1351                         }
1352                         retval.append(name);
1353                 }
1354                 if(type == GB_COMPUTED){
1355                         retval = "(scalarexp) AS ";
1356                         retval.append(name);
1357                 }
1358                 return(retval);
1359         };
1360
1361         gb_t *duplicate();
1362
1363 };
1364
1365 /*
1366                 A (null terminated) list of group by attributes
1367 */
1368
1369 class gb_list_t{
1370 public:
1371         std::vector<gb_t *> gb_list;
1372         int lineno, charno;
1373
1374         gb_list_t(gb_t *g){gb_list.push_back(g);
1375                 lineno = flex_fta_lineno; charno = flex_fta_ch;};
1376
1377         gb_list_t *append(gb_t *s){
1378                         gb_list.push_back(s);
1379                         return(this);
1380         };
1381         gb_list_t(int l, int c) : lineno(l), charno(c){ }
1382
1383         std::string to_string(){
1384                 int i;
1385                 std::string retval;
1386                 for(i=0;i<gb_list.size();i++){
1387                         if(i>0) retval.append(", ");
1388                         retval.append(gb_list[i]->to_string());
1389                 }
1390                 return(retval);
1391         };
1392
1393         std::vector<gb_t *> get_gb_list(){return gb_list;       };
1394
1395         gb_list_t *duplicate(){
1396                 gb_list_t *ret = new gb_list_t(lineno, charno);
1397                 int i;
1398                 for(i=0;i<gb_list.size();++i){
1399                         ret->append(gb_list[i]->duplicate());
1400                 }
1401
1402                 return ret;
1403         }
1404
1405
1406 };
1407
1408 class list_of_gb_list_t{
1409 public:
1410         std::vector<gb_list_t *> gb_lists;
1411
1412         list_of_gb_list_t(gb_list_t *gl){
1413                 gb_lists.push_back(gl);
1414         }
1415
1416         list_of_gb_list_t *append(gb_list_t *gl){
1417                 gb_lists.push_back(gl);
1418                 return this;
1419         }
1420 };
1421
1422
1423 enum extended_gb_type {no_egb_type, gb_egb_type, rollup_egb_type,
1424                         cube_egb_type, gsets_egb_type};
1425 class extended_gb_t{
1426 public:
1427
1428         extended_gb_type type;
1429         gb_t *gb;
1430         std::vector<gb_list_t *> gb_lists;
1431
1432         extended_gb_t(){
1433                 gb = NULL;
1434                 type = no_egb_type;
1435         }
1436
1437         ~extended_gb_t(){
1438         }
1439
1440         static extended_gb_t *create_from_gb(gb_t *g){
1441                 extended_gb_t *ret  = new extended_gb_t();
1442                 ret->type = gb_egb_type;
1443                 ret->gb = g;
1444                 return ret;
1445         }
1446
1447         static extended_gb_t *extended_create_from_rollup(gb_list_t *gl){
1448                 extended_gb_t *ret  = new extended_gb_t();
1449                 ret->type = rollup_egb_type;
1450                 ret->gb_lists.push_back(gl);
1451                 return ret;
1452         }
1453
1454         static extended_gb_t *extended_create_from_cube(gb_list_t *gl){
1455                 extended_gb_t *ret  = new extended_gb_t();
1456                 ret->type = cube_egb_type;
1457                 ret->gb_lists.push_back(gl);
1458                 return ret;
1459         }
1460
1461         static extended_gb_t *extended_create_from_gsets(list_of_gb_list_t *lgl){
1462                 extended_gb_t *ret  = new extended_gb_t();
1463                 ret->type = gsets_egb_type;
1464                 ret->gb_lists = lgl->gb_lists;
1465                 return ret;
1466         }
1467
1468         extended_gb_t *duplicate(){
1469                 extended_gb_t *ret = new extended_gb_t();
1470                 ret->type = type;
1471                 if(gb != NULL)
1472                         ret->gb = gb->duplicate();
1473                 int i;
1474                 for(i=0;i<gb_lists.size();++i){
1475                         ret->gb_lists.push_back(gb_lists[i]->duplicate());
1476                 }
1477                 return ret;
1478         }
1479
1480
1481         std::string to_string(){
1482                 std::string ret;
1483                 int i;
1484
1485                 switch(type){
1486                 case no_egb_type:
1487                         return "Error, undefined extended gb type.";
1488                 case gb_egb_type:
1489                         return gb->to_string();
1490                 case rollup_egb_type:
1491                         return "ROLLUP("+gb_lists[0]->to_string()+")";
1492                 case cube_egb_type:
1493                         return "CUBE("+gb_lists[0]->to_string()+")";
1494                 case gsets_egb_type:
1495                         ret = "GROUPING_SETS(";
1496                         for(i=0;i<gb_lists.size();++i){
1497                                 if(i>0) ret+=", ";
1498                                 ret += "(" +gb_lists[i]->to_string()+")";
1499                         }
1500                         ret += ")";
1501                         return ret;
1502                 default:
1503                         break;
1504                 }
1505                 return "Error, unknown extended gb type.";
1506         }
1507
1508 };
1509
1510 class extended_gb_list_t{
1511 public:
1512         std::vector<extended_gb_t *> gb_list;
1513         int lineno, charno;
1514
1515         extended_gb_list_t(extended_gb_t *g){gb_list.push_back(g);
1516                 lineno = flex_fta_lineno; charno = flex_fta_ch;};
1517
1518         extended_gb_list_t *append(extended_gb_t *s){
1519                         gb_list.push_back(s);
1520                         return(this);
1521         };
1522
1523         std::string to_string(){
1524                 int i;
1525                 std::string retval;
1526                 for(i=0;i<gb_list.size();i++){
1527                         if(i>0) retval.append(", ");
1528                         retval.append(gb_list[i]->to_string());
1529                 }
1530                 return(retval);
1531         };
1532
1533         std::vector<extended_gb_t *> get_gb_list(){return gb_list;      };
1534 };
1535
1536
1537
1538 /*
1539                 A predicate tree.  Structure is similar to
1540                 a scalar expression tree but the type is always boolean.
1541                 Used by
1542                         opt_where_clause, where_clause, opt_having_clause,
1543                         search_condition, predicate, comparison_predicate, repl_predicate
1544 */
1545
1546 #define PRED_COMPARE 1
1547 #define PRED_UNARY_OP 2
1548 #define PRED_BINARY_OP 3
1549 #define PRED_FUNC 4
1550 #define PRED_IN 5
1551
1552 class  predicate_t{
1553 public:
1554         int operator_type;
1555         std::string op;
1556         union {
1557                 predicate_t *predp;
1558                 scalarexp_t *sexp;
1559         }lhs;
1560         union {
1561                 predicate_t *predp;
1562                 scalarexp_t *sexp;
1563                 literal_list_t *ll;
1564         }rhs;
1565         std::vector<scalarexp_t *> param_list;  /// pred fcn params
1566         int fcn_id;                                                             /// external pred fcn id
1567         int combinable_ref;
1568         bool is_sampling_fcn;
1569         int lineno, charno;
1570
1571         predicate_t(scalarexp_t *s, literal_list_t *litl){
1572                 operator_type = PRED_IN;
1573                 op = "in";
1574                 lhs.sexp = s;
1575                 rhs.ll = litl;
1576                 fcn_id = -1;
1577                 combinable_ref = -1;
1578                 lineno = flex_fta_lineno; charno = flex_fta_ch;
1579         };
1580
1581         predicate_t(scalarexp_t *s, std::vector<literal_t *> litv){
1582                 operator_type = PRED_IN;
1583                 op = "in";
1584                 lhs.sexp = s;
1585                 rhs.ll = new literal_list_t(litv);
1586                 fcn_id = -1;
1587                 combinable_ref = -1;
1588                 lineno = flex_fta_lineno; charno = flex_fta_ch;
1589         };
1590
1591
1592         predicate_t(scalarexp_t *l_op, const char *o, scalarexp_t *r_op){
1593                 operator_type = PRED_COMPARE;
1594                 op = o;
1595                 lhs.sexp = l_op;
1596                 rhs.sexp = r_op;
1597                 fcn_id = -1;
1598                 combinable_ref = -1;
1599                 lineno = flex_fta_lineno; charno = flex_fta_ch;
1600         };
1601
1602         predicate_t(const char *o, predicate_t *p){
1603                 operator_type = PRED_UNARY_OP;
1604                 op = o;
1605                 lhs.predp = p;
1606                 fcn_id = -1;
1607                 combinable_ref = -1;
1608                 lineno = flex_fta_lineno; charno = flex_fta_ch;
1609         };
1610
1611         predicate_t(const char *o, predicate_t *l_p, predicate_t *r_p){
1612                 operator_type = PRED_BINARY_OP;
1613                 op = o;
1614                 lhs.predp = l_p;
1615                 rhs.predp = r_p;
1616                 fcn_id = -1;
1617                 combinable_ref = -1;
1618                 lineno = flex_fta_lineno; charno = flex_fta_ch;
1619         };
1620
1621         predicate_t(const char *o, std::vector<scalarexp_t *> op_list){
1622                 operator_type = PRED_FUNC;
1623                 op = o;
1624                 param_list = op_list;
1625                 fcn_id = -1;
1626                 combinable_ref = -1;
1627                 lineno = flex_fta_lineno; charno = flex_fta_ch;
1628         };
1629
1630         predicate_t(const char *o){
1631                 op = o;
1632                 fcn_id = -1;
1633                 combinable_ref = -1;
1634                 lineno = flex_fta_lineno; charno = flex_fta_ch;
1635         };
1636
1637
1638         static predicate_t *make_paramless_fcn_predicate(const char *o){
1639                 predicate_t *ret = new predicate_t(o);
1640                 ret->operator_type = PRED_FUNC;
1641                 ret->fcn_id = -1;
1642                 ret->combinable_ref = -1;
1643                 return(ret);
1644         };
1645
1646         std::string to_string(){
1647                 if(operator_type == PRED_IN){
1648                         return( lhs.sexp->to_string() + " " + op + " [ " + rhs.ll->to_string() +" ]");
1649                 }
1650                 if(operator_type == PRED_COMPARE){
1651                         return( lhs.sexp->to_string() + " " + op + " " + rhs.sexp->to_string() );
1652                 }
1653                 if(operator_type == PRED_UNARY_OP){
1654                         return( op + " (" + lhs.predp->to_string() + ")" );
1655                 }
1656                 if(operator_type == PRED_BINARY_OP){
1657                         return( "(" + lhs.predp->to_string() + " " + op + " " + rhs.predp->to_string() + ")" );
1658                 }
1659                 if(operator_type == PRED_FUNC){
1660                         std::string ret = op + "[ ";
1661                         int i;
1662                         for(i=0;i<param_list.size();++i){
1663                                 if(i>0) ret += ", ";
1664                                 ret += param_list[i]->to_string();
1665                         }
1666                         ret += "] ";
1667                         return(ret);
1668                 }
1669                 return("");
1670         };
1671
1672         std::vector<scalarexp_t *> get_op_list(){return param_list;     };
1673         int get_operator_type(){return operator_type;   };
1674         std::string get_op(){return op; };
1675         int get_lineno(){return lineno; };
1676         int get_charno(){return charno; };
1677         int get_combinable_ref(){return combinable_ref;}
1678         void set_combinable_ref(int f){combinable_ref = f;};
1679         predicate_t *get_left_pr(){return(lhs.predp);   };
1680         predicate_t *get_right_pr(){return(rhs.predp);  };
1681         scalarexp_t *get_left_se(){return(lhs.sexp);    };
1682         scalarexp_t *get_right_se(){return(rhs.sexp);   };
1683         std::vector<literal_t *> get_lit_vec(){return(rhs.ll->get_literal_vector());            };
1684
1685         void swap_scalar_operands(){
1686                 if(operator_type != PRED_COMPARE){
1687                         fprintf(stderr,"INTERNAL ERROR: swap_scalar_operands called on predicate of type %d\n",operator_type);
1688                         exit(1);
1689                 }
1690                 scalarexp_t *tmp;
1691                 tmp = lhs.sexp; lhs.sexp = rhs.sexp; rhs.sexp = tmp;
1692                 if(op == ">"){op = "<"; return;}
1693                 if(op == ">="){op = "<="; return;}
1694                 if(op == "<"){op = ">"; return;}
1695                 if(op == "<="){op = ">="; return;}
1696         };
1697         void set_fcn_id(int i){fcn_id = i;};
1698         int get_fcn_id(){return fcn_id;};
1699
1700
1701 };
1702
1703
1704 /*
1705                 A structure that holds the components of a query.
1706                 This is the root type.
1707                 Used by manipulative_statement, select_statement, table_exp
1708 */
1709
1710 #define SELECT_QUERY 1
1711 #define MERGE_QUERY 2
1712
1713 class table_exp_t{
1714 public:
1715   int query_type;                                       // roughly, the type of the query.
1716   ss_map nmap;                                          //      DEFINE block
1717   std::vector<var_pair_t *> query_params;       // PARAM block (uninterpreted)
1718   select_list_t *sl;                                    // SELECT
1719   tablevar_list_t *fm;                                  // FROM
1720   predicate_t *wh;                                      // WHERE
1721   predicate_t *hv;                                      // HAVING
1722   predicate_t *cleaning_when;           // CLEANING WHEN
1723   predicate_t *cleaning_by;                     // CLEANING BY
1724   predicate_t *closing_when;            // CLOSING WHEN
1725   std::vector<extended_gb_t *> gb;                      // GROUP BY
1726   std::vector<colref_t *> mergevars;            // merge colrefs.
1727   std::vector<colref_t *> supergb;      // supergroup.
1728   scalarexp_t *slack;                           // merge slack
1729   bool exernal_visible;                         // true iff. it can be subscribed to.
1730   int lineno, charno;
1731
1732
1733   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)
1734                 {fm = f; wh = p; hv = h;
1735                 cleaning_when = cw; cleaning_by = cb;
1736                 closing_when = closew;
1737                 if(g != NULL)
1738                         gb = g->gb_list;
1739                 if(sg != NULL)
1740                         supergb = sg->get_clist();
1741                 slack = NULL;
1742                 query_type = SELECT_QUERY;
1743                 exernal_visible = true;
1744                 lineno = flex_fta_lineno; charno = flex_fta_ch;
1745         };
1746
1747   table_exp_t(colref_list_t *mv, tablevar_list_t *f)
1748                 {fm = f; mergevars=mv->get_clist();
1749                  slack = NULL;
1750                 query_type = MERGE_QUERY;
1751                 exernal_visible = true;
1752                 lineno = flex_fta_lineno; charno = flex_fta_ch;
1753         };
1754
1755   table_exp_t(colref_list_t *mv, scalarexp_t *sl, tablevar_list_t *f)
1756                 {fm = f; mergevars=mv->get_clist();
1757                  slack = sl;
1758                 query_type = MERGE_QUERY;
1759                 exernal_visible = true;
1760                 lineno = flex_fta_lineno; charno = flex_fta_ch;
1761         };
1762
1763 //                      Figure out the temporal merge field at analyze_fta time.
1764         static table_exp_t *make_deferred_merge(std::vector<std::string> src_tbls){
1765                 table_exp_t *ret = new table_exp_t();
1766                 ret->query_type = MERGE_QUERY;
1767                 ret->fm = new tablevar_list_t();
1768                 int t;
1769                 for(t=0;t<src_tbls.size();++t){
1770                         ret->fm->append_table(new tablevar_t(src_tbls[t].c_str()));
1771                 }
1772                 ret->lineno = 0; ret->charno = 0;
1773                 return ret;
1774         }
1775
1776         table_exp_t(){
1777                 fm = NULL; sl = NULL; wh=NULL; hv=NULL;
1778                 slack = NULL;
1779                 cleaning_when=NULL; cleaning_by = NULL;
1780                 closing_when = NULL;
1781                 exernal_visible = true;
1782         };
1783
1784   table_exp_t *add_selection(select_list_t *s){
1785           sl = s;
1786           return(this);
1787         };
1788
1789         void add_nmap(var_defs_t *vd){
1790                 int n;
1791                 if(vd != NULL){
1792                         for(n=0;n<vd->size();++n){
1793                                 nmap[vd->get_name(n)] = vd->get_def(n);
1794 //printf("Adding (%s, %s) to name map.\n",vd->get_name(n).c_str(), vd->get_def(n).c_str());
1795                         }
1796                 }
1797         };
1798
1799         void add_param_list(var_defs_t *vd){
1800                 int n;
1801                 if(vd != NULL){
1802                         query_params = vd->get_nvec();
1803                 }
1804         };
1805
1806
1807         std::string to_string(){
1808                 std::string retval;
1809                 if(sl != NULL){
1810                         retval.append("Select " + sl->to_string() + "\n");
1811                 }
1812                 if(fm != NULL){
1813                         retval.append("From " + fm->to_string() + "\n");
1814                 }
1815                 if(wh != NULL){
1816                         retval.append("Where "+ wh->to_string() + "\n");
1817                 }
1818                 if(hv != NULL){
1819                         retval.append("Having "+hv->to_string() + "\n");
1820                 }
1821                 return(retval);
1822                 };
1823
1824         tablevar_list_t *get_from(){return fm;  };
1825         select_list_t *get_select(){return sl;  };
1826         std::vector<select_element *> get_sl_vec(){return sl->get_select_list();        };
1827         predicate_t *get_where(){return wh;     };
1828         predicate_t *get_having(){return hv;    };
1829         predicate_t *get_cleaning_by(){return cleaning_by;      };
1830         predicate_t *get_cleaning_when(){return cleaning_when;  };
1831         predicate_t *get_closing_when(){return closing_when;    };
1832         std::vector<extended_gb_t *> get_groupby(){return(gb);  };
1833     std::vector<colref_t *> get_supergb(){return supergb;};
1834
1835         ss_map get_name_map(){return nmap;};
1836
1837         bool name_exists(std::string nm){
1838                 return(nmap.count(nm) > 0);
1839         };
1840
1841         std::string get_val_of_name(std::string nm){
1842                 if(nmap.count(nm) == 0) return("");
1843                 else return nmap[nm];
1844         };
1845
1846         void set_val_of_name(const std::string n, const std::string v){
1847                 nmap[n]=v;
1848         }
1849
1850         void set_visible(bool v){exernal_visible=v;};
1851         bool get_visible(){return exernal_visible;};
1852 };
1853
1854 struct query_list_t{
1855         std::vector<table_exp_t *> qlist;
1856
1857         query_list_t(table_exp_t *t){
1858                 qlist.push_back(t);
1859         };
1860         query_list_t *append(table_exp_t *t){
1861                 qlist.push_back(t);
1862                 return(this);
1863         };
1864 };
1865
1866
1867 #define TABLE_PARSE 1
1868 #define QUERY_PARSE 2
1869 #define STREAM_PARSE 3
1870
1871 struct fta_parse_t{
1872         query_list_t *parse_tree_list;
1873         table_exp_t *fta_parse_tree;
1874         table_list *tables;
1875         int parse_type;
1876 };
1877
1878
1879
1880
1881
1882         extern table_exp_t *fta_parse_tree;
1883
1884
1885
1886
1887
1888 #endif
1889