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 ------------------------------------------- */
16 #ifndef __ANALYZE_FTA_H_DEFINED__
17 #define __ANALYZE_FTA_H_DEFINED__
21 #include "parse_fta.h"
22 #include "parse_schema.h"
23 #include"type_objects.h"
24 #include "parse_ext_fcns.h"
33 // Represent a component of a predicate,
34 // these components are ANDed together.
35 // Often they are simple enough to analyze.
38 int is_atom; // i.e., is an atomic predicate
39 int eq_pred; // And, it is a test for equality
40 int in_pred; // Or, it is a an IN predicate
42 int pr_gb; // the predicate refs a gb column.
43 int pr_attr; // the predicate refs a table column.
44 int pr_aggr; // the predicate refs an aggregate
46 int l_simple; // the lhs is simple (just a colref)
47 int l_gb; // the lhs refs a gb var
48 int l_attr; // the lhs refs a table column
49 int l_aggr; // the lhs refs an aggregate.
51 int r_simple; // the rhs is simple (just a colref)
52 int r_gb; // the rhs refs a gb var
53 int r_attr; // the rhs refs a table column
54 int r_aggr; // the rhs refs an aggregate.
56 int cost; // an estiamte of the evaluation cost.
60 cnf_elem(predicate_t *p){
62 eq_pred = 0; in_pred = 0;
63 pr_gb = pr_attr = pr_aggr = 0;
64 l_simple = l_gb = l_attr = l_aggr = 0;
65 r_simple = r_gb = r_attr = r_aggr = 0;
69 cnf_elem(){ is_atom = 0;
70 eq_pred = 0; in_pred = 0;
71 pr_gb = pr_attr = pr_aggr = 0;
72 l_simple = l_gb = l_attr = l_aggr = 0;
73 r_simple = r_gb = r_attr = r_aggr = 0;
79 void swap_scalar_operands(){
81 if(in_pred) return; // can't swap IN predicates, se list always on right.
82 if(! is_atom) return; // can only swap scalar expressions.
84 tmp = l_simple; l_simple = r_simple; r_simple = tmp;
85 tmp = l_gb; l_gb = r_gb; r_gb = tmp;
86 tmp = l_attr; l_attr = r_attr; r_attr = tmp;
87 tmp = l_aggr; l_aggr = r_aggr; r_aggr = tmp;
89 pr->swap_scalar_operands();
94 // A GB variable is identified by its name and
95 // its source table variable -- so that joins can be expressed.
96 // GB Vars defined AS a scalar expression have a null tableref.
101 // Also carry the schema ref -- used to get data type info
102 // when defining variables.
105 col_id(){tblvar_ref = -1;};
106 col_id(colref_t *cr){
108 tblvar_ref = cr-> get_tablevar_ref();
109 schema_ref = cr->get_schema_ref();
114 void load_from_colref(colref_t *cr){
116 tblvar_ref = cr-> get_tablevar_ref();
117 schema_ref = cr->get_schema_ref();
122 bool operator()(const col_id &cr1, const col_id &cr2) const{
123 if(cr1.tblvar_ref < cr2.tblvar_ref) return(1);
124 if(cr1.tblvar_ref == cr2.tblvar_ref)
125 return (cr1.field < cr2.field);
130 bool operator<(const col_id &cr1, const col_id &cr2);
133 // Every GB variable is represented by its name
134 // (defined above) and the scalar expression which
135 // defines its value. If the GB var is devlared as a
136 // colref, the add_gb_attr method of gb_table will
137 // create an SE consisting of the colref.
138 // NOTE : using col_id is dangerous when the
139 // agregation operator is defiend over a self-join
141 #define GBVAR_COLREF 1
144 struct gb_table_entry{
145 col_id name; // tblref in col_id refers to the tablevar.
146 scalarexp_t *definition;
152 data_type *get_data_type(){
153 return(definition->get_data_type());
155 void reset_temporal(){
156 if(definition) definition->reset_temporal();
161 // The GB table is the symbol table containing
162 // the GB vars. This object puts a wrapper around
163 // access to the table.
167 std::vector<gb_table_entry *> gtbl;
170 std::vector<vector<bool> > gb_patterns;
171 // rollup, cube, and grouping_sets cannot be readily reconstructed by
172 // analyzing the patterns, so explicitly record them here.
173 // used only so that sgah_qpn::to_query_string produces
174 // something meaningful.
175 std::vector<std::string> gb_entry_type;
176 std::vector<int> gb_entry_count;
177 std::vector<std::vector<std::vector<bool> > > pattern_components;
181 int add_gb_attr(gb_t *c, tablevar_list_t *fm, table_list *schema,
182 table_exp_t *fta_tree, ext_fcn_list *Ext_fcns);
184 void add_gb_var(std::string n, int t, scalarexp_t *d, int rt){
185 gb_table_entry *entry = new gb_table_entry();
186 entry->name.field = n;
187 entry->name.tblvar_ref = t;
188 entry->definition = d;
189 entry->ref_type = rt;
190 gtbl.push_back(entry);
192 data_type *get_data_type(int g){return(gtbl[g]->get_data_type()); };
193 int find_gb(colref_t *c, tablevar_list_t *fm, table_list *schema);
194 scalarexp_t *get_def(int i){return gtbl[i]->definition; };
195 std::string get_name(int i){return gtbl[i]->name.field; };
196 int get_tblvar_ref(int i){return gtbl[i]->name.tblvar_ref; };
197 int get_reftype(int i){return gtbl[i]->ref_type; };
198 int size(){return(gtbl.size()); };
199 void set_pattern_info(gb_table *g){
200 gb_patterns = g->gb_patterns;
201 gb_entry_type = g->gb_entry_type;
202 gb_entry_count = g->gb_entry_count;
203 pattern_components = g->pattern_components;
205 void reset_temporal(int i){
206 gtbl[i]->reset_temporal();
212 // Represent an aggregate to be calculated.
213 // The unique identifier is the aggregate fcn, and the
214 // expression aggregated over.
215 // TODO: unify udaf with built-in better
216 // (but then again, the core dumps help with debugging)
218 struct aggr_table_entry{
220 scalarexp_t *operand;
221 std::vector<scalarexp_t *> oplist;
222 int fcn_id; // -1 for built-in aggrs.
223 data_type *sdt; // storage data type.
224 data_type *rdt; // return value data type.
229 aggr_table_entry(){ sdt = NULL; rdt = NULL; is_superag = false;};
230 aggr_table_entry(std::string o, scalarexp_t *se, bool s){
231 op = o; operand = se; fcn_id = -1; sdt = NULL;
233 rdt = new data_type();
234 rdt->set_aggr_data_type(o,se->get_data_type());
236 rdt = new data_type("INT");
242 aggr_table_entry(std::string o, int f, std::vector<scalarexp_t *> s, data_type *st, bool spr, bool r, bool b_o){
254 bool fta_legal(ext_fcn_list *Ext_fcns);
255 bool is_star_aggr(){return operand==NULL;};
256 bool is_builtin(){return fcn_id < 0;};
257 int get_fcn_id(){return fcn_id;};
258 bool is_superaggr(){return is_superag;};
259 bool is_running_aggr(){return is_running;};
260 bool has_bailout(){return bailout;};
261 void set_super(bool s){is_superag = s;};
263 std::vector<std::string> get_subaggr_fcns(std::vector<bool> &use_se);
264 std::vector<data_type *> get_subaggr_dt();
265 scalarexp_t *make_superaggr_se(std::vector<scalarexp_t *> se_refs);
266 data_type *get_storage_type(){return sdt;};
267 std::vector<scalarexp_t *> get_operand_list(){return oplist;};
269 aggr_table_entry *duplicate(){
270 aggr_table_entry *dup = new aggr_table_entry();
272 dup->operand = operand;
273 dup->oplist = oplist;
274 dup->fcn_id = fcn_id;
277 dup->is_superag = is_superag;
278 dup->is_running = is_running;
279 dup->bailout = bailout;
283 static bool superaggr_allowed(std::string op, ext_fcn_list *Ext_fcns){
284 if(op == "SUM" || op == "COUNT" || op == "MIN" || op=="MAX")
289 bool superaggr_allowed(){
291 return aggr_table_entry::superaggr_allowed(op,NULL);
292 // Currently, no UDAFS allowed as superaggregates
296 static bool multiple_return_allowed(bool is_built_in, ext_fcn_list *Ext_fcns, int fcn_id){
299 // Currently, no UDAFS allowed as stateful fcn params.
300 // in cleaning_when, cleaning_by clauses.
301 if(Ext_fcns->is_running_aggr(fcn_id) || Ext_fcns->multiple_returns(fcn_id))
309 class aggregate_table{
311 std::vector<aggr_table_entry *> agr_tbl;
315 int add_aggr(std::string op, scalarexp_t *se, bool is_spr);
316 int add_aggr(std::string op, int fcn_id, std::vector<scalarexp_t *> opl, data_type *sdt, bool is_spr, bool is_running, bool has_lfta_bailout);
317 int add_aggr(aggr_table_entry *a){agr_tbl.push_back(a); return agr_tbl.size(); };
318 int size(){return(agr_tbl.size()); };
319 scalarexp_t *get_aggr_se(int i){return agr_tbl[i]->operand; };
321 data_type *get_data_type(int i){
322 // if(agr_tbl[i]->op == "COUNT")
323 // return new data_type("uint");
325 if(! agr_tbl[i]->rdt){
326 fprintf(stderr,"INTERNAL ERROR in aggregate_table::get_data_type : rdt is NULL.\n");
329 return agr_tbl[i]->rdt;
332 std::string get_op(int i){return agr_tbl[i]->op;};
334 bool fta_legal(int i,ext_fcn_list *Ext_fcns){return agr_tbl[i]->fta_legal(Ext_fcns); };
335 bool is_star_aggr(int i){return agr_tbl[i]->is_star_aggr(); };
336 bool is_builtin(int i){return agr_tbl[i]->is_builtin(); };
337 int get_fcn_id(int i){return agr_tbl[i]->get_fcn_id();};
338 bool is_superaggr(int i){return agr_tbl[i]->is_superaggr();};
339 bool is_running_aggr(int i){return agr_tbl[i]->is_running_aggr();};
340 bool has_bailout(int i){return agr_tbl[i]->has_bailout();};
341 // bool multiple_return_allowed(int i){
342 // return agr_tbl[i]->multiple_return_allowed(agr_tbl[i]->is_builtin(),NULL);
344 bool superaggr_allowed(int i){return agr_tbl[i]->superaggr_allowed();};
345 std::vector<scalarexp_t *> get_operand_list(int i){
346 return agr_tbl[i]->get_operand_list();
349 std::vector<std::string> get_subaggr_fcns(int i, std::vector<bool> &use_se){
350 return(agr_tbl[i]->get_subaggr_fcns(use_se) );
353 std::vector<data_type *> get_subaggr_dt(int i){
354 return(agr_tbl[i]->get_subaggr_dt() );
356 data_type *get_storage_type(int i){
357 return( agr_tbl[i]->get_storage_type());
360 aggr_table_entry *duplicate(int i){
361 return agr_tbl[i]->duplicate();
364 scalarexp_t *make_superaggr_se(int i, std::vector<scalarexp_t *> se_refs){
365 return(agr_tbl[i]->make_superaggr_se(se_refs) );
370 class cplx_lit_table{
371 std::vector<literal_t *> cplx_lit_tbl;
372 std::vector<bool> hdl_ref_tbl;
377 int add_cpx_lit(literal_t *, bool);
378 int size(){return cplx_lit_tbl.size();};
379 literal_t *get_literal(int i){return cplx_lit_tbl[i];};
380 bool is_handle_ref(int i){return hdl_ref_tbl[i];};
384 enum param_handle_type { cplx_lit_e, litval_e, param_e};
386 class handle_param_tbl_entry{
390 std::string fcn_name;
393 int complex_literal_idx;
394 std::string param_name;
395 param_handle_type val_type;
396 std::string type_name;
398 handle_param_tbl_entry(std::string fname, int slot,
399 literal_t *l, std::string tnm){
400 fcn_name = fname; param_slot = slot;
405 handle_param_tbl_entry(std::string fname, int slot, std::string p, std::string tnm){
406 fcn_name = fname; param_slot = slot;
411 handle_param_tbl_entry(std::string fname, int slot, int ci, std::string tnm){
412 fcn_name = fname; param_slot = slot;
413 val_type = cplx_lit_e;
414 complex_literal_idx = ci;
418 std::string lfta_registration_fcn(){
420 sprintf(tmps,"register_handle_for_%s_slot_%d",fcn_name.c_str(),param_slot);
423 std::string hfta_registration_fcn(){return lfta_registration_fcn();};
425 std::string lfta_deregistration_fcn(){
427 sprintf(tmps,"deregister_handle_for_%s_slot_%d",fcn_name.c_str(),param_slot);
430 std::string hfta_rdeegistration_fcn(){return lfta_registration_fcn();};
436 // Store the data in vectors to preserve
438 std::vector<std::string> pname;
439 std::vector<data_type *> pdtype;
440 std::vector<bool> phandle;
442 int find_name(std::string n){
444 for(p=0;p<pname.size();++p){
445 if(pname[p] == n) break;
447 if(p == pname.size()) return(-1);
454 // Add the param with the given name and associated
455 // data type and handle use.
456 // if its a new name, return true.
457 // Else, take OR of use_handle, return false.
458 // (builds param table and collects handle references).
459 bool add_param(std::string pnm, data_type *pdt, bool use_handle){
460 int p = find_name(pnm);
462 pname.push_back(pnm);
463 pdtype.push_back(pdt);
464 phandle.push_back(use_handle);
467 if(use_handle) phandle[p] = use_handle;
473 int size(){return pname.size(); };
475 std::vector<std::string> get_param_names(){
479 data_type *get_data_type(std::string pnm){
480 int p = find_name(pnm);
484 return(new data_type("undefined_type"));
487 bool handle_access(std::string pnm){
488 int p = find_name(pnm);
498 // Two columns are the same if they come from the
499 // same source, and have the same field name.
500 // (use to determine which fields must be unpacked).
501 // NOTE : dangerous in the presence of self-joins.
502 typedef std::set<col_id, lt_col_id> col_id_set;
504 bool contains_gb_pr(predicate_t *pr, std::set<int> &gref_set);
505 bool contains_gb_se(scalarexp_t *se, std::set<int> &gref_set);
508 void gather_se_col_ids(scalarexp_t *se, col_id_set &cid_set, gb_table *gtbl);
509 void gather_pr_col_ids(predicate_t *pr, col_id_set &cid_set, gb_table *gtbl);
511 void gather_se_opcmp_fcns(scalarexp_t *se, std::set<std::string> &fcn_set);
512 void gather_pr_opcmp_fcns(predicate_t *pr, std::set<std::string> &fcn_set);
514 ////////////////////////////////////////////
515 // Structures to record usage of operator views.
519 std::string parent_qname;
520 std::string root_name;
521 std::string view_name;
522 std::string exec_fl; // name of executable file (if any)
523 std::string udop_alias; // unique ID of the UDOP
525 int liveness_timeout; // maximum delay between hearbeats from udop
527 std::vector<std::string> subq_names;
529 opview_entry(){mangler="";};
534 std::vector<opview_entry *> opview_list;
536 int append(opview_entry *opv){opview_list.push_back(opv);
537 return opview_list.size()-1;};
538 int size(){return opview_list.size();};
539 opview_entry *get_entry(int i){ return opview_list[i];};
542 /////////////////////////////////////////////////////////////////
543 // Wrap up all of the analysis of the FTA into this package.
545 // There is some duplication between query_summary_class,
546 // but I'd rather avoid pushing analysis structures
547 // into the parse modules.
549 // TODO: revisit the issue when nested subqueries are implemented.
550 // One possibility: implement accessor methods to hide the
552 // For now: this class contains data structures not in table_exp_t
553 // (with a bit of duplication)
555 struct query_summary_class{
556 std::string query_name; // the name of the query, becomes the name
558 int query_type; // e.g. SELECT, MERGE, etc.
560 gb_table *gb_tbl; // Table of all group-by attributes.
561 std::set<int> sg_tbl; // Names of the superGB attributes
562 aggregate_table *aggr_tbl; // Table of all referenced aggregates.
563 std::set<std::string> states_refd; // states ref'd by stateful fcns.
566 // copied from parse tree, then into query node.
567 // interpret the string representation of data type into a type_object
568 param_table *param_tbl; // Table of all query parameters.
570 // There is stuff that is not copied over by analyze_fta,
571 // it still resides in fta_tree.
572 table_exp_t *fta_tree; // The (decorated) parse tree.
575 // This is copied from the parse tree (except for "query_name")
576 // then copied to the query node in query_plan.cc:145
577 std::map<std::string, std::string> definitions; // additional definitions.
580 // CNF representation of the where and having predicates.
581 std::vector<cnf_elem *> wh_cnf;
582 std::vector<cnf_elem *> hav_cnf;
583 std::vector<cnf_elem *> cb_cnf;
584 std::vector<cnf_elem *> cw_cnf;
585 std::vector<cnf_elem *> closew_cnf;
590 // For MERGE type queries.
591 std::vector<colref_t *> mvars;
594 //////// Constructors
595 query_summary_class(){
599 query_summary_class(table_exp_t *f){
606 bool add_query_param(std::string pnm, data_type *pdt, bool use_handle){
607 return( param_tbl->add_param(pnm,pdt,use_handle));
613 // Create the gb_tbl, aggr_tbl, and param_tbl objects
614 gb_tbl = new gb_table();
615 aggr_tbl = new aggregate_table();
616 param_tbl = new param_table();
621 int verify_colref(scalarexp_t *se, tablevar_list_t *fm,
622 table_list *schema, gb_table *gtbl);
623 std::string impute_query_name(table_exp_t *fta_tree, std::string default_nm);
625 query_summary_class *analyze_fta(table_exp_t *fta_tree, table_list *schema, ext_fcn_list *Ext_fcns, std::string qname);
626 bool is_equivalent_se(scalarexp_t *se1, scalarexp_t *se2);
627 bool is_equivalent_se_base(scalarexp_t *se1, scalarexp_t *se2, table_list *Schema);
628 bool is_equivalent_pred_base(predicate_t *p1, predicate_t *p2, table_list *Schema);
630 bool is_equivalent_class_pred_base(predicate_t *p1, predicate_t *p2, table_list *Schema,ext_fcn_list *Ext_fcns);
631 void analyze_cnf(cnf_elem *c);
633 void find_partial_fcns(scalarexp_t *se, std::vector<scalarexp_t *> *pf_list, std::vector<int> *fcn_ref_cnt, std::vector<bool> *is_partial_fcn, ext_fcn_list *Ext_fcns);
634 void find_partial_fcns_pr(predicate_t *pr, std::vector<scalarexp_t *> *pf_list,std::vector<int> *fcn_ref_cnt, std::vector<bool> *is_partial_fcn, ext_fcn_list *Ext_fcns);
635 void collect_partial_fcns(scalarexp_t *se, std::set<int> &pfcn_refs);
636 void collect_partial_fcns_pr(predicate_t *pr, std::set<int> &pfcn_refs);
638 void find_combinable_preds(predicate_t *pr, vector<predicate_t *> *pr_list,
639 table_list *Schema, ext_fcn_list *Ext_fcns);
641 void collect_agg_refs(scalarexp_t *se, std::set<int> &agg_refs);
642 void collect_aggr_refs_pr(predicate_t *pr, std::set<int> &agg_refs);
644 int bind_to_schema_pr(predicate_t *pr, tablevar_list_t *fm, table_list *schema);
645 int bind_to_schema_se(scalarexp_t *se, tablevar_list_t *fm, table_list *schema);
647 temporal_type compute_se_temporal(scalarexp_t *se, std::map<col_id, temporal_type> &tcol);
650 bool find_complex_literal_se(scalarexp_t *se, ext_fcn_list *Ext_fcns,
651 cplx_lit_table *complex_literals);
652 void find_complex_literal_pr(predicate_t *pr, ext_fcn_list *Ext_fcns,
653 cplx_lit_table *complex_literals);
654 void find_param_handles_se(scalarexp_t *se, ext_fcn_list *Ext_fcns,
655 std::vector<handle_param_tbl_entry *> &handle_tbl);
656 void find_param_handles_pr(predicate_t *pr, ext_fcn_list *Ext_fcns,
657 std::vector<handle_param_tbl_entry *> &handle_tbl);
659 // Copy a scalar expression / predicate tree
660 scalarexp_t *dup_se(scalarexp_t *se, aggregate_table *aggr_tbl);
661 select_element *dup_select(select_element *sl, aggregate_table *aggr_tbl);
662 predicate_t *dup_pr(predicate_t *pr, aggregate_table *aggr_tbl);
665 void expand_gbvars_pr(predicate_t *pr, gb_table &gb_tbl);
666 scalarexp_t *expand_gbvars_se(scalarexp_t *se, gb_table &gb_tbl);
670 table_exp_t *dup_table_exp(table_exp_t *te);
673 // Tie colrefs to a new range var
674 void bind_colref_se(scalarexp_t *se,
675 std::vector<tablevar_t *> &fm,
676 int prev_ref, int new_ref
678 void bind_colref_pr(predicate_t *pr,
679 std::vector<tablevar_t *> &fm,
680 int prev_ref, int new_ref
684 std::string impute_colname(std::vector<select_element *> &sel_list, scalarexp_t *se);
685 std::string impute_colname(std::set<std::string> &curr_names, scalarexp_t *se);
687 bool is_literal_or_param_only(scalarexp_t *se);
690 void build_aggr_tbl_fm_pred(predicate_t *pr, aggregate_table *agr_tbl);
691 void build_aggr_tbl_fm_se(scalarexp_t *se, aggregate_table *agr_tbl);
693 void compute_cnf_cost(cnf_elem *cm, ext_fcn_list *Ext_fcns);
694 struct compare_cnf_cost{
695 bool operator()(const cnf_elem *c1, const cnf_elem *c2) const{
696 if(c1->cost < c2->cost) return(true);
701 void get_tablevar_ref_se(scalarexp_t *se, std::vector<int> &reflist);
702 void get_tablevar_ref_pr(predicate_t *pr, std::vector<int> &reflist);
704 long long int find_temporal_divisor(scalarexp_t *se, gb_table *gbt, std::string &fnm);
707 int count_se_ifp_refs(scalarexp_t *se, std::set<std::string> &ifpnames);
708 int count_pr_ifp_refs(predicate_t *pr, std::set<std::string> &ifpnames);
709 int resolve_se_ifp_refs(scalarexp_t *se, std::string ifm, std::string ifn, ifq_t *ifdb, std::string &err);
710 int resolve_pr_ifp_refs(predicate_t *pr, std::string ifm, std::string ifn, ifq_t *ifdb, std::string &err);
712 int pred_refs_sfun(predicate_t *pr);
713 int se_refs_sfun(scalarexp_t *se);
716 // Represent preds for the prefilter, and
717 // the LFTAs which reference them.
720 std::set<int> lfta_id;
721 std::set<unsigned int> pred_id;
724 cnf_set(predicate_t *p, unsigned int l, unsigned int i){
725 pr = dup_pr(p,NULL); // NEED TO UPDATE dup_se TO PROPAGATE
727 pred_id.insert((l << 16)+i);
729 void subsume(cnf_set *c){
730 std::set<int>::iterator ssi;
731 for(ssi=c->lfta_id.begin();ssi!=c->lfta_id.end();++ssi){
732 lfta_id.insert((*ssi));
734 std::set<unsigned int >::iterator spi;
735 for(spi=c->pred_id.begin();spi!=c->pred_id.end();++spi){
736 pred_id.insert((*spi));
739 void combine_pred(cnf_set *c){
740 pr = new predicate_t("AND",pr,c->pr);
741 std::set<unsigned int >::iterator spi;
742 for(spi=c->pred_id.begin();spi!=c->pred_id.end();++spi){
743 pred_id.insert((*spi));
747 void add_pred_ids(set<unsigned int> &pred_set){
748 std::set<unsigned int >::iterator spi;
749 for(spi=pred_id.begin();spi!=pred_id.end();++spi){
750 pred_set.insert((*spi));
754 static unsigned int make_lfta_key(unsigned int l){
761 struct compare_cnf_set{
762 bool operator()(const cnf_set *c1, const cnf_set *c2) const{
763 if(c1->lfta_id.size() > c2->lfta_id.size()) return(true);
768 bool operator<(const cnf_set &c1, const cnf_set &c2);
771 void find_common_filter(std::vector< std::vector<cnf_elem *> > &where_list, table_list *Schema, ext_fcn_list *Ext_fcns, std::vector<cnf_set *> &prefilter_preds, std::set<unsigned int> &pred_ids);
774 cnf_elem *find_common_filter(std::vector< std::vector<cnf_elem *> > &where_list, table_list *Schema);
776 std::string int_to_string(int i);
777 void insert_gb_def_pr(predicate_t *pr, gb_table *gtbl);
778 void insert_gb_def_se(scalarexp_t *se, gb_table *gtbl);