improved odps sql parser, support true/false/close, fixed issue #1294

This commit is contained in:
高铁
2016-06-25 17:11:51 +08:00
parent 7808fe9118
commit ee31a42afc
6 changed files with 217 additions and 92 deletions
@@ -77,6 +77,7 @@ public class OdpsExprParser extends SQLExprParser {
expr = expr();
}
String alias = null;
if (lexer.token() == Token.AS) {
lexer.nextToken();
@@ -88,7 +89,7 @@ public class OdpsExprParser extends SQLExprParser {
selectItem.setExpr(expr);
for (;;) {
String alias = lexer.stringVal();
alias = lexer.stringVal();
lexer.nextToken();
selectItem.getAliasList().add(alias);
@@ -103,10 +104,12 @@ public class OdpsExprParser extends SQLExprParser {
accept(Token.RPAREN);
return selectItem;
} else {
alias = alias();
}
} else {
alias = as();
}
final String alias = as();
SQLSelectItem item = new SQLSelectItem(expr, alias);
@@ -45,6 +45,8 @@ public class OdpsLexer extends Lexer {
map.put("LIMIT", Token.LIMIT);
map.put("IF", Token.IF);
map.put("DISTRIBUTE", Token.DISTRIBUTE);
map.put("TRUE", Token.TRUE);
map.put("FALSE", Token.FALSE);
DEFAULT_ODPS_KEYWORDS = new Keywords(map);
}
@@ -66,93 +66,7 @@ public class SQLParser {
if (lexer.token() == Token.AS) {
lexer.nextToken();
if (lexer.token() == Token.LITERAL_ALIAS) {
alias = '"' + lexer.stringVal() + '"';
lexer.nextToken();
} else if (lexer.token() == Token.IDENTIFIER) {
alias = lexer.stringVal();
lexer.nextToken();
} else if (lexer.token() == Token.LITERAL_CHARS) {
alias = "'" + lexer.stringVal() + "'";
lexer.nextToken();
} else {
switch (lexer.token()) {
case KEY:
case INDEX:
case CASE:
case MODEL:
case PCTFREE:
case INITRANS:
case MAXTRANS:
case SEGMENT:
case CREATION:
case IMMEDIATE:
case DEFERRED:
case STORAGE:
case NEXT:
case MINEXTENTS:
case MAXEXTENTS:
case MAXSIZE:
case PCTINCREASE:
case FLASH_CACHE:
case CELL_FLASH_CACHE:
case KEEP:
case NONE:
case LOB:
case STORE:
case ROW:
case CHUNK:
case CACHE:
case NOCACHE:
case LOGGING:
case NOCOMPRESS:
case KEEP_DUPLICATES:
case EXCEPTIONS:
case PURGE:
case INITIALLY:
case END:
case COMMENT:
case ENABLE:
case DISABLE:
case SEQUENCE:
case USER:
case ANALYZE:
case OPTIMIZE:
case GRANT:
case REVOKE:
case FULL:
case TO:
case NEW:
case INTERVAL:
case LOCK:
case LIMIT:
case IDENTIFIED:
case PASSWORD:
case BINARY:
case WINDOW:
case OFFSET:
case SHARE:
case START:
case CONNECT:
case MATCHED:
case ERRORS:
case REJECT:
case UNLIMITED:
case BEGIN:
case EXCLUSIVE:
case MODE:
case ADVISE:
case TYPE:
alias = lexer.stringVal();
lexer.nextToken();
return alias;
case QUES:
alias = "?";
lexer.nextToken();
default:
break;
}
}
alias = alias();
if (alias != null) {
while (lexer.token() == Token.DOT) {
@@ -205,6 +119,99 @@ public class SQLParser {
return alias;
}
protected String alias() {
String alias = null;
if (lexer.token() == Token.LITERAL_ALIAS) {
alias = '"' + lexer.stringVal() + '"';
lexer.nextToken();
} else if (lexer.token() == Token.IDENTIFIER) {
alias = lexer.stringVal();
lexer.nextToken();
} else if (lexer.token() == Token.LITERAL_CHARS) {
alias = "'" + lexer.stringVal() + "'";
lexer.nextToken();
} else {
switch (lexer.token()) {
case KEY:
case INDEX:
case CASE:
case MODEL:
case PCTFREE:
case INITRANS:
case MAXTRANS:
case SEGMENT:
case CREATION:
case IMMEDIATE:
case DEFERRED:
case STORAGE:
case NEXT:
case MINEXTENTS:
case MAXEXTENTS:
case MAXSIZE:
case PCTINCREASE:
case FLASH_CACHE:
case CELL_FLASH_CACHE:
case KEEP:
case NONE:
case LOB:
case STORE:
case ROW:
case CHUNK:
case CACHE:
case NOCACHE:
case LOGGING:
case NOCOMPRESS:
case KEEP_DUPLICATES:
case EXCEPTIONS:
case PURGE:
case INITIALLY:
case END:
case COMMENT:
case ENABLE:
case DISABLE:
case SEQUENCE:
case USER:
case ANALYZE:
case OPTIMIZE:
case GRANT:
case REVOKE:
case FULL:
case TO:
case NEW:
case INTERVAL:
case LOCK:
case LIMIT:
case IDENTIFIED:
case PASSWORD:
case BINARY:
case WINDOW:
case OFFSET:
case SHARE:
case START:
case CONNECT:
case MATCHED:
case ERRORS:
case REJECT:
case UNLIMITED:
case BEGIN:
case EXCLUSIVE:
case MODE:
case ADVISE:
case TYPE:
case CLOSE:
alias = lexer.stringVal();
lexer.nextToken();
return alias;
case QUES:
alias = "?";
lexer.nextToken();
default:
break;
}
}
return alias;
}
protected void printError(Token token) {
String arround;
if (lexer.mark >= 0 && (lexer.text.length() > lexer.mark + 30)) {
@@ -24,8 +24,6 @@ import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.dialect.db2.parser.DB2StatementParser;
import com.alibaba.druid.sql.dialect.db2.visitor.DB2SchemaStatVisitor;
import com.alibaba.druid.stat.TableStat;
import com.alibaba.druid.stat.TableStat.Column;
import com.alibaba.druid.util.JdbcConstants;
public class DB2DropSequenceTest_0 extends DB2Test {
@@ -0,0 +1,56 @@
/*
* Copyright 1999-2101 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.odps;
import java.util.List;
import org.junit.Assert;
import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.visitor.SchemaStatVisitor;
import com.alibaba.druid.util.JdbcConstants;
import junit.framework.TestCase;
public class OdpsSelectTest6 extends TestCase {
public void test_select() throws Exception {
String sql = "select true from abc";//
Assert.assertEquals("SELECT true"
+ "\nFROM abc", SQLUtils.formatOdps(sql));
Assert.assertEquals("select true"
+ "\nfrom abc", SQLUtils.formatOdps(sql, SQLUtils.DEFAULT_LCASE_FORMAT_OPTION));
List<SQLStatement> statementList = SQLUtils.parseStatements(sql, JdbcConstants.ODPS);
SQLStatement stmt = statementList.get(0);
Assert.assertEquals(1, statementList.size());
SchemaStatVisitor visitor = SQLUtils.createSchemaStatVisitor(JdbcConstants.ODPS);
stmt.accept(visitor);
// System.out.println("Tables : " + visitor.getTables());
// System.out.println("fields : " + visitor.getColumns());
// System.out.println("coditions : " + visitor.getConditions());
// System.out.println("orderBy : " + visitor.getOrderByColumns());
Assert.assertEquals(1, visitor.getTables().size());
Assert.assertEquals(0, visitor.getColumns().size());
Assert.assertEquals(0, visitor.getConditions().size());
}
}
@@ -0,0 +1,59 @@
/*
* Copyright 1999-2101 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.odps;
import java.util.List;
import org.junit.Assert;
import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.visitor.SchemaStatVisitor;
import com.alibaba.druid.stat.TableStat.Column;
import com.alibaba.druid.util.JdbcConstants;
import junit.framework.TestCase;
public class OdpsSelectTest7 extends TestCase {
public void test_select() throws Exception {
String sql = "select name as close from abc";//
Assert.assertEquals("SELECT name AS close"
+ "\nFROM abc", SQLUtils.formatOdps(sql));
Assert.assertEquals("select name as close"
+ "\nfrom abc", SQLUtils.formatOdps(sql, SQLUtils.DEFAULT_LCASE_FORMAT_OPTION));
List<SQLStatement> statementList = SQLUtils.parseStatements(sql, JdbcConstants.ODPS);
SQLStatement stmt = statementList.get(0);
Assert.assertEquals(1, statementList.size());
SchemaStatVisitor visitor = SQLUtils.createSchemaStatVisitor(JdbcConstants.ODPS);
stmt.accept(visitor);
// System.out.println("Tables : " + visitor.getTables());
// System.out.println("fields : " + visitor.getColumns());
// System.out.println("coditions : " + visitor.getConditions());
// System.out.println("orderBy : " + visitor.getOrderByColumns());
Assert.assertEquals(1, visitor.getTables().size());
Assert.assertEquals(1, visitor.getColumns().size());
Assert.assertEquals(0, visitor.getConditions().size());
Assert.assertTrue(visitor.getColumns().contains(new Column("abc", "name")));
}
}