1 /* ------------------------------------------------
2 Copyright 2014 AT&T Intellectual Property
3 Licensed under the Apache License, Version 2.0 (the "License");
4 you may not use this file except in compliance with the License.
5 You may obtain a copy of the License at
7 http://www.apache.org/licenses/LICENSE-2.0
9 Unless required by applicable law or agreed to in writing, software
10 distributed under the License is distributed on an "AS IS" BASIS,
11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 See the License for the specific language governing permissions and
13 limitations under the License.
14 ------------------------------------------- */
21 #include "parse_fta.h"
22 #include "parse_schema.h"
23 #include "analyze_fta.h"
24 #include "generate_utils.h"
25 #include "query_plan.h"
26 #include "generate_nic_code.h"
27 #include"analyze_fta.h"
34 static const char *fcn_for_op[] = {
49 ">=", "greater_equal",
55 static const char *fcn_for_unary_op[]= {
64 static string nic_fcn(string op){
69 if(string(fcn_for_op[i]) == string("END")){
73 if(string(fcn_for_op[i]) == op){
74 return string(fcn_for_op[i+1]);
78 fprintf(stderr,"INTERNAL ERROR, operator %s not found in nic_fcn\n",op.c_str());
79 return string("ERROR");
83 static string unary_nic_fcn(string op){
88 if(string(fcn_for_unary_op[i]) == string("END")){
92 if(string(fcn_for_unary_op[i]) == op){
93 return string(fcn_for_unary_op[i+1]);
97 fprintf(stderr,"INTERNAL ERROR, operator %s not found in unary_nic_fcn\n",op.c_str());
98 return string("ERROR");
104 // Generate code that makes reference
105 // to the tuple, and not to any aggregates.
106 static string generate_nic_se_code(scalarexp_t *se,
107 map<string, string> &constants,
109 set<string> &no_copy_vars,
110 string *retvar, int lr,
115 data_type *ldt, *rdt;
117 vector<scalarexp_t *> operands;
121 string op = se->get_op();
122 //printf("op_type=%d op=%s\n",se->get_operator_type(),op.c_str());
124 switch(se->get_operator_type()){
126 l = se->get_literal()->to_query_string();
127 if(constants.count(l)){
130 cid = "constant"+int_to_string(constants.size());
135 *retvar = "copyvar_"+int_to_string(copy_var_cnt);
137 ret += "load_with_copy("+*retvar+","+cid+")\n";
141 fprintf(stderr,"INTERNAL ERROR, param ref'd in generate_nic_se_code\n");
143 return("ERROR in generate_nic_se_code");
145 ret += generate_nic_se_code(se->get_left_se(),
146 constants, copy_var_cnt, no_copy_vars, &lvar,LEFT,gbt);
147 ret += unary_nic_fcn(op)+"("+lvar+")\n";
151 ret += generate_nic_se_code(se->get_left_se(),
152 constants, copy_var_cnt, no_copy_vars, &lvar,LEFT,gbt);
153 ret += generate_nic_se_code(se->get_right_se(),
154 constants, copy_var_cnt, no_copy_vars, &rvar,RIGHT,gbt);
155 ret += nic_fcn(op)+"("+lvar+","+rvar+")\n";
157 //printf("op %s; lvar=%s, rvar=%s, retvar=%s\n",op.c_str(), lvar.c_str(), rvar.c_str(), retvar->c_str());
161 gbref = se->get_gb_ref();
163 if(gbt->get_reftype(gbref) != GBVAR_COLREF){
164 fprintf(stderr,"INTERNAL ERROR, non-colref gbvar in generate_nic_se_code\n");
168 ret = generate_nic_se_code(gbt->get_def(gbref),constants,copy_var_cnt, no_copy_vars, &lvar,LEFT,gbt);
173 *retvar = "copyvar_"+int_to_string(copy_var_cnt);
175 ret += "load_with_copy("+*retvar+","+se->get_colref()->get_field()+")\n";
177 *retvar = "nocopyvar_"+se->get_colref()->get_field();
178 if(no_copy_vars.count(*retvar) == 0){
179 no_copy_vars.insert(*retvar);
180 ret += "load("+*retvar+","+se->get_colref()->get_field()+")\n";
186 fprintf(stderr,"CONFIG ERROR, fcn reference in generate_nic_se_code, not yet implemented.\n");
190 fprintf(stderr,"INTERNAL ERROR in generate_nic_se_code (lfta), line %d, character %d: unknown operator type %d\n",
191 se->get_lineno(), se->get_charno(),se->get_operator_type());
193 return("ERROR in generate_nic_se_code");
198 static string generate_nic_predicate_code(predicate_t *pr,
199 map<string, string> &constants,
201 set<string> &no_copy_vars,
202 string *retvar, gb_table *gbt ){
204 vector<literal_t *> litv;
206 data_type *ldt, *rdt;
207 vector<scalarexp_t *> op_list;
211 string op = pr->get_op();
213 switch(pr->get_operator_type()){
215 fprintf(stderr,"CONFIG ERROR: IN not supported in generate_nic_predicate_code\n");
217 return("ERROR in generate_nic_predicate_code");
220 ret += generate_nic_se_code(pr->get_left_se(),
221 constants, copy_var_cnt, no_copy_vars, &lvar,LEFT,gbt);
222 ret += generate_nic_se_code(pr->get_right_se(),
223 constants, copy_var_cnt, no_copy_vars, &rvar,RIGHT,gbt);
224 ret += nic_fcn(op)+"("+lvar+","+rvar+")\n";
228 ret += generate_nic_predicate_code(pr->get_left_pr(),
229 constants, copy_var_cnt, no_copy_vars, &lvar,gbt);
230 ret += unary_nic_fcn(op)+"("+lvar+")\n";
234 ret += generate_nic_predicate_code(pr->get_left_pr(),
235 constants, copy_var_cnt, no_copy_vars, &lvar,gbt);
236 ret += generate_nic_predicate_code(pr->get_right_pr(),
237 constants, copy_var_cnt, no_copy_vars, &rvar,gbt);
238 ret += nic_fcn(op)+"("+lvar+","+rvar+")\n";
242 fprintf(stderr,"CONFIG ERROR, fcn reference in generate_nic_pred_code, not yet implemented.\n");
248 fprintf(stderr,"INTERNAL ERROR in generate_predicate_nic_code, line %d, character %d, unknown predicate operator type %d\n",
249 pr->get_lineno(), pr->get_charno(), pr->get_operator_type() );
250 return("ERROR in generate_nic_predicate_code");
255 bool se_is_nic_safe(scalarexp_t *se, nic_property *nicp, gb_table *gbt){
260 switch(se->get_operator_type()){
262 dts = se->get_data_type()->get_type_str();
263 if(nicp->legal_type(dts))
271 if(!se_is_nic_safe(se->get_left_se(), nicp, gbt)) return false;
272 return(nicp->legal_unary_op(se->get_op()));
275 if(!se_is_nic_safe(se->get_left_se(), nicp, gbt)) return false;
276 if(!se_is_nic_safe(se->get_right_se(), nicp, gbt)) return false;
277 return(nicp->legal_binary_op(se->get_op()));
281 gbref = se->get_gb_ref();
283 if(gbt->get_reftype(gbref) != GBVAR_COLREF){
287 return se_is_nic_safe(gbt->get_def(gbref),nicp,gbt);
289 dts = se->get_data_type()->get_type_str();
290 if(! nicp->legal_type(dts))
292 colname = se->get_colref()->get_field();
293 if(! nicp->illegal_field(colname))
307 bool pr_is_nic_safe(predicate_t *pr, nic_property *nicp, gb_table *gbt){
310 switch(pr->get_operator_type()){
314 if(!se_is_nic_safe(pr->get_left_se(), nicp, gbt)) return false;
315 if(!se_is_nic_safe(pr->get_right_se(), nicp, gbt)) return false;
316 return(nicp->legal_binary_op(pr->get_op()));
318 if(!pr_is_nic_safe(pr->get_left_pr(),nicp, gbt)) return false;
319 return(nicp->legal_unary_op(pr->get_op()));
321 if(!pr_is_nic_safe(pr->get_left_pr(),nicp, gbt)) return false;
322 if(!pr_is_nic_safe(pr->get_right_pr(),nicp, gbt)) return false;
323 return(nicp->legal_binary_op(pr->get_op()));
334 void gather_nicsafe_cols(scalarexp_t *se, vector<string> &cols, nic_property *nicp, gb_table *gbt){
337 vector<scalarexp_t *> operands;
339 switch(se->get_operator_type()){
344 gather_nicsafe_cols(se->get_left_se(),cols,nicp, gbt);
347 gather_nicsafe_cols(se->get_left_se(),cols,nicp, gbt);
348 gather_nicsafe_cols(se->get_right_se(),cols,nicp, gbt);
352 gbref = se->get_gb_ref();
353 return gather_nicsafe_cols(gbt->get_def(gbref),cols,nicp, gbt);
355 colname = se->get_colref()->get_field();
356 if(! nicp->illegal_field(colname)){
357 for(i=0;i<cols.size();++i){
358 if(colname == cols[i])
362 cols.push_back(colname);
366 operands = se->get_operands();
367 for(i=0;i<operands.size();++i)
368 gather_nicsafe_cols(operands[i],cols,nicp,gbt);
376 void gather_nicsafe_cols(predicate_t *pr, vector<string> &cols, nic_property *nicp, gb_table *gbt){
379 vector<scalarexp_t *> operands;
382 switch(pr->get_operator_type()){
384 gather_nicsafe_cols(pr->get_left_se(), cols, nicp, gbt);
387 gather_nicsafe_cols(pr->get_left_se(), cols, nicp, gbt);
388 gather_nicsafe_cols(pr->get_right_se(), cols, nicp, gbt);
391 gather_nicsafe_cols(pr->get_left_pr(),cols, nicp, gbt);
394 gather_nicsafe_cols(pr->get_left_pr(),cols, nicp, gbt);
395 gather_nicsafe_cols(pr->get_right_pr(),cols, nicp, gbt);
398 operands = pr->get_op_list();
399 for(i=0;i<operands.size();++i)
400 gather_nicsafe_cols(operands[i],cols,nicp, gbt);
410 string generate_nic_code(vector<stream_query *> lftas, nic_property *nicp){
416 bool packed_return = false;
418 if(nicp->option_exists("Return")){
419 if(nicp->option_value("Return") == "Packed"){
420 //printf("val of Return is %s\n",nicp->option_value("Return").c_str());
421 packed_return = true;
423 fprintf(stderr,"Warning, nic option value of Return=%s is not recognized, ignoring\n",nicp->option_value("Return").c_str());
427 vector<vector<predicate_t *> > nicsafe_preds;
428 vector<predicate_t *> empty_list;
429 for(i=0;i<lftas.size();i++){
430 qp_node *qpn = lftas[i]->get_query_head();
431 if(qpn->node_type() == "sgah_qpn"){
432 gbtbl = ((sgah_qpn *)(qpn))->get_gb_tbl();
436 nicsafe_preds.push_back(empty_list);
437 vector<cnf_elem *> lfta_cnfs = qpn->get_filter_clause();
438 for(p=0;p<lfta_cnfs.size();++p){
439 if(pr_is_nic_safe(lfta_cnfs[p]->pr,nicp,gbtbl)){
440 nicsafe_preds[i].push_back(lfta_cnfs[p]->pr);
445 map<string, string> consts;
447 set<string> nocopy_vars;
451 //printf("dping packed return\n");
452 for(i=0;i<lftas.size();++i){
453 qp_node *qpn = lftas[i]->get_query_head();
454 ret += "comment( lfta "+qpn->get_node_name() + " )\n";
455 if(qpn->node_type() == "sgah_qpn"){
456 gbtbl = ((sgah_qpn *)(qpn))->get_gb_tbl();
460 ret += "\nlabel(lfta"+int_to_string(i)+")\n";
461 for(p=0;p<nicsafe_preds[i].size();++p){
462 ret += generate_nic_predicate_code(nicsafe_preds[i][p],
463 consts, n_copyvar, nocopy_vars, &retvar, gbtbl);
464 ret += "jump_if_zero("+retvar+",lfta"+int_to_string(i+1)+")\n";
466 vector<scalarexp_t *> se_list;
467 if(qpn->node_type() == "sgah_qpn"){
468 se_list =((sgah_qpn *)(qpn))->get_select_se_list();
470 se_list =((spx_qpn *)(qpn))->get_select_se_list();
473 vector<string> refd_cols;
474 for(s=0;s<se_list.size();++s){
475 gather_nicsafe_cols(se_list[s],refd_cols, nicp, gbtbl);
477 vector<cnf_elem *> lfta_cnfs = qpn->get_where_clause();
478 for(p=0;p<lfta_cnfs.size();++p){
479 gather_nicsafe_cols(lfta_cnfs[p]->pr,refd_cols, nicp, gbtbl);
482 for(g=0;g<gbtbl->size();++g){
483 //printf("gathering gbvar %d\n",g);
484 gather_nicsafe_cols(gbtbl->get_def(g),refd_cols, nicp, gbtbl);
487 sort(refd_cols.begin(), refd_cols.end());
489 ret += "pack_and_send(const_id"+int_to_string(i);
490 consts["const_id"+int_to_string(i)] = int_to_string(lftas[i]->get_gid());
491 for(s=0;s<refd_cols.size();++s){
497 ret += "\nlabel(lfta"+int_to_string(i)+")\n";
499 for(i=0;i<lftas.size();++i){
500 qp_node *qpn = lftas[i]->get_query_head();
501 ret += "comment( lfta "+qpn->get_node_name() + " )\n";
502 if(qpn->node_type() == "sgah_qpn"){
503 gbtbl = ((sgah_qpn *)(qpn))->get_gb_tbl();
507 ret += "\nlabel(lfta"+int_to_string(i)+")\n";
508 for(p=0;p<nicsafe_preds[i].size();++p){
509 ret += generate_nic_predicate_code(nicsafe_preds[i][p],
510 consts, n_copyvar, nocopy_vars, &retvar, gbtbl);
511 if(p<nicsafe_preds[i].size()-1){
512 ret += "jump_if_zero("+retvar+",lfta"+int_to_string(i+1)+")\n\n";
514 ret += "jump_if_notzero("+retvar+",pass)\n\n";
518 ret += "label(pass)\n";
519 ret += "send_packet()\n";
520 ret += "\nlabel(lfta"+int_to_string(i)+")\n";
522 ret += "label(exit)\n";
525 map<string, string>::iterator mssi;
526 for(mssi=consts.begin();mssi!=consts.end();++mssi){
527 vars += "constant( "+(*mssi).first+" , "+(*mssi).second+")\n";
529 for(i=0;i<n_copyvar;++i){
530 vars += "variable( copyvar_"+int_to_string(i)+" )\n";
532 set<string>::iterator ssi;
533 for(ssi=nocopy_vars.begin(); ssi!=nocopy_vars.end(); ++ssi){
534 vars += "variable( "+(*ssi)+" )\n";
537 ret = "BEGIN\n"+vars + "\n"+ret + "END\n";