-/* ------------------------------------------------
-Copyright 2014 AT&T Intellectual Property
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- ------------------------------------------- */
-
-#include <string>
-#include <stdio.h>
-#include <stdlib.h>
-#include <algorithm>
-
-#include "parse_fta.h"
-#include "parse_schema.h"
-#include "analyze_fta.h"
-#include "generate_utils.h"
-#include "query_plan.h"
-#include "generate_nic_code.h"
-#include"analyze_fta.h"
-
-#define LEFT 1
-#define RIGHT 2
-
-using namespace std;
-
-static const char *fcn_for_op[] = {
- "+", "plus",
- "-", "minus",
- "|", "bitwise_or",
- "*", "multiply",
- "/", "divide",
- "&", "bitwise_and",
- "%", "modulo",
- ">>", "shift_right",
- "<<", "shift_left",
- "AND", "AND",
- "OR", "OR",
- "=", "equal",
- ">", "greater",
- "<", "less",
- ">=", "greater_equal",
- "<=", "less_equal",
- "<>", "not_equal",
- "END"
-};
-
-static const char *fcn_for_unary_op[]= {
- "+", "unary_plus",
- "-", "unary_minus",
- "!", "integer_not",
- "~", "bitwise_not",
- "NOT", "logical_not",
- "END"
-};
-
-static string nic_fcn(string op){
-int i = 0;
-bool done = false;
-
- while(!done){
- if(string(fcn_for_op[i]) == string("END")){
- done = true;
- break;
- }
- if(string(fcn_for_op[i]) == op){
- return string(fcn_for_op[i+1]);
- }
- i++;
- }
- fprintf(stderr,"INTERNAL ERROR, operator %s not found in nic_fcn\n",op.c_str());
- return string("ERROR");
-}
-
-
-static string unary_nic_fcn(string op){
-int i = 0;
-bool done = false;
-
- while(!done){
- if(string(fcn_for_unary_op[i]) == string("END")){
- done = true;
- break;
- }
- if(string(fcn_for_unary_op[i]) == op){
- return string(fcn_for_unary_op[i+1]);
- }
- i++;
- }
- fprintf(stderr,"INTERNAL ERROR, operator %s not found in unary_nic_fcn\n",op.c_str());
- return string("ERROR");
-}
-
-
-
-
-// Generate code that makes reference
-// to the tuple, and not to any aggregates.
-static string generate_nic_se_code(scalarexp_t *se,
- map<string, string> &constants,
- int ©_var_cnt,
- set<string> &no_copy_vars,
- string *retvar, int lr,
- gb_table *gbt ){
-
- string ret = "";
- string l,cid;
- data_type *ldt, *rdt;
- int o;
- vector<scalarexp_t *> operands;
- string lvar, rvar;
- int gbref;
-
- string op = se->get_op();
-//printf("op_type=%d op=%s\n",se->get_operator_type(),op.c_str());
-
- switch(se->get_operator_type()){
- case SE_LITERAL:
- l = se->get_literal()->to_query_string();
- if(constants.count(l)){
- cid = constants[l];
- }else{
- cid = "constant"+int_to_string(constants.size());
- constants[cid] = l;
- }
- *retvar = cid;
- if(lr == LEFT){
- *retvar = "copyvar_"+int_to_string(copy_var_cnt);
- copy_var_cnt++;
- ret += "load_with_copy("+*retvar+","+cid+")\n";
- }
- return(ret);
- case SE_PARAM:
- fprintf(stderr,"INTERNAL ERROR, param ref'd in generate_nic_se_code\n");
- *retvar = "error";
- return("ERROR in generate_nic_se_code");
- case SE_UNARY_OP:
- ret += generate_nic_se_code(se->get_left_se(),
- constants, copy_var_cnt, no_copy_vars, &lvar,LEFT,gbt);
- ret += unary_nic_fcn(op)+"("+lvar+")\n";
- *retvar = lvar;
- return(ret);
- case SE_BINARY_OP:
- ret += generate_nic_se_code(se->get_left_se(),
- constants, copy_var_cnt, no_copy_vars, &lvar,LEFT,gbt);
- ret += generate_nic_se_code(se->get_right_se(),
- constants, copy_var_cnt, no_copy_vars, &rvar,RIGHT,gbt);
- ret += nic_fcn(op)+"("+lvar+","+rvar+")\n";
- *retvar = lvar;
-//printf("op %s; lvar=%s, rvar=%s, retvar=%s\n",op.c_str(), lvar.c_str(), rvar.c_str(), retvar->c_str());
- return(ret);
- case SE_COLREF:
- if(se->is_gb()){
- gbref = se->get_gb_ref();
-/*
- if(gbt->get_reftype(gbref) != GBVAR_COLREF){
- fprintf(stderr,"INTERNAL ERROR, non-colref gbvar in generate_nic_se_code\n");
- exit(1);
- }
-*/
- ret = generate_nic_se_code(gbt->get_def(gbref),constants,copy_var_cnt, no_copy_vars, &lvar,LEFT,gbt);
- *retvar = lvar;
- return ret;
- }
- if(lr == LEFT){
- *retvar = "copyvar_"+int_to_string(copy_var_cnt);
- copy_var_cnt++;
- ret += "load_with_copy("+*retvar+","+se->get_colref()->get_field()+")\n";
- }else{
- *retvar = "nocopyvar_"+se->get_colref()->get_field();
- if(no_copy_vars.count(*retvar) == 0){
- no_copy_vars.insert(*retvar);
- ret += "load("+*retvar+","+se->get_colref()->get_field()+")\n";
- }
- }
- return ret;
-
- case SE_FUNC:
- fprintf(stderr,"CONFIG ERROR, fcn reference in generate_nic_se_code, not yet implemented.\n");
- *retvar = "error";
- return(ret);
- default:
- fprintf(stderr,"INTERNAL ERROR in generate_nic_se_code (lfta), line %d, character %d: unknown operator type %d\n",
- se->get_lineno(), se->get_charno(),se->get_operator_type());
- *retvar = "error";
- return("ERROR in generate_nic_se_code");
- }
-}
-
-
-static string generate_nic_predicate_code(predicate_t *pr,
- map<string, string> &constants,
- int ©_var_cnt,
- set<string> &no_copy_vars,
- string *retvar, gb_table *gbt ){
- string ret;
- vector<literal_t *> litv;
- int i;
- data_type *ldt, *rdt;
- vector<scalarexp_t *> op_list;
- int o;
- string lvar, rvar;
- string l,cid;
- string op = pr->get_op();
-
- switch(pr->get_operator_type()){
- case PRED_IN:
- fprintf(stderr,"CONFIG ERROR: IN not supported in generate_nic_predicate_code\n");
- *retvar = "error";
- return("ERROR in generate_nic_predicate_code");
-
- case PRED_COMPARE:
- ret += generate_nic_se_code(pr->get_left_se(),
- constants, copy_var_cnt, no_copy_vars, &lvar,LEFT,gbt);
- ret += generate_nic_se_code(pr->get_right_se(),
- constants, copy_var_cnt, no_copy_vars, &rvar,RIGHT,gbt);
- ret += nic_fcn(op)+"("+lvar+","+rvar+")\n";
- *retvar = lvar;
- return(ret);
- case PRED_UNARY_OP:
- ret += generate_nic_predicate_code(pr->get_left_pr(),
- constants, copy_var_cnt, no_copy_vars, &lvar,gbt);
- ret += unary_nic_fcn(op)+"("+lvar+")\n";
- *retvar = lvar;
- return(ret);
- case PRED_BINARY_OP:
- ret += generate_nic_predicate_code(pr->get_left_pr(),
- constants, copy_var_cnt, no_copy_vars, &lvar,gbt);
- ret += generate_nic_predicate_code(pr->get_right_pr(),
- constants, copy_var_cnt, no_copy_vars, &rvar,gbt);
- ret += nic_fcn(op)+"("+lvar+","+rvar+")\n";
- *retvar = lvar;
- return(ret);
- case PRED_FUNC:
- fprintf(stderr,"CONFIG ERROR, fcn reference in generate_nic_pred_code, not yet implemented.\n");
- *retvar = "error";
- return(ret);
- ret += " )";
- return(ret);
- default:
- fprintf(stderr,"INTERNAL ERROR in generate_predicate_nic_code, line %d, character %d, unknown predicate operator type %d\n",
- pr->get_lineno(), pr->get_charno(), pr->get_operator_type() );
- return("ERROR in generate_nic_predicate_code");
- }
-}
-
-
-bool se_is_nic_safe(scalarexp_t *se, nic_property *nicp, gb_table *gbt){
- string dts, colname;
- bool rs, ls;
- int gbref;
-
- switch(se->get_operator_type()){
- case SE_LITERAL:
- dts = se->get_data_type()->get_type_str();
- if(nicp->legal_type(dts))
- return true;
- return false;
- break;
- case SE_PARAM:
- return false;
- break;
- case SE_UNARY_OP:
- if(!se_is_nic_safe(se->get_left_se(), nicp, gbt)) return false;
- return(nicp->legal_unary_op(se->get_op()));
- break;
- case SE_BINARY_OP:
- if(!se_is_nic_safe(se->get_left_se(), nicp, gbt)) return false;
- if(!se_is_nic_safe(se->get_right_se(), nicp, gbt)) return false;
- return(nicp->legal_binary_op(se->get_op()));
- break;
- case SE_COLREF:
- if(se->is_gb()){
- gbref = se->get_gb_ref();
-/*
- if(gbt->get_reftype(gbref) != GBVAR_COLREF){
- return false;
- }
-*/
- return se_is_nic_safe(gbt->get_def(gbref),nicp,gbt);
- }
- dts = se->get_data_type()->get_type_str();
- if(! nicp->legal_type(dts))
- return false;
- colname = se->get_colref()->get_field();
- if(! nicp->illegal_field(colname))
- return true;
- return false;
- break;
- case SE_FUNC:
- return false;
- default:
- return false;
- }
-
- return false;
-}
-
-
-bool pr_is_nic_safe(predicate_t *pr, nic_property *nicp, gb_table *gbt){
- string dts, colname;
- bool rs, ls;
- switch(pr->get_operator_type()){
- case PRED_IN:
- return false;
- case PRED_COMPARE:
- if(!se_is_nic_safe(pr->get_left_se(), nicp, gbt)) return false;
- if(!se_is_nic_safe(pr->get_right_se(), nicp, gbt)) return false;
- return(nicp->legal_binary_op(pr->get_op()));
- case PRED_UNARY_OP:
- if(!pr_is_nic_safe(pr->get_left_pr(),nicp, gbt)) return false;
- return(nicp->legal_unary_op(pr->get_op()));
- case PRED_BINARY_OP:
- if(!pr_is_nic_safe(pr->get_left_pr(),nicp, gbt)) return false;
- if(!pr_is_nic_safe(pr->get_right_pr(),nicp, gbt)) return false;
- return(nicp->legal_binary_op(pr->get_op()));
- case PRED_FUNC:
- return false;
- default:
- return false;
- }
-
- return false;
-}
-
-
-void gather_nicsafe_cols(scalarexp_t *se, vector<string> &cols, nic_property *nicp, gb_table *gbt){
- int i, gbref;
- string colname;
- vector<scalarexp_t *> operands;
-
- switch(se->get_operator_type()){
- case SE_LITERAL:
- case SE_PARAM:
- return;
- case SE_UNARY_OP:
- gather_nicsafe_cols(se->get_left_se(),cols,nicp, gbt);
- return;
- case SE_BINARY_OP:
- gather_nicsafe_cols(se->get_left_se(),cols,nicp, gbt);
- gather_nicsafe_cols(se->get_right_se(),cols,nicp, gbt);
- return;
- case SE_COLREF:
- if(se->is_gb()){
- gbref = se->get_gb_ref();
- return gather_nicsafe_cols(gbt->get_def(gbref),cols,nicp, gbt);
- }
- colname = se->get_colref()->get_field();
- if(! nicp->illegal_field(colname)){
- for(i=0;i<cols.size();++i){
- if(colname == cols[i])
- break;
- }
- if(i==cols.size())
- cols.push_back(colname);
- }
- return;
- case SE_FUNC:
- operands = se->get_operands();
- for(i=0;i<operands.size();++i)
- gather_nicsafe_cols(operands[i],cols,nicp,gbt);
- return;
- default:
- return;
- }
- return;
-}
-
-void gather_nicsafe_cols(predicate_t *pr, vector<string> &cols, nic_property *nicp, gb_table *gbt){
- string dts, colname;
- bool rs, ls;
- vector<scalarexp_t *> operands;
- int i;
-
- switch(pr->get_operator_type()){
- case PRED_IN:
- gather_nicsafe_cols(pr->get_left_se(), cols, nicp, gbt);
- return ;
- case PRED_COMPARE:
- gather_nicsafe_cols(pr->get_left_se(), cols, nicp, gbt);
- gather_nicsafe_cols(pr->get_right_se(), cols, nicp, gbt);
- return;
- case PRED_UNARY_OP:
- gather_nicsafe_cols(pr->get_left_pr(),cols, nicp, gbt);
- return;
- case PRED_BINARY_OP:
- gather_nicsafe_cols(pr->get_left_pr(),cols, nicp, gbt);
- gather_nicsafe_cols(pr->get_right_pr(),cols, nicp, gbt);
- return;
- case PRED_FUNC:
- operands = pr->get_op_list();
- for(i=0;i<operands.size();++i)
- gather_nicsafe_cols(operands[i],cols,nicp, gbt);
- return ;
- default:
- return ;
- }
-
- return ;
-}
-
-
-string generate_nic_code(vector<stream_query *> lftas, nic_property *nicp){
- int i,p,s,g;
- string ret = "";
- string vars = "";
- gb_table *gbtbl;
-
- bool packed_return = false;
-
- if(nicp->option_exists("Return")){
- if(nicp->option_value("Return") == "Packed"){
-//printf("val of Return is %s\n",nicp->option_value("Return").c_str());
- packed_return = true;
- }else{
- fprintf(stderr,"Warning, nic option value of Return=%s is not recognized, ignoring\n",nicp->option_value("Return").c_str());
- }
- }
-
- vector<vector<predicate_t *> > nicsafe_preds;
- vector<predicate_t *> empty_list;
- for(i=0;i<lftas.size();i++){
- qp_node *qpn = lftas[i]->get_query_head();
- if(qpn->node_type() == "sgah_qpn"){
- gbtbl = ((sgah_qpn *)(qpn))->get_gb_tbl();
- }else{
- gbtbl = NULL;
- }
- nicsafe_preds.push_back(empty_list);
- vector<cnf_elem *> lfta_cnfs = qpn->get_filter_clause();
- for(p=0;p<lfta_cnfs.size();++p){
- if(pr_is_nic_safe(lfta_cnfs[p]->pr,nicp,gbtbl)){
- nicsafe_preds[i].push_back(lfta_cnfs[p]->pr);
- }
- }
- }
-
- map<string, string> consts;
- int n_copyvar = 0;
- set<string> nocopy_vars;
- string retvar;
-
- if(packed_return){
-//printf("dping packed return\n");
- for(i=0;i<lftas.size();++i){
- qp_node *qpn = lftas[i]->get_query_head();
- ret += "comment( lfta "+qpn->get_node_name() + " )\n";
- if(qpn->node_type() == "sgah_qpn"){
- gbtbl = ((sgah_qpn *)(qpn))->get_gb_tbl();
- }else{
- gbtbl = NULL;
- }
- ret += "\nlabel(lfta"+int_to_string(i)+")\n";
- for(p=0;p<nicsafe_preds[i].size();++p){
- ret += generate_nic_predicate_code(nicsafe_preds[i][p],
- consts, n_copyvar, nocopy_vars, &retvar, gbtbl);
- ret += "jump_if_zero("+retvar+",lfta"+int_to_string(i+1)+")\n";
- }
- vector<scalarexp_t *> se_list;
- if(qpn->node_type() == "sgah_qpn"){
- se_list =((sgah_qpn *)(qpn))->get_select_se_list();
- }else{
- se_list =((spx_qpn *)(qpn))->get_select_se_list();
- }
-
- vector<string> refd_cols;
- for(s=0;s<se_list.size();++s){
- gather_nicsafe_cols(se_list[s],refd_cols, nicp, gbtbl);
- }
- vector<cnf_elem *> lfta_cnfs = qpn->get_where_clause();
- for(p=0;p<lfta_cnfs.size();++p){
- gather_nicsafe_cols(lfta_cnfs[p]->pr,refd_cols, nicp, gbtbl);
- }
- if(gbtbl){
- for(g=0;g<gbtbl->size();++g){
-//printf("gathering gbvar %d\n",g);
- gather_nicsafe_cols(gbtbl->get_def(g),refd_cols, nicp, gbtbl);
- }
- }
- sort(refd_cols.begin(), refd_cols.end());
-
- ret += "pack_and_send(const_id"+int_to_string(i);
- consts["const_id"+int_to_string(i)] = int_to_string(lftas[i]->get_gid());
- for(s=0;s<refd_cols.size();++s){
- ret += ",";
- ret += refd_cols[s];
- }
- ret += ")\n\n";
- }
- ret += "\nlabel(lfta"+int_to_string(i)+")\n";
- }else{
- for(i=0;i<lftas.size();++i){
- qp_node *qpn = lftas[i]->get_query_head();
- ret += "comment( lfta "+qpn->get_node_name() + " )\n";
- if(qpn->node_type() == "sgah_qpn"){
- gbtbl = ((sgah_qpn *)(qpn))->get_gb_tbl();
- }else{
- gbtbl = NULL;
- }
- ret += "\nlabel(lfta"+int_to_string(i)+")\n";
- for(p=0;p<nicsafe_preds[i].size();++p){
- ret += generate_nic_predicate_code(nicsafe_preds[i][p],
- consts, n_copyvar, nocopy_vars, &retvar, gbtbl);
- if(p<nicsafe_preds[i].size()-1){
- ret += "jump_if_zero("+retvar+",lfta"+int_to_string(i+1)+")\n\n";
- }else{
- ret += "jump_if_notzero("+retvar+",pass)\n\n";
- }
- }
- }
- ret += "label(pass)\n";
- ret += "send_packet()\n";
- ret += "\nlabel(lfta"+int_to_string(i)+")\n";
- }
- ret += "label(exit)\n";
- ret += "exit()\n";
-
- map<string, string>::iterator mssi;
- for(mssi=consts.begin();mssi!=consts.end();++mssi){
- vars += "constant( "+(*mssi).first+" , "+(*mssi).second+")\n";
- }
- for(i=0;i<n_copyvar;++i){
- vars += "variable( copyvar_"+int_to_string(i)+" )\n";
- }
- set<string>::iterator ssi;
- for(ssi=nocopy_vars.begin(); ssi!=nocopy_vars.end(); ++ssi){
- vars += "variable( "+(*ssi)+" )\n";
- }
-
- ret = "BEGIN\n"+vars + "\n"+ret + "END\n";
-
- return ret;
-
-}
-
-
+/* ------------------------------------------------\r
+Copyright 2014 AT&T Intellectual Property\r
+ Licensed under the Apache License, Version 2.0 (the "License");\r
+ you may not use this file except in compliance with the License.\r
+ You may obtain a copy of the License at\r
+\r
+ http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+ Unless required by applicable law or agreed to in writing, software\r
+ distributed under the License is distributed on an "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ See the License for the specific language governing permissions and\r
+ limitations under the License.\r
+ ------------------------------------------- */\r
+\r
+#include <string>\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <algorithm>\r
+\r
+#include "parse_fta.h"\r
+#include "parse_schema.h"\r
+#include "analyze_fta.h"\r
+#include "generate_utils.h"\r
+#include "query_plan.h"\r
+#include "generate_nic_code.h"\r
+#include"analyze_fta.h"\r
+\r
+#define LEFT 1\r
+#define RIGHT 2\r
+\r
+using namespace std;\r
+\r
+static const char *fcn_for_op[] = {\r
+ "+", "plus",\r
+ "-", "minus",\r
+ "|", "bitwise_or",\r
+ "*", "multiply",\r
+ "/", "divide",\r
+ "&", "bitwise_and",\r
+ "%", "modulo",\r
+ ">>", "shift_right",\r
+ "<<", "shift_left",\r
+ "AND", "AND",\r
+ "OR", "OR",\r
+ "=", "equal",\r
+ ">", "greater",\r
+ "<", "less",\r
+ ">=", "greater_equal",\r
+ "<=", "less_equal",\r
+ "<>", "not_equal",\r
+ "END"\r
+};\r
+\r
+static const char *fcn_for_unary_op[]= {\r
+ "+", "unary_plus",\r
+ "-", "unary_minus",\r
+ "!", "integer_not",\r
+ "~", "bitwise_not",\r
+ "NOT", "logical_not",\r
+ "END"\r
+};\r
+\r
+static string nic_fcn(string op){\r
+int i = 0;\r
+bool done = false;\r
+\r
+ while(!done){\r
+ if(string(fcn_for_op[i]) == string("END")){\r
+ done = true;\r
+ break;\r
+ }\r
+ if(string(fcn_for_op[i]) == op){\r
+ return string(fcn_for_op[i+1]);\r
+ }\r
+ i++;\r
+ }\r
+ fprintf(stderr,"INTERNAL ERROR, operator %s not found in nic_fcn\n",op.c_str());\r
+ return string("ERROR");\r
+}\r
+\r
+\r
+static string unary_nic_fcn(string op){\r
+int i = 0;\r
+bool done = false;\r
+\r
+ while(!done){\r
+ if(string(fcn_for_unary_op[i]) == string("END")){\r
+ done = true;\r
+ break;\r
+ }\r
+ if(string(fcn_for_unary_op[i]) == op){\r
+ return string(fcn_for_unary_op[i+1]);\r
+ }\r
+ i++;\r
+ }\r
+ fprintf(stderr,"INTERNAL ERROR, operator %s not found in unary_nic_fcn\n",op.c_str());\r
+ return string("ERROR");\r
+}\r
+\r
+\r
+\r
+\r
+// Generate code that makes reference\r
+// to the tuple, and not to any aggregates.\r
+static string generate_nic_se_code(scalarexp_t *se,\r
+ map<string, string> &constants,\r
+ int ©_var_cnt,\r
+ set<string> &no_copy_vars,\r
+ string *retvar, int lr,\r
+ gb_table *gbt ){\r
+\r
+ string ret = "";\r
+ string l,cid;\r
+ data_type *ldt, *rdt;\r
+ int o;\r
+ vector<scalarexp_t *> operands;\r
+ string lvar, rvar;\r
+ int gbref;\r
+\r
+ string op = se->get_op();\r
+//printf("op_type=%d op=%s\n",se->get_operator_type(),op.c_str());\r
+\r
+ switch(se->get_operator_type()){\r
+ case SE_LITERAL:\r
+ l = se->get_literal()->to_query_string();\r
+ if(constants.count(l)){\r
+ cid = constants[l];\r
+ }else{\r
+ cid = "constant"+int_to_string(constants.size());\r
+ constants[cid] = l;\r
+ }\r
+ *retvar = cid;\r
+ if(lr == LEFT){\r
+ *retvar = "copyvar_"+int_to_string(copy_var_cnt);\r
+ copy_var_cnt++;\r
+ ret += "load_with_copy("+*retvar+","+cid+")\n";\r
+ }\r
+ return(ret);\r
+ case SE_PARAM:\r
+ fprintf(stderr,"INTERNAL ERROR, param ref'd in generate_nic_se_code\n");\r
+ *retvar = "error";\r
+ return("ERROR in generate_nic_se_code");\r
+ case SE_UNARY_OP:\r
+ ret += generate_nic_se_code(se->get_left_se(),\r
+ constants, copy_var_cnt, no_copy_vars, &lvar,LEFT,gbt);\r
+ ret += unary_nic_fcn(op)+"("+lvar+")\n";\r
+ *retvar = lvar;\r
+ return(ret);\r
+ case SE_BINARY_OP:\r
+ ret += generate_nic_se_code(se->get_left_se(),\r
+ constants, copy_var_cnt, no_copy_vars, &lvar,LEFT,gbt);\r
+ ret += generate_nic_se_code(se->get_right_se(),\r
+ constants, copy_var_cnt, no_copy_vars, &rvar,RIGHT,gbt);\r
+ ret += nic_fcn(op)+"("+lvar+","+rvar+")\n";\r
+ *retvar = lvar;\r
+//printf("op %s; lvar=%s, rvar=%s, retvar=%s\n",op.c_str(), lvar.c_str(), rvar.c_str(), retvar->c_str());\r
+ return(ret);\r
+ case SE_COLREF:\r
+ if(se->is_gb()){\r
+ gbref = se->get_gb_ref();\r
+/*\r
+ if(gbt->get_reftype(gbref) != GBVAR_COLREF){\r
+ fprintf(stderr,"INTERNAL ERROR, non-colref gbvar in generate_nic_se_code\n");\r
+ exit(1);\r
+ }\r
+*/\r
+ ret = generate_nic_se_code(gbt->get_def(gbref),constants,copy_var_cnt, no_copy_vars, &lvar,LEFT,gbt);\r
+ *retvar = lvar;\r
+ return ret;\r
+ }\r
+ if(lr == LEFT){\r
+ *retvar = "copyvar_"+int_to_string(copy_var_cnt);\r
+ copy_var_cnt++;\r
+ ret += "load_with_copy("+*retvar+","+se->get_colref()->get_field()+")\n";\r
+ }else{\r
+ *retvar = "nocopyvar_"+se->get_colref()->get_field();\r
+ if(no_copy_vars.count(*retvar) == 0){\r
+ no_copy_vars.insert(*retvar);\r
+ ret += "load("+*retvar+","+se->get_colref()->get_field()+")\n";\r
+ }\r
+ }\r
+ return ret;\r
+\r
+ case SE_FUNC:\r
+ fprintf(stderr,"CONFIG ERROR, fcn reference in generate_nic_se_code, not yet implemented.\n");\r
+ *retvar = "error";\r
+ return(ret);\r
+ default:\r
+ fprintf(stderr,"INTERNAL ERROR in generate_nic_se_code (lfta), line %d, character %d: unknown operator type %d\n",\r
+ se->get_lineno(), se->get_charno(),se->get_operator_type());\r
+ *retvar = "error";\r
+ return("ERROR in generate_nic_se_code");\r
+ }\r
+}\r
+\r
+\r
+static string generate_nic_predicate_code(predicate_t *pr,\r
+ map<string, string> &constants,\r
+ int ©_var_cnt,\r
+ set<string> &no_copy_vars,\r
+ string *retvar, gb_table *gbt ){\r
+ string ret;\r
+ vector<literal_t *> litv;\r
+ int i;\r
+ data_type *ldt, *rdt;\r
+ vector<scalarexp_t *> op_list;\r
+ int o;\r
+ string lvar, rvar;\r
+ string l,cid;\r
+ string op = pr->get_op();\r
+\r
+ switch(pr->get_operator_type()){\r
+ case PRED_IN:\r
+ fprintf(stderr,"CONFIG ERROR: IN not supported in generate_nic_predicate_code\n");\r
+ *retvar = "error";\r
+ return("ERROR in generate_nic_predicate_code");\r
+\r
+ case PRED_COMPARE:\r
+ ret += generate_nic_se_code(pr->get_left_se(),\r
+ constants, copy_var_cnt, no_copy_vars, &lvar,LEFT,gbt);\r
+ ret += generate_nic_se_code(pr->get_right_se(),\r
+ constants, copy_var_cnt, no_copy_vars, &rvar,RIGHT,gbt);\r
+ ret += nic_fcn(op)+"("+lvar+","+rvar+")\n";\r
+ *retvar = lvar;\r
+ return(ret);\r
+ case PRED_UNARY_OP:\r
+ ret += generate_nic_predicate_code(pr->get_left_pr(),\r
+ constants, copy_var_cnt, no_copy_vars, &lvar,gbt);\r
+ ret += unary_nic_fcn(op)+"("+lvar+")\n";\r
+ *retvar = lvar;\r
+ return(ret);\r
+ case PRED_BINARY_OP:\r
+ ret += generate_nic_predicate_code(pr->get_left_pr(),\r
+ constants, copy_var_cnt, no_copy_vars, &lvar,gbt);\r
+ ret += generate_nic_predicate_code(pr->get_right_pr(),\r
+ constants, copy_var_cnt, no_copy_vars, &rvar,gbt);\r
+ ret += nic_fcn(op)+"("+lvar+","+rvar+")\n";\r
+ *retvar = lvar;\r
+ return(ret);\r
+ case PRED_FUNC:\r
+ fprintf(stderr,"CONFIG ERROR, fcn reference in generate_nic_pred_code, not yet implemented.\n");\r
+ *retvar = "error";\r
+ return(ret);\r
+ ret += " )";\r
+ return(ret);\r
+ default:\r
+ fprintf(stderr,"INTERNAL ERROR in generate_predicate_nic_code, line %d, character %d, unknown predicate operator type %d\n",\r
+ pr->get_lineno(), pr->get_charno(), pr->get_operator_type() );\r
+ return("ERROR in generate_nic_predicate_code");\r
+ }\r
+}\r
+\r
+\r
+bool se_is_nic_safe(scalarexp_t *se, nic_property *nicp, gb_table *gbt){\r
+ string dts, colname;\r
+ bool rs, ls;\r
+ int gbref;\r
+\r
+ switch(se->get_operator_type()){\r
+ case SE_LITERAL:\r
+ dts = se->get_data_type()->get_type_str();\r
+ if(nicp->legal_type(dts))\r
+ return true;\r
+ return false;\r
+ break;\r
+ case SE_PARAM:\r
+ return false;\r
+ break;\r
+ case SE_UNARY_OP:\r
+ if(!se_is_nic_safe(se->get_left_se(), nicp, gbt)) return false;\r
+ return(nicp->legal_unary_op(se->get_op()));\r
+ break;\r
+ case SE_BINARY_OP:\r
+ if(!se_is_nic_safe(se->get_left_se(), nicp, gbt)) return false;\r
+ if(!se_is_nic_safe(se->get_right_se(), nicp, gbt)) return false;\r
+ return(nicp->legal_binary_op(se->get_op()));\r
+ break;\r
+ case SE_COLREF:\r
+ if(se->is_gb()){\r
+ gbref = se->get_gb_ref();\r
+/*\r
+ if(gbt->get_reftype(gbref) != GBVAR_COLREF){\r
+ return false;\r
+ }\r
+*/\r
+ return se_is_nic_safe(gbt->get_def(gbref),nicp,gbt);\r
+ }\r
+ dts = se->get_data_type()->get_type_str();\r
+ if(! nicp->legal_type(dts))\r
+ return false;\r
+ colname = se->get_colref()->get_field();\r
+ if(! nicp->illegal_field(colname))\r
+ return true;\r
+ return false;\r
+ break;\r
+ case SE_FUNC:\r
+ return false;\r
+ default:\r
+ return false;\r
+ }\r
+\r
+ return false;\r
+}\r
+\r
+\r
+bool pr_is_nic_safe(predicate_t *pr, nic_property *nicp, gb_table *gbt){\r
+ string dts, colname;\r
+ bool rs, ls;\r
+ switch(pr->get_operator_type()){\r
+ case PRED_IN:\r
+ return false;\r
+ case PRED_COMPARE:\r
+ if(!se_is_nic_safe(pr->get_left_se(), nicp, gbt)) return false;\r
+ if(!se_is_nic_safe(pr->get_right_se(), nicp, gbt)) return false;\r
+ return(nicp->legal_binary_op(pr->get_op()));\r
+ case PRED_UNARY_OP:\r
+ if(!pr_is_nic_safe(pr->get_left_pr(),nicp, gbt)) return false;\r
+ return(nicp->legal_unary_op(pr->get_op()));\r
+ case PRED_BINARY_OP:\r
+ if(!pr_is_nic_safe(pr->get_left_pr(),nicp, gbt)) return false;\r
+ if(!pr_is_nic_safe(pr->get_right_pr(),nicp, gbt)) return false;\r
+ return(nicp->legal_binary_op(pr->get_op()));\r
+ case PRED_FUNC:\r
+ return false;\r
+ default:\r
+ return false;\r
+ }\r
+\r
+ return false;\r
+}\r
+\r
+\r
+void gather_nicsafe_cols(scalarexp_t *se, vector<string> &cols, nic_property *nicp, gb_table *gbt){\r
+ int i, gbref;\r
+ string colname;\r
+ vector<scalarexp_t *> operands;\r
+\r
+ switch(se->get_operator_type()){\r
+ case SE_LITERAL:\r
+ case SE_PARAM:\r
+ return;\r
+ case SE_UNARY_OP:\r
+ gather_nicsafe_cols(se->get_left_se(),cols,nicp, gbt);\r
+ return;\r
+ case SE_BINARY_OP:\r
+ gather_nicsafe_cols(se->get_left_se(),cols,nicp, gbt);\r
+ gather_nicsafe_cols(se->get_right_se(),cols,nicp, gbt);\r
+ return;\r
+ case SE_COLREF:\r
+ if(se->is_gb()){\r
+ gbref = se->get_gb_ref();\r
+ return gather_nicsafe_cols(gbt->get_def(gbref),cols,nicp, gbt);\r
+ }\r
+ colname = se->get_colref()->get_field();\r
+ if(! nicp->illegal_field(colname)){\r
+ for(i=0;i<cols.size();++i){\r
+ if(colname == cols[i])\r
+ break;\r
+ }\r
+ if(i==cols.size())\r
+ cols.push_back(colname);\r
+ }\r
+ return;\r
+ case SE_FUNC:\r
+ operands = se->get_operands();\r
+ for(i=0;i<operands.size();++i)\r
+ gather_nicsafe_cols(operands[i],cols,nicp,gbt);\r
+ return;\r
+ default:\r
+ return;\r
+ }\r
+ return;\r
+}\r
+\r
+void gather_nicsafe_cols(predicate_t *pr, vector<string> &cols, nic_property *nicp, gb_table *gbt){\r
+ string dts, colname;\r
+ bool rs, ls;\r
+ vector<scalarexp_t *> operands;\r
+ int i;\r
+\r
+ switch(pr->get_operator_type()){\r
+ case PRED_IN:\r
+ gather_nicsafe_cols(pr->get_left_se(), cols, nicp, gbt);\r
+ return ;\r
+ case PRED_COMPARE:\r
+ gather_nicsafe_cols(pr->get_left_se(), cols, nicp, gbt);\r
+ gather_nicsafe_cols(pr->get_right_se(), cols, nicp, gbt);\r
+ return;\r
+ case PRED_UNARY_OP:\r
+ gather_nicsafe_cols(pr->get_left_pr(),cols, nicp, gbt);\r
+ return;\r
+ case PRED_BINARY_OP:\r
+ gather_nicsafe_cols(pr->get_left_pr(),cols, nicp, gbt);\r
+ gather_nicsafe_cols(pr->get_right_pr(),cols, nicp, gbt);\r
+ return;\r
+ case PRED_FUNC:\r
+ operands = pr->get_op_list();\r
+ for(i=0;i<operands.size();++i)\r
+ gather_nicsafe_cols(operands[i],cols,nicp, gbt);\r
+ return ;\r
+ default:\r
+ return ;\r
+ }\r
+\r
+ return ;\r
+}\r
+\r
+\r
+string generate_nic_code(vector<stream_query *> lftas, nic_property *nicp){\r
+ int i,p,s,g;\r
+ string ret = "";\r
+ string vars = "";\r
+ gb_table *gbtbl;\r
+\r
+ bool packed_return = false;\r
+\r
+ if(nicp->option_exists("Return")){\r
+ if(nicp->option_value("Return") == "Packed"){\r
+//printf("val of Return is %s\n",nicp->option_value("Return").c_str());\r
+ packed_return = true;\r
+ }else{\r
+ fprintf(stderr,"Warning, nic option value of Return=%s is not recognized, ignoring\n",nicp->option_value("Return").c_str());\r
+ }\r
+ }\r
+\r
+ vector<vector<predicate_t *> > nicsafe_preds;\r
+ vector<predicate_t *> empty_list;\r
+ for(i=0;i<lftas.size();i++){\r
+ qp_node *qpn = lftas[i]->get_query_head();\r
+ if(qpn->node_type() == "sgah_qpn"){\r
+ gbtbl = ((sgah_qpn *)(qpn))->get_gb_tbl();\r
+ }else{\r
+ gbtbl = NULL;\r
+ }\r
+ nicsafe_preds.push_back(empty_list);\r
+ vector<cnf_elem *> lfta_cnfs = qpn->get_filter_clause();\r
+ for(p=0;p<lfta_cnfs.size();++p){\r
+ if(pr_is_nic_safe(lfta_cnfs[p]->pr,nicp,gbtbl)){\r
+ nicsafe_preds[i].push_back(lfta_cnfs[p]->pr);\r
+ }\r
+ }\r
+ }\r
+\r
+ map<string, string> consts;\r
+ int n_copyvar = 0;\r
+ set<string> nocopy_vars;\r
+ string retvar;\r
+\r
+ if(packed_return){\r
+//printf("dping packed return\n");\r
+ for(i=0;i<lftas.size();++i){\r
+ qp_node *qpn = lftas[i]->get_query_head();\r
+ ret += "comment( lfta "+qpn->get_node_name() + " )\n";\r
+ if(qpn->node_type() == "sgah_qpn"){\r
+ gbtbl = ((sgah_qpn *)(qpn))->get_gb_tbl();\r
+ }else{\r
+ gbtbl = NULL;\r
+ }\r
+ ret += "\nlabel(lfta"+int_to_string(i)+")\n";\r
+ for(p=0;p<nicsafe_preds[i].size();++p){\r
+ ret += generate_nic_predicate_code(nicsafe_preds[i][p],\r
+ consts, n_copyvar, nocopy_vars, &retvar, gbtbl);\r
+ ret += "jump_if_zero("+retvar+",lfta"+int_to_string(i+1)+")\n";\r
+ }\r
+ vector<scalarexp_t *> se_list;\r
+ if(qpn->node_type() == "sgah_qpn"){\r
+ se_list =((sgah_qpn *)(qpn))->get_select_se_list();\r
+ }else{\r
+ se_list =((spx_qpn *)(qpn))->get_select_se_list();\r
+ }\r
+\r
+ vector<string> refd_cols;\r
+ for(s=0;s<se_list.size();++s){\r
+ gather_nicsafe_cols(se_list[s],refd_cols, nicp, gbtbl);\r
+ }\r
+ vector<cnf_elem *> lfta_cnfs = qpn->get_where_clause();\r
+ for(p=0;p<lfta_cnfs.size();++p){\r
+ gather_nicsafe_cols(lfta_cnfs[p]->pr,refd_cols, nicp, gbtbl);\r
+ }\r
+ if(gbtbl){\r
+ for(g=0;g<gbtbl->size();++g){\r
+//printf("gathering gbvar %d\n",g);\r
+ gather_nicsafe_cols(gbtbl->get_def(g),refd_cols, nicp, gbtbl);\r
+ }\r
+ }\r
+ sort(refd_cols.begin(), refd_cols.end());\r
+\r
+ ret += "pack_and_send(const_id"+int_to_string(i);\r
+ consts["const_id"+int_to_string(i)] = int_to_string(lftas[i]->get_gid());\r
+ for(s=0;s<refd_cols.size();++s){\r
+ ret += ",";\r
+ ret += refd_cols[s];\r
+ }\r
+ ret += ")\n\n";\r
+ }\r
+ ret += "\nlabel(lfta"+int_to_string(i)+")\n";\r
+ }else{\r
+ for(i=0;i<lftas.size();++i){\r
+ qp_node *qpn = lftas[i]->get_query_head();\r
+ ret += "comment( lfta "+qpn->get_node_name() + " )\n";\r
+ if(qpn->node_type() == "sgah_qpn"){\r
+ gbtbl = ((sgah_qpn *)(qpn))->get_gb_tbl();\r
+ }else{\r
+ gbtbl = NULL;\r
+ }\r
+ ret += "\nlabel(lfta"+int_to_string(i)+")\n";\r
+ for(p=0;p<nicsafe_preds[i].size();++p){\r
+ ret += generate_nic_predicate_code(nicsafe_preds[i][p],\r
+ consts, n_copyvar, nocopy_vars, &retvar, gbtbl);\r
+ if(p<nicsafe_preds[i].size()-1){\r
+ ret += "jump_if_zero("+retvar+",lfta"+int_to_string(i+1)+")\n\n";\r
+ }else{\r
+ ret += "jump_if_notzero("+retvar+",pass)\n\n";\r
+ }\r
+ }\r
+ }\r
+ ret += "label(pass)\n";\r
+ ret += "send_packet()\n";\r
+ ret += "\nlabel(lfta"+int_to_string(i)+")\n";\r
+ }\r
+ ret += "label(exit)\n";\r
+ ret += "exit()\n";\r
+\r
+ map<string, string>::iterator mssi;\r
+ for(mssi=consts.begin();mssi!=consts.end();++mssi){\r
+ vars += "constant( "+(*mssi).first+" , "+(*mssi).second+")\n";\r
+ }\r
+ for(i=0;i<n_copyvar;++i){\r
+ vars += "variable( copyvar_"+int_to_string(i)+" )\n";\r
+ }\r
+ set<string>::iterator ssi;\r
+ for(ssi=nocopy_vars.begin(); ssi!=nocopy_vars.end(); ++ssi){\r
+ vars += "variable( "+(*ssi)+" )\n";\r
+ }\r
+\r
+ ret = "BEGIN\n"+vars + "\n"+ret + "END\n";\r
+\r
+ return ret;\r
+\r
+}\r
+\r
+\r