Merge pull request #715 from wenshao/master

improved sql parser for postgresql
This commit is contained in:
高铁
2014-11-16 15:37:16 +08:00
29 changed files with 655 additions and 74 deletions
@@ -142,11 +142,13 @@ public class PagerUtils {
SQLBinaryOpExpr gt = new SQLBinaryOpExpr(new SQLIdentifierExpr("ROWNUM"), //
SQLBinaryOperator.GreaterThan, //
new SQLNumberExpr(offset));
new SQLNumberExpr(offset), //
JdbcConstants.DB2);
SQLBinaryOpExpr lteq = new SQLBinaryOpExpr(new SQLIdentifierExpr("ROWNUM"), //
SQLBinaryOperator.LessThanOrEqual, //
new SQLNumberExpr(count + offset));
SQLBinaryOpExpr pageCondition = new SQLBinaryOpExpr(gt, SQLBinaryOperator.BooleanAnd, lteq);
new SQLNumberExpr(count + offset), //
JdbcConstants.DB2);
SQLBinaryOpExpr pageCondition = new SQLBinaryOpExpr(gt, SQLBinaryOperator.BooleanAnd, lteq, JdbcConstants.DB2);
if (query instanceof SQLSelectQueryBlock) {
DB2SelectQueryBlock queryBlock = (DB2SelectQueryBlock) query;
@@ -199,11 +201,14 @@ public class PagerUtils {
SQLBinaryOpExpr gt = new SQLBinaryOpExpr(new SQLIdentifierExpr("ROWNUM"), //
SQLBinaryOperator.GreaterThan, //
new SQLNumberExpr(offset));
new SQLNumberExpr(offset), //
JdbcConstants.SQL_SERVER
);
SQLBinaryOpExpr lteq = new SQLBinaryOpExpr(new SQLIdentifierExpr("ROWNUM"), //
SQLBinaryOperator.LessThanOrEqual, //
new SQLNumberExpr(count + offset));
SQLBinaryOpExpr pageCondition = new SQLBinaryOpExpr(gt, SQLBinaryOperator.BooleanAnd, lteq);
new SQLNumberExpr(count + offset), //
JdbcConstants.SQL_SERVER);
SQLBinaryOpExpr pageCondition = new SQLBinaryOpExpr(gt, SQLBinaryOperator.BooleanAnd, lteq, JdbcConstants.SQL_SERVER);
if (query instanceof SQLSelectQueryBlock) {
SQLServerSelectQueryBlock queryBlock = (SQLServerSelectQueryBlock) query;
@@ -262,13 +267,17 @@ public class PagerUtils {
if (queryBlock.getGroupBy() == null && select.getOrderBy() == null && offset <= 0) {
SQLExpr condition = new SQLBinaryOpExpr(new SQLIdentifierExpr("ROWNUM"), //
SQLBinaryOperator.LessThanOrEqual, //
new SQLNumberExpr(count));
new SQLNumberExpr(count), //
JdbcConstants.ORACLE
);
if (queryBlock.getWhere() == null) {
queryBlock.setWhere(condition);
} else {
queryBlock.setWhere(new SQLBinaryOpExpr(queryBlock.getWhere(), //
SQLBinaryOperator.BooleanAnd, //
condition));
condition, //
JdbcConstants.ORACLE
));
}
return SQLUtils.toSQLString(select, dbType);
@@ -282,7 +291,8 @@ public class PagerUtils {
countQueryBlock.setFrom(new SQLSubqueryTableSource(select, "XX"));
countQueryBlock.setWhere(new SQLBinaryOpExpr(new SQLIdentifierExpr("ROWNUM"), //
SQLBinaryOperator.LessThanOrEqual, //
new SQLNumberExpr(count + offset)));
new SQLNumberExpr(count + offset), //
JdbcConstants.ORACLE));
if (offset <= 0) {
return SQLUtils.toSQLString(countQueryBlock, dbType);
}
@@ -292,7 +302,8 @@ public class PagerUtils {
offsetQueryBlock.setFrom(new SQLSubqueryTableSource(new SQLSelect(countQueryBlock), "XXX"));
offsetQueryBlock.setWhere(new SQLBinaryOpExpr(new SQLIdentifierExpr("RN"), //
SQLBinaryOperator.GreaterThan, //
new SQLNumberExpr(offset)));
new SQLNumberExpr(offset), //
JdbcConstants.ORACLE));
return SQLUtils.toSQLString(offsetQueryBlock, dbType);
}
@@ -28,16 +28,25 @@ public class SQLBinaryOpExpr extends SQLExprImpl implements Serializable {
private SQLExpr left;
private SQLExpr right;
private SQLBinaryOperator operator;
private String dbType;
public SQLBinaryOpExpr(){
}
public SQLBinaryOpExpr(SQLExpr left, SQLBinaryOperator operator, SQLExpr right){
public SQLBinaryOpExpr(String dbType){
this.dbType = dbType;
}
public SQLBinaryOpExpr(SQLExpr left, SQLBinaryOperator operator, SQLExpr right){
this(left, operator, right, null);
}
public SQLBinaryOpExpr(SQLExpr left, SQLBinaryOperator operator, SQLExpr right, String dbType){
setLeft(left);
setRight(right);
this.operator = operator;
this.dbType = dbType;
}
public SQLBinaryOpExpr(SQLExpr left, SQLExpr right, SQLBinaryOperator operator){
@@ -47,6 +56,14 @@ public class SQLBinaryOpExpr extends SQLExprImpl implements Serializable {
this.operator = operator;
}
public String getDbType() {
return dbType;
}
public void setDbType(String dbType) {
this.dbType = dbType;
}
public SQLExpr getLeft() {
return this.left;
}
@@ -129,6 +146,6 @@ public class SQLBinaryOpExpr extends SQLExprImpl implements Serializable {
}
public String toString() {
return SQLUtils.toSQLString(this);
return SQLUtils.toSQLString(this, getDbType());
}
}
@@ -117,4 +117,8 @@ public enum SQLBinaryOperator {
return false;
}
}
public boolean isLogical() {
return this == BooleanAnd || this == BooleanOr || this == BooleanXor;
}
}
@@ -24,7 +24,9 @@ public enum SQLUnaryOperator {
ConnectByRoot("CONNECT BY"), //
BINARY("BINARY"), //
RAW("RAW"), //
NOT("NOT");
NOT("NOT"),
Pound("#") // Number of points in path or polygon
;
public final String name;
@@ -57,6 +57,7 @@ import com.alibaba.druid.sql.parser.ParserException;
import com.alibaba.druid.sql.parser.SQLExprParser;
import com.alibaba.druid.sql.parser.SQLSelectParser;
import com.alibaba.druid.sql.parser.Token;
import com.alibaba.druid.util.JdbcConstants;
public class MySqlExprParser extends SQLExprParser {
@@ -79,7 +80,7 @@ public class MySqlExprParser extends SQLExprParser {
rightExp = relationalRest(rightExp);
return new SQLBinaryOpExpr(expr, SQLBinaryOperator.RegExp, rightExp);
return new SQLBinaryOpExpr(expr, SQLBinaryOperator.RegExp, rightExp, JdbcConstants.MYSQL);
}
return super.relationalRest(expr);
@@ -92,7 +93,7 @@ public class MySqlExprParser extends SQLExprParser {
rightExp = relationalRest(rightExp);
return new SQLBinaryOpExpr(expr, SQLBinaryOperator.Modulus, rightExp);
return new SQLBinaryOpExpr(expr, SQLBinaryOperator.Modulus, rightExp, JdbcConstants.MYSQL);
}
return super.multiplicativeRest(expr);
@@ -105,7 +106,7 @@ public class MySqlExprParser extends SQLExprParser {
rightExp = relationalRest(rightExp);
return new SQLBinaryOpExpr(expr, SQLBinaryOperator.NotRegExp, rightExp);
return new SQLBinaryOpExpr(expr, SQLBinaryOperator.NotRegExp, rightExp, JdbcConstants.MYSQL);
}
return super.notRationalRest(expr);
@@ -245,7 +246,7 @@ public class MySqlExprParser extends SQLExprParser {
lexer.nextToken();
SQLBinaryOpExpr binaryExpr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.COLLATE,
new SQLIdentifierExpr(collate));
new SQLIdentifierExpr(collate), JdbcConstants.MYSQL);
expr = binaryExpr;
@@ -470,7 +471,7 @@ public class MySqlExprParser extends SQLExprParser {
lexer.nextToken();
return userName;
}
if (lexer.token() == Token.ERROR) {
throw new ParserException("syntax error, token: " + lexer.token() + " " + lexer.stringVal() + ", pos : "
+ lexer.pos());
@@ -583,12 +584,12 @@ public class MySqlExprParser extends SQLExprParser {
lexer.nextToken();
SQLExpr rightExp = and();
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.BooleanOr, rightExp);
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.BooleanOr, rightExp, JdbcConstants.MYSQL);
} else if (lexer.token() == Token.XOR) {
lexer.nextToken();
SQLExpr rightExp = and();
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.BooleanXor, rightExp);
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.BooleanXor, rightExp, JdbcConstants.MYSQL);
} else {
break;
}
@@ -596,19 +597,19 @@ public class MySqlExprParser extends SQLExprParser {
return expr;
}
public SQLExpr additiveRest(SQLExpr expr) {
if (lexer.token() == Token.PLUS) {
lexer.nextToken();
SQLExpr rightExp = multiplicative();
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Add, rightExp);
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Add, rightExp, JdbcConstants.MYSQL);
expr = additiveRest(expr);
} else if (lexer.token() == Token.SUB) {
lexer.nextToken();
SQLExpr rightExp = multiplicative();
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Subtract, rightExp);
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Subtract, rightExp, JdbcConstants.MYSQL);
expr = additiveRest(expr);
}
@@ -845,7 +846,7 @@ public class MySqlExprParser extends SQLExprParser {
}
return aggregateExpr;
}
public MySqlSelectGroupByExpr parseSelectGroupByItem() {
MySqlSelectGroupByExpr item = new MySqlSelectGroupByExpr();
@@ -80,6 +80,7 @@ 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 OracleExprParser extends SQLExprParser {
@@ -139,11 +140,13 @@ public class OracleExprParser extends SQLExprParser {
public OracleExprParser(Lexer lexer){
super(lexer);
this.aggregateFunctions = AGGREGATE_FUNCTIONS;
this.dbType = JdbcConstants.ORACLE;
}
public OracleExprParser(String text){
this(new OracleLexer(text));
this.lexer.nextToken();
this.dbType = JdbcConstants.ORACLE;
}
protected boolean isCharType(String dataTypeName) {
@@ -966,14 +969,14 @@ public class OracleExprParser extends SQLExprParser {
if (lexer.token() == Token.NOT) {
lexer.nextToken();
SQLExpr rightExpr = primary();
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.IsNot, rightExpr);
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.IsNot, rightExpr, getDbType());
} else if (identifierEquals("A")) {
lexer.nextToken();
accept(Token.SET);
expr = new OracleIsSetExpr(expr);
} else {
SQLExpr rightExpr = primary();
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Is, rightExpr);
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Is, rightExpr, getDbType());
}
return expr;
@@ -1016,14 +1019,14 @@ public class OracleExprParser extends SQLExprParser {
rightExp = equalityRest(rightExp);
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Equality, rightExp);
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Equality, rightExp, getDbType());
} else if (lexer.token() == Token.BANGEQ) {
lexer.nextToken();
rightExp = shift();
rightExp = equalityRest(rightExp);
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.NotEqual, rightExp);
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.NotEqual, rightExp, getDbType());
}
return expr;
@@ -1113,7 +1116,7 @@ public class OracleExprParser extends SQLExprParser {
if (lexer.token() == Token.COLONEQ) {
lexer.nextToken();
SQLExpr right = expr();
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Assignment, right);
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Assignment, right, getDbType());
}
return expr;
@@ -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);
}
@@ -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) {
}
}
@@ -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;
}
}
@@ -33,6 +33,7 @@ import com.alibaba.druid.sql.dialect.sqlserver.ast.expr.SQLServerObjectReference
import com.alibaba.druid.sql.parser.Lexer;
import com.alibaba.druid.sql.parser.SQLExprParser;
import com.alibaba.druid.sql.parser.Token;
import com.alibaba.druid.util.JdbcConstants;
public class SQLServerExprParser extends SQLExprParser {
@@ -40,12 +41,14 @@ public class SQLServerExprParser extends SQLExprParser {
public SQLServerExprParser(Lexer lexer){
super(lexer);
this.dbType = JdbcConstants.SQL_SERVER;
this.aggregateFunctions = AGGREGATE_FUNCTIONS;
}
public SQLServerExprParser(String sql){
this(new SQLServerLexer(sql));
this.lexer.nextToken();
this.dbType = JdbcConstants.SQL_SERVER;
}
public SQLExpr primary() {
@@ -498,7 +498,15 @@ public class Lexer {
scanChar();
if (ch == '|') {
scanChar();
token = Token.BARBAR;
if (ch == '/') {
scanChar();
token = Token.BARBARSLASH;
} else {
token = Token.BARBAR;
}
} else if (ch == '/') {
scanChar();
token = Token.BARSLASH;
} else {
token = Token.BAR;
}
@@ -563,6 +571,9 @@ public class Lexer {
} else if (ch == '<') {
scanChar();
token = Token.BANGLT;
} else if (ch == '!') {
scanChar();
token = Token.BANGBANG; // postsql
} else {
token = Token.BANG;
}
@@ -149,7 +149,7 @@ public class SQLExprParser extends SQLParser {
if (lexer.token() == Token.CARET) {
lexer.nextToken();
SQLExpr rightExp = primary();
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.BitwiseXor, rightExp);
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.BitwiseXor, rightExp, getDbType());
expr = bitXorRest(expr);
}
@@ -165,17 +165,17 @@ public class SQLExprParser extends SQLParser {
if (lexer.token() == Token.STAR) {
lexer.nextToken();
SQLExpr rightExp = bitXor();
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Multiply, rightExp);
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Multiply, rightExp, getDbType());
expr = multiplicativeRest(expr);
} else if (lexer.token() == Token.SLASH) {
lexer.nextToken();
SQLExpr rightExp = bitXor();
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Divide, rightExp);
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Divide, rightExp, getDbType());
expr = multiplicativeRest(expr);
} else if (lexer.token() == Token.PERCENT) {
lexer.nextToken();
SQLExpr rightExp = bitXor();
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Modulus, rightExp);
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Modulus, rightExp, getDbType());
expr = multiplicativeRest(expr);
}
return expr;
@@ -997,7 +997,7 @@ public class SQLExprParser extends SQLParser {
while (lexer.token() == Token.AMP) {
lexer.nextToken();
SQLExpr rightExp = shift();
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.BitwiseAnd, rightExp);
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.BitwiseAnd, rightExp, getDbType());
}
return expr;
}
@@ -1011,7 +1011,7 @@ public class SQLExprParser extends SQLParser {
while (lexer.token() == Token.BAR) {
lexer.nextToken();
SQLExpr rightExp = bitAnd();
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.BitwiseOr, rightExp);
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.BitwiseOr, rightExp, getDbType());
expr = bitAndRest(expr);
}
return expr;
@@ -1033,18 +1033,18 @@ public class SQLExprParser extends SQLParser {
}
rightExp = equalityRest(rightExp);
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Equality, rightExp);
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Equality, rightExp, getDbType());
} else if (lexer.token() == Token.BANGEQ) {
lexer.nextToken();
rightExp = bitOr();
rightExp = equalityRest(rightExp);
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.NotEqual, rightExp);
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.NotEqual, rightExp, getDbType());
} else if (lexer.token() == Token.COLONEQ) {
lexer.nextToken();
rightExp = expr();
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Assignment, rightExp);
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Assignment, rightExp, getDbType());
}
return expr;
@@ -1092,18 +1092,18 @@ public class SQLExprParser extends SQLParser {
lexer.nextToken();
SQLExpr rightExp = multiplicative();
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Add, rightExp);
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Add, rightExp, getDbType());
expr = additiveRest(expr);
} else if (lexer.token() == Token.BARBAR) {
lexer.nextToken();
SQLExpr rightExp = multiplicative();
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Concat, rightExp);
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Concat, rightExp, getDbType());
expr = additiveRest(expr);
} else if (lexer.token() == Token.SUB) {
lexer.nextToken();
SQLExpr rightExp = multiplicative();
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Subtract, rightExp);
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Subtract, rightExp, getDbType());
expr = additiveRest(expr);
}
@@ -1120,13 +1120,13 @@ public class SQLExprParser extends SQLParser {
lexer.nextToken();
SQLExpr rightExp = additive();
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.LeftShift, rightExp);
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.LeftShift, rightExp, getDbType());
expr = shiftRest(expr);
} else if (lexer.token() == Token.GTGT) {
lexer.nextToken();
SQLExpr rightExp = additive();
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.RightShift, rightExp);
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.RightShift, rightExp, getDbType());
expr = shiftRest(expr);
}
@@ -1144,7 +1144,7 @@ public class SQLExprParser extends SQLParser {
lexer.nextToken();
SQLExpr rightExp = relational();
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.BooleanAnd, rightExp);
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.BooleanAnd, rightExp, getDbType());
} else {
break;
}
@@ -1165,12 +1165,12 @@ public class SQLExprParser extends SQLParser {
lexer.nextToken();
SQLExpr rightExp = and();
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.BooleanOr, rightExp);
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.BooleanOr, rightExp, getDbType());
} else if (lexer.token() == Token.XOR) {
lexer.nextToken();
SQLExpr rightExp = and();
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.BooleanXor, rightExp);
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.BooleanXor, rightExp, getDbType());
} else {
break;
}
@@ -1198,7 +1198,7 @@ public class SQLExprParser extends SQLParser {
}
rightExp = bitOr();
expr = new SQLBinaryOpExpr(expr, op, rightExp);
expr = new SQLBinaryOpExpr(expr, op, rightExp, getDbType());
// expr = relationalRest(expr);
} else if (lexer.token() == Token.LTEQ) {
lexer.nextToken();
@@ -1206,12 +1206,12 @@ public class SQLExprParser extends SQLParser {
// rightExp = relationalRest(rightExp);
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.LessThanOrEqual, rightExp);
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.LessThanOrEqual, rightExp, getDbType());
} else if (lexer.token() == Token.LTEQGT) {
lexer.nextToken();
rightExp = bitOr();
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.LessThanOrEqualOrGreaterThan, rightExp);
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.LessThanOrEqualOrGreaterThan, rightExp, getDbType());
} else if (lexer.token() == Token.GT) {
SQLBinaryOperator op = SQLBinaryOperator.GreaterThan;
@@ -1224,47 +1224,47 @@ public class SQLExprParser extends SQLParser {
rightExp = bitOr();
expr = new SQLBinaryOpExpr(expr, op, rightExp);
expr = new SQLBinaryOpExpr(expr, op, rightExp, getDbType());
} else if (lexer.token() == Token.GTEQ) {
lexer.nextToken();
rightExp = bitOr();
// rightExp = relationalRest(rightExp);
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.GreaterThanOrEqual, rightExp);
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.GreaterThanOrEqual, rightExp, getDbType());
} else if (lexer.token() == Token.BANGLT) {
lexer.nextToken();
rightExp = bitOr();
// rightExp = relationalRest(rightExp);
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.NotLessThan, rightExp);
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.NotLessThan, rightExp, getDbType());
} else if (lexer.token() == Token.BANGGT) {
lexer.nextToken();
rightExp = bitOr();
rightExp = relationalRest(rightExp);
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.NotGreaterThan, rightExp);
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.NotGreaterThan, rightExp, getDbType());
} else if (lexer.token() == Token.LTGT) {
lexer.nextToken();
rightExp = bitOr();
// rightExp = relationalRest(rightExp);
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.LessThanOrGreater, rightExp);
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.LessThanOrGreater, rightExp, getDbType());
} else if (lexer.token() == Token.LIKE) {
lexer.nextToken();
rightExp = bitOr();
// rightExp = relationalRest(rightExp);
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Like, rightExp);
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Like, rightExp, getDbType());
if (lexer.token() == Token.ESCAPE) {
lexer.nextToken();
rightExp = primary();
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Escape, rightExp);
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Escape, rightExp, getDbType());
}
} else if (identifierEquals("RLIKE")) {
lexer.nextToken();
@@ -1272,7 +1272,7 @@ public class SQLExprParser extends SQLParser {
rightExp = relationalRest(rightExp);
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.RLike, rightExp);
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.RLike, rightExp, getDbType());
} else if (lexer.token() == (Token.NOT)) {
lexer.nextToken();
expr = notRationalRest(expr);
@@ -1288,10 +1288,10 @@ public class SQLExprParser extends SQLParser {
if (lexer.token() == (Token.NOT)) {
lexer.nextToken();
SQLExpr rightExpr = primary();
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.IsNot, rightExpr);
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.IsNot, rightExpr, getDbType());
} else {
SQLExpr rightExpr = primary();
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Is, rightExpr);
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Is, rightExpr, getDbType());
}
} else if (lexer.token() == Token.IN) {
expr = inRest(expr);
@@ -1307,12 +1307,12 @@ public class SQLExprParser extends SQLParser {
rightExp = relationalRest(rightExp);
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.NotLike, rightExp);
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.NotLike, rightExp, getDbType());
if (lexer.token() == Token.ESCAPE) {
lexer.nextToken();
rightExp = expr();
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Escape, rightExp);
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Escape, rightExp, getDbType());
}
} else if (lexer.token() == Token.IN) {
lexer.nextToken();
@@ -1352,7 +1352,7 @@ public class SQLExprParser extends SQLParser {
rightExp = relationalRest(rightExp);
return new SQLBinaryOpExpr(expr, SQLBinaryOperator.NotRLike, rightExp);
return new SQLBinaryOpExpr(expr, SQLBinaryOperator.NotRLike, rightExp, getDbType());
} else {
throw new ParserException("TODO " + lexer.token());
}
@@ -264,6 +264,7 @@ public enum Token {
GT(">"),
LT("<"),
BANG("!"),
BANGBANG("!!"),
TILDE("~"),
QUES("?"),
COLON(":"),
@@ -279,6 +280,8 @@ public enum Token {
BANGLT("!<"),
AMPAMP("&&"),
BARBAR("||"),
BARBARSLASH("||/"),
BARSLASH("|/"),
PLUS("+"),
SUB("-"),
STAR("*"),
@@ -289,7 +292,9 @@ public enum Token {
PERCENT("%"),
LTLT("<<"),
GTGT(">>"),
MONKEYS_AT("@");
MONKEYS_AT("@"),
POUND("#")
;
public final String name;
@@ -583,15 +583,7 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Printab
if (expr instanceof SQLBinaryOpExpr) {
SQLBinaryOpExpr binaryOpExpr = (SQLBinaryOpExpr) expr;
switch (binaryOpExpr.getOperator()) {
case BooleanAnd:
case BooleanOr:
case BooleanXor:
needQuote = true;
break;
default:
break;
}
needQuote = binaryOpExpr.getOperator().isLogical();
}
if (needQuote) {
@@ -18,4 +18,6 @@ pg_trigger_depth
session_user
user
version
pg_sleep
pg_sleep
pg_sleep_for
pg_sleep_until
@@ -0,0 +1,59 @@
/*
* Copyright 1999-2011 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.bvt.sql.postgresql;
import java.util.List;
import org.junit.Assert;
import com.alibaba.druid.sql.PGTest;
import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.dialect.postgresql.parser.PGSQLStatementParser;
import com.alibaba.druid.sql.dialect.postgresql.visitor.PGSchemaStatVisitor;
import com.alibaba.druid.stat.TableStat;
public class PGInsertTest6_multi extends PGTest {
public void test_0() throws Exception {
String sql = "INSERT INTO products (product_no, name, price) VALUES"
+ "\n (1, 'Cheese', 9.99),"
+ "\n (2, 'Bread', 1.99),"
+ "\n (3, 'Milk', 2.99);";
PGSQLStatementParser parser = new PGSQLStatementParser(sql);
List<SQLStatement> statementList = parser.parseStatementList();
SQLStatement statemen = statementList.get(0);
print(statementList);
Assert.assertEquals(1, statementList.size());
PGSchemaStatVisitor visitor = new PGSchemaStatVisitor();
statemen.accept(visitor);
System.out.println("Tables : " + visitor.getTables());
System.out.println("fields : " + visitor.getColumns());
System.out.println("coditions : " + visitor.getConditions());
Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("products")));
Assert.assertEquals(3, visitor.getColumns().size());
Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("products", "product_no")));
Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("products", "name")));
Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("products", "price")));
}
}
@@ -0,0 +1,16 @@
package com.alibaba.druid.bvt.sql.postgresql.datatypes;
import com.alibaba.druid.sql.PGTest;
import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGTypeCastExpr;
import com.alibaba.druid.sql.dialect.postgresql.parser.PGExprParser;
public class BitsTest extends PGTest {
public void test_timestamp() throws Exception {
String sql = "44::bit(10)";
PGExprParser parser = new PGExprParser(sql);
PGTypeCastExpr expr = (PGTypeCastExpr) parser.expr();
System.out.println(expr.toString());
}
}
@@ -0,0 +1,23 @@
package com.alibaba.druid.bvt.sql.postgresql.expr;
import org.junit.Assert;
import com.alibaba.druid.sql.PGTest;
import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr;
import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGBoxExpr;
import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGPointExpr;
import com.alibaba.druid.sql.dialect.postgresql.parser.PGExprParser;
public class BoxTest extends PGTest {
public void test_timestamp() throws Exception {
String sql = "box '((0,0),(1,1))' + point '(2.0,0)'";
PGExprParser parser = new PGExprParser(sql);
SQLBinaryOpExpr binaryExpr = (SQLBinaryOpExpr) parser.expr();
PGBoxExpr box = (PGBoxExpr) binaryExpr.getLeft();
PGPointExpr point = (PGPointExpr) binaryExpr.getRight();
Assert.assertEquals("BOX '((0,0),(1,1))' + POINT '(2.0,0)'", binaryExpr.toString());
}
}
@@ -0,0 +1,15 @@
package com.alibaba.druid.bvt.sql.postgresql.expr;
import com.alibaba.druid.sql.PGTest;
import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGExtractExpr;
import com.alibaba.druid.sql.dialect.postgresql.parser.PGExprParser;
public class ExtractTest_Year extends PGTest {
public void test_timestamp() throws Exception {
String sql = "EXTRACT(YEAR FROM TIMESTAMP '2001-02-16 20:38:40')";
PGExprParser parser = new PGExprParser(sql);
PGExtractExpr expr = (PGExtractExpr) parser.expr();
System.out.println(expr.toString());
}
}
@@ -0,0 +1,21 @@
package com.alibaba.druid.bvt.sql.postgresql.expr;
import org.junit.Assert;
import com.alibaba.druid.sql.PGTest;
import com.alibaba.druid.sql.ast.expr.SQLUnaryExpr;
import com.alibaba.druid.sql.ast.expr.SQLUnaryOperator;
import com.alibaba.druid.sql.dialect.postgresql.parser.PGExprParser;
public class PolygonTest extends PGTest {
public void test_timestamp() throws Exception {
String sql = "# '((1,0),(0,1),(-1,0))'";
PGExprParser parser = new PGExprParser(sql);
SQLUnaryExpr unaryExpr = (SQLUnaryExpr) parser.expr();
Assert.assertEquals(SQLUnaryOperator.Pound, unaryExpr.getOperator());
}
}