From 88a53c0a13a6ab48d439b974745480c108d6ad26 Mon Sep 17 00:00:00 2001 From: shenqi Date: Wed, 3 May 2023 23:12:58 +0800 Subject: [PATCH] add postgresql refresh mv keywords support --- .../SQLRefreshMaterializedViewStatement.java | 36 +++++++++++++++++++ .../druid/sql/parser/SQLStatementParser.java | 20 +++++++++++ .../sql/visitor/SQLASTOutputVisitor.java | 16 ++++++++- .../postgresql/PostgresqlResourceTest.java | 4 +++ .../resources/bvt/parser/postgresql-15.txt | 3 ++ 5 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 core/src/test/resources/bvt/parser/postgresql-15.txt diff --git a/core/src/main/java/com/alibaba/druid/sql/ast/statement/SQLRefreshMaterializedViewStatement.java b/core/src/main/java/com/alibaba/druid/sql/ast/statement/SQLRefreshMaterializedViewStatement.java index 5afa4f2edf..5cc6de7dcb 100644 --- a/core/src/main/java/com/alibaba/druid/sql/ast/statement/SQLRefreshMaterializedViewStatement.java +++ b/core/src/main/java/com/alibaba/druid/sql/ast/statement/SQLRefreshMaterializedViewStatement.java @@ -27,11 +27,23 @@ public class SQLRefreshMaterializedViewStatement extends SQLStatementImpl { private SQLExpr name; + private boolean concurrently; + + private boolean withNoData; + + private boolean withData; + public SQLRefreshMaterializedViewStatement() { + this.setConcurrently(false); + this.setWithData(false); + this.setWithNoData(false); } public SQLRefreshMaterializedViewStatement(DbType dbType) { super(dbType); + this.setConcurrently(false); + this.setWithData(false); + this.setWithNoData(false); } @Override @@ -53,6 +65,30 @@ public void setName(SQLExpr x) { this.name = x; } + public boolean isConcurrently() { + return concurrently; + } + + public void setConcurrently(boolean concurrently) { + this.concurrently = concurrently; + } + + public boolean isWithNoData() { + return withNoData; + } + + public void setWithNoData(boolean withNoData) { + this.withNoData = withNoData; + } + + public void setWithData(boolean withData) { + this.withData = withData; + } + + public boolean isWithData() { + return withData; + } + @Override public List getChildren() { List children = new ArrayList(); diff --git a/core/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java b/core/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java index b626136b24..70b338ad0b 100644 --- a/core/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java +++ b/core/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java @@ -926,9 +926,29 @@ public SQLStatement parseRefresh() { acceptIdentifier("MATERIALIZED"); + if (lexer.identifierEquals("CONCURRENTLY")) { + lexer.nextToken(); + stmt.setConcurrently(true); + } accept(Token.VIEW); stmt.setName(this.exprParser.name()); + + if (lexer.token() == WITH) { + lexer.nextToken(); + + if (lexer.token() == IDENTIFIER && "NO".equalsIgnoreCase(lexer.stringVal())) { + lexer.nextToken(); + stmt.setWithNoData(true); + } + + if (lexer.token() == IDENTIFIER && "DATA".equalsIgnoreCase(lexer.stringVal())) { + lexer.nextToken(); + stmt.setWithData(true); + } else { + throw new ParserException("syntax error, expect DATA, actual " + lexer.token() + ", pos " + lexer.pos()); + } + } return stmt; } diff --git a/core/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java b/core/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java index 67042fbaca..3eb2d91e91 100644 --- a/core/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java +++ b/core/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java @@ -8560,8 +8560,22 @@ public boolean visit(SQLShowCreateMaterializedViewStatement x) { @Override public boolean visit(SQLRefreshMaterializedViewStatement x) { - print0(ucase ? "REFRESH MATERIALIZED VIEW " : "refresh materialized view "); + print0(ucase ? "REFRESH MATERIALIZED" : "refresh materialized"); + + if (x.isConcurrently()) { + print0(ucase ? " CONCURRENTLY" : " concurrently"); + } + + print0(ucase ? " VIEW " : " view "); + x.getName().accept(this); + + if (x.isWithNoData()) { + print0(ucase ? " WITH NO DATA" : " with no data"); + } else if (x.isWithData()) { + print0(ucase ? " WITH DATA" : " with data"); + } + return false; } diff --git a/core/src/test/java/com/alibaba/druid/bvt/sql/postgresql/PostgresqlResourceTest.java b/core/src/test/java/com/alibaba/druid/bvt/sql/postgresql/PostgresqlResourceTest.java index 04095c2834..2de7c3efdc 100644 --- a/core/src/test/java/com/alibaba/druid/bvt/sql/postgresql/PostgresqlResourceTest.java +++ b/core/src/test/java/com/alibaba/druid/bvt/sql/postgresql/PostgresqlResourceTest.java @@ -95,6 +95,10 @@ public void test_14() throws Exception { exec_test("bvt/parser/postgresql-14.txt"); } + public void test_15() throws Exception { + exec_test("bvt/parser/postgresql-15.txt"); + } + public void exec_test(String resource) throws Exception { System.out.println(resource); InputStream is = null; diff --git a/core/src/test/resources/bvt/parser/postgresql-15.txt b/core/src/test/resources/bvt/parser/postgresql-15.txt new file mode 100644 index 0000000000..422dafaff7 --- /dev/null +++ b/core/src/test/resources/bvt/parser/postgresql-15.txt @@ -0,0 +1,3 @@ +refresh materialized concurrently view v1 with no data +--------------------------- +REFRESH MATERIALIZED CONCURRENTLY VIEW v1 WITH NO DATA \ No newline at end of file