mirror of
https://github.com/alibaba/druid.git
synced 2023-03-04 19:17:16 +00:00
Merge pull request #482 from wenshao/master
add odps sql parser support
This commit is contained in:
@@ -27,6 +27,7 @@ import com.alibaba.druid.sql.dialect.db2.visitor.DB2OutputVisitor;
|
||||
import com.alibaba.druid.sql.dialect.db2.visitor.DB2SchemaStatVisitor;
|
||||
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlOutputVisitor;
|
||||
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlSchemaStatVisitor;
|
||||
import com.alibaba.druid.sql.dialect.odps.visitor.OdpsOutputVisitor;
|
||||
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleOutputVisitor;
|
||||
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleSchemaStatVisitor;
|
||||
import com.alibaba.druid.sql.dialect.postgresql.visitor.PGOutputVisitor;
|
||||
@@ -68,6 +69,10 @@ public class SQLUtils {
|
||||
if (JdbcUtils.DB2.equals(dbType)) {
|
||||
return toDB2String(sqlObject);
|
||||
}
|
||||
|
||||
if (JdbcUtils.ODPS.equals(dbType)) {
|
||||
return toDB2String(sqlObject);
|
||||
}
|
||||
|
||||
return toSQLServerString(sqlObject);
|
||||
}
|
||||
@@ -80,10 +85,18 @@ public class SQLUtils {
|
||||
return sql;
|
||||
}
|
||||
|
||||
public static String toOdpsString(SQLObject sqlObject) {
|
||||
StringBuilder out = new StringBuilder();
|
||||
sqlObject.accept(new OdpsOutputVisitor(out));
|
||||
|
||||
String sql = out.toString();
|
||||
return sql;
|
||||
}
|
||||
|
||||
public static String toMySqlString(SQLObject sqlObject) {
|
||||
StringBuilder out = new StringBuilder();
|
||||
sqlObject.accept(new MySqlOutputVisitor(out));
|
||||
|
||||
|
||||
String sql = out.toString();
|
||||
return sql;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
package com.alibaba.druid.sql.dialect.odps.ast;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLExpr;
|
||||
import com.alibaba.druid.sql.ast.SQLName;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLColumnDefinition;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLExprTableSource;
|
||||
import com.alibaba.druid.sql.dialect.odps.visitor.OdpsASTVisitor;
|
||||
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
|
||||
public class OdpsCreateTableStatement extends SQLCreateTableStatement {
|
||||
|
||||
private boolean ifNotExiists = false;
|
||||
|
||||
private SQLExprTableSource like;
|
||||
|
||||
protected SQLExpr comment;
|
||||
|
||||
protected List<SQLColumnDefinition> partitionColumns = new ArrayList<SQLColumnDefinition>(2);
|
||||
|
||||
public boolean isIfNotExiists() {
|
||||
return ifNotExiists;
|
||||
}
|
||||
|
||||
public void setIfNotExiists(boolean ifNotExiists) {
|
||||
this.ifNotExiists = ifNotExiists;
|
||||
}
|
||||
|
||||
public SQLExprTableSource getLike() {
|
||||
return like;
|
||||
}
|
||||
|
||||
public void setLike(SQLName like) {
|
||||
this.setLike(new SQLExprTableSource(like));
|
||||
}
|
||||
|
||||
public void setLike(SQLExprTableSource like) {
|
||||
this.like = like;
|
||||
}
|
||||
|
||||
public SQLExpr getComment() {
|
||||
return comment;
|
||||
}
|
||||
|
||||
public void setComment(SQLExpr comment) {
|
||||
this.comment = comment;
|
||||
}
|
||||
|
||||
public List<SQLColumnDefinition> getPartitionColumns() {
|
||||
return partitionColumns;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void accept0(SQLASTVisitor visitor) {
|
||||
accept0((OdpsASTVisitor) visitor);
|
||||
}
|
||||
|
||||
protected void accept0(OdpsASTVisitor visitor) {
|
||||
if (visitor.visit(this)) {
|
||||
this.acceptChild(visitor, tableSource);
|
||||
this.acceptChild(visitor, tableElementList);
|
||||
this.acceptChild(visitor, partitionColumns);
|
||||
}
|
||||
visitor.endVisit(this);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
package com.alibaba.druid.sql.dialect.odps.ast;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLName;
|
||||
import com.alibaba.druid.sql.ast.SQLObjectImpl;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLAssignItem;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLExprTableSource;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelect;
|
||||
import com.alibaba.druid.sql.dialect.odps.visitor.OdpsASTVisitor;
|
||||
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
|
||||
|
||||
public class OdpsInsert extends SQLObjectImpl {
|
||||
private boolean overwrite = false;
|
||||
private List<SQLAssignItem> partitions = new ArrayList<SQLAssignItem>();
|
||||
protected SQLExprTableSource tableSource;
|
||||
|
||||
private SQLSelect query;
|
||||
|
||||
public boolean isOverwrite() {
|
||||
return overwrite;
|
||||
}
|
||||
|
||||
public void setOverwrite(boolean overwrite) {
|
||||
this.overwrite = overwrite;
|
||||
}
|
||||
|
||||
public List<SQLAssignItem> getPartitions() {
|
||||
return partitions;
|
||||
}
|
||||
|
||||
public void setPartitions(List<SQLAssignItem> partitions) {
|
||||
this.partitions = partitions;
|
||||
}
|
||||
|
||||
|
||||
public SQLExprTableSource getTableSource() {
|
||||
return tableSource;
|
||||
}
|
||||
|
||||
public void setTableSource(SQLExprTableSource tableSource) {
|
||||
if (tableSource != null) {
|
||||
tableSource.setParent(this);
|
||||
}
|
||||
this.tableSource = tableSource;
|
||||
}
|
||||
|
||||
public void setTableSource(SQLName tableName) {
|
||||
this.setTableSource(new SQLExprTableSource(tableName));
|
||||
}
|
||||
|
||||
public SQLSelect getQuery() {
|
||||
return query;
|
||||
}
|
||||
|
||||
public void setQuery(SQLSelect query) {
|
||||
if (query != null) {
|
||||
query.setParent(this);
|
||||
}
|
||||
this.query = query;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void accept0(SQLASTVisitor visitor) {
|
||||
accept0((OdpsASTVisitor) visitor);
|
||||
}
|
||||
|
||||
protected void accept0(OdpsASTVisitor visitor) {
|
||||
if (visitor.visit(this)) {
|
||||
acceptChild(visitor, tableSource);
|
||||
acceptChild(visitor, partitions);
|
||||
acceptChild(visitor, query);
|
||||
}
|
||||
visitor.endVisit(this);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.alibaba.druid.sql.dialect.odps.ast;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLStatement;
|
||||
import com.alibaba.druid.sql.ast.SQLStatementImpl;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSubqueryTableSource;
|
||||
import com.alibaba.druid.sql.dialect.odps.visitor.OdpsASTVisitor;
|
||||
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
|
||||
public class OdpsInsertStatement extends SQLStatementImpl implements SQLStatement {
|
||||
|
||||
private SQLSubqueryTableSource from;
|
||||
|
||||
private List<OdpsInsert> items = new ArrayList<OdpsInsert>();
|
||||
|
||||
public void setFrom(SQLSubqueryTableSource from) {
|
||||
this.from = from;
|
||||
}
|
||||
|
||||
public SQLSubqueryTableSource getFrom() {
|
||||
return from;
|
||||
}
|
||||
|
||||
public List<OdpsInsert> getItems() {
|
||||
return items;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void accept0(SQLASTVisitor visitor) {
|
||||
accept0((OdpsASTVisitor) visitor);
|
||||
}
|
||||
|
||||
protected void accept0(OdpsASTVisitor visitor) {
|
||||
if (visitor.visit(this)) {
|
||||
acceptChild(visitor, from);
|
||||
acceptChild(visitor, items);
|
||||
}
|
||||
visitor.endVisit(this);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
package com.alibaba.druid.sql.dialect.odps.parser;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLName;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLColumnDefinition;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement;
|
||||
import com.alibaba.druid.sql.dialect.odps.ast.OdpsCreateTableStatement;
|
||||
import com.alibaba.druid.sql.parser.ParserException;
|
||||
import com.alibaba.druid.sql.parser.SQLCreateTableParser;
|
||||
import com.alibaba.druid.sql.parser.SQLExprParser;
|
||||
import com.alibaba.druid.sql.parser.Token;
|
||||
|
||||
public class OdpsCreateTableParser extends SQLCreateTableParser {
|
||||
|
||||
public OdpsCreateTableParser(String sql){
|
||||
super(new OdpsExprParser(sql));
|
||||
}
|
||||
|
||||
public OdpsCreateTableParser(SQLExprParser exprParser){
|
||||
super(exprParser);
|
||||
}
|
||||
|
||||
public SQLCreateTableStatement parseCrateTable(boolean acceptCreate) {
|
||||
OdpsCreateTableStatement stmt = new OdpsCreateTableStatement();
|
||||
|
||||
if (acceptCreate) {
|
||||
accept(Token.CREATE);
|
||||
}
|
||||
|
||||
accept(Token.TABLE);
|
||||
|
||||
if (lexer.token() == Token.IF || identifierEquals("IF")) {
|
||||
lexer.nextToken();
|
||||
accept(Token.NOT);
|
||||
accept(Token.EXISTS);
|
||||
|
||||
stmt.setIfNotExiists(true);
|
||||
}
|
||||
|
||||
stmt.setName(this.exprParser.name());
|
||||
|
||||
if (lexer.token() == Token.LIKE) {
|
||||
lexer.nextToken();
|
||||
SQLName name = this.exprParser.name();
|
||||
stmt.setLike(name);
|
||||
} else {
|
||||
accept(Token.LPAREN);
|
||||
|
||||
for (;;) {
|
||||
if (lexer.token() != Token.IDENTIFIER) {
|
||||
throw new ParserException("expect identifier");
|
||||
}
|
||||
|
||||
SQLColumnDefinition column = this.exprParser.parseColumn();
|
||||
stmt.getTableElementList().add(column);
|
||||
|
||||
if (!(lexer.token() == (Token.COMMA))) {
|
||||
break;
|
||||
} else {
|
||||
lexer.nextToken();
|
||||
}
|
||||
}
|
||||
accept(Token.RPAREN);
|
||||
}
|
||||
|
||||
if (lexer.token() == Token.COMMENT) {
|
||||
lexer.nextToken();
|
||||
stmt.setComment(this.exprParser.primary());
|
||||
}
|
||||
|
||||
if (lexer.token() == Token.PARTITIONED) {
|
||||
lexer.nextToken();
|
||||
accept(Token.BY);
|
||||
accept(Token.LPAREN);
|
||||
|
||||
for (;;) {
|
||||
if (lexer.token() != Token.IDENTIFIER) {
|
||||
throw new ParserException("expect identifier");
|
||||
}
|
||||
|
||||
SQLColumnDefinition column = this.exprParser.parseColumn();
|
||||
stmt.getPartitionColumns().add(column);
|
||||
|
||||
if (!(lexer.token() == (Token.COMMA))) {
|
||||
break;
|
||||
} else {
|
||||
lexer.nextToken();
|
||||
}
|
||||
}
|
||||
|
||||
accept(Token.RPAREN);
|
||||
}
|
||||
|
||||
return stmt;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.alibaba.druid.sql.dialect.odps.parser;
|
||||
|
||||
import com.alibaba.druid.sql.parser.Lexer;
|
||||
import com.alibaba.druid.sql.parser.SQLExprParser;
|
||||
|
||||
public class OdpsExprParser extends SQLExprParser {
|
||||
|
||||
public final static String[] AGGREGATE_FUNCTIONS = { "AVG", //
|
||||
"COUNT", //
|
||||
"LAG",
|
||||
"LEAD",
|
||||
"MAX", //
|
||||
"MIN", //
|
||||
"STDDEV", //
|
||||
"SUM", //
|
||||
"ROW_NUMBER"//
|
||||
};
|
||||
|
||||
public OdpsExprParser(Lexer lexer){
|
||||
super(lexer);
|
||||
|
||||
this.aggregateFunctions = AGGREGATE_FUNCTIONS;
|
||||
}
|
||||
|
||||
public OdpsExprParser(String sql){
|
||||
this(new OdpsLexer(sql));
|
||||
this.lexer.nextToken();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
package com.alibaba.druid.sql.dialect.odps.parser;
|
||||
|
||||
import static com.alibaba.druid.sql.parser.LayoutCharacters.EOI;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.alibaba.druid.sql.parser.Keywords;
|
||||
import com.alibaba.druid.sql.parser.Lexer;
|
||||
import com.alibaba.druid.sql.parser.NotAllowCommentException;
|
||||
import com.alibaba.druid.sql.parser.Token;
|
||||
|
||||
public class OdpsLexer extends Lexer {
|
||||
|
||||
public final static Keywords DEFAULT_ODPS_KEYWORDS;
|
||||
|
||||
static {
|
||||
Map<String, Token> map = new HashMap<String, Token>();
|
||||
|
||||
map.putAll(Keywords.DEFAULT_KEYWORDS.getKeywords());
|
||||
|
||||
map.put("PARTITION", Token.PARTITION);
|
||||
map.put("PARTITIONED", Token.PARTITIONED);
|
||||
map.put("OVERWRITE", Token.OVERWRITE);
|
||||
map.put("OVER", Token.OVER);
|
||||
|
||||
DEFAULT_ODPS_KEYWORDS = new Keywords(map);
|
||||
}
|
||||
|
||||
public OdpsLexer(String input){
|
||||
super(input);
|
||||
super.keywods = DEFAULT_ODPS_KEYWORDS;
|
||||
}
|
||||
|
||||
public void scanComment() {
|
||||
if (ch != '/' && ch != '-') {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
mark = pos;
|
||||
bufPos = 0;
|
||||
scanChar();
|
||||
|
||||
// /*+ */
|
||||
if (ch == '*') {
|
||||
scanChar();
|
||||
bufPos++;
|
||||
|
||||
while (ch == ' ') {
|
||||
scanChar();
|
||||
bufPos++;
|
||||
}
|
||||
|
||||
boolean isHint = false;
|
||||
int startHintSp = bufPos + 1;
|
||||
if (ch == '+') {
|
||||
isHint = true;
|
||||
scanChar();
|
||||
bufPos++;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
if (ch == '*' && charAt(pos + 1) == '/') {
|
||||
bufPos += 2;
|
||||
scanChar();
|
||||
scanChar();
|
||||
break;
|
||||
}
|
||||
|
||||
scanChar();
|
||||
bufPos++;
|
||||
}
|
||||
|
||||
if (isHint) {
|
||||
stringVal = subString(mark + startHintSp, (bufPos - startHintSp) - 1);
|
||||
token = Token.HINT;
|
||||
} else {
|
||||
stringVal = subString(mark, bufPos);
|
||||
token = Token.MULTI_LINE_COMMENT;
|
||||
}
|
||||
|
||||
if (token != Token.HINT && !isAllowComment()) {
|
||||
throw new NotAllowCommentException();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isAllowComment()) {
|
||||
throw new NotAllowCommentException();
|
||||
}
|
||||
|
||||
if (ch == '/' || ch == '-') {
|
||||
scanChar();
|
||||
bufPos++;
|
||||
|
||||
for (;;) {
|
||||
if (ch == '\r') {
|
||||
if (charAt(pos + 1) == '\n') {
|
||||
bufPos += 2;
|
||||
scanChar();
|
||||
break;
|
||||
}
|
||||
bufPos++;
|
||||
break;
|
||||
} else if (ch == EOI) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (ch == '\n') {
|
||||
scanChar();
|
||||
bufPos++;
|
||||
break;
|
||||
}
|
||||
|
||||
scanChar();
|
||||
bufPos++;
|
||||
}
|
||||
|
||||
stringVal = subString(mark + 1, bufPos);
|
||||
token = Token.LINE_COMMENT;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
package com.alibaba.druid.sql.dialect.odps.parser;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLExpr;
|
||||
import com.alibaba.druid.sql.ast.SQLStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLAssignItem;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelect;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSubqueryTableSource;
|
||||
import com.alibaba.druid.sql.dialect.odps.ast.OdpsInsert;
|
||||
import com.alibaba.druid.sql.dialect.odps.ast.OdpsInsertStatement;
|
||||
import com.alibaba.druid.sql.parser.SQLCreateTableParser;
|
||||
import com.alibaba.druid.sql.parser.SQLExprParser;
|
||||
import com.alibaba.druid.sql.parser.SQLSelectParser;
|
||||
import com.alibaba.druid.sql.parser.SQLStatementParser;
|
||||
import com.alibaba.druid.sql.parser.Token;
|
||||
|
||||
public class OdpsStatementParser extends SQLStatementParser {
|
||||
|
||||
public OdpsStatementParser(String sql){
|
||||
super(new OdpsExprParser(sql));
|
||||
}
|
||||
|
||||
public OdpsStatementParser(SQLExprParser exprParser){
|
||||
super(exprParser);
|
||||
}
|
||||
|
||||
public SQLCreateTableStatement parseCreateTable() {
|
||||
SQLCreateTableParser parser = new OdpsCreateTableParser(this.exprParser);
|
||||
return parser.parseCrateTable();
|
||||
}
|
||||
|
||||
public SQLCreateTableParser getSQLCreateTableParser() {
|
||||
return new OdpsCreateTableParser(this.exprParser);
|
||||
}
|
||||
|
||||
public boolean parseStatementListDialect(List<SQLStatement> statementList) {
|
||||
if (lexer.token() == Token.FROM) {
|
||||
SQLStatement stmt = this.parseInsert();
|
||||
statementList.add(stmt);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public SQLStatement parseInsert() {
|
||||
OdpsInsertStatement stmt = new OdpsInsertStatement();
|
||||
|
||||
if (lexer.token() == Token.FROM) {
|
||||
lexer.nextToken();
|
||||
accept(Token.LPAREN);
|
||||
|
||||
SQLSelectParser selectParser = createSQLSelectParser();
|
||||
SQLSelect select = selectParser.select();
|
||||
|
||||
accept(Token.RPAREN);
|
||||
|
||||
String alias = lexer.stringVal();
|
||||
accept(Token.IDENTIFIER);
|
||||
|
||||
SQLSubqueryTableSource from = new SQLSubqueryTableSource(select, alias);
|
||||
|
||||
stmt.setFrom(from);
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
OdpsInsert insert = parseOdpsInsert();
|
||||
stmt.getItems().add(insert);
|
||||
|
||||
if (lexer.token() != Token.INSERT) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return stmt;
|
||||
}
|
||||
|
||||
public OdpsInsert parseOdpsInsert() {
|
||||
OdpsInsert insert = new OdpsInsert();
|
||||
SQLSelectParser selectParser = createSQLSelectParser();
|
||||
|
||||
accept(Token.INSERT);
|
||||
|
||||
if (lexer.token() == Token.INTO) {
|
||||
lexer.nextToken();
|
||||
} else {
|
||||
accept(Token.OVERWRITE);
|
||||
insert.setOverwrite(true);
|
||||
}
|
||||
|
||||
accept(Token.TABLE);
|
||||
insert.setTableSource(this.exprParser.name());
|
||||
|
||||
if (lexer.token() == Token.PARTITION) {
|
||||
lexer.nextToken();
|
||||
accept(Token.LPAREN);
|
||||
for (;;) {
|
||||
SQLAssignItem ptExpr = new SQLAssignItem();
|
||||
ptExpr.setTarget(this.exprParser.name());
|
||||
if (lexer.token() == Token.EQ) {
|
||||
lexer.nextToken();
|
||||
SQLExpr ptValue = this.exprParser.expr();
|
||||
ptExpr.setValue(ptValue);
|
||||
}
|
||||
insert.getPartitions().add(ptExpr);
|
||||
if (!(lexer.token() == (Token.COMMA))) {
|
||||
break;
|
||||
} else {
|
||||
lexer.nextToken();
|
||||
}
|
||||
}
|
||||
accept(Token.RPAREN);
|
||||
}
|
||||
|
||||
SQLSelect query = selectParser.select();
|
||||
insert.setQuery(query);
|
||||
|
||||
return insert;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.alibaba.druid.sql.dialect.odps.visitor;
|
||||
|
||||
import com.alibaba.druid.sql.dialect.odps.ast.OdpsCreateTableStatement;
|
||||
import com.alibaba.druid.sql.dialect.odps.ast.OdpsInsert;
|
||||
import com.alibaba.druid.sql.dialect.odps.ast.OdpsInsertStatement;
|
||||
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
|
||||
public interface OdpsASTVisitor extends SQLASTVisitor {
|
||||
|
||||
void endVisit(OdpsCreateTableStatement x);
|
||||
|
||||
boolean visit(OdpsCreateTableStatement x);
|
||||
|
||||
void endVisit(OdpsInsertStatement x);
|
||||
|
||||
boolean visit(OdpsInsertStatement x);
|
||||
|
||||
void endVisit(OdpsInsert x);
|
||||
|
||||
boolean visit(OdpsInsert x);
|
||||
}
|
||||
@@ -0,0 +1,263 @@
|
||||
package com.alibaba.druid.sql.dialect.odps.visitor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLStatement;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLCaseExpr;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLAssignItem;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLJoinTableSource;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLJoinTableSource.JoinType;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelectGroupByClause;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelectItem;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSubqueryTableSource;
|
||||
import com.alibaba.druid.sql.dialect.odps.ast.OdpsCreateTableStatement;
|
||||
import com.alibaba.druid.sql.dialect.odps.ast.OdpsInsert;
|
||||
import com.alibaba.druid.sql.dialect.odps.ast.OdpsInsertStatement;
|
||||
import com.alibaba.druid.sql.visitor.SQLASTOutputVisitor;
|
||||
|
||||
public class OdpsOutputVisitor extends SQLASTOutputVisitor implements OdpsASTVisitor {
|
||||
|
||||
public OdpsOutputVisitor(Appendable appender){
|
||||
super(appender);
|
||||
}
|
||||
|
||||
public boolean visit(OdpsCreateTableStatement x) {
|
||||
if (x.isIfNotExiists()) {
|
||||
print("CREATE TABLE IF NOT EXISTS ");
|
||||
} else {
|
||||
print("CREATE TABLE ");
|
||||
}
|
||||
|
||||
x.getName().accept(this);
|
||||
|
||||
x.getName().accept(this);
|
||||
|
||||
if (x.getLike() != null) {
|
||||
print(" LIKE ");
|
||||
x.getLike().accept(this);
|
||||
}
|
||||
|
||||
int size = x.getTableElementList().size();
|
||||
if (size > 0) {
|
||||
print(" (");
|
||||
incrementIndent();
|
||||
println();
|
||||
for (int i = 0; i < size; ++i) {
|
||||
if (i != 0) {
|
||||
print(", ");
|
||||
println();
|
||||
}
|
||||
x.getTableElementList().get(i).accept(this);
|
||||
}
|
||||
decrementIndent();
|
||||
println();
|
||||
print(")");
|
||||
}
|
||||
|
||||
if (x.getComment() != null) {
|
||||
println();
|
||||
print("COMMENT ");
|
||||
x.getComment().accept(this);
|
||||
}
|
||||
|
||||
int partitionSize = x.getPartitionColumns().size();
|
||||
if (partitionSize > 0) {
|
||||
println();
|
||||
print("PARTITIONED (");
|
||||
for (int i = 0; i < partitionSize; ++i) {
|
||||
if (i != 0) {
|
||||
print(", ");
|
||||
}
|
||||
x.getPartitionColumns().get(i).accept(this);
|
||||
}
|
||||
print(")");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(OdpsCreateTableStatement x) {
|
||||
super.endVisit((SQLCreateTableStatement) x);
|
||||
}
|
||||
|
||||
public SQLStatement parseInsert() {
|
||||
OdpsInsertStatement stmt = new OdpsInsertStatement();
|
||||
|
||||
return stmt;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(OdpsInsertStatement x) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(OdpsInsertStatement x) {
|
||||
if (x.getFrom() != null) {
|
||||
print("FROM (");
|
||||
incrementIndent();
|
||||
println();
|
||||
x.getFrom().getSelect().accept(this);
|
||||
decrementIndent();
|
||||
println();
|
||||
print(") ");
|
||||
print(x.getFrom().getAlias());
|
||||
}
|
||||
|
||||
for (OdpsInsert insert : x.getItems()) {
|
||||
println();
|
||||
println();
|
||||
insert.accept(this);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(OdpsInsert x) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(OdpsInsert x) {
|
||||
if (x.isOverwrite()) {
|
||||
print("INSERT OVERWRITE TABLE ");
|
||||
} else {
|
||||
print("INSERT INTO OVERWRITE ");
|
||||
}
|
||||
x.getTableSource().accept(this);
|
||||
|
||||
int partitions = x.getPartitions().size();
|
||||
if (partitions > 0) {
|
||||
print(" PARTITION (");
|
||||
for (int i = 0; i < partitions; ++i) {
|
||||
if (i != 0) {
|
||||
print(", ");
|
||||
}
|
||||
|
||||
SQLAssignItem assign = x.getPartitions().get(i);
|
||||
assign.getTarget().accept(this);
|
||||
|
||||
if (assign.getValue() != null) {
|
||||
print("=");
|
||||
assign.getValue().accept(this);
|
||||
}
|
||||
}
|
||||
print(")");
|
||||
}
|
||||
println();
|
||||
x.getQuery().accept(this);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean visit(SQLCaseExpr x) {
|
||||
incrementIndent();
|
||||
print("CASE ");
|
||||
if (x.getValueExpr() != null) {
|
||||
x.getValueExpr().accept(this);
|
||||
println();
|
||||
}
|
||||
|
||||
printAndAccept(x.getItems(), " ");
|
||||
|
||||
if (x.getElseExpr() != null) {
|
||||
println();
|
||||
print("ELSE ");
|
||||
x.getElseExpr().accept(this);
|
||||
}
|
||||
|
||||
println();
|
||||
print("END");
|
||||
decrementIndent();
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean visit(SQLSelectGroupByClause x) {
|
||||
int itemSize = x.getItems().size();
|
||||
if (itemSize > 0) {
|
||||
print("GROUP BY ");
|
||||
incrementIndent();
|
||||
for (int i = 0; i < itemSize; ++i) {
|
||||
if (i != 0) {
|
||||
println(", ");
|
||||
}
|
||||
x.getItems().get(i).accept(this);
|
||||
}
|
||||
decrementIndent();
|
||||
}
|
||||
|
||||
if (x.getHaving() != null) {
|
||||
println();
|
||||
print("HAVING ");
|
||||
x.getHaving().accept(this);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected void printSelectList(List<SQLSelectItem> selectList) {
|
||||
incrementIndent();
|
||||
for (int i = 0, size = selectList.size(); i < size; ++i) {
|
||||
if (i != 0) {
|
||||
print(", ");
|
||||
println();
|
||||
}
|
||||
|
||||
selectList.get(i).accept(this);
|
||||
}
|
||||
decrementIndent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(SQLSubqueryTableSource x) {
|
||||
print("(");
|
||||
incrementIndent();
|
||||
println();
|
||||
x.getSelect().accept(this);
|
||||
decrementIndent();
|
||||
println();
|
||||
print(")");
|
||||
|
||||
if (x.getAlias() != null) {
|
||||
print(' ');
|
||||
print(x.getAlias());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(SQLJoinTableSource x) {
|
||||
x.getLeft().accept(this);
|
||||
|
||||
if (x.getJoinType() == JoinType.COMMA) {
|
||||
print(",");
|
||||
} else {
|
||||
println();
|
||||
print(JoinType.toString(x.getJoinType()));
|
||||
}
|
||||
print(" ");
|
||||
x.getRight().accept(this);
|
||||
|
||||
if (x.getCondition() != null) {
|
||||
incrementIndent();
|
||||
print(" ON ");
|
||||
x.getCondition().accept(this);
|
||||
decrementIndent();
|
||||
}
|
||||
|
||||
if (x.getUsing().size() > 0) {
|
||||
print(" USING (");
|
||||
printAndAccept(x.getUsing(), ", ");
|
||||
print(")");
|
||||
}
|
||||
|
||||
if (x.getAlias() != null) {
|
||||
print(" AS ");
|
||||
print(x.getAlias());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package com.alibaba.druid.sql.dialect.odps.visitor;
|
||||
|
||||
import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement;
|
||||
import com.alibaba.druid.sql.dialect.odps.ast.OdpsCreateTableStatement;
|
||||
import com.alibaba.druid.sql.dialect.odps.ast.OdpsInsert;
|
||||
import com.alibaba.druid.sql.dialect.odps.ast.OdpsInsertStatement;
|
||||
import com.alibaba.druid.sql.visitor.SchemaStatVisitor;
|
||||
|
||||
|
||||
public class OdpsSchemaStatVisitor extends SchemaStatVisitor implements OdpsASTVisitor {
|
||||
|
||||
@Override
|
||||
public void endVisit(OdpsCreateTableStatement x) {
|
||||
super.endVisit((SQLCreateTableStatement) x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(OdpsCreateTableStatement x) {
|
||||
return super.visit((SQLCreateTableStatement) x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(OdpsInsertStatement x) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(OdpsInsertStatement x) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(OdpsInsert x) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(OdpsInsert x) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -667,7 +667,6 @@ public class Lexer {
|
||||
bufPos = 1;
|
||||
char ch;
|
||||
|
||||
boolean mybatisFlag = false;
|
||||
if (charAt(pos + 1) == '@') {
|
||||
ch = charAt(++pos);
|
||||
|
||||
@@ -675,7 +674,29 @@ public class Lexer {
|
||||
} else if (charAt(pos + 1) == '{') {
|
||||
pos++;
|
||||
bufPos++;
|
||||
mybatisFlag = true;
|
||||
|
||||
for (;;) {
|
||||
ch = charAt(++pos);
|
||||
|
||||
if (ch == '}') {
|
||||
break;
|
||||
}
|
||||
|
||||
bufPos++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ch != '}') {
|
||||
throw new ParserException("syntax error");
|
||||
}
|
||||
++pos;
|
||||
bufPos++;
|
||||
|
||||
this.ch = charAt(pos);
|
||||
|
||||
stringVal = addSymbol();
|
||||
token = Token.VARIANT;
|
||||
return;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
@@ -689,14 +710,6 @@ public class Lexer {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (mybatisFlag) {
|
||||
if (ch != '}') {
|
||||
throw new ParserException("syntax error");
|
||||
}
|
||||
++pos;
|
||||
bufPos++;
|
||||
}
|
||||
|
||||
this.ch = charAt(pos);
|
||||
|
||||
stringVal = addSymbol();
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -19,6 +19,7 @@ import com.alibaba.druid.sql.dialect.db2.parser.DB2ExprParser;
|
||||
import com.alibaba.druid.sql.dialect.db2.parser.DB2StatementParser;
|
||||
import com.alibaba.druid.sql.dialect.mysql.parser.MySqlExprParser;
|
||||
import com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser;
|
||||
import com.alibaba.druid.sql.dialect.odps.parser.OdpsExprParser;
|
||||
import com.alibaba.druid.sql.dialect.oracle.parser.OracleExprParser;
|
||||
import com.alibaba.druid.sql.dialect.oracle.parser.OracleStatementParser;
|
||||
import com.alibaba.druid.sql.dialect.postgresql.parser.PGExprParser;
|
||||
@@ -83,6 +84,10 @@ public class SQLParserUtils {
|
||||
if (JdbcUtils.DB2.equals(dbType)) {
|
||||
return new DB2ExprParser(sql);
|
||||
}
|
||||
|
||||
if (JdbcUtils.ODPS.equals(dbType)) {
|
||||
return new OdpsExprParser(sql);
|
||||
}
|
||||
|
||||
return new SQLExprParser(sql);
|
||||
}
|
||||
|
||||
@@ -240,6 +240,11 @@ public enum Token {
|
||||
// Oracle
|
||||
BINARY_FLOAT,
|
||||
BINARY_DOUBLE,
|
||||
|
||||
// odps,hive
|
||||
PARTITION,
|
||||
PARTITIONED,
|
||||
OVERWRITE,
|
||||
|
||||
LPAREN("("),
|
||||
RPAREN(")"),
|
||||
|
||||
@@ -144,9 +144,10 @@ import com.alibaba.druid.sql.ast.statement.SQLWithSubqueryClause;
|
||||
public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements PrintableVisitor {
|
||||
|
||||
protected final Appendable appender;
|
||||
private String indent = "\t";
|
||||
private int indentCount = 0;
|
||||
private boolean prettyFormat = true;
|
||||
private String indent = "\t";
|
||||
private int indentCount = 0;
|
||||
private boolean prettyFormat = true;
|
||||
protected int selectListNumberOfLine = 5;
|
||||
|
||||
private List<Object> parameters;
|
||||
|
||||
@@ -252,7 +253,7 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Printab
|
||||
incrementIndent();
|
||||
for (int i = 0, size = selectList.size(); i < size; ++i) {
|
||||
if (i != 0) {
|
||||
if (i % 5 == 0) {
|
||||
if (i % selectListNumberOfLine == 0) {
|
||||
println();
|
||||
}
|
||||
|
||||
@@ -642,7 +643,7 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Printab
|
||||
println();
|
||||
x.getOrderBy().accept(this);
|
||||
}
|
||||
|
||||
|
||||
if (x.getHintsSize() > 0) {
|
||||
printAndAccept(x.getHints(), "");
|
||||
}
|
||||
@@ -894,6 +895,11 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Printab
|
||||
}
|
||||
}
|
||||
|
||||
if (x.getComment() != null) {
|
||||
print(" COMMENT ");
|
||||
x.getComment().accept(this);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1148,11 +1154,11 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Printab
|
||||
x.getOutParameter().accept(this);
|
||||
print(" = ");
|
||||
}
|
||||
|
||||
|
||||
print("CALL ");
|
||||
x.getProcedureName().accept(this);
|
||||
print('(');
|
||||
|
||||
|
||||
printAndAccept(x.getParameters(), ", ");
|
||||
print(')');
|
||||
if (x.isBrace()) {
|
||||
@@ -1417,6 +1423,7 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Printab
|
||||
public boolean visit(SQLOver x) {
|
||||
print("OVER (");
|
||||
if (x.getPartitionBy().size() > 0) {
|
||||
print("PARTITION BY ");
|
||||
printAndAccept(x.getPartitionBy(), ", ");
|
||||
print(' ');
|
||||
}
|
||||
@@ -1790,7 +1797,7 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Printab
|
||||
}
|
||||
print(" ADMIN OPTION");
|
||||
}
|
||||
|
||||
|
||||
if (x.getIdentifiedBy() != null) {
|
||||
print(" IDENTIFIED BY ");
|
||||
x.getIdentifiedBy().accept(this);
|
||||
@@ -1811,43 +1818,43 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Printab
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean visit(SQLDropFunctionStatement x) {
|
||||
print("DROP FUNCTION ");
|
||||
|
||||
|
||||
if (x.isIfExists()) {
|
||||
print("IF EXISTS ");
|
||||
}
|
||||
|
||||
|
||||
x.getName().accept(this);
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean visit(SQLDropTableSpaceStatement x) {
|
||||
print("DROP TABLESPACE ");
|
||||
|
||||
|
||||
if (x.isIfExists()) {
|
||||
print("IF EXISTS ");
|
||||
}
|
||||
|
||||
|
||||
x.getName().accept(this);
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean visit(SQLDropProcedureStatement x) {
|
||||
print("DROP PROCEDURE ");
|
||||
|
||||
|
||||
if (x.isIfExists()) {
|
||||
print("IF EXISTS ");
|
||||
}
|
||||
|
||||
|
||||
x.getName().accept(this);
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1891,18 +1898,18 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Printab
|
||||
x.getConstraint().accept(this);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public boolean visit(SQLCreateTriggerStatement x) {
|
||||
print("CREATE ");
|
||||
|
||||
|
||||
if (x.isOrReplace()) {
|
||||
print("OR REPLEACE ");
|
||||
}
|
||||
|
||||
|
||||
print("TRIGGER ");
|
||||
|
||||
|
||||
x.getName().accept(this);
|
||||
|
||||
|
||||
incrementIndent();
|
||||
println();
|
||||
if (TriggerType.INSTEAD_OF.equals(x.getTriggerType())) {
|
||||
@@ -1910,7 +1917,7 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Printab
|
||||
} else {
|
||||
print(x.getTriggerType().name());
|
||||
}
|
||||
|
||||
|
||||
for (TriggerEvent event : x.getTriggerEvents()) {
|
||||
print(' ');
|
||||
print(event.name());
|
||||
@@ -1918,7 +1925,7 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Printab
|
||||
println();
|
||||
print("ON ");
|
||||
x.getOn().accept(this);
|
||||
|
||||
|
||||
if (x.isForEachRow()) {
|
||||
println();
|
||||
print("FOR EACH ROW");
|
||||
|
||||
@@ -54,4 +54,9 @@ public interface JdbcConstants {
|
||||
public static final String H2 = "h2";
|
||||
|
||||
public static final String H2_DRIVER = "org.h2.Driver";
|
||||
|
||||
/**
|
||||
* 阿里云odps
|
||||
*/
|
||||
public static final String ODPS = "odps";
|
||||
}
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* 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.odps;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.Reader;
|
||||
import java.util.List;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.junit.Assert;
|
||||
|
||||
import com.alibaba.druid.sql.SQLUtils;
|
||||
import com.alibaba.druid.sql.ast.SQLStatement;
|
||||
import com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser;
|
||||
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlParameterizedOutputVisitor;
|
||||
import com.alibaba.druid.sql.dialect.odps.parser.OdpsStatementParser;
|
||||
import com.alibaba.druid.sql.dialect.odps.visitor.OdpsSchemaStatVisitor;
|
||||
import com.alibaba.druid.sql.visitor.SchemaStatVisitor;
|
||||
import com.alibaba.druid.util.JdbcUtils;
|
||||
import com.alibaba.druid.util.Utils;
|
||||
|
||||
public class OdpsInsertTest extends TestCase {
|
||||
|
||||
public void test_0() throws Exception {
|
||||
exec_test("bvt/parser/odps-2.sql");
|
||||
}
|
||||
|
||||
public void exec_test(String resource) throws Exception {
|
||||
System.out.println(resource);
|
||||
InputStream is = null;
|
||||
|
||||
is = Thread.currentThread().getContextClassLoader().getResourceAsStream(resource);
|
||||
Reader reader = new InputStreamReader(is, "UTF-8");
|
||||
String input = Utils.read(reader);
|
||||
JdbcUtils.close(reader);
|
||||
String[] items = input.split("---------------------------");
|
||||
String sql = items[0].trim();
|
||||
String expect = items[1].trim();
|
||||
|
||||
OdpsStatementParser parser = new OdpsStatementParser(sql);
|
||||
List<SQLStatement> statementList = parser.parseStatementList();
|
||||
SQLStatement stmt = statementList.get(0);
|
||||
|
||||
Assert.assertEquals(1, statementList.size());
|
||||
|
||||
SchemaStatVisitor visitor = new OdpsSchemaStatVisitor();
|
||||
stmt.accept(visitor);
|
||||
|
||||
System.out.println(sql);
|
||||
System.out.println("Tables : " + visitor.getTables());
|
||||
System.out.println("fields : " + visitor.getColumns());
|
||||
|
||||
System.out.println();
|
||||
System.out.println("---------------------------");
|
||||
System.out.println(SQLUtils.toOdpsString(stmt));
|
||||
}
|
||||
|
||||
void mergValidate(String sql, String expect) {
|
||||
|
||||
MySqlStatementParser parser = new MySqlStatementParser(sql);
|
||||
List<SQLStatement> statementList = parser.parseStatementList();
|
||||
SQLStatement statemen = statementList.get(0);
|
||||
|
||||
Assert.assertEquals(1, statementList.size());
|
||||
|
||||
StringBuilder out = new StringBuilder();
|
||||
MySqlParameterizedOutputVisitor visitor = new MySqlParameterizedOutputVisitor(out);
|
||||
statemen.accept(visitor);
|
||||
|
||||
System.out.println(out.toString());
|
||||
|
||||
Assert.assertEquals(expect, out.toString());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* 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.odps;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.Reader;
|
||||
import java.util.List;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.junit.Assert;
|
||||
|
||||
import com.alibaba.druid.sql.SQLUtils;
|
||||
import com.alibaba.druid.sql.ast.SQLStatement;
|
||||
import com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser;
|
||||
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlParameterizedOutputVisitor;
|
||||
import com.alibaba.druid.sql.dialect.odps.parser.OdpsStatementParser;
|
||||
import com.alibaba.druid.sql.dialect.odps.visitor.OdpsSchemaStatVisitor;
|
||||
import com.alibaba.druid.sql.visitor.SchemaStatVisitor;
|
||||
import com.alibaba.druid.util.JdbcUtils;
|
||||
import com.alibaba.druid.util.Utils;
|
||||
|
||||
public class OdpsMultiInsertTest extends TestCase {
|
||||
|
||||
public void test_0() throws Exception {
|
||||
exec_test("bvt/parser/odps-1.sql");
|
||||
}
|
||||
|
||||
public void exec_test(String resource) throws Exception {
|
||||
System.out.println(resource);
|
||||
InputStream is = null;
|
||||
|
||||
is = Thread.currentThread().getContextClassLoader().getResourceAsStream(resource);
|
||||
Reader reader = new InputStreamReader(is, "UTF-8");
|
||||
String input = Utils.read(reader);
|
||||
JdbcUtils.close(reader);
|
||||
String[] items = input.split("---------------------------");
|
||||
String sql = items[0].trim();
|
||||
String expect = items[1].trim();
|
||||
|
||||
OdpsStatementParser parser = new OdpsStatementParser(sql);
|
||||
List<SQLStatement> statementList = parser.parseStatementList();
|
||||
SQLStatement stmt = statementList.get(0);
|
||||
|
||||
Assert.assertEquals(1, statementList.size());
|
||||
|
||||
SchemaStatVisitor visitor = new OdpsSchemaStatVisitor();
|
||||
stmt.accept(visitor);
|
||||
|
||||
System.out.println(sql);
|
||||
System.out.println("Tables : " + visitor.getTables());
|
||||
System.out.println("fields : " + visitor.getColumns());
|
||||
|
||||
System.out.println();
|
||||
System.out.println("---------------------------");
|
||||
System.out.println(SQLUtils.toOdpsString(stmt));
|
||||
}
|
||||
|
||||
void mergValidate(String sql, String expect) {
|
||||
|
||||
MySqlStatementParser parser = new MySqlStatementParser(sql);
|
||||
List<SQLStatement> statementList = parser.parseStatementList();
|
||||
SQLStatement statemen = statementList.get(0);
|
||||
|
||||
Assert.assertEquals(1, statementList.size());
|
||||
|
||||
StringBuilder out = new StringBuilder();
|
||||
MySqlParameterizedOutputVisitor visitor = new MySqlParameterizedOutputVisitor(out);
|
||||
statemen.accept(visitor);
|
||||
|
||||
System.out.println(out.toString());
|
||||
|
||||
Assert.assertEquals(expect, out.toString());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* 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.odps;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.Reader;
|
||||
import java.util.List;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.junit.Assert;
|
||||
|
||||
import com.alibaba.druid.sql.SQLUtils;
|
||||
import com.alibaba.druid.sql.ast.SQLStatement;
|
||||
import com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser;
|
||||
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlParameterizedOutputVisitor;
|
||||
import com.alibaba.druid.sql.dialect.odps.parser.OdpsStatementParser;
|
||||
import com.alibaba.druid.sql.dialect.odps.visitor.OdpsSchemaStatVisitor;
|
||||
import com.alibaba.druid.sql.visitor.SchemaStatVisitor;
|
||||
import com.alibaba.druid.util.JdbcUtils;
|
||||
import com.alibaba.druid.util.Utils;
|
||||
|
||||
public class OdpsResourceTest extends TestCase {
|
||||
|
||||
public void test_0() throws Exception {
|
||||
exec_test("bvt/parser/odps-0.sql");
|
||||
}
|
||||
|
||||
public void exec_test(String resource) throws Exception {
|
||||
System.out.println(resource);
|
||||
InputStream is = null;
|
||||
|
||||
is = Thread.currentThread().getContextClassLoader().getResourceAsStream(resource);
|
||||
Reader reader = new InputStreamReader(is, "UTF-8");
|
||||
String input = Utils.read(reader);
|
||||
JdbcUtils.close(reader);
|
||||
String[] items = input.split("---------------------------");
|
||||
String sql = items[0].trim();
|
||||
String expect = items[1].trim();
|
||||
|
||||
OdpsStatementParser parser = new OdpsStatementParser(sql);
|
||||
List<SQLStatement> statementList = parser.parseStatementList();
|
||||
SQLStatement stmt = statementList.get(0);
|
||||
|
||||
Assert.assertEquals(1, statementList.size());
|
||||
|
||||
SchemaStatVisitor visitor = new OdpsSchemaStatVisitor();
|
||||
stmt.accept(visitor);
|
||||
|
||||
System.out.println(sql);
|
||||
System.out.println("Tables : " + visitor.getTables());
|
||||
System.out.println("fields : " + visitor.getColumns());
|
||||
|
||||
System.out.println();
|
||||
System.out.println("---------------------------");
|
||||
System.out.println(SQLUtils.toOdpsString(stmt));
|
||||
}
|
||||
|
||||
void mergValidate(String sql, String expect) {
|
||||
|
||||
MySqlStatementParser parser = new MySqlStatementParser(sql);
|
||||
List<SQLStatement> statementList = parser.parseStatementList();
|
||||
SQLStatement statemen = statementList.get(0);
|
||||
|
||||
Assert.assertEquals(1, statementList.size());
|
||||
|
||||
StringBuilder out = new StringBuilder();
|
||||
MySqlParameterizedOutputVisitor visitor = new MySqlParameterizedOutputVisitor(out);
|
||||
statemen.accept(visitor);
|
||||
|
||||
System.out.println(out.toString());
|
||||
|
||||
Assert.assertEquals(expect, out.toString());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* 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.odps;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.Reader;
|
||||
import java.util.List;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.junit.Assert;
|
||||
|
||||
import com.alibaba.druid.sql.SQLUtils;
|
||||
import com.alibaba.druid.sql.ast.SQLStatement;
|
||||
import com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser;
|
||||
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlParameterizedOutputVisitor;
|
||||
import com.alibaba.druid.sql.dialect.odps.parser.OdpsStatementParser;
|
||||
import com.alibaba.druid.sql.dialect.odps.visitor.OdpsSchemaStatVisitor;
|
||||
import com.alibaba.druid.sql.visitor.SchemaStatVisitor;
|
||||
import com.alibaba.druid.util.JdbcUtils;
|
||||
import com.alibaba.druid.util.Utils;
|
||||
|
||||
public class OdpsSelectTest extends TestCase {
|
||||
|
||||
public void test_0() throws Exception {
|
||||
exec_test("bvt/parser/odps-3.sql");
|
||||
}
|
||||
|
||||
public void exec_test(String resource) throws Exception {
|
||||
System.out.println(resource);
|
||||
InputStream is = null;
|
||||
|
||||
is = Thread.currentThread().getContextClassLoader().getResourceAsStream(resource);
|
||||
Reader reader = new InputStreamReader(is, "UTF-8");
|
||||
String input = Utils.read(reader);
|
||||
JdbcUtils.close(reader);
|
||||
String[] items = input.split("---------------------------");
|
||||
String sql = items[0].trim();
|
||||
String expect = items[1].trim();
|
||||
|
||||
OdpsStatementParser parser = new OdpsStatementParser(sql);
|
||||
List<SQLStatement> statementList = parser.parseStatementList();
|
||||
SQLStatement stmt = statementList.get(0);
|
||||
|
||||
Assert.assertEquals(1, statementList.size());
|
||||
|
||||
SchemaStatVisitor visitor = new OdpsSchemaStatVisitor();
|
||||
stmt.accept(visitor);
|
||||
|
||||
System.out.println(sql);
|
||||
System.out.println("Tables : " + visitor.getTables());
|
||||
System.out.println("fields : " + visitor.getColumns());
|
||||
|
||||
System.out.println();
|
||||
System.out.println("---------------------------");
|
||||
System.out.println(SQLUtils.toOdpsString(stmt));
|
||||
}
|
||||
|
||||
void mergValidate(String sql, String expect) {
|
||||
|
||||
MySqlStatementParser parser = new MySqlStatementParser(sql);
|
||||
List<SQLStatement> statementList = parser.parseStatementList();
|
||||
SQLStatement statemen = statementList.get(0);
|
||||
|
||||
Assert.assertEquals(1, statementList.size());
|
||||
|
||||
StringBuilder out = new StringBuilder();
|
||||
MySqlParameterizedOutputVisitor visitor = new MySqlParameterizedOutputVisitor(out);
|
||||
statemen.accept(visitor);
|
||||
|
||||
System.out.println(out.toString());
|
||||
|
||||
Assert.assertEquals(expect, out.toString());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
create table tt_xx (
|
||||
f1 string,
|
||||
f2 string comment 'xxx',
|
||||
f3 string comment 'xxx',
|
||||
gmt_first datetime comment '首次时间',
|
||||
gmt_last datetime comment '末次时间',
|
||||
pv_cnt bigint comment 'PV数量',
|
||||
pv_day_cnt bigint comment 'PV天数'
|
||||
)
|
||||
comment 'xx comment xxx' partitioned by (pt string comment '按天分区字段', seg string comment '时间跨度')
|
||||
;
|
||||
---------------------------
|
||||
create table tt_xx (
|
||||
f1 string,
|
||||
f2 string comment 'xxx',
|
||||
f3 string comment 'xxx',
|
||||
gmt_first datetime comment '首次时间',
|
||||
gmt_last datetime comment '末次时间',
|
||||
pv_cnt bigint comment 'PV数量',
|
||||
pv_day_cnt bigint comment 'PV天数'
|
||||
)
|
||||
comment 'xx comment xxx'
|
||||
partitioned by (pt string comment '按天分区字段', seg string comment '时间跨度')
|
||||
;
|
||||
@@ -0,0 +1,77 @@
|
||||
FROM (
|
||||
select * from uxoe.xhaayi
|
||||
where pt = '${bizdate}'
|
||||
) x
|
||||
|
||||
INSERT overwrite TABLE uxoe.ialeulxx PARTITION(pt=${bizdate-1})
|
||||
select case when length(iweet_d) > 2 then iweet_d else NULL end iweet_d
|
||||
, case when length(user_nick) > 2 then user_nick else NULL end user_nick
|
||||
, olx
|
||||
, uoex
|
||||
, brand
|
||||
, cpu
|
||||
, umsis
|
||||
, iakxh
|
||||
, resolution
|
||||
, os
|
||||
, os_version
|
||||
, client_ip
|
||||
, count(*) as count
|
||||
, max(from_unixtime(cast(server_time as bigint)/1000)) last_time
|
||||
, min(from_unixtime(cast(server_time as bigint)/1000)) first_time
|
||||
group by iweet_d, user_nick, olx, uoex, brand, cpu, umsis, iakxh, resolution, os, os_version, client_ip
|
||||
|
||||
INSERT overwrite TABLE uxoe.adl_wdm_ip_device_sdt PARTITION (pt='${bizdate}', seg='d1')
|
||||
select client_ip
|
||||
, olx
|
||||
, uoex
|
||||
, brand
|
||||
, cpu
|
||||
, umsis
|
||||
, iakxh
|
||||
, reserve2 utdid
|
||||
, min(from_unixtime(cast(server_time as bigint)/1000)) first_time
|
||||
, max(from_unixtime(cast(server_time as bigint)/1000)) last_time
|
||||
, count(*)
|
||||
, count(distinct pt)
|
||||
group by client_ip, olx, uoex, brand, cpu, umsis, iakxh, reserve2
|
||||
|
||||
INSERT overwrite TABLE uxoe.hxeh PARTITION(pt='${bizdate}')
|
||||
select unique_id() as uuid
|
||||
, regexp_extract(args, 'ongitude=(.*?)(,)') longitude
|
||||
, regexp_extract(args, 'latitude=(.*?)(,)') latitude
|
||||
, client_ip
|
||||
, protocol_version
|
||||
, olx
|
||||
, uoex
|
||||
, brand
|
||||
, cpu
|
||||
, umsis
|
||||
, iakxh
|
||||
, resolution
|
||||
, carrier
|
||||
, access
|
||||
, access_subtype
|
||||
, channel
|
||||
, app_key
|
||||
, app_version
|
||||
, user_nick
|
||||
, phone_number
|
||||
, country
|
||||
, language,os,os_version,sdk_type,sdk_version,reserve1,reserve2,reserve3,reserve4,reserve5
|
||||
, reserves,local_time
|
||||
, from_unixtime(cast(server_time as bigint)/1000) server_time
|
||||
, page
|
||||
, event_id
|
||||
, arg1
|
||||
, arg2
|
||||
, arg3
|
||||
, args
|
||||
, day
|
||||
, hour_id
|
||||
, iweet_d
|
||||
, oqlx
|
||||
, cast(regexp_extract(args, 'wifi_num=(.*?)(,)') as bigint) wifi_num
|
||||
WHERE length(args) > 5
|
||||
AND instr(args, 'gsm_') > 0
|
||||
---------------------------
|
||||
@@ -0,0 +1,110 @@
|
||||
--@exclude_input=bqxef;
|
||||
--@exclude_output=avwaefrwagqbw;
|
||||
|
||||
INSERT overwrite TABLE avwaefrwagqbw partition (pt)
|
||||
SELECT a.zxbw
|
||||
, a.xbax
|
||||
, a.brand
|
||||
, a.cpu
|
||||
, a.xx_x3
|
||||
, a.nwxus
|
||||
, a.xbax xbax_first
|
||||
, a.xbax xbax_first
|
||||
, b.xbax xbax_last
|
||||
, b.xbax xbax_last
|
||||
, first_time
|
||||
, last_time
|
||||
, (rn_lead - rn_lag) + 1 count
|
||||
, province(b.xbax, b.xbax) province
|
||||
, province_code(b.xbax, b.xbax) province_code
|
||||
, city(b.xbax, b.xbax) city
|
||||
, city_code(b.xbax, b.xbax) city_code
|
||||
, a.pt
|
||||
FROM (
|
||||
SELECT row_number() over(partition by pt, zxbw, xbax, brand, cpu, xx_x3, nwxus order by rn_lead) rn
|
||||
, zxbw
|
||||
, xbax
|
||||
, brand
|
||||
, cpu
|
||||
, xx_x3
|
||||
, nwxus
|
||||
, xbax
|
||||
, xbax
|
||||
, server_time first_time
|
||||
, pt
|
||||
, rn_lead
|
||||
FROM (
|
||||
SELECT row_number() over(partition by pt, zxbw, xbax, brand, cpu, xx_x3, nwxus order by server_time, xbax, xbax) rn_lead
|
||||
, zxbw
|
||||
, xbax
|
||||
, brand
|
||||
, cpu
|
||||
, xx_x3
|
||||
, nwxus
|
||||
, xbax
|
||||
, LEAD(xbax, 1, 0) over(partition by pt, zxbw, xbax, brand, cpu, xx_x3, nwxus order by server_time, xbax, xbax) xbax_lead
|
||||
, xbax
|
||||
, LEAD(xbax, 1, 0) over(partition by pt, zxbw, xbax, brand, cpu, xx_x3, nwxus order by server_time, xbax, xbax) xbax_lead
|
||||
, server_time
|
||||
, pt
|
||||
FROM bqxef
|
||||
where length(zxbw) >= 15
|
||||
AND xbax IS NOT NULL
|
||||
AND xbax IS NOT NULL
|
||||
AND abs(xbax) <= 180
|
||||
AND abs(xbax) <= 90
|
||||
AND xbax <> 0
|
||||
AND xbax <> 0
|
||||
AND pt >= ${bizdate}
|
||||
) x1
|
||||
WHERE round(xbax, 2) <> round(xbax_lead, 2)
|
||||
OR round(xbax, 2) <> round(xbax_lead, 2)
|
||||
) a inner join (
|
||||
SELECT row_number() over(partition by pt, zxbw, xbax, brand, cpu, xx_x3, nwxus order by rn_lag) rn
|
||||
, zxbw
|
||||
, xbax
|
||||
, brand
|
||||
, cpu
|
||||
, xx_x3
|
||||
, nwxus
|
||||
, xbax
|
||||
, xbax
|
||||
, server_time last_time
|
||||
, pt
|
||||
, rn_lag
|
||||
FROM (
|
||||
SELECT row_number() over(partition by pt, zxbw, xbax, brand, cpu, xx_x3, nwxus order by server_time, xbax, xbax) rn_lag
|
||||
, zxbw
|
||||
, xbax
|
||||
, brand
|
||||
, cpu
|
||||
, xx_x3
|
||||
, nwxus
|
||||
, xbax
|
||||
, LAG(xbax, 1, 0) over(partition by pt, zxbw, xbax, brand, cpu, xx_x3, nwxus order by server_time, xbax, xbax) xbax_lag
|
||||
, xbax
|
||||
, LAG(xbax, 1, 0) over(partition by pt, zxbw, xbax, brand, cpu, xx_x3, nwxus order by server_time, xbax, xbax) xbax_lag
|
||||
, server_time
|
||||
, pt
|
||||
FROM bqxef
|
||||
where length(zxbw) >= 15
|
||||
AND xbax IS NOT NULL
|
||||
AND xbax IS NOT NULL
|
||||
AND abs(xbax) <= 180
|
||||
AND abs(xbax) <= 90
|
||||
AND xbax <> 0
|
||||
AND xbax <> 0
|
||||
AND pt >= ${bizdate}
|
||||
) x2
|
||||
WHERE round(xbax, 2) <> round(xbax_lag, 2)
|
||||
OR round(xbax, 2) <> round(xbax_lag, 2)
|
||||
) b on a.pt = b.pt
|
||||
AND a.zxbw = b.zxbw
|
||||
AND a.xbax = b.xbax
|
||||
AND a.brand = b.brand
|
||||
AND a.cpu = b.cpu
|
||||
AND a.xx_x3 = b.xx_x3
|
||||
AND a.nwxus = b.nwxus
|
||||
AND a.rn = b.rn
|
||||
;
|
||||
---------------------------
|
||||
@@ -0,0 +1,61 @@
|
||||
select a.user_id
|
||||
, a.user_nick
|
||||
, a.xrwq
|
||||
, a.exesag
|
||||
, a.brand
|
||||
, a.cpu
|
||||
, a.xagawef
|
||||
, a.qwgqwer
|
||||
, b.os
|
||||
, b.os_version
|
||||
, b.resolution
|
||||
, a.count
|
||||
, a.day_count
|
||||
, a.last_time
|
||||
, a.first_time
|
||||
, ip
|
||||
from (
|
||||
select user_id
|
||||
, max(user_nick) user_nick
|
||||
, xrwq
|
||||
, exesag
|
||||
, brand
|
||||
, cpu
|
||||
, xagawef
|
||||
, qwgqwer
|
||||
, sum(count) count
|
||||
, count(distinct pt) day_count
|
||||
, max(coalesce(last_time, to_date(pt, 'yyyymmdd'))) last_time
|
||||
, min(coalesce(first_time, to_date(pt, 'yyyymmdd'))) first_time
|
||||
from x_dsls_yw3l
|
||||
where xrwq <> 'xxx-xxxx--xxx'
|
||||
group by user_id, xrwq, exesag, brand, cpu, xagawef, qwgqwer
|
||||
) a inner join (
|
||||
select *
|
||||
from (
|
||||
select user_id
|
||||
, user_nick
|
||||
, xrwq
|
||||
, exesag
|
||||
, brand
|
||||
, cpu
|
||||
, xagawef
|
||||
, qwgqwer
|
||||
, os
|
||||
, os_version
|
||||
, resolution
|
||||
, ip
|
||||
, row_number() over(partition by user_id, user_nick, xrwq, exesag, brand, cpu, xagawef, qwgqwer order by last_time desc) rn
|
||||
from x_dsls_yw3l
|
||||
where xrwq <> 'c1976429369bfe063ed8b3409db7c7e7d87196d9'
|
||||
) r1
|
||||
where rn = 1
|
||||
) b on a.user_id = b.user_id
|
||||
AND a.xrwq = b.xrwq
|
||||
AND a.exesag = b.exesag
|
||||
AND a.brand = b.brand
|
||||
AND a.cpu = b.cpu
|
||||
AND a.xagawef = b.xagawef
|
||||
AND a.qwgqwer = b.qwgqwer
|
||||
;
|
||||
---------------------------
|
||||
@@ -0,0 +1,106 @@
|
||||
INSERT OVERWRITE TABLE wdm_device_gps_range_day PARTITION (pt)
|
||||
SELECT a.imei,
|
||||
a.imsi,
|
||||
a.brand,
|
||||
a.cpu,
|
||||
a.device_id,
|
||||
a.device_model,
|
||||
a.longitude AS longitude_first,
|
||||
a.latitude AS latitude_first,
|
||||
b.longitude AS longitude_last,
|
||||
b.latitude AS latitude_last,
|
||||
first_time,
|
||||
last_time,
|
||||
rn_lead - rn_lag + 1 AS count,
|
||||
province(b.longitude, b.latitude) AS province,
|
||||
province_code(b.longitude, b.latitude) AS province_code,
|
||||
city(b.longitude, b.latitude) AS city,
|
||||
city_code(b.longitude, b.latitude) AS city_code,
|
||||
a.pt
|
||||
FROM (
|
||||
SELECT ROW_NUMBER() OVER (PARTITION BY pt, imei, imsi, brand, cpu, device_id, device_model ORDER BY rn_lead) AS rn,
|
||||
imei,
|
||||
imsi,
|
||||
brand,
|
||||
cpu,
|
||||
device_id,
|
||||
device_model,
|
||||
longitude,
|
||||
latitude,
|
||||
server_time AS first_time,
|
||||
pt,
|
||||
rn_lead
|
||||
FROM (
|
||||
SELECT ROW_NUMBER() OVER (PARTITION BY pt, imei, imsi, brand, cpu, device_id, device_model ORDER BY server_time, longitude, latitude) AS rn_lead,
|
||||
imei,
|
||||
imsi,
|
||||
brand,
|
||||
cpu,
|
||||
device_id,
|
||||
device_model,
|
||||
longitude,
|
||||
LEAD(longitude, 1, 0) OVER (PARTITION BY pt, imei, imsi, brand, cpu, device_id, device_model ORDER BY server_time, longitude, latitude) AS longitude_lead,
|
||||
latitude,
|
||||
LEAD(latitude, 1, 0) OVER (PARTITION BY pt, imei, imsi, brand, cpu, device_id, device_model ORDER BY server_time, longitude, latitude) AS latitude_lead,
|
||||
server_time,
|
||||
pt
|
||||
FROM wdm_args
|
||||
WHERE length(imei) >= 15
|
||||
AND longitude IS NOT NULL
|
||||
AND latitude IS NOT NULL
|
||||
AND abs(longitude) <= 180
|
||||
AND abs(latitude) <= 90
|
||||
AND longitude <> 0
|
||||
AND latitude <> 0
|
||||
AND pt >= ${bizdate}
|
||||
) x1
|
||||
WHERE round(longitude, 2) <> round(longitude_lead, 2)
|
||||
OR round(latitude, 2) <> round(latitude_lead, 2)
|
||||
) a
|
||||
INNER JOIN (
|
||||
SELECT ROW_NUMBER() OVER (PARTITION BY pt, imei, imsi, brand, cpu, device_id, device_model ORDER BY rn_lag) AS rn,
|
||||
imei,
|
||||
imsi,
|
||||
brand,
|
||||
cpu,
|
||||
device_id,
|
||||
device_model,
|
||||
longitude,
|
||||
latitude,
|
||||
server_time AS last_time,
|
||||
pt,
|
||||
rn_lag
|
||||
FROM (
|
||||
SELECT ROW_NUMBER() OVER (PARTITION BY pt, imei, imsi, brand, cpu, device_id, device_model ORDER BY server_time, longitude, latitude) AS rn_lag,
|
||||
imei,
|
||||
imsi,
|
||||
brand,
|
||||
cpu,
|
||||
device_id,
|
||||
device_model,
|
||||
longitude,
|
||||
LAG(longitude, 1, 0) OVER (PARTITION BY pt, imei, imsi, brand, cpu, device_id, device_model ORDER BY server_time, longitude, latitude) AS longitude_lag,
|
||||
latitude,
|
||||
LAG(latitude, 1, 0) OVER (PARTITION BY pt, imei, imsi, brand, cpu, device_id, device_model ORDER BY server_time, longitude, latitude) AS latitude_lag,
|
||||
server_time,
|
||||
pt
|
||||
FROM wdm_args
|
||||
WHERE length(imei) >= 15
|
||||
AND longitude IS NOT NULL
|
||||
AND latitude IS NOT NULL
|
||||
AND abs(longitude) <= 180
|
||||
AND abs(latitude) <= 90
|
||||
AND longitude <> 0
|
||||
AND latitude <> 0
|
||||
AND pt >= ${bizdate}
|
||||
) x2
|
||||
WHERE round(longitude, 2) <> round(longitude_lag, 2)
|
||||
OR round(latitude, 2) <> round(latitude_lag, 2)
|
||||
) b ON a.pt = b.pt
|
||||
AND a.imei = b.imei
|
||||
AND a.imsi = b.imsi
|
||||
AND a.brand = b.brand
|
||||
AND a.cpu = b.cpu
|
||||
AND a.device_id = b.device_id
|
||||
AND a.device_model = b.device_model
|
||||
AND a.rn = b.rn
|
||||
Reference in New Issue
Block a user