Add support for query key extraction
[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 //      Make visible for predicate insertion
94 void make_cnf_from_pr(predicate_t *pr, std::vector<cnf_elem *> &clist);
95
96
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.
100
101 struct col_id{
102   std::string field;
103   int tblvar_ref;
104 //              Also carry the schema ref -- used to get data type info
105 //              when defining variables.
106   int schema_ref;
107
108   col_id(){tblvar_ref = -1;};
109   col_id(colref_t *cr){
110           field = cr->field;
111           tblvar_ref = cr-> get_tablevar_ref();
112           schema_ref = cr->get_schema_ref();
113   };
114
115
116
117   void load_from_colref(colref_t *cr){
118           field = cr->field;
119           tblvar_ref = cr-> get_tablevar_ref();
120           schema_ref = cr->get_schema_ref();
121   };
122 };
123
124 struct lt_col_id{
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);
129         return(0);
130   }
131 };
132
133   bool operator<(const col_id &cr1, const col_id &cr2);
134
135
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
143
144 #define GBVAR_COLREF 1
145 #define GBVAR_SE 2
146
147 struct gb_table_entry{
148         col_id name;            // tblref in col_id refers to the tablevar.
149         scalarexp_t *definition;
150         int ref_type;
151
152         gb_table_entry(){
153                 definition = NULL;
154         };
155         data_type *get_data_type(){
156                 return(definition->get_data_type());
157         };
158         void reset_temporal(){
159                 if(definition) definition->reset_temporal();
160         }
161 };
162
163
164 //              The GB table is the symbol table containing
165 //              the GB vars.  This object puts a wrapper around
166 //              access to the table.
167
168 class gb_table{
169 private:
170         std::vector<gb_table_entry *> gtbl;
171
172 public:
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;
181
182         gb_table(){};
183
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);
186
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);
194         };
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;
207         }
208         void reset_temporal(int i){
209                 gtbl[i]->reset_temporal();
210         }
211 };
212
213
214
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)
220
221 struct aggr_table_entry{
222         std::string op;
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.
228         bool is_superag;
229         bool is_running;
230         bool bailout;
231
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;
235                 if(se){
236                         rdt = new data_type();
237                         rdt->set_aggr_data_type(o,se->get_data_type());
238                 }else{
239                         rdt = new data_type("INT");
240                 }
241                 is_superag = s;
242                 is_running = false;
243                 bailout = false;
244         };
245         aggr_table_entry(std::string o, int f, std::vector<scalarexp_t *> s, data_type *st, bool spr, bool r, bool b_o){
246                 op = o;
247                 fcn_id = f;
248                 operand = NULL;
249                 oplist = s;
250                 sdt = st;
251                 rdt = NULL;
252                 is_superag = spr;
253                 is_running = r;
254                 bailout = b_o;
255         }
256
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;};
265
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;};
271
272         aggr_table_entry *duplicate(){
273                 aggr_table_entry *dup = new aggr_table_entry();
274                 dup->op = op;
275                 dup->operand = operand;
276                 dup->oplist = oplist;
277                 dup->fcn_id = fcn_id;
278                 dup->sdt = sdt;
279                 dup->rdt = rdt;
280                 dup->is_superag = is_superag;
281                 dup->is_running = is_running;
282                 dup->bailout = bailout;
283                 return dup;
284         }
285
286         static bool superaggr_allowed(std::string op, ext_fcn_list *Ext_fcns){
287                 if(op == "SUM" || op == "COUNT" || op == "MIN" || op=="MAX")
288                         return true;
289                 return false;
290         }
291
292         bool superaggr_allowed(){
293                 if(is_builtin())
294                         return aggr_table_entry::superaggr_allowed(op,NULL);
295 //              Currently, no UDAFS allowed as superaggregates
296                 return false;
297         }
298
299         static bool multiple_return_allowed(bool is_built_in, ext_fcn_list *Ext_fcns, int fcn_id){
300                 if(is_built_in)
301                         return true;
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))
305                         return true;
306                 return false;
307         }
308
309 };
310
311
312 class aggregate_table{
313 public:
314         std::vector<aggr_table_entry *> agr_tbl;
315
316         aggregate_table(){};
317
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;     };
323
324         data_type *get_data_type(int i){
325 //              if(agr_tbl[i]->op == "COUNT")
326 //                       return new data_type("uint");
327 //              else
328                         if(! agr_tbl[i]->rdt){
329                                 fprintf(stderr,"INTERNAL ERROR in aggregate_table::get_data_type : rdt is NULL.\n");
330                                 exit(1);
331                         }
332                         return agr_tbl[i]->rdt;
333         };
334
335         std::string get_op(int i){return agr_tbl[i]->op;};
336
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);
346 //      };
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();
350         }
351
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) );
354         };
355
356         std::vector<data_type *> get_subaggr_dt(int i){
357                 return(agr_tbl[i]->get_subaggr_dt() );
358         }
359         data_type *get_storage_type(int i){
360                 return( agr_tbl[i]->get_storage_type());
361         }
362
363         aggr_table_entry *duplicate(int i){
364                 return agr_tbl[i]->duplicate();
365         };
366
367         scalarexp_t *make_superaggr_se(int i, std::vector<scalarexp_t *> se_refs){
368                 return(agr_tbl[i]->make_superaggr_se(se_refs) );
369         };
370 };
371
372
373 class cplx_lit_table{
374         std::vector<literal_t *> cplx_lit_tbl;
375         std::vector<bool> hdl_ref_tbl;
376
377 public:
378         cplx_lit_table(){};
379
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];};
384
385 };
386
387 enum param_handle_type { cplx_lit_e, litval_e, param_e};
388
389 class handle_param_tbl_entry{
390 private:
391
392 public:
393         std::string fcn_name;
394         int param_slot;
395         literal_t *litval;
396         int complex_literal_idx;
397         std::string param_name;
398         param_handle_type val_type;
399     std::string type_name;
400
401         handle_param_tbl_entry(std::string fname, int slot,
402                                                         literal_t *l, std::string tnm){
403                 fcn_name = fname; param_slot = slot;
404                 val_type = litval_e;
405                 litval = l;
406                 type_name = tnm;
407         };
408         handle_param_tbl_entry(std::string fname, int slot, std::string p, std::string tnm){
409                 fcn_name = fname; param_slot = slot;
410                 val_type = param_e;
411                 param_name = p;
412                 type_name = tnm;
413         };
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;
418                 type_name = tnm;
419         };
420
421         std::string lfta_registration_fcn(){
422                 char tmps[500];
423                 sprintf(tmps,"register_handle_for_%s_slot_%d",fcn_name.c_str(),param_slot);
424                 return(tmps);
425         };
426         std::string hfta_registration_fcn(){return lfta_registration_fcn();};
427
428         std::string lfta_deregistration_fcn(){
429                 char tmps[500];
430                 sprintf(tmps,"deregister_handle_for_%s_slot_%d",fcn_name.c_str(),param_slot);
431                 return(tmps);
432         };
433         std::string hfta_rdeegistration_fcn(){return lfta_registration_fcn();};
434
435 };
436
437
438 class param_table{
439 //                      Store the data in vectors to preserve
440 //                      listing order.
441         std::vector<std::string> pname;
442         std::vector<data_type *> pdtype;
443         std::vector<bool> phandle;
444
445         int find_name(std::string n){
446                 int p;
447                 for(p=0;p<pname.size();++p){
448                         if(pname[p] == n) break;
449                 }
450                 if(p == pname.size()) return(-1);
451                 return(p);
452         };
453
454 public:
455         param_table(){};
456
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);
464                 if(p == -1){
465                         pname.push_back(pnm);
466                         pdtype.push_back(pdt);
467                         phandle.push_back(use_handle);
468                         return(true);
469         }else{
470                         if(use_handle) phandle[p] = use_handle;
471                         return(false);
472                 }
473
474         };
475
476         int size(){return pname.size(); };
477
478         std::vector<std::string> get_param_names(){
479                 return(pname);
480         };
481
482         data_type *get_data_type(std::string pnm){
483                 int p = find_name(pnm);
484                 if(p >= 0){
485                         return(pdtype[p]);
486                 }
487                 return(new data_type("undefined_type"));
488         };
489
490         bool handle_access(std::string pnm){
491                 int p = find_name(pnm);
492                 if(p >= 0){
493                         return(phandle[p]);
494                 }
495                 return(false);
496         };
497
498 };
499
500
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;
506
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);
509
510
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);
513
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);
516
517 ////////////////////////////////////////////
518 //              Structures to record usage of operator views.
519
520 class opview_entry{
521 public:
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
527         std::string mangler;
528         int liveness_timeout;           // maximum delay between hearbeats from udop
529         int pos;
530         std::vector<std::string> subq_names;
531
532         opview_entry(){mangler="";};
533 };
534
535 class opview_set{
536 public:
537         std::vector<opview_entry *> opview_list;
538
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];};
543 };
544
545 /////////////////////////////////////////////////////////////////
546 //              Wrap up all of the analysis of the FTA into this package.
547 //
548 //              There is some duplication between query_summary_class,
549 //              but I'd rather avoid pushing analysis structures
550 //              into the parse modules.
551 //
552 //              TODO: revisit the issue when nested subqueries are implemented.
553 //              One possibility: implement accessor methods to hide the
554 //              complexity
555 //              For now: this class contains data structures not in table_exp_t
556 //              (with a bit of duplication)
557
558 struct query_summary_class{
559         std::string query_name;                 // the name of the query, becomes the name
560                                                                         // of the output.
561         int query_type;         // e.g. SELECT, MERGE, etc.
562
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.
567
568
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.
572
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.
576
577
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.
581
582
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;
589
590
591
592
593 //              For MERGE type queries.
594         std::vector<colref_t *> mvars;
595         scalarexp_t *slack;
596
597 ////////                        Constructors
598         query_summary_class(){
599                 init();
600         }
601
602         query_summary_class(table_exp_t *f){
603                 fta_tree = f;
604                 init();
605         }
606
607 /////                   Methods
608
609         bool add_query_param(std::string pnm, data_type *pdt, bool use_handle){
610                 return( param_tbl->add_param(pnm,pdt,use_handle));
611         };
612
613
614 private:
615         void init(){
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();
620
621         }
622 };
623
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);
627
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);
632
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);
635
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);
640
641 void find_combinable_preds(predicate_t *pr,  vector<predicate_t *> *pr_list,
642                                                                 table_list *Schema, ext_fcn_list *Ext_fcns);
643
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);
646
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);
649
650 temporal_type compute_se_temporal(scalarexp_t *se, std::map<col_id, temporal_type> &tcol);
651
652
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);
661
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);
666
667 //              Expand gbvars
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);
670
671
672 //              copy a query
673 table_exp_t *dup_table_exp(table_exp_t *te);
674
675
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
680                                  );
681 void bind_colref_pr(predicate_t *pr,
682                                   std::vector<tablevar_t *> &fm,
683                                   int prev_ref, int new_ref
684                                  );
685
686
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);
689
690 bool is_literal_or_param_only(scalarexp_t *se);
691
692
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);
695
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);
700         return(false);
701   }
702 };
703
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);
706
707 long long int find_temporal_divisor(scalarexp_t *se, gb_table *gbt, std::string &fnm);
708
709
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);
714
715 int pred_refs_sfun(predicate_t *pr);
716 int se_refs_sfun(scalarexp_t *se);
717
718
719 //              Represent preds for the prefilter, and
720 //              the LFTAs which reference them.
721 struct cnf_set{
722         predicate_t *pr;
723         std::set<int> lfta_id;
724         std::set<unsigned int> pred_id;
725
726         cnf_set(){};
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
729                 lfta_id.insert(l);
730                 pred_id.insert((l << 16)+i);
731         }
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));
736                 }
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));
740                 }
741         }
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));
747                 }
748         }
749
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));
754                 }
755         }
756
757         static unsigned int make_lfta_key(unsigned int l){
758                 return l << 16;
759         }
760
761
762         ~cnf_set(){};
763 };
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);
767         return(false);
768   }
769 };
770
771 bool operator<(const cnf_set &c1, const cnf_set &c2);
772
773
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);
775
776
777 cnf_elem *find_common_filter(std::vector< std::vector<cnf_elem *> > &where_list, table_list *Schema);
778
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);
782
783
784
785
786 #endif
787