From ca00e5c406c3465473e77eae630b4fcd5043a639 Mon Sep 17 00:00:00 2001 From: sunzhengfang Date: Thu, 2 Nov 2017 10:20:02 +0800 Subject: [PATCH] #303 view support add support of alter view --- .../com/actiontech/dble/meta/ViewMeta.java | 9 ++++- .../actiontech/dble/meta/ViewMetaParser.java | 15 +++++++ .../dble/server/ServerQueryHandler.java | 3 ++ .../dble/server/handler/DropViewHandler.java | 7 ++++ .../dble/server/parser/ServerParse.java | 40 +++++++++++++++---- .../dble/parser/ServerParserTest.java | 1 + 6 files changed, 67 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/actiontech/dble/meta/ViewMeta.java b/src/main/java/com/actiontech/dble/meta/ViewMeta.java index bd1076f46..354887a23 100644 --- a/src/main/java/com/actiontech/dble/meta/ViewMeta.java +++ b/src/main/java/com/actiontech/dble/meta/ViewMeta.java @@ -36,12 +36,19 @@ public class ViewMeta { try { SchemaMeta schemaMeta = DbleServer.getInstance().getTmManager().getCatalogs().get(schema); + //if the alter table + if (viewParser.getType() == ViewMetaParser.TYPE_ALTER_VIEW && !isReplace) { + if (schemaMeta.getView(viewName) == null) { + throw new Exception("Table '" + viewName + "' doesn't exist"); + } + } + // if the table with same name exists if (schemaMeta.getTableMeta(viewName) != null) { throw new Exception("Table '" + viewName + "' already exists"); } - if (!isReplace) { + if (viewParser.getType() == ViewMetaParser.TYPE_CREATE_VIEW) { // if the sql without replace & the view exists if (schemaMeta.getView(viewName) != null) { // return error because the view is exists diff --git a/src/main/java/com/actiontech/dble/meta/ViewMetaParser.java b/src/main/java/com/actiontech/dble/meta/ViewMetaParser.java index af59c652f..9cc114266 100644 --- a/src/main/java/com/actiontech/dble/meta/ViewMetaParser.java +++ b/src/main/java/com/actiontech/dble/meta/ViewMetaParser.java @@ -7,8 +7,13 @@ import java.util.*; */ public class ViewMetaParser { + public static final int TYPE_CREATE_VIEW = 1; + public static final int TYPE_REPLACE_VIEW = 2; + public static final int TYPE_ALTER_VIEW = 3; + private int offset = -1; private String originalSql; + private int type = TYPE_CREATE_VIEW; public ViewMetaParser(String originalSql) { this.originalSql = originalSql; @@ -33,6 +38,10 @@ public class ViewMetaParser { case '\r': case '\n': continue; + case 'a': + offset = offset + 5; + type = TYPE_ALTER_VIEW; + return parseCreateOrReplace(); default: //skip the create because in ServerParse is already know offset = offset + 6; @@ -52,6 +61,7 @@ public class ViewMetaParser { next = originalSql.charAt(++offset); if (next == 'r' || next == 'R') { offset += 7; + this.type = TYPE_REPLACE_VIEW; return parseCreateOrReplace(); } } @@ -112,4 +122,9 @@ public class ViewMetaParser { } return new ArrayList(Arrays.asList(columnList.split(","))); } + + + public int getType() { + return type; + } } diff --git a/src/main/java/com/actiontech/dble/server/ServerQueryHandler.java b/src/main/java/com/actiontech/dble/server/ServerQueryHandler.java index 4dd644471..18402f6e0 100644 --- a/src/main/java/com/actiontech/dble/server/ServerQueryHandler.java +++ b/src/main/java/com/actiontech/dble/server/ServerQueryHandler.java @@ -111,6 +111,9 @@ public class ServerQueryHandler implements FrontendQueryHandler { case ServerParse.REPLACE_VIEW: CreateViewHandler.handle(sql, c, true); break; + case ServerParse.ALTER_VIEW: + CreateViewHandler.handle(sql, c, false); + break; case ServerParse.DROP_VIEW: DropViewHandler.handle(sql, c); break; diff --git a/src/main/java/com/actiontech/dble/server/handler/DropViewHandler.java b/src/main/java/com/actiontech/dble/server/handler/DropViewHandler.java index c71a6b12e..6ecf6bb7e 100644 --- a/src/main/java/com/actiontech/dble/server/handler/DropViewHandler.java +++ b/src/main/java/com/actiontech/dble/server/handler/DropViewHandler.java @@ -4,6 +4,7 @@ import com.actiontech.dble.DbleServer; import com.actiontech.dble.net.mysql.OkPacket; import com.actiontech.dble.server.ServerConnection; +import static com.actiontech.dble.config.ErrorCode.ER_BAD_TABLE_ERROR; import static com.actiontech.dble.config.ErrorCode.ER_PARSE_ERROR; /** @@ -19,6 +20,12 @@ public final class DropViewHandler { try { String[] viewName = parseViewName(stmt); //check if all the view is exists + for (String singleName : viewName) { + if (!(DbleServer.getInstance().getTmManager().getCatalogs().get(c.getSchema()).getViewMetas().containsKey(singleName))) { + c.writeErrMessage(ER_BAD_TABLE_ERROR, " Unknown table '" + singleName + "'"); + return; + } + } for (String singleName : viewName) { DbleServer.getInstance().getTmManager().getCatalogs().get(c.getSchema()).getViewMetas().remove(singleName.trim()); } diff --git a/src/main/java/com/actiontech/dble/server/parser/ServerParse.java b/src/main/java/com/actiontech/dble/server/parser/ServerParse.java index 587ccc5a8..e881a6814 100644 --- a/src/main/java/com/actiontech/dble/server/parser/ServerParse.java +++ b/src/main/java/com/actiontech/dble/server/parser/ServerParse.java @@ -45,6 +45,7 @@ public final class ServerParse { public static final int UNLOCK = 23; public static final int CREATE_VIEW = 24; public static final int REPLACE_VIEW = 25; + public static final int ALTER_VIEW = 27; public static final int DROP_VIEW = 26; public static final int LOAD_DATA_INFILE_SQL = 99; public static final int DDL = 100; @@ -226,12 +227,37 @@ public final class ServerParse { (c3 == 'E' || c3 == 'e') && (c4 == 'R' || c4 == 'r') && (c5 == ' ' || c5 == '\t' || c5 == '\r' || c5 == '\n')) { - return DDL; + return alterViewCheck(stmt, offset); } } return OTHER; } + private static int alterViewCheck(String stmt, int offset) { + while (true) { + if (!(stmt.charAt(++offset) == ' ' || + stmt.charAt(offset) == '\t' || + stmt.charAt(offset) == '\r' || + stmt.charAt(offset) == '\n')) { + char c1 = stmt.charAt(offset); + char c2 = stmt.charAt(++offset); + char c3 = stmt.charAt(++offset); + char c4 = stmt.charAt(++offset); + char c5 = stmt.charAt(++offset); + if ((c1 == 'v' || c1 == 'V') && + (c2 == 'i' || c2 == 'I') && + (c3 == 'e' || c3 == 'E') && + (c4 == 'w' || c4 == 'W') && + (c5 == ' ' || c5 == '\t' || c5 == '\r' || c5 == '\n')) { + return ALTER_VIEW; + } else { + return DDL; + } + } + } + } + + //create table/view/... private static int createCheck(String stmt, int offset) { if (stmt.length() > offset + 5) { @@ -264,13 +290,13 @@ public final class ServerParse { try { while (true) { if (!(stmt.charAt(++offset) == ' ' || - stmt.charAt(offset) == '\t' || - stmt.charAt(offset) == '\r' || - stmt.charAt(offset) == '\n')) { + stmt.charAt(offset) == '\t' || + stmt.charAt(offset) == '\r' || + stmt.charAt(offset) == '\n')) { if ((stmt.charAt(offset) == 'o' || stmt.charAt(offset) == 'O') && - (stmt.charAt(++offset) == 'r' || stmt.charAt(offset) == 'R') && - (stmt.charAt(++offset) == ' ' || stmt.charAt(offset) == '\t' || - stmt.charAt(offset) == '\r' || stmt.charAt(offset) == '\n')) { + (stmt.charAt(++offset) == 'r' || stmt.charAt(offset) == 'R') && + (stmt.charAt(++offset) == ' ' || stmt.charAt(offset) == '\t' || + stmt.charAt(offset) == '\r' || stmt.charAt(offset) == '\n')) { return replaceViewCheck(stmt, offset); } else if (stmt.charAt(offset) == 'v' || stmt.charAt(offset) == 'V') { return createViewCheck(stmt, offset, isReplace); diff --git a/src/test/java/com/actiontech/dble/parser/ServerParserTest.java b/src/test/java/com/actiontech/dble/parser/ServerParserTest.java index d4de25fe6..f099f3507 100644 --- a/src/test/java/com/actiontech/dble/parser/ServerParserTest.java +++ b/src/test/java/com/actiontech/dble/parser/ServerParserTest.java @@ -357,6 +357,7 @@ public class ServerParserTest { @Test public void testCreateView(){ Assert.assertEquals(ServerParse.CREATE_VIEW, ServerParse.parse("create view asdfasdf as asdfasdfasdfsdf")); + Assert.assertEquals(ServerParse.ALTER_VIEW, ServerParse.parse("ALTER view x_xx_xx as select * from suntest")); Assert.assertEquals(ServerParse.REPLACE_VIEW, ServerParse.parse("create or replace view x_xx_xx as select * from suntest")); Assert.assertEquals(ServerParse.DDL, ServerParse.parse("create or replace viasdfasdfew asdfasdf as asdfasdfasdfsdf")); Assert.assertEquals(ServerParse.DDL, ServerParse.parse("create "));