-/* ------------------------------------------------\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 __SCHEMA_DEF_H_INCLUDED__\r
-#define __SCHEMA_DEF_H_INCLUDED__\r
-\r
-#include <string>\r
-#include <vector>\r
-#include <map>\r
-#include<set>\r
-\r
-#include <string.h>\r
-#include <stdlib.h>\r
-\r
-\r
-// A param_list is used to represent a list of\r
-// parameters with optional values.\r
-\r
-class param_list{\r
-private:\r
- std::map< std::string, std::string > pmap;\r
-\r
-public:\r
- param_list(){};\r
- param_list(const char *key){\r
- pmap[key]="";\r
- };\r
- param_list(const char *key, const char *val){\r
- pmap[key]=val;\r
- };\r
-\r
- param_list *append(const char *key){\r
- pmap[key]="";\r
- return(this);\r
- };\r
- param_list *append(const char *key, const char *val){\r
- pmap[key]=val;\r
- return(this);\r
- };\r
- param_list *append( std::string key){\r
- pmap[key]="";\r
- return(this);\r
- };\r
-\r
- int size(){return pmap.size();};\r
-\r
-\r
- bool contains_key(std::string key){\r
- return(pmap.count(key)>0);\r
- }\r
-\r
- int delete_key(std::string k){\r
- return pmap.erase(k);\r
- }\r
-\r
- std::string val_of(std::string key){\r
- if(pmap.count(key)>0)\r
- return(pmap[key]);\r
- return(std::string(""));\r
- }\r
-\r
- std::vector<std::string> get_key_vec(){\r
- std::vector<std::string> retval;\r
- std::map<std::string, std::string>::iterator mssi;\r
- for(mssi=pmap.begin();mssi!=pmap.end();++mssi){\r
- retval.push_back( (*mssi).first );\r
- }\r
- return(retval);\r
- }\r
-\r
- std::string to_string();\r
-};\r
-\r
-\r
-// list of names, order matters.\r
-class name_vec{\r
-public:\r
- std::vector<std::string> svec;\r
- std::vector<std::string> nvec;\r
- std::vector<param_list *> pvec;\r
-\r
- name_vec(char *c, char *n, param_list *p){\r
- svec.push_back(c);\r
- nvec.push_back(n);\r
- if(p) pvec.push_back(p);\r
- else pvec.push_back(new param_list());\r
- };\r
-\r
- name_vec *append(char *c, char *n, param_list *p){\r
- svec.push_back(c);\r
- nvec.push_back(n);\r
- if(p) pvec.push_back(p);\r
- else pvec.push_back(new param_list());\r
- return this;\r
- };\r
-};\r
-\r
-\r
-\r
-// A field in a STREAM or PROTOCOL\r
-\r
-\r
-class field_entry{\r
-private:\r
- std::string type; // data type\r
- std::string name; // name in a query\r
- std::string function; // access function, if any (PROTOCOL only).\r
- param_list *mod_list; // special properties.\r
- std::set<std::string> ufcns; // unpacking functions, if any.\r
-\r
- std::string base_table; // for hierarchically structured data sources,\r
- // the bast table where the field is defined.\r
- // mostly used for computing the LFTA prefilter.\r
-public:\r
-\r
- field_entry(const char *t, const char *n, const char *f, param_list *plist, param_list *ulist){\r
- if(plist == NULL)\r
- mod_list = new param_list();\r
- else\r
- mod_list = plist;\r
- if(ulist){\r
- int u;\r
- std::vector<std::string> tmp_ufl = ulist->get_key_vec();\r
- for(u=0;u<tmp_ufl.size();++u)\r
- ufcns.insert(tmp_ufl[u]);\r
- }\r
-\r
- type=t; name=n; function=f;\r
- base_table = "";\r
- };\r
-\r
- field_entry(std::string t, std::string n, std::string f, param_list *plist, const std::set<std::string> &ulist){\r
- if(plist == NULL)\r
- mod_list = new param_list();\r
- else\r
- mod_list = plist;\r
- ufcns = ulist;\r
- type=t; name=n; function=f;\r
- base_table = "";\r
- };\r
-\r
- field_entry(std::string n, std::string t){\r
- name = n;\r
- type = t;\r
- mod_list = new param_list();\r
- }\r
-\r
- void add_unpack_fcns(param_list *ufl){\r
- std::vector<std::string> new_ufl = ufl->get_key_vec();\r
- int u;\r
- for(u=0;u<new_ufl.size();++u)\r
- ufcns.insert(new_ufl[u]);\r
- }\r
-\r
-\r
- param_list *get_modifier_list(){return mod_list; };\r
- std::string get_type(){return(type);};\r
- std::string get_name(){return(name);};\r
- std::string get_fcn(){return(function);};\r
- std::set<std::string> get_unpack_fcns(){\r
- return ufcns;\r
- }\r
-\r
- void set_basetable(std::string b){base_table=b;};\r
- std::string get_basetable(){return base_table;};\r
-\r
- std::string to_string();\r
-\r
- int delete_modifier(std::string k){\r
- return mod_list->delete_key(k);\r
- }\r
- void add_modifier(const char *k, const char *v){\r
- mod_list->append(k,v);\r
- }\r
- void add_modifier(const char *k){\r
- mod_list->append(k);\r
- }\r
-\r
-};\r
-\r
-\r
-// list of fields. An intermediate parse structure.\r
-// it gets loaded into table_def.fields\r
-\r
-class field_entry_list{\r
-private:\r
- std::vector<field_entry *> fl;\r
-\r
-public:\r
- field_entry_list(){};\r
-\r
- field_entry_list(field_entry *f){\r
- fl.push_back(f);\r
- };\r
-\r
- field_entry_list *append_field(field_entry *f){\r
- fl.push_back(f);\r
- return(this);\r
- };\r
-\r
- std::vector<field_entry *> get_list(){return fl; };\r
-};\r
-\r
-class subquery_spec{\r
-public:\r
- std::string name;\r
- std::vector<std::string> types;\r
- std::vector<std::string> names;\r
- std::vector<param_list *> modifiers;\r
-\r
-\r
- subquery_spec(){}\r
-\r
- subquery_spec(const char *n, name_vec *t){\r
- name = n;\r
- types = t->svec;\r
- names = t->nvec;\r
- modifiers = t->pvec;\r
- };\r
-\r
- std::string to_string(){\r
- std::string ret = name+" (";\r
- int i;\r
- for(i=0;i<types.size();++i){\r
- if(i>0) ret+=", ";\r
- ret += types[i] + " " + names[i];\r
- if(modifiers[i]->size() >0){\r
- ret+=" ("+modifiers[i]->to_string()+") ";\r
- }\r
- }\r
- ret += ") ";\r
- return(ret);\r
- };\r
-\r
- subquery_spec *duplicate(){\r
- subquery_spec *ret = new subquery_spec();\r
- ret->name = name;\r
- ret->types = types;\r
- ret->names = names;\r
-\r
- return ret;\r
- }\r
-\r
-\r
-\r
-};\r
-\r
-class subqueryspec_list{\r
-public:\r
- std::vector<subquery_spec *> spec_list;\r
-\r
- subqueryspec_list(subquery_spec *ss){\r
- spec_list.push_back(ss);\r
- };\r
- subqueryspec_list *append(subquery_spec *ss){\r
- spec_list.push_back(ss);\r
- return this;\r
- };\r
-};\r
-\r
-class unpack_fcn{\r
-public:\r
- std::string name;\r
- std::string fcn;\r
- int cost;\r
-\r
- unpack_fcn(const char *n, const char *f, const char *c){\r
- name = n;\r
- fcn = f;\r
- cost = atoi(c);\r
- };\r
-};\r
-\r
-class unpack_fcn_list{\r
-public:\r
- std::vector<unpack_fcn *> ufcn_v;\r
-\r
- unpack_fcn_list(unpack_fcn *u){\r
- ufcn_v.push_back(u);\r
- };\r
-\r
- unpack_fcn_list *append(unpack_fcn *u){\r
- ufcn_v.push_back(u);\r
- return this;\r
- };\r
-};\r
-\r
-\r
-\r
-\r
-// forward definition, needed for table_def\r
-class table_exp_t;\r
-struct query_list_t;\r
-\r
-/* ============================================\r
- The schema can support several different\r
- flavors of table.\r
- PROTOCOL : the base data that an FTA can retrieve.\r
- STREAM : Data created by an FTA or a stream operator.\r
- More to come. Perhaps this is better handled by\r
- annotations in the schema def.\r
- ============================================= */\r
-\r
-#define PROTOCOL_SCHEMA 1\r
-#define STREAM_SCHEMA 2\r
-#define OPERATOR_VIEW_SCHEMA 3\r
-#define UNPACK_FCNS_SCHEMA 4\r
-\r
-// Represent a STREAM, PROTOCOL, OPERATOR_VIEW, or UNPACK_FCN list.\r
-\r
-class table_def{\r
-private:\r
- std::string table_name;\r
- std::vector<field_entry *> fields;\r
- param_list *base_tables; // if PROTOCOL, the PROTOCOLS that\r
- // this PROTOCOL inherits fields from.\r
- int schema_type; // STREAM_SCHEMA, PROTOCOL_SCHEMA, OPERATOR_VIEW_SCHEMA\r
-// For operator_view tables\r
- param_list *op_properties;\r
- std::vector<subquery_spec *> qspec_list;\r
- param_list *selpush;\r
-\r
-public:\r
-// for unpacking function group specs.\r
- std::vector<unpack_fcn *> ufcn_list;\r
-\r
-\r
-\r
-// Unpack functions defined at the PROTOCOL level are added to\r
-// PROTOCOL fields here ... implying that ony those fields\r
-// explicitly defined in the PROTOCOL (as opposed to inherited)\r
-// get the PROTOCOL-wide unpack functions.\r
- table_def(const char *name, param_list *plist, param_list *ufcn_l, field_entry_list *fel, int sch_t){\r
- int f;\r
- if(plist == NULL)\r
- base_tables = new param_list();\r
- else\r
- base_tables = plist;\r
- table_name =name;\r
- fields = fel->get_list();\r
- schema_type = sch_t;\r
-\r
-// fields inherit table-level unpacking functions, if any.\r
- if(ufcn_l){\r
- for(f=0;f<fields.size();++f)\r
- fields[f]->add_unpack_fcns(ufcn_l);\r
- }\r
-\r
- op_properties = new param_list();\r
- selpush = new param_list();\r
- };\r
-\r
- table_def(const char *name, param_list *oprop, field_entry_list *fel,\r
- subqueryspec_list *ql, param_list *selp);\r
-\r
- table_def(unpack_fcn_list *ufcn_l){\r
- schema_type = UNPACK_FCNS_SCHEMA;\r
- ufcn_list = ufcn_l->ufcn_v;\r
- }\r
-\r
- table_def(){};\r
-\r
- table_def *make_shallow_copy(std::string n);\r
-\r
- void mangle_subq_names(std::string mngl);\r
-\r
- std::string get_tbl_name(){return table_name; };\r
- std::vector<field_entry *> get_fields(){return(fields); };\r
-\r
- field_entry *get_field(int i){\r
- if(i>=0 && i<fields.size()) return(fields[i]);\r
- return NULL;\r
- };\r
-\r
- std::string get_field_name(int i){\r
- if(i>=0 && i<fields.size()) return(fields[i]->get_name());\r
- return "";\r
- };\r
-\r
- bool contains_field(std::string f);\r
- bool contains_field(int f);\r
-\r
- int get_field_idx(std::string f);\r
- std::string get_type_name(std::string f);\r
- param_list *get_modifier_list(std::string f);\r
- std::string get_fcn(std::string f);\r
-\r
- std::string get_op_prop(std::string s){\r
- return op_properties->val_of(s);\r
- };\r
-\r
-// Used in generating the LFTA prefilter\r
- std::string get_field_basetable(std::string f);\r
-\r
-\r
- int verify_no_duplicates(std::string &err);\r
- int verify_access_fcns(std::string &err);\r
-\r
-\r
- std::vector<std::string> get_pred_tbls(){\r
- return base_tables->get_key_vec() ;\r
- };\r
-\r
- int add_field(field_entry *fe);\r
-\r
- int get_schema_type(){return schema_type;};\r
-\r
- std::vector<subquery_spec *> get_subqueryspecs(){return qspec_list;};\r
-\r
- std::string to_string();\r
- std::string to_stream_string(){\r
- int tmp_sch = schema_type;\r
- schema_type = STREAM_SCHEMA;\r
- std::string ret = this->to_string();\r
- schema_type = tmp_sch;\r
- return ret;\r
- }\r
-};\r
-\r
-\r
-// A Schema -- a collection of stream layout definitions.\r
-\r
-class table_list{\r
-private:\r
- std::vector<table_def *> tbl_list;\r
- // for an unpack_fcn_list, collect from the set of\r
- // UNPACK_FCNS_SCHEMA in the table list.\r
- std::map<std::string, std::string> ufcn_fcn;\r
- std::map<std::string, int> ufcn_cost;\r
-\r
-\r
-public:\r
- table_list(table_def *td){tbl_list.push_back(td); };\r
- table_list(){};\r
-\r
- table_list *append_table(table_def *td){\r
- tbl_list.push_back(td);\r
- return(this);\r
- };\r
-\r
- int add_table(table_def *td);\r
- table_def *get_table(int t){\r
- if(t<0 || t>tbl_list.size()) return(NULL);\r
- return(tbl_list[t]);\r
- };\r
-\r
- int add_duplicate_table(std::string src, std::string dest){\r
- int src_pos = this->find_tbl(src);\r
- if(src_pos<0)\r
- return src_pos;\r
- table_def *dest_tbl = tbl_list[src_pos]->make_shallow_copy(dest);\r
- tbl_list.push_back(dest_tbl);\r
- return tbl_list.size()-1;\r
- }\r
-\r
- void mangle_subq_names(int pos, std::string mngl){\r
- tbl_list[pos]->mangle_subq_names(mngl);\r
- }\r
-\r
-\r
- int size(){return tbl_list.size();};\r
-\r
-/////////////\r
-// Accessor methods : get table and field info without\r
-// descending into the underlying data structures.\r
-// Can specify a table by name (string), or by index (int)\r
-// (e.g. returned by get_table_ref)\r
-\r
- int get_ufcn_cost(std::string fname){\r
- if(ufcn_cost.count(fname))\r
- return ufcn_cost[fname];\r
- else\r
- return -1;\r
- }\r
- std::string get_ufcn_fcn(std::string fname){\r
- if(ufcn_fcn.count(fname))\r
- return ufcn_fcn[fname];\r
- else\r
- return "ERROR_ufcn_fcn_of_"+fname+"_not_found";\r
- }\r
-\r
- std::string get_table_name(int i){\r
- if(i>tbl_list.size()) return("");\r
- else return tbl_list[i]->get_tbl_name();\r
- };\r
- std::vector<std::string> get_table_names();\r
-\r
- std::vector<field_entry *> get_fields(std::string t);\r
- field_entry *get_field(std::string t, int i);\r
- field_entry *get_field(int t, std::string f){\r
- return tbl_list[t]->get_field(tbl_list[t]->get_field_idx(f));\r
- }\r
- int get_field_idx(std::string t, std::string f);\r
-\r
- int find_tbl(std::string t);\r
-\r
- std::vector<int> get_tblref_of_field(std::string f);\r
-\r
- int get_table_ref(std::string t);\r
-\r
- std::string get_type_name(int t, std::string f){\r
- return(tbl_list[t]->get_type_name(f));\r
- };\r
-\r
- param_list *get_modifier_list(int t, std::string f){\r
- return(tbl_list[t]->get_modifier_list(f));\r
- };\r
-\r
- std::string get_fcn(int t, std::string f){\r
- return(tbl_list[t]->get_fcn(f));\r
- };\r
-\r
- int get_schema_type(int t){\r
- return(tbl_list[t]->get_schema_type());\r
- };\r
-\r
- std::string get_op_prop(int t, std::string s){\r
- return(tbl_list[t]->get_op_prop(s));\r
- };\r
-\r
- std::vector<subquery_spec *> get_subqueryspecs(int t){\r
- return tbl_list[t]->get_subqueryspecs();\r
- };\r
-\r
-\r
-// Used in generating the LFTA prefilter\r
- std::string get_basetbl_name(int t, std::string f){\r
- return(tbl_list[t]->get_field_basetable(f));\r
- };\r
-\r
- bool contains_field(int t, std::string f){\r
- return(tbl_list[t]->contains_field(f));\r
- };\r
-\r
-\r
-//////////////\r
-// Additional methods\r
-\r
-// Process field inheritance for PROTOCOL tables.\r
- int unroll_tables(std::string &err);\r
-\r
- std::string to_string();\r
-};\r
-#endif\r
+/* ------------------------------------------------
+Copyright 2014 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 __SCHEMA_DEF_H_INCLUDED__
+#define __SCHEMA_DEF_H_INCLUDED__
+
+#include <string>
+#include <vector>
+#include <map>
+#include<set>
+
+#include <string.h>
+#include <stdlib.h>
+
+
+// A param_list is used to represent a list of
+// parameters with optional values.
+
+class param_list{
+private:
+ std::map< std::string, std::string > pmap;
+
+public:
+ param_list(){};
+ param_list(const char *key){
+ pmap[key]="";
+ };
+ param_list(const char *key, const char *val){
+ pmap[key]=val;
+ };
+
+ param_list *append(const char *key){
+ pmap[key]="";
+ return(this);
+ };
+ param_list *append(const char *key, const char *val){
+ pmap[key]=val;
+ return(this);
+ };
+ param_list *append( std::string key){
+ pmap[key]="";
+ return(this);
+ };
+
+ int size(){return pmap.size();};
+
+
+ bool contains_key(std::string key){
+ return(pmap.count(key)>0);
+ }
+
+ int delete_key(std::string k){
+ return pmap.erase(k);
+ }
+
+ std::string val_of(std::string key){
+ if(pmap.count(key)>0)
+ return(pmap[key]);
+ return(std::string(""));
+ }
+
+ std::vector<std::string> get_key_vec(){
+ std::vector<std::string> retval;
+ std::map<std::string, std::string>::iterator mssi;
+ for(mssi=pmap.begin();mssi!=pmap.end();++mssi){
+ retval.push_back( (*mssi).first );
+ }
+ return(retval);
+ }
+
+ std::string to_string();
+};
+
+
+// list of names, order matters.
+class name_vec{
+public:
+ std::vector<std::string> svec;
+ std::vector<std::string> nvec;
+ std::vector<param_list *> pvec;
+
+ name_vec(char *c, char *n, param_list *p){
+ svec.push_back(c);
+ nvec.push_back(n);
+ if(p) pvec.push_back(p);
+ else pvec.push_back(new param_list());
+ };
+
+ name_vec *append(char *c, char *n, param_list *p){
+ svec.push_back(c);
+ nvec.push_back(n);
+ if(p) pvec.push_back(p);
+ else pvec.push_back(new param_list());
+ return this;
+ };
+};
+
+
+
+// A field in a STREAM or PROTOCOL
+
+
+class field_entry{
+private:
+ std::string type; // data type
+ std::string name; // name in a query
+ std::string function; // access function, if any (PROTOCOL only).
+ param_list *mod_list; // special properties.
+ std::set<std::string> ufcns; // unpacking functions, if any.
+
+ std::string base_table; // for hierarchically structured data sources,
+ // the bast table where the field is defined.
+ // mostly used for computing the LFTA prefilter.
+public:
+
+ field_entry(const char *t, const char *n, const char *f, param_list *plist, param_list *ulist){
+ if(plist == NULL)
+ mod_list = new param_list();
+ else
+ mod_list = plist;
+ if(ulist){
+ int u;
+ std::vector<std::string> tmp_ufl = ulist->get_key_vec();
+ for(u=0;u<tmp_ufl.size();++u)
+ ufcns.insert(tmp_ufl[u]);
+ }
+
+ type=t; name=n; function=f;
+ base_table = "";
+ };
+
+ field_entry(std::string t, std::string n, std::string f, param_list *plist, const std::set<std::string> &ulist){
+ if(plist == NULL)
+ mod_list = new param_list();
+ else
+ mod_list = plist;
+ ufcns = ulist;
+ type=t; name=n; function=f;
+ base_table = "";
+ };
+
+ field_entry(std::string n, std::string t){
+ name = n;
+ type = t;
+ mod_list = new param_list();
+ }
+
+ void add_unpack_fcns(param_list *ufl){
+ std::vector<std::string> new_ufl = ufl->get_key_vec();
+ int u;
+ for(u=0;u<new_ufl.size();++u)
+ ufcns.insert(new_ufl[u]);
+ }
+
+
+ param_list *get_modifier_list(){return mod_list; };
+ std::string get_type(){return(type);};
+ std::string get_name(){return(name);};
+ std::string get_fcn(){return(function);};
+ std::set<std::string> get_unpack_fcns(){
+ return ufcns;
+ }
+
+ void set_basetable(std::string b){base_table=b;};
+ std::string get_basetable(){return base_table;};
+
+ std::string to_string();
+
+ int delete_modifier(std::string k){
+ return mod_list->delete_key(k);
+ }
+ void add_modifier(const char *k, const char *v){
+ mod_list->append(k,v);
+ }
+ void add_modifier(const char *k){
+ mod_list->append(k);
+ }
+
+};
+
+
+// list of fields. An intermediate parse structure.
+// it gets loaded into table_def.fields
+
+class field_entry_list{
+private:
+ std::vector<field_entry *> fl;
+
+public:
+ field_entry_list(){};
+
+ field_entry_list(field_entry *f){
+ fl.push_back(f);
+ };
+
+ field_entry_list *append_field(field_entry *f){
+ fl.push_back(f);
+ return(this);
+ };
+
+ std::vector<field_entry *> get_list(){return fl; };
+};
+
+class subquery_spec{
+public:
+ std::string name;
+ std::vector<std::string> types;
+ std::vector<std::string> names;
+ std::vector<param_list *> modifiers;
+
+
+ subquery_spec(){}
+
+ subquery_spec(const char *n, name_vec *t){
+ name = n;
+ types = t->svec;
+ names = t->nvec;
+ modifiers = t->pvec;
+ };
+
+ std::string to_string(){
+ std::string ret = name+" (";
+ int i;
+ for(i=0;i<types.size();++i){
+ if(i>0) ret+=", ";
+ ret += types[i] + " " + names[i];
+ if(modifiers[i]->size() >0){
+ ret+=" ("+modifiers[i]->to_string()+") ";
+ }
+ }
+ ret += ") ";
+ return(ret);
+ };
+
+ subquery_spec *duplicate(){
+ subquery_spec *ret = new subquery_spec();
+ ret->name = name;
+ ret->types = types;
+ ret->names = names;
+
+ return ret;
+ }
+
+
+
+};
+
+class subqueryspec_list{
+public:
+ std::vector<subquery_spec *> spec_list;
+
+ subqueryspec_list(subquery_spec *ss){
+ spec_list.push_back(ss);
+ };
+ subqueryspec_list *append(subquery_spec *ss){
+ spec_list.push_back(ss);
+ return this;
+ };
+};
+
+class unpack_fcn{
+public:
+ std::string name;
+ std::string fcn;
+ int cost;
+
+ unpack_fcn(const char *n, const char *f, const char *c){
+ name = n;
+ fcn = f;
+ cost = atoi(c);
+ };
+};
+
+class unpack_fcn_list{
+public:
+ std::vector<unpack_fcn *> ufcn_v;
+
+ unpack_fcn_list(unpack_fcn *u){
+ ufcn_v.push_back(u);
+ };
+
+ unpack_fcn_list *append(unpack_fcn *u){
+ ufcn_v.push_back(u);
+ return this;
+ };
+};
+
+
+
+
+// forward definition, needed for table_def
+class table_exp_t;
+struct query_list_t;
+
+/* ============================================
+ The schema can support several different
+ flavors of table.
+ PROTOCOL : the base data that an FTA can retrieve.
+ STREAM : Data created by an FTA or a stream operator.
+ More to come. Perhaps this is better handled by
+ annotations in the schema def.
+ ============================================= */
+
+#define PROTOCOL_SCHEMA 1
+#define STREAM_SCHEMA 2
+#define OPERATOR_VIEW_SCHEMA 3
+#define UNPACK_FCNS_SCHEMA 4
+#define WATCHLIST_SCHEMA 5
+
+
+// Represent a STREAM, PROTOCOL, OPERATOR_VIEW, or UNPACK_FCN list.
+
+class table_def{
+private:
+ std::string table_name;
+ std::vector<field_entry *> fields;
+ param_list *base_tables; // if PROTOCOL, the PROTOCOLS that
+ // this PROTOCOL inherits fields from.
+ int schema_type; // STREAM_SCHEMA, PROTOCOL_SCHEMA, OPERATOR_VIEW_SCHEMA
+ int schema_id; // the id associated with the protocol
+ std::set<int> all_schema_ids; // schema_id plus the inherited ones
+// For operator_view tables
+ param_list *op_properties;
+ std::vector<subquery_spec *> qspec_list;
+ param_list *selpush;
+ std::vector<std::string> key_flds; // keys of a watchlist
+
+public:
+// for unpacking function group specs.
+ std::vector<unpack_fcn *> ufcn_list;
+
+
+
+// Unpack functions defined at the PROTOCOL level are added to
+// PROTOCOL fields here ... implying that ony those fields
+// explicitly defined in the PROTOCOL (as opposed to inherited)
+// get the PROTOCOL-wide unpack functions.
+ table_def(const char *name, param_list *plist, param_list *ufcn_l, field_entry_list *fel, int sch_t){
+ int f;
+ schema_id = -1;
+ base_tables = new param_list();
+ if(plist != NULL){
+ std::vector<std::string> pkeys = plist->get_key_vec();
+ for(int p=0;p<pkeys.size();++p){
+ std::string val = plist->val_of(pkeys[p]);
+ if(val!=""){
+ if(pkeys[p] == "schema_id" || pkeys[p] == "schemaId"){
+ schema_id = atoi(val.c_str());
+ if(schema_id <= 0){
+ fprintf(stderr,"Error, Protocol %s has a schema_id value of %d, must be larger than 0.\n",name, schema_id);
+ exit(1);
+ }
+ all_schema_ids.insert(schema_id);
+ }
+ }else{
+ base_tables->append(pkeys[p]);
+ }
+ }
+ }
+ table_name =name;
+ fields = fel->get_list();
+ schema_type = sch_t;
+
+// fields inherit table-level unpacking functions, if any.
+ if(ufcn_l){
+ for(f=0;f<fields.size();++f)
+ fields[f]->add_unpack_fcns(ufcn_l);
+ }
+
+ op_properties = new param_list();
+ selpush = new param_list();
+ };
+
+ table_def(const char *name, param_list *oprop, field_entry_list *fel,
+ subqueryspec_list *ql, param_list *selp);
+
+ table_def(unpack_fcn_list *ufcn_l){
+ schema_type = UNPACK_FCNS_SCHEMA;
+ ufcn_list = ufcn_l->ufcn_v;
+ }
+
+ table_def(){};
+
+ table_def *make_shallow_copy(std::string n);
+
+ void mangle_subq_names(std::string mngl);
+
+ std::string get_tbl_name(){return table_name; };
+ std::vector<field_entry *> get_fields(){return(fields); };
+
+ field_entry *get_field(int i){
+ if(i>=0 && i<fields.size()) return(fields[i]);
+ return NULL;
+ };
+
+ std::string get_field_name(int i){
+ if(i>=0 && i<fields.size()) return(fields[i]->get_name());
+ return "";
+ };
+
+ bool contains_field(std::string f);
+ bool contains_field(int f);
+
+ int get_field_idx(std::string f);
+ std::string get_type_name(std::string f);
+ param_list *get_modifier_list(std::string f);
+ std::string get_fcn(std::string f);
+
+ std::string get_op_prop(std::string s){
+ return op_properties->val_of(s);
+ };
+
+ void set_keys(const std::vector<std::string> &kf){
+ key_flds = kf;
+ }
+ std::vector<std::string> get_keys(){
+ return key_flds;
+ }
+
+// Used in generating the LFTA prefilter
+ std::string get_field_basetable(std::string f);
+
+
+ int verify_no_duplicates(std::string &err);
+ int verify_access_fcns(std::string &err);
+
+
+ std::vector<std::string> get_pred_tbls(){
+ return base_tables->get_key_vec() ;
+ };
+
+ int add_field(field_entry *fe);
+
+ int get_schema_type(){return schema_type;};
+
+ int get_schema_id(){return schema_id;};
+
+ std::set<int> get_all_schema_ids(){ return all_schema_ids;}
+ void add_to_all_schema_ids(int sid){
+ all_schema_ids.insert(sid);
+ }
+
+
+ std::vector<subquery_spec *> get_subqueryspecs(){return qspec_list;};
+
+ std::string to_string();
+ std::string to_stream_string(){
+ int tmp_sch = schema_type;
+ schema_type = STREAM_SCHEMA;
+ std::string ret = this->to_string();
+ schema_type = tmp_sch;
+ return ret;
+ }
+
+ bool is_stream(){
+ return(schema_type == PROTOCOL_SCHEMA || schema_type == STREAM_SCHEMA || schema_type == OPERATOR_VIEW_SCHEMA);
+ }
+};
+
+
+// A Schema -- a collection of stream layout definitions.
+
+class table_list{
+private:
+ std::vector<table_def *> tbl_list;
+ // for an unpack_fcn_list, collect from the set of
+ // UNPACK_FCNS_SCHEMA in the table list.
+ std::map<std::string, std::string> ufcn_fcn;
+ std::map<std::string, int> ufcn_cost;
+
+
+public:
+ table_list(table_def *td){tbl_list.push_back(td); };
+ table_list(){};
+
+ table_list *append_table(table_def *td){
+ tbl_list.push_back(td);
+ return(this);
+ };
+
+ int add_table(table_def *td);
+ table_def *get_table(int t){
+ if(t<0 || t>tbl_list.size()) return(NULL);
+ return(tbl_list[t]);
+ };
+
+ int add_duplicate_table(std::string src, std::string dest){
+ int src_pos = this->find_tbl(src);
+ if(src_pos<0)
+ return src_pos;
+ table_def *dest_tbl = tbl_list[src_pos]->make_shallow_copy(dest);
+ tbl_list.push_back(dest_tbl);
+ return tbl_list.size()-1;
+ }
+
+ void mangle_subq_names(int pos, std::string mngl){
+ tbl_list[pos]->mangle_subq_names(mngl);
+ }
+
+
+ int size(){return tbl_list.size();};
+
+/////////////
+// Accessor methods : get table and field info without
+// descending into the underlying data structures.
+// Can specify a table by name (string), or by index (int)
+// (e.g. returned by get_table_ref)
+
+ int get_ufcn_cost(std::string fname){
+ if(ufcn_cost.count(fname))
+ return ufcn_cost[fname];
+ else
+ return -1;
+ }
+ std::string get_ufcn_fcn(std::string fname){
+ if(ufcn_fcn.count(fname))
+ return ufcn_fcn[fname];
+ else
+ return "ERROR_ufcn_fcn_of_"+fname+"_not_found";
+ }
+
+ std::string get_table_name(int i){
+ if(i>tbl_list.size()) return("");
+ else return tbl_list[i]->get_tbl_name();
+ };
+ std::vector<std::string> get_table_names();
+
+ std::vector<field_entry *> get_fields(std::string t);
+ field_entry *get_field(std::string t, int i);
+ field_entry *get_field(int t, std::string f){
+ return tbl_list[t]->get_field(tbl_list[t]->get_field_idx(f));
+ }
+ int get_field_idx(std::string t, std::string f);
+
+ int find_tbl(std::string t);
+
+ std::vector<int> get_tblref_of_field(std::string f);
+
+ int get_table_ref(std::string t);
+
+ std::string get_type_name(int t, std::string f){
+ return(tbl_list[t]->get_type_name(f));
+ };
+
+ param_list *get_modifier_list(int t, std::string f){
+ return(tbl_list[t]->get_modifier_list(f));
+ };
+
+ std::string get_fcn(int t, std::string f){
+ return(tbl_list[t]->get_fcn(f));
+ };
+
+ int get_schema_type(int t){
+ return(tbl_list[t]->get_schema_type());
+ };
+
+ int get_schema_id(int t){
+ return(tbl_list[t]->get_schema_id());
+ };
+
+ bool is_stream(int t){
+ return tbl_list[t]->is_stream();
+ }
+
+ std::string get_op_prop(int t, std::string s){
+ return(tbl_list[t]->get_op_prop(s));
+ };
+
+ std::vector<subquery_spec *> get_subqueryspecs(int t){
+ return tbl_list[t]->get_subqueryspecs();
+ };
+
+
+// Used in generating the LFTA prefilter
+ std::string get_basetbl_name(int t, std::string f){
+ return(tbl_list[t]->get_field_basetable(f));
+ };
+
+ bool contains_field(int t, std::string f){
+ return(tbl_list[t]->contains_field(f));
+ };
+
+
+//////////////
+// Additional methods
+
+// Process field inheritance for PROTOCOL tables.
+ int unroll_tables(std::string &err);
+
+ std::string to_string();
+};
+#endif