32833c5bb47da2740aaa5898a07f42c61eb5b02f
[com/gs-lite.git] / src / ftacmp / analyze_fta.h
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
6
7      http://www.apache.org/licenses/LICENSE-2.0
8
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
16 #ifndef __ANALYZE_FTA_H_DEFINED__
17 #define __ANALYZE_FTA_H_DEFINED__
18
19
20
21 #include "parse_fta.h"
22 #include "parse_schema.h"
23 #include"type_objects.h"
24 #include "parse_ext_fcns.h"
25 #include "iface_q.h"
26
27
28 #include<set>
29 #include<algorithm>
30 using namespace std;
31
32
33 //              Represent a component of a predicate,
34 //              these components are ANDed together.
35 //              Often they are simple enough to analyze.
36 class cnf_elem{
37 public:
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
41
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
45
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.
50
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.
55
56         int cost;               // an estiamte of the evaluation cost.
57
58    predicate_t *pr;
59
60         cnf_elem(predicate_t *p){
61                 is_atom = 0;
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;
66                 pr = p;
67         };
68
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;
74                 pr = NULL;
75         };
76
77
78
79         void swap_scalar_operands(){
80         int tmp;
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.
83
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;
88
89         pr->swap_scalar_operands();
90   }
91 };
92
93
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.
97
98 struct col_id{
99   std::string field;
100   int tblvar_ref;
101 //              Also carry the schema ref -- used to get data type info
102 //              when defining variables.
103   int schema_ref;
104
105   col_id(){tblvar_ref = -1;};
106   col_id(colref_t *cr){
107           field = cr->field;
108           tblvar_ref = cr-> get_tablevar_ref();
109           schema_ref = cr->get_schema_ref();
110   };
111
112
113
114   void load_from_colref(colref_t *cr){
115           field = cr->field;
116           tblvar_ref = cr-> get_tablevar_ref();
117           schema_ref = cr->get_schema_ref();
118   };
119 };
120
121 struct lt_col_id{
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);
126         return(0);
127   }
128 };
129
130   bool operator<(const col_id &cr1, const col_id &cr2);
131
132
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
140
141 #define GBVAR_COLREF 1
142 #define GBVAR_SE 2
143
144 struct gb_table_entry{
145         col_id name;            // tblref in col_id refers to the tablevar.
146         scalarexp_t *definition;
147         int ref_type;
148
149         gb_table_entry(){
150                 definition = NULL;
151         };
152         data_type *get_data_type(){
153                 return(definition->get_data_type());
154         };
155         void reset_temporal(){
156                 if(definition) definition->reset_temporal();
157         }
158 };
159
160
161 //              The GB table is the symbol table containing
162 //              the GB vars.  This object puts a wrapper around
163 //              access to the table.
164
165 class gb_table{
166 private:
167         std::vector<gb_table_entry *> gtbl;
168
169 public:
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;
178
179         gb_table(){};
180
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);
183
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);
191         };
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;
204         }
205         void reset_temporal(int i){
206                 gtbl[i]->reset_temporal();
207         }
208 };
209
210
211
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)
217
218 struct aggr_table_entry{
219         std::string op;
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.
225         bool is_superag;
226         bool is_running;
227         bool bailout;
228
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;
232                 if(se){
233                         rdt = new data_type();
234                         rdt->set_aggr_data_type(o,se->get_data_type());
235                 }else{
236                         rdt = new data_type("INT");
237                 }
238                 is_superag = s;
239                 is_running = false;
240                 bailout = false;
241         };
242         aggr_table_entry(std::string o, int f, std::vector<scalarexp_t *> s, data_type *st, bool spr, bool r, bool b_o){
243                 op = o;
244                 fcn_id = f;
245                 operand = NULL;
246                 oplist = s;
247                 sdt = st;
248                 rdt = NULL;
249                 is_superag = spr;
250                 is_running = r;
251                 bailout = b_o;
252         }
253
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;};
262
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;};
268
269         aggr_table_entry *duplicate(){
270                 aggr_table_entry *dup = new aggr_table_entry();
271                 dup->op = op;
272                 dup->operand = operand;
273                 dup->oplist = oplist;
274                 dup->fcn_id = fcn_id;
275                 dup->sdt = sdt;
276                 dup->rdt = rdt;
277                 dup->is_superag = is_superag;
278                 dup->is_running = is_running;
279                 dup->bailout = bailout;
280                 return dup;
281         }
282
283         static bool superaggr_allowed(std::string op, ext_fcn_list *Ext_fcns){
284                 if(op == "SUM" || op == "COUNT" || op == "MIN" || op=="MAX")
285                         return true;
286                 return false;
287         }
288
289         bool superaggr_allowed(){
290                 if(is_builtin())
291                         return aggr_table_entry::superaggr_allowed(op,NULL);
292 //              Currently, no UDAFS allowed as superaggregates
293                 return false;
294         }
295
296         static bool multiple_return_allowed(bool is_built_in, ext_fcn_list *Ext_fcns, int fcn_id){
297                 if(is_built_in)
298                         return true;
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))
302                         return true;
303                 return false;
304         }
305
306 };
307
308
309 class aggregate_table{
310 public:
311         std::vector<aggr_table_entry *> agr_tbl;
312
313         aggregate_table(){};
314
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;     };
320
321         data_type *get_data_type(int i){
322 //              if(agr_tbl[i]->op == "COUNT")
323 //                       return new data_type("uint");
324 //              else
325                         if(! agr_tbl[i]->rdt){
326                                 fprintf(stderr,"INTERNAL ERROR in aggregate_table::get_data_type : rdt is NULL.\n");
327                                 exit(1);
328                         }
329                         return agr_tbl[i]->rdt;
330         };
331
332         std::string get_op(int i){return agr_tbl[i]->op;};
333
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);
343 //      };
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();
347         }
348
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) );
351         };
352
353         std::vector<data_type *> get_subaggr_dt(int i){
354                 return(agr_tbl[i]->get_subaggr_dt() );
355         }
356         data_type *get_storage_type(int i){
357                 return( agr_tbl[i]->get_storage_type());
358         }
359
360         aggr_table_entry *duplicate(int i){
361                 return agr_tbl[i]->duplicate();
362         };
363
364         scalarexp_t *make_superaggr_se(int i, std::vector<scalarexp_t *> se_refs){
365                 return(agr_tbl[i]->make_superaggr_se(se_refs) );
366         };
367 };
368
369
370 class cplx_lit_table{
371         std::vector<literal_t *> cplx_lit_tbl;
372         std::vector<bool> hdl_ref_tbl;
373
374 public:
375         cplx_lit_table(){};
376
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];};
381
382 };
383
384 enum param_handle_type { cplx_lit_e, litval_e, param_e};
385
386 class handle_param_tbl_entry{
387 private:
388
389 public:
390         std::string fcn_name;
391         int param_slot;
392         literal_t *litval;
393         int complex_literal_idx;
394         std::string param_name;
395         param_handle_type val_type;
396     std::string type_name;
397
398         handle_param_tbl_entry(std::string fname, int slot,
399                                                         literal_t *l, std::string tnm){
400                 fcn_name = fname; param_slot = slot;
401                 val_type = litval_e;
402                 litval = l;
403                 type_name = tnm;
404         };
405         handle_param_tbl_entry(std::string fname, int slot, std::string p, std::string tnm){
406                 fcn_name = fname; param_slot = slot;
407                 val_type = param_e;
408                 param_name = p;
409                 type_name = tnm;
410         };
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;
415                 type_name = tnm;
416         };
417
418         std::string lfta_registration_fcn(){
419                 char tmps[500];
420                 sprintf(tmps,"register_handle_for_%s_slot_%d",fcn_name.c_str(),param_slot);
421                 return(tmps);
422         };
423         std::string hfta_registration_fcn(){return lfta_registration_fcn();};
424
425         std::string lfta_deregistration_fcn(){
426                 char tmps[500];
427                 sprintf(tmps,"deregister_handle_for_%s_slot_%d",fcn_name.c_str(),param_slot);
428                 return(tmps);
429         };
430         std::string hfta_rdeegistration_fcn(){return lfta_registration_fcn();};
431
432 };
433
434
435 class param_table{
436 //                      Store the data in vectors to preserve
437 //                      listing order.
438         std::vector<std::string> pname;
439         std::vector<data_type *> pdtype;
440         std::vector<bool> phandle;
441
442         int find_name(std::string n){
443                 int p;
444                 for(p=0;p<pname.size();++p){
445                         if(pname[p] == n) break;
446                 }
447                 if(p == pname.size()) return(-1);
448                 return(p);
449         };
450
451 public:
452         param_table(){};
453
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);
461                 if(p == -1){
462                         pname.push_back(pnm);
463                         pdtype.push_back(pdt);
464                         phandle.push_back(use_handle);
465                         return(true);
466         }else{
467                         if(use_handle) phandle[p] = use_handle;
468                         return(false);
469                 }
470
471         };
472
473         int size(){return pname.size(); };
474
475         std::vector<std::string> get_param_names(){
476                 return(pname);
477         };
478
479         data_type *get_data_type(std::string pnm){
480                 int p = find_name(pnm);
481                 if(p >= 0){
482                         return(pdtype[p]);
483                 }
484                 return(new data_type("undefined_type"));
485         };
486
487         bool handle_access(std::string pnm){
488                 int p = find_name(pnm);
489                 if(p >= 0){
490                         return(phandle[p]);
491                 }
492                 return(false);
493         };
494
495 };
496
497
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;
503
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);
506
507
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);
510
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);
513
514 ////////////////////////////////////////////
515 //              Structures to record usage of operator views.
516
517 class opview_entry{
518 public:
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
524         std::string mangler;
525         int liveness_timeout;           // maximum delay between hearbeats from udop
526         int pos;
527         std::vector<std::string> subq_names;
528
529         opview_entry(){mangler="";};
530 };
531
532 class opview_set{
533 public:
534         std::vector<opview_entry *> opview_list;
535
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];};
540 };
541
542 /////////////////////////////////////////////////////////////////
543 //              Wrap up all of the analysis of the FTA into this package.
544 //
545 //              There is some duplication between query_summary_class,
546 //              but I'd rather avoid pushing analysis structures
547 //              into the parse modules.
548 //
549 //              TODO: revisit the issue when nested subqueries are implemented.
550 //              One possibility: implement accessor methods to hide the
551 //              complexity
552 //              For now: this class contains data structures not in table_exp_t
553 //              (with a bit of duplication)
554
555 struct query_summary_class{
556         std::string query_name;                 // the name of the query, becomes the name
557                                                                         // of the output.
558         int query_type;         // e.g. SELECT, MERGE, etc.
559
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.
564
565
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.
569
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.
573
574
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.
578
579
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;
586
587
588
589
590 //              For MERGE type queries.
591         std::vector<colref_t *> mvars;
592         scalarexp_t *slack;
593
594 ////////                        Constructors
595         query_summary_class(){
596                 init();
597         }
598
599         query_summary_class(table_exp_t *f){
600                 fta_tree = f;
601                 init();
602         }
603
604 /////                   Methods
605
606         bool add_query_param(std::string pnm, data_type *pdt, bool use_handle){
607                 return( param_tbl->add_param(pnm,pdt,use_handle));
608         };
609
610
611 private:
612         void init(){
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();
617
618         }
619 };
620
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);
624
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);
629
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);
632
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);
637
638 void find_combinable_preds(predicate_t *pr,  vector<predicate_t *> *pr_list,
639                                                                 table_list *Schema, ext_fcn_list *Ext_fcns);
640
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);
643
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);
646
647 temporal_type compute_se_temporal(scalarexp_t *se, std::map<col_id, temporal_type> &tcol);
648
649
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);
658
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);
663
664 //              Expand gbvars
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);
667
668
669 //              copy a query
670 table_exp_t *dup_table_exp(table_exp_t *te);
671
672
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
677                                  );
678 void bind_colref_pr(predicate_t *pr,
679                                   std::vector<tablevar_t *> &fm,
680                                   int prev_ref, int new_ref
681                                  );
682
683
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);
686
687 bool is_literal_or_param_only(scalarexp_t *se);
688
689
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);
692
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);
697         return(false);
698   }
699 };
700
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);
703
704 long long int find_temporal_divisor(scalarexp_t *se, gb_table *gbt, std::string &fnm);
705
706
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);
711
712 int pred_refs_sfun(predicate_t *pr);
713 int se_refs_sfun(scalarexp_t *se);
714
715
716 //              Represent preds for the prefilter, and
717 //              the LFTAs which reference them.
718 struct cnf_set{
719         predicate_t *pr;
720         std::set<int> lfta_id;
721         std::set<unsigned int> pred_id;
722
723         cnf_set(){};
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
726                 lfta_id.insert(l);
727                 pred_id.insert((l << 16)+i);
728         }
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));
733                 }
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));
737                 }
738         }
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));
744                 }
745         }
746
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));
751                 }
752         }
753
754         static unsigned int make_lfta_key(unsigned int l){
755                 return l << 16;
756         }
757
758
759         ~cnf_set(){};
760 };
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);
764         return(false);
765   }
766 };
767
768 bool operator<(const cnf_set &c1, const cnf_set &c2);
769
770
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);
772
773
774 cnf_elem *find_common_filter(std::vector< std::vector<cnf_elem *> > &where_list, table_list *Schema);
775
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);
779
780
781
782
783 #endif
784