/* * the transformqual() transform the ast(the parsetree) to expression tree */ QNode * transformqual(Node *node,LogicalOperator* child) { // memalign(cacheline_size,1024) if(node==NULL) return NULL; switch(node->type) { case t_expr_cal: { Expr_cal * calnode=(Expr_cal *)node; if(strcmp(calnode->sign,"ANDOP")==0)//now in and the two parameter should be boolean,so the a_type = t_boolean { QNode *lnode=transformqual(calnode->lnext,child); QNode *rnode=transformqual(calnode->rnext,child); QExpr_binary *qcalnode=new QExpr_binary(lnode,rnode,t_boolean,oper_and,t_qexpr_cal,calnode->str); return qcalnode; } else if(strcmp(calnode->sign,"OR")==0)//now in or the two parameter should be boolean,so the a_type = t_boolean { QNode *lnode=transformqual(calnode->lnext,child); QNode *rnode=transformqual(calnode->rnext,child); QExpr_binary *qcalnode=new QExpr_binary(lnode,rnode,t_boolean,oper_or,t_qexpr_cal,calnode->str); return qcalnode; } else if(strcmp(calnode->sign,"+")==0) { QNode *lnode=transformqual(calnode->lnext,child); QNode *rnode=transformqual(calnode->rnext,child); data_type a_type=TypePromotion::arith_type_promotion_map[lnode->actual_type][rnode->actual_type]; QExpr_binary *qcalnode=new QExpr_binary(lnode,rnode,a_type,oper_add,t_qexpr_cal,calnode->str); return qcalnode; } else if(strcmp(calnode->sign,"-")==0) { QNode *lnode=transformqual(calnode->lnext,child); QNode *rnode=transformqual(calnode->rnext,child); data_type a_type=TypePromotion::arith_type_promotion_map[lnode->actual_type][rnode->actual_type]; QExpr_binary *qcalnode=new QExpr_binary(lnode,rnode,a_type,oper_minus,t_qexpr_cal,calnode->str); return qcalnode; } else if(strcmp(calnode->sign,"*")==0) { QNode *lnode=transformqual(calnode->lnext,child); QNode *rnode=transformqual(calnode->rnext,child); data_type a_type=TypePromotion::arith_type_promotion_map[lnode->actual_type][rnode->actual_type]; QExpr_binary *qcalnode=new QExpr_binary(lnode,rnode,a_type,oper_multiply,t_qexpr_cal,calnode->str); return qcalnode; } else if(strcmp(calnode->sign,"/")==0) { QNode *lnode=transformqual(calnode->lnext,child); QNode *rnode=transformqual(calnode->rnext,child); data_type a_type=TypePromotion::arith_type_promotion_map[lnode->actual_type][rnode->actual_type]; QExpr_binary *qcalnode=new QExpr_binary(lnode,rnode,a_type,oper_divide,t_qexpr_cal,calnode->str); return qcalnode; } else if(strcmp(calnode->sign,"%")==0) { QNode *lnode=transformqual(calnode->lnext,child); QNode *rnode=transformqual(calnode->rnext,child); data_type a_type=TypePromotion::arith_type_promotion_map[lnode->actual_type][rnode->actual_type]; QExpr_binary *qcalnode=new QExpr_binary(lnode,rnode,a_type,oper_mod,t_qexpr_cal,calnode->str); return qcalnode; } else if(strcmp(calnode->sign,"LIKE")==0) { QNode *lnode=transformqual(calnode->lnext,child); QNode *rnode=transformqual(calnode->rnext,child); data_type a_type=TypePromotion::arith_type_promotion_map[lnode->actual_type][rnode->actual_type]; QExpr_binary *likenode=new QExpr_binary(lnode,rnode,a_type,oper_like,t_qexpr_cmp,calnode->str); return likenode; } else if(strcmp(calnode->sign,"NLIKE")==0) { QNode *lnode=transformqual(calnode->lnext,child); QNode *rnode=transformqual(calnode->rnext,child); data_type a_type=TypePromotion::arith_type_promotion_map[lnode->actual_type][rnode->actual_type]; QExpr_binary *likenode=new QExpr_binary(lnode,rnode,a_type,oper_not_like,t_qexpr_cmp,calnode->str); return likenode; } else if(strcmp(calnode->sign,"NOT")==0||strcmp(calnode->sign,"!")==0) { QNode *nnode=transformqual(calnode->rnext,child); QExpr_unary *unode=new QExpr_unary(nnode,t_boolean,oper_not,t_qexpr_unary,calnode->str); return unode; } else if(strcmp(calnode->sign,"--")==0) { QNode *nnode=transformqual(calnode->rnext,child); QExpr_unary *unode=new QExpr_unary(nnode,nnode->actual_type,oper_negative,t_qexpr_unary,calnode->str); return unode; } else if(strcmp(calnode->sign,"INVS")==0)//in (2,3),one level list,one comparison parameter { vector<QNode *>lnode,tmp; vector< vector<QNode *> >rnode; lnode.push_back(transformqual(calnode->lnext,child));//only one int index=0; for(Node *tpnode=calnode->rnext;tpnode!=NULL;) { Expr_list *elnode=(Expr_list *)tpnode; tmp.push_back(transformqual(elnode->data,child));//only one column,more rows tpnode=elnode->next; rnode.push_back(tmp); tmp.clear(); } vector<QNode *>cmpnode; for(int i=0;i<lnode.size();i++) { data_type a_type=TypePromotion::arith_type_promotion_map[lnode[i]->actual_type][rnode[0][i]->actual_type]; QExpr_binary *qcalnode=new QExpr_binary(lnode[i],rnode[0][i],a_type,oper_equal,t_qexpr_cmp,"tempnode"); cmpnode.push_back(qcalnode); } QNode *innode=new QExpr_in(cmpnode,rnode,calnode->str); return innode; } else if(strcmp(calnode->sign,"INVM")==0)//in ((2,'a'),(3,'b')),two level list,more comparison parameter { vector<QNode *>lnode,tmp; vector< vector<QNode *> >rnode; for(Node *tpnode=calnode->lnext;tpnode!=NULL;)//more columns { Expr_list *elnode=(Expr_list *)tpnode; lnode.push_back(transformqual(elnode->data,child)); tpnode=elnode->next; } int index=0; for(Node *tpnode=calnode->rnext;tpnode!=NULL;)//more rows { Expr_list *elnode=(Expr_list *)tpnode; for(Node *pnode=elnode->data;pnode!=NULL;)//more columns { Expr_list *enode=(Expr_list *)pnode; tmp.push_back(transformqual(enode->data,child)); pnode=enode->next; } rnode.push_back(tmp); tmp.clear(); index++; tpnode=elnode->next; } vector<QNode *>cmpnode; for(int i=0;i<lnode.size();i++)//more comparisons form one list { data_type a_type=TypePromotion::arith_type_promotion_map[lnode[i]->actual_type][rnode[0][i]->actual_type]; QExpr_binary *qcalnode=new QExpr_binary(lnode[i],rnode[0][i],a_type,oper_equal,t_qexpr_cmp,"tempnode"); cmpnode.push_back(qcalnode); } QNode *innode=new QExpr_in(cmpnode,rnode,calnode->str); return innode; } else if(strcmp(calnode->sign,"CMP")==0) { QNode *lnode=transformqual(calnode->lnext,child); QNode *rnode=transformqual(calnode->rnext,child); data_type a_type=TypePromotion::arith_type_promotion_map[lnode->actual_type][rnode->actual_type]; switch(calnode->cmp) { case 1://"<" { QExpr_binary *qcalnode=new QExpr_binary(lnode,rnode,a_type,oper_less,t_qexpr_cmp,calnode->str); return qcalnode; }break; case 2://">" { QExpr_binary *qcalnode=new QExpr_binary(lnode,rnode,a_type,oper_great,t_qexpr_cmp,calnode->str); return qcalnode; }break; case 3://"<>" { QExpr_binary *qcalnode=new QExpr_binary(lnode,rnode,a_type,oper_not_equal,t_qexpr_cmp,calnode->str); return qcalnode; }break; case 4://"=" { QExpr_binary *qcalnode=new QExpr_binary(lnode,rnode,a_type,oper_equal,t_qexpr_cmp,calnode->str); return qcalnode; }break; case 5://"<=" { QExpr_binary *qcalnode=new QExpr_binary(lnode,rnode,a_type,oper_less_equal,t_qexpr_cmp,calnode->str); return qcalnode; }break; case 6://">=" { QExpr_binary *qcalnode=new QExpr_binary(lnode,rnode,a_type,oper_great_equal,t_qexpr_cmp,calnode->str); return qcalnode; }break; default: { SQLParse_elog("not support now\n"); } } } }break; case t_expr_func: { Expr_func * funcnode=(Expr_func *)node; if(strcmp(funcnode->funname,"CASE3")==0)//no END in CASE...WHEN { vector<QNode *>qual; vector<QNode *>ans; for(Node *tnode=funcnode->parameter1;tnode!=NULL;) { Expr_func *tfnode=(Expr_func *)tnode; assert(strcmp(tfnode->funname,"WHEN2")==0); qual.push_back(transformqual(tfnode->parameter1,child)); ans.push_back(transformqual(tfnode->parameter2,child)); tnode=tfnode->next; } QNode *cwnode=new QExpr_case_when(qual,ans,funcnode->str); return cwnode; } else if(strcmp(funcnode->funname,"CASE4")==0)//now just support |case [when expr then expr]* [else expr] end| { vector<QNode *>qual; vector<QNode *>ans; for(Node *tnode=funcnode->parameter1;tnode!=NULL;) { Expr_func *tfnode=(Expr_func *)tnode; assert(strcmp(tfnode->funname,"WHEN2")==0); qual.push_back(transformqual(tfnode->parameter1,child)); ans.push_back(transformqual(tfnode->parameter2,child)); tnode=tfnode->next; } ans.push_back(transformqual(funcnode->parameter2,child)); QNode *cwnode=new QExpr_case_when(qual,ans,funcnode->str); return cwnode; } else if(strcmp(funcnode->funname,"WHEN1")==0)//no use { } else if(strcmp(funcnode->funname,"WHEN2")==0)//no use { } else if(strcmp(funcnode->funname,"FSUBSTRING0")==0)//TODO the max length is 128,but it may be larger in practice { QNode *node0=transformqual(funcnode->args,child); QNode *node1=transformqual(funcnode->parameter1,child); QNode *node2=new QExpr("128",t_int,"t_const_node");//128 is the size of the qnode->value data_type a_type=t_string; QExpr_ternary *substrnode=new QExpr_ternary(node0,node1,node2,a_type,oper_substring,t_qexpr_ternary,funcnode->str); return substrnode; } else if(strcmp(funcnode->funname,"FSUBSTRING1")==0) { QNode *node0=transformqual(funcnode->args,child); QNode *node1=transformqual(funcnode->parameter1,child); QNode *node2=transformqual(funcnode->parameter2,child); data_type a_type=t_string; QExpr_ternary *substrnode=new QExpr_ternary(node0,node1,node2,a_type,oper_substring,t_qexpr_ternary,funcnode->str); return substrnode; } else if(strcmp(funcnode->funname,"FTRIM0")==0)//both { QNode *lnode=transformqual(funcnode->parameter1,child); QNode *rnode=transformqual(funcnode->parameter2,child); data_type a_type=t_string; QExpr_binary *trimnode=new QExpr_binary(lnode,rnode,a_type,oper_both_trim,t_qexpr_cal,funcnode->str); return trimnode; } else if(strcmp(funcnode->funname,"FTRIM1")==0)//leading { QNode *lnode=transformqual(funcnode->parameter1,child); QNode *rnode=transformqual(funcnode->parameter2,child); data_type a_type=t_string; QExpr_binary *trimnode=new QExpr_binary(lnode,rnode,a_type,oper_leading_trim,t_qexpr_cal,funcnode->str); return trimnode; } else if(strcmp(funcnode->funname,"FTRIM2")==0)//trailing { QNode *lnode=transformqual(funcnode->parameter1,child); QNode *rnode=transformqual(funcnode->parameter2,child); data_type a_type=t_string; QExpr_binary *trimnode=new QExpr_binary(lnode,rnode,a_type,oper_trailing_trim,t_qexpr_cal,funcnode->str); return trimnode; } else if(strcmp(funcnode->funname,"FTRIM3")==0)//both ' ' { QNode *lnode=new QExpr(" ",t_string,"t_const_node");//construct the ' ' const node QNode *rnode=transformqual(funcnode->parameter1,child); data_type a_type=t_string; QExpr_binary *trimnode=new QExpr_binary(lnode,rnode,a_type,oper_both_trim,t_qexpr_cal,funcnode->str); return trimnode; } else if(strcmp(funcnode->funname,"FUPPER")==0) { QNode *nnext=transformqual(funcnode->parameter1,child); data_type a_type=t_string; QExpr_unary *uppernode=new QExpr_unary(nnext,a_type,oper_upper,t_qexpr_unary,funcnode->str); return uppernode; } else if(strcmp(funcnode->funname,"FCAST")==0) { } else if(strcmp(funcnode->funname,"FCOALESCE")==0) { } else if(strcmp(funcnode->funname,"FCOUNTALL")==0)//the agg nodes are changed to QColumns node ,only to get value from tuple is ok { QNode *aggnode=new QColcumns("",funcnode->str,t_u_long,funcnode->str); return aggnode; } else if(strcmp(funcnode->funname,"FCOUNT")==0) { QNode *aggnode=new QColcumns("",funcnode->str,t_u_long,funcnode->str); return aggnode; } else if(strcmp(funcnode->funname,"FSUM")==0) { // QNode *anext=transformqual(funcnode->parameter1,child); data_type a_type=child->GetPlanContext().GetAttribute(string(funcnode->str)).attrType->type; QNode *aggnode=new QColcumns("",funcnode->str,a_type,funcnode->str); return aggnode; } else if(strcmp(funcnode->funname,"FAVG")==0) { // QNode *anext=transformqual(funcnode->parameter1,child); data_type a_type=child->GetPlanContext().GetAttribute(string(funcnode->str)).attrType->type; QNode *aggnode=new QColcumns("",funcnode->str,a_type,funcnode->str); return aggnode; } else if(strcmp(funcnode->funname,"FMIN")==0) { // QNode *anext=transformqual(funcnode->parameter1,child); data_type a_type=child->GetPlanContext().GetAttribute(string(funcnode->str)).attrType->type; QNode *aggnode=new QColcumns("",funcnode->str,a_type,funcnode->str); return aggnode; } else if(strcmp(funcnode->funname,"FMAX")==0) { // QNode *anext=transformqual(funcnode->parameter1,child); data_type a_type=child->GetPlanContext().GetAttribute(string(funcnode->str)).attrType->type; QNode *aggnode=new QColcumns("",funcnode->str,a_type,funcnode->str); return aggnode; } else if(strcmp(funcnode->funname,"BA")==0)//between...and... transform to arg>=param1 and arg<=param2 { QNode *arg=transformqual(funcnode->args,child); QNode *param1=transformqual(funcnode->parameter1,child); QNode *param2=transformqual(funcnode->parameter2,child); data_type a_type=TypePromotion::arith_type_promotion_map[arg->actual_type][param1->actual_type]; QNode *lnext=new QExpr_binary(arg,param1,a_type,oper_great_equal,t_qexpr_cmp,"arg>=parma1"); QNode *rnext=new QExpr_binary(arg,param2,a_type,oper_less_equal,t_qexpr_cmp,"arg<=parma2"); QExpr_binary *banode=new QExpr_binary(lnext,rnext,t_boolean,oper_and,t_qexpr_cal,funcnode->str); return banode; } /* * special case for solving FDATE_ADD and FDATE_SUB * FDATE_ADD(date_str,deta) * the date_str,deta and the return type are all t_string * so take them as string_date_add and string_date_sub * the function above is slow ,so construct special QExpr_date_add_sub node */ else if(strcmp(funcnode->funname,"FDATE_ADD")==0) { QNode *lnext=transformqual(funcnode->args,child); Expr_func *datefunc=(Expr_func *)funcnode->parameter1; QExpr_date_add_sub *date_add; if(strcmp(datefunc->funname,"INTERVAL_DAY")==0) { QNode *rnext=transformqual(datefunc->args,child); date_add=new QExpr_date_add_sub(lnext,rnext,t_date,oper_date_add_day,t_qexpr_date_add_sub,t_date_day,funcnode->str); } else if(strcmp(datefunc->funname,"INTERVAL_WEEK")==0) { QNode *rnext=transformqual(datefunc->args,child); date_add=new QExpr_date_add_sub(lnext,rnext,t_date,oper_date_add_week,t_qexpr_date_add_sub,t_date_week,funcnode->str); } else if(strcmp(datefunc->funname,"INTERVAL_MONTH")==0) { QNode *rnext=transformqual(datefunc->args,child); date_add=new QExpr_date_add_sub(lnext,rnext,t_date,oper_date_add_month,t_qexpr_date_add_sub,t_date_month,funcnode->str); } else if(strcmp(datefunc->funname,"INTERVAL_YEAR")==0) { QNode *rnext=transformqual(datefunc->args,child); date_add=new QExpr_date_add_sub(lnext,rnext,t_date,oper_date_add_year,t_qexpr_date_add_sub,t_date_year,funcnode->str); } else if(strcmp(datefunc->funname,"INTERVAL_QUARTER")==0) { QNode *rnext=transformqual(datefunc->args,child); date_add=new QExpr_date_add_sub(lnext,rnext,t_date,oper_date_add_month,t_qexpr_date_add_sub,t_date_quarter,funcnode->str); } return date_add; } else if(strcmp(funcnode->funname,"FDATE_SUB")==0) { QNode *lnext=transformqual(funcnode->args,child); Expr_func *datefunc=(Expr_func *)funcnode->parameter1; QExpr_date_add_sub *date_sub; if(strcmp(datefunc->funname,"INTERVAL_DAY")==0) { QNode *rnext=transformqual(datefunc->args,child); date_sub=new QExpr_date_add_sub(lnext,rnext,t_date,oper_date_sub_day,t_qexpr_date_add_sub,t_date_day,funcnode->str); } else if(strcmp(datefunc->funname,"INTERVAL_WEEK")==0) { QNode *rnext=transformqual(datefunc->args,child); date_sub=new QExpr_date_add_sub(lnext,rnext,t_date,oper_date_sub_week,t_qexpr_date_add_sub,t_date_week,funcnode->str); } else if(strcmp(datefunc->funname,"INTERVAL_MONTH")==0) { QNode *rnext=transformqual(datefunc->args,child); date_sub=new QExpr_date_add_sub(lnext,rnext,t_date,oper_date_sub_month,t_qexpr_date_add_sub,t_date_month,funcnode->str); } else if(strcmp(datefunc->funname,"INTERVAL_YEAR")==0) { QNode *rnext=transformqual(datefunc->args,child); date_sub=new QExpr_date_add_sub(lnext,rnext,t_date,oper_date_sub_year,t_qexpr_date_add_sub,t_date_year,funcnode->str); } else if(strcmp(datefunc->funname,"INTERVAL_QUARTER")==0) { QNode *rnext=transformqual(datefunc->args,child); date_sub=new QExpr_date_add_sub(lnext,rnext,t_date,oper_date_sub_month,t_qexpr_date_add_sub,t_date_quarter,funcnode->str); } return date_sub; } else { SQLParse_elog("get_a_expression_item: %s is null",funcnode->funname); } }break; case t_name: case t_name_name: { Columns *col=(Columns *)node; // data_type a_type=Environment::getInstance()->getCatalog()->name_to_table[col->parameter1]->getAttribute2(col->parameter2).attrType->type; data_type a_type=child->GetPlanContext().GetAttribute(string(col->parameter2)).attrType->type; if(col->parameter1==NULL)//for temporary variable { col->parameter1=""; } QColcumns *qcol=new QColcumns(col->parameter1,col->parameter2,a_type,col->parameter2); return qcol; }break; case t_stringval: { Expr * exprval=(Expr *)node; QExpr *qexpr=new QExpr(exprval->data,t_string,exprval->data); return qexpr; }break; case t_intnum: { Expr * exprval=(Expr *)node; QExpr *qexpr = NULL; long temp = atol(exprval->data); if (temp < INT_MAX) { qexpr=new QExpr(exprval->data,t_int,exprval->data); } else { qexpr=new QExpr(exprval->data, t_u_long, exprval->data); } return qexpr; }break; case t_approxnum: { Expr * exprval=(Expr *)node; QExpr *qexpr=new QExpr(exprval->data,t_double,exprval->data); return qexpr; }break; case t_bool: { }break; default: { } } return NULL; }
string expr_to_str(Node * node,int level) { string str=""; int thislevel=0; switch(node->type) { case t_expr_func: { Expr_func * funcnode=(Expr_func *)node; if(strcmp(funcnode->funname,"CASE3")==0) { str="case "; str=str+expr_to_str(funcnode->parameter1,0); str=str+" end"; } else if(strcmp(funcnode->funname,"CASE4")==0) { str="case "; str=str+expr_to_str(funcnode->parameter1,0); str=str+" else "; str=str+expr_to_str(funcnode->parameter2,0); str=str+" end"; } else if(strcmp(funcnode->funname,"WHEN1")==0) { str="when "; str=str+expr_to_str(funcnode->parameter1,0); str=str+" then "; str=str+expr_to_str(funcnode->parameter2,0); } else if(strcmp(funcnode->funname,"WHEN2")==0) { str="when "; str=str+expr_to_str(funcnode->parameter1,0); str=str+" then "; str=str+expr_to_str(funcnode->parameter2,0); } else if(strcmp(funcnode->funname,"FSUBSTRING0")==0) { str="substr("; str=str+expr_to_str(funcnode->args,0); str=str+","; str=str+expr_to_str(funcnode->parameter1,0); str=str+")"; } else if(strcmp(funcnode->funname,"FSUBSTRING1")==0) { str="substr("; str=str+expr_to_str(funcnode->args,0); str=str+","; str=str+expr_to_str(funcnode->parameter1,0); str=str+","; str=str+expr_to_str(funcnode->parameter2,0); str=str+")"; } else if(strcmp(funcnode->funname,"FTRIM0")==0) { str="trim("; str=str+"both "; str=str+expr_to_str(funcnode->parameter1,0); str=str+"from "; str=str+expr_to_str(funcnode->parameter2,0); str=str+")"; } else if(strcmp(funcnode->funname,"FTRIM1")==0) { str="trim("; str=str+"trailing "; str=str+expr_to_str(funcnode->parameter1,0); str=str+"from "; str=str+expr_to_str(funcnode->parameter2,0); str=str+")"; } else if(strcmp(funcnode->funname,"FTRIM2")==0) { str="trim("; str=str+"leading "; str=str+expr_to_str(funcnode->parameter1,0); str=str+"from "; str=str+expr_to_str(funcnode->parameter2,0); str=str+")"; } else if(strcmp(funcnode->funname,"FTRIM3")==0) { str="trim("; str=str+expr_to_str(funcnode->parameter1,0); str=str+")"; } else if(strcmp(funcnode->funname,"FUPPER")==0) { str="upper("; str=str+expr_to_str(funcnode->parameter1,0); str=str+")"; } else if(strcmp(funcnode->funname,"FCAST")==0) { str="case("; str=str+expr_to_str(funcnode->parameter1,0); str=str+" as "; str=str+expr_to_str(funcnode->parameter2,0); str=str+")"; } else if(strcmp(funcnode->funname,"FCOALESCE")==0) { } else if(strcmp(funcnode->funname,"FCOUNTALL")==0) { str="count(*)"; } else if(strcmp(funcnode->funname,"FCOUNT")==0) { str="count("; str=str+expr_to_str(funcnode->parameter1,0); str=str+")"; } else if(strcmp(funcnode->funname,"FSUM")==0) { str="sum("; str=str+expr_to_str(funcnode->parameter1,0); str=str+")"; } else if(strcmp(funcnode->funname,"FAVG")==0) { str="avg("; str=str+expr_to_str(funcnode->parameter1,0); str=str+")"; } else if(strcmp(funcnode->funname,"FMIN")==0) { str="min("; str=str+expr_to_str(funcnode->parameter1,0); str=str+")"; } else if(strcmp(funcnode->funname,"FMAX")==0) { str="max("; str=str+expr_to_str(funcnode->parameter1,0); str=str+")"; } else if(strcmp(funcnode->funname,"FDATE_ADD")==0) { Expr_func *datefunc=(Expr_func *)funcnode->parameter1; str="date_add("; str=str+expr_to_str(funcnode->args,0); str=str+",interval "; str=str+expr_to_str(datefunc->args,0); if(strcmp(datefunc->funname,"INTERVAL_DAY")==0) { str=str+" day)"; } else if(strcmp(datefunc->funname,"INTERVAL_WEEK")==0) { str=str+" week)"; } else if(strcmp(datefunc->funname,"INTERVAL_MONTH")==0) { str=str+" month)"; } else if(strcmp(datefunc->funname,"INTERVAL_YEAR")==0) { str=str+" year)"; } else if(strcmp(datefunc->funname,"INTERVAL_QUARTER")==0) { str=str+" quarter)"; } } else if(strcmp(funcnode->funname,"FDATE_SUB")==0) { Expr_func *datefunc=(Expr_func *)funcnode->parameter1; str="date_sub("; str=str+expr_to_str(funcnode->args,0); str=str+",interval "; str=str+expr_to_str(datefunc->args,0); if(strcmp(datefunc->funname,"INTERVAL_DAY")==0) { str=str+" day)"; } else if(strcmp(datefunc->funname,"INTERVAL_WEEK")==0) { str=str+" week)"; } else if(strcmp(datefunc->funname,"INTERVAL_MONTH")==0) { str=str+" month)"; } else if(strcmp(datefunc->funname,"INTERVAL_YEAR")==0) { str=str+" year)"; } else if(strcmp(datefunc->funname,"INTERVAL_QUARTER")==0) { str=str+" quarter)"; } } else if(strcmp(funcnode->funname,"BA")==0) { str=expr_to_str(funcnode->args,0); str=str+" between "; str=str+expr_to_str(funcnode->parameter1,0); str=str+" and "; str=str+expr_to_str(funcnode->parameter2,0); } else { SQLParse_elog("expr_to_str doesn't exist this function !!!"); } funcnode->str=(char *)malloc(str.size()+1); strcpy(funcnode->str,str.c_str()); }break; case t_expr_cal: { Expr_cal * calnode=(Expr_cal *)node; thislevel=getlevel(calnode); if(strcmp(calnode->sign,"--")==0) { str="-"; } else if(strcmp(calnode->sign,"++")==0) { str="+"; } else if(strcmp(calnode->sign,"!")==0) { str="!"; } else if(strcmp(calnode->sign,"NOT")==0) { str="not"; } else { str=expr_to_str(calnode->lnext,thislevel); if(strcmp(calnode->sign,"CMP")==0) { switch(calnode->cmp) { case 1://"<" { str=str+"<"; }break; case 2://">" { str=str+">"; }break; case 3://"<>" { str=str+"!="; }break; case 4://"=" { str=str+"="; }break; case 5://"<=" { str=str+"<="; }break; case 6://">=" { str=str+">="; }break; default: { } } } else if(strcmp(calnode->sign,"ANDOP")==0) { str=str+"and"; } else if(strcmp(calnode->sign,"OR")==0) { str=str+"or"; } else { str=str+calnode->sign; } } str=str+expr_to_str(calnode->rnext,thislevel); calnode->str=(char *)malloc(str.size()+1); strcpy(calnode->str,str.c_str()); if(thislevel<level) { str="("+str+")"; } // memcpy(calnode->str,str.c_str(),str.size()); }break; case t_name: case t_name_name: { Columns *col=(Columns *)node; if(col->parameter1==NULL) { str=str+string(col->parameter2); } else { str=str+string(col->parameter2); } }break; case t_stringval: { Expr * exprval=(Expr *)node; str=str+string(exprval->data); }break; case t_intnum: { Expr * exprval=(Expr *)node; str=str+string(exprval->data); }break; case t_approxnum: { Expr * exprval=(Expr *)node; str=str+string(exprval->data); }break; case t_bool: { }break; default: { } } return str; }