package jef.database.query.function;
import java.util.List;
import jef.database.jsqlparser.expression.Function;
import jef.database.jsqlparser.expression.LongValue;
import jef.database.jsqlparser.expression.Parenthesis;
import jef.database.jsqlparser.expression.StringValue;
import jef.database.jsqlparser.expression.operators.arithmetic.Division;
import jef.database.jsqlparser.expression.operators.arithmetic.Subtraction;
import jef.database.jsqlparser.visitor.Expression;
/**
* 后来看了一下,timestampdiff和timestampadd是JDBC函数,貌似postgres的驱动已经实现了这个两个函数。
*
* 但是我这边做不到的,Postgres的JDBC驱动一样做不到,该驱动会抛出异常。
*
*
* 需要存储过程……
* create or replace function get_months(interval , OUT result Integer) AS $$
select cast(extract(year from $1)*12+extract(month from $1) as Integer) as result
$$ language SQL;
*
* @author jiyi
*
*/
public class EmuPostgreTimestampDiff extends BaseArgumentSqlFunction{
public String getName() {
return "timestampdiff";
}
public Expression renderExpression(List<Expression> arguments) {
Expression arg1=arguments.get(1);
Expression arg2=arguments.get(2);
String unit=arguments.get(0).toString().toLowerCase();
if(unit.startsWith("sql_tsi_")){
unit=unit.substring(8);
}
Expression subtraction;
if("day".equals(unit)){
subtraction=new Subtraction(arg2,arg1);
subtraction=new Function("date_part",new StringValue("day",false),subtraction);
}else if("hour".equals(unit)){
subtraction=new Subtraction(arg2,arg1);
subtraction=new Function("date_part",new StringValue("epoch",false),subtraction);//转为秒数
subtraction=new Division(new Parenthesis(subtraction),new LongValue(3600)); //除以3600转为小时数
subtraction=new Function("trunc",subtraction); //截断
}else if("minute".equals(unit)){
subtraction=new Subtraction(arg2,arg1);
subtraction=new Function("date_part",new StringValue("epoch",false),subtraction);//转为秒数
subtraction=new Division(new Parenthesis(subtraction),new LongValue(60)); //除以60转为分钟数
subtraction=new Function("trunc",subtraction); //截断
}else if("second".equals(unit)){
subtraction=new Subtraction(arg2,arg1);
subtraction=new Function("date_part",new StringValue("epoch",false),subtraction);//转为秒数
subtraction=new Function("trunc",subtraction); //截断
}else if("month".equals(unit)){
//FIXME Support timestamp diff month on PostgreSQL
throw new UnsupportedOperationException("Since there's no function to convert interval to months, this function can't be supported untill we create a procedure in database");
//用存储过程是能支持的,先不做
// subtraction=new Function("age",arg2,arg1);
// subtraction=new Function("date_part",new StringValue("month",false),subtraction);//
}else if("quarter".equals(unit)){
//FIXME Support timestamp diff quarter on PostgreSQL
//用存储过程是能支持的,先不做
throw new UnsupportedOperationException("Since there's no function to convert interval to months, this function can't be supported untill we create a procedure in database");
// subtraction=new Function("age",arg2,arg1);
// subtraction=new Function("date_part",new StringValue("quarter",false),subtraction);//转为秒数
}else if("year".equals(unit)){
subtraction=new Function("age",arg2,arg1);
subtraction=new Function("date_part",new StringValue("year",false),subtraction);//无问题
}else{
throw new UnsupportedOperationException("The Oracle Dialect can't handle datetime unit ["+unit+"] for now.");
}
return subtraction;
}
}