-/* ------------------------------------------------\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
+/* ------------------------------------------------
+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;
+
+}
+
+