-/* ------------------------------------------------\r
-Copyright 2014 AT&T Intellectual Property\r
- Licensed under the Apache License, Version 2.0 (the "License");\r
- you may not use this file except in compliance with the License.\r
- You may obtain a copy of the License at\r
-\r
- http://www.apache.org/licenses/LICENSE-2.0\r
-\r
- Unless required by applicable law or agreed to in writing, software\r
- distributed under the License is distributed on an "AS IS" BASIS,\r
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- See the License for the specific language governing permissions and\r
- limitations under the License.\r
- ------------------------------------------- */\r
-#ifndef _FTA_PARSE_H_INCLUDED__\r
-#define _FTA_PARSE_H_INCLUDED__\r
-\r
-#include<stdio.h>\r
-#include<ctype.h>\r
-\r
- int yyparse();\r
- void yyerror(char *s);\r
- int yylex();\r
-extern int flex_fta_lineno, flex_fta_ch;\r
-\r
-/* Interface to FTA Parser */\r
-void FtaParser_setfileinput(FILE *f);\r
-void FtaParser_setstringinput(char *s);\r
-\r
-\r
-/* Get type defines. */\r
-#include"type_objects.h"\r
-#include"literal_types.h"\r
-#include"type_indicators.h"\r
-\r
-#include <string>\r
-#include <vector>\r
-#include <map>\r
-#include <math.h>\r
-#include <string>\r
-#include <stdio.h>\r
-#include <stdlib.h>\r
-\r
-\r
-// colref_t::is_equivalent needs to understand the schema\r
-#include"parse_schema.h"\r
-class colref_t;\r
-\r
-\r
-\r
-class var_pair_t{\r
-public:\r
- std::string name;\r
- std::string val;\r
-\r
- var_pair_t(char *n, char *v){\r
- name=n; val=v;\r
-//printf("NEW var_pair_t(%s, %s)\n",n,v);\r
- };\r
-\r
- var_pair_t(const std::string n, const std::string v){\r
- name=n; val=v;\r
- };\r
-};\r
-\r
-typedef std::map< std::string, std::string > ss_map;\r
-\r
-class var_defs_t{\r
-private:\r
- std::vector<var_pair_t *> namevec;\r
-\r
-public:\r
- var_defs_t(var_pair_t *vp){\r
- namevec.push_back(vp);\r
- };\r
-\r
- var_defs_t *add_var_pair(var_pair_t *vp){\r
- namevec.push_back(vp);\r
- return(this);\r
- };\r
-\r
- std::vector<var_pair_t *> get_nvec(){return namevec;};\r
-\r
- int size(){return namevec.size();};\r
-\r
- int find_name(std::string n){\r
- int i;\r
- for(i=0;i<namevec.size();i++){\r
- if(namevec[i]->name == n)\r
- return i;\r
- }\r
- return -1;\r
- }\r
- std::string get_name(int i){\r
- if(i>=0 && i<namevec.size()){\r
- return(namevec[i]->name);\r
- }else{\r
- return("");\r
- }\r
- }\r
-\r
- std::string get_def(int i){\r
- if(i>=0 && i<namevec.size()){\r
- return(namevec[i]->val);\r
- }else{\r
- return("");\r
- }\r
- }\r
-\r
- std::string dump(){\r
- int i;\r
- std::string ret;\r
- for(i=0;i<namevec.size();++i){\r
- ret += "\t"+namevec[i]->name+" = "+namevec[i]->val+"\n";\r
- }\r
- return ret;\r
- }\r
-\r
-};\r
-\r
-\r
-\r
-\r
-// literal type constants are defined in literal_types.h\r
-// (must share this info with type_objects.h)\r
-\r
-// Represents a literal, as expected\r
-// NOTE: this class contains some code generation methods.\r
-\r
-class literal_t{\r
-private:\r
-\r
-public:\r
- std::string lstring; /* literal value */\r
- short int ltype; /* literal type */\r
- int lineno, charno;\r
-\r
- int complex_literal_id; // if this literal has a complex constructor,\r
- // there is a function which constructs it)\r
- //set to the idx in the complex literal\r
- // table. (Must store this here (instead of in SE)\r
- // because of bare literals in the IN predicate).\r
-\r
-\r
- literal_t(std::string v){\r
- lstring = v;\r
- ltype = LITERAL_STRING;\r
- complex_literal_id = -1;\r
- lineno = flex_fta_lineno; charno = flex_fta_ch;\r
- }\r
- static literal_t *make_define_literal(const char *s, var_defs_t *d){\r
- int i;\r
- i=d->find_name(s);\r
- if(i<0){\r
- 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);\r
- exit(1);\r
- }\r
- return new literal_t(d->get_def(i));\r
- }\r
-\r
- literal_t(const char *lit, int t){lstring = lit; ltype = t;\r
- lineno = flex_fta_lineno; charno = flex_fta_ch;\r
- complex_literal_id = -1;\r
-\r
-// For some datatypes we need to modify literal so make a copy of the string\r
- char v[100];\r
- strcpy(v, lit);\r
-\r
-// Remove UL, ULL suffix from INT constants.\r
- if(ltype == LITERAL_INT || ltype == LITERAL_LONGINT){\r
- int i;\r
- int len=strlen(v);\r
- for(i=0;i<len;++i){\r
- if(v[i] == 'U') v[i] = '\0';\r
- }\r
- lstring = v;\r
- }\r
-\r
-// HEX and LONGHEX must be converted to uint (long long uint)\r
- if(ltype == LITERAL_HEX){\r
- char *c,ltmpstr[100];\r
- unsigned long tmp_l;\r
- for(c=v; (*c)!='\0';++c){\r
- if(! ( ((*c) >= '0' && (*c) <= '9') || (tolower(*c) >= 'a' && tolower(*c) <= 'f') ) ){\r
- fprintf(stderr,"Syntax Error, line=%d, character=%d. The literal %s is not a HEX constant.\n",\r
- lineno, charno, v);\r
- exit(1);\r
- }\r
- }\r
- sscanf(v,"%lx",&tmp_l);\r
- sprintf(ltmpstr,"%lu",tmp_l);\r
- lstring = ltmpstr;\r
- ltype = LITERAL_INT;\r
- }\r
- if(ltype == LITERAL_LONGHEX){\r
- char *c,ltmpstr[100];\r
- unsigned long long tmp_ll;\r
- for(c=v; (*c)!='\0';++c){\r
- if(! ( ((*c) >= '0' && (*c) <= '9') || (tolower(*c) >= 'a' && tolower(*c) <= 'f') ) ){\r
- fprintf(stderr,"Syntax Error, line=%d, character=%d. The literal %s is not a LHEX constant.\n",\r
- lineno, charno, v);\r
- exit(1);\r
- }\r
- }\r
- sscanf(v,"%llx",&tmp_ll);\r
- sprintf(ltmpstr,"%llu",tmp_ll);\r
- lstring = ltmpstr;\r
- ltype = LITERAL_LONGINT;\r
- }\r
-// Convert IP to uint\r
- if(ltype == LITERAL_IP){\r
- char ltmpstr[100];\r
- unsigned int o1,o2,o3,o4,tmp_l;\r
- if(sscanf(v,"%u.%u.%u.%u",&o1,&o2,&o3,&o4) != 4){\r
- fprintf(stderr,"Syntax Error, line=%d, character=%d. The literal %s is not an IP constant.\n",\r
- lineno, charno, v);\r
- exit(1);\r
- }\r
- if( (o1>255) || (o2>255) || (o3>255) || (o4>255) ){\r
- fprintf(stderr,"Syntax Error, line=%d, character=%d. The literal %s is not an IP constant.\n",\r
- lineno, charno, v);\r
- exit(1);\r
- }\r
- tmp_l = (o1<<24)+(o2<<16)+(o3<<8)+o4;\r
- sprintf(ltmpstr,"%u",tmp_l);\r
- lstring = ltmpstr;\r
- ltype = LITERAL_IP;\r
- }\r
- };\r
-\r
-// used to create literals with a default or initial value.\r
- literal_t(int type_indicator){\r
- lineno=-1; charno=-1;\r
- complex_literal_id = -1;\r
-\r
- switch(type_indicator){\r
- case UINT_TYPE:\r
- case INT_TYPE:\r
- case USHORT_TYPE:\r
- ltype = LITERAL_INT;\r
- lstring = "0";\r
- break;\r
- case ULLONG_TYPE:\r
- case LLONG_TYPE:\r
- ltype = LITERAL_LONGINT;\r
- lstring = "0";\r
- break;\r
- case FLOAT_TYPE:\r
- ltype = LITERAL_FLOAT;\r
- lstring = "0.0";\r
- break;\r
- case BOOL_TYPE:\r
- ltype = LITERAL_BOOL;\r
- lstring = "FALSE";\r
- break;\r
- case VSTR_TYPE:\r
- ltype = LITERAL_STRING;\r
- lstring = ""; complex_literal_id = 0; // unregistred complex lit\r
- break;\r
- case TIMEVAL_TYPE:\r
- ltype = LITERAL_TIMEVAL;\r
- lstring = "0.0";\r
- break;\r
- case IPV6_TYPE:\r
- ltype = LITERAL_IPV6;\r
- lstring = "0000:0000:0000:0000:0000:0000:0000:0000";\r
- complex_literal_id = 0; // unregistered complex literal\r
- break;\r
- case IP_TYPE:\r
- ltype = LITERAL_IP;\r
- lstring = "0";\r
- break;\r
- default:\r
- ltype = LITERAL_UDEF;\r
- lstring=" INTERNAL ERROR, UNKNOWN TYPE INDICATOR IN literal_t::literal_t(int) ";\r
- }\r
- };\r
-\r
- std::string to_string(){return lstring;};\r
-\r
- int get_type(){return ltype; };\r
- int get_lineno(){return lineno; };\r
- int get_charno(){return charno; };\r
-\r
- bool is_equivalent(literal_t *l2){\r
- if(ltype != l2->ltype)\r
- return(false);\r
- if(lstring != l2->lstring)\r
- return(false);\r
-\r
- return(true);\r
- };\r
-\r
-// Internal function to unescape control characters.\r
- static std::string gsqlstr_to_cstr(std::string s){\r
- std::string retval;\r
- unsigned char c, prev_c='\0';\r
- int i;\r
-\r
- for(i=0;i<s.size();++i){\r
- c = s[i];\r
- if(c=='\''){ // || c=='\\'\r
- if(prev_c==c){\r
- retval += c;\r
- prev_c = '\0';\r
- }else{\r
- prev_c=c;\r
- }\r
- continue;\r
- }\r
-\r
- retval += c;\r
- prev_c = c;\r
- }\r
-\r
- return retval;\r
- }\r
-\r
-\r
-\r
- std::string to_hfta_C_code(std::string param){\r
- std::string retval;\r
- double tmp_f;\r
- int secs, millisecs;\r
- char tmpstr[100];\r
-\r
- switch(ltype){\r
- case LITERAL_STRING:\r
- retval.append(this->hfta_constructor_name() );\r
- retval.append("("+param+",\"");\r
- retval.append(gsqlstr_to_cstr(lstring));\r
- retval.append("\")");\r
- return(retval);\r
- case LITERAL_INT:\r
- case LITERAL_IP:\r
- return("((gs_uint32_t)"+lstring+")");\r
- case LITERAL_LONGINT:\r
- return("((gs_uint64_t)"+lstring+")");\r
- case LITERAL_FLOAT:\r
- return(lstring);\r
-// case LITERAL_HEX:\r
-// return("0x"+lstring);\r
- case LITERAL_BOOL:\r
- if(lstring == "TRUE"){\r
- return("1");\r
- }else{\r
- return("0");\r
- }\r
- case LITERAL_TIMEVAL:\r
- retval.append(this->hfta_constructor_name() );\r
- tmp_f = atof(lstring.c_str());\r
- secs = (int)floor(tmp_f);\r
- millisecs = (int) rint((tmp_f - secs)*1000);\r
- sprintf(tmpstr,"(%d, %d)",secs,millisecs);\r
- retval.append(tmpstr);\r
- return(retval);\r
- case LITERAL_IPV6:\r
- retval = this->hfta_constructor_name();\r
- retval += "("+param+",\""+lstring+"\")";\r
- return retval;\r
- }\r
-\r
- return("ERROR UNKNOWN LITERAL");\r
- };\r
-\r
-\r
-/// for LFTA code generation\r
- std::string to_C_code(std::string param){\r
- std::string retval;\r
- double tmp_f;\r
- int secs, millisecs;\r
- char tmpstr[100];\r
-\r
- switch(ltype){\r
- case LITERAL_STRING:\r
- retval = this->constructor_name()+"("+param+",\""+gsqlstr_to_cstr(lstring)+"\")";\r
- return(retval);\r
- case LITERAL_INT:\r
- case LITERAL_IP:\r
- return("((gs_uint32_t)"+lstring+")");\r
- case LITERAL_LONGINT:\r
- return("((gs_uint64_t)"+lstring+")");\r
- case LITERAL_FLOAT:\r
- return(lstring);\r
-// case LITERAL_HEX:\r
-// return("0x"+lstring);\r
- case LITERAL_BOOL:\r
- if(lstring == "TRUE"){\r
- return("1");\r
- }else{\r
- return("0");\r
- }\r
- case LITERAL_IPV6:\r
- retval = this->constructor_name()+"("+param+",\""+lstring+"\")";\r
- return(retval);\r
- case LITERAL_TIMEVAL:\r
- retval.append(this->constructor_name() );\r
- tmp_f = atof(lstring.c_str());\r
- secs = (int)floor(tmp_f);\r
- millisecs = (int) rint((tmp_f - secs)*1000);\r
- sprintf(tmpstr,"(%d, %d)",secs,millisecs);\r
- retval.append(tmpstr);\r
- return(retval);\r
- }\r
-\r
- return("ERROR UNKNOWN LITERAL");\r
- };\r
-\r
-\r
- std::string to_query_string(){\r
- std::string retval;\r
-\r
- switch(ltype){\r
- case LITERAL_IP:\r
- {\r
- unsigned int v;\r
- sscanf(lstring.c_str(),"%u",&v);\r
- int d1 = v & 0xff;\r
- int d2 = (v & 0xff00) >> 8;\r
- int d3 = (v & 0xff0000) >> 16;\r
- int d4 = (v & 0xff000000) >> 24;\r
- char ret[200];\r
- sprintf(ret,"IP_VAL'%u.%u.%u.%u'",d4,d3,d2,d1);\r
- return ret;\r
- }\r
- case LITERAL_STRING:\r
- retval = "'"+lstring+"'";\r
- return(retval);\r
- case LITERAL_INT:\r
- case LITERAL_FLOAT:\r
- case LITERAL_TIMEVAL:\r
- case LITERAL_IPV6:\r
- case LITERAL_BOOL:\r
- return(lstring);\r
- case LITERAL_LONGINT:\r
- return(lstring+"ULL");\r
- }\r
-\r
- return("ERROR UNKNOWN LITERAL in literal_t::to_query_string");\r
- };\r
-\r
-// TODO : Use definition files instead of hardwiring these.\r
-\r
-// constructor in LFTA code\r
- std::string constructor_name(){\r
-\r
- switch(ltype){\r
- case LITERAL_TIMEVAL:\r
- return("Timeval_Constructor");\r
- case LITERAL_IPV6:\r
- return("Ipv6_Constructor");\r
- case LITERAL_STRING:\r
- return("str_constructor");\r
- case LITERAL_INT:\r
- case LITERAL_IP:\r
- case LITERAL_LONGINT:\r
- case LITERAL_BOOL:\r
- case LITERAL_FLOAT:\r
- return("");\r
- }\r
- return("ERROR UNKNOWN LITERAL");\r
- };\r
-\r
- std::string hfta_constructor_name(){\r
-\r
- switch(ltype){\r
- case LITERAL_TIMEVAL:\r
- return("HFTA_Timeval_Constructor");\r
- case LITERAL_IPV6:\r
- return("HFTA_Ipv6_Constructor");\r
- case LITERAL_STRING:\r
- return("Vstring_Constructor");\r
- case LITERAL_INT:\r
- case LITERAL_IP:\r
- case LITERAL_LONGINT:\r
- case LITERAL_BOOL:\r
- case LITERAL_FLOAT:\r
- return("");\r
- }\r
- return("ERROR UNKNOWN LITERAL");\r
- };\r
-\r
- std::string hfta_empty_literal_name(){\r
-\r
- switch(ltype){\r
- case LITERAL_TIMEVAL:\r
- return("EmptyTimeval");\r
- case LITERAL_IPV6:\r
- return("EmptyIp6");\r
- case LITERAL_STRING:\r
- return("EmptyString");\r
- }\r
- return("ERROR_NOT_A_COMPLEX_LITERAL");\r
- };\r
-\r
-\r
- void set_cpx_lit_ref(int g){complex_literal_id = g; };\r
- int get_cpx_lit_ref(){return (complex_literal_id ); };\r
- bool is_cpx_lit(){return(complex_literal_id >= 0); };\r
-\r
-};\r
-\r
-\r
-/*\r
- A (null terminated) list of literals.\r
- Used for the IN clause\r
-*/\r
-\r
-class literal_list_t{\r
-private:\r
-\r
-public:\r
- std::vector<literal_t *> lit_list;\r
- int lineno, charno;\r
-\r
- literal_list_t(literal_t *l){\r
- lit_list.push_back(l);\r
- lineno = flex_fta_lineno; charno = flex_fta_ch;\r
- };\r
-\r
- literal_list_t(std::vector<literal_t *> lvec){\r
- lineno = charno = 0;\r
- lit_list = lvec;\r
- };\r
-\r
- literal_list_t *append_literal(literal_t *l){\r
- lit_list.push_back(l);\r
- return(this);\r
- };\r
-\r
- std::string to_string(){\r
- int i;\r
- std::string retval;\r
- for(i=0;i<lit_list.size();i++){\r
- if(i>0) retval.append(", ");\r
- retval.append(lit_list[i]->to_query_string());\r
- }\r
- return(retval);\r
- };\r
-\r
- std::vector<literal_t *> get_literal_vector(){return(lit_list);};\r
-\r
-};\r
-\r
-\r
-class string_t{\r
-public:\r
- std::string val;\r
- string_t(char *s){\r
- val = s;\r
- }\r
- string_t *append(char *s){\r
- val += s;\r
- return this;\r
- }\r
- string_t *append(char *sep, char *s){\r
- val += sep;\r
- val += s;\r
- return this;\r
- }\r
- const char *c_str(){\r
- return val.c_str();\r
- }\r
-};\r
-\r
-// A tablevar is a data source in a GSQL query.\r
-// Every column ref must be bound to a tablevar,\r
-// either explicitly or via imputation.\r
-\r
-\r
-class tablevar_t{\r
-public:\r
-// A tablevar is a variable which binds to a named data source.\r
-// the variable name might be explicit in the query, or it might be\r
-// implicit in which case the variable name is imputed. In either case\r
-// the variable name is set via the set_range_var method.\r
-//\r
-// The data source is the name of either a STREAM or a PROTOCOL.\r
-// All STREAMS are unique, but a PROTOCOL must be bound to an\r
-// interface. If the interface is not given, it is imputed to be\r
-// the default interface.\r
-\r
- std::string machine;\r
- std::string interface;\r
- std::string schema_name;\r
- std::string variable_name;\r
- std::string udop_alias; // record UDOP ID for of UDOP\r
- // for use by cluster manager\r
-\r
- int schema_ref; // index of the table in the schema (table_list)\r
- int opview_idx; // index in list of operator views (if any)\r
- bool iface_is_query; // true if iface resolves to query\r
- // instead of specific interface.\r
-\r
- int properties; // inner (0) or outer (1) join;\r
- // labeled using FROM clause,\r
- // determines join algorithm.\r
-\r
- int lineno, charno;\r
-\r
- tablevar_t(){ opview_idx = -1; schema_ref=-1; iface_is_query = false;\r
- lineno=-1; charno=-1;};\r
- tablevar_t(const char *t){schema_name=t; interface="";\r
- opview_idx = -1; schema_ref = -1;\r
- variable_name=""; properties = 0;\r
- iface_is_query = false;\r
- lineno = flex_fta_lineno; charno = flex_fta_ch;};\r
-\r
- tablevar_t(const char *i, const char *s, int iq){interface=i; schema_name=s;\r
- opview_idx = -1; schema_ref = -1;\r
- variable_name=""; properties = 0;\r
- if(iq) iface_is_query = true; else iface_is_query = false;\r
- lineno = flex_fta_lineno; charno = flex_fta_ch;};\r
-\r
- tablevar_t(const char *m, const char *i, const char *s){\r
- machine = m; interface=i; schema_name=s;\r
- opview_idx = -1; schema_ref = -1;\r
- variable_name=""; properties = 0;\r
- iface_is_query = false;\r
- lineno = flex_fta_lineno; charno = flex_fta_ch;};\r
-\r
- tablevar_t *duplicate(){\r
- tablevar_t *ret = new tablevar_t();\r
- ret->lineno = lineno; ret->charno = charno;\r
- ret->schema_ref = schema_ref;\r
- ret->opview_idx = opview_idx;\r
- ret->machine = machine;\r
- ret->interface = interface;\r
- ret->schema_name = schema_name;\r
- ret->variable_name = variable_name;\r
- ret->properties = properties;\r
- ret->iface_is_query = iface_is_query;\r
- return(ret);\r
- };\r
-\r
- tablevar_t *set_range_var(const char *r){\r
- variable_name = r;\r
- return(this);\r
- };\r
- tablevar_t *set_range_var(std::string r){\r
- variable_name = r;\r
- return(this);\r
- };\r
-\r
- void set_schema(std::string s){schema_name = s;};\r
- void set_interface(std::string i){interface=i;};\r
- void set_machine(std::string m){machine = m;};\r
- void set_udop_alias(std::string u){udop_alias = u;};\r
-\r
- void set_schema_ref(int r){schema_ref = r;};\r
- int get_schema_ref(){return schema_ref;};\r
-\r
- void set_opview_idx(int i){opview_idx = i;};\r
- int get_opview_idx(){return opview_idx;};\r
-\r
- void set_property(int p){properties = p;};\r
- int get_property(){return properties;};\r
-\r
- bool get_ifq(){return iface_is_query;};\r
- void set_ifq(bool b){iface_is_query = b;};\r
-\r
- std::string to_string(){\r
- std::string retval;\r
-\r
- if(machine != "" && !iface_is_query)\r
- retval += "'"+machine+"'.";\r
- if(interface != ""){\r
- if(iface_is_query){\r
- retval += '['+interface+"].";\r
- }else{\r
- retval += interface+".";\r
- }\r
- }\r
- retval += schema_name;\r
- if(variable_name != "") retval+=" "+variable_name;\r
-\r
- return(retval);\r
- };\r
-\r
- std::string get_schema_name(){return schema_name;};\r
- void set_schema_name(std::string n){schema_name=n;};\r
- std::string get_var_name(){return variable_name;};\r
- std::string get_interface(){return interface;};\r
- std::string get_machine(){return machine;};\r
- std::string get_udop_alias(){return udop_alias;};\r
-\r
- int get_lineno(){return(lineno); };\r
- int get_charno(){return(charno); };\r
-\r
-};\r
-\r
-#define INNER_JOIN_PROPERTY 0\r
-#define LEFT_OUTER_JOIN_PROPERTY 1\r
-#define RIGHT_OUTER_JOIN_PROPERTY 2\r
-#define OUTER_JOIN_PROPERTY 3\r
-#define FILTER_JOIN_PROPERTY 4\r
-\r
-// tablevar_list_t is the list of tablevars in a FROM clause\r
-\r
-struct tablevar_list_t{\r
-public:\r
- std::vector<tablevar_t *> tlist;\r
- int properties;\r
- int lineno, charno;\r
-// For filter join\r
- colref_t *temporal_var;\r
- unsigned int temporal_range;\r
-\r
- tablevar_list_t(){properties = -1; temporal_var = NULL;}\r
- tablevar_list_t(tablevar_t *t){tlist.push_back(t); properties=-1; temporal_var = NULL;\r
- lineno = flex_fta_lineno; charno = flex_fta_ch;};\r
- tablevar_list_t(std::vector<tablevar_t *> t){tlist = t; properties=-1; temporal_var = NULL;\r
- lineno = 0; charno = 0;};\r
-\r
- tablevar_list_t *duplicate(){\r
- tablevar_list_t *ret = new tablevar_list_t();\r
- ret->lineno = lineno; ret->charno = charno;\r
- ret->properties = properties;\r
- ret->temporal_var = temporal_var;\r
- ret->temporal_range = temporal_range;\r
- int i;\r
- for(i=0;i<tlist.size();++i){\r
- ret->append_table(tlist[i]->duplicate());\r
- }\r
- return(ret);\r
- }\r
-\r
-\r
-\r
- tablevar_list_t *append_table(tablevar_t *t){\r
- tlist.push_back(t);\r
- return(this);\r
- };\r
-\r
- std::string to_string(){\r
- int i;\r
- std::string retval;\r
-\r
- for(i=0;i<tlist.size();i++){\r
- if(i>0) retval.append(", ");\r
- retval.append(tlist[i]->to_string());\r
- }\r
- return(retval);\r
- };\r
-\r
- std::vector<tablevar_t *> get_table_list(){return(tlist); };\r
-\r
- std::vector<std::string> get_table_names(){\r
- std::vector<std::string> ret;\r
- int t;\r
- for(t=0;t<tlist.size();++t){\r
- std::string tbl_name = tlist[t]->get_schema_name();\r
- ret.push_back(tbl_name);\r
- }\r
- return(ret);\r
- }\r
-\r
- std::vector<std::string> get_src_tbls(table_list *Schema){\r
- std::vector<std::string> ret;\r
- int t, sq;\r
- for(t=0;t<tlist.size();++t){\r
- std::string tbl_name = tlist[t]->get_schema_name();\r
- int sid = Schema->find_tbl(tbl_name);\r
- if(sid < 0){ ret.push_back(tbl_name);\r
- }else\r
- if(Schema->get_schema_type(sid) != OPERATOR_VIEW_SCHEMA){\r
- ret.push_back(tbl_name);\r
- }else{\r
- std::vector<subquery_spec *> sqspec = Schema->get_subqueryspecs(sid);\r
- for(sq=0;sq<sqspec.size();++sq){\r
- ret.push_back(sqspec[sq]->name);\r
- }\r
- }\r
- }\r
- return(ret);\r
- };\r
-\r
- int size(){\r
- return tlist.size();\r
- };\r
-\r
-// Some accessor functions.\r
-\r
- std::vector<std::string> get_schema_names(){\r
- int i;\r
- std::vector<std::string > retval;\r
- for(i=0;i<tlist.size();i++){\r
- retval.push_back(tlist[i]->get_schema_name());\r
- }\r
- return(retval);\r
- }\r
-\r
- std::vector<int> get_schema_refs(){\r
- int i;\r
- std::vector<int> retval;\r
- for(i=0;i<tlist.size();i++){\r
- retval.push_back(tlist[i]->get_schema_ref());\r
- }\r
- return(retval);\r
- }\r
-\r
-\r
- int get_schema_ref(int i){\r
- if(i<0 || i>=tlist.size()) return(-1);\r
- return tlist[i]->get_schema_ref();\r
- };\r
-\r
- std::string get_tablevar_name(int i){\r
- if(i<0 || i>=tlist.size()) return("");\r
- return tlist[i]->get_var_name();\r
- };\r
-\r
- void set_properties(int p){properties = p;};\r
- int get_properties(){return properties;};\r
-\r
- void set_colref(colref_t *c){temporal_var = c;};\r
- void set_temporal_range(unsigned int t){temporal_range = t;};\r
- void set_temporal_range(const char *t){temporal_range= atoi(t);};\r
- colref_t *get_colref(){return temporal_var;};\r
- unsigned int get_temporal_range(){return temporal_range;};\r
-\r
-};\r
-\r
-// A reference to an interface parameter.\r
-// (I need to be able to record the source\r
-// tablevar, else this would be a lot simpler).\r
-class ifpref_t{\r
-public:\r
- std::string tablevar;\r
- std::string pname;\r
- int tablevar_ref;\r
- int lineno, charno;\r
-\r
- ifpref_t(const char *p){\r
- tablevar="";\r
- pname = p;\r
- tablevar_ref = -1;\r
- lineno = flex_fta_lineno; charno = flex_fta_ch;\r
- };\r
-\r
- ifpref_t(const char *t, const char *p){\r
- tablevar=t;\r
- pname = p;\r
- tablevar_ref = -1;\r
- lineno = flex_fta_lineno; charno = flex_fta_ch;\r
- };\r
-\r
- void set_tablevar_ref(int i){tablevar_ref = i;};\r
- int get_tablevar_ref(){return tablevar_ref;};\r
- std::string get_tablevar(){return tablevar;}\r
- void set_tablevar(std::string t){tablevar = t;};\r
- std::string get_pname(){return pname;}\r
- std::string to_string(){\r
- std::string ret;\r
- if(tablevar != "")\r
- ret += tablevar + ".";\r
- ret += "@"+pname;\r
- return ret;\r
- };\r
- bool is_equivalent(ifpref_t *i){\r
- return (tablevar_ref == i->tablevar_ref) && (pname == i->pname);\r
- };\r
-};\r
-\r
-\r
-\r
-\r
-// A representation of a reference to a field of a\r
-// stream (or table). This reference must be bound\r
-// to a particular schema (schema_ref) and to a\r
-// particular table variable in the FROM clause (tablevar_ref)\r
-// If the column reference was generated by the parser,\r
-// it will contain some binding text wich might need\r
-// interpretation to do the actual binding.\r
-class colref_t{\r
-public:\r
- std::string interface; // specified interface, if any.\r
- std::string table_name; // specified table name or range var, if any.\r
- std::string field; // field name\r
- bool default_table; // true iff. no table or range var given.\r
- int schema_ref; // ID of the source schema.\r
- int tablevar_ref; // ID of the tablevar (in FROM clause).\r
- int lineno, charno;\r
-\r
- colref_t(const char *f){\r
- field = f; default_table = true;\r
- schema_ref = -1; tablevar_ref = -1;\r
- lineno = flex_fta_lineno; charno = flex_fta_ch;\r
- };\r
-\r
- colref_t(const char *t, const char *f){\r
- table_name = t; field=f; default_table = false;\r
- schema_ref = -1; tablevar_ref = -1;\r
- lineno = flex_fta_lineno; charno = flex_fta_ch;\r
- };\r
-\r
- colref_t(const char *i, const char *t, const char *f){\r
- interface=i;\r
- table_name = t; field=f; default_table = false;\r
- schema_ref = -1; tablevar_ref = -1;\r
- lineno = flex_fta_lineno; charno = flex_fta_ch;\r
- };\r
-\r
- colref_t *duplicate(){\r
- colref_t *retval = new colref_t(interface.c_str(), table_name.c_str(), field.c_str());\r
- retval->schema_ref = schema_ref;\r
- retval->tablevar_ref = tablevar_ref;\r
- retval->lineno = lineno;\r
- retval->charno = charno;\r
- retval->default_table = default_table;\r
- return(retval);\r
- }\r
-\r
- std::string to_string(){\r
- if(default_table){\r
- return field;\r
- }else{\r
- if(interface != "") return(interface+"."+table_name+"."+field);\r
- return(table_name + "." + field);\r
- }\r
- };\r
-\r
- std::string to_query_string(){\r
- if(default_table){\r
- return field;\r
- }else{\r
- if(interface != "") return(interface+"."+table_name+"."+field);\r
- if(table_name != "") return(table_name + "." + field);\r
- return(field);\r
- }\r
- };\r
-\r
- int get_lineno(){return lineno; };\r
- int get_charno(){return charno; };\r
-\r
- bool uses_default_table(){return default_table; };\r
-\r
- std::string get_field(){return(field); };\r
- void set_field(std::string f){field=f;};\r
- std::string get_table_name(){return(table_name);};\r
- std::string get_interface(){return(interface);};\r
- void set_table_name(std::string t){table_name = t; default_table=false;};\r
- void set_interface(std::string i){interface=i;};\r
-\r
- int get_schema_ref(){return schema_ref;}\r
- void set_schema_ref(int s){schema_ref = s;};\r
- int get_tablevar_ref(){return tablevar_ref;}\r
- void set_tablevar_ref(int s){tablevar_ref = s;};\r
-\r
-// Should equivalence be based on tablevar_ref or schema_ref?\r
- bool is_equivalent(colref_t *c2){\r
- if(schema_ref == c2->schema_ref){\r
- return(field == c2->field);\r
- }\r
- return(false);\r
- };\r
-\r
- bool is_equivalent_base(colref_t *c2, table_list *Schema){\r
- if(Schema->get_basetbl_name(schema_ref,field) ==\r
- Schema->get_basetbl_name(c2->schema_ref,c2->field)){\r
- return(field == c2->field);\r
- }\r
- return(false);\r
- };\r
-};\r
-\r
-class colref_list_t{\r
-public:\r
- std::vector<colref_t *> clist;\r
-\r
-// colref_list_t(){};\r
-\r
- colref_list_t(colref_t *c){\r
- clist.push_back(c);\r
- }\r
-\r
- colref_list_t *append(colref_t *c){\r
- clist.push_back(c);\r
- return this;\r
- }\r
-\r
- std::vector<colref_t *> get_clist(){\r
- return clist;\r
- }\r
-};\r
-\r
-\r
-\r
-\r
-\r
-\r
-/*\r
- A tree containing a scalar expression.\r
- Used for\r
- atom : a parameter or a literal\r
- scalar_exp (see the scalar_exp: rule in emf.l for details)\r
- function_ref (a function that has a value, e.g. an aggregate\r
- function).\r
- operator_type defines the contents of the node. If its a non-terminal,\r
- then op has a meaning and defines the operation. See the list of\r
- #define'd constants following the structure definition.\r
-\r
-\r
-*/\r
-\r
-#define SE_LITERAL 1\r
-#define SE_PARAM 2\r
-#define SE_COLREF 3\r
-#define SE_UNARY_OP 4\r
-#define SE_BINARY_OP 5\r
-#define SE_AGGR_STAR 6\r
-#define SE_AGGR_SE 7\r
-#define SE_FUNC 8\r
-#define SE_IFACE_PARAM 9\r
-\r
-\r
-class scalarexp_t{\r
-public:\r
- int operator_type;\r
- std::string op;\r
- union{\r
- scalarexp_t *scalarp;\r
- literal_t *litp;\r
- colref_t *colref;\r
- ifpref_t *ifp;\r
- } lhs;\r
- union{\r
- scalarexp_t *scalarp;\r
- } rhs;\r
- std::vector<scalarexp_t *> param_list;\r
-\r
-// SE node decorations -- results of query analysis.\r
- data_type *dt;\r
- int gb_ref; // set to the gb attr tbl ref, else -1\r
- int aggr_id; // set to the aggr tbl ref, else -1\r
- int fcn_id; // external function table ref, else -1\r
- int partial_ref; // partial fcn table ref, else -1\r
- int fcn_cache_ref; // function cache ref, else -1\r
- int handle_ref; // Entry in pass-by-handle parameter table, else -1.\r
- // (might be a literal or a query param).\r
- bool is_superagg; // true if is aggregate and associated with supergroup.\r
- std::string storage_state; // storage state of stateful fcn,\r
- // empty o'wise.\r
-\r
- int lineno, charno;\r
-\r
- void default_init(){\r
- operator_type = 0;\r
- gb_ref = -1; aggr_id = -1; fcn_id = -1;\r
- partial_ref = -1; fcn_cache_ref=-1;\r
- handle_ref = -1;\r
- dt = NULL; lineno = flex_fta_lineno; charno = flex_fta_ch;\r
- is_superagg = false;\r
- };\r
-\r
- scalarexp_t(){\r
- default_init();};\r
-\r
- scalarexp_t(colref_t *c){\r
- default_init();\r
- operator_type = SE_COLREF;\r
- lhs.colref = c;\r
- };\r
-\r
- scalarexp_t(literal_t *l){\r
- default_init();\r
- operator_type = SE_LITERAL;\r
- lhs.litp = l;\r
- };\r
-\r
- void convert_to_literal(literal_t *l){\r
-// default_init();\r
- if(operator_type != SE_IFACE_PARAM){\r
- fprintf(stderr,"INTERNAL ERROR in literal_t::convert_to_literal, operator type isn't SE_IFACE_PARAM.\n");\r
- exit(1);\r
- }\r
- operator_type = SE_LITERAL;\r
- lhs.litp = l;\r
- }\r
-\r
- scalarexp_t(const char *o, scalarexp_t *operand){\r
- default_init();\r
- operator_type = SE_UNARY_OP;\r
- op = o;\r
- lhs.scalarp = operand;\r
- };\r
-\r
- scalarexp_t(const char *o, scalarexp_t *l_op, scalarexp_t *r_op){\r
- default_init();\r
- operator_type = SE_BINARY_OP;\r
- op = o;\r
- lhs.scalarp = l_op;\r
- rhs.scalarp = r_op;\r
- };\r
-\r
- scalarexp_t(const char *o, std::vector<scalarexp_t *> op_list){\r
- default_init();\r
- operator_type = SE_FUNC;\r
- op = o;\r
- param_list = op_list;\r
- };\r
-\r
- static scalarexp_t *make_paramless_fcn(const char *o){\r
- scalarexp_t *ret = new scalarexp_t();\r
- ret->operator_type = SE_FUNC;\r
- ret->op = o;\r
- return(ret);\r
- };\r
-\r
- static scalarexp_t *make_star_aggr(const char *ag){\r
- scalarexp_t *ret = new scalarexp_t();\r
- ret->operator_type = SE_AGGR_STAR;\r
- ret->op = ag;\r
- return(ret);\r
- };\r
-\r
- static scalarexp_t *make_se_aggr(const char *ag, scalarexp_t *l_op){\r
- scalarexp_t *ret = new scalarexp_t();\r
- ret->operator_type = SE_AGGR_SE;\r
- ret->op = ag;\r
- ret->lhs.scalarp = l_op;\r
- return(ret);\r
- };\r
-\r
- static scalarexp_t *make_param_reference(const char *param){\r
- scalarexp_t *ret = new scalarexp_t();\r
- ret->operator_type = SE_PARAM;\r
- ret->op = param;\r
- return(ret);\r
- };\r
-\r
- static scalarexp_t *make_iface_param_reference(ifpref_t *i){\r
- scalarexp_t *ret = new scalarexp_t();\r
- ret->operator_type = SE_IFACE_PARAM;\r
- ret->lhs.ifp = i;\r
- return(ret);\r
- };\r
-\r
-\r
- std::string to_string(){\r
- if(operator_type == SE_COLREF){\r
- return lhs.colref->to_string();\r
- }\r
- if(operator_type == SE_LITERAL){\r
- return lhs.litp->to_string();\r
- }\r
- if(operator_type == SE_UNARY_OP){\r
- return op + " (" + lhs.scalarp->to_string() + ")";\r
- }\r
- if(operator_type == SE_BINARY_OP){\r
- return "(" + lhs.scalarp->to_string() + " " + op + " " + rhs.scalarp->to_string() + ")";\r
- }\r
- return("");\r
- };\r
-\r
- scalarexp_t *get_left_se(){return lhs.scalarp; };\r
- scalarexp_t *get_right_se(){return rhs.scalarp; };\r
- int get_operator_type(){return operator_type; };\r
- std::string & get_op(){return op; };\r
- std::string & get_param_name(){return op; };\r
-// std::string & get_iface_param_name(){return op; };\r
- colref_t *get_colref(){return lhs.colref; };\r
- ifpref_t *get_ifpref(){return lhs.ifp; };\r
- literal_t *get_literal(){return lhs.litp; };\r
-\r
- int get_lineno(){return lineno; };\r
- int get_charno(){return charno; };\r
-\r
- void set_data_type(data_type *d){dt=d; };\r
- data_type *get_data_type(){return dt; };\r
- void reset_temporal(){if(dt!=NULL) dt->reset_temporal();}\r
-\r
- void set_gb_ref(int g){gb_ref = g; };\r
- int get_gb_ref(){return (gb_ref); };\r
- bool is_gb(){return(gb_ref >= 0); };\r
-\r
- void set_aggr_id(int a){aggr_id = a;};\r
- int get_aggr_ref(){return(aggr_id); };\r
-\r
- void set_storage_state(std::string s){storage_state = s;};\r
- std::string get_storage_state(){return storage_state;};\r
-\r
- std::vector<scalarexp_t *> get_operands(){return param_list;};\r
- void set_fcn_id(int f){fcn_id = f; };\r
- int get_fcn_id(){return fcn_id; };\r
-\r
- void set_partial_ref(int p){partial_ref = p; };\r
- int get_partial_ref(){return partial_ref; };\r
- bool is_partial(){return partial_ref >= 0; };\r
-\r
- void set_fcncache_ref(int p){fcn_cache_ref = p; };\r
- int get_fcncache_ref(){return fcn_cache_ref; };\r
- bool is_fcncached(){return fcn_cache_ref >= 0; };\r
-\r
- void set_handle_ref(int tf){handle_ref = tf; };\r
- int get_handle_ref(){return handle_ref; };\r
- bool is_handle_ref(){return handle_ref>=0; };\r
-\r
- void set_superaggr(bool b){is_superagg=b;};\r
- bool is_superaggr(){return is_superagg;};\r
-\r
- void use_decorations_of(scalarexp_t *se){\r
- if(se->get_data_type() != NULL)\r
- dt = se->get_data_type()->duplicate();\r
- gb_ref = se->gb_ref;\r
- aggr_id = se->aggr_id;\r
- fcn_id = se->fcn_id;\r
- partial_ref = se->partial_ref;\r
- handle_ref = se->handle_ref;\r
- lineno = se->lineno;\r
- charno = se->charno;\r
- is_superagg = se->is_superagg;\r
- };\r
-};\r
-\r
-\r
-/*\r
- A (null terminated) list of scalar expressions.\r
- Used for\r
- selection, scalar_exp_commalist\r
-*/\r
-\r
-class se_list_t{\r
-public:\r
- std::vector<scalarexp_t *> se_list;\r
- int lineno, charno;\r
-\r
- se_list_t(scalarexp_t *s){se_list.push_back(s);\r
- lineno = flex_fta_lineno; charno = flex_fta_ch;};\r
-\r
- se_list_t *append(scalarexp_t *s){\r
- se_list.push_back(s);\r
- return(this);\r
- };\r
-\r
- std::string to_string(){\r
- int i;\r
- std::string retval;\r
- for(i=0;i<se_list.size();i++){\r
- if(i>0) retval.append(", ");\r
- retval.append(se_list[i]->to_string());\r
- }\r
- return(retval);\r
- };\r
-\r
- std::vector<scalarexp_t *> get_se_list(){return se_list; };\r
-\r
-\r
-};\r
-\r
-/*\r
- select_commalist : collect some additional info about\r
- the selected things -- mostly the name.\r
-*/\r
-\r
-struct select_element{\r
- scalarexp_t *se;\r
- std::string name;\r
-\r
- select_element(){se=NULL; name="";};\r
- select_element(scalarexp_t *s){se=s; name="";};\r
- select_element(scalarexp_t *s, std::string n){se=s; name=n;};\r
-};\r
-\r
-class select_list_t{\r
-public:\r
- std::vector<select_element *> select_list;\r
- int lineno, charno;\r
-\r
- select_list_t(){lineno = -1; charno = -1;};\r
- select_list_t(scalarexp_t *s){select_list.push_back(new select_element(s));\r
- lineno = flex_fta_lineno; charno = flex_fta_ch;};\r
- select_list_t(scalarexp_t *s, std::string n){\r
- select_list.push_back(new select_element(s,n));\r
- lineno = flex_fta_lineno; charno = flex_fta_ch;\r
- };\r
- select_list_t *append(scalarexp_t *s){\r
- select_list.push_back(new select_element(s));\r
- return(this);\r
- };\r
- select_list_t *append(scalarexp_t *s, std::string n){\r
- select_list.push_back(new select_element(s,n));\r
- return(this);\r
- };\r
-\r
- std::string to_string(){\r
- int i;\r
- std::string retval;\r
- for(i=0;i<select_list.size();i++){\r
- if(i>0) retval.append(", ");\r
- retval.append(select_list[i]->se->to_string());\r
- if(select_list[i]->name != "")\r
- retval += " AS " + select_list[i]->name;\r
-\r
- }\r
- return(retval);\r
- };\r
-\r
- std::vector<select_element *> get_select_list(){return select_list; };\r
- std::vector<scalarexp_t *> get_select_se_list(){\r
- std::vector<scalarexp_t *> ret;\r
- int i;\r
- for(i=0; i<select_list.size();++i) ret.push_back(select_list[i]->se);\r
- return ret;\r
- };\r
-};\r
-\r
-\r
-\r
-#define GB_COLREF 1\r
-#define GB_COMPUTED 2\r
-\r
-class gb_t{\r
-public:\r
- std::string name;\r
- std::string table;\r
- std::string interface;\r
- scalarexp_t *def;\r
- int type;\r
- int lineno, charno;\r
-\r
- gb_t(const char *field_name){\r
- interface="";\r
- name = field_name; table=""; def=NULL; type=GB_COLREF;\r
- lineno = flex_fta_lineno; charno = flex_fta_ch;\r
- };\r
-\r
- gb_t(const char *table_name, const char *field_name){\r
- interface="";\r
- name = field_name; table=""; def=NULL; type=GB_COLREF;\r
- lineno = flex_fta_lineno; charno = flex_fta_ch;\r
- };\r
-\r
- gb_t(const char *iface, const char *table_name, const char *field_name){\r
- interface=iface;\r
- name = field_name; table=""; def=NULL; type=GB_COLREF;\r
- lineno = flex_fta_lineno; charno = flex_fta_ch;\r
- };\r
-\r
- gb_t( scalarexp_t *s, const char *gname){\r
- name = gname; table = ""; def = s; type = GB_COMPUTED;\r
- lineno = flex_fta_lineno; charno = flex_fta_ch;\r
- };\r
-\r
- std::string to_string(){\r
- std::string retval;\r
- if(type == GB_COLREF){\r
- if(table != ""){\r
- retval = table;\r
- retval.append(".");\r
- }\r
- retval.append(name);\r
- }\r
- if(type == GB_COMPUTED){\r
- retval = "(scalarexp) AS ";\r
- retval.append(name);\r
- }\r
- return(retval);\r
- };\r
-\r
- gb_t *duplicate();\r
-\r
-};\r
-\r
-/*\r
- A (null terminated) list of group by attributes\r
-*/\r
-\r
-class gb_list_t{\r
-public:\r
- std::vector<gb_t *> gb_list;\r
- int lineno, charno;\r
-\r
- gb_list_t(gb_t *g){gb_list.push_back(g);\r
- lineno = flex_fta_lineno; charno = flex_fta_ch;};\r
-\r
- gb_list_t *append(gb_t *s){\r
- gb_list.push_back(s);\r
- return(this);\r
- };\r
- gb_list_t(int l, int c) : lineno(l), charno(c){ }\r
-\r
- std::string to_string(){\r
- int i;\r
- std::string retval;\r
- for(i=0;i<gb_list.size();i++){\r
- if(i>0) retval.append(", ");\r
- retval.append(gb_list[i]->to_string());\r
- }\r
- return(retval);\r
- };\r
-\r
- std::vector<gb_t *> get_gb_list(){return gb_list; };\r
-\r
- gb_list_t *duplicate(){\r
- gb_list_t *ret = new gb_list_t(lineno, charno);\r
- int i;\r
- for(i=0;i<gb_list.size();++i){\r
- ret->append(gb_list[i]->duplicate());\r
- }\r
-\r
- return ret;\r
- }\r
-\r
-\r
-};\r
-\r
-class list_of_gb_list_t{\r
-public:\r
- std::vector<gb_list_t *> gb_lists;\r
-\r
- list_of_gb_list_t(gb_list_t *gl){\r
- gb_lists.push_back(gl);\r
- }\r
-\r
- list_of_gb_list_t *append(gb_list_t *gl){\r
- gb_lists.push_back(gl);\r
- return this;\r
- }\r
-};\r
-\r
-\r
-enum extended_gb_type {no_egb_type, gb_egb_type, rollup_egb_type,\r
- cube_egb_type, gsets_egb_type};\r
-class extended_gb_t{\r
-public:\r
-\r
- extended_gb_type type;\r
- gb_t *gb;\r
- std::vector<gb_list_t *> gb_lists;\r
-\r
- extended_gb_t(){\r
- gb = NULL;\r
- type = no_egb_type;\r
- }\r
-\r
- ~extended_gb_t(){\r
- }\r
-\r
- static extended_gb_t *create_from_gb(gb_t *g){\r
- extended_gb_t *ret = new extended_gb_t();\r
- ret->type = gb_egb_type;\r
- ret->gb = g;\r
- return ret;\r
- }\r
-\r
- static extended_gb_t *extended_create_from_rollup(gb_list_t *gl){\r
- extended_gb_t *ret = new extended_gb_t();\r
- ret->type = rollup_egb_type;\r
- ret->gb_lists.push_back(gl);\r
- return ret;\r
- }\r
-\r
- static extended_gb_t *extended_create_from_cube(gb_list_t *gl){\r
- extended_gb_t *ret = new extended_gb_t();\r
- ret->type = cube_egb_type;\r
- ret->gb_lists.push_back(gl);\r
- return ret;\r
- }\r
-\r
- static extended_gb_t *extended_create_from_gsets(list_of_gb_list_t *lgl){\r
- extended_gb_t *ret = new extended_gb_t();\r
- ret->type = gsets_egb_type;\r
- ret->gb_lists = lgl->gb_lists;\r
- return ret;\r
- }\r
-\r
- extended_gb_t *duplicate(){\r
- extended_gb_t *ret = new extended_gb_t();\r
- ret->type = type;\r
- if(gb != NULL)\r
- ret->gb = gb->duplicate();\r
- int i;\r
- for(i=0;i<gb_lists.size();++i){\r
- ret->gb_lists.push_back(gb_lists[i]->duplicate());\r
- }\r
- return ret;\r
- }\r
-\r
-\r
- std::string to_string(){\r
- std::string ret;\r
- int i;\r
-\r
- switch(type){\r
- case no_egb_type:\r
- return "Error, undefined extended gb type.";\r
- case gb_egb_type:\r
- return gb->to_string();\r
- case rollup_egb_type:\r
- return "ROLLUP("+gb_lists[0]->to_string()+")";\r
- case cube_egb_type:\r
- return "CUBE("+gb_lists[0]->to_string()+")";\r
- case gsets_egb_type:\r
- ret = "GROUPING_SETS(";\r
- for(i=0;i<gb_lists.size();++i){\r
- if(i>0) ret+=", ";\r
- ret += "(" +gb_lists[i]->to_string()+")";\r
- }\r
- ret += ")";\r
- return ret;\r
- default:\r
- break;\r
- }\r
- return "Error, unknown extended gb type.";\r
- }\r
-\r
-};\r
-\r
-class extended_gb_list_t{\r
-public:\r
- std::vector<extended_gb_t *> gb_list;\r
- int lineno, charno;\r
-\r
- extended_gb_list_t(extended_gb_t *g){gb_list.push_back(g);\r
- lineno = flex_fta_lineno; charno = flex_fta_ch;};\r
-\r
- extended_gb_list_t *append(extended_gb_t *s){\r
- gb_list.push_back(s);\r
- return(this);\r
- };\r
-\r
- std::string to_string(){\r
- int i;\r
- std::string retval;\r
- for(i=0;i<gb_list.size();i++){\r
- if(i>0) retval.append(", ");\r
- retval.append(gb_list[i]->to_string());\r
- }\r
- return(retval);\r
- };\r
-\r
- std::vector<extended_gb_t *> get_gb_list(){return gb_list; };\r
-};\r
-\r
-\r
-\r
-/*\r
- A predicate tree. Structure is similar to\r
- a scalar expression tree but the type is always boolean.\r
- Used by\r
- opt_where_clause, where_clause, opt_having_clause,\r
- search_condition, predicate, comparison_predicate, repl_predicate\r
-*/\r
-\r
-#define PRED_COMPARE 1\r
-#define PRED_UNARY_OP 2\r
-#define PRED_BINARY_OP 3\r
-#define PRED_FUNC 4\r
-#define PRED_IN 5\r
-\r
-class predicate_t{\r
-public:\r
- int operator_type;\r
- std::string op;\r
- union {\r
- predicate_t *predp;\r
- scalarexp_t *sexp;\r
- }lhs;\r
- union {\r
- predicate_t *predp;\r
- scalarexp_t *sexp;\r
- literal_list_t *ll;\r
- }rhs;\r
- std::vector<scalarexp_t *> param_list; /// pred fcn params\r
- int fcn_id; /// external pred fcn id\r
- int combinable_ref;\r
- bool is_sampling_fcn;\r
- int lineno, charno;\r
-\r
- predicate_t(scalarexp_t *s, literal_list_t *litl){\r
- operator_type = PRED_IN;\r
- op = "in";\r
- lhs.sexp = s;\r
- rhs.ll = litl;\r
- fcn_id = -1;\r
- combinable_ref = -1;\r
- lineno = flex_fta_lineno; charno = flex_fta_ch;\r
- };\r
-\r
- predicate_t(scalarexp_t *s, std::vector<literal_t *> litv){\r
- operator_type = PRED_IN;\r
- op = "in";\r
- lhs.sexp = s;\r
- rhs.ll = new literal_list_t(litv);\r
- fcn_id = -1;\r
- combinable_ref = -1;\r
- lineno = flex_fta_lineno; charno = flex_fta_ch;\r
- };\r
-\r
-\r
- predicate_t(scalarexp_t *l_op, const char *o, scalarexp_t *r_op){\r
- operator_type = PRED_COMPARE;\r
- op = o;\r
- lhs.sexp = l_op;\r
- rhs.sexp = r_op;\r
- fcn_id = -1;\r
- combinable_ref = -1;\r
- lineno = flex_fta_lineno; charno = flex_fta_ch;\r
- };\r
-\r
- predicate_t(const char *o, predicate_t *p){\r
- operator_type = PRED_UNARY_OP;\r
- op = o;\r
- lhs.predp = p;\r
- fcn_id = -1;\r
- combinable_ref = -1;\r
- lineno = flex_fta_lineno; charno = flex_fta_ch;\r
- };\r
-\r
- predicate_t(const char *o, predicate_t *l_p, predicate_t *r_p){\r
- operator_type = PRED_BINARY_OP;\r
- op = o;\r
- lhs.predp = l_p;\r
- rhs.predp = r_p;\r
- fcn_id = -1;\r
- combinable_ref = -1;\r
- lineno = flex_fta_lineno; charno = flex_fta_ch;\r
- };\r
-\r
- predicate_t(const char *o, std::vector<scalarexp_t *> op_list){\r
- operator_type = PRED_FUNC;\r
- op = o;\r
- param_list = op_list;\r
- fcn_id = -1;\r
- combinable_ref = -1;\r
- lineno = flex_fta_lineno; charno = flex_fta_ch;\r
- };\r
-\r
- predicate_t(const char *o){\r
- op = o;\r
- fcn_id = -1;\r
- combinable_ref = -1;\r
- lineno = flex_fta_lineno; charno = flex_fta_ch;\r
- };\r
-\r
-\r
- static predicate_t *make_paramless_fcn_predicate(const char *o){\r
- predicate_t *ret = new predicate_t(o);\r
- ret->operator_type = PRED_FUNC;\r
- ret->fcn_id = -1;\r
- ret->combinable_ref = -1;\r
- return(ret);\r
- };\r
-\r
- std::string to_string(){\r
- if(operator_type == PRED_IN){\r
- return( lhs.sexp->to_string() + " " + op + " [ " + rhs.ll->to_string() +" ]");\r
- }\r
- if(operator_type == PRED_COMPARE){\r
- return( lhs.sexp->to_string() + " " + op + " " + rhs.sexp->to_string() );\r
- }\r
- if(operator_type == PRED_UNARY_OP){\r
- return( op + " (" + lhs.predp->to_string() + ")" );\r
- }\r
- if(operator_type == PRED_BINARY_OP){\r
- return( "(" + lhs.predp->to_string() + " " + op + " " + rhs.predp->to_string() + ")" );\r
- }\r
- if(operator_type == PRED_FUNC){\r
- std::string ret = op + "[ ";\r
- int i;\r
- for(i=0;i<param_list.size();++i){\r
- if(i>0) ret += ", ";\r
- ret += param_list[i]->to_string();\r
- }\r
- ret += "] ";\r
- return(ret);\r
- }\r
- return("");\r
- };\r
-\r
- std::vector<scalarexp_t *> get_op_list(){return param_list; };\r
- int get_operator_type(){return operator_type; };\r
- std::string get_op(){return op; };\r
- int get_lineno(){return lineno; };\r
- int get_charno(){return charno; };\r
- int get_combinable_ref(){return combinable_ref;}\r
- void set_combinable_ref(int f){combinable_ref = f;};\r
- predicate_t *get_left_pr(){return(lhs.predp); };\r
- predicate_t *get_right_pr(){return(rhs.predp); };\r
- scalarexp_t *get_left_se(){return(lhs.sexp); };\r
- scalarexp_t *get_right_se(){return(rhs.sexp); };\r
- std::vector<literal_t *> get_lit_vec(){return(rhs.ll->get_literal_vector()); };\r
-\r
- void swap_scalar_operands(){\r
- if(operator_type != PRED_COMPARE){\r
- fprintf(stderr,"INTERNAL ERROR: swap_scalar_operands called on predicate of type %d\n",operator_type);\r
- exit(1);\r
- }\r
- scalarexp_t *tmp;\r
- tmp = lhs.sexp; lhs.sexp = rhs.sexp; rhs.sexp = tmp;\r
- if(op == ">"){op = "<"; return;}\r
- if(op == ">="){op = "<="; return;}\r
- if(op == "<"){op = ">"; return;}\r
- if(op == "<="){op = ">="; return;}\r
- };\r
- void set_fcn_id(int i){fcn_id = i;};\r
- int get_fcn_id(){return fcn_id;};\r
-\r
-\r
-};\r
-\r
-\r
-/*\r
- A structure that holds the components of a query.\r
- This is the root type.\r
- Used by manipulative_statement, select_statement, table_exp\r
-*/\r
-\r
-#define SELECT_QUERY 1\r
-#define MERGE_QUERY 2\r
-\r
-class table_exp_t{\r
-public:\r
- int query_type; // roughly, the type of the query.\r
- ss_map nmap; // DEFINE block\r
- std::vector<var_pair_t *> query_params; // PARAM block (uninterpreted)\r
- select_list_t *sl; // SELECT\r
- tablevar_list_t *fm; // FROM\r
- predicate_t *wh; // WHERE\r
- predicate_t *hv; // HAVING\r
- predicate_t *cleaning_when; // CLEANING WHEN\r
- predicate_t *cleaning_by; // CLEANING BY\r
- predicate_t *closing_when; // CLOSING WHEN\r
- std::vector<extended_gb_t *> gb; // GROUP BY\r
- std::vector<colref_t *> mergevars; // merge colrefs.\r
- std::vector<colref_t *> supergb; // supergroup.\r
- scalarexp_t *slack; // merge slack\r
- bool exernal_visible; // true iff. it can be subscribed to.\r
- int lineno, charno;\r
-\r
-\r
- 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)\r
- {fm = f; wh = p; hv = h;\r
- cleaning_when = cw; cleaning_by = cb;\r
- closing_when = closew;\r
- if(g != NULL)\r
- gb = g->gb_list;\r
- if(sg != NULL)\r
- supergb = sg->get_clist();\r
- slack = NULL;\r
- query_type = SELECT_QUERY;\r
- exernal_visible = true;\r
- lineno = flex_fta_lineno; charno = flex_fta_ch;\r
- };\r
-\r
- table_exp_t(colref_list_t *mv, tablevar_list_t *f)\r
- {fm = f; mergevars=mv->get_clist();\r
- slack = NULL;\r
- query_type = MERGE_QUERY;\r
- exernal_visible = true;\r
- lineno = flex_fta_lineno; charno = flex_fta_ch;\r
- };\r
-\r
- table_exp_t(colref_list_t *mv, scalarexp_t *sl, tablevar_list_t *f)\r
- {fm = f; mergevars=mv->get_clist();\r
- slack = sl;\r
- query_type = MERGE_QUERY;\r
- exernal_visible = true;\r
- lineno = flex_fta_lineno; charno = flex_fta_ch;\r
- };\r
-\r
-// Figure out the temporal merge field at analyze_fta time.\r
- static table_exp_t *make_deferred_merge(std::vector<std::string> src_tbls){\r
- table_exp_t *ret = new table_exp_t();\r
- ret->query_type = MERGE_QUERY;\r
- ret->fm = new tablevar_list_t();\r
- int t;\r
- for(t=0;t<src_tbls.size();++t){\r
- ret->fm->append_table(new tablevar_t(src_tbls[t].c_str()));\r
- }\r
- ret->lineno = 0; ret->charno = 0;\r
- return ret;\r
- }\r
-\r
- table_exp_t(){\r
- fm = NULL; sl = NULL; wh=NULL; hv=NULL;\r
- slack = NULL;\r
- cleaning_when=NULL; cleaning_by = NULL;\r
- closing_when = NULL;\r
- exernal_visible = true;\r
- };\r
-\r
- table_exp_t *add_selection(select_list_t *s){\r
- sl = s;\r
- return(this);\r
- };\r
-\r
- void add_nmap(var_defs_t *vd){\r
- int n;\r
- if(vd != NULL){\r
- for(n=0;n<vd->size();++n){\r
- nmap[vd->get_name(n)] = vd->get_def(n);\r
-//printf("Adding (%s, %s) to name map.\n",vd->get_name(n).c_str(), vd->get_def(n).c_str());\r
- }\r
- }\r
- };\r
-\r
- void add_param_list(var_defs_t *vd){\r
- int n;\r
- if(vd != NULL){\r
- query_params = vd->get_nvec();\r
- }\r
- };\r
-\r
-\r
- std::string to_string(){\r
- std::string retval;\r
- if(sl != NULL){\r
- retval.append("Select " + sl->to_string() + "\n");\r
- }\r
- if(fm != NULL){\r
- retval.append("From " + fm->to_string() + "\n");\r
- }\r
- if(wh != NULL){\r
- retval.append("Where "+ wh->to_string() + "\n");\r
- }\r
- if(hv != NULL){\r
- retval.append("Having "+hv->to_string() + "\n");\r
- }\r
- return(retval);\r
- };\r
-\r
- tablevar_list_t *get_from(){return fm; };\r
- select_list_t *get_select(){return sl; };\r
- std::vector<select_element *> get_sl_vec(){return sl->get_select_list(); };\r
- predicate_t *get_where(){return wh; };\r
- predicate_t *get_having(){return hv; };\r
- predicate_t *get_cleaning_by(){return cleaning_by; };\r
- predicate_t *get_cleaning_when(){return cleaning_when; };\r
- predicate_t *get_closing_when(){return closing_when; };\r
- std::vector<extended_gb_t *> get_groupby(){return(gb); };\r
- std::vector<colref_t *> get_supergb(){return supergb;};\r
-\r
- ss_map get_name_map(){return nmap;};\r
-\r
- bool name_exists(std::string nm){\r
- return(nmap.count(nm) > 0);\r
- };\r
-\r
- std::string get_val_of_name(std::string nm){\r
- if(nmap.count(nm) == 0) return("");\r
- else return nmap[nm];\r
- };\r
-\r
- void set_val_of_name(const std::string n, const std::string v){\r
- nmap[n]=v;\r
- }\r
-\r
- void set_visible(bool v){exernal_visible=v;};\r
- bool get_visible(){return exernal_visible;};\r
-};\r
-\r
-struct query_list_t{\r
- std::vector<table_exp_t *> qlist;\r
-\r
- query_list_t(table_exp_t *t){\r
- qlist.push_back(t);\r
- };\r
- query_list_t *append(table_exp_t *t){\r
- qlist.push_back(t);\r
- return(this);\r
- };\r
-};\r
-\r
-\r
-#define TABLE_PARSE 1\r
-#define QUERY_PARSE 2\r
-#define STREAM_PARSE 3\r
-\r
-struct fta_parse_t{\r
- query_list_t *parse_tree_list;\r
- table_exp_t *fta_parse_tree;\r
- table_list *tables;\r
- int parse_type;\r
-};\r
-\r
-\r
-\r
-\r
-\r
- extern table_exp_t *fta_parse_tree;\r
-\r
-\r
-\r
-\r
-\r
-#endif\r
-\r
+/* ------------------------------------------------
+Copyright 2020 AT&T Intellectual Property
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ------------------------------------------- */
+#ifndef _FTA_PARSE_H_INCLUDED__
+#define _FTA_PARSE_H_INCLUDED__
+
+#include<stdio.h>
+#include<ctype.h>
+
+ int yyparse();
+ void yyerror(char *s);
+ int yylex();
+extern int flex_fta_lineno, flex_fta_ch;
+
+/* Interface to FTA Parser */
+void FtaParser_setfileinput(FILE *f);
+void FtaParser_setstringinput(char *s);
+
+
+/* Get type defines. */
+#include"type_objects.h"
+#include"literal_types.h"
+#include"type_indicators.h"
+
+#include <string>
+#include <vector>
+#include <map>
+#include <math.h>
+#include <string>
+#include <stdio.h>
+#include <stdlib.h>
+
+
+// colref_t::is_equivalent needs to understand the schema
+#include"parse_schema.h"
+class colref_t;
+
+
+
+class var_pair_t{
+public:
+ std::string name;
+ std::string val;
+
+ var_pair_t(char *n, char *v){
+ name=n; val=v;
+//printf("NEW var_pair_t(%s, %s)\n",n,v);
+ };
+
+ var_pair_t(const std::string n, const std::string v){
+ name=n; val=v;
+ };
+};
+
+typedef std::map< std::string, std::string > ss_map;
+
+class var_defs_t{
+private:
+ std::vector<var_pair_t *> namevec;
+
+public:
+ var_defs_t(var_pair_t *vp){
+ namevec.push_back(vp);
+ };
+
+ var_defs_t *add_var_pair(var_pair_t *vp){
+ namevec.push_back(vp);
+ return(this);
+ };
+
+ std::vector<var_pair_t *> get_nvec(){return namevec;};
+
+ int size(){return namevec.size();};
+
+ int find_name(std::string n){
+ int i;
+ for(i=0;i<namevec.size();i++){
+ if(namevec[i]->name == n)
+ return i;
+ }
+ return -1;
+ }
+ std::string get_name(int i){
+ if(i>=0 && i<namevec.size()){
+ return(namevec[i]->name);
+ }else{
+ return("");
+ }
+ }
+
+ std::string get_def(int i){
+ if(i>=0 && i<namevec.size()){
+ return(namevec[i]->val);
+ }else{
+ return("");
+ }
+ }
+
+ std::string dump(){
+ int i;
+ std::string ret;
+ for(i=0;i<namevec.size();++i){
+ ret += "\t"+namevec[i]->name+" = "+namevec[i]->val+"\n";
+ }
+ return ret;
+ }
+
+};
+
+
+
+
+// literal type constants are defined in literal_types.h
+// (must share this info with type_objects.h)
+
+// Represents a literal, as expected
+// NOTE: this class contains some code generation methods.
+
+class literal_t{
+private:
+
+public:
+ std::string lstring; /* literal value */
+ short int ltype; /* literal type */
+ int lineno, charno;
+
+ int complex_literal_id; // if this literal has a complex constructor,
+ // there is a function which constructs it)
+ //set to the idx in the complex literal
+ // table. (Must store this here (instead of in SE)
+ // because of bare literals in the IN predicate).
+
+
+ literal_t(std::string v){
+ lstring = v;
+ ltype = LITERAL_STRING;
+ complex_literal_id = -1;
+ lineno = flex_fta_lineno; charno = flex_fta_ch;
+ }
+ static literal_t *make_define_literal(const char *s, var_defs_t *d){
+ int i;
+ i=d->find_name(s);
+ if(i<0){
+ 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);
+ exit(1);
+ }
+ return new literal_t(d->get_def(i));
+ }
+
+ literal_t(const char *lit, int t){lstring = lit; ltype = t;
+ lineno = flex_fta_lineno; charno = flex_fta_ch;
+ complex_literal_id = -1;
+
+// For some datatypes we need to modify literal so make a copy of the string
+ char v[100];
+ strcpy(v, lit);
+
+// Remove UL, ULL suffix from INT constants.
+ if(ltype == LITERAL_INT || ltype == LITERAL_LONGINT){
+ int i;
+ int len=strlen(v);
+ for(i=0;i<len;++i){
+ if(v[i] == 'U') v[i] = '\0';
+ }
+ lstring = v;
+ }
+
+// HEX and LONGHEX must be converted to uint (long long uint)
+ if(ltype == LITERAL_HEX){
+ char *c,ltmpstr[100];
+ unsigned long tmp_l;
+ for(c=v; (*c)!='\0';++c){
+ if(! ( ((*c) >= '0' && (*c) <= '9') || (tolower(*c) >= 'a' && tolower(*c) <= 'f') ) ){
+ fprintf(stderr,"Syntax Error, line=%d, character=%d. The literal %s is not a HEX constant.\n",
+ lineno, charno, v);
+ exit(1);
+ }
+ }
+ sscanf(v,"%lx",&tmp_l);
+ sprintf(ltmpstr,"%lu",tmp_l);
+ lstring = ltmpstr;
+ ltype = LITERAL_INT;
+ }
+ if(ltype == LITERAL_LONGHEX){
+ char *c,ltmpstr[100];
+ unsigned long long tmp_ll;
+ for(c=v; (*c)!='\0';++c){
+ if(! ( ((*c) >= '0' && (*c) <= '9') || (tolower(*c) >= 'a' && tolower(*c) <= 'f') ) ){
+ fprintf(stderr,"Syntax Error, line=%d, character=%d. The literal %s is not a LHEX constant.\n",
+ lineno, charno, v);
+ exit(1);
+ }
+ }
+ sscanf(v,"%llx",&tmp_ll);
+ sprintf(ltmpstr,"%llu",tmp_ll);
+ lstring = ltmpstr;
+ ltype = LITERAL_LONGINT;
+ }
+// Convert IP to uint
+ if(ltype == LITERAL_IP){
+ char ltmpstr[100];
+ unsigned int o1,o2,o3,o4,tmp_l;
+ if(sscanf(v,"%u.%u.%u.%u",&o1,&o2,&o3,&o4) != 4){
+ fprintf(stderr,"Syntax Error, line=%d, character=%d. The literal %s is not an IP constant.\n",
+ lineno, charno, v);
+ exit(1);
+ }
+ if( (o1>255) || (o2>255) || (o3>255) || (o4>255) ){
+ fprintf(stderr,"Syntax Error, line=%d, character=%d. The literal %s is not an IP constant.\n",
+ lineno, charno, v);
+ exit(1);
+ }
+ tmp_l = (o1<<24)+(o2<<16)+(o3<<8)+o4;
+ sprintf(ltmpstr,"%u",tmp_l);
+ lstring = ltmpstr;
+ ltype = LITERAL_IP;
+ }
+ };
+
+// used to create literals with a default or initial value.
+ literal_t(int type_indicator){
+ lineno=-1; charno=-1;
+ complex_literal_id = -1;
+
+ switch(type_indicator){
+ case UINT_TYPE:
+ case INT_TYPE:
+ case USHORT_TYPE:
+ ltype = LITERAL_INT;
+ lstring = "0";
+ break;
+ case ULLONG_TYPE:
+ case LLONG_TYPE:
+ ltype = LITERAL_LONGINT;
+ lstring = "0";
+ break;
+ case FLOAT_TYPE:
+ ltype = LITERAL_FLOAT;
+ lstring = "0.0";
+ break;
+ case BOOL_TYPE:
+ ltype = LITERAL_BOOL;
+ lstring = "FALSE";
+ break;
+ case VSTR_TYPE:
+ ltype = LITERAL_STRING;
+ lstring = ""; complex_literal_id = 0; // unregistred complex lit
+ break;
+ case TIMEVAL_TYPE:
+ ltype = LITERAL_TIMEVAL;
+ lstring = "0.0";
+ break;
+ case IPV6_TYPE:
+ ltype = LITERAL_IPV6;
+ lstring = "0000:0000:0000:0000:0000:0000:0000:0000";
+ complex_literal_id = 0; // unregistered complex literal
+ break;
+ case IP_TYPE:
+ ltype = LITERAL_IP;
+ lstring = "0";
+ break;
+ default:
+ ltype = LITERAL_UDEF;
+ lstring=" INTERNAL ERROR, UNKNOWN TYPE INDICATOR IN literal_t::literal_t(int) ";
+ }
+ };
+
+ std::string to_string(){return lstring;};
+
+ int get_type(){return ltype; };
+ int get_lineno(){return lineno; };
+ int get_charno(){return charno; };
+
+ bool is_equivalent(literal_t *l2){
+ if(ltype != l2->ltype)
+ return(false);
+ if(lstring != l2->lstring)
+ return(false);
+
+ return(true);
+ };
+
+// Internal function to unescape control characters.
+ static std::string gsqlstr_to_cstr(std::string s){
+ std::string retval;
+ unsigned char c, prev_c='\0';
+ int i;
+
+ for(i=0;i<s.size();++i){
+ c = s[i];
+ if(c=='\''){ // || c=='\\'
+ if(prev_c==c){
+ retval += c;
+ prev_c = '\0';
+ }else{
+ prev_c=c;
+ }
+ continue;
+ }
+
+ retval += c;
+ prev_c = c;
+ }
+
+ return retval;
+ }
+
+
+
+ std::string to_hfta_C_code(std::string param){
+ std::string retval;
+ double tmp_f;
+ int secs, millisecs;
+ char tmpstr[100];
+
+ switch(ltype){
+ case LITERAL_STRING:
+ retval.append(this->hfta_constructor_name() );
+ retval.append("("+param+",\"");
+ retval.append(gsqlstr_to_cstr(lstring));
+ retval.append("\")");
+ return(retval);
+ case LITERAL_INT:
+ case LITERAL_IP:
+ return("((gs_uint32_t)"+lstring+")");
+ case LITERAL_LONGINT:
+ return("((gs_uint64_t)"+lstring+")");
+ case LITERAL_FLOAT:
+ return(lstring);
+// case LITERAL_HEX:
+// return("0x"+lstring);
+ case LITERAL_BOOL:
+ if(lstring == "TRUE"){
+ return("1");
+ }else{
+ return("0");
+ }
+ case LITERAL_TIMEVAL:
+ retval.append(this->hfta_constructor_name() );
+ tmp_f = atof(lstring.c_str());
+ secs = (int)floor(tmp_f);
+ millisecs = (int) rint((tmp_f - secs)*1000);
+ sprintf(tmpstr,"(%d, %d)",secs,millisecs);
+ retval.append(tmpstr);
+ return(retval);
+ case LITERAL_IPV6:
+ retval = this->hfta_constructor_name();
+ retval += "("+param+",\""+lstring+"\")";
+ return retval;
+ }
+
+ return("ERROR UNKNOWN LITERAL");
+ };
+
+
+/// for LFTA code generation
+ std::string to_C_code(std::string param){
+ std::string retval;
+ double tmp_f;
+ int secs, millisecs;
+ char tmpstr[100];
+
+ switch(ltype){
+ case LITERAL_STRING:
+ retval = this->constructor_name()+"("+param+",\""+gsqlstr_to_cstr(lstring)+"\")";
+ return(retval);
+ case LITERAL_INT:
+ case LITERAL_IP:
+ return("((gs_uint32_t)"+lstring+")");
+ case LITERAL_LONGINT:
+ return("((gs_uint64_t)"+lstring+")");
+ case LITERAL_FLOAT:
+ return(lstring);
+// case LITERAL_HEX:
+// return("0x"+lstring);
+ case LITERAL_BOOL:
+ if(lstring == "TRUE"){
+ return("1");
+ }else{
+ return("0");
+ }
+ case LITERAL_IPV6:
+ retval = this->constructor_name()+"("+param+",\""+lstring+"\")";
+ return(retval);
+ case LITERAL_TIMEVAL:
+ retval.append(this->constructor_name() );
+ tmp_f = atof(lstring.c_str());
+ secs = (int)floor(tmp_f);
+ millisecs = (int) rint((tmp_f - secs)*1000);
+ sprintf(tmpstr,"(%d, %d)",secs,millisecs);
+ retval.append(tmpstr);
+ return(retval);
+ }
+
+ return("ERROR UNKNOWN LITERAL");
+ };
+
+
+ std::string to_query_string(){
+ std::string retval;
+
+ switch(ltype){
+ case LITERAL_IP:
+ {
+ unsigned int v;
+ sscanf(lstring.c_str(),"%u",&v);
+ int d1 = v & 0xff;
+ int d2 = (v & 0xff00) >> 8;
+ int d3 = (v & 0xff0000) >> 16;
+ int d4 = (v & 0xff000000) >> 24;
+ char ret[200];
+ sprintf(ret,"IP_VAL'%u.%u.%u.%u'",d4,d3,d2,d1);
+ return ret;
+ }
+ case LITERAL_STRING:
+ retval = "'"+lstring+"'";
+ return(retval);
+ case LITERAL_INT:
+ case LITERAL_FLOAT:
+ case LITERAL_TIMEVAL:
+ case LITERAL_IPV6:
+ case LITERAL_BOOL:
+ return(lstring);
+ case LITERAL_LONGINT:
+ return(lstring+"ULL");
+ }
+
+ return("ERROR UNKNOWN LITERAL in literal_t::to_query_string");
+ };
+
+// TODO : Use definition files instead of hardwiring these.
+
+// constructor in LFTA code
+ std::string constructor_name(){
+
+ switch(ltype){
+ case LITERAL_TIMEVAL:
+ return("Timeval_Constructor");
+ case LITERAL_IPV6:
+ return("Ipv6_Constructor");
+ case LITERAL_STRING:
+ return("str_constructor");
+ case LITERAL_INT:
+ case LITERAL_IP:
+ case LITERAL_LONGINT:
+ case LITERAL_BOOL:
+ case LITERAL_FLOAT:
+ return("");
+ }
+ return("ERROR UNKNOWN LITERAL");
+ };
+
+ std::string hfta_constructor_name(){
+
+ switch(ltype){
+ case LITERAL_TIMEVAL:
+ return("HFTA_Timeval_Constructor");
+ case LITERAL_IPV6:
+ return("HFTA_Ipv6_Constructor");
+ case LITERAL_STRING:
+ return("Vstring_Constructor");
+ case LITERAL_INT:
+ case LITERAL_IP:
+ case LITERAL_LONGINT:
+ case LITERAL_BOOL:
+ case LITERAL_FLOAT:
+ return("");
+ }
+ return("ERROR UNKNOWN LITERAL");
+ };
+
+ std::string hfta_empty_literal_name(){
+
+ switch(ltype){
+ case LITERAL_TIMEVAL:
+ return("EmptyTimeval");
+ case LITERAL_IPV6:
+ return("EmptyIp6");
+ case LITERAL_STRING:
+ return("EmptyString");
+ }
+ return("ERROR_NOT_A_COMPLEX_LITERAL");
+ };
+
+
+ void set_cpx_lit_ref(int g){complex_literal_id = g; };
+ int get_cpx_lit_ref(){return (complex_literal_id ); };
+ bool is_cpx_lit(){return(complex_literal_id >= 0); };
+
+};
+
+
+/*
+ A (null terminated) list of literals.
+ Used for the IN clause
+*/
+
+class literal_list_t{
+private:
+
+public:
+ std::vector<literal_t *> lit_list;
+ int lineno, charno;
+
+ literal_list_t(literal_t *l){
+ lit_list.push_back(l);
+ lineno = flex_fta_lineno; charno = flex_fta_ch;
+ };
+
+ literal_list_t(std::vector<literal_t *> lvec){
+ lineno = charno = 0;
+ lit_list = lvec;
+ };
+
+ literal_list_t *append_literal(literal_t *l){
+ lit_list.push_back(l);
+ return(this);
+ };
+
+ std::string to_string(){
+ int i;
+ std::string retval;
+ for(i=0;i<lit_list.size();i++){
+ if(i>0) retval.append(", ");
+ retval.append(lit_list[i]->to_query_string());
+ }
+ return(retval);
+ };
+
+ std::vector<literal_t *> get_literal_vector(){return(lit_list);};
+
+};
+
+
+class string_t{
+public:
+ std::string val;
+ string_t(char *s){
+ val = s;
+ }
+ string_t *append(char *s){
+ val += s;
+ return this;
+ }
+ string_t *append(char *sep, char *s){
+ val += sep;
+ val += s;
+ return this;
+ }
+ const char *c_str(){
+ return val.c_str();
+ }
+};
+
+// A tablevar is a data source in a GSQL query.
+// Every column ref must be bound to a tablevar,
+// either explicitly or via imputation.
+
+
+class tablevar_t{
+public:
+// A tablevar is a variable which binds to a named data source.
+// the variable name might be explicit in the query, or it might be
+// implicit in which case the variable name is imputed. In either case
+// the variable name is set via the set_range_var method.
+//
+// The data source is the name of either a STREAM or a PROTOCOL.
+// All STREAMS are unique, but a PROTOCOL must be bound to an
+// interface. If the interface is not given, it is imputed to be
+// the default interface.
+
+ std::string machine;
+ std::string interface;
+ std::string schema_name;
+ std::string variable_name;
+ std::string udop_alias; // record UDOP ID for of UDOP
+ // for use by cluster manager
+
+ int schema_ref; // index of the table in the schema (table_list)
+ int opview_idx; // index in list of operator views (if any)
+ bool iface_is_query; // true if iface resolves to query
+ // instead of specific interface.
+
+ int properties; // inner (0) or outer (1) join;
+ // labeled using FROM clause,
+ // determines join algorithm.
+
+ int lineno, charno;
+
+ tablevar_t(){ opview_idx = -1; schema_ref=-1; iface_is_query = false;
+ lineno=-1; charno=-1;};
+ tablevar_t(const char *t){schema_name=t; interface="";
+ opview_idx = -1; schema_ref = -1;
+ variable_name=""; properties = 0;
+ iface_is_query = false;
+ lineno = flex_fta_lineno; charno = flex_fta_ch;};
+
+ tablevar_t(const char *i, const char *s, int iq){interface=i; schema_name=s;
+ opview_idx = -1; schema_ref = -1;
+ variable_name=""; properties = 0;
+ if(iq) iface_is_query = true; else iface_is_query = false;
+ lineno = flex_fta_lineno; charno = flex_fta_ch;};
+
+ tablevar_t(const char *m, const char *i, const char *s){
+ machine = m; interface=i; schema_name=s;
+ opview_idx = -1; schema_ref = -1;
+ variable_name=""; properties = 0;
+ iface_is_query = false;
+ lineno = flex_fta_lineno; charno = flex_fta_ch;};
+
+ tablevar_t *duplicate(){
+ tablevar_t *ret = new tablevar_t();
+ ret->lineno = lineno; ret->charno = charno;
+ ret->schema_ref = schema_ref;
+ ret->opview_idx = opview_idx;
+ ret->machine = machine;
+ ret->interface = interface;
+ ret->schema_name = schema_name;
+ ret->variable_name = variable_name;
+ ret->properties = properties;
+ ret->iface_is_query = iface_is_query;
+ return(ret);
+ };
+
+ tablevar_t *set_range_var(const char *r){
+ variable_name = r;
+ return(this);
+ };
+ tablevar_t *set_range_var(std::string r){
+ variable_name = r;
+ return(this);
+ };
+
+ void set_schema(std::string s){schema_name = s;};
+ void set_interface(std::string i){interface=i;};
+ void set_machine(std::string m){machine = m;};
+ void set_udop_alias(std::string u){udop_alias = u;};
+
+ void set_schema_ref(int r){schema_ref = r;};
+ int get_schema_ref(){return schema_ref;};
+
+ void set_opview_idx(int i){opview_idx = i;};
+ int get_opview_idx(){return opview_idx;};
+
+ void set_property(int p){properties = p;};
+ int get_property(){return properties;};
+
+ bool get_ifq(){return iface_is_query;};
+ void set_ifq(bool b){iface_is_query = b;};
+
+ std::string to_string(){
+ std::string retval;
+
+ if(machine != "" && !iface_is_query)
+ retval += "'"+machine+"'.";
+ if(interface != ""){
+ if(iface_is_query){
+ retval += '['+interface+"].";
+ }else{
+ retval += interface+".";
+ }
+ }
+ retval += schema_name;
+ if(variable_name != "") retval+=" "+variable_name;
+
+ return(retval);
+ };
+
+ std::string get_schema_name(){return schema_name;};
+ void set_schema_name(std::string n){schema_name=n;}; // DUPLICATE with set_shema
+ std::string get_var_name(){return variable_name;};
+ std::string get_interface(){return interface;};
+ std::string get_machine(){return machine;};
+ std::string get_udop_alias(){return udop_alias;};
+
+ int get_lineno(){return(lineno); };
+ int get_charno(){return(charno); };
+
+};
+
+#define INNER_JOIN_PROPERTY 0
+#define LEFT_OUTER_JOIN_PROPERTY 1
+#define RIGHT_OUTER_JOIN_PROPERTY 2
+#define OUTER_JOIN_PROPERTY 3
+#define WATCHLIST_JOIN_PROPERTY 3
+#define FILTER_JOIN_PROPERTY 4
+
+// tablevar_list_t is the list of tablevars in a FROM clause
+
+struct tablevar_list_t{
+public:
+ std::vector<tablevar_t *> tlist;
+ int properties;
+ int lineno, charno;
+// For filter join
+ colref_t *temporal_var;
+ unsigned int temporal_range;
+
+ tablevar_list_t(){properties = -1; temporal_var = NULL;}
+ tablevar_list_t(tablevar_t *t){tlist.push_back(t); properties=-1; temporal_var = NULL;
+ lineno = flex_fta_lineno; charno = flex_fta_ch;};
+ tablevar_list_t(std::vector<tablevar_t *> t){tlist = t; properties=-1; temporal_var = NULL;
+ lineno = 0; charno = 0;};
+
+ tablevar_list_t *duplicate(){
+ tablevar_list_t *ret = new tablevar_list_t();
+ ret->lineno = lineno; ret->charno = charno;
+ ret->properties = properties;
+ ret->temporal_var = temporal_var;
+ ret->temporal_range = temporal_range;
+ int i;
+ for(i=0;i<tlist.size();++i){
+ ret->append_table(tlist[i]->duplicate());
+ }
+ return(ret);
+ }
+
+
+
+ tablevar_list_t *append_table(tablevar_t *t){
+ tlist.push_back(t);
+ return(this);
+ };
+
+ std::string to_string(){
+ int i;
+ std::string retval;
+
+ for(i=0;i<tlist.size();i++){
+ if(i>0) retval.append(", ");
+ retval.append(tlist[i]->to_string());
+ }
+ return(retval);
+ };
+
+ std::vector<tablevar_t *> get_table_list(){return(tlist); };
+
+ std::vector<std::string> get_table_names(){
+ std::vector<std::string> ret;
+ int t;
+ for(t=0;t<tlist.size();++t){
+ std::string tbl_name = tlist[t]->get_schema_name();
+ ret.push_back(tbl_name);
+ }
+ return(ret);
+ }
+
+ std::vector<std::string> get_src_tbls(table_list *Schema){
+ std::vector<std::string> ret;
+ int t, sq;
+ for(t=0;t<tlist.size();++t){
+ std::string tbl_name = tlist[t]->get_schema_name();
+ int sid = Schema->find_tbl(tbl_name);
+ if(sid < 0){ ret.push_back(tbl_name);
+ }else
+ if(Schema->get_schema_type(sid) != OPERATOR_VIEW_SCHEMA){
+ ret.push_back(tbl_name);
+ }else{
+ std::vector<subquery_spec *> sqspec = Schema->get_subqueryspecs(sid);
+ for(sq=0;sq<sqspec.size();++sq){
+ ret.push_back(sqspec[sq]->name);
+ }
+ }
+ }
+ return(ret);
+ };
+
+ int size(){
+ return tlist.size();
+ };
+
+// Some accessor functions.
+
+ std::vector<std::string> get_schema_names(){
+ int i;
+ std::vector<std::string > retval;
+ for(i=0;i<tlist.size();i++){
+ retval.push_back(tlist[i]->get_schema_name());
+ }
+ return(retval);
+ }
+
+ std::vector<int> get_schema_refs(){
+ int i;
+ std::vector<int> retval;
+ for(i=0;i<tlist.size();i++){
+ retval.push_back(tlist[i]->get_schema_ref());
+ }
+ return(retval);
+ }
+
+
+ int get_schema_ref(int i){
+ if(i<0 || i>=tlist.size()) return(-1);
+ return tlist[i]->get_schema_ref();
+ };
+
+ std::string get_tablevar_name(int i){
+ if(i<0 || i>=tlist.size()) return("");
+ return tlist[i]->get_var_name();
+ };
+
+ void set_properties(int p){properties = p;};
+ int get_properties(){return properties;};
+
+ void set_colref(colref_t *c){temporal_var = c;};
+ void set_temporal_range(unsigned int t){temporal_range = t;};
+ void set_temporal_range(const char *t){temporal_range= atoi(t);};
+ colref_t *get_colref(){return temporal_var;};
+ unsigned int get_temporal_range(){return temporal_range;};
+
+};
+
+// A reference to an interface parameter.
+// (I need to be able to record the source
+// tablevar, else this would be a lot simpler).
+class ifpref_t{
+public:
+ std::string tablevar;
+ std::string pname;
+ int tablevar_ref;
+ int lineno, charno;
+
+ ifpref_t(const char *p){
+ tablevar="";
+ pname = p;
+ tablevar_ref = -1;
+ lineno = flex_fta_lineno; charno = flex_fta_ch;
+ };
+
+ ifpref_t(const char *t, const char *p){
+ tablevar=t;
+ pname = p;
+ tablevar_ref = -1;
+ lineno = flex_fta_lineno; charno = flex_fta_ch;
+ };
+
+ void set_tablevar_ref(int i){tablevar_ref = i;};
+ int get_tablevar_ref(){return tablevar_ref;};
+ std::string get_tablevar(){return tablevar;}
+ void set_tablevar(std::string t){tablevar = t;};
+ std::string get_pname(){return pname;}
+ std::string to_string(){
+ std::string ret;
+ if(tablevar != "")
+ ret += tablevar + ".";
+ ret += "@"+pname;
+ return ret;
+ };
+ bool is_equivalent(ifpref_t *i){
+ return (tablevar_ref == i->tablevar_ref) && (pname == i->pname);
+ };
+};
+
+
+
+
+// A representation of a reference to a field of a
+// stream (or table). This reference must be bound
+// to a particular schema (schema_ref) and to a
+// particular table variable in the FROM clause (tablevar_ref)
+// If the column reference was generated by the parser,
+// it will contain some binding text wich might need
+// interpretation to do the actual binding.
+class colref_t{
+public:
+ std::string interface; // specified interface, if any.
+ std::string table_name; // specified table name or range var, if any.
+ std::string field; // field name
+ bool default_table; // true iff. no table or range var given.
+ int schema_ref; // ID of the source schema.
+ int tablevar_ref; // ID of the tablevar (in FROM clause).
+ int lineno, charno;
+
+ colref_t(const char *f){
+ field = f; default_table = true;
+ schema_ref = -1; tablevar_ref = -1;
+ lineno = flex_fta_lineno; charno = flex_fta_ch;
+ };
+
+ colref_t(const char *t, const char *f){
+ table_name = t; field=f; default_table = false;
+ schema_ref = -1; tablevar_ref = -1;
+ lineno = flex_fta_lineno; charno = flex_fta_ch;
+ };
+
+ colref_t(const char *i, const char *t, const char *f){
+ interface=i;
+ table_name = t; field=f; default_table = false;
+ schema_ref = -1; tablevar_ref = -1;
+ lineno = flex_fta_lineno; charno = flex_fta_ch;
+ };
+
+ colref_t *duplicate(){
+ colref_t *retval = new colref_t(interface.c_str(), table_name.c_str(), field.c_str());
+ retval->schema_ref = schema_ref;
+ retval->tablevar_ref = tablevar_ref;
+ retval->lineno = lineno;
+ retval->charno = charno;
+ retval->default_table = default_table;
+ return(retval);
+ }
+
+ std::string to_string(){
+ if(default_table){
+ return field;
+ }else{
+ if(interface != "") return(interface+"."+table_name+"."+field);
+ return(table_name + "." + field);
+ }
+ };
+
+ std::string to_query_string(){
+ if(default_table){
+ return field;
+ }else{
+ if(interface != "") return(interface+"."+table_name+"."+field);
+ if(table_name != "") return(table_name + "." + field);
+ return(field);
+ }
+ };
+
+ int get_lineno(){return lineno; };
+ int get_charno(){return charno; };
+
+ bool uses_default_table(){return default_table; };
+
+ std::string get_field(){return(field); };
+ void set_field(std::string f){field=f;};
+ std::string get_table_name(){return(table_name);};
+ std::string get_interface(){return(interface);};
+ void set_table_name(std::string t){table_name = t; default_table=false;};
+ void set_interface(std::string i){interface=i;};
+
+ int get_schema_ref(){return schema_ref;}
+ void set_schema_ref(int s){schema_ref = s;};
+ int get_tablevar_ref(){return tablevar_ref;}
+ void set_tablevar_ref(int s){tablevar_ref = s;};
+
+// Should equivalence be based on tablevar_ref or schema_ref?
+ bool is_equivalent(colref_t *c2){
+ if(schema_ref == c2->schema_ref){
+ return(field == c2->field);
+ }
+ return(false);
+ };
+
+ bool is_equivalent_base(colref_t *c2, table_list *Schema){
+ if(Schema->get_basetbl_name(schema_ref,field) ==
+ Schema->get_basetbl_name(c2->schema_ref,c2->field)){
+ return(field == c2->field);
+ }
+ return(false);
+ };
+};
+
+class colref_list_t{
+public:
+ std::vector<colref_t *> clist;
+
+// colref_list_t(){};
+
+ colref_list_t(colref_t *c){
+ clist.push_back(c);
+ }
+
+ colref_list_t *append(colref_t *c){
+ clist.push_back(c);
+ return this;
+ }
+
+ std::vector<colref_t *> get_clist(){
+ return clist;
+ }
+};
+
+
+
+
+
+
+/*
+ A tree containing a scalar expression.
+ Used for
+ atom : a parameter or a literal
+ scalar_exp (see the scalar_exp: rule in emf.l for details)
+ function_ref (a function that has a value, e.g. an aggregate
+ function).
+ operator_type defines the contents of the node. If its a non-terminal,
+ then op has a meaning and defines the operation. See the list of
+ #define'd constants following the structure definition.
+
+
+*/
+
+#define SE_LITERAL 1
+#define SE_PARAM 2
+#define SE_COLREF 3
+#define SE_UNARY_OP 4
+#define SE_BINARY_OP 5
+#define SE_AGGR_STAR 6
+#define SE_AGGR_SE 7
+#define SE_FUNC 8
+#define SE_IFACE_PARAM 9
+
+
+class scalarexp_t{
+public:
+ int operator_type;
+ std::string op;
+ union{
+ scalarexp_t *scalarp;
+ literal_t *litp;
+ colref_t *colref;
+ ifpref_t *ifp;
+ } lhs;
+ union{
+ scalarexp_t *scalarp;
+ } rhs;
+ std::vector<scalarexp_t *> param_list;
+
+// SE node decorations -- results of query analysis.
+ data_type *dt;
+ int gb_ref; // set to the gb attr tbl ref, else -1
+ int aggr_id; // set to the aggr tbl ref, else -1
+ int fcn_id; // external function table ref, else -1
+ int partial_ref; // partial fcn table ref, else -1
+ int fcn_cache_ref; // function cache ref, else -1
+ int handle_ref; // Entry in pass-by-handle parameter table, else -1.
+ // (might be a literal or a query param).
+ bool is_superagg; // true if is aggregate and associated with supergroup.
+ std::string storage_state; // storage state of stateful fcn,
+ // empty o'wise.
+
+ int lineno, charno;
+
+ void default_init(){
+ operator_type = 0;
+ gb_ref = -1; aggr_id = -1; fcn_id = -1;
+ partial_ref = -1; fcn_cache_ref=-1;
+ handle_ref = -1;
+ dt = NULL; lineno = flex_fta_lineno; charno = flex_fta_ch;
+ is_superagg = false;
+ };
+
+ scalarexp_t(){
+ default_init();};
+
+ scalarexp_t(colref_t *c){
+ default_init();
+ operator_type = SE_COLREF;
+ lhs.colref = c;
+ };
+
+ scalarexp_t(literal_t *l){
+ default_init();
+ operator_type = SE_LITERAL;
+ lhs.litp = l;
+ };
+
+ void convert_to_literal(literal_t *l){
+// default_init();
+ if(operator_type != SE_IFACE_PARAM){
+ fprintf(stderr,"INTERNAL ERROR in literal_t::convert_to_literal, operator type isn't SE_IFACE_PARAM.\n");
+ exit(1);
+ }
+ operator_type = SE_LITERAL;
+ lhs.litp = l;
+ }
+
+ scalarexp_t(const char *o, scalarexp_t *operand){
+ default_init();
+ operator_type = SE_UNARY_OP;
+ op = o;
+ lhs.scalarp = operand;
+ };
+
+ scalarexp_t(const char *o, scalarexp_t *l_op, scalarexp_t *r_op){
+ default_init();
+ operator_type = SE_BINARY_OP;
+ op = o;
+ lhs.scalarp = l_op;
+ rhs.scalarp = r_op;
+ };
+
+ scalarexp_t(const char *o, std::vector<scalarexp_t *> op_list){
+ default_init();
+ operator_type = SE_FUNC;
+ op = o;
+ param_list = op_list;
+ };
+
+ static scalarexp_t *make_paramless_fcn(const char *o){
+ scalarexp_t *ret = new scalarexp_t();
+ ret->operator_type = SE_FUNC;
+ ret->op = o;
+ return(ret);
+ };
+
+ static scalarexp_t *make_star_aggr(const char *ag){
+ scalarexp_t *ret = new scalarexp_t();
+ ret->operator_type = SE_AGGR_STAR;
+ ret->op = ag;
+ return(ret);
+ };
+
+ static scalarexp_t *make_se_aggr(const char *ag, scalarexp_t *l_op){
+ scalarexp_t *ret = new scalarexp_t();
+ ret->operator_type = SE_AGGR_SE;
+ ret->op = ag;
+ ret->lhs.scalarp = l_op;
+ return(ret);
+ };
+
+ static scalarexp_t *make_param_reference(const char *param){
+ scalarexp_t *ret = new scalarexp_t();
+ ret->operator_type = SE_PARAM;
+ ret->op = param;
+ return(ret);
+ };
+
+ static scalarexp_t *make_iface_param_reference(ifpref_t *i){
+ scalarexp_t *ret = new scalarexp_t();
+ ret->operator_type = SE_IFACE_PARAM;
+ ret->lhs.ifp = i;
+ return(ret);
+ };
+
+
+ std::string to_string(){
+ if(operator_type == SE_COLREF){
+ return lhs.colref->to_string();
+ }
+ if(operator_type == SE_LITERAL){
+ return lhs.litp->to_string();
+ }
+ if(operator_type == SE_UNARY_OP){
+ return op + " (" + lhs.scalarp->to_string() + ")";
+ }
+ if(operator_type == SE_BINARY_OP){
+ return "(" + lhs.scalarp->to_string() + " " + op + " " + rhs.scalarp->to_string() + ")";
+ }
+ return("");
+ };
+
+ scalarexp_t *get_left_se(){return lhs.scalarp; };
+ scalarexp_t *get_right_se(){return rhs.scalarp; };
+ int get_operator_type(){return operator_type; };
+ std::string & get_op(){return op; };
+ std::string & get_param_name(){return op; };
+// std::string & get_iface_param_name(){return op; };
+ colref_t *get_colref(){return lhs.colref; };
+ ifpref_t *get_ifpref(){return lhs.ifp; };
+ literal_t *get_literal(){return lhs.litp; };
+
+ int get_lineno(){return lineno; };
+ int get_charno(){return charno; };
+
+ void set_data_type(data_type *d){dt=d; };
+ data_type *get_data_type(){return dt; };
+ void reset_temporal(){if(dt!=NULL) dt->reset_temporal();}
+
+ void set_gb_ref(int g){gb_ref = g; };
+ int get_gb_ref(){return (gb_ref); };
+ bool is_gb(){return(gb_ref >= 0); };
+
+ void set_aggr_id(int a){aggr_id = a;};
+ int get_aggr_ref(){return(aggr_id); };
+
+ void set_storage_state(std::string s){storage_state = s;};
+ std::string get_storage_state(){return storage_state;};
+
+ std::vector<scalarexp_t *> get_operands(){return param_list;};
+ void set_fcn_id(int f){fcn_id = f; };
+ int get_fcn_id(){return fcn_id; };
+
+ void set_partial_ref(int p){partial_ref = p; };
+ int get_partial_ref(){return partial_ref; };
+ bool is_partial(){return partial_ref >= 0; };
+
+ void set_fcncache_ref(int p){fcn_cache_ref = p; };
+ int get_fcncache_ref(){return fcn_cache_ref; };
+ bool is_fcncached(){return fcn_cache_ref >= 0; };
+
+ void set_handle_ref(int tf){handle_ref = tf; };
+ int get_handle_ref(){return handle_ref; };
+ bool is_handle_ref(){return handle_ref>=0; };
+
+ void set_superaggr(bool b){is_superagg=b;};
+ bool is_superaggr(){return is_superagg;};
+
+ void use_decorations_of(scalarexp_t *se){
+ if(se->get_data_type() != NULL)
+ dt = se->get_data_type()->duplicate();
+ gb_ref = se->gb_ref;
+ aggr_id = se->aggr_id;
+ fcn_id = se->fcn_id;
+ partial_ref = se->partial_ref;
+ handle_ref = se->handle_ref;
+ lineno = se->lineno;
+ charno = se->charno;
+ is_superagg = se->is_superagg;
+ };
+};
+
+
+/*
+ A (null terminated) list of scalar expressions.
+ Used for
+ selection, scalar_exp_commalist
+*/
+
+class se_list_t{
+public:
+ std::vector<scalarexp_t *> se_list;
+ int lineno, charno;
+
+ se_list_t(scalarexp_t *s){se_list.push_back(s);
+ lineno = flex_fta_lineno; charno = flex_fta_ch;};
+
+ se_list_t *append(scalarexp_t *s){
+ se_list.push_back(s);
+ return(this);
+ };
+
+ std::string to_string(){
+ int i;
+ std::string retval;
+ for(i=0;i<se_list.size();i++){
+ if(i>0) retval.append(", ");
+ retval.append(se_list[i]->to_string());
+ }
+ return(retval);
+ };
+
+ std::vector<scalarexp_t *> get_se_list(){return se_list; };
+
+
+};
+
+/*
+ select_commalist : collect some additional info about
+ the selected things -- mostly the name.
+*/
+
+struct select_element{
+ scalarexp_t *se;
+ std::string name;
+
+ select_element(){se=NULL; name="";};
+ select_element(scalarexp_t *s){se=s; name="";};
+ select_element(scalarexp_t *s, std::string n){se=s; name=n;};
+};
+
+class select_list_t{
+public:
+ std::vector<select_element *> select_list;
+ int lineno, charno;
+
+ select_list_t(){lineno = -1; charno = -1;};
+ select_list_t(scalarexp_t *s){select_list.push_back(new select_element(s));
+ lineno = flex_fta_lineno; charno = flex_fta_ch;};
+ select_list_t(scalarexp_t *s, std::string n){
+ select_list.push_back(new select_element(s,n));
+ lineno = flex_fta_lineno; charno = flex_fta_ch;
+ };
+ select_list_t *append(scalarexp_t *s){
+ select_list.push_back(new select_element(s));
+ return(this);
+ };
+ select_list_t *append(scalarexp_t *s, std::string n){
+ select_list.push_back(new select_element(s,n));
+ return(this);
+ };
+
+ std::string to_string(){
+ int i;
+ std::string retval;
+ for(i=0;i<select_list.size();i++){
+ if(i>0) retval.append(", ");
+ retval.append(select_list[i]->se->to_string());
+ if(select_list[i]->name != "")
+ retval += " AS " + select_list[i]->name;
+
+ }
+ return(retval);
+ };
+
+ std::vector<select_element *> get_select_list(){return select_list; };
+ std::vector<scalarexp_t *> get_select_se_list(){
+ std::vector<scalarexp_t *> ret;
+ int i;
+ for(i=0; i<select_list.size();++i) ret.push_back(select_list[i]->se);
+ return ret;
+ };
+};
+
+
+
+#define GB_COLREF 1
+#define GB_COMPUTED 2
+
+class gb_t{
+public:
+ std::string name;
+ std::string table;
+ std::string interface;
+ scalarexp_t *def;
+ int type;
+ int lineno, charno;
+
+ gb_t(const char *field_name){
+ interface="";
+ name = field_name; table=""; def=NULL; type=GB_COLREF;
+ lineno = flex_fta_lineno; charno = flex_fta_ch;
+ };
+
+ gb_t(const char *table_name, const char *field_name){
+ interface="";
+ name = field_name; table=""; def=NULL; type=GB_COLREF;
+ lineno = flex_fta_lineno; charno = flex_fta_ch;
+ };
+
+ gb_t(const char *iface, const char *table_name, const char *field_name){
+ interface=iface;
+ name = field_name; table=""; def=NULL; type=GB_COLREF;
+ lineno = flex_fta_lineno; charno = flex_fta_ch;
+ };
+
+ gb_t( scalarexp_t *s, const char *gname){
+ name = gname; table = ""; def = s; type = GB_COMPUTED;
+ lineno = flex_fta_lineno; charno = flex_fta_ch;
+ };
+
+ std::string to_string(){
+ std::string retval;
+ if(type == GB_COLREF){
+ if(table != ""){
+ retval = table;
+ retval.append(".");
+ }
+ retval.append(name);
+ }
+ if(type == GB_COMPUTED){
+ retval = "(scalarexp) AS ";
+ retval.append(name);
+ }
+ return(retval);
+ };
+
+ gb_t *duplicate();
+
+};
+
+/*
+ A (null terminated) list of group by attributes
+*/
+
+class gb_list_t{
+public:
+ std::vector<gb_t *> gb_list;
+ int lineno, charno;
+
+ gb_list_t(gb_t *g){gb_list.push_back(g);
+ lineno = flex_fta_lineno; charno = flex_fta_ch;};
+
+ gb_list_t *append(gb_t *s){
+ gb_list.push_back(s);
+ return(this);
+ };
+ gb_list_t(int l, int c) : lineno(l), charno(c){ }
+
+ std::string to_string(){
+ int i;
+ std::string retval;
+ for(i=0;i<gb_list.size();i++){
+ if(i>0) retval.append(", ");
+ retval.append(gb_list[i]->to_string());
+ }
+ return(retval);
+ };
+
+ std::vector<gb_t *> get_gb_list(){return gb_list; };
+
+ gb_list_t *duplicate(){
+ gb_list_t *ret = new gb_list_t(lineno, charno);
+ int i;
+ for(i=0;i<gb_list.size();++i){
+ ret->append(gb_list[i]->duplicate());
+ }
+
+ return ret;
+ }
+
+
+};
+
+class list_of_gb_list_t{
+public:
+ std::vector<gb_list_t *> gb_lists;
+
+ list_of_gb_list_t(gb_list_t *gl){
+ gb_lists.push_back(gl);
+ }
+
+ list_of_gb_list_t *append(gb_list_t *gl){
+ gb_lists.push_back(gl);
+ return this;
+ }
+};
+
+
+enum extended_gb_type {no_egb_type, gb_egb_type, rollup_egb_type,
+ cube_egb_type, gsets_egb_type};
+class extended_gb_t{
+public:
+
+ extended_gb_type type;
+ gb_t *gb;
+ std::vector<gb_list_t *> gb_lists;
+
+ extended_gb_t(){
+ gb = NULL;
+ type = no_egb_type;
+ }
+
+ ~extended_gb_t(){
+ }
+
+ static extended_gb_t *create_from_gb(gb_t *g){
+ extended_gb_t *ret = new extended_gb_t();
+ ret->type = gb_egb_type;
+ ret->gb = g;
+ return ret;
+ }
+
+ static extended_gb_t *extended_create_from_rollup(gb_list_t *gl){
+ extended_gb_t *ret = new extended_gb_t();
+ ret->type = rollup_egb_type;
+ ret->gb_lists.push_back(gl);
+ return ret;
+ }
+
+ static extended_gb_t *extended_create_from_cube(gb_list_t *gl){
+ extended_gb_t *ret = new extended_gb_t();
+ ret->type = cube_egb_type;
+ ret->gb_lists.push_back(gl);
+ return ret;
+ }
+
+ static extended_gb_t *extended_create_from_gsets(list_of_gb_list_t *lgl){
+ extended_gb_t *ret = new extended_gb_t();
+ ret->type = gsets_egb_type;
+ ret->gb_lists = lgl->gb_lists;
+ return ret;
+ }
+
+ extended_gb_t *duplicate(){
+ extended_gb_t *ret = new extended_gb_t();
+ ret->type = type;
+ if(gb != NULL)
+ ret->gb = gb->duplicate();
+ int i;
+ for(i=0;i<gb_lists.size();++i){
+ ret->gb_lists.push_back(gb_lists[i]->duplicate());
+ }
+ return ret;
+ }
+
+
+ std::string to_string(){
+ std::string ret;
+ int i;
+
+ switch(type){
+ case no_egb_type:
+ return "Error, undefined extended gb type.";
+ case gb_egb_type:
+ return gb->to_string();
+ case rollup_egb_type:
+ return "ROLLUP("+gb_lists[0]->to_string()+")";
+ case cube_egb_type:
+ return "CUBE("+gb_lists[0]->to_string()+")";
+ case gsets_egb_type:
+ ret = "GROUPING_SETS(";
+ for(i=0;i<gb_lists.size();++i){
+ if(i>0) ret+=", ";
+ ret += "(" +gb_lists[i]->to_string()+")";
+ }
+ ret += ")";
+ return ret;
+ default:
+ break;
+ }
+ return "Error, unknown extended gb type.";
+ }
+
+};
+
+class extended_gb_list_t{
+public:
+ std::vector<extended_gb_t *> gb_list;
+ int lineno, charno;
+
+ extended_gb_list_t(extended_gb_t *g){gb_list.push_back(g);
+ lineno = flex_fta_lineno; charno = flex_fta_ch;};
+
+ extended_gb_list_t *append(extended_gb_t *s){
+ gb_list.push_back(s);
+ return(this);
+ };
+
+ std::string to_string(){
+ int i;
+ std::string retval;
+ for(i=0;i<gb_list.size();i++){
+ if(i>0) retval.append(", ");
+ retval.append(gb_list[i]->to_string());
+ }
+ return(retval);
+ };
+
+ std::vector<extended_gb_t *> get_gb_list(){return gb_list; };
+};
+
+
+
+/*
+ A predicate tree. Structure is similar to
+ a scalar expression tree but the type is always boolean.
+ Used by
+ opt_where_clause, where_clause, opt_having_clause,
+ search_condition, predicate, comparison_predicate, repl_predicate
+*/
+
+#define PRED_COMPARE 1
+#define PRED_UNARY_OP 2
+#define PRED_BINARY_OP 3
+#define PRED_FUNC 4
+#define PRED_IN 5
+
+class predicate_t{
+public:
+ int operator_type;
+ std::string op;
+ union {
+ predicate_t *predp;
+ scalarexp_t *sexp;
+ }lhs;
+ union {
+ predicate_t *predp;
+ scalarexp_t *sexp;
+ literal_list_t *ll;
+ }rhs;
+ std::vector<scalarexp_t *> param_list; /// pred fcn params
+ int fcn_id; /// external pred fcn id
+ int combinable_ref;
+ bool is_sampling_fcn;
+ int lineno, charno;
+
+ predicate_t(scalarexp_t *s, literal_list_t *litl){
+ operator_type = PRED_IN;
+ op = "in";
+ lhs.sexp = s;
+ rhs.ll = litl;
+ fcn_id = -1;
+ combinable_ref = -1;
+ lineno = flex_fta_lineno; charno = flex_fta_ch;
+ };
+
+ predicate_t(scalarexp_t *s, std::vector<literal_t *> litv){
+ operator_type = PRED_IN;
+ op = "in";
+ lhs.sexp = s;
+ rhs.ll = new literal_list_t(litv);
+ fcn_id = -1;
+ combinable_ref = -1;
+ lineno = flex_fta_lineno; charno = flex_fta_ch;
+ };
+
+
+ predicate_t(scalarexp_t *l_op, const char *o, scalarexp_t *r_op){
+ operator_type = PRED_COMPARE;
+ op = o;
+ lhs.sexp = l_op;
+ rhs.sexp = r_op;
+ fcn_id = -1;
+ combinable_ref = -1;
+ lineno = flex_fta_lineno; charno = flex_fta_ch;
+ };
+
+ predicate_t(const char *o, predicate_t *p){
+ operator_type = PRED_UNARY_OP;
+ op = o;
+ lhs.predp = p;
+ fcn_id = -1;
+ combinable_ref = -1;
+ lineno = flex_fta_lineno; charno = flex_fta_ch;
+ };
+
+ predicate_t(const char *o, predicate_t *l_p, predicate_t *r_p){
+ operator_type = PRED_BINARY_OP;
+ op = o;
+ lhs.predp = l_p;
+ rhs.predp = r_p;
+ fcn_id = -1;
+ combinable_ref = -1;
+ lineno = flex_fta_lineno; charno = flex_fta_ch;
+ };
+
+ predicate_t(const char *o, std::vector<scalarexp_t *> op_list){
+ operator_type = PRED_FUNC;
+ op = o;
+ param_list = op_list;
+ fcn_id = -1;
+ combinable_ref = -1;
+ lineno = flex_fta_lineno; charno = flex_fta_ch;
+ };
+
+ predicate_t(const char *o){
+ op = o;
+ fcn_id = -1;
+ combinable_ref = -1;
+ lineno = flex_fta_lineno; charno = flex_fta_ch;
+ };
+
+
+ static predicate_t *make_paramless_fcn_predicate(const char *o){
+ predicate_t *ret = new predicate_t(o);
+ ret->operator_type = PRED_FUNC;
+ ret->fcn_id = -1;
+ ret->combinable_ref = -1;
+ return(ret);
+ };
+
+ std::string to_string(){
+ if(operator_type == PRED_IN){
+ return( lhs.sexp->to_string() + " " + op + " [ " + rhs.ll->to_string() +" ]");
+ }
+ if(operator_type == PRED_COMPARE){
+ return( lhs.sexp->to_string() + " " + op + " " + rhs.sexp->to_string() );
+ }
+ if(operator_type == PRED_UNARY_OP){
+ return( op + " (" + lhs.predp->to_string() + ")" );
+ }
+ if(operator_type == PRED_BINARY_OP){
+ return( "(" + lhs.predp->to_string() + " " + op + " " + rhs.predp->to_string() + ")" );
+ }
+ if(operator_type == PRED_FUNC){
+ std::string ret = op + "[ ";
+ int i;
+ for(i=0;i<param_list.size();++i){
+ if(i>0) ret += ", ";
+ ret += param_list[i]->to_string();
+ }
+ ret += "] ";
+ return(ret);
+ }
+ return("");
+ };
+
+ std::vector<scalarexp_t *> get_op_list(){return param_list; };
+ int get_operator_type(){return operator_type; };
+ std::string get_op(){return op; };
+ int get_lineno(){return lineno; };
+ int get_charno(){return charno; };
+ int get_combinable_ref(){return combinable_ref;}
+ void set_combinable_ref(int f){combinable_ref = f;};
+ predicate_t *get_left_pr(){return(lhs.predp); };
+ predicate_t *get_right_pr(){return(rhs.predp); };
+ scalarexp_t *get_left_se(){return(lhs.sexp); };
+ scalarexp_t *get_right_se(){return(rhs.sexp); };
+ std::vector<literal_t *> get_lit_vec(){return(rhs.ll->get_literal_vector()); };
+
+ void swap_scalar_operands(){
+ if(operator_type != PRED_COMPARE){
+ fprintf(stderr,"INTERNAL ERROR: swap_scalar_operands called on predicate of type %d\n",operator_type);
+ exit(1);
+ }
+ scalarexp_t *tmp;
+ tmp = lhs.sexp; lhs.sexp = rhs.sexp; rhs.sexp = tmp;
+ if(op == ">"){op = "<"; return;}
+ if(op == ">="){op = "<="; return;}
+ if(op == "<"){op = ">"; return;}
+ if(op == "<="){op = ">="; return;}
+ };
+ void set_fcn_id(int i){fcn_id = i;};
+ int get_fcn_id(){return fcn_id;};
+
+
+};
+
+
+/*
+ A structure that holds the components of a query.
+ This is the root type.
+ Used by manipulative_statement, select_statement, table_exp
+*/
+
+#define SELECT_QUERY 1
+#define MERGE_QUERY 2
+#define WATCHLIST_QUERY 3
+
+class table_exp_t{
+public:
+ int query_type; // roughly, the type of the query.
+ ss_map nmap; // DEFINE block
+ std::vector<var_pair_t *> query_params; // PARAM block (uninterpreted)
+ select_list_t *sl; // SELECT
+ tablevar_list_t *fm; // FROM
+ predicate_t *wh; // WHERE
+ predicate_t *hv; // HAVING
+ predicate_t *cleaning_when; // CLEANING WHEN
+ predicate_t *cleaning_by; // CLEANING BY
+ predicate_t *closing_when; // CLOSING WHEN
+ std::vector<extended_gb_t *> gb; // GROUP BY
+ std::vector<colref_t *> mergevars; // merge colrefs.
+ std::vector<colref_t *> supergb; // supergroup.
+ scalarexp_t *slack; // merge slack
+
+ field_entry_list * fel; // List of watchlist fields
+
+ bool exernal_visible; // true iff. it can be subscribed to.
+ int lineno, charno;
+
+
+ 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)
+ {fm = f; wh = p; hv = h;
+ cleaning_when = cw; cleaning_by = cb;
+ closing_when = closew;
+ if(g != NULL)
+ gb = g->gb_list;
+ if(sg != NULL)
+ supergb = sg->get_clist();
+ slack = NULL;
+ query_type = SELECT_QUERY;
+ exernal_visible = true;
+ lineno = flex_fta_lineno; charno = flex_fta_ch;
+ };
+
+ table_exp_t(colref_list_t *mv, tablevar_list_t *f)
+ {fm = f; mergevars=mv->get_clist();
+ slack = NULL;
+ query_type = MERGE_QUERY;
+ exernal_visible = true;
+ lineno = flex_fta_lineno; charno = flex_fta_ch;
+ };
+
+ table_exp_t(colref_list_t *mv, scalarexp_t *sl, tablevar_list_t *f)
+ {fm = f; mergevars=mv->get_clist();
+ slack = sl;
+ query_type = MERGE_QUERY;
+ exernal_visible = true;
+ lineno = flex_fta_lineno; charno = flex_fta_ch;
+ };
+
+// Figure out the temporal merge field at analyze_fta time.
+ static table_exp_t *make_deferred_merge(std::vector<std::string> src_tbls){
+ table_exp_t *ret = new table_exp_t();
+ ret->query_type = MERGE_QUERY;
+ ret->fm = new tablevar_list_t();
+ int t;
+ for(t=0;t<src_tbls.size();++t){
+ ret->fm->append_table(new tablevar_t(src_tbls[t].c_str()));
+ }
+ ret->lineno = 0; ret->charno = 0;
+ return ret;
+ }
+
+// For externally-defined watchlist
+ static table_exp_t *make_watchlist_tbl(field_entry_list *fel_){
+ table_exp_t *ret = new table_exp_t();
+ ret->query_type = WATCHLIST_QUERY;
+ ret->fel = fel_;
+ ret->sl=NULL;
+ ret->fm= new tablevar_list_t(); // generic analyses need the fm clause
+ ret->wh=NULL;
+ ret->hv=NULL;
+ ret->cleaning_when=NULL;
+ ret->cleaning_by=NULL;
+ ret->closing_when=NULL;
+ ret->slack=NULL;
+ ret->exernal_visible = true;
+ ret->lineno = flex_fta_lineno; ret->charno = flex_fta_ch;
+ };
+
+
+
+ table_exp_t(){
+ fm = NULL; sl = NULL; wh=NULL; hv=NULL;
+ slack = NULL;
+ cleaning_when=NULL; cleaning_by = NULL;
+ closing_when = NULL;
+ exernal_visible = true;
+ };
+
+ table_exp_t *add_selection(select_list_t *s){
+ sl = s;
+ return(this);
+ };
+
+ void add_nmap(var_defs_t *vd){
+ int n;
+ if(vd != NULL){
+ for(n=0;n<vd->size();++n){
+ nmap[vd->get_name(n)] = vd->get_def(n);
+//printf("Adding (%s, %s) to name map.\n",vd->get_name(n).c_str(), vd->get_def(n).c_str());
+ }
+ }
+ };
+
+ void add_param_list(var_defs_t *vd){
+ int n;
+ if(vd != NULL){
+ query_params = vd->get_nvec();
+ }
+ };
+
+
+ std::string to_string(){
+ std::string retval;
+ if(sl != NULL){
+ retval.append("Select " + sl->to_string() + "\n");
+ }
+ if(fm != NULL){
+ retval.append("From " + fm->to_string() + "\n");
+ }
+ if(wh != NULL){
+ retval.append("Where "+ wh->to_string() + "\n");
+ }
+ if(hv != NULL){
+ retval.append("Having "+hv->to_string() + "\n");
+ }
+ return(retval);
+ };
+
+ tablevar_list_t *get_from(){return fm; };
+ select_list_t *get_select(){return sl; };
+ std::vector<select_element *> get_sl_vec(){return sl->get_select_list(); };
+ predicate_t *get_where(){return wh; };
+ predicate_t *get_having(){return hv; };
+ predicate_t *get_cleaning_by(){return cleaning_by; };
+ predicate_t *get_cleaning_when(){return cleaning_when; };
+ predicate_t *get_closing_when(){return closing_when; };
+ std::vector<extended_gb_t *> get_groupby(){return(gb); };
+ std::vector<colref_t *> get_supergb(){return supergb;};
+
+ ss_map get_name_map(){return nmap;};
+
+ bool name_exists(std::string nm){
+ return(nmap.count(nm) > 0);
+ };
+
+ std::string get_val_of_name(std::string nm){
+ if(nmap.count(nm) == 0) return("");
+ else return nmap[nm];
+ };
+
+ void set_val_of_name(const std::string n, const std::string v){
+ nmap[n]=v;
+ }
+
+ void set_visible(bool v){exernal_visible=v;};
+ bool get_visible(){return exernal_visible;};
+};
+
+struct query_list_t{
+ std::vector<table_exp_t *> qlist;
+
+ query_list_t(table_exp_t *t){
+ qlist.push_back(t);
+ };
+ query_list_t *append(table_exp_t *t){
+ qlist.push_back(t);
+ return(this);
+ };
+};
+
+
+#define TABLE_PARSE 1
+#define QUERY_PARSE 2
+#define STREAM_PARSE 3
+
+struct fta_parse_t{
+ query_list_t *parse_tree_list;
+ table_exp_t *fta_parse_tree;
+ table_list *tables;
+ int parse_type;
+};
+
+
+
+
+
+ extern table_exp_t *fta_parse_tree;
+
+
+
+
+
+#endif
+