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
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 FILTER_JOIN_PROPERTY 4
698 // tablevar_list_t is the list of tablevars in a FROM clause
700 struct tablevar_list_t{
702 std::vector<tablevar_t *> tlist;
706 colref_t *temporal_var;
707 unsigned int temporal_range;
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;};
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;
722 for(i=0;i<tlist.size();++i){
723 ret->append_table(tlist[i]->duplicate());
730 tablevar_list_t *append_table(tablevar_t *t){
735 std::string to_string(){
739 for(i=0;i<tlist.size();i++){
740 if(i>0) retval.append(", ");
741 retval.append(tlist[i]->to_string());
746 std::vector<tablevar_t *> get_table_list(){return(tlist); };
748 std::vector<std::string> get_table_names(){
749 std::vector<std::string> ret;
751 for(t=0;t<tlist.size();++t){
752 std::string tbl_name = tlist[t]->get_schema_name();
753 ret.push_back(tbl_name);
758 std::vector<std::string> get_src_tbls(table_list *Schema){
759 std::vector<std::string> ret;
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);
766 if(Schema->get_schema_type(sid) != OPERATOR_VIEW_SCHEMA){
767 ret.push_back(tbl_name);
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);
782 // Some accessor functions.
784 std::vector<std::string> get_schema_names(){
786 std::vector<std::string > retval;
787 for(i=0;i<tlist.size();i++){
788 retval.push_back(tlist[i]->get_schema_name());
793 std::vector<int> get_schema_refs(){
795 std::vector<int> retval;
796 for(i=0;i<tlist.size();i++){
797 retval.push_back(tlist[i]->get_schema_ref());
803 int get_schema_ref(int i){
804 if(i<0 || i>=tlist.size()) return(-1);
805 return tlist[i]->get_schema_ref();
808 std::string get_tablevar_name(int i){
809 if(i<0 || i>=tlist.size()) return("");
810 return tlist[i]->get_var_name();
813 void set_properties(int p){properties = p;};
814 int get_properties(){return properties;};
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;};
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).
829 std::string tablevar;
834 ifpref_t(const char *p){
838 lineno = flex_fta_lineno; charno = flex_fta_ch;
841 ifpref_t(const char *t, const char *p){
845 lineno = flex_fta_lineno; charno = flex_fta_ch;
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(){
856 ret += tablevar + ".";
860 bool is_equivalent(ifpref_t *i){
861 return (tablevar_ref == i->tablevar_ref) && (pname == i->pname);
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.
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).
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;
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;
897 colref_t(const char *i, const char *t, const char *f){
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;
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;
914 std::string to_string(){
918 if(interface != "") return(interface+"."+table_name+"."+field);
919 return(table_name + "." + field);
923 std::string to_query_string(){
927 if(interface != "") return(interface+"."+table_name+"."+field);
928 if(table_name != "") return(table_name + "." + field);
933 int get_lineno(){return lineno; };
934 int get_charno(){return charno; };
936 bool uses_default_table(){return default_table; };
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;};
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;};
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);
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);
969 std::vector<colref_t *> clist;
971 // colref_list_t(){};
973 colref_list_t(colref_t *c){
977 colref_list_t *append(colref_t *c){
982 std::vector<colref_t *> get_clist(){
993 A tree containing a scalar expression.
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
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.
1006 #define SE_LITERAL 1
1009 #define SE_UNARY_OP 4
1010 #define SE_BINARY_OP 5
1011 #define SE_AGGR_STAR 6
1012 #define SE_AGGR_SE 7
1014 #define SE_IFACE_PARAM 9
1022 scalarexp_t *scalarp;
1028 scalarexp_t *scalarp;
1030 std::vector<scalarexp_t *> param_list;
1032 // SE node decorations -- results of query analysis.
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,
1047 void default_init(){
1049 gb_ref = -1; aggr_id = -1; fcn_id = -1;
1050 partial_ref = -1; fcn_cache_ref=-1;
1052 dt = NULL; lineno = flex_fta_lineno; charno = flex_fta_ch;
1053 is_superagg = false;
1059 scalarexp_t(colref_t *c){
1061 operator_type = SE_COLREF;
1065 scalarexp_t(literal_t *l){
1067 operator_type = SE_LITERAL;
1071 void convert_to_literal(literal_t *l){
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");
1077 operator_type = SE_LITERAL;
1081 scalarexp_t(const char *o, scalarexp_t *operand){
1083 operator_type = SE_UNARY_OP;
1085 lhs.scalarp = operand;
1088 scalarexp_t(const char *o, scalarexp_t *l_op, scalarexp_t *r_op){
1090 operator_type = SE_BINARY_OP;
1096 scalarexp_t(const char *o, std::vector<scalarexp_t *> op_list){
1098 operator_type = SE_FUNC;
1100 param_list = op_list;
1103 static scalarexp_t *make_paramless_fcn(const char *o){
1104 scalarexp_t *ret = new scalarexp_t();
1105 ret->operator_type = SE_FUNC;
1110 static scalarexp_t *make_star_aggr(const char *ag){
1111 scalarexp_t *ret = new scalarexp_t();
1112 ret->operator_type = SE_AGGR_STAR;
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;
1121 ret->lhs.scalarp = l_op;
1125 static scalarexp_t *make_param_reference(const char *param){
1126 scalarexp_t *ret = new scalarexp_t();
1127 ret->operator_type = SE_PARAM;
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;
1140 std::string to_string(){
1141 if(operator_type == SE_COLREF){
1142 return lhs.colref->to_string();
1144 if(operator_type == SE_LITERAL){
1145 return lhs.litp->to_string();
1147 if(operator_type == SE_UNARY_OP){
1148 return op + " (" + lhs.scalarp->to_string() + ")";
1150 if(operator_type == SE_BINARY_OP){
1151 return "(" + lhs.scalarp->to_string() + " " + op + " " + rhs.scalarp->to_string() + ")";
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; };
1166 int get_lineno(){return lineno; };
1167 int get_charno(){return charno; };
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();}
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); };
1177 void set_aggr_id(int a){aggr_id = a;};
1178 int get_aggr_ref(){return(aggr_id); };
1180 void set_storage_state(std::string s){storage_state = s;};
1181 std::string get_storage_state(){return storage_state;};
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; };
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; };
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; };
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; };
1199 void set_superaggr(bool b){is_superagg=b;};
1200 bool is_superaggr(){return is_superagg;};
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;
1218 A (null terminated) list of scalar expressions.
1220 selection, scalar_exp_commalist
1225 std::vector<scalarexp_t *> se_list;
1228 se_list_t(scalarexp_t *s){se_list.push_back(s);
1229 lineno = flex_fta_lineno; charno = flex_fta_ch;};
1231 se_list_t *append(scalarexp_t *s){
1232 se_list.push_back(s);
1236 std::string to_string(){
1239 for(i=0;i<se_list.size();i++){
1240 if(i>0) retval.append(", ");
1241 retval.append(se_list[i]->to_string());
1246 std::vector<scalarexp_t *> get_se_list(){return se_list; };
1252 select_commalist : collect some additional info about
1253 the selected things -- mostly the name.
1256 struct select_element{
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;};
1265 class select_list_t{
1267 std::vector<select_element *> select_list;
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;
1277 select_list_t *append(scalarexp_t *s){
1278 select_list.push_back(new select_element(s));
1281 select_list_t *append(scalarexp_t *s, std::string n){
1282 select_list.push_back(new select_element(s,n));
1286 std::string to_string(){
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;
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;
1303 for(i=0; i<select_list.size();++i) ret.push_back(select_list[i]->se);
1311 #define GB_COMPUTED 2
1317 std::string interface;
1322 gb_t(const char *field_name){
1324 name = field_name; table=""; def=NULL; type=GB_COLREF;
1325 lineno = flex_fta_lineno; charno = flex_fta_ch;
1328 gb_t(const char *table_name, const char *field_name){
1330 name = field_name; table=""; def=NULL; type=GB_COLREF;
1331 lineno = flex_fta_lineno; charno = flex_fta_ch;
1334 gb_t(const char *iface, const char *table_name, const char *field_name){
1336 name = field_name; table=""; def=NULL; type=GB_COLREF;
1337 lineno = flex_fta_lineno; charno = flex_fta_ch;
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;
1345 std::string to_string(){
1347 if(type == GB_COLREF){
1352 retval.append(name);
1354 if(type == GB_COMPUTED){
1355 retval = "(scalarexp) AS ";
1356 retval.append(name);
1366 A (null terminated) list of group by attributes
1371 std::vector<gb_t *> gb_list;
1374 gb_list_t(gb_t *g){gb_list.push_back(g);
1375 lineno = flex_fta_lineno; charno = flex_fta_ch;};
1377 gb_list_t *append(gb_t *s){
1378 gb_list.push_back(s);
1381 gb_list_t(int l, int c) : lineno(l), charno(c){ }
1383 std::string to_string(){
1386 for(i=0;i<gb_list.size();i++){
1387 if(i>0) retval.append(", ");
1388 retval.append(gb_list[i]->to_string());
1393 std::vector<gb_t *> get_gb_list(){return gb_list; };
1395 gb_list_t *duplicate(){
1396 gb_list_t *ret = new gb_list_t(lineno, charno);
1398 for(i=0;i<gb_list.size();++i){
1399 ret->append(gb_list[i]->duplicate());
1408 class list_of_gb_list_t{
1410 std::vector<gb_list_t *> gb_lists;
1412 list_of_gb_list_t(gb_list_t *gl){
1413 gb_lists.push_back(gl);
1416 list_of_gb_list_t *append(gb_list_t *gl){
1417 gb_lists.push_back(gl);
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{
1428 extended_gb_type type;
1430 std::vector<gb_list_t *> gb_lists;
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;
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);
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);
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;
1468 extended_gb_t *duplicate(){
1469 extended_gb_t *ret = new extended_gb_t();
1472 ret->gb = gb->duplicate();
1474 for(i=0;i<gb_lists.size();++i){
1475 ret->gb_lists.push_back(gb_lists[i]->duplicate());
1481 std::string to_string(){
1487 return "Error, undefined extended gb type.";
1489 return gb->to_string();
1490 case rollup_egb_type:
1491 return "ROLLUP("+gb_lists[0]->to_string()+")";
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){
1498 ret += "(" +gb_lists[i]->to_string()+")";
1505 return "Error, unknown extended gb type.";
1510 class extended_gb_list_t{
1512 std::vector<extended_gb_t *> gb_list;
1515 extended_gb_list_t(extended_gb_t *g){gb_list.push_back(g);
1516 lineno = flex_fta_lineno; charno = flex_fta_ch;};
1518 extended_gb_list_t *append(extended_gb_t *s){
1519 gb_list.push_back(s);
1523 std::string to_string(){
1526 for(i=0;i<gb_list.size();i++){
1527 if(i>0) retval.append(", ");
1528 retval.append(gb_list[i]->to_string());
1533 std::vector<extended_gb_t *> get_gb_list(){return gb_list; };
1539 A predicate tree. Structure is similar to
1540 a scalar expression tree but the type is always boolean.
1542 opt_where_clause, where_clause, opt_having_clause,
1543 search_condition, predicate, comparison_predicate, repl_predicate
1546 #define PRED_COMPARE 1
1547 #define PRED_UNARY_OP 2
1548 #define PRED_BINARY_OP 3
1565 std::vector<scalarexp_t *> param_list; /// pred fcn params
1566 int fcn_id; /// external pred fcn id
1568 bool is_sampling_fcn;
1571 predicate_t(scalarexp_t *s, literal_list_t *litl){
1572 operator_type = PRED_IN;
1577 combinable_ref = -1;
1578 lineno = flex_fta_lineno; charno = flex_fta_ch;
1581 predicate_t(scalarexp_t *s, std::vector<literal_t *> litv){
1582 operator_type = PRED_IN;
1585 rhs.ll = new literal_list_t(litv);
1587 combinable_ref = -1;
1588 lineno = flex_fta_lineno; charno = flex_fta_ch;
1592 predicate_t(scalarexp_t *l_op, const char *o, scalarexp_t *r_op){
1593 operator_type = PRED_COMPARE;
1598 combinable_ref = -1;
1599 lineno = flex_fta_lineno; charno = flex_fta_ch;
1602 predicate_t(const char *o, predicate_t *p){
1603 operator_type = PRED_UNARY_OP;
1607 combinable_ref = -1;
1608 lineno = flex_fta_lineno; charno = flex_fta_ch;
1611 predicate_t(const char *o, predicate_t *l_p, predicate_t *r_p){
1612 operator_type = PRED_BINARY_OP;
1617 combinable_ref = -1;
1618 lineno = flex_fta_lineno; charno = flex_fta_ch;
1621 predicate_t(const char *o, std::vector<scalarexp_t *> op_list){
1622 operator_type = PRED_FUNC;
1624 param_list = op_list;
1626 combinable_ref = -1;
1627 lineno = flex_fta_lineno; charno = flex_fta_ch;
1630 predicate_t(const char *o){
1633 combinable_ref = -1;
1634 lineno = flex_fta_lineno; charno = flex_fta_ch;
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;
1642 ret->combinable_ref = -1;
1646 std::string to_string(){
1647 if(operator_type == PRED_IN){
1648 return( lhs.sexp->to_string() + " " + op + " [ " + rhs.ll->to_string() +" ]");
1650 if(operator_type == PRED_COMPARE){
1651 return( lhs.sexp->to_string() + " " + op + " " + rhs.sexp->to_string() );
1653 if(operator_type == PRED_UNARY_OP){
1654 return( op + " (" + lhs.predp->to_string() + ")" );
1656 if(operator_type == PRED_BINARY_OP){
1657 return( "(" + lhs.predp->to_string() + " " + op + " " + rhs.predp->to_string() + ")" );
1659 if(operator_type == PRED_FUNC){
1660 std::string ret = op + "[ ";
1662 for(i=0;i<param_list.size();++i){
1663 if(i>0) ret += ", ";
1664 ret += param_list[i]->to_string();
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()); };
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);
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;}
1697 void set_fcn_id(int i){fcn_id = i;};
1698 int get_fcn_id(){return fcn_id;};
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
1710 #define SELECT_QUERY 1
1711 #define MERGE_QUERY 2
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.
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;
1740 supergb = sg->get_clist();
1742 query_type = SELECT_QUERY;
1743 exernal_visible = true;
1744 lineno = flex_fta_lineno; charno = flex_fta_ch;
1747 table_exp_t(colref_list_t *mv, tablevar_list_t *f)
1748 {fm = f; mergevars=mv->get_clist();
1750 query_type = MERGE_QUERY;
1751 exernal_visible = true;
1752 lineno = flex_fta_lineno; charno = flex_fta_ch;
1755 table_exp_t(colref_list_t *mv, scalarexp_t *sl, tablevar_list_t *f)
1756 {fm = f; mergevars=mv->get_clist();
1758 query_type = MERGE_QUERY;
1759 exernal_visible = true;
1760 lineno = flex_fta_lineno; charno = flex_fta_ch;
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();
1769 for(t=0;t<src_tbls.size();++t){
1770 ret->fm->append_table(new tablevar_t(src_tbls[t].c_str()));
1772 ret->lineno = 0; ret->charno = 0;
1777 fm = NULL; sl = NULL; wh=NULL; hv=NULL;
1779 cleaning_when=NULL; cleaning_by = NULL;
1780 closing_when = NULL;
1781 exernal_visible = true;
1784 table_exp_t *add_selection(select_list_t *s){
1789 void add_nmap(var_defs_t *vd){
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());
1799 void add_param_list(var_defs_t *vd){
1802 query_params = vd->get_nvec();
1807 std::string to_string(){
1810 retval.append("Select " + sl->to_string() + "\n");
1813 retval.append("From " + fm->to_string() + "\n");
1816 retval.append("Where "+ wh->to_string() + "\n");
1819 retval.append("Having "+hv->to_string() + "\n");
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;};
1835 ss_map get_name_map(){return nmap;};
1837 bool name_exists(std::string nm){
1838 return(nmap.count(nm) > 0);
1841 std::string get_val_of_name(std::string nm){
1842 if(nmap.count(nm) == 0) return("");
1843 else return nmap[nm];
1846 void set_val_of_name(const std::string n, const std::string v){
1850 void set_visible(bool v){exernal_visible=v;};
1851 bool get_visible(){return exernal_visible;};
1854 struct query_list_t{
1855 std::vector<table_exp_t *> qlist;
1857 query_list_t(table_exp_t *t){
1860 query_list_t *append(table_exp_t *t){
1867 #define TABLE_PARSE 1
1868 #define QUERY_PARSE 2
1869 #define STREAM_PARSE 3
1872 query_list_t *parse_tree_list;
1873 table_exp_t *fta_parse_tree;
1882 extern table_exp_t *fta_parse_tree;