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();
93 // Make visible for predicate insertion
94 void make_cnf_from_pr(predicate_t *pr, std::vector<cnf_elem *> &clist);
97 // A GB variable is identified by its name and
98 // its source table variable -- so that joins can be expressed.
99 // GB Vars defined AS a scalar expression have a null tableref.
104 // Also carry the schema ref -- used to get data type info
105 // when defining variables.
108 col_id(){tblvar_ref = -1;};
109 col_id(colref_t *cr){
111 tblvar_ref = cr-> get_tablevar_ref();
112 schema_ref = cr->get_schema_ref();
117 void load_from_colref(colref_t *cr){
119 tblvar_ref = cr-> get_tablevar_ref();
120 schema_ref = cr->get_schema_ref();
125 bool operator()(const col_id &cr1, const col_id &cr2) const{
126 if(cr1.tblvar_ref < cr2.tblvar_ref) return(1);
127 if(cr1.tblvar_ref == cr2.tblvar_ref)
128 return (cr1.field < cr2.field);
133 bool operator<(const col_id &cr1, const col_id &cr2);
136 // Every GB variable is represented by its name
137 // (defined above) and the scalar expression which
138 // defines its value. If the GB var is devlared as a
139 // colref, the add_gb_attr method of gb_table will
140 // create an SE consisting of the colref.
141 // NOTE : using col_id is dangerous when the
142 // agregation operator is defiend over a self-join
144 #define GBVAR_COLREF 1
147 struct gb_table_entry{
148 col_id name; // tblref in col_id refers to the tablevar.
149 scalarexp_t *definition;
155 data_type *get_data_type(){
156 return(definition->get_data_type());
158 void reset_temporal(){
159 if(definition) definition->reset_temporal();
164 // The GB table is the symbol table containing
165 // the GB vars. This object puts a wrapper around
166 // access to the table.
170 std::vector<gb_table_entry *> gtbl;
173 std::vector<vector<bool> > gb_patterns;
174 // rollup, cube, and grouping_sets cannot be readily reconstructed by
175 // analyzing the patterns, so explicitly record them here.
176 // used only so that sgah_qpn::to_query_string produces
177 // something meaningful.
178 std::vector<std::string> gb_entry_type;
179 std::vector<int> gb_entry_count;
180 std::vector<std::vector<std::vector<bool> > > pattern_components;
184 int add_gb_attr(gb_t *c, tablevar_list_t *fm, table_list *schema,
185 table_exp_t *fta_tree, ext_fcn_list *Ext_fcns);
187 void add_gb_var(std::string n, int t, scalarexp_t *d, int rt){
188 gb_table_entry *entry = new gb_table_entry();
189 entry->name.field = n;
190 entry->name.tblvar_ref = t;
191 entry->definition = d;
192 entry->ref_type = rt;
193 gtbl.push_back(entry);
195 data_type *get_data_type(int g){return(gtbl[g]->get_data_type()); };
196 int find_gb(colref_t *c, tablevar_list_t *fm, table_list *schema);
197 scalarexp_t *get_def(int i){return gtbl[i]->definition; };
198 std::string get_name(int i){return gtbl[i]->name.field; };
199 int get_tblvar_ref(int i){return gtbl[i]->name.tblvar_ref; };
200 int get_reftype(int i){return gtbl[i]->ref_type; };
201 int size(){return(gtbl.size()); };
202 void set_pattern_info(gb_table *g){
203 gb_patterns = g->gb_patterns;
204 gb_entry_type = g->gb_entry_type;
205 gb_entry_count = g->gb_entry_count;
206 pattern_components = g->pattern_components;
208 void reset_temporal(int i){
209 gtbl[i]->reset_temporal();
215 // Represent an aggregate to be calculated.
216 // The unique identifier is the aggregate fcn, and the
217 // expression aggregated over.
218 // TODO: unify udaf with built-in better
219 // (but then again, the core dumps help with debugging)
221 struct aggr_table_entry{
223 scalarexp_t *operand;
224 std::vector<scalarexp_t *> oplist;
225 int fcn_id; // -1 for built-in aggrs.
226 data_type *sdt; // storage data type.
227 data_type *rdt; // return value data type.
232 aggr_table_entry(){ sdt = NULL; rdt = NULL; is_superag = false;};
233 aggr_table_entry(std::string o, scalarexp_t *se, bool s){
234 op = o; operand = se; fcn_id = -1; sdt = NULL;
236 rdt = new data_type();
237 rdt->set_aggr_data_type(o,se->get_data_type());
239 rdt = new data_type("INT");
245 aggr_table_entry(std::string o, int f, std::vector<scalarexp_t *> s, data_type *st, bool spr, bool r, bool b_o){
257 bool fta_legal(ext_fcn_list *Ext_fcns);
258 bool is_star_aggr(){return operand==NULL;};
259 bool is_builtin(){return fcn_id < 0;};
260 int get_fcn_id(){return fcn_id;};
261 bool is_superaggr(){return is_superag;};
262 bool is_running_aggr(){return is_running;};
263 bool has_bailout(){return bailout;};
264 void set_super(bool s){is_superag = s;};
266 std::vector<std::string> get_subaggr_fcns(std::vector<bool> &use_se);
267 std::vector<data_type *> get_subaggr_dt();
268 scalarexp_t *make_superaggr_se(std::vector<scalarexp_t *> se_refs);
269 data_type *get_storage_type(){return sdt;};
270 std::vector<scalarexp_t *> get_operand_list(){return oplist;};
272 aggr_table_entry *duplicate(){
273 aggr_table_entry *dup = new aggr_table_entry();
275 dup->operand = operand;
276 dup->oplist = oplist;
277 dup->fcn_id = fcn_id;
280 dup->is_superag = is_superag;
281 dup->is_running = is_running;
282 dup->bailout = bailout;
286 static bool superaggr_allowed(std::string op, ext_fcn_list *Ext_fcns){
287 if(op == "SUM" || op == "COUNT" || op == "MIN" || op=="MAX")
292 bool superaggr_allowed(){
294 return aggr_table_entry::superaggr_allowed(op,NULL);
295 // Currently, no UDAFS allowed as superaggregates
299 static bool multiple_return_allowed(bool is_built_in, ext_fcn_list *Ext_fcns, int fcn_id){
302 // Currently, no UDAFS allowed as stateful fcn params.
303 // in cleaning_when, cleaning_by clauses.
304 if(Ext_fcns->is_running_aggr(fcn_id) || Ext_fcns->multiple_returns(fcn_id))
312 class aggregate_table{
314 std::vector<aggr_table_entry *> agr_tbl;
318 int add_aggr(std::string op, scalarexp_t *se, bool is_spr);
319 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);
320 int add_aggr(aggr_table_entry *a){agr_tbl.push_back(a); return agr_tbl.size(); };
321 int size(){return(agr_tbl.size()); };
322 scalarexp_t *get_aggr_se(int i){return agr_tbl[i]->operand; };
324 data_type *get_data_type(int i){
325 // if(agr_tbl[i]->op == "COUNT")
326 // return new data_type("uint");
328 if(! agr_tbl[i]->rdt){
329 fprintf(stderr,"INTERNAL ERROR in aggregate_table::get_data_type : rdt is NULL.\n");
332 return agr_tbl[i]->rdt;
335 std::string get_op(int i){return agr_tbl[i]->op;};
337 bool fta_legal(int i,ext_fcn_list *Ext_fcns){return agr_tbl[i]->fta_legal(Ext_fcns); };
338 bool is_star_aggr(int i){return agr_tbl[i]->is_star_aggr(); };
339 bool is_builtin(int i){return agr_tbl[i]->is_builtin(); };
340 int get_fcn_id(int i){return agr_tbl[i]->get_fcn_id();};
341 bool is_superaggr(int i){return agr_tbl[i]->is_superaggr();};
342 bool is_running_aggr(int i){return agr_tbl[i]->is_running_aggr();};
343 bool has_bailout(int i){return agr_tbl[i]->has_bailout();};
344 // bool multiple_return_allowed(int i){
345 // return agr_tbl[i]->multiple_return_allowed(agr_tbl[i]->is_builtin(),NULL);
347 bool superaggr_allowed(int i){return agr_tbl[i]->superaggr_allowed();};
348 std::vector<scalarexp_t *> get_operand_list(int i){
349 return agr_tbl[i]->get_operand_list();
352 std::vector<std::string> get_subaggr_fcns(int i, std::vector<bool> &use_se){
353 return(agr_tbl[i]->get_subaggr_fcns(use_se) );
356 std::vector<data_type *> get_subaggr_dt(int i){
357 return(agr_tbl[i]->get_subaggr_dt() );
359 data_type *get_storage_type(int i){
360 return( agr_tbl[i]->get_storage_type());
363 aggr_table_entry *duplicate(int i){
364 return agr_tbl[i]->duplicate();
367 scalarexp_t *make_superaggr_se(int i, std::vector<scalarexp_t *> se_refs){
368 return(agr_tbl[i]->make_superaggr_se(se_refs) );
373 class cplx_lit_table{
374 std::vector<literal_t *> cplx_lit_tbl;
375 std::vector<bool> hdl_ref_tbl;
380 int add_cpx_lit(literal_t *, bool);
381 int size(){return cplx_lit_tbl.size();};
382 literal_t *get_literal(int i){return cplx_lit_tbl[i];};
383 bool is_handle_ref(int i){return hdl_ref_tbl[i];};
387 enum param_handle_type { cplx_lit_e, litval_e, param_e};
389 class handle_param_tbl_entry{
393 std::string fcn_name;
396 int complex_literal_idx;
397 std::string param_name;
398 param_handle_type val_type;
399 std::string type_name;
401 handle_param_tbl_entry(std::string fname, int slot,
402 literal_t *l, std::string tnm){
403 fcn_name = fname; param_slot = slot;
408 handle_param_tbl_entry(std::string fname, int slot, std::string p, std::string tnm){
409 fcn_name = fname; param_slot = slot;
414 handle_param_tbl_entry(std::string fname, int slot, int ci, std::string tnm){
415 fcn_name = fname; param_slot = slot;
416 val_type = cplx_lit_e;
417 complex_literal_idx = ci;
421 std::string lfta_registration_fcn(){
423 sprintf(tmps,"register_handle_for_%s_slot_%d",fcn_name.c_str(),param_slot);
426 std::string hfta_registration_fcn(){return lfta_registration_fcn();};
428 std::string lfta_deregistration_fcn(){
430 sprintf(tmps,"deregister_handle_for_%s_slot_%d",fcn_name.c_str(),param_slot);
433 std::string hfta_rdeegistration_fcn(){return lfta_registration_fcn();};
439 // Store the data in vectors to preserve
441 std::vector<std::string> pname;
442 std::vector<data_type *> pdtype;
443 std::vector<bool> phandle;
445 int find_name(std::string n){
447 for(p=0;p<pname.size();++p){
448 if(pname[p] == n) break;
450 if(p == pname.size()) return(-1);
457 // Add the param with the given name and associated
458 // data type and handle use.
459 // if its a new name, return true.
460 // Else, take OR of use_handle, return false.
461 // (builds param table and collects handle references).
462 bool add_param(std::string pnm, data_type *pdt, bool use_handle){
463 int p = find_name(pnm);
465 pname.push_back(pnm);
466 pdtype.push_back(pdt);
467 phandle.push_back(use_handle);
470 if(use_handle) phandle[p] = use_handle;
476 int size(){return pname.size(); };
478 std::vector<std::string> get_param_names(){
482 data_type *get_data_type(std::string pnm){
483 int p = find_name(pnm);
487 return(new data_type("undefined_type"));
490 bool handle_access(std::string pnm){
491 int p = find_name(pnm);
501 // Two columns are the same if they come from the
502 // same source, and have the same field name.
503 // (use to determine which fields must be unpacked).
504 // NOTE : dangerous in the presence of self-joins.
505 typedef std::set<col_id, lt_col_id> col_id_set;
507 bool contains_gb_pr(predicate_t *pr, std::set<int> &gref_set);
508 bool contains_gb_se(scalarexp_t *se, std::set<int> &gref_set);
511 void gather_se_col_ids(scalarexp_t *se, col_id_set &cid_set, gb_table *gtbl);
512 void gather_pr_col_ids(predicate_t *pr, col_id_set &cid_set, gb_table *gtbl);
514 void gather_se_opcmp_fcns(scalarexp_t *se, std::set<std::string> &fcn_set);
515 void gather_pr_opcmp_fcns(predicate_t *pr, std::set<std::string> &fcn_set);
517 ////////////////////////////////////////////
518 // Structures to record usage of operator views.
522 std::string parent_qname;
523 std::string root_name;
524 std::string view_name;
525 std::string exec_fl; // name of executable file (if any)
526 std::string udop_alias; // unique ID of the UDOP
528 int liveness_timeout; // maximum delay between hearbeats from udop
530 std::vector<std::string> subq_names;
532 opview_entry(){mangler="";};
537 std::vector<opview_entry *> opview_list;
539 int append(opview_entry *opv){opview_list.push_back(opv);
540 return opview_list.size()-1;};
541 int size(){return opview_list.size();};
542 opview_entry *get_entry(int i){ return opview_list[i];};
545 /////////////////////////////////////////////////////////////////
546 // Wrap up all of the analysis of the FTA into this package.
548 // There is some duplication between query_summary_class,
549 // but I'd rather avoid pushing analysis structures
550 // into the parse modules.
552 // TODO: revisit the issue when nested subqueries are implemented.
553 // One possibility: implement accessor methods to hide the
555 // For now: this class contains data structures not in table_exp_t
556 // (with a bit of duplication)
558 struct query_summary_class{
559 std::string query_name; // the name of the query, becomes the name
561 int query_type; // e.g. SELECT, MERGE, etc.
563 gb_table *gb_tbl; // Table of all group-by attributes.
564 std::set<int> sg_tbl; // Names of the superGB attributes
565 aggregate_table *aggr_tbl; // Table of all referenced aggregates.
566 std::set<std::string> states_refd; // states ref'd by stateful fcns.
569 // copied from parse tree, then into query node.
570 // interpret the string representation of data type into a type_object
571 param_table *param_tbl; // Table of all query parameters.
573 // There is stuff that is not copied over by analyze_fta,
574 // it still resides in fta_tree.
575 table_exp_t *fta_tree; // The (decorated) parse tree.
578 // This is copied from the parse tree (except for "query_name")
579 // then copied to the query node in query_plan.cc:145
580 std::map<std::string, std::string> definitions; // additional definitions.
583 // CNF representation of the where and having predicates.
584 std::vector<cnf_elem *> wh_cnf;
585 std::vector<cnf_elem *> hav_cnf;
586 std::vector<cnf_elem *> cb_cnf;
587 std::vector<cnf_elem *> cw_cnf;
588 std::vector<cnf_elem *> closew_cnf;
593 // For MERGE type queries.
594 std::vector<colref_t *> mvars;
597 //////// Constructors
598 query_summary_class(){
602 query_summary_class(table_exp_t *f){
609 bool add_query_param(std::string pnm, data_type *pdt, bool use_handle){
610 return( param_tbl->add_param(pnm,pdt,use_handle));
616 // Create the gb_tbl, aggr_tbl, and param_tbl objects
617 gb_tbl = new gb_table();
618 aggr_tbl = new aggregate_table();
619 param_tbl = new param_table();
624 int verify_colref(scalarexp_t *se, tablevar_list_t *fm,
625 table_list *schema, gb_table *gtbl);
626 std::string impute_query_name(table_exp_t *fta_tree, std::string default_nm);
628 query_summary_class *analyze_fta(table_exp_t *fta_tree, table_list *schema, ext_fcn_list *Ext_fcns, std::string qname);
629 bool is_equivalent_se(scalarexp_t *se1, scalarexp_t *se2);
630 bool is_equivalent_se_base(scalarexp_t *se1, scalarexp_t *se2, table_list *Schema);
631 bool is_equivalent_pred_base(predicate_t *p1, predicate_t *p2, table_list *Schema);
633 bool is_equivalent_class_pred_base(predicate_t *p1, predicate_t *p2, table_list *Schema,ext_fcn_list *Ext_fcns);
634 void analyze_cnf(cnf_elem *c);
636 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);
637 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);
638 void collect_partial_fcns(scalarexp_t *se, std::set<int> &pfcn_refs);
639 void collect_partial_fcns_pr(predicate_t *pr, std::set<int> &pfcn_refs);
641 void find_combinable_preds(predicate_t *pr, vector<predicate_t *> *pr_list,
642 table_list *Schema, ext_fcn_list *Ext_fcns);
644 void collect_agg_refs(scalarexp_t *se, std::set<int> &agg_refs);
645 void collect_aggr_refs_pr(predicate_t *pr, std::set<int> &agg_refs);
647 int bind_to_schema_pr(predicate_t *pr, tablevar_list_t *fm, table_list *schema);
648 int bind_to_schema_se(scalarexp_t *se, tablevar_list_t *fm, table_list *schema);
650 temporal_type compute_se_temporal(scalarexp_t *se, std::map<col_id, temporal_type> &tcol);
653 bool find_complex_literal_se(scalarexp_t *se, ext_fcn_list *Ext_fcns,
654 cplx_lit_table *complex_literals);
655 void find_complex_literal_pr(predicate_t *pr, ext_fcn_list *Ext_fcns,
656 cplx_lit_table *complex_literals);
657 void find_param_handles_se(scalarexp_t *se, ext_fcn_list *Ext_fcns,
658 std::vector<handle_param_tbl_entry *> &handle_tbl);
659 void find_param_handles_pr(predicate_t *pr, ext_fcn_list *Ext_fcns,
660 std::vector<handle_param_tbl_entry *> &handle_tbl);
662 // Copy a scalar expression / predicate tree
663 scalarexp_t *dup_se(scalarexp_t *se, aggregate_table *aggr_tbl);
664 select_element *dup_select(select_element *sl, aggregate_table *aggr_tbl);
665 predicate_t *dup_pr(predicate_t *pr, aggregate_table *aggr_tbl);
668 void expand_gbvars_pr(predicate_t *pr, gb_table &gb_tbl);
669 scalarexp_t *expand_gbvars_se(scalarexp_t *se, gb_table &gb_tbl);
673 table_exp_t *dup_table_exp(table_exp_t *te);
676 // Tie colrefs to a new range var
677 void bind_colref_se(scalarexp_t *se,
678 std::vector<tablevar_t *> &fm,
679 int prev_ref, int new_ref
681 void bind_colref_pr(predicate_t *pr,
682 std::vector<tablevar_t *> &fm,
683 int prev_ref, int new_ref
687 std::string impute_colname(std::vector<select_element *> &sel_list, scalarexp_t *se);
688 std::string impute_colname(std::set<std::string> &curr_names, scalarexp_t *se);
690 bool is_literal_or_param_only(scalarexp_t *se);
693 void build_aggr_tbl_fm_pred(predicate_t *pr, aggregate_table *agr_tbl);
694 void build_aggr_tbl_fm_se(scalarexp_t *se, aggregate_table *agr_tbl);
696 void compute_cnf_cost(cnf_elem *cm, ext_fcn_list *Ext_fcns);
697 struct compare_cnf_cost{
698 bool operator()(const cnf_elem *c1, const cnf_elem *c2) const{
699 if(c1->cost < c2->cost) return(true);
704 void get_tablevar_ref_se(scalarexp_t *se, std::vector<int> &reflist);
705 void get_tablevar_ref_pr(predicate_t *pr, std::vector<int> &reflist);
707 long long int find_temporal_divisor(scalarexp_t *se, gb_table *gbt, std::string &fnm);
710 int count_se_ifp_refs(scalarexp_t *se, std::set<std::string> &ifpnames);
711 int count_pr_ifp_refs(predicate_t *pr, std::set<std::string> &ifpnames);
712 int resolve_se_ifp_refs(scalarexp_t *se, std::string ifm, std::string ifn, ifq_t *ifdb, std::string &err);
713 int resolve_pr_ifp_refs(predicate_t *pr, std::string ifm, std::string ifn, ifq_t *ifdb, std::string &err);
715 int pred_refs_sfun(predicate_t *pr);
716 int se_refs_sfun(scalarexp_t *se);
719 // Represent preds for the prefilter, and
720 // the LFTAs which reference them.
723 std::set<int> lfta_id;
724 std::set<unsigned int> pred_id;
727 cnf_set(predicate_t *p, unsigned int l, unsigned int i){
728 pr = dup_pr(p,NULL); // NEED TO UPDATE dup_se TO PROPAGATE
730 pred_id.insert((l << 16)+i);
732 void subsume(cnf_set *c){
733 std::set<int>::iterator ssi;
734 for(ssi=c->lfta_id.begin();ssi!=c->lfta_id.end();++ssi){
735 lfta_id.insert((*ssi));
737 std::set<unsigned int >::iterator spi;
738 for(spi=c->pred_id.begin();spi!=c->pred_id.end();++spi){
739 pred_id.insert((*spi));
742 void combine_pred(cnf_set *c){
743 pr = new predicate_t("AND",pr,c->pr);
744 std::set<unsigned int >::iterator spi;
745 for(spi=c->pred_id.begin();spi!=c->pred_id.end();++spi){
746 pred_id.insert((*spi));
750 void add_pred_ids(set<unsigned int> &pred_set){
751 std::set<unsigned int >::iterator spi;
752 for(spi=pred_id.begin();spi!=pred_id.end();++spi){
753 pred_set.insert((*spi));
757 static unsigned int make_lfta_key(unsigned int l){
764 struct compare_cnf_set{
765 bool operator()(const cnf_set *c1, const cnf_set *c2) const{
766 if(c1->lfta_id.size() > c2->lfta_id.size()) return(true);
771 bool operator<(const cnf_set &c1, const cnf_set &c2);
774 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);
777 cnf_elem *find_common_filter(std::vector< std::vector<cnf_elem *> > &where_list, table_list *Schema);
779 std::string int_to_string(int i);
780 void insert_gb_def_pr(predicate_t *pr, gb_table *gtbl);
781 void insert_gb_def_se(scalarexp_t *se, gb_table *gtbl);