jsqlparser:实现MySQL 函数DATE_FORMAT到Phoenix函数TO_CHAR的替换

Posted 10km

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了jsqlparser:实现MySQL 函数DATE_FORMAT到Phoenix函数TO_CHAR的替换相关的知识,希望对你有一定的参考价值。

上一篇博客《jsqlparser:基于语法分析实现SQL中的CAST函数替换》中我用jsqlparser这个神器实现了 TO_DATE(TO_CHAR("local_time"), 'yyyy-MM-dd')替换CAST(local_time AS DATE)
现在又遇到新问题了,
mysql中日期格式化函数为DATE_FORMAT,对应Phoenix中的函数为TO_CHAR,如果应用层使用DATE_FORMAT函数,也要替换为TO_CHAR才能在HBase数据库中正常执行。有了上次经验,这次就简单多了,
不同的是DATE_FORMAT的日期格式定义与Phoenix不同,所以DATE_FORMATformat参数也需要自动替换,但是只能不完全替换。

以下为实现代码

import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.Function;
import net.sf.jsqlparser.expression.StringValue;
import net.sf.jsqlparser.util.TablesNamesFinder;

import java.util.List;
/**
 * 基于SQL语法对象实现对SQL的修改<br>
 * 将MySQL函数DATE_FORMAT替换为Phoenix的函数TO_CHAR
 * @author guyadong
 *
 */
public class PhoenixNormalizer  extends TablesNamesFinder
    public PhoenixNormalizer() 
	
	
    /**
     * 将MySQL的 DATE_FORMAT格式转为Java 日期格式<br>     
     * 参见 <a href="https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_date-format">function_date-format</a>,
     * 因为不能实现完全转换,所以当有不支持的格式时返回原字符串 
     * @param format
     * @see java.text.SimpleDateFormat
     */
    String castFormat(String format)
        if(null != format)
            String fmt=format.replace("%Y", "yyyy").replace("%y", "yy").replace("%m", "MM").replaceAll("%[de]", "dd")
            .replaceAll("%[Hk]", "HH").replace("%i", "mm").replaceAll("%[sS]", "ss")
            .replace("%W", "E")
            .replace("%j", "D")
            .replace("%T", "hh:mm:ss")
            .replace("%r", "hh:mm:ss a")
            .replaceAll("%[Uu]", "w")
            .replace("%%", "%");
            // 当有不支持的格式时返回原字符串 
            if(fmt.indexOf('%') < 0)
                return fmt;
            
        
        return format;
    
    
    @Override
    public void visit(Function function)
        if("DATE_FORMAT".equalsIgnoreCase(function.getName()))
            /** DATE_FORMAT 改为 TO_CHAR */
            List<Expression> expressions = function.getParameters().getExpressions();
            if(null != expressions && 2 == expressions.size() )
            	/** 修改函数名 */
                function.setName("TO_CHAR");
                Expression formatExp = expressions.get(1);
                if(formatExp instanceof StringValue)
                	/** 修改第二个参数(format) */
                    StringValue stringValue = (StringValue)formatExp;
                    stringValue.setValue(castFormat(stringValue.getValue()));
                
            
            
        
        super.visit(function);
    


完整的代码参见码云仓库:

https://gitee.com/l0km/sql2java/blob/master/sql2java-manager/src/main/java/gu/sql2java/phoenix/PhoenixNormalizer.java

参考资料

《DATE_FORMAT》
《TO_CHAR》

以上是关于jsqlparser:实现MySQL 函数DATE_FORMAT到Phoenix函数TO_CHAR的替换的主要内容,如果未能解决你的问题,请参考以下文章

jsqlparser:修改语法定义(JSqlParserCC.jjt)实现UPSERT支持Phoenix语法ON DUPLICATE KEY IGNORE

jsqlparser:修改语法定义(JSqlParserCC.jjt)实现UPSERT支持Phoenix语法ON DUPLICATE KEY IGNORE

SpringBoot项目:net.sf.jsqlparser.parser.ParseException: Encountered unexpected token:XXXXX

jsqlparser:实现基于SQL语法分析的SQL注入攻击检查

java sql解析器比较druid sql parser vs jsqlparser vs fdb-sql-parser

jsqlparser:基于抽象语法树(AST)遍历SQL语句的语法元素