Added quantiling UDAFs
[com/gs-lite.git] / src / ftacmp / generate_nic_code.cc
index 77de31a..efd9eca 100644 (file)
-/* ------------------------------------------------
-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 &copy_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 &copy_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 &copy_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 &copy_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