ElasticSql2DslParser.java 3.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. package org.elasticsearch.dsl;
  2. import com.alibaba.druid.sql.ast.SQLExpr;
  3. import com.alibaba.druid.sql.ast.expr.SQLQueryExpr;
  4. import com.alibaba.druid.sql.parser.ParserException;
  5. import com.alibaba.druid.sql.parser.Token;
  6. import com.google.common.collect.ImmutableList;
  7. import org.elasticsearch.dsl.exception.ElasticSql2DslException;
  8. import org.elasticsearch.dsl.parser.*;
  9. import org.elasticsearch.sql.ElasticSqlExprParser;
  10. import org.elasticsearch.sql.ElasticSqlSelectQueryBlock;
  11. import java.lang.reflect.Array;
  12. import java.util.Collection;
  13. import java.util.List;
  14. import java.util.function.Consumer;
  15. public class ElasticSql2DslParser {
  16. public ElasticSqlParseResult parse(String sql) throws ElasticSql2DslException {
  17. return parse(sql, null, new ParseActionListenerAdapter());
  18. }
  19. public ElasticSqlParseResult parse(String sql, ParseActionListener parseActionListener) throws ElasticSql2DslException {
  20. return parse(sql, null, parseActionListener);
  21. }
  22. public ElasticSqlParseResult parse(String sql, Object[] sqlArgs) throws ElasticSql2DslException {
  23. return parse(sql, sqlArgs, new ParseActionListenerAdapter());
  24. }
  25. public ElasticSqlParseResult parse(String sql, Object[] sqlArgs, ParseActionListener parseActionListener) throws ElasticSql2DslException {
  26. SQLQueryExpr queryExpr = null;
  27. try {
  28. ElasticSqlExprParser elasticSqlExprParser = new ElasticSqlExprParser(sql);
  29. SQLExpr sqlQueryExpr = elasticSqlExprParser.expr();
  30. check(elasticSqlExprParser, sqlQueryExpr, sqlArgs);
  31. queryExpr = (SQLQueryExpr) sqlQueryExpr;
  32. } catch (ParserException ex) {
  33. throw new ElasticSql2DslException(ex);
  34. }
  35. final ElasticDslContext elasticDslContext = new ElasticDslContext(queryExpr, sqlArgs);
  36. if (queryExpr.getSubQuery().getQuery() instanceof ElasticSqlSelectQueryBlock) {
  37. buildSqlParserChain(parseActionListener).stream().forEach(new Consumer<QueryParser>() {
  38. @Override
  39. public void accept(QueryParser sqlParser) {
  40. sqlParser.parse(elasticDslContext);
  41. }
  42. });
  43. } else {
  44. throw new ElasticSql2DslException("[syntax error] Sql only support Select Sql");
  45. }
  46. return elasticDslContext.getParseResult();
  47. }
  48. private void check(ElasticSqlExprParser sqlExprParser, SQLExpr sqlQueryExpr, Object[] sqlArgs) {
  49. if (sqlExprParser.getLexer().token() != Token.EOF) {
  50. throw new ElasticSql2DslException("[syntax error] Sql last token is not EOF");
  51. }
  52. if (!(sqlQueryExpr instanceof SQLQueryExpr)) {
  53. throw new ElasticSql2DslException("[syntax error] Sql is not select sql");
  54. }
  55. if (sqlArgs != null && sqlArgs.length > 0) {
  56. for (Object arg : sqlArgs) {
  57. if (arg instanceof Array || arg instanceof Collection) {
  58. throw new ElasticSql2DslException("[syntax error] Sql arg cannot support collection type");
  59. }
  60. }
  61. }
  62. }
  63. private List<QueryParser> buildSqlParserChain(ParseActionListener parseActionListener) {
  64. //SQL解析器的顺序不能改变
  65. return ImmutableList.of(
  66. //解析SQL指定的索引和文档类型
  67. new QueryFromParser(parseActionListener),
  68. //解析SQL查询指定的where条件
  69. new QueryWhereConditionParser(parseActionListener),
  70. //解析SQL排序条件
  71. new QueryOrderConditionParser(parseActionListener),
  72. //解析路由参数
  73. new QueryRoutingValParser(parseActionListener),
  74. //解析SQL查询指定的字段
  75. new QuerySelectFieldListParser(parseActionListener),
  76. //解析SQL的分页条数
  77. new QueryLimitSizeParser(parseActionListener)
  78. );
  79. }
  80. }