Skip to content

Commit

Permalink
支持 PG DDL 语句若干,MySQL 支持 create/alter database ... collate 语句 (#6276)
Browse files Browse the repository at this point in the history
* 1. 支持 PG create schema ... create table 连体写法。
2. 修复 PG insert ... with ... select 被分解为两条语句的问题。

* 1. 支持 PG create database ... owner
2. 支持 PG create database ... template
3. 支持 PG alter database ... allow_connections
4. 支持 PG alter database ... is_template

* 1. fix code style.

* 1. 支持 pg drop database ... force
2. 移除 guava 依赖。

* 1. 修复 pg create schema ... create ... 多个元素。

* 1. 支持 pg drop schema 多名称.

* 1. 使用新方式编写单侧。

* 1. 优化 PG 新语句支持的实现逻辑。
2. 支持 MySQL alter schema abc default collate utf8mb4_unicode_ci; 语句
3. 支持 MySQL create database abc collate utf8mb4_unicode_ci; 语句

* 1. fix code style.

* 1. add test case.

* 1. format code.
  • Loading branch information
zycgit authored Dec 9, 2024
1 parent fd59bdb commit d5c8936
Show file tree
Hide file tree
Showing 20 changed files with 729 additions and 23 deletions.
8 changes: 7 additions & 1 deletion core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -310,12 +310,18 @@
<artifactId>calcite-core</artifactId>
<version>1.26.0</version>
<scope>provided</scope>
<exclusions>
<exclusion>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>30.1-jre</version>
<scope>provided</scope>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
import com.alibaba.druid.sql.parser.SQLParserFeature;
import com.alibaba.druid.sql.parser.Token;
import com.alibaba.druid.util.FnvHash;
import com.google.common.collect.Lists;

import java.util.Arrays;
import java.util.List;
Expand All @@ -53,7 +52,7 @@ public class CKExprParser extends SQLExprParser {
int index = Arrays.binarySearch(AGGREGATE_FUNCTIONS_CODES, hash);
AGGREGATE_FUNCTIONS[index] = str;
}
NESTED_DATA_TYPE = Lists.newArrayList("array", "tuple", "nullable", "lowcardinality", "variant");
NESTED_DATA_TYPE = Arrays.asList("array", "tuple", "nullable", "lowcardinality", "variant");
}

public CKExprParser(String sql) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8184,12 +8184,28 @@ public SQLStatement alterDatabase() {
if (lexer.identifierEquals(FnvHash.Constants.CHARACTER)) {
SQLAlterCharacter item = alterTableCharacter();
stmt.setCharacter(item);
} else if (lexer.identifierEquals(FnvHash.Constants.COLLATE)) {
lexer.nextToken();
if (lexer.token() == Token.EQ) {
lexer.nextToken();
}
SQLAlterCharacter character = new SQLAlterCharacter();
character.setCollate(this.exprParser.primary());
stmt.setCharacter(character);
} else {
throw new ParserException("TODO " + lexer.info());
}
} else if (lexer.identifierEquals(FnvHash.Constants.CHARACTER)) {
SQLAlterCharacter item = alterTableCharacter();
stmt.setCharacter(item);
} else if (lexer.identifierEquals(FnvHash.Constants.COLLATE)) {
lexer.nextToken();
if (lexer.token() == Token.EQ) {
lexer.nextToken();
}
SQLAlterCharacter character = new SQLAlterCharacter();
character.setCollate(this.exprParser.primary());
stmt.setCharacter(character);
}

return stmt;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
/*
* Copyright 1999-2017 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.druid.sql.dialect.postgresql.ast.expr;

import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLObject;
import com.alibaba.druid.sql.ast.SQLReplaceable;
import com.alibaba.druid.sql.dialect.postgresql.visitor.PGASTVisitor;

import java.util.Collections;
import java.util.List;
import java.util.Objects;

public class PGAttrExpr extends PGExprImpl implements SQLReplaceable {
private SQLExpr name;
private SQLExpr value;
private PGExprMode mode;

public static enum PGExprMode {
EMPTY,
EQ
}

public PGAttrExpr clone() {
PGAttrExpr x = new PGAttrExpr();
if (value != null) {
x.setName(name.clone());
x.setValue(value.clone());
x.setMode(this.mode);
}
return x;
}

public SQLExpr getName() {
return name;
}

public void setName(SQLExpr name) {
this.name = name;
}

public SQLExpr getValue() { return value; }

public void setValue(SQLExpr value) { this.value = value; }

public PGExprMode getMode() { return this.mode; }

public void setMode(PGExprMode mode) { this.mode = mode; }

@Override
public void accept0(PGASTVisitor visitor) {
if (visitor.visit(this)) {
acceptChild(visitor, value);
}
visitor.endVisit(this);
}

@Override
public boolean replace(SQLExpr expr, SQLExpr target) {
if (this.value == expr) {
setValue(target);
return true;
}

return false;
}

public List<SQLObject> getChildren() {
return Collections.singletonList(value);
}

@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((value == null) ? 0 : value.hashCode());
result = prime * result + ((mode == null) ? 0 : mode.hashCode());
return result;
}

@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
PGAttrExpr other = (PGAttrExpr) obj;

return Objects.equals(this.name, other.name) &&
Objects.equals(this.value, other.value) &&
Objects.equals(this.mode, other.mode);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ public class PGAlterDatabaseStatement extends SQLStatementImpl implements PGSQLS
private SQLExpr setParameterValue;
private boolean setFromCurrent;
private SQLIdentifierExpr resetParameterName;
private boolean haveWith;
private Boolean allowConnections;
private Boolean setTemplateMark;

public SQLIdentifierExpr getDatabaseName() {
return databaseName;
Expand Down Expand Up @@ -119,6 +122,31 @@ public SQLIdentifierExpr getResetParameterName() {
public void setResetParameterName(SQLIdentifierExpr resetParameterName) {
this.resetParameterName = resetParameterName;
}

public boolean isHaveWith() {
return haveWith;
}

public void setHaveWith(boolean haveWith) {
this.haveWith = haveWith;
}

public Boolean getAllowConnections() {
return allowConnections;
}

public void setAllowConnections(Boolean allowConnections) {
this.allowConnections = allowConnections;
}

public Boolean getSetTemplateMark() {
return setTemplateMark;
}

public void setSetTemplateMark(Boolean setTemplateMark) {
this.setTemplateMark = setTemplateMark;
}

public PGAlterDatabaseStatement(DbType dbType) {
super.dbType = dbType;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
* Copyright 1999-2017 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.druid.sql.dialect.postgresql.ast.stmt;

import com.alibaba.druid.DbType;
import com.alibaba.druid.sql.ast.SQLName;
import com.alibaba.druid.sql.ast.SQLStatementImpl;
import com.alibaba.druid.sql.ast.statement.SQLCreateStatement;
import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGAttrExpr;
import com.alibaba.druid.sql.dialect.postgresql.visitor.PGASTVisitor;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;

import java.util.ArrayList;
import java.util.List;

public class PGCreateDatabaseStatement extends SQLStatementImpl implements PGSQLStatement, SQLCreateStatement {
private SQLName name;
private boolean haveWith;
private List<PGAttrExpr> stats = new ArrayList<>();

public PGCreateDatabaseStatement(DbType dbType) {
super(dbType);
}

@Override
public SQLName getName() { return this.name; }

public void setName(SQLName dbName) { this.name = dbName; }

public boolean isHaveWith() { return haveWith; }

public void setHaveWith(boolean haveWith) { this.haveWith = haveWith; }

public List<PGAttrExpr> getStats() { return stats; }

public void setStats(List<PGAttrExpr> stats) { this.stats = stats; }

protected void accept0(SQLASTVisitor visitor) {
if (visitor instanceof PGASTVisitor) {
accept0((PGASTVisitor) visitor);
}
}

@Override
public void accept0(PGASTVisitor visitor) {
if (visitor.visit(this)) {
acceptChild(visitor, this.name);
acceptChild(visitor, this.stats);
}

visitor.endVisit(this);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,15 @@
import com.alibaba.druid.sql.dialect.postgresql.visitor.PGASTVisitor;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;

import java.util.ArrayList;
import java.util.List;

public class PGCreateSchemaStatement extends SQLStatementImpl implements PGSQLStatement, SQLCreateStatement {
private SQLIdentifierExpr schemaName;
private SQLIdentifierExpr userName;
private boolean ifNotExists;
private boolean authorization;
private List<SQLCreateStatement> createStatements = new ArrayList<>();

public SQLIdentifierExpr getSchemaName() {
return schemaName;
Expand Down Expand Up @@ -59,6 +63,14 @@ public void setAuthorization(boolean authorization) {
this.authorization = authorization;
}

public List<SQLCreateStatement> getCreateStatements() {
return createStatements;
}

public void setCreateStatements(List<SQLCreateStatement> createStatements) {
this.createStatements = createStatements;
}

protected void accept0(SQLASTVisitor visitor) {
if (visitor instanceof PGASTVisitor) {
accept0((PGASTVisitor) visitor);
Expand All @@ -71,6 +83,13 @@ public void accept0(PGASTVisitor visitor) {
acceptChild(visitor, this.schemaName);
acceptChild(visitor, this.userName);
}

if (this.createStatements != null && !this.createStatements.isEmpty()) {
for (SQLCreateStatement stat : this.createStatements) {
acceptChild(visitor, stat);
}
}

visitor.endVisit(this);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* Copyright 1999-2017 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.druid.sql.dialect.postgresql.ast.stmt;

import com.alibaba.druid.DbType;
import com.alibaba.druid.sql.ast.statement.SQLDropCatalogStatement;
import com.alibaba.druid.sql.dialect.postgresql.visitor.PGASTVisitor;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;

public class PGDropDatabaseStatement extends SQLDropCatalogStatement implements PGSQLStatement {
private boolean usingWith;
private boolean force;

public PGDropDatabaseStatement(DbType dbType) {
super(dbType);
}

public boolean isUsingWith() {
return usingWith;
}

public void setUsingWith(boolean usingWith) {
this.usingWith = usingWith;
}

public boolean isForce() { return force; }

public void setForce(boolean force) { this.force = force; }

protected void accept0(SQLASTVisitor visitor) {
if (visitor instanceof PGASTVisitor) {
accept0((PGASTVisitor) visitor);
}
}

@Override
public void accept0(PGASTVisitor visitor) {
if (visitor.visit(this)) {
acceptChild(visitor, this.getName());
}
visitor.endVisit(this);
}
}
Loading

0 comments on commit d5c8936

Please sign in to comment.