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
7 http://www.apache.org/licenses/LICENSE-2.0
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__
22 void yyerror(char *s);
24 extern int flex_fta_lineno, flex_fta_ch;
26 /* Interface to FTA Parser */
27 void FtaParser_setfileinput(FILE *f);
28 void FtaParser_setstringinput(char *s);
31 /* Get type defines. */
32 #include"type_objects.h"
33 #include"literal_types.h"
34 #include"type_indicators.h"
45 // colref_t::is_equivalent needs to understand the schema
46 #include"parse_schema.h"
56 var_pair_t(char *n, char *v){
58 //printf("NEW var_pair_t(%s, %s)\n",n,v);
61 var_pair_t(const std::string n, const std::string v){
66 typedef std::map< std::string, std::string > ss_map;
70 std::vector<var_pair_t *> namevec;
73 var_defs_t(var_pair_t *vp){
74 namevec.push_back(vp);
77 var_defs_t *add_var_pair(var_pair_t *vp){
78 namevec.push_back(vp);
82 std::vector<var_pair_t *> get_nvec(){return namevec;};
84 int size(){return namevec.size();};
86 int find_name(std::string n){
88 for(i=0;i<namevec.size();i++){
89 if(namevec[i]->name == n)
94 std::string get_name(int i){
95 if(i>=0 && i<namevec.size()){
96 return(namevec[i]->name);
102 std::string get_def(int i){
103 if(i>=0 && i<namevec.size()){
104 return(namevec[i]->val);
113 for(i=0;i<namevec.size();++i){
114 ret += "\t"+namevec[i]->name+" = "+namevec[i]->val+"\n";
124 // literal type constants are defined in literal_types.h
125 // (must share this info with type_objects.h)
127 // Represents a literal, as expected
128 // NOTE: this class contains some code generation methods.
134 std::string lstring; /* literal value */
135 short int ltype; /* literal type */
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).
145 literal_t(std::string v){
147 ltype = LITERAL_STRING;
148 complex_literal_id = -1;
149 lineno = flex_fta_lineno; charno = flex_fta_ch;
151 static literal_t *make_define_literal(const char *s, var_defs_t *d){
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);
158 return new literal_t(d->get_def(i));
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;
165 // For some datatypes we need to modify literal so make a copy of the string
169 // Remove UL, ULL suffix from INT constants.
170 if(ltype == LITERAL_INT || ltype == LITERAL_LONGINT){
174 if(v[i] == 'U') v[i] = '\0';
179 // HEX and LONGHEX must be converted to uint (long long uint)
180 if(ltype == LITERAL_HEX){
181 char *c,ltmpstr[100];
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",
190 sscanf(v,"%lx",&tmp_l);
191 sprintf(ltmpstr,"%lu",tmp_l);
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",
205 sscanf(v,"%llx",&tmp_ll);
206 sprintf(ltmpstr,"%llu",tmp_ll);
208 ltype = LITERAL_LONGINT;
210 // Convert IP to uint
211 if(ltype == LITERAL_IP){
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",
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",
224 tmp_l = (o1<<24)+(o2<<16)+(o3<<8)+o4;
225 sprintf(ltmpstr,"%u",tmp_l);
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;
236 switch(type_indicator){
245 ltype = LITERAL_LONGINT;
249 ltype = LITERAL_FLOAT;
253 ltype = LITERAL_BOOL;
257 ltype = LITERAL_STRING;
258 lstring = ""; complex_literal_id = 0; // unregistred complex lit
261 ltype = LITERAL_TIMEVAL;
265 ltype = LITERAL_IPV6;
266 lstring = "0000:0000:0000:0000:0000:0000:0000:0000";
267 complex_literal_id = 0; // unregistered complex literal
274 ltype = LITERAL_UDEF;
275 lstring=" INTERNAL ERROR, UNKNOWN TYPE INDICATOR IN literal_t::literal_t(int) ";
279 std::string to_string(){return lstring;};
281 int get_type(){return ltype; };
282 int get_lineno(){return lineno; };
283 int get_charno(){return charno; };
285 bool is_equivalent(literal_t *l2){
286 if(ltype != l2->ltype)
288 if(lstring != l2->lstring)
294 // Internal function to unescape control characters.
295 static std::string gsqlstr_to_cstr(std::string s){
297 unsigned char c, prev_c='\0';
300 for(i=0;i<s.size();++i){
302 if(c=='\''){ // || c=='\\'
321 std::string to_hfta_C_code(std::string param){
329 retval.append(this->hfta_constructor_name() );
330 retval.append("("+param+",\"");
331 retval.append(gsqlstr_to_cstr(lstring));
332 retval.append("\")");
336 return("((gs_uint32_t)"+lstring+")");
337 case LITERAL_LONGINT:
338 return("((gs_uint64_t)"+lstring+")");
342 // return("0x"+lstring);
344 if(lstring == "TRUE"){
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);
358 retval = this->hfta_constructor_name();
359 retval += "("+param+",\""+lstring+"\")";
363 return("ERROR UNKNOWN LITERAL");
367 /// for LFTA code generation
368 std::string to_C_code(std::string param){
376 retval = this->constructor_name()+"("+param+",\""+gsqlstr_to_cstr(lstring)+"\")";
380 return("((gs_uint32_t)"+lstring+")");
381 case LITERAL_LONGINT:
382 return("((gs_uint64_t)"+lstring+")");
386 // return("0x"+lstring);
388 if(lstring == "TRUE"){
394 retval = this->constructor_name()+"("+param+",\""+lstring+"\")";
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);
406 return("ERROR UNKNOWN LITERAL");
410 std::string to_query_string(){
417 sscanf(lstring.c_str(),"%u",&v);
419 int d2 = (v & 0xff00) >> 8;
420 int d3 = (v & 0xff0000) >> 16;
421 int d4 = (v & 0xff000000) >> 24;
423 sprintf(ret,"IP_VAL'%u.%u.%u.%u'",d4,d3,d2,d1);
427 retval = "'"+lstring+"'";
431 case LITERAL_TIMEVAL:
435 case LITERAL_LONGINT:
436 return(lstring+"ULL");
439 return("ERROR UNKNOWN LITERAL in literal_t::to_query_string");
442 // TODO : Use definition files instead of hardwiring these.
444 // constructor in LFTA code
445 std::string constructor_name(){
448 case LITERAL_TIMEVAL:
449 return("Timeval_Constructor");
451 return("Ipv6_Constructor");
453 return("str_constructor");
456 case LITERAL_LONGINT:
461 return("ERROR UNKNOWN LITERAL");
464 std::string hfta_constructor_name(){
467 case LITERAL_TIMEVAL:
468 return("HFTA_Timeval_Constructor");
470 return("HFTA_Ipv6_Constructor");
472 return("Vstring_Constructor");
475 case LITERAL_LONGINT:
480 return("ERROR UNKNOWN LITERAL");
483 std::string hfta_empty_literal_name(){
486 case LITERAL_TIMEVAL:
487 return("EmptyTimeval");
491 return("EmptyString");
493 return("ERROR_NOT_A_COMPLEX_LITERAL");
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); };
505 A (null terminated) list of literals.
506 Used for the IN clause
509 class literal_list_t{
513 std::vector<literal_t *> lit_list;
516 literal_list_t(literal_t *l){
517 lit_list.push_back(l);
518 lineno = flex_fta_lineno; charno = flex_fta_ch;
521 literal_list_t(std::vector<literal_t *> lvec){
526 literal_list_t *append_literal(literal_t *l){
527 lit_list.push_back(l);
531 std::string to_string(){
534 for(i=0;i<lit_list.size();i++){
535 if(i>0) retval.append(", ");
536 retval.append(lit_list[i]->to_query_string());
541 std::vector<literal_t *> get_literal_vector(){return(lit_list);};
552 string_t *append(char *s){
556 string_t *append(char *sep, char *s){
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.
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.
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.
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
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.
595 int properties; // inner (0) or outer (1) join;
596 // labeled using FROM clause,
597 // determines join algorithm.
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;};
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;};
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;};
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;
636 tablevar_t *set_range_var(const char *r){
640 tablevar_t *set_range_var(std::string r){
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;};
650 void set_schema_ref(int r){schema_ref = r;};
651 int get_schema_ref(){return schema_ref;};
653 void set_opview_idx(int i){opview_idx = i;};
654 int get_opview_idx(){return opview_idx;};
656 void set_property(int p){properties = p;};
657 int get_property(){return properties;};
659 bool get_ifq(){return iface_is_query;};
660 void set_ifq(bool b){iface_is_query = b;};
662 std::string to_string(){
665 if(machine != "" && !iface_is_query)
666 retval += "'"+machine+"'.";
669 retval += '['+interface+"].";
671 retval += interface+".";
674 retval += schema_name;
675 if(variable_name != "") retval+=" "+variable_name;
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;};
687 int get_lineno(){return(lineno); };
688 int get_charno(){return(charno); };
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
699 // tablevar_list_t is the list of tablevars in a FROM clause
701 struct tablevar_list_t{
703 std::vector<tablevar_t *> tlist;
707 colref_t *temporal_var;
708 unsigned int temporal_range;
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;};
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;
723 for(i=0;i<tlist.size();++i){
724 ret->append_table(tlist[i]->duplicate());
731 tablevar_list_t *append_table(tablevar_t *t){
736 std::string to_string(){
740 for(i=0;i<tlist.size();i++){
741 if(i>0) retval.append(", ");
742 retval.append(tlist[i]->to_string());
747 std::vector<tablevar_t *> get_table_list(){return(tlist); };
749 std::vector<std::string> get_table_names(){
750 std::vector<std::string> ret;
752 for(t=0;t<tlist.size();++t){
753 std::string tbl_name = tlist[t]->get_schema_name();
754 ret.push_back(tbl_name);
759 std::vector<std::string> get_src_tbls(table_list *Schema){
760 std::vector<std::string> ret;
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);
767 if(Schema->get_schema_type(sid) != OPERATOR_VIEW_SCHEMA){
768 ret.push_back(tbl_name);
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);
783 // Some accessor functions.
785 std::vector<std::string> get_schema_names(){
787 std::vector<std::string > retval;
788 for(i=0;i<tlist.size();i++){
789 retval.push_back(tlist[i]->get_schema_name());
794 std::vector<int> get_schema_refs(){
796 std::vector<int> retval;
797 for(i=0;i<tlist.size();i++){
798 retval.push_back(tlist[i]->get_schema_ref());
804 int get_schema_ref(int i){
805 if(i<0 || i>=tlist.size()) return(-1);
806 return tlist[i]->get_schema_ref();
809 std::string get_tablevar_name(int i){
810 if(i<0 || i>=tlist.size()) return("");
811 return tlist[i]->get_var_name();
814 void set_properties(int p){properties = p;};
815 int get_properties(){return properties;};
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;};
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).
830 std::string tablevar;
835 ifpref_t(const char *p){
839 lineno = flex_fta_lineno; charno = flex_fta_ch;
842 ifpref_t(const char *t, const char *p){
846 lineno = flex_fta_lineno; charno = flex_fta_ch;
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(){
857 ret += tablevar + ".";
861 bool is_equivalent(ifpref_t *i){
862 return (tablevar_ref == i->tablevar_ref) && (pname == i->pname);
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.
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).
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;
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;
898 colref_t(const char *i, const char *t, const char *f){
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;
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;
915 std::string to_string(){
919 if(interface != "") return(interface+"."+table_name+"."+field);
920 return(table_name + "." + field);
924 std::string to_query_string(){
928 if(interface != "") return(interface+"."+table_name+"."+field);
929 if(table_name != "") return(table_name + "." + field);
934 int get_lineno(){return lineno; };
935 int get_charno(){return charno; };
937 bool uses_default_table(){return default_table; };
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;};
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;};
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);
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);
970 std::vector<colref_t *> clist;
972 // colref_list_t(){};
974 colref_list_t(colref_t *c){
978 colref_list_t *append(colref_t *c){
983 std::vector<colref_t *> get_clist(){
994 A tree containing a scalar expression.
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
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.
1007 #define SE_LITERAL 1
1010 #define SE_UNARY_OP 4
1011 #define SE_BINARY_OP 5
1012 #define SE_AGGR_STAR 6
1013 #define SE_AGGR_SE 7
1015 #define SE_IFACE_PARAM 9
1023 scalarexp_t *scalarp;
1029 scalarexp_t *scalarp;
1031 std::vector<scalarexp_t *> param_list;
1033 // SE node decorations -- results of query analysis.
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,
1048 void default_init(){
1050 gb_ref = -1; aggr_id = -1; fcn_id = -1;
1051 partial_ref = -1; fcn_cache_ref=-1;
1053 dt = NULL; lineno = flex_fta_lineno; charno = flex_fta_ch;
1054 is_superagg = false;
1060 scalarexp_t(colref_t *c){
1062 operator_type = SE_COLREF;
1066 scalarexp_t(literal_t *l){
1068 operator_type = SE_LITERAL;
1072 void convert_to_literal(literal_t *l){
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");
1078 operator_type = SE_LITERAL;
1082 scalarexp_t(const char *o, scalarexp_t *operand){
1084 operator_type = SE_UNARY_OP;
1086 lhs.scalarp = operand;
1089 scalarexp_t(const char *o, scalarexp_t *l_op, scalarexp_t *r_op){
1091 operator_type = SE_BINARY_OP;
1097 scalarexp_t(const char *o, std::vector<scalarexp_t *> op_list){
1099 operator_type = SE_FUNC;
1101 param_list = op_list;
1104 static scalarexp_t *make_paramless_fcn(const char *o){
1105 scalarexp_t *ret = new scalarexp_t();
1106 ret->operator_type = SE_FUNC;
1111 static scalarexp_t *make_star_aggr(const char *ag){
1112 scalarexp_t *ret = new scalarexp_t();
1113 ret->operator_type = SE_AGGR_STAR;
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;
1122 ret->lhs.scalarp = l_op;
1126 static scalarexp_t *make_param_reference(const char *param){
1127 scalarexp_t *ret = new scalarexp_t();
1128 ret->operator_type = SE_PARAM;
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;
1141 std::string to_string(){
1142 if(operator_type == SE_COLREF){
1143 return lhs.colref->to_string();
1145 if(operator_type == SE_LITERAL){
1146 return lhs.litp->to_string();
1148 if(operator_type == SE_UNARY_OP){
1149 return op + " (" + lhs.scalarp->to_string() + ")";
1151 if(operator_type == SE_BINARY_OP){
1152 return "(" + lhs.scalarp->to_string() + " " + op + " " + rhs.scalarp->to_string() + ")";
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; };
1167 int get_lineno(){return lineno; };
1168 int get_charno(){return charno; };
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();}
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); };
1178 void set_aggr_id(int a){aggr_id = a;};
1179 int get_aggr_ref(){return(aggr_id); };
1181 void set_storage_state(std::string s){storage_state = s;};
1182 std::string get_storage_state(){return storage_state;};
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; };
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; };
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; };
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; };
1200 void set_superaggr(bool b){is_superagg=b;};
1201 bool is_superaggr(){return is_superagg;};
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;
1219 A (null terminated) list of scalar expressions.
1221 selection, scalar_exp_commalist
1226 std::vector<scalarexp_t *> se_list;
1229 se_list_t(scalarexp_t *s){se_list.push_back(s);
1230 lineno = flex_fta_lineno; charno = flex_fta_ch;};
1232 se_list_t *append(scalarexp_t *s){
1233 se_list.push_back(s);
1237 std::string to_string(){
1240 for(i=0;i<se_list.size();i++){
1241 if(i>0) retval.append(", ");
1242 retval.append(se_list[i]->to_string());
1247 std::vector<scalarexp_t *> get_se_list(){return se_list; };
1253 select_commalist : collect some additional info about
1254 the selected things -- mostly the name.
1257 struct select_element{
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;};
1266 class select_list_t{
1268 std::vector<select_element *> select_list;
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;
1278 select_list_t *append(scalarexp_t *s){
1279 select_list.push_back(new select_element(s));
1282 select_list_t *append(scalarexp_t *s, std::string n){
1283 select_list.push_back(new select_element(s,n));
1287 std::string to_string(){
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;
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;
1304 for(i=0; i<select_list.size();++i) ret.push_back(select_list[i]->se);
1312 #define GB_COMPUTED 2
1318 std::string interface;
1323 gb_t(const char *field_name){
1325 name = field_name; table=""; def=NULL; type=GB_COLREF;
1326 lineno = flex_fta_lineno; charno = flex_fta_ch;
1329 gb_t(const char *table_name, const char *field_name){
1331 name = field_name; table=""; def=NULL; type=GB_COLREF;
1332 lineno = flex_fta_lineno; charno = flex_fta_ch;
1335 gb_t(const char *iface, const char *table_name, const char *field_name){
1337 name = field_name; table=""; def=NULL; type=GB_COLREF;
1338 lineno = flex_fta_lineno; charno = flex_fta_ch;
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;
1346 std::string to_string(){
1348 if(type == GB_COLREF){
1353 retval.append(name);
1355 if(type == GB_COMPUTED){
1356 retval = "(scalarexp) AS ";
1357 retval.append(name);
1367 A (null terminated) list of group by attributes
1372 std::vector<gb_t *> gb_list;
1375 gb_list_t(gb_t *g){gb_list.push_back(g);
1376 lineno = flex_fta_lineno; charno = flex_fta_ch;};
1378 gb_list_t *append(gb_t *s){
1379 gb_list.push_back(s);
1382 gb_list_t(int l, int c) : lineno(l), charno(c){ }
1384 std::string to_string(){
1387 for(i=0;i<gb_list.size();i++){
1388 if(i>0) retval.append(", ");
1389 retval.append(gb_list[i]->to_string());
1394 std::vector<gb_t *> get_gb_list(){return gb_list; };
1396 gb_list_t *duplicate(){
1397 gb_list_t *ret = new gb_list_t(lineno, charno);
1399 for(i=0;i<gb_list.size();++i){
1400 ret->append(gb_list[i]->duplicate());
1409 class list_of_gb_list_t{
1411 std::vector<gb_list_t *> gb_lists;
1413 list_of_gb_list_t(gb_list_t *gl){
1414 gb_lists.push_back(gl);
1417 list_of_gb_list_t *append(gb_list_t *gl){
1418 gb_lists.push_back(gl);
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{
1429 extended_gb_type type;
1431 std::vector<gb_list_t *> gb_lists;
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;
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);
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);
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;
1469 extended_gb_t *duplicate(){
1470 extended_gb_t *ret = new extended_gb_t();
1473 ret->gb = gb->duplicate();
1475 for(i=0;i<gb_lists.size();++i){
1476 ret->gb_lists.push_back(gb_lists[i]->duplicate());
1482 std::string to_string(){
1488 return "Error, undefined extended gb type.";
1490 return gb->to_string();
1491 case rollup_egb_type:
1492 return "ROLLUP("+gb_lists[0]->to_string()+")";
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){
1499 ret += "(" +gb_lists[i]->to_string()+")";
1506 return "Error, unknown extended gb type.";
1511 class extended_gb_list_t{
1513 std::vector<extended_gb_t *> gb_list;
1516 extended_gb_list_t(extended_gb_t *g){gb_list.push_back(g);
1517 lineno = flex_fta_lineno; charno = flex_fta_ch;};
1519 extended_gb_list_t *append(extended_gb_t *s){
1520 gb_list.push_back(s);
1524 std::string to_string(){
1527 for(i=0;i<gb_list.size();i++){
1528 if(i>0) retval.append(", ");
1529 retval.append(gb_list[i]->to_string());
1534 std::vector<extended_gb_t *> get_gb_list(){return gb_list; };
1540 A predicate tree. Structure is similar to
1541 a scalar expression tree but the type is always boolean.
1543 opt_where_clause, where_clause, opt_having_clause,
1544 search_condition, predicate, comparison_predicate, repl_predicate
1547 #define PRED_COMPARE 1
1548 #define PRED_UNARY_OP 2
1549 #define PRED_BINARY_OP 3
1566 std::vector<scalarexp_t *> param_list; /// pred fcn params
1567 int fcn_id; /// external pred fcn id
1569 bool is_sampling_fcn;
1572 predicate_t(scalarexp_t *s, literal_list_t *litl){
1573 operator_type = PRED_IN;
1578 combinable_ref = -1;
1579 lineno = flex_fta_lineno; charno = flex_fta_ch;
1582 predicate_t(scalarexp_t *s, std::vector<literal_t *> litv){
1583 operator_type = PRED_IN;
1586 rhs.ll = new literal_list_t(litv);
1588 combinable_ref = -1;
1589 lineno = flex_fta_lineno; charno = flex_fta_ch;
1593 predicate_t(scalarexp_t *l_op, const char *o, scalarexp_t *r_op){
1594 operator_type = PRED_COMPARE;
1599 combinable_ref = -1;
1600 lineno = flex_fta_lineno; charno = flex_fta_ch;
1603 predicate_t(const char *o, predicate_t *p){
1604 operator_type = PRED_UNARY_OP;
1608 combinable_ref = -1;
1609 lineno = flex_fta_lineno; charno = flex_fta_ch;
1612 predicate_t(const char *o, predicate_t *l_p, predicate_t *r_p){
1613 operator_type = PRED_BINARY_OP;
1618 combinable_ref = -1;
1619 lineno = flex_fta_lineno; charno = flex_fta_ch;
1622 predicate_t(const char *o, std::vector<scalarexp_t *> op_list){
1623 operator_type = PRED_FUNC;
1625 param_list = op_list;
1627 combinable_ref = -1;
1628 lineno = flex_fta_lineno; charno = flex_fta_ch;
1631 predicate_t(const char *o){
1634 combinable_ref = -1;
1635 lineno = flex_fta_lineno; charno = flex_fta_ch;
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;
1643 ret->combinable_ref = -1;
1647 std::string to_string(){
1648 if(operator_type == PRED_IN){
1649 return( lhs.sexp->to_string() + " " + op + " [ " + rhs.ll->to_string() +" ]");
1651 if(operator_type == PRED_COMPARE){
1652 return( lhs.sexp->to_string() + " " + op + " " + rhs.sexp->to_string() );
1654 if(operator_type == PRED_UNARY_OP){
1655 return( op + " (" + lhs.predp->to_string() + ")" );
1657 if(operator_type == PRED_BINARY_OP){
1658 return( "(" + lhs.predp->to_string() + " " + op + " " + rhs.predp->to_string() + ")" );
1660 if(operator_type == PRED_FUNC){
1661 std::string ret = op + "[ ";
1663 for(i=0;i<param_list.size();++i){
1664 if(i>0) ret += ", ";
1665 ret += param_list[i]->to_string();
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()); };
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);
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;}
1698 void set_fcn_id(int i){fcn_id = i;};
1699 int get_fcn_id(){return fcn_id;};
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
1711 #define SELECT_QUERY 1
1712 #define MERGE_QUERY 2
1713 #define WATCHLIST_QUERY 3
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
1732 field_entry_list * fel; // List of watchlist fields
1734 bool exernal_visible; // true iff. it can be subscribed to.
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;
1745 supergb = sg->get_clist();
1747 query_type = SELECT_QUERY;
1748 exernal_visible = true;
1749 lineno = flex_fta_lineno; charno = flex_fta_ch;
1752 table_exp_t(colref_list_t *mv, tablevar_list_t *f)
1753 {fm = f; mergevars=mv->get_clist();
1755 query_type = MERGE_QUERY;
1756 exernal_visible = true;
1757 lineno = flex_fta_lineno; charno = flex_fta_ch;
1760 table_exp_t(colref_list_t *mv, scalarexp_t *sl, tablevar_list_t *f)
1761 {fm = f; mergevars=mv->get_clist();
1763 query_type = MERGE_QUERY;
1764 exernal_visible = true;
1765 lineno = flex_fta_lineno; charno = flex_fta_ch;
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();
1774 for(t=0;t<src_tbls.size();++t){
1775 ret->fm->append_table(new tablevar_t(src_tbls[t].c_str()));
1777 ret->lineno = 0; ret->charno = 0;
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;
1787 ret->fm= new tablevar_list_t(); // generic analyses need the fm clause
1790 ret->cleaning_when=NULL;
1791 ret->cleaning_by=NULL;
1792 ret->closing_when=NULL;
1794 ret->exernal_visible = true;
1795 ret->lineno = flex_fta_lineno; ret->charno = flex_fta_ch;
1801 fm = NULL; sl = NULL; wh=NULL; hv=NULL;
1803 cleaning_when=NULL; cleaning_by = NULL;
1804 closing_when = NULL;
1805 exernal_visible = true;
1808 table_exp_t *add_selection(select_list_t *s){
1813 void add_nmap(var_defs_t *vd){
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());
1823 void add_param_list(var_defs_t *vd){
1826 query_params = vd->get_nvec();
1831 std::string to_string(){
1834 retval.append("Select " + sl->to_string() + "\n");
1837 retval.append("From " + fm->to_string() + "\n");
1840 retval.append("Where "+ wh->to_string() + "\n");
1843 retval.append("Having "+hv->to_string() + "\n");
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;};
1859 ss_map get_name_map(){return nmap;};
1861 bool name_exists(std::string nm){
1862 return(nmap.count(nm) > 0);
1865 std::string get_val_of_name(std::string nm){
1866 if(nmap.count(nm) == 0) return("");
1867 else return nmap[nm];
1870 void set_val_of_name(const std::string n, const std::string v){
1874 void set_visible(bool v){exernal_visible=v;};
1875 bool get_visible(){return exernal_visible;};
1878 struct query_list_t{
1879 std::vector<table_exp_t *> qlist;
1881 query_list_t(table_exp_t *t){
1884 query_list_t *append(table_exp_t *t){
1891 #define TABLE_PARSE 1
1892 #define QUERY_PARSE 2
1893 #define STREAM_PARSE 3
1896 query_list_t *parse_tree_list;
1897 table_exp_t *fta_parse_tree;
1906 extern table_exp_t *fta_parse_tree;