1 /* ------------------------------------------------
2 Copyright 2014 AT&T Intellectual Property
3 Licensed under the Apache License, Version 2.0 (the "License");
4 you may not use this file except in compliance with the License.
5 You may obtain a copy of the License at
7 http://www.apache.org/licenses/LICENSE-2.0
9 Unless required by applicable law or agreed to in writing, software
10 distributed under the License is distributed on an "AS IS" BASIS,
11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 See the License for the specific language governing permissions and
13 limitations under the License.
14 ------------------------------------------- */
15 #ifndef __SCHEMA_DEF_H_INCLUDED__
16 #define __SCHEMA_DEF_H_INCLUDED__
27 // A param_list is used to represent a list of
28 // parameters with optional values.
32 std::map< std::string, std::string > pmap;
36 param_list(const char *key){
39 param_list(const char *key, const char *val){
43 param_list *append(const char *key){
47 param_list *append(const char *key, const char *val){
51 param_list *append( std::string key){
56 int size(){return pmap.size();};
59 bool contains_key(std::string key){
60 return(pmap.count(key)>0);
63 int delete_key(std::string k){
67 std::string val_of(std::string key){
70 return(std::string(""));
73 std::vector<std::string> get_key_vec(){
74 std::vector<std::string> retval;
75 std::map<std::string, std::string>::iterator mssi;
76 for(mssi=pmap.begin();mssi!=pmap.end();++mssi){
77 retval.push_back( (*mssi).first );
82 std::string to_string();
86 // list of names, order matters.
89 std::vector<std::string> svec;
90 std::vector<std::string> nvec;
91 std::vector<param_list *> pvec;
93 name_vec(char *c, char *n, param_list *p){
96 if(p) pvec.push_back(p);
97 else pvec.push_back(new param_list());
100 name_vec *append(char *c, char *n, param_list *p){
103 if(p) pvec.push_back(p);
104 else pvec.push_back(new param_list());
111 // A field in a STREAM or PROTOCOL
116 std::string type; // data type
117 std::string name; // name in a query
118 std::string function; // access function, if any (PROTOCOL only).
119 param_list *mod_list; // special properties.
120 std::set<std::string> ufcns; // unpacking functions, if any.
122 std::string base_table; // for hierarchically structured data sources,
123 // the bast table where the field is defined.
124 // mostly used for computing the LFTA prefilter.
127 field_entry(const char *t, const char *n, const char *f, param_list *plist, param_list *ulist){
129 mod_list = new param_list();
134 std::vector<std::string> tmp_ufl = ulist->get_key_vec();
135 for(u=0;u<tmp_ufl.size();++u)
136 ufcns.insert(tmp_ufl[u]);
139 type=t; name=n; function=f;
143 field_entry(std::string t, std::string n, std::string f, param_list *plist, const std::set<std::string> &ulist){
145 mod_list = new param_list();
149 type=t; name=n; function=f;
153 field_entry(std::string n, std::string t){
156 mod_list = new param_list();
159 void add_unpack_fcns(param_list *ufl){
160 std::vector<std::string> new_ufl = ufl->get_key_vec();
162 for(u=0;u<new_ufl.size();++u)
163 ufcns.insert(new_ufl[u]);
167 param_list *get_modifier_list(){return mod_list; };
168 std::string get_type(){return(type);};
169 std::string get_name(){return(name);};
170 std::string get_fcn(){return(function);};
171 std::set<std::string> get_unpack_fcns(){
175 void set_basetable(std::string b){base_table=b;};
176 std::string get_basetable(){return base_table;};
178 std::string to_string();
180 int delete_modifier(std::string k){
181 return mod_list->delete_key(k);
183 void add_modifier(const char *k, const char *v){
184 mod_list->append(k,v);
186 void add_modifier(const char *k){
193 // list of fields. An intermediate parse structure.
194 // it gets loaded into table_def.fields
196 class field_entry_list{
198 std::vector<field_entry *> fl;
201 field_entry_list(){};
203 field_entry_list(field_entry *f){
207 field_entry_list *append_field(field_entry *f){
212 std::vector<field_entry *> get_list(){return fl; };
218 std::vector<std::string> types;
219 std::vector<std::string> names;
220 std::vector<param_list *> modifiers;
225 subquery_spec(const char *n, name_vec *t){
232 std::string to_string(){
233 std::string ret = name+" (";
235 for(i=0;i<types.size();++i){
237 ret += types[i] + " " + names[i];
238 if(modifiers[i]->size() >0){
239 ret+=" ("+modifiers[i]->to_string()+") ";
246 subquery_spec *duplicate(){
247 subquery_spec *ret = new subquery_spec();
259 class subqueryspec_list{
261 std::vector<subquery_spec *> spec_list;
263 subqueryspec_list(subquery_spec *ss){
264 spec_list.push_back(ss);
266 subqueryspec_list *append(subquery_spec *ss){
267 spec_list.push_back(ss);
278 unpack_fcn(const char *n, const char *f, const char *c){
285 class unpack_fcn_list{
287 std::vector<unpack_fcn *> ufcn_v;
289 unpack_fcn_list(unpack_fcn *u){
293 unpack_fcn_list *append(unpack_fcn *u){
302 // forward definition, needed for table_def
306 /* ============================================
307 The schema can support several different
309 PROTOCOL : the base data that an FTA can retrieve.
310 STREAM : Data created by an FTA or a stream operator.
311 More to come. Perhaps this is better handled by
312 annotations in the schema def.
313 ============================================= */
315 #define PROTOCOL_SCHEMA 1
316 #define STREAM_SCHEMA 2
317 #define OPERATOR_VIEW_SCHEMA 3
318 #define UNPACK_FCNS_SCHEMA 4
320 // Represent a STREAM, PROTOCOL, OPERATOR_VIEW, or UNPACK_FCN list.
324 std::string table_name;
325 std::vector<field_entry *> fields;
326 param_list *base_tables; // if PROTOCOL, the PROTOCOLS that
327 // this PROTOCOL inherits fields from.
328 int schema_type; // STREAM_SCHEMA, PROTOCOL_SCHEMA, OPERATOR_VIEW_SCHEMA
329 int schema_id; // the id associated with the protocol
330 std::set<int> all_schema_ids; // schema_id plus the inherited ones
331 // For operator_view tables
332 param_list *op_properties;
333 std::vector<subquery_spec *> qspec_list;
337 // for unpacking function group specs.
338 std::vector<unpack_fcn *> ufcn_list;
342 // Unpack functions defined at the PROTOCOL level are added to
343 // PROTOCOL fields here ... implying that ony those fields
344 // explicitly defined in the PROTOCOL (as opposed to inherited)
345 // get the PROTOCOL-wide unpack functions.
346 table_def(const char *name, param_list *plist, param_list *ufcn_l, field_entry_list *fel, int sch_t){
349 base_tables = new param_list();
351 std::vector<std::string> pkeys = plist->get_key_vec();
352 for(int p=0;p<pkeys.size();++p){
353 std::string val = plist->val_of(pkeys[p]);
355 if(pkeys[p] == "schema_id" || pkeys[p] == "schemaId"){
356 schema_id = atoi(val.c_str());
358 fprintf(stderr,"Error, Protocol %s has a schema_id value of %d, must be larger than 0.\n",name, schema_id);
361 all_schema_ids.insert(schema_id);
364 base_tables->append(pkeys[p]);
369 fields = fel->get_list();
372 // fields inherit table-level unpacking functions, if any.
374 for(f=0;f<fields.size();++f)
375 fields[f]->add_unpack_fcns(ufcn_l);
378 op_properties = new param_list();
379 selpush = new param_list();
382 table_def(const char *name, param_list *oprop, field_entry_list *fel,
383 subqueryspec_list *ql, param_list *selp);
385 table_def(unpack_fcn_list *ufcn_l){
386 schema_type = UNPACK_FCNS_SCHEMA;
387 ufcn_list = ufcn_l->ufcn_v;
392 table_def *make_shallow_copy(std::string n);
394 void mangle_subq_names(std::string mngl);
396 std::string get_tbl_name(){return table_name; };
397 std::vector<field_entry *> get_fields(){return(fields); };
399 field_entry *get_field(int i){
400 if(i>=0 && i<fields.size()) return(fields[i]);
404 std::string get_field_name(int i){
405 if(i>=0 && i<fields.size()) return(fields[i]->get_name());
409 bool contains_field(std::string f);
410 bool contains_field(int f);
412 int get_field_idx(std::string f);
413 std::string get_type_name(std::string f);
414 param_list *get_modifier_list(std::string f);
415 std::string get_fcn(std::string f);
417 std::string get_op_prop(std::string s){
418 return op_properties->val_of(s);
421 // Used in generating the LFTA prefilter
422 std::string get_field_basetable(std::string f);
425 int verify_no_duplicates(std::string &err);
426 int verify_access_fcns(std::string &err);
429 std::vector<std::string> get_pred_tbls(){
430 return base_tables->get_key_vec() ;
433 int add_field(field_entry *fe);
435 int get_schema_type(){return schema_type;};
437 int get_schema_id(){return schema_id;};
439 std::set<int> get_all_schema_ids(){ return all_schema_ids;}
440 void add_to_all_schema_ids(int sid){
441 all_schema_ids.insert(sid);
445 std::vector<subquery_spec *> get_subqueryspecs(){return qspec_list;};
447 std::string to_string();
448 std::string to_stream_string(){
449 int tmp_sch = schema_type;
450 schema_type = STREAM_SCHEMA;
451 std::string ret = this->to_string();
452 schema_type = tmp_sch;
458 // A Schema -- a collection of stream layout definitions.
462 std::vector<table_def *> tbl_list;
463 // for an unpack_fcn_list, collect from the set of
464 // UNPACK_FCNS_SCHEMA in the table list.
465 std::map<std::string, std::string> ufcn_fcn;
466 std::map<std::string, int> ufcn_cost;
470 table_list(table_def *td){tbl_list.push_back(td); };
473 table_list *append_table(table_def *td){
474 tbl_list.push_back(td);
478 int add_table(table_def *td);
479 table_def *get_table(int t){
480 if(t<0 || t>tbl_list.size()) return(NULL);
484 int add_duplicate_table(std::string src, std::string dest){
485 int src_pos = this->find_tbl(src);
488 table_def *dest_tbl = tbl_list[src_pos]->make_shallow_copy(dest);
489 tbl_list.push_back(dest_tbl);
490 return tbl_list.size()-1;
493 void mangle_subq_names(int pos, std::string mngl){
494 tbl_list[pos]->mangle_subq_names(mngl);
498 int size(){return tbl_list.size();};
501 // Accessor methods : get table and field info without
502 // descending into the underlying data structures.
503 // Can specify a table by name (string), or by index (int)
504 // (e.g. returned by get_table_ref)
506 int get_ufcn_cost(std::string fname){
507 if(ufcn_cost.count(fname))
508 return ufcn_cost[fname];
512 std::string get_ufcn_fcn(std::string fname){
513 if(ufcn_fcn.count(fname))
514 return ufcn_fcn[fname];
516 return "ERROR_ufcn_fcn_of_"+fname+"_not_found";
519 std::string get_table_name(int i){
520 if(i>tbl_list.size()) return("");
521 else return tbl_list[i]->get_tbl_name();
523 std::vector<std::string> get_table_names();
525 std::vector<field_entry *> get_fields(std::string t);
526 field_entry *get_field(std::string t, int i);
527 field_entry *get_field(int t, std::string f){
528 return tbl_list[t]->get_field(tbl_list[t]->get_field_idx(f));
530 int get_field_idx(std::string t, std::string f);
532 int find_tbl(std::string t);
534 std::vector<int> get_tblref_of_field(std::string f);
536 int get_table_ref(std::string t);
538 std::string get_type_name(int t, std::string f){
539 return(tbl_list[t]->get_type_name(f));
542 param_list *get_modifier_list(int t, std::string f){
543 return(tbl_list[t]->get_modifier_list(f));
546 std::string get_fcn(int t, std::string f){
547 return(tbl_list[t]->get_fcn(f));
550 int get_schema_type(int t){
551 return(tbl_list[t]->get_schema_type());
554 int get_schema_id(int t){
555 return(tbl_list[t]->get_schema_id());
558 std::string get_op_prop(int t, std::string s){
559 return(tbl_list[t]->get_op_prop(s));
562 std::vector<subquery_spec *> get_subqueryspecs(int t){
563 return tbl_list[t]->get_subqueryspecs();
567 // Used in generating the LFTA prefilter
568 std::string get_basetbl_name(int t, std::string f){
569 return(tbl_list[t]->get_field_basetable(f));
572 bool contains_field(int t, std::string f){
573 return(tbl_list[t]->contains_field(f));
578 // Additional methods
580 // Process field inheritance for PROTOCOL tables.
581 int unroll_tables(std::string &err);
583 std::string to_string();