mirror of
https://github.com/alibaba/druid.git
synced 2023-03-04 19:17:16 +00:00
improved sql parser for postgresql
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
package com.alibaba.druid.sql.dialect.postgresql.ast.expr;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLExpr;
|
||||
import com.alibaba.druid.sql.dialect.postgresql.visitor.PGASTVisitor;
|
||||
|
||||
public class PGBoxExpr extends PGExprImpl {
|
||||
|
||||
private SQLExpr value;
|
||||
|
||||
public SQLExpr getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(SQLExpr value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept0(PGASTVisitor visitor) {
|
||||
if (visitor.visit(this)) {
|
||||
acceptChild(visitor, value);
|
||||
}
|
||||
visitor.endVisit(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((value == null) ? 0 : value.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;
|
||||
}
|
||||
PGBoxExpr other = (PGBoxExpr) obj;
|
||||
if (value == null) {
|
||||
if (other.value != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!value.equals(other.value)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.alibaba.druid.sql.dialect.postgresql.ast.expr;
|
||||
|
||||
public enum PGDateField {
|
||||
CENTURY,
|
||||
DAY,
|
||||
DECADE,
|
||||
DOW,
|
||||
DOY,
|
||||
EPOCH,
|
||||
HOUR,
|
||||
ISODOW,
|
||||
ISOYEAR,
|
||||
MICROSECONDS,
|
||||
MILLENNIUM,
|
||||
MILLISECONDS,
|
||||
MINUTE,
|
||||
MONTH,
|
||||
QUARTER,
|
||||
SECOND,
|
||||
TIMEZONE,
|
||||
TIMEZONE_HOUR,
|
||||
TIMEZONE_MINUTE,
|
||||
WEEK,
|
||||
YEAR
|
||||
}
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.alibaba.druid.sql.dialect.postgresql.ast.expr;
|
||||
|
||||
import com.alibaba.druid.sql.SQLUtils;
|
||||
import com.alibaba.druid.sql.ast.SQLExprImpl;
|
||||
import com.alibaba.druid.sql.dialect.postgresql.visitor.PGASTVisitor;
|
||||
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
@@ -30,4 +31,7 @@ public abstract class PGExprImpl extends SQLExprImpl implements PGExpr {
|
||||
accept0((PGASTVisitor) visitor);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return SQLUtils.toPGString(this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
package com.alibaba.druid.sql.dialect.postgresql.ast.expr;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLExpr;
|
||||
import com.alibaba.druid.sql.dialect.postgresql.visitor.PGASTVisitor;
|
||||
|
||||
public class PGExtractExpr extends PGExprImpl {
|
||||
|
||||
private PGDateField field;
|
||||
private SQLExpr source;
|
||||
|
||||
public PGDateField getField() {
|
||||
return field;
|
||||
}
|
||||
|
||||
public void setField(PGDateField field) {
|
||||
this.field = field;
|
||||
}
|
||||
|
||||
public SQLExpr getSource() {
|
||||
return source;
|
||||
}
|
||||
|
||||
public void setSource(SQLExpr source) {
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept0(PGASTVisitor visitor) {
|
||||
if (visitor.visit(this)) {
|
||||
acceptChild(visitor, source);
|
||||
}
|
||||
visitor.endVisit(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((field == null) ? 0 : field.hashCode());
|
||||
result = prime * result + ((source == null) ? 0 : source.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;
|
||||
}
|
||||
PGExtractExpr other = (PGExtractExpr) obj;
|
||||
if (field != other.field) {
|
||||
return false;
|
||||
}
|
||||
if (source == null) {
|
||||
if (other.source != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!source.equals(other.source)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package com.alibaba.druid.sql.dialect.postgresql.ast.expr;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLExpr;
|
||||
import com.alibaba.druid.sql.dialect.postgresql.visitor.PGASTVisitor;
|
||||
|
||||
public class PGPointExpr extends PGExprImpl {
|
||||
|
||||
private SQLExpr value;
|
||||
|
||||
public SQLExpr getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(SQLExpr value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept0(PGASTVisitor visitor) {
|
||||
if (visitor.visit(this)) {
|
||||
acceptChild(visitor, value);
|
||||
}
|
||||
visitor.endVisit(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((value == null) ? 0 : value.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;
|
||||
}
|
||||
PGPointExpr other = (PGPointExpr) obj;
|
||||
if (value == null) {
|
||||
if (other.value != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!value.equals(other.value)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.alibaba.druid.sql.dialect.postgresql.ast.expr;
|
||||
|
||||
import com.alibaba.druid.sql.SQLUtils;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLCastExpr;
|
||||
import com.alibaba.druid.sql.dialect.postgresql.visitor.PGASTVisitor;
|
||||
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
@@ -35,4 +36,7 @@ public class PGTypeCastExpr extends SQLCastExpr implements PGExpr {
|
||||
accept0((PGASTVisitor) visitor);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return SQLUtils.toPGString(this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,12 +19,21 @@ import com.alibaba.druid.sql.ast.SQLDataType;
|
||||
import com.alibaba.druid.sql.ast.SQLExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLTimestampExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLUnaryExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLUnaryOperator;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr;
|
||||
import com.alibaba.druid.sql.dialect.postgresql.ast.PGOrderBy;
|
||||
import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGArrayExpr;
|
||||
import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGBoxExpr;
|
||||
import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGDateField;
|
||||
import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGExtractExpr;
|
||||
import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGPointExpr;
|
||||
import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGTypeCastExpr;
|
||||
import com.alibaba.druid.sql.parser.Lexer;
|
||||
import com.alibaba.druid.sql.parser.ParserException;
|
||||
import com.alibaba.druid.sql.parser.SQLExprParser;
|
||||
import com.alibaba.druid.sql.parser.Token;
|
||||
import com.alibaba.druid.util.JdbcConstants;
|
||||
|
||||
public class PGExprParser extends SQLExprParser {
|
||||
|
||||
@@ -33,11 +42,13 @@ public class PGExprParser extends SQLExprParser {
|
||||
public PGExprParser(String sql){
|
||||
this(new PGLexer(sql));
|
||||
this.lexer.nextToken();
|
||||
this.dbType = JdbcConstants.POSTGRESQL;
|
||||
}
|
||||
|
||||
public PGExprParser(Lexer lexer){
|
||||
super(lexer);
|
||||
this.aggregateFunctions = AGGREGATE_FUNCTIONS;
|
||||
this.dbType = JdbcConstants.POSTGRESQL;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -74,7 +85,22 @@ public class PGExprParser extends SQLExprParser {
|
||||
this.exprList(array.getValues(), array);
|
||||
accept(Token.RBRACKET);
|
||||
return primaryRest(array);
|
||||
} else if (lexer.token() == Token.POUND) {
|
||||
lexer.nextToken();
|
||||
if (lexer.token() == Token.LBRACE) {
|
||||
lexer.nextToken();
|
||||
String varName = lexer.stringVal();
|
||||
lexer.nextToken();
|
||||
accept(Token.RBRACE);
|
||||
SQLVariantRefExpr expr = new SQLVariantRefExpr("#{" + varName + "}");
|
||||
return primaryRest(expr);
|
||||
} else {
|
||||
SQLExpr value = this.primary();
|
||||
SQLUnaryExpr expr = new SQLUnaryExpr(SQLUnaryOperator.Pound, value);
|
||||
return primaryRest(expr);
|
||||
}
|
||||
}
|
||||
|
||||
return super.primary();
|
||||
}
|
||||
|
||||
@@ -126,6 +152,35 @@ public class PGExprParser extends SQLExprParser {
|
||||
|
||||
|
||||
return primaryRest(timestamp);
|
||||
} else if ("EXTRACT".equalsIgnoreCase(ident)) {
|
||||
accept(Token.LPAREN);
|
||||
|
||||
PGExtractExpr extract = new PGExtractExpr();
|
||||
|
||||
String fieldName = lexer.stringVal();
|
||||
PGDateField field = PGDateField.valueOf(fieldName.toUpperCase());
|
||||
lexer.nextToken();
|
||||
|
||||
extract.setField(field);
|
||||
|
||||
accept(Token.FROM);
|
||||
SQLExpr source = this.expr();
|
||||
|
||||
extract.setSource(source);
|
||||
|
||||
accept(Token.RPAREN);
|
||||
|
||||
return primaryRest(extract);
|
||||
} else if ("POINT".equalsIgnoreCase(ident)) {
|
||||
SQLExpr value = this.primary();
|
||||
PGPointExpr point = new PGPointExpr();
|
||||
point.setValue(value);
|
||||
return primaryRest(point);
|
||||
} else if ("BOX".equalsIgnoreCase(ident)) {
|
||||
SQLExpr value = this.primary();
|
||||
PGBoxExpr box = new PGBoxExpr();
|
||||
box.setValue(value);
|
||||
return primaryRest(box);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -158,4 +158,9 @@ public class PGLexer extends Lexer {
|
||||
stringVal = new String(buf, 0, bufPos);
|
||||
}
|
||||
}
|
||||
|
||||
public void scanSharp() {
|
||||
token = Token.POUND;
|
||||
scanChar();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,10 @@ package com.alibaba.druid.sql.dialect.postgresql.visitor;
|
||||
import com.alibaba.druid.sql.dialect.postgresql.ast.PGWithClause;
|
||||
import com.alibaba.druid.sql.dialect.postgresql.ast.PGWithQuery;
|
||||
import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGArrayExpr;
|
||||
import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGBoxExpr;
|
||||
import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGExtractExpr;
|
||||
import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGParameter;
|
||||
import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGPointExpr;
|
||||
import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGTypeCastExpr;
|
||||
import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGDeleteStatement;
|
||||
import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGFunctionTableSource;
|
||||
@@ -94,5 +97,17 @@ public interface PGASTVisitor extends SQLASTVisitor {
|
||||
void endVisit(PGArrayExpr x);
|
||||
|
||||
boolean visit(PGArrayExpr x);
|
||||
|
||||
void endVisit(PGExtractExpr x);
|
||||
|
||||
boolean visit(PGExtractExpr x);
|
||||
|
||||
void endVisit(PGBoxExpr x);
|
||||
|
||||
boolean visit(PGBoxExpr x);
|
||||
|
||||
void endVisit(PGPointExpr x);
|
||||
|
||||
boolean visit(PGPointExpr x);
|
||||
|
||||
}
|
||||
|
||||
+33
@@ -18,7 +18,10 @@ package com.alibaba.druid.sql.dialect.postgresql.visitor;
|
||||
import com.alibaba.druid.sql.dialect.postgresql.ast.PGWithClause;
|
||||
import com.alibaba.druid.sql.dialect.postgresql.ast.PGWithQuery;
|
||||
import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGArrayExpr;
|
||||
import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGBoxExpr;
|
||||
import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGExtractExpr;
|
||||
import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGParameter;
|
||||
import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGPointExpr;
|
||||
import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGTypeCastExpr;
|
||||
import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGDeleteStatement;
|
||||
import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGFunctionTableSource;
|
||||
@@ -199,5 +202,35 @@ public class PGASTVisitorAdapter extends SQLASTVisitorAdapter implements PGASTVi
|
||||
public boolean visit(PGArrayExpr x) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(PGExtractExpr x) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(PGExtractExpr x) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(PGBoxExpr x) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(PGBoxExpr x) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(PGPointExpr x) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(PGPointExpr x) {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -21,7 +21,10 @@ import com.alibaba.druid.sql.ast.statement.SQLTruncateStatement;
|
||||
import com.alibaba.druid.sql.dialect.postgresql.ast.PGWithClause;
|
||||
import com.alibaba.druid.sql.dialect.postgresql.ast.PGWithQuery;
|
||||
import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGArrayExpr;
|
||||
import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGBoxExpr;
|
||||
import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGExtractExpr;
|
||||
import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGParameter;
|
||||
import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGPointExpr;
|
||||
import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGTypeCastExpr;
|
||||
import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGDeleteStatement;
|
||||
import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGFunctionTableSource;
|
||||
@@ -525,5 +528,43 @@ public class PGOutputVisitor extends SQLASTOutputVisitor implements PGASTVisitor
|
||||
print("]");
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(PGExtractExpr x) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(PGExtractExpr x) {
|
||||
print("EXTRACT (");
|
||||
print(x.getField().name());
|
||||
print(" FROM ");
|
||||
x.getSource().accept(this);
|
||||
print(")");
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(PGBoxExpr x) {
|
||||
print("BOX ");
|
||||
x.getValue().accept(this);
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(PGBoxExpr x) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(PGPointExpr x) {
|
||||
print("POINT ");
|
||||
x.getValue().accept(this);
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(PGPointExpr x) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
+33
@@ -24,7 +24,10 @@ import com.alibaba.druid.sql.ast.statement.SQLSelectStatement;
|
||||
import com.alibaba.druid.sql.dialect.postgresql.ast.PGWithClause;
|
||||
import com.alibaba.druid.sql.dialect.postgresql.ast.PGWithQuery;
|
||||
import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGArrayExpr;
|
||||
import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGBoxExpr;
|
||||
import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGExtractExpr;
|
||||
import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGParameter;
|
||||
import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGPointExpr;
|
||||
import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGTypeCastExpr;
|
||||
import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGDeleteStatement;
|
||||
import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGFunctionTableSource;
|
||||
@@ -309,4 +312,34 @@ public class PGSchemaStatVisitor extends SchemaStatVisitor implements PGASTVisit
|
||||
public boolean visit(PGArrayExpr x) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(PGExtractExpr x) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(PGExtractExpr x) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(PGBoxExpr x) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(PGBoxExpr x) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(PGPointExpr x) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(PGPointExpr x) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user