Added quantiling UDAFs
[com/gs-lite.git] / src / ftacmp / analyze_fta.h
1 /* ------------------------------------------------\r
2 Copyright 2014 AT&T Intellectual Property\r
3    Licensed under the Apache License, Version 2.0 (the "License");\r
4    you may not use this file except in compliance with the License.\r
5    You may obtain a copy of the License at\r
6 \r
7      http://www.apache.org/licenses/LICENSE-2.0\r
8 \r
9    Unless required by applicable law or agreed to in writing, software\r
10    distributed under the License is distributed on an "AS IS" BASIS,\r
11    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
12    See the License for the specific language governing permissions and\r
13    limitations under the License.\r
14  ------------------------------------------- */\r
15 \r
16 #ifndef __ANALYZE_FTA_H_DEFINED__\r
17 #define __ANALYZE_FTA_H_DEFINED__\r
18 \r
19 \r
20 \r
21 #include "parse_fta.h"\r
22 #include "parse_schema.h"\r
23 #include"type_objects.h"\r
24 #include "parse_ext_fcns.h"\r
25 #include "iface_q.h"\r
26 \r
27 \r
28 #include<set>\r
29 #include<algorithm>\r
30 using namespace std;\r
31 \r
32 \r
33 //              Represent a component of a predicate,\r
34 //              these components are ANDed together.\r
35 //              Often they are simple enough to analyze.\r
36 class cnf_elem{\r
37 public:\r
38         int is_atom;    // i.e., is an atomic predicate\r
39         int eq_pred;    // And, it is a test for equality\r
40         int in_pred;    // Or, it is a an IN predicate\r
41 \r
42         int pr_gb;              // the predicate refs a gb column.\r
43         int pr_attr;    // the predicate refs a table column.\r
44         int pr_aggr;    // the predicate refs an aggregate\r
45 \r
46         int l_simple;   // the lhs is simple (just a colref)\r
47         int l_gb;               // the lhs refs a gb var\r
48         int l_attr;             // the lhs refs a table column\r
49         int l_aggr;             // the lhs refs an aggregate.\r
50 \r
51         int r_simple;   // the rhs is simple (just a colref)\r
52         int r_gb;               // the rhs refs a gb var\r
53         int r_attr;             // the rhs refs a table column\r
54         int r_aggr;             // the rhs refs an aggregate.\r
55 \r
56         int cost;               // an estiamte of the evaluation cost.\r
57 \r
58    predicate_t *pr;\r
59 \r
60         cnf_elem(predicate_t *p){\r
61                 is_atom = 0;\r
62                 eq_pred = 0; in_pred = 0;\r
63                 pr_gb = pr_attr = pr_aggr = 0;\r
64                 l_simple = l_gb = l_attr = l_aggr = 0;\r
65                 r_simple = r_gb = r_attr = r_aggr = 0;\r
66                 pr = p;\r
67         };\r
68 \r
69         cnf_elem(){ is_atom = 0;\r
70                 eq_pred = 0; in_pred = 0;\r
71                 pr_gb = pr_attr = pr_aggr = 0;\r
72                 l_simple = l_gb = l_attr = l_aggr = 0;\r
73                 r_simple = r_gb = r_attr = r_aggr = 0;\r
74                 pr = NULL;\r
75         };\r
76 \r
77 \r
78 \r
79         void swap_scalar_operands(){\r
80         int tmp;\r
81         if(in_pred) return;     // can't swap IN predicates, se list always on right.\r
82         if(! is_atom) return;   // can only swap scalar expressions.\r
83 \r
84         tmp = l_simple; l_simple = r_simple; r_simple = tmp;\r
85         tmp = l_gb; l_gb = r_gb; r_gb = tmp;\r
86         tmp = l_attr; l_attr = r_attr; r_attr = tmp;\r
87         tmp = l_aggr; l_aggr = r_aggr; r_aggr = tmp;\r
88 \r
89         pr->swap_scalar_operands();\r
90   }\r
91 };\r
92 \r
93 \r
94 //              A GB variable is identified by its name and\r
95 //              its source table variable -- so that joins can be expressed.\r
96 //              GB Vars defined AS a scalar expression have a null tableref.\r
97 \r
98 struct col_id{\r
99   std::string field;\r
100   int tblvar_ref;\r
101 //              Also carry the schema ref -- used to get data type info\r
102 //              when defining variables.\r
103   int schema_ref;\r
104 \r
105   col_id(){tblvar_ref = -1;};\r
106   col_id(colref_t *cr){\r
107           field = cr->field;\r
108           tblvar_ref = cr-> get_tablevar_ref();\r
109           schema_ref = cr->get_schema_ref();\r
110   };\r
111 \r
112 \r
113 \r
114   void load_from_colref(colref_t *cr){\r
115           field = cr->field;\r
116           tblvar_ref = cr-> get_tablevar_ref();\r
117           schema_ref = cr->get_schema_ref();\r
118   };\r
119 };\r
120 \r
121 struct lt_col_id{\r
122   bool operator()(const col_id &cr1, const col_id &cr2) const{\r
123         if(cr1.tblvar_ref < cr2.tblvar_ref) return(1);\r
124         if(cr1.tblvar_ref == cr2.tblvar_ref)\r
125            return (cr1.field < cr2.field);\r
126         return(0);\r
127   }\r
128 };\r
129 \r
130   bool operator<(const col_id &cr1, const col_id &cr2);\r
131 \r
132 \r
133 //              Every GB variable is represented by its name\r
134 //              (defined above) and the scalar expression which\r
135 //              defines its value.  If the GB var is devlared as a\r
136 //              colref, the add_gb_attr method of gb_table will\r
137 //              create an SE consisting of the colref.\r
138 //                      NOTE : using col_id is dangerous when the\r
139 //                                      agregation operator is defiend over a self-join\r
140 \r
141 #define GBVAR_COLREF 1\r
142 #define GBVAR_SE 2\r
143 \r
144 struct gb_table_entry{\r
145         col_id name;            // tblref in col_id refers to the tablevar.\r
146         scalarexp_t *definition;\r
147         int ref_type;\r
148 \r
149         gb_table_entry(){\r
150                 definition = NULL;\r
151         };\r
152         data_type *get_data_type(){\r
153                 return(definition->get_data_type());\r
154         };\r
155         void reset_temporal(){\r
156                 if(definition) definition->reset_temporal();\r
157         }\r
158 };\r
159 \r
160 \r
161 //              The GB table is the symbol table containing\r
162 //              the GB vars.  This object puts a wrapper around\r
163 //              access to the table.\r
164 \r
165 class gb_table{\r
166 private:\r
167         std::vector<gb_table_entry *> gtbl;\r
168 \r
169 public:\r
170         std::vector<vector<bool> > gb_patterns;\r
171 //              rollup, cube, and grouping_sets cannot be readily reconstructed by\r
172 //              analyzing the patterns, so explicitly record them here.\r
173 //              used only so that sgah_qpn::to_query_string produces \r
174 //              something meaningful.\r
175         std::vector<std::string> gb_entry_type;\r
176         std::vector<int> gb_entry_count;\r
177         std::vector<std::vector<std::vector<bool> > > pattern_components;\r
178 \r
179         gb_table(){};\r
180 \r
181         int add_gb_attr(gb_t *c, tablevar_list_t *fm, table_list *schema,\r
182                                         table_exp_t *fta_tree, ext_fcn_list *Ext_fcns);\r
183 \r
184         void add_gb_var(std::string n, int t, scalarexp_t *d, int rt){\r
185                 gb_table_entry *entry = new gb_table_entry();\r
186                 entry->name.field = n;\r
187                 entry->name.tblvar_ref = t;\r
188                 entry->definition = d;\r
189                 entry->ref_type = rt;\r
190                 gtbl.push_back(entry);\r
191         };\r
192         data_type *get_data_type(int g){return(gtbl[g]->get_data_type());       };\r
193         int find_gb(colref_t *c, tablevar_list_t *fm, table_list *schema);\r
194         scalarexp_t *get_def(int i){return gtbl[i]->definition; };\r
195         std::string get_name(int i){return gtbl[i]->name.field; };\r
196         int get_tblvar_ref(int i){return gtbl[i]->name.tblvar_ref;      };\r
197         int get_reftype(int i){return gtbl[i]->ref_type;        };\r
198         int size(){return(gtbl.size()); };\r
199         void set_pattern_info(gb_table *g){\r
200                 gb_patterns = g->gb_patterns;\r
201                 gb_entry_type = g->gb_entry_type;\r
202                 gb_entry_count = g->gb_entry_count;\r
203                 pattern_components = g->pattern_components;\r
204         }\r
205         void reset_temporal(int i){\r
206                 gtbl[i]->reset_temporal();\r
207         }\r
208 };\r
209 \r
210 \r
211 \r
212 //                      Represent an aggregate to be calculated.\r
213 //                      The unique identifier is the aggregate fcn, and the\r
214 //                      expression aggregated over.\r
215 //                      TODO: unify udaf with built-in better\r
216 //                              (but then again, the core dumps help with debugging)\r
217 \r
218 struct aggr_table_entry{\r
219         std::string op;\r
220         scalarexp_t *operand;\r
221         std::vector<scalarexp_t *> oplist;\r
222         int fcn_id;             // -1 for built-in aggrs.\r
223         data_type *sdt; // storage data type.\r
224         data_type *rdt; // return value data type.\r
225         bool is_superag;\r
226         bool is_running;\r
227         bool bailout;\r
228 \r
229         aggr_table_entry(){ sdt = NULL; rdt = NULL; is_superag = false;};\r
230         aggr_table_entry(std::string o, scalarexp_t *se, bool s){\r
231                 op = o; operand = se; fcn_id = -1; sdt = NULL;\r
232                 if(se){\r
233                         rdt = new data_type();\r
234                         rdt->set_aggr_data_type(o,se->get_data_type());\r
235                 }else{\r
236                         rdt = new data_type("INT");\r
237                 }\r
238                 is_superag = s;\r
239                 is_running = false;\r
240                 bailout = false;\r
241         };\r
242         aggr_table_entry(std::string o, int f, std::vector<scalarexp_t *> s, data_type *st, bool spr, bool r, bool b_o){\r
243                 op = o;\r
244                 fcn_id = f;\r
245                 operand = NULL;\r
246                 oplist = s;\r
247                 sdt = st;\r
248                 rdt = NULL;\r
249                 is_superag = spr;\r
250                 is_running = r;\r
251                 bailout = b_o;\r
252         }\r
253 \r
254         bool fta_legal(ext_fcn_list *Ext_fcns);\r
255     bool is_star_aggr(){return operand==NULL;};\r
256         bool is_builtin(){return fcn_id < 0;};\r
257         int get_fcn_id(){return fcn_id;};\r
258         bool is_superaggr(){return is_superag;};\r
259         bool is_running_aggr(){return is_running;};\r
260         bool has_bailout(){return bailout;};\r
261     void set_super(bool s){is_superag = s;};\r
262 \r
263         std::vector<std::string> get_subaggr_fcns(std::vector<bool> &use_se);\r
264         std::vector<data_type *> get_subaggr_dt();\r
265         scalarexp_t *make_superaggr_se(std::vector<scalarexp_t *> se_refs);\r
266         data_type *get_storage_type(){return sdt;};\r
267         std::vector<scalarexp_t *> get_operand_list(){return oplist;};\r
268 \r
269         aggr_table_entry *duplicate(){\r
270                 aggr_table_entry *dup = new aggr_table_entry();\r
271                 dup->op = op;\r
272                 dup->operand = operand;\r
273                 dup->oplist = oplist;\r
274                 dup->fcn_id = fcn_id;\r
275                 dup->sdt = sdt;\r
276                 dup->rdt = rdt;\r
277                 dup->is_superag = is_superag;\r
278                 dup->is_running = is_running;\r
279                 dup->bailout = bailout;\r
280                 return dup;\r
281         }\r
282 \r
283         static bool superaggr_allowed(std::string op, ext_fcn_list *Ext_fcns){\r
284                 if(op == "SUM" || op == "COUNT" || op == "MIN" || op=="MAX")\r
285                         return true;\r
286                 return false;\r
287         }\r
288 \r
289         bool superaggr_allowed(){\r
290                 if(is_builtin())\r
291                         return aggr_table_entry::superaggr_allowed(op,NULL);\r
292 //              Currently, no UDAFS allowed as superaggregates\r
293                 return false;\r
294         }\r
295 \r
296         static bool multiple_return_allowed(bool is_built_in, ext_fcn_list *Ext_fcns, int fcn_id){\r
297                 if(is_built_in)\r
298                         return true;\r
299 //                      Currently, no UDAFS allowed as stateful fcn params.\r
300 //                      in cleaning_when, cleaning_by clauses.\r
301                 if(Ext_fcns->is_running_aggr(fcn_id) || Ext_fcns->multiple_returns(fcn_id))\r
302                         return true;\r
303                 return false;\r
304         }\r
305 \r
306 };\r
307 \r
308 \r
309 class aggregate_table{\r
310 public:\r
311         std::vector<aggr_table_entry *> agr_tbl;\r
312 \r
313         aggregate_table(){};\r
314 \r
315         int add_aggr(std::string op, scalarexp_t *se, bool is_spr);\r
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);\r
317         int add_aggr(aggr_table_entry *a){agr_tbl.push_back(a); return agr_tbl.size(); };\r
318         int size(){return(agr_tbl.size());      };\r
319         scalarexp_t *get_aggr_se(int i){return agr_tbl[i]->operand;     };\r
320 \r
321         data_type *get_data_type(int i){\r
322 //              if(agr_tbl[i]->op == "COUNT")\r
323 //                       return new data_type("uint");\r
324 //              else\r
325                         if(! agr_tbl[i]->rdt){\r
326                                 fprintf(stderr,"INTERNAL ERROR in aggregate_table::get_data_type : rdt is NULL.\n");\r
327                                 exit(1);\r
328                         }\r
329                         return agr_tbl[i]->rdt;\r
330         };\r
331 \r
332         std::string get_op(int i){return agr_tbl[i]->op;};\r
333 \r
334         bool fta_legal(int i,ext_fcn_list *Ext_fcns){return agr_tbl[i]->fta_legal(Ext_fcns);    };\r
335     bool is_star_aggr(int i){return agr_tbl[i]->is_star_aggr(); };\r
336         bool is_builtin(int i){return agr_tbl[i]->is_builtin(); };\r
337         int get_fcn_id(int i){return agr_tbl[i]->get_fcn_id();};\r
338         bool is_superaggr(int i){return agr_tbl[i]->is_superaggr();};\r
339         bool is_running_aggr(int i){return agr_tbl[i]->is_running_aggr();};\r
340         bool has_bailout(int i){return agr_tbl[i]->has_bailout();};\r
341 //      bool multiple_return_allowed(int i){\r
342 //              return agr_tbl[i]->multiple_return_allowed(agr_tbl[i]->is_builtin(),NULL);\r
343 //      };\r
344         bool superaggr_allowed(int i){return agr_tbl[i]->superaggr_allowed();};\r
345         std::vector<scalarexp_t *> get_operand_list(int i){\r
346                 return agr_tbl[i]->get_operand_list();\r
347         }\r
348 \r
349         std::vector<std::string> get_subaggr_fcns(int i, std::vector<bool> &use_se){\r
350                 return(agr_tbl[i]->get_subaggr_fcns(use_se) );\r
351         };\r
352 \r
353         std::vector<data_type *> get_subaggr_dt(int i){\r
354                 return(agr_tbl[i]->get_subaggr_dt() );\r
355         }\r
356         data_type *get_storage_type(int i){\r
357                 return( agr_tbl[i]->get_storage_type());\r
358         }\r
359 \r
360         aggr_table_entry *duplicate(int i){\r
361                 return agr_tbl[i]->duplicate();\r
362         };\r
363 \r
364         scalarexp_t *make_superaggr_se(int i, std::vector<scalarexp_t *> se_refs){\r
365                 return(agr_tbl[i]->make_superaggr_se(se_refs) );\r
366         };\r
367 };\r
368 \r
369 \r
370 class cplx_lit_table{\r
371         std::vector<literal_t *> cplx_lit_tbl;\r
372         std::vector<bool> hdl_ref_tbl;\r
373 \r
374 public:\r
375         cplx_lit_table(){};\r
376 \r
377         int add_cpx_lit(literal_t *, bool);\r
378         int size(){return cplx_lit_tbl.size();};\r
379         literal_t *get_literal(int i){return cplx_lit_tbl[i];};\r
380         bool is_handle_ref(int i){return hdl_ref_tbl[i];};\r
381 \r
382 };\r
383 \r
384 enum param_handle_type { cplx_lit_e, litval_e, param_e};\r
385 \r
386 class handle_param_tbl_entry{\r
387 private:\r
388 \r
389 public:\r
390         std::string fcn_name;\r
391         int param_slot;\r
392         literal_t *litval;\r
393         int complex_literal_idx;\r
394         std::string param_name;\r
395         param_handle_type val_type;\r
396     std::string type_name;\r
397 \r
398         handle_param_tbl_entry(std::string fname, int slot,\r
399                                                         literal_t *l, std::string tnm){\r
400                 fcn_name = fname; param_slot = slot;\r
401                 val_type = litval_e;\r
402                 litval = l;\r
403                 type_name = tnm;\r
404         };\r
405         handle_param_tbl_entry(std::string fname, int slot, std::string p, std::string tnm){\r
406                 fcn_name = fname; param_slot = slot;\r
407                 val_type = param_e;\r
408                 param_name = p;\r
409                 type_name = tnm;\r
410         };\r
411         handle_param_tbl_entry(std::string fname, int slot, int ci, std::string tnm){\r
412                 fcn_name = fname; param_slot = slot;\r
413                 val_type = cplx_lit_e;\r
414                 complex_literal_idx = ci;\r
415                 type_name = tnm;\r
416         };\r
417 \r
418         std::string lfta_registration_fcn(){\r
419                 char tmps[500];\r
420                 sprintf(tmps,"register_handle_for_%s_slot_%d",fcn_name.c_str(),param_slot);\r
421                 return(tmps);\r
422         };\r
423         std::string hfta_registration_fcn(){return lfta_registration_fcn();};\r
424 \r
425         std::string lfta_deregistration_fcn(){\r
426                 char tmps[500];\r
427                 sprintf(tmps,"deregister_handle_for_%s_slot_%d",fcn_name.c_str(),param_slot);\r
428                 return(tmps);\r
429         };\r
430         std::string hfta_rdeegistration_fcn(){return lfta_registration_fcn();};\r
431 \r
432 };\r
433 \r
434 \r
435 class param_table{\r
436 //                      Store the data in vectors to preserve\r
437 //                      listing order.\r
438         std::vector<std::string> pname;\r
439         std::vector<data_type *> pdtype;\r
440         std::vector<bool> phandle;\r
441 \r
442         int find_name(std::string n){\r
443                 int p;\r
444                 for(p=0;p<pname.size();++p){\r
445                         if(pname[p] == n) break;\r
446                 }\r
447                 if(p == pname.size()) return(-1);\r
448                 return(p);\r
449         };\r
450 \r
451 public:\r
452         param_table(){};\r
453 \r
454 //                      Add the param with the given name and associated\r
455 //                      data type and handle use.\r
456 //                      if its a new name, return true.\r
457 //                      Else, take OR of use_handle, return false.\r
458 //                      (builds param table and collects handle references).\r
459         bool add_param(std::string pnm, data_type *pdt, bool use_handle){\r
460                 int p = find_name(pnm);\r
461                 if(p == -1){\r
462                         pname.push_back(pnm);\r
463                         pdtype.push_back(pdt);\r
464                         phandle.push_back(use_handle);\r
465                         return(true);\r
466         }else{\r
467                         if(use_handle) phandle[p] = use_handle;\r
468                         return(false);\r
469                 }\r
470 \r
471         };\r
472 \r
473         int size(){return pname.size(); };\r
474 \r
475         std::vector<std::string> get_param_names(){\r
476                 return(pname);\r
477         };\r
478 \r
479         data_type *get_data_type(std::string pnm){\r
480                 int p = find_name(pnm);\r
481                 if(p >= 0){\r
482                         return(pdtype[p]);\r
483                 }\r
484                 return(new data_type("undefined_type"));\r
485         };\r
486 \r
487         bool handle_access(std::string pnm){\r
488                 int p = find_name(pnm);\r
489                 if(p >= 0){\r
490                         return(phandle[p]);\r
491                 }\r
492                 return(false);\r
493         };\r
494 \r
495 };\r
496 \r
497 \r
498 //                      Two columns are the same if they come from the\r
499 //                      same source, and have the same field name.\r
500 //                      (use to determine which fields must be unpacked).\r
501 //                      NOTE : dangerous in the presence of self-joins.\r
502 typedef std::set<col_id, lt_col_id> col_id_set;\r
503 \r
504 bool contains_gb_pr(predicate_t *pr, std::set<int> &gref_set);\r
505 bool contains_gb_se(scalarexp_t *se, std::set<int> &gref_set);\r
506 \r
507 \r
508 void gather_se_col_ids(scalarexp_t *se, col_id_set &cid_set,  gb_table *gtbl);\r
509 void gather_pr_col_ids(predicate_t *pr, col_id_set &cid_set, gb_table *gtbl);\r
510 \r
511 void gather_se_opcmp_fcns(scalarexp_t *se, std::set<std::string> &fcn_set);\r
512 void gather_pr_opcmp_fcns(predicate_t *pr, std::set<std::string> &fcn_set);\r
513 \r
514 ////////////////////////////////////////////\r
515 //              Structures to record usage of operator views.\r
516 \r
517 class opview_entry{\r
518 public:\r
519         std::string parent_qname;\r
520         std::string root_name;\r
521         std::string view_name;\r
522         std::string exec_fl;            // name of executable file (if any)\r
523         std::string udop_alias;         // unique ID of the UDOP\r
524         std::string mangler;\r
525         int liveness_timeout;           // maximum delay between hearbeats from udop\r
526         int pos;\r
527         std::vector<std::string> subq_names;\r
528 \r
529         opview_entry(){mangler="";};\r
530 };\r
531 \r
532 class opview_set{\r
533 public:\r
534         std::vector<opview_entry *> opview_list;\r
535 \r
536         int append(opview_entry *opv){opview_list.push_back(opv);\r
537                                                                   return opview_list.size()-1;};\r
538         int size(){return opview_list.size();};\r
539         opview_entry *get_entry(int i){ return opview_list[i];};\r
540 };\r
541 \r
542 /////////////////////////////////////////////////////////////////\r
543 //              Wrap up all of the analysis of the FTA into this package.\r
544 //\r
545 //              There is some duplication between query_summary_class,\r
546 //              but I'd rather avoid pushing analysis structures\r
547 //              into the parse modules.\r
548 //\r
549 //              TODO: revisit the issue when nested subqueries are implemented.\r
550 //              One possibility: implement accessor methods to hide the\r
551 //              complexity\r
552 //              For now: this class contains data structures not in table_exp_t\r
553 //              (with a bit of duplication)\r
554 \r
555 struct query_summary_class{\r
556         std::string query_name;                 // the name of the query, becomes the name\r
557                                                                         // of the output.\r
558         int query_type;         // e.g. SELECT, MERGE, etc.\r
559 \r
560         gb_table *gb_tbl;                       // Table of all group-by attributes.\r
561         std::set<int> sg_tbl;           // Names of the superGB attributes\r
562         aggregate_table *aggr_tbl;      // Table of all referenced aggregates.\r
563         std::set<std::string> states_refd;      // states ref'd by stateful fcns.\r
564 \r
565 \r
566 //              copied from parse tree, then into query node.\r
567 //              interpret the string representation of data type into a type_object\r
568         param_table *param_tbl;         // Table of all query parameters.\r
569 \r
570 //              There is stuff that is not copied over by analyze_fta,\r
571 //              it still resides in fta_tree.\r
572     table_exp_t *fta_tree;              // The (decorated) parse tree.\r
573 \r
574 \r
575 //              This is copied from the parse tree (except for "query_name")\r
576 //              then copied to the query node in query_plan.cc:145\r
577         std::map<std::string, std::string> definitions; // additional definitions.\r
578 \r
579 \r
580 //              CNF representation of the where and having predicates.\r
581         std::vector<cnf_elem *> wh_cnf;\r
582         std::vector<cnf_elem *> hav_cnf;\r
583         std::vector<cnf_elem *> cb_cnf;\r
584         std::vector<cnf_elem *> cw_cnf;\r
585         std::vector<cnf_elem *> closew_cnf;\r
586 \r
587 \r
588 \r
589 \r
590 //              For MERGE type queries.\r
591         std::vector<colref_t *> mvars;\r
592         scalarexp_t *slack;\r
593 \r
594 ////////                        Constructors\r
595         query_summary_class(){\r
596                 init();\r
597         }\r
598 \r
599         query_summary_class(table_exp_t *f){\r
600                 fta_tree = f;\r
601                 init();\r
602         }\r
603 \r
604 /////                   Methods\r
605 \r
606         bool add_query_param(std::string pnm, data_type *pdt, bool use_handle){\r
607                 return( param_tbl->add_param(pnm,pdt,use_handle));\r
608         };\r
609 \r
610 \r
611 private:\r
612         void init(){\r
613 //              Create the gb_tbl, aggr_tbl, and param_tbl objects\r
614                 gb_tbl = new gb_table();\r
615                 aggr_tbl = new aggregate_table();\r
616                 param_tbl = new param_table();\r
617 \r
618         }\r
619 };\r
620 \r
621 int verify_colref(scalarexp_t *se, tablevar_list_t *fm,\r
622                                         table_list *schema, gb_table *gtbl);\r
623 std::string impute_query_name(table_exp_t *fta_tree, std::string default_nm);\r
624 \r
625 query_summary_class *analyze_fta(table_exp_t *fta_tree, table_list *schema, ext_fcn_list *Ext_fcns, std::string qname);\r
626 bool is_equivalent_se(scalarexp_t *se1, scalarexp_t *se2);\r
627 bool is_equivalent_se_base(scalarexp_t *se1, scalarexp_t *se2, table_list *Schema);\r
628 bool is_equivalent_pred_base(predicate_t *p1, predicate_t *p2, table_list *Schema);\r
629 \r
630 bool is_equivalent_class_pred_base(predicate_t *p1, predicate_t *p2, table_list *Schema,ext_fcn_list *Ext_fcns);\r
631 void analyze_cnf(cnf_elem *c);\r
632 \r
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);\r
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);\r
635 void collect_partial_fcns(scalarexp_t *se, std::set<int> &pfcn_refs);\r
636 void collect_partial_fcns_pr(predicate_t *pr,  std::set<int> &pfcn_refs);\r
637 \r
638 void find_combinable_preds(predicate_t *pr,  vector<predicate_t *> *pr_list,\r
639                                                                 table_list *Schema, ext_fcn_list *Ext_fcns);\r
640 \r
641 void collect_agg_refs(scalarexp_t *se, std::set<int> &agg_refs);\r
642 void collect_aggr_refs_pr(predicate_t *pr,  std::set<int> &agg_refs);\r
643 \r
644 int bind_to_schema_pr(predicate_t *pr, tablevar_list_t *fm, table_list *schema);\r
645 int bind_to_schema_se(scalarexp_t *se, tablevar_list_t *fm, table_list *schema);\r
646 \r
647 temporal_type compute_se_temporal(scalarexp_t *se, std::map<col_id, temporal_type> &tcol);\r
648 \r
649 \r
650 bool find_complex_literal_se(scalarexp_t *se, ext_fcn_list *Ext_fcns,\r
651                                                                 cplx_lit_table *complex_literals);\r
652 void find_complex_literal_pr(predicate_t *pr, ext_fcn_list *Ext_fcns,\r
653                                                                 cplx_lit_table *complex_literals);\r
654 void find_param_handles_se(scalarexp_t *se, ext_fcn_list *Ext_fcns,\r
655                                                 std::vector<handle_param_tbl_entry *> &handle_tbl);\r
656 void find_param_handles_pr(predicate_t *pr, ext_fcn_list *Ext_fcns,\r
657                                                 std::vector<handle_param_tbl_entry *> &handle_tbl);\r
658 \r
659 //              Copy a scalar expression / predicate tree\r
660 scalarexp_t *dup_se(scalarexp_t *se, aggregate_table *aggr_tbl);\r
661 select_element *dup_select(select_element *sl, aggregate_table *aggr_tbl);\r
662 predicate_t *dup_pr(predicate_t *pr, aggregate_table *aggr_tbl);\r
663 \r
664 //              Expand gbvars\r
665 void expand_gbvars_pr(predicate_t *pr, gb_table &gb_tbl);\r
666 scalarexp_t *expand_gbvars_se(scalarexp_t *se, gb_table &gb_tbl);\r
667 \r
668 \r
669 //              copy a query\r
670 table_exp_t *dup_table_exp(table_exp_t *te);\r
671 \r
672 \r
673 //              Tie colrefs to a new range var\r
674 void bind_colref_se(scalarexp_t *se,\r
675                                   std::vector<tablevar_t *> &fm,\r
676                                   int prev_ref, int new_ref\r
677                                  );\r
678 void bind_colref_pr(predicate_t *pr,\r
679                                   std::vector<tablevar_t *> &fm,\r
680                                   int prev_ref, int new_ref\r
681                                  );\r
682 \r
683 \r
684 std::string impute_colname(std::vector<select_element *> &sel_list, scalarexp_t *se);\r
685 std::string impute_colname(std::set<std::string> &curr_names, scalarexp_t *se);\r
686 \r
687 bool is_literal_or_param_only(scalarexp_t *se);\r
688 \r
689 \r
690 void build_aggr_tbl_fm_pred(predicate_t *pr, aggregate_table *agr_tbl);\r
691 void build_aggr_tbl_fm_se(scalarexp_t *se, aggregate_table *agr_tbl);\r
692 \r
693 void compute_cnf_cost(cnf_elem *cm, ext_fcn_list *Ext_fcns);\r
694 struct compare_cnf_cost{\r
695   bool operator()(const cnf_elem *c1, const cnf_elem *c2) const{\r
696         if(c1->cost < c2->cost) return(true);\r
697         return(false);\r
698   }\r
699 };\r
700 \r
701 void get_tablevar_ref_se(scalarexp_t *se, std::vector<int> &reflist);\r
702 void get_tablevar_ref_pr(predicate_t *pr, std::vector<int> &reflist);\r
703 \r
704 long long int find_temporal_divisor(scalarexp_t *se, gb_table *gbt, std::string &fnm);\r
705 \r
706 \r
707 int count_se_ifp_refs(scalarexp_t *se, std::set<std::string> &ifpnames);\r
708 int count_pr_ifp_refs(predicate_t *pr, std::set<std::string> &ifpnames);\r
709 int resolve_se_ifp_refs(scalarexp_t *se, std::string ifm, std::string ifn, ifq_t *ifdb,  std::string &err);\r
710 int resolve_pr_ifp_refs(predicate_t *pr, std::string ifm, std::string ifn, ifq_t *ifdb,  std::string &err);\r
711 \r
712 int pred_refs_sfun(predicate_t *pr);\r
713 int se_refs_sfun(scalarexp_t *se);\r
714 \r
715 \r
716 //              Represent preds for the prefilter, and\r
717 //              the LFTAs which reference them.\r
718 struct cnf_set{\r
719         predicate_t *pr;\r
720         std::set<int> lfta_id;\r
721         std::set<unsigned int> pred_id;\r
722 \r
723         cnf_set(){};\r
724         cnf_set(predicate_t *p, unsigned int l, unsigned int i){\r
725                 pr = dup_pr(p,NULL);            // NEED TO UPDATE dup_se TO PROPAGATE\r
726                 lfta_id.insert(l);\r
727                 pred_id.insert((l << 16)+i);\r
728         }\r
729         void subsume(cnf_set *c){\r
730                 std::set<int>::iterator ssi;\r
731                 for(ssi=c->lfta_id.begin();ssi!=c->lfta_id.end();++ssi){\r
732                         lfta_id.insert((*ssi));\r
733                 }\r
734                 std::set<unsigned int >::iterator spi;\r
735                 for(spi=c->pred_id.begin();spi!=c->pred_id.end();++spi){\r
736                         pred_id.insert((*spi));\r
737                 }\r
738         }\r
739         void combine_pred(cnf_set *c){\r
740                 pr = new predicate_t("AND",pr,c->pr);\r
741                 std::set<unsigned int >::iterator spi;\r
742                 for(spi=c->pred_id.begin();spi!=c->pred_id.end();++spi){\r
743                         pred_id.insert((*spi));\r
744                 }\r
745         }\r
746 \r
747         void add_pred_ids(set<unsigned int> &pred_set){\r
748                 std::set<unsigned int >::iterator spi;\r
749                 for(spi=pred_id.begin();spi!=pred_id.end();++spi){\r
750                         pred_set.insert((*spi));\r
751                 }\r
752         }\r
753 \r
754         static unsigned int make_lfta_key(unsigned int l){\r
755                 return l << 16;\r
756         }\r
757 \r
758 \r
759         ~cnf_set(){};\r
760 };\r
761 struct compare_cnf_set{\r
762   bool operator()(const cnf_set *c1, const cnf_set *c2) const{\r
763         if(c1->lfta_id.size() > c2->lfta_id.size()) return(true);\r
764         return(false);\r
765   }\r
766 };\r
767 \r
768 bool operator<(const cnf_set &c1, const cnf_set &c2);\r
769 \r
770 \r
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);\r
772 \r
773 \r
774 cnf_elem *find_common_filter(std::vector< std::vector<cnf_elem *> > &where_list, table_list *Schema);\r
775 \r
776 std::string int_to_string(int i);\r
777 void insert_gb_def_pr(predicate_t *pr, gb_table *gtbl);\r
778 void insert_gb_def_se(scalarexp_t *se, gb_table *gtbl);\r
779 \r
780 \r
781 \r
782 \r
783 #endif\r
784 \r