Exemple #1
0
/*
 * 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;
}
Exemple #2
0
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;
}