-/* ------------------------------------------------
-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"parse_partn.h"
-#include "parse_schema.h"
-#include"analyze_fta.h"
-
-
-using namespace std;
-
-
-int find_field(scalarexp_t *se, string &fld){
- vector<scalarexp_t *> operands;
- int o,ret=0;
-
- switch(se->get_operator_type()){
- case SE_LITERAL:
- return 0;
- case SE_PARAM:
- case SE_IFACE_PARAM:
- return 100; // force failure, but no error message.
- case SE_UNARY_OP:
- return find_field(se->get_left_se(), fld);
- case SE_BINARY_OP:
- return find_field(se->get_left_se(), fld)+find_field(se->get_right_se(), fld);
- case SE_COLREF:
- fld = se->get_colref()->get_field();
- return 1;
- case SE_AGGR_STAR:
- case SE_AGGR_SE:
-// Should be no aggregates
- return 0;
- case SE_FUNC:
- return 100; // force failure, but no error message.
- default:
- fprintf(stderr,"INTERNAL ERROR in find_field, unknown operator type %d\n", se->get_operator_type());
- return(-100);
- }
- return(-100);
-}
-
-
-int partn_def_t::verify(table_list *schema, string &err_msg){
- if(schema->find_tbl(protocol) < 0){
- err_msg += "ERROR, partition definition "+name+" uses source "+protocol+", but its not in the schema.\n";
- return 1;
- }
- if(schema->get_schema_type(schema->find_tbl(protocol)) != PROTOCOL_SCHEMA){
- err_msg += "ERROR, partition definition "+name+" uses source "+protocol+", but its not a PROTOCOL.\n";
- return 1;
- }
-
- tablevar_t *fme = new tablevar_t(protocol.c_str());
- tablevar_list_t fm(fme);
-
-// Validate the SE and assign data types.
- int i;
- int retval = 0;
- for(i=0;i<se_list.size();++i){
- int ret = verify_colref(se_list[i],&fm,schema,NULL);
- if(ret){
- err_msg += "ERROR validating entry "+int_to_string(i)+" of partition definition "+name+".\n";
- retval=1;
- }
- }
- if(retval)
- return 1;
-
-// Ensure that the data type is an integer type.
- for(i=0;i<se_list.size();++i){
- data_type *dt = se_list[i]->get_data_type();
- string type_s = dt->get_type_str();
- if(! ( type_s=="UINT" || type_s=="INT" || type_s=="ULLONG" || type_s=="LLONG") ){
- err_msg += "ERROR, entry "+int_to_string(i)+" of partition definition "+name+" has type "+type_s+", but it must be one of UINT, INT, ULLONG, LLONG.\n";
- retval=1;
- }
- }
- if(retval)
- return 1;
-
-// Ensure that each SE ref's a field only once.
- for(i=0;i<se_list.size();++i){
- string fld;
- int ret = find_field(se_list[i],fld);
- if(ret<0){
- err_msg += "ERROR validating entry "+int_to_string(i)+" of partition definition "+name+".\n";
- retval=1;
- }
- if(ret!=1){
- err_msg += "ERROR validating entry "+int_to_string(i)+" of partition definition "+name+": the expression references a field "+int_to_string(ret)+" times, but it should reference a field exactly once.\n";
- retval=1;
- field_list.push_back("");
- }else{
- field_list.push_back(fld);
- }
- }
- if(retval)
- return 1;
-
- return 0;
-
-}
-
-void find_colref_path(scalarexp_t *se, vector<scalarexp_t *> &se_stack){
- vector<scalarexp_t *> operands;
- int o,ret=0;
-
- switch(se->get_operator_type()){
- case SE_LITERAL:
- case SE_PARAM:
- case SE_IFACE_PARAM:
- return ;
- case SE_UNARY_OP:
- find_colref_path(se->get_left_se(), se_stack);
- if(se_stack.size()>0)
- se_stack.push_back(se);
- return;
- case SE_BINARY_OP:
- find_colref_path(se->get_left_se(), se_stack);
- if(se_stack.size()>0){
- se_stack.push_back(se);
- return;
- }
- find_colref_path(se->get_right_se(), se_stack);
- if(se_stack.size()>0)
- se_stack.push_back(se);
- return;
- case SE_COLREF:
- se_stack.push_back(se);
- return;
- case SE_AGGR_STAR:
- case SE_AGGR_SE:
-// Should be no aggregates
- return;
- case SE_FUNC:
- operands = se->get_operands();
- for(o=0;o<operands.size();o++){
- find_colref_path(operands[o], se_stack);
- if(se_stack.size()>0){
- se_stack.push_back(se);
- return;
- }
- }
- return;
- default:
- fprintf(stderr,"INTERNAL ERROR in find_colref_path, unknown operator type %d\n", se->get_operator_type());
- return;
- }
- return;
-}
-
-struct param_int{
- union{
- long int li;
- unsigned long int uli;
- long long int lli;
- unsigned long long int ulli;
- } v;
- dtype d;
-
- void convert_to_final() {};
-
- void load_val(dtype dt, const char *val){
- d=dt;
- switch(dt){
- case u_int_t:
- sscanf(val,"%llu",&(v.ulli));
- break;
- case int_t:
- sscanf(val,"%lld",&(v.lli));
- break;
- case u_llong_t:
- sscanf(val,"%llu",&(v.ulli));
- break;
- case llong_t:
- sscanf(val,"%lld",&(v.lli));
- break;
- default:
- fprintf(stderr,"INTERNAL ERROR, data type %d passed to param_int::load_val.\n",dt);
- exit(1);
- }
- }
-
- void add(dtype dt, param_int &l, param_int &r){
- d=dt;
- if(dt==int_t || dt==llong_t)
- if(l.d==int_t || l.d==llong_t)
- if(r.d==int_t || r.d==llong_t) v.lli = l.v.lli+r.v.lli; else v.lli = l.v.lli+r.v.ulli;
- else
- if(r.d==int_t || r.d==llong_t) v.lli = l.v.ulli+r.v.lli; else v.lli = l.v.ulli+r.v.ulli;
- else
- if(l.d==int_t || l.d==llong_t)
- if(r.d==int_t || r.d==llong_t) v.ulli = l.v.lli+r.v.lli; else v.ulli = l.v.lli+r.v.ulli;
- else
- if(r.d==int_t || r.d==llong_t) v.ulli = l.v.ulli+r.v.lli; else v.ulli = l.v.ulli+r.v.ulli;
- }
- void subtract(dtype dt, param_int &l, param_int &r){
- d=dt;
- if(dt==int_t || dt==llong_t)
- if(l.d==int_t || l.d==llong_t)
- if(r.d==int_t || r.d==llong_t) v.lli = l.v.lli-r.v.lli; else v.lli = l.v.lli-r.v.ulli;
- else
- if(r.d==int_t || r.d==llong_t) v.lli = l.v.ulli-r.v.lli; else v.lli = l.v.ulli-r.v.ulli;
- else
- if(l.d==int_t || l.d==llong_t)
- if(r.d==int_t || r.d==llong_t) v.ulli = l.v.lli-r.v.lli; else v.ulli = l.v.lli-r.v.ulli;
- else
- if(r.d==int_t || r.d==llong_t) v.ulli = l.v.ulli-r.v.lli; else v.ulli = l.v.ulli-r.v.ulli;
- }
- void mult(dtype dt, param_int &l, param_int &r){
- d=dt;
- if(dt==int_t || dt==llong_t)
- if(l.d==int_t || l.d==llong_t)
- if(r.d==int_t || r.d==llong_t) v.lli = l.v.lli*r.v.lli; else v.lli = l.v.lli*r.v.ulli;
- else
- if(r.d==int_t || r.d==llong_t) v.lli = l.v.ulli*r.v.lli; else v.lli = l.v.ulli*r.v.ulli;
- else
- if(l.d==int_t || l.d==llong_t)
- if(r.d==int_t || r.d==llong_t) v.ulli = l.v.lli*r.v.lli; else v.ulli = l.v.lli*r.v.ulli;
- else
- if(r.d==int_t || r.d==llong_t) v.ulli = l.v.ulli*r.v.lli; else v.ulli = l.v.ulli*r.v.ulli;
- }
- void div(dtype dt, param_int &l, param_int &r){
- d=dt;
- if(dt==int_t || dt==llong_t)
- if(l.d==int_t || l.d==llong_t)
- if(r.d==int_t || r.d==llong_t) v.lli = l.v.lli/r.v.lli; else v.lli = l.v.lli/r.v.ulli;
- else
- if(r.d==int_t || r.d==llong_t) v.lli = l.v.ulli/r.v.lli; else v.lli = l.v.ulli/r.v.ulli;
- else
- if(l.d==int_t || l.d==llong_t)
- if(r.d==int_t || r.d==llong_t) v.ulli = l.v.lli/r.v.lli; else v.ulli = l.v.lli/r.v.ulli;
- else
- if(r.d==int_t || r.d==llong_t) v.ulli = l.v.ulli/r.v.lli; else v.ulli = l.v.ulli/r.v.ulli;
- }
- void bit_and(dtype dt, param_int &l, param_int &r){
- d=dt;
- if(dt==int_t || dt==llong_t)
- if(l.d==int_t || l.d==llong_t)
- if(r.d==int_t || r.d==llong_t) v.lli = l.v.lli&r.v.lli; else v.lli = l.v.lli&r.v.ulli;
- else
- if(r.d==int_t || r.d==llong_t) v.lli = l.v.ulli&r.v.lli; else v.lli = l.v.ulli&r.v.ulli;
- else
- if(l.d==int_t || l.d==llong_t)
- if(r.d==int_t || r.d==llong_t) v.ulli = l.v.lli&r.v.lli; else v.ulli = l.v.lli&r.v.ulli;
- else
- if(r.d==int_t || r.d==llong_t) v.ulli = l.v.ulli&r.v.lli; else v.ulli = l.v.ulli&r.v.ulli;
- }
- void bit_or(dtype dt, param_int &l, param_int &r){
- d=dt;
- if(dt==int_t || dt==llong_t)
- if(l.d==int_t || l.d==llong_t)
- if(r.d==int_t || r.d==llong_t) v.lli = l.v.lli|r.v.lli; else v.lli = l.v.lli|r.v.ulli;
- else
- if(r.d==int_t || r.d==llong_t) v.lli = l.v.ulli|r.v.lli; else v.lli = l.v.ulli|r.v.ulli;
- else
- if(l.d==int_t || l.d==llong_t)
- if(r.d==int_t || r.d==llong_t) v.ulli = l.v.lli|r.v.lli; else v.ulli = l.v.lli|r.v.ulli;
- else
- if(r.d==int_t || r.d==llong_t) v.ulli = l.v.ulli|r.v.lli; else v.ulli = l.v.ulli|r.v.ulli;
- }
- void modulo(dtype dt, param_int &l, param_int &r){
- d=dt;
- if(dt==int_t || dt==llong_t)
- if(l.d==int_t || l.d==llong_t)
- if(r.d==int_t || r.d==llong_t) v.lli = l.v.lli%r.v.lli; else v.lli = l.v.lli%r.v.ulli;
- else
- if(r.d==int_t || r.d==llong_t) v.lli = l.v.ulli%r.v.lli; else v.lli = l.v.ulli%r.v.ulli;
- else
- if(l.d==int_t || l.d==llong_t)
- if(r.d==int_t || r.d==llong_t) v.ulli = l.v.lli%r.v.lli; else v.ulli = l.v.lli%r.v.ulli;
- else
- if(r.d==int_t || r.d==llong_t) v.ulli = l.v.ulli%r.v.lli; else v.ulli = l.v.ulli%r.v.ulli;
- }
- void shift_left(dtype dt, param_int &l, param_int &r){
- d=dt;
- if(dt==int_t || dt==llong_t)
- if(l.d==int_t || l.d==llong_t)
- if(r.d==int_t || r.d==llong_t) v.lli = l.v.lli<<r.v.lli; else v.lli = l.v.lli<<r.v.ulli;
- else
- if(r.d==int_t || r.d==llong_t) v.lli = l.v.ulli<<r.v.lli; else v.lli = l.v.ulli<<r.v.ulli;
- else
- if(l.d==int_t || l.d==llong_t)
- if(r.d==int_t || r.d==llong_t) v.ulli = l.v.lli<<r.v.lli; else v.ulli = l.v.lli<<r.v.ulli;
- else
- if(r.d==int_t || r.d==llong_t) v.ulli = l.v.ulli<<r.v.lli; else v.ulli = l.v.ulli<<r.v.ulli;
- }
- void shift_right(dtype dt, param_int &l, param_int &r){
- d=dt;
- if(dt==int_t || dt==llong_t)
- if(l.d==int_t || l.d==llong_t)
- if(r.d==int_t || r.d==llong_t) v.lli = l.v.lli>>r.v.lli; else v.lli = l.v.lli>>r.v.ulli;
- else
- if(r.d==int_t || r.d==llong_t) v.lli = l.v.ulli>>r.v.lli; else v.lli = l.v.ulli>>r.v.ulli;
- else
- if(l.d==int_t || l.d==llong_t)
- if(r.d==int_t || r.d==llong_t) v.ulli = l.v.lli>>r.v.lli; else v.ulli = l.v.lli>>r.v.ulli;
- else
- if(r.d==int_t || r.d==llong_t) v.ulli = l.v.ulli>>r.v.lli; else v.ulli = l.v.ulli>>r.v.ulli;
- }
-
- void plus(dtype dt, param_int &l){
- d=dt;
- if(dt==int_t || dt==llong_t)
- if(l.d==int_t || l.d==llong_t)
- v.lli = l.v.ulli;
- else
- v.lli = l.v.lli;
- else
- if(l.d==int_t || l.d==llong_t)
- v.ulli = l.v.ulli;
- else
- v.ulli = l.v.lli;
- }
- void minus(dtype dt, param_int &l){
- d=dt;
- if(dt==int_t || dt==llong_t)
- if(l.d==int_t || l.d==llong_t)
- v.lli = -l.v.ulli;
- else
- v.lli = -l.v.lli;
- else
- if(l.d==int_t || l.d==llong_t)
- v.ulli = -l.v.ulli;
- else
- v.ulli = -l.v.lli;
- }
- void abs_not(dtype dt, param_int &l){
- d=dt;
- if(dt==int_t || dt==llong_t)
- if(l.d==int_t || l.d==llong_t)
- v.lli = !l.v.ulli;
- else
- v.lli = !l.v.lli;
- else
- if(l.d==int_t || l.d==llong_t)
- v.ulli = !l.v.ulli;
- else
- v.ulli = !l.v.lli;
- }
- void bit_not(dtype dt, param_int &l){
- d=dt;
- if(dt==int_t || dt==llong_t)
- if(l.d==int_t || l.d==llong_t)
- v.lli = ~l.v.ulli;
- else
- v.lli = ~l.v.lli;
- else
- if(l.d==int_t || l.d==llong_t)
- v.ulli = ~l.v.ulli;
- else
- v.ulli = ~l.v.lli;
- }
-};
-
-
-bool int_operand_divides(param_int &lp, param_int &rp){
- if( (lp.d==int_t || lp.d==llong_t)){
- if(lp.v.lli < 0)
- lp.v.ulli = -lp.v.lli;
- else
- lp.v.ulli = lp.v.lli;
- }
- if( (rp.d==int_t || rp.d==llong_t)){
- if(rp.v.lli < 0)
- rp.v.ulli = -rp.v.lli;
- else
- rp.v.ulli = rp.v.lli;
- }
- unsigned long long int d = rp.v.ulli / lp.v.ulli;
- unsigned long long int r = rp.v.ulli - d * lp.v.ulli;
- return d==0;
-}
-
-bool int_operand_implies(param_int &lp, param_int &rp){
- unsigned long long int d = (lp.v.ulli & rp.v.ulli) | (!lp.v.ulli);
- return (~d)==0;
-}
-
-
-
-
-void extract_param_int(scalarexp_t *se, param_int &p_int) {
-param_int lp, rp;
-string op_str;
-dtype dt = se->get_data_type()->get_type();
- switch(se->get_operator_type()){
- case SE_LITERAL:
- p_int.load_val(se->get_data_type()->get_type(),se->to_string().c_str());
- return;
- case SE_UNARY_OP:
- extract_param_int(se->get_left_se(), lp);
- op_str = se->get_op();
- if(op_str=="+") p_int.plus(dt,lp);
- if(op_str=="-") p_int.minus(dt,lp);
- if(op_str=="!") p_int.abs_not(dt,lp);
- if(op_str=="~") p_int.bit_not(dt,lp);
- return;
- case SE_BINARY_OP:
- extract_param_int(se->get_left_se(), lp);
- extract_param_int(se->get_right_se(), rp);
- op_str = se->get_op();
- if(op_str=="+") p_int.add(dt,lp,rp);
- if(op_str=="-") p_int.subtract(dt,lp,rp);
- if(op_str=="*") p_int.mult(dt,lp,rp);
- if(op_str=="/") p_int.div(dt,lp,rp);
- if(op_str=="&") p_int.bit_and(dt,lp,rp);
- if(op_str=="|") p_int.bit_or(dt,lp,rp);
- if(op_str=="%") p_int.modulo(dt,lp,rp);
- if(op_str=="<<") p_int.shift_left(dt,lp,rp);
- if(op_str==">>") p_int.shift_right(dt,lp,rp);
- return;
- default:
- fprintf(stderr,"INTERNAL ERROR in find_field, invalid operator type %d\n", se->get_operator_type());
- exit(1);
- }
- return;
-
-}
-
-
-void get_int_operand(scalarexp_t *parent, scalarexp_t *child, param_int &p_int){
- if(parent->get_operator_type() != SE_BINARY_OP){
- fprintf(stderr,"INTERNAL ERROR, operator type %d in get_int_operand.\n",
-parent->get_operator_type());
- exit(1);
- }
- if(parent->get_right_se() == child){
- extract_param_int(parent->get_left_se(), p_int);
- p_int.convert_to_final();
- }else{
- extract_param_int(parent->get_right_se(), p_int);
- p_int.convert_to_final();
- }
-}
-
-
-bool partition_compatible(scalarexp_t *pse, scalarexp_t *gse){
- vector<scalarexp_t *> pstack, gstack;
-
- find_colref_path(pse, pstack);
- find_colref_path(gse, gstack);
-
- int ppos=0, gpos=0;
- string p_op, g_op;
- param_int p_int, g_int;
-
- while(ppos<pstack.size()-1 && gpos<gstack.size()-1){
-
-// first, try to raise both stack pointers.
- if(ppos<pstack.size()-1 && gpos<gstack.size()-1){
- p_op = pstack[ppos+1]->get_op();
- g_op = gstack[gpos+1]->get_op();
- if(p_op==g_op){
- if(p_op=="/"){
- get_int_operand(pstack[ppos+1],pstack[ppos],p_int);
- get_int_operand(gstack[gpos+1],gstack[gpos],g_int);
- if(int_operand_divides(g_int, p_int)){
- ppos++;
- gpos++;
- continue;
- }else{
- return false;
- }
- }
- if(p_op=="&"){
- get_int_operand(pstack[ppos+1],pstack[ppos],p_int);
- get_int_operand(gstack[gpos+1],gstack[gpos],g_int);
- if(int_operand_implies(p_int, g_int)){
- ppos++;
- gpos++;
- continue;
- }else{
- return false;
- }
- }
- if(p_op=="|"){
- get_int_operand(pstack[ppos+1],pstack[ppos],p_int);
- get_int_operand(gstack[gpos+1],gstack[gpos],g_int);
- if(int_operand_implies(g_int, p_int)){
- ppos++;
- gpos++;
- continue;
- }else{
- return false;
- }
- }
- }
- }
- if(ppos<pstack.size()-1){
- p_op = pstack[ppos+1]->get_op();
- if(p_op=="+" || p_op=="-" || p_op=="*" || p_op=="/" || p_op=="&" || p_op=="|"){
- ppos++;
- continue;
- }
- }
- if(gpos<gstack.size()-1){
- g_op = gstack[gpos+1]->get_op();
- if(g_op=="+" || g_op=="-" || g_op=="*" || g_op=="/" || g_op=="&" || g_op=="|"){
- gpos++;
- continue;
- }
- }
-
- return false; // no reduction rule applies
- }
-
- return true; // reduced both stacks.
-}
-
-
-bool partn_def_t::is_compatible(gb_table *gb_tbl){
- vector<string> gb_flds;
- int i,p,g;
-
- for(i=0;i<gb_tbl->size();++i){
- string gfld;
- if(find_field(gb_tbl->get_def(i),gfld)==1){
- gb_flds.push_back(gfld);
- }else{
- gb_flds.push_back("");
- }
- }
-
- for(p=p;p<se_list.size();++p){
- for(g=0;g<gb_tbl->size();++g){
- if(partition_compatible(se_list[p], gb_tbl->get_def(g)))
- break;
- }
- if(g==gb_tbl->size()){
- return false;
- }
- }
- return true;
-}
+/* ------------------------------------------------\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
+#include"parse_partn.h"\r
+#include "parse_schema.h"\r
+#include"analyze_fta.h"\r
+\r
+\r
+using namespace std;\r
+\r
+\r
+int find_field(scalarexp_t *se, string &fld){\r
+ vector<scalarexp_t *> operands;\r
+ int o,ret=0;\r
+\r
+ switch(se->get_operator_type()){\r
+ case SE_LITERAL:\r
+ return 0;\r
+ case SE_PARAM:\r
+ case SE_IFACE_PARAM:\r
+ return 100; // force failure, but no error message.\r
+ case SE_UNARY_OP:\r
+ return find_field(se->get_left_se(), fld);\r
+ case SE_BINARY_OP:\r
+ return find_field(se->get_left_se(), fld)+find_field(se->get_right_se(), fld);\r
+ case SE_COLREF:\r
+ fld = se->get_colref()->get_field();\r
+ return 1;\r
+ case SE_AGGR_STAR:\r
+ case SE_AGGR_SE:\r
+// Should be no aggregates\r
+ return 0;\r
+ case SE_FUNC:\r
+ return 100; // force failure, but no error message.\r
+ default:\r
+ fprintf(stderr,"INTERNAL ERROR in find_field, unknown operator type %d\n", se->get_operator_type());\r
+ return(-100);\r
+ }\r
+ return(-100);\r
+}\r
+\r
+\r
+int partn_def_t::verify(table_list *schema, string &err_msg){\r
+ if(schema->find_tbl(protocol) < 0){\r
+ err_msg += "ERROR, partition definition "+name+" uses source "+protocol+", but its not in the schema.\n";\r
+ return 1;\r
+ }\r
+ if(schema->get_schema_type(schema->find_tbl(protocol)) != PROTOCOL_SCHEMA){\r
+ err_msg += "ERROR, partition definition "+name+" uses source "+protocol+", but its not a PROTOCOL.\n";\r
+ return 1;\r
+ }\r
+\r
+ tablevar_t *fme = new tablevar_t(protocol.c_str());\r
+ tablevar_list_t fm(fme);\r
+\r
+// Validate the SE and assign data types.\r
+ int i;\r
+ int retval = 0;\r
+ for(i=0;i<se_list.size();++i){\r
+ int ret = verify_colref(se_list[i],&fm,schema,NULL);\r
+ if(ret){\r
+ err_msg += "ERROR validating entry "+int_to_string(i)+" of partition definition "+name+".\n";\r
+ retval=1;\r
+ }\r
+ }\r
+ if(retval)\r
+ return 1;\r
+\r
+// Ensure that the data type is an integer type.\r
+ for(i=0;i<se_list.size();++i){\r
+ data_type *dt = se_list[i]->get_data_type();\r
+ string type_s = dt->get_type_str();\r
+ if(! ( type_s=="UINT" || type_s=="INT" || type_s=="ULLONG" || type_s=="LLONG") ){\r
+ err_msg += "ERROR, entry "+int_to_string(i)+" of partition definition "+name+" has type "+type_s+", but it must be one of UINT, INT, ULLONG, LLONG.\n";\r
+ retval=1;\r
+ }\r
+ }\r
+ if(retval)\r
+ return 1;\r
+\r
+// Ensure that each SE ref's a field only once.\r
+ for(i=0;i<se_list.size();++i){\r
+ string fld;\r
+ int ret = find_field(se_list[i],fld);\r
+ if(ret<0){\r
+ err_msg += "ERROR validating entry "+int_to_string(i)+" of partition definition "+name+".\n";\r
+ retval=1;\r
+ }\r
+ if(ret!=1){\r
+ err_msg += "ERROR validating entry "+int_to_string(i)+" of partition definition "+name+": the expression references a field "+int_to_string(ret)+" times, but it should reference a field exactly once.\n";\r
+ retval=1;\r
+ field_list.push_back("");\r
+ }else{\r
+ field_list.push_back(fld);\r
+ }\r
+ }\r
+ if(retval)\r
+ return 1;\r
+\r
+ return 0;\r
+\r
+}\r
+\r
+void find_colref_path(scalarexp_t *se, vector<scalarexp_t *> &se_stack){\r
+ vector<scalarexp_t *> operands;\r
+ int o,ret=0;\r
+\r
+ switch(se->get_operator_type()){\r
+ case SE_LITERAL:\r
+ case SE_PARAM:\r
+ case SE_IFACE_PARAM:\r
+ return ;\r
+ case SE_UNARY_OP:\r
+ find_colref_path(se->get_left_se(), se_stack);\r
+ if(se_stack.size()>0)\r
+ se_stack.push_back(se);\r
+ return;\r
+ case SE_BINARY_OP:\r
+ find_colref_path(se->get_left_se(), se_stack);\r
+ if(se_stack.size()>0){\r
+ se_stack.push_back(se);\r
+ return;\r
+ }\r
+ find_colref_path(se->get_right_se(), se_stack);\r
+ if(se_stack.size()>0)\r
+ se_stack.push_back(se);\r
+ return;\r
+ case SE_COLREF:\r
+ se_stack.push_back(se);\r
+ return;\r
+ case SE_AGGR_STAR:\r
+ case SE_AGGR_SE:\r
+// Should be no aggregates\r
+ return;\r
+ case SE_FUNC:\r
+ operands = se->get_operands();\r
+ for(o=0;o<operands.size();o++){\r
+ find_colref_path(operands[o], se_stack);\r
+ if(se_stack.size()>0){\r
+ se_stack.push_back(se);\r
+ return;\r
+ }\r
+ }\r
+ return;\r
+ default:\r
+ fprintf(stderr,"INTERNAL ERROR in find_colref_path, unknown operator type %d\n", se->get_operator_type());\r
+ return;\r
+ }\r
+ return;\r
+}\r
+\r
+struct param_int{\r
+ union{\r
+ long int li;\r
+ unsigned long int uli;\r
+ long long int lli;\r
+ unsigned long long int ulli;\r
+ } v;\r
+ dtype d;\r
+\r
+ void convert_to_final() {};\r
+\r
+ void load_val(dtype dt, const char *val){\r
+ d=dt;\r
+ switch(dt){\r
+ case u_int_t:\r
+ sscanf(val,"%llu",&(v.ulli));\r
+ break;\r
+ case int_t:\r
+ sscanf(val,"%lld",&(v.lli));\r
+ break;\r
+ case u_llong_t:\r
+ sscanf(val,"%llu",&(v.ulli));\r
+ break;\r
+ case llong_t:\r
+ sscanf(val,"%lld",&(v.lli));\r
+ break;\r
+ default:\r
+ fprintf(stderr,"INTERNAL ERROR, data type %d passed to param_int::load_val.\n",dt);\r
+ exit(1);\r
+ }\r
+ }\r
+\r
+ void add(dtype dt, param_int &l, param_int &r){\r
+ d=dt;\r
+ if(dt==int_t || dt==llong_t)\r
+ if(l.d==int_t || l.d==llong_t)\r
+ if(r.d==int_t || r.d==llong_t) v.lli = l.v.lli+r.v.lli; else v.lli = l.v.lli+r.v.ulli;\r
+ else\r
+ if(r.d==int_t || r.d==llong_t) v.lli = l.v.ulli+r.v.lli; else v.lli = l.v.ulli+r.v.ulli;\r
+ else\r
+ if(l.d==int_t || l.d==llong_t)\r
+ if(r.d==int_t || r.d==llong_t) v.ulli = l.v.lli+r.v.lli; else v.ulli = l.v.lli+r.v.ulli;\r
+ else\r
+ if(r.d==int_t || r.d==llong_t) v.ulli = l.v.ulli+r.v.lli; else v.ulli = l.v.ulli+r.v.ulli;\r
+ }\r
+ void subtract(dtype dt, param_int &l, param_int &r){\r
+ d=dt;\r
+ if(dt==int_t || dt==llong_t)\r
+ if(l.d==int_t || l.d==llong_t)\r
+ if(r.d==int_t || r.d==llong_t) v.lli = l.v.lli-r.v.lli; else v.lli = l.v.lli-r.v.ulli;\r
+ else\r
+ if(r.d==int_t || r.d==llong_t) v.lli = l.v.ulli-r.v.lli; else v.lli = l.v.ulli-r.v.ulli;\r
+ else\r
+ if(l.d==int_t || l.d==llong_t)\r
+ if(r.d==int_t || r.d==llong_t) v.ulli = l.v.lli-r.v.lli; else v.ulli = l.v.lli-r.v.ulli;\r
+ else\r
+ if(r.d==int_t || r.d==llong_t) v.ulli = l.v.ulli-r.v.lli; else v.ulli = l.v.ulli-r.v.ulli;\r
+ }\r
+ void mult(dtype dt, param_int &l, param_int &r){\r
+ d=dt;\r
+ if(dt==int_t || dt==llong_t)\r
+ if(l.d==int_t || l.d==llong_t)\r
+ if(r.d==int_t || r.d==llong_t) v.lli = l.v.lli*r.v.lli; else v.lli = l.v.lli*r.v.ulli;\r
+ else\r
+ if(r.d==int_t || r.d==llong_t) v.lli = l.v.ulli*r.v.lli; else v.lli = l.v.ulli*r.v.ulli;\r
+ else\r
+ if(l.d==int_t || l.d==llong_t)\r
+ if(r.d==int_t || r.d==llong_t) v.ulli = l.v.lli*r.v.lli; else v.ulli = l.v.lli*r.v.ulli;\r
+ else\r
+ if(r.d==int_t || r.d==llong_t) v.ulli = l.v.ulli*r.v.lli; else v.ulli = l.v.ulli*r.v.ulli;\r
+ }\r
+ void div(dtype dt, param_int &l, param_int &r){\r
+ d=dt;\r
+ if(dt==int_t || dt==llong_t)\r
+ if(l.d==int_t || l.d==llong_t)\r
+ if(r.d==int_t || r.d==llong_t) v.lli = l.v.lli/r.v.lli; else v.lli = l.v.lli/r.v.ulli;\r
+ else\r
+ if(r.d==int_t || r.d==llong_t) v.lli = l.v.ulli/r.v.lli; else v.lli = l.v.ulli/r.v.ulli;\r
+ else\r
+ if(l.d==int_t || l.d==llong_t)\r
+ if(r.d==int_t || r.d==llong_t) v.ulli = l.v.lli/r.v.lli; else v.ulli = l.v.lli/r.v.ulli;\r
+ else\r
+ if(r.d==int_t || r.d==llong_t) v.ulli = l.v.ulli/r.v.lli; else v.ulli = l.v.ulli/r.v.ulli;\r
+ }\r
+ void bit_and(dtype dt, param_int &l, param_int &r){\r
+ d=dt;\r
+ if(dt==int_t || dt==llong_t)\r
+ if(l.d==int_t || l.d==llong_t)\r
+ if(r.d==int_t || r.d==llong_t) v.lli = l.v.lli&r.v.lli; else v.lli = l.v.lli&r.v.ulli;\r
+ else\r
+ if(r.d==int_t || r.d==llong_t) v.lli = l.v.ulli&r.v.lli; else v.lli = l.v.ulli&r.v.ulli;\r
+ else\r
+ if(l.d==int_t || l.d==llong_t)\r
+ if(r.d==int_t || r.d==llong_t) v.ulli = l.v.lli&r.v.lli; else v.ulli = l.v.lli&r.v.ulli;\r
+ else\r
+ if(r.d==int_t || r.d==llong_t) v.ulli = l.v.ulli&r.v.lli; else v.ulli = l.v.ulli&r.v.ulli;\r
+ }\r
+ void bit_or(dtype dt, param_int &l, param_int &r){\r
+ d=dt;\r
+ if(dt==int_t || dt==llong_t)\r
+ if(l.d==int_t || l.d==llong_t)\r
+ if(r.d==int_t || r.d==llong_t) v.lli = l.v.lli|r.v.lli; else v.lli = l.v.lli|r.v.ulli;\r
+ else\r
+ if(r.d==int_t || r.d==llong_t) v.lli = l.v.ulli|r.v.lli; else v.lli = l.v.ulli|r.v.ulli;\r
+ else\r
+ if(l.d==int_t || l.d==llong_t)\r
+ if(r.d==int_t || r.d==llong_t) v.ulli = l.v.lli|r.v.lli; else v.ulli = l.v.lli|r.v.ulli;\r
+ else\r
+ if(r.d==int_t || r.d==llong_t) v.ulli = l.v.ulli|r.v.lli; else v.ulli = l.v.ulli|r.v.ulli;\r
+ }\r
+ void modulo(dtype dt, param_int &l, param_int &r){\r
+ d=dt;\r
+ if(dt==int_t || dt==llong_t)\r
+ if(l.d==int_t || l.d==llong_t)\r
+ if(r.d==int_t || r.d==llong_t) v.lli = l.v.lli%r.v.lli; else v.lli = l.v.lli%r.v.ulli;\r
+ else\r
+ if(r.d==int_t || r.d==llong_t) v.lli = l.v.ulli%r.v.lli; else v.lli = l.v.ulli%r.v.ulli;\r
+ else\r
+ if(l.d==int_t || l.d==llong_t)\r
+ if(r.d==int_t || r.d==llong_t) v.ulli = l.v.lli%r.v.lli; else v.ulli = l.v.lli%r.v.ulli;\r
+ else\r
+ if(r.d==int_t || r.d==llong_t) v.ulli = l.v.ulli%r.v.lli; else v.ulli = l.v.ulli%r.v.ulli;\r
+ }\r
+ void shift_left(dtype dt, param_int &l, param_int &r){\r
+ d=dt;\r
+ if(dt==int_t || dt==llong_t)\r
+ if(l.d==int_t || l.d==llong_t)\r
+ if(r.d==int_t || r.d==llong_t) v.lli = l.v.lli<<r.v.lli; else v.lli = l.v.lli<<r.v.ulli;\r
+ else\r
+ if(r.d==int_t || r.d==llong_t) v.lli = l.v.ulli<<r.v.lli; else v.lli = l.v.ulli<<r.v.ulli;\r
+ else\r
+ if(l.d==int_t || l.d==llong_t)\r
+ if(r.d==int_t || r.d==llong_t) v.ulli = l.v.lli<<r.v.lli; else v.ulli = l.v.lli<<r.v.ulli;\r
+ else\r
+ if(r.d==int_t || r.d==llong_t) v.ulli = l.v.ulli<<r.v.lli; else v.ulli = l.v.ulli<<r.v.ulli;\r
+ }\r
+ void shift_right(dtype dt, param_int &l, param_int &r){\r
+ d=dt;\r
+ if(dt==int_t || dt==llong_t)\r
+ if(l.d==int_t || l.d==llong_t)\r
+ if(r.d==int_t || r.d==llong_t) v.lli = l.v.lli>>r.v.lli; else v.lli = l.v.lli>>r.v.ulli;\r
+ else\r
+ if(r.d==int_t || r.d==llong_t) v.lli = l.v.ulli>>r.v.lli; else v.lli = l.v.ulli>>r.v.ulli;\r
+ else\r
+ if(l.d==int_t || l.d==llong_t)\r
+ if(r.d==int_t || r.d==llong_t) v.ulli = l.v.lli>>r.v.lli; else v.ulli = l.v.lli>>r.v.ulli;\r
+ else\r
+ if(r.d==int_t || r.d==llong_t) v.ulli = l.v.ulli>>r.v.lli; else v.ulli = l.v.ulli>>r.v.ulli;\r
+ }\r
+\r
+ void plus(dtype dt, param_int &l){\r
+ d=dt;\r
+ if(dt==int_t || dt==llong_t)\r
+ if(l.d==int_t || l.d==llong_t)\r
+ v.lli = l.v.ulli;\r
+ else\r
+ v.lli = l.v.lli;\r
+ else\r
+ if(l.d==int_t || l.d==llong_t)\r
+ v.ulli = l.v.ulli;\r
+ else\r
+ v.ulli = l.v.lli;\r
+ }\r
+ void minus(dtype dt, param_int &l){\r
+ d=dt;\r
+ if(dt==int_t || dt==llong_t)\r
+ if(l.d==int_t || l.d==llong_t)\r
+ v.lli = -l.v.ulli;\r
+ else\r
+ v.lli = -l.v.lli;\r
+ else\r
+ if(l.d==int_t || l.d==llong_t)\r
+ v.ulli = -l.v.ulli;\r
+ else\r
+ v.ulli = -l.v.lli;\r
+ }\r
+ void abs_not(dtype dt, param_int &l){\r
+ d=dt;\r
+ if(dt==int_t || dt==llong_t)\r
+ if(l.d==int_t || l.d==llong_t)\r
+ v.lli = !l.v.ulli;\r
+ else\r
+ v.lli = !l.v.lli;\r
+ else\r
+ if(l.d==int_t || l.d==llong_t)\r
+ v.ulli = !l.v.ulli;\r
+ else\r
+ v.ulli = !l.v.lli;\r
+ }\r
+ void bit_not(dtype dt, param_int &l){\r
+ d=dt;\r
+ if(dt==int_t || dt==llong_t)\r
+ if(l.d==int_t || l.d==llong_t)\r
+ v.lli = ~l.v.ulli;\r
+ else\r
+ v.lli = ~l.v.lli;\r
+ else\r
+ if(l.d==int_t || l.d==llong_t)\r
+ v.ulli = ~l.v.ulli;\r
+ else\r
+ v.ulli = ~l.v.lli;\r
+ }\r
+};\r
+\r
+\r
+bool int_operand_divides(param_int &lp, param_int &rp){\r
+ if( (lp.d==int_t || lp.d==llong_t)){\r
+ if(lp.v.lli < 0)\r
+ lp.v.ulli = -lp.v.lli;\r
+ else\r
+ lp.v.ulli = lp.v.lli;\r
+ }\r
+ if( (rp.d==int_t || rp.d==llong_t)){\r
+ if(rp.v.lli < 0)\r
+ rp.v.ulli = -rp.v.lli;\r
+ else\r
+ rp.v.ulli = rp.v.lli;\r
+ }\r
+ unsigned long long int d = rp.v.ulli / lp.v.ulli;\r
+ unsigned long long int r = rp.v.ulli - d * lp.v.ulli;\r
+ return d==0;\r
+}\r
+\r
+bool int_operand_implies(param_int &lp, param_int &rp){\r
+ unsigned long long int d = (lp.v.ulli & rp.v.ulli) | (!lp.v.ulli);\r
+ return (~d)==0;\r
+}\r
+\r
+\r
+\r
+\r
+void extract_param_int(scalarexp_t *se, param_int &p_int) {\r
+param_int lp, rp;\r
+string op_str;\r
+dtype dt = se->get_data_type()->get_type();\r
+ switch(se->get_operator_type()){\r
+ case SE_LITERAL:\r
+ p_int.load_val(se->get_data_type()->get_type(),se->to_string().c_str());\r
+ return;\r
+ case SE_UNARY_OP:\r
+ extract_param_int(se->get_left_se(), lp);\r
+ op_str = se->get_op();\r
+ if(op_str=="+") p_int.plus(dt,lp);\r
+ if(op_str=="-") p_int.minus(dt,lp);\r
+ if(op_str=="!") p_int.abs_not(dt,lp);\r
+ if(op_str=="~") p_int.bit_not(dt,lp);\r
+ return;\r
+ case SE_BINARY_OP:\r
+ extract_param_int(se->get_left_se(), lp);\r
+ extract_param_int(se->get_right_se(), rp);\r
+ op_str = se->get_op();\r
+ if(op_str=="+") p_int.add(dt,lp,rp);\r
+ if(op_str=="-") p_int.subtract(dt,lp,rp);\r
+ if(op_str=="*") p_int.mult(dt,lp,rp);\r
+ if(op_str=="/") p_int.div(dt,lp,rp);\r
+ if(op_str=="&") p_int.bit_and(dt,lp,rp);\r
+ if(op_str=="|") p_int.bit_or(dt,lp,rp);\r
+ if(op_str=="%") p_int.modulo(dt,lp,rp);\r
+ if(op_str=="<<") p_int.shift_left(dt,lp,rp);\r
+ if(op_str==">>") p_int.shift_right(dt,lp,rp);\r
+ return;\r
+ default:\r
+ fprintf(stderr,"INTERNAL ERROR in find_field, invalid operator type %d\n", se->get_operator_type());\r
+ exit(1);\r
+ }\r
+ return;\r
+\r
+}\r
+\r
+\r
+void get_int_operand(scalarexp_t *parent, scalarexp_t *child, param_int &p_int){\r
+ if(parent->get_operator_type() != SE_BINARY_OP){\r
+ fprintf(stderr,"INTERNAL ERROR, operator type %d in get_int_operand.\n",\r
+parent->get_operator_type());\r
+ exit(1);\r
+ }\r
+ if(parent->get_right_se() == child){\r
+ extract_param_int(parent->get_left_se(), p_int);\r
+ p_int.convert_to_final();\r
+ }else{\r
+ extract_param_int(parent->get_right_se(), p_int);\r
+ p_int.convert_to_final();\r
+ }\r
+}\r
+\r
+\r
+bool partition_compatible(scalarexp_t *pse, scalarexp_t *gse){\r
+ vector<scalarexp_t *> pstack, gstack;\r
+\r
+ find_colref_path(pse, pstack);\r
+ find_colref_path(gse, gstack);\r
+\r
+ int ppos=0, gpos=0;\r
+ string p_op, g_op;\r
+ param_int p_int, g_int;\r
+\r
+ while(ppos<pstack.size()-1 && gpos<gstack.size()-1){\r
+\r
+// first, try to raise both stack pointers.\r
+ if(ppos<pstack.size()-1 && gpos<gstack.size()-1){\r
+ p_op = pstack[ppos+1]->get_op();\r
+ g_op = gstack[gpos+1]->get_op();\r
+ if(p_op==g_op){\r
+ if(p_op=="/"){\r
+ get_int_operand(pstack[ppos+1],pstack[ppos],p_int);\r
+ get_int_operand(gstack[gpos+1],gstack[gpos],g_int);\r
+ if(int_operand_divides(g_int, p_int)){\r
+ ppos++;\r
+ gpos++;\r
+ continue;\r
+ }else{\r
+ return false;\r
+ }\r
+ }\r
+ if(p_op=="&"){\r
+ get_int_operand(pstack[ppos+1],pstack[ppos],p_int);\r
+ get_int_operand(gstack[gpos+1],gstack[gpos],g_int);\r
+ if(int_operand_implies(p_int, g_int)){\r
+ ppos++;\r
+ gpos++;\r
+ continue;\r
+ }else{\r
+ return false;\r
+ }\r
+ }\r
+ if(p_op=="|"){\r
+ get_int_operand(pstack[ppos+1],pstack[ppos],p_int);\r
+ get_int_operand(gstack[gpos+1],gstack[gpos],g_int);\r
+ if(int_operand_implies(g_int, p_int)){\r
+ ppos++;\r
+ gpos++;\r
+ continue;\r
+ }else{\r
+ return false;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ if(ppos<pstack.size()-1){\r
+ p_op = pstack[ppos+1]->get_op();\r
+ if(p_op=="+" || p_op=="-" || p_op=="*" || p_op=="/" || p_op=="&" || p_op=="|"){\r
+ ppos++;\r
+ continue;\r
+ }\r
+ }\r
+ if(gpos<gstack.size()-1){\r
+ g_op = gstack[gpos+1]->get_op();\r
+ if(g_op=="+" || g_op=="-" || g_op=="*" || g_op=="/" || g_op=="&" || g_op=="|"){\r
+ gpos++;\r
+ continue;\r
+ }\r
+ }\r
+\r
+ return false; // no reduction rule applies\r
+ }\r
+\r
+ return true; // reduced both stacks.\r
+}\r
+\r
+\r
+bool partn_def_t::is_compatible(gb_table *gb_tbl){\r
+ vector<string> gb_flds;\r
+ int i,p,g;\r
+\r
+ for(i=0;i<gb_tbl->size();++i){\r
+ string gfld;\r
+ if(find_field(gb_tbl->get_def(i),gfld)==1){\r
+ gb_flds.push_back(gfld);\r
+ }else{\r
+ gb_flds.push_back("");\r
+ }\r
+ }\r
+\r
+ for(p=p;p<se_list.size();++p){\r
+ for(g=0;g<gb_tbl->size();++g){\r
+ if(partition_compatible(se_list[p], gb_tbl->get_def(g)))\r
+ break;\r
+ }\r
+ if(g==gb_tbl->size()){\r
+ return false;\r
+ }\r
+ }\r
+ return true;\r
+}\r