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
319 #define WATCHLIST_SCHEMA 5
322 // Represent a STREAM, PROTOCOL, OPERATOR_VIEW, or UNPACK_FCN list.
326 std::string table_name;
327 std::vector<field_entry *> fields;
328 param_list *base_tables; // if PROTOCOL, the PROTOCOLS that
329 // this PROTOCOL inherits fields from.
330 int schema_type; // STREAM_SCHEMA, PROTOCOL_SCHEMA, OPERATOR_VIEW_SCHEMA
331 int schema_id; // the id associated with the protocol
332 std::set<int> all_schema_ids; // schema_id plus the inherited ones
333 // For operator_view tables
334 param_list *op_properties;
335 std::vector<subquery_spec *> qspec_list;
337 std::vector<std::string> key_flds; // keys of a watchlist
340 // for unpacking function group specs.
341 std::vector<unpack_fcn *> ufcn_list;
345 // Unpack functions defined at the PROTOCOL level are added to
346 // PROTOCOL fields here ... implying that ony those fields
347 // explicitly defined in the PROTOCOL (as opposed to inherited)
348 // get the PROTOCOL-wide unpack functions.
349 table_def(const char *name, param_list *plist, param_list *ufcn_l, field_entry_list *fel, int sch_t){
352 base_tables = new param_list();
354 std::vector<std::string> pkeys = plist->get_key_vec();
355 for(int p=0;p<pkeys.size();++p){
356 std::string val = plist->val_of(pkeys[p]);
358 if(pkeys[p] == "schema_id" || pkeys[p] == "schemaId"){
359 schema_id = atoi(val.c_str());
361 fprintf(stderr,"Error, Protocol %s has a schema_id value of %d, must be larger than 0.\n",name, schema_id);
364 all_schema_ids.insert(schema_id);
367 base_tables->append(pkeys[p]);
372 fields = fel->get_list();
375 // fields inherit table-level unpacking functions, if any.
377 for(f=0;f<fields.size();++f)
378 fields[f]->add_unpack_fcns(ufcn_l);
381 op_properties = new param_list();
382 selpush = new param_list();
385 table_def(const char *name, param_list *oprop, field_entry_list *fel,
386 subqueryspec_list *ql, param_list *selp);
388 table_def(unpack_fcn_list *ufcn_l){
389 schema_type = UNPACK_FCNS_SCHEMA;
390 ufcn_list = ufcn_l->ufcn_v;
395 table_def *make_shallow_copy(std::string n);
397 void mangle_subq_names(std::string mngl);
399 std::string get_tbl_name(){return table_name; };
400 std::vector<field_entry *> get_fields(){return(fields); };
402 field_entry *get_field(int i){
403 if(i>=0 && i<fields.size()) return(fields[i]);
407 std::string get_field_name(int i){
408 if(i>=0 && i<fields.size()) return(fields[i]->get_name());
412 bool contains_field(std::string f);
413 bool contains_field(int f);
415 int get_field_idx(std::string f);
416 std::string get_type_name(std::string f);
417 param_list *get_modifier_list(std::string f);
418 std::string get_fcn(std::string f);
420 std::string get_op_prop(std::string s){
421 return op_properties->val_of(s);
424 void set_keys(const std::vector<std::string> &kf){
427 std::vector<std::string> get_keys(){
431 // Used in generating the LFTA prefilter
432 std::string get_field_basetable(std::string f);
435 int verify_no_duplicates(std::string &err);
436 int verify_access_fcns(std::string &err);
439 std::vector<std::string> get_pred_tbls(){
440 return base_tables->get_key_vec() ;
443 int add_field(field_entry *fe);
445 int get_schema_type(){return schema_type;};
447 int get_schema_id(){return schema_id;};
449 std::set<int> get_all_schema_ids(){ return all_schema_ids;}
450 void add_to_all_schema_ids(int sid){
451 all_schema_ids.insert(sid);
455 std::vector<subquery_spec *> get_subqueryspecs(){return qspec_list;};
457 std::string to_string();
458 std::string to_stream_string(){
459 int tmp_sch = schema_type;
460 schema_type = STREAM_SCHEMA;
461 std::string ret = this->to_string();
462 schema_type = tmp_sch;
467 return(schema_type == PROTOCOL_SCHEMA || schema_type == STREAM_SCHEMA || schema_type == OPERATOR_VIEW_SCHEMA);
472 // A Schema -- a collection of stream layout definitions.
476 std::vector<table_def *> tbl_list;
477 // for an unpack_fcn_list, collect from the set of
478 // UNPACK_FCNS_SCHEMA in the table list.
479 std::map<std::string, std::string> ufcn_fcn;
480 std::map<std::string, int> ufcn_cost;
484 table_list(table_def *td){tbl_list.push_back(td); };
487 table_list *append_table(table_def *td){
488 tbl_list.push_back(td);
492 int add_table(table_def *td);
493 table_def *get_table(int t){
494 if(t<0 || t>tbl_list.size()) return(NULL);
498 int add_duplicate_table(std::string src, std::string dest){
499 int src_pos = this->find_tbl(src);
502 table_def *dest_tbl = tbl_list[src_pos]->make_shallow_copy(dest);
503 tbl_list.push_back(dest_tbl);
504 return tbl_list.size()-1;
507 void mangle_subq_names(int pos, std::string mngl){
508 tbl_list[pos]->mangle_subq_names(mngl);
512 int size(){return tbl_list.size();};
515 // Accessor methods : get table and field info without
516 // descending into the underlying data structures.
517 // Can specify a table by name (string), or by index (int)
518 // (e.g. returned by get_table_ref)
520 int get_ufcn_cost(std::string fname){
521 if(ufcn_cost.count(fname))
522 return ufcn_cost[fname];
526 std::string get_ufcn_fcn(std::string fname){
527 if(ufcn_fcn.count(fname))
528 return ufcn_fcn[fname];
530 return "ERROR_ufcn_fcn_of_"+fname+"_not_found";
533 std::string get_table_name(int i){
534 if(i>tbl_list.size()) return("");
535 else return tbl_list[i]->get_tbl_name();
537 std::vector<std::string> get_table_names();
539 std::vector<field_entry *> get_fields(std::string t);
540 field_entry *get_field(std::string t, int i);
541 field_entry *get_field(int t, std::string f){
542 return tbl_list[t]->get_field(tbl_list[t]->get_field_idx(f));
544 int get_field_idx(std::string t, std::string f);
546 int find_tbl(std::string t);
548 std::vector<int> get_tblref_of_field(std::string f);
550 int get_table_ref(std::string t);
552 std::string get_type_name(int t, std::string f){
553 return(tbl_list[t]->get_type_name(f));
556 param_list *get_modifier_list(int t, std::string f){
557 return(tbl_list[t]->get_modifier_list(f));
560 std::string get_fcn(int t, std::string f){
561 return(tbl_list[t]->get_fcn(f));
564 int get_schema_type(int t){
565 return(tbl_list[t]->get_schema_type());
568 int get_schema_id(int t){
569 return(tbl_list[t]->get_schema_id());
572 bool is_stream(int t){
573 return tbl_list[t]->is_stream();
576 std::string get_op_prop(int t, std::string s){
577 return(tbl_list[t]->get_op_prop(s));
580 std::vector<subquery_spec *> get_subqueryspecs(int t){
581 return tbl_list[t]->get_subqueryspecs();
585 // Used in generating the LFTA prefilter
586 std::string get_basetbl_name(int t, std::string f){
587 return(tbl_list[t]->get_field_basetable(f));
590 bool contains_field(int t, std::string f){
591 return(tbl_list[t]->contains_field(f));
596 // Additional methods
598 // Process field inheritance for PROTOCOL tables.
599 int unroll_tables(std::string &err);
601 std::string to_string();