提交 d1952d08 编写于 作者: L liipx

update vitess, rename Newtable to others

上级 461b6899
......@@ -2305,7 +2305,7 @@ func (q *Query4Audit) RuleCreateDualTable() Rule {
var rule = q.RuleOK()
switch s := q.Stmt.(type) {
case *sqlparser.DDL:
if s.NewName.Name.String() == "dual" {
if s.Table.Name.String() == "dual" {
rule = HeuristicRules["TBL.003"]
}
......
......@@ -77,27 +77,15 @@ func GetMeta(stmt sqlparser.Statement, meta common.Meta) common.Meta {
switch expr := node.(type) {
case *sqlparser.DDL:
// 如果SQL是一个DDL,则不需要继续遍历语法树了
db1 := expr.Table.Qualifier.String()
tb1 := expr.Table.Name.String()
db2 := expr.NewName.Qualifier.String()
tb2 := expr.NewName.Name.String()
if tb1 != "" {
if _, ok := meta[db1]; !ok {
meta[db1] = common.NewDB(db1)
}
meta[db1].Table[tb1] = common.NewTable(tb1)
for _, tb := range expr.FromTables {
appendTable(tb, "", meta)
}
if tb2 != "" {
if _, ok := meta[db2]; !ok {
meta[db2] = common.NewDB(db2)
}
meta[db2].Table[tb2] = common.NewTable(tb2)
for _, tb := range expr.ToTables {
appendTable(tb, "", meta)
}
appendTable(expr.Table, "", meta)
return false, nil
case *sqlparser.AliasedTableExpr:
// 非 DDL 情况下处理 TableExpr
......@@ -110,26 +98,7 @@ func GetMeta(stmt sqlparser.Statement, meta common.Meta) common.Meta {
// 表名存放在 AST 中 TableName 里,包含表名与表前缀名。
// 当与 As 相对应的 Expr 为 TableName 的时候,别名才是一张实体表的别名,否则为结果集的别名。
case sqlparser.TableName:
db := table.Qualifier.String()
tb := table.Name.String()
if meta[db] == nil {
meta[db] = common.NewDB(db)
}
meta[db].Table[tb] = common.NewTable(tb)
// alias去重
aliasExist := false
for _, existedAlias := range meta[db].Table[tb].TableAliases {
if existedAlias == expr.As.String() {
aliasExist = true
}
}
if !aliasExist {
meta[db].Table[tb].TableAliases = append(meta[db].Table[tb].TableAliases, expr.As.String())
}
appendTable(table, expr.As.String(), meta)
default:
// 如果 AliasedTableExpr 中的 Expr 不是 TableName 结构体,则表示该表为一个查询结果集(子查询或临时表)。
// 在这里记录一下别名,但将列名制空,用来保证在其他环节中判断列前缀的时候不会有遗漏
......@@ -152,6 +121,49 @@ func GetMeta(stmt sqlparser.Statement, meta common.Meta) common.Meta {
return meta
}
// appendTable 将 sqlparser.TableName 中的库表信息提取后放到 meta 中
// @tb 为 sqlparser.TableName 对象
// @as 为该表的别名,无别名时为空
// @meta 为信息集合
func appendTable(tb sqlparser.TableName, as string, meta map[string]*common.DB) map[string]*common.DB {
if meta == nil {
return meta
}
dbName := tb.Qualifier.String()
tbName := tb.Name.String()
if tbName == "" {
return meta
}
if meta[dbName] == nil {
meta[dbName] = common.NewDB(dbName)
}
meta[dbName].Table[tbName] = common.NewTable(tbName)
mergeAlias(dbName, tbName, as, meta)
return meta
}
// mergeAlias 将所有的表别名归并到一个表下
func mergeAlias(db, tb, as string, meta map[string]*common.DB) {
if meta == nil || as == "" {
return
}
aliasExist := false
for _, existedAlias := range meta[db].Table[tb].TableAliases {
if existedAlias == as {
aliasExist = true
}
}
if !aliasExist {
meta[db].Table[tb].TableAliases = append(meta[db].Table[tb].TableAliases, as)
}
}
// eqOperators 等值条件判断关键字
var eqOperators = map[string]string{
"=": "eq",
......
......@@ -59,7 +59,7 @@ func TestFindCondition(t *testing.T) {
for _, sql := range common.TestSQLs {
fmt.Println(sql)
stmt, err := sqlparser.Parse(sql)
//pretty.Println(stmt)
// pretty.Println(stmt)
if err != nil {
panic(err)
}
......@@ -143,7 +143,7 @@ func TestFindJoinTable(t *testing.T) {
for _, sql := range sqlList {
fmt.Println(sql)
stmt, err := sqlparser.Parse(sql)
//pretty.Println(stmt)
// pretty.Println(stmt)
if err != nil {
panic(err)
}
......@@ -167,7 +167,7 @@ func TestFindJoinCols(t *testing.T) {
for _, sql := range sqlList {
fmt.Println(sql)
stmt, err := sqlparser.Parse(sql)
//pretty.Println(stmt)
// pretty.Println(stmt)
if err != nil {
panic(err)
}
......@@ -189,7 +189,7 @@ func TestFindJoinColBeWhereEQ(t *testing.T) {
for _, sql := range sqlList {
fmt.Println(sql)
stmt, err := sqlparser.Parse(sql)
//pretty.Println(stmt)
// pretty.Println(stmt)
if err != nil {
panic(err)
}
......@@ -211,7 +211,7 @@ func TestFindJoinColBeWhereINEQ(t *testing.T) {
for _, sql := range sqlList {
fmt.Println(sql)
stmt, err := sqlparser.Parse(sql)
//pretty.Println(stmt)
// pretty.Println(stmt)
if err != nil {
panic(err)
}
......@@ -239,7 +239,7 @@ func TestFindAllCondition(t *testing.T) {
for _, sql := range sqlList {
fmt.Println(sql)
stmt, err := sqlparser.Parse(sql)
//pretty.Println(stmt)
// pretty.Println(stmt)
if err != nil {
panic(err)
}
......@@ -258,7 +258,7 @@ func TestFindColumn(t *testing.T) {
for _, sql := range sqlList {
fmt.Println(sql)
stmt, err := sqlparser.Parse(sql)
//pretty.Println(stmt)
// pretty.Println(stmt)
if err != nil {
panic(err)
}
......@@ -286,7 +286,7 @@ func TestFindAllCols(t *testing.T) {
for _, sql := range sqlList {
fmt.Println(sql)
stmt, err := sqlparser.Parse(sql)
//pretty.Println(stmt)
// pretty.Println(stmt)
if err != nil {
panic(err)
}
......@@ -322,3 +322,47 @@ func TestGetSubqueryDepth(t *testing.T) {
fmt.Println(dep)
}
}
func TestAppendTable(t *testing.T) {
sqlList := []string{
"select ID,name from (select address from customer_list where SID=1 order by phone limit 50,10) a join customer_list l on (a.address=l.address) join city c on (c.city=l.city) order by phone desc;",
}
meta := make(map[string]*common.DB)
for _, sql := range sqlList {
fmt.Println(sql)
stmt, err := sqlparser.Parse(sql)
if err != nil {
t.Error("syntax check error.")
}
err = sqlparser.Walk(func(node sqlparser.SQLNode) (kontinue bool, err error) {
switch expr := node.(type) {
case *sqlparser.AliasedTableExpr:
switch table := expr.Expr.(type) {
case sqlparser.TableName:
appendTable(table, expr.As.String(), meta)
default:
if meta == nil {
meta = make(map[string]*common.DB)
}
if meta[""] == nil {
meta[""] = common.NewDB("")
}
meta[""].Table[""] = common.NewTable("")
meta[""].Table[""].TableAliases = append(meta[""].Table[""].TableAliases, expr.As.String())
}
}
return true, nil
}, stmt)
if err != nil {
t.Error(err)
}
}
// 仅对第一条测试SQL进行测试,验证别名正确性
if meta[""].Table["customer_list"].TableAliases[0] != "l" || meta[""].Table["city"].TableAliases[0] != "c" {
t.Error("alias filed\n", pretty.Sprint(meta))
}
}
......@@ -248,11 +248,25 @@ func (ve *VirtualEnv) BuildVirtualEnv(rEnv *database.Connector, SQLs ...string)
// 为了支持并发,需要将DB进行映射,但db.table这种形式无法保证DB的映射是正确的
// TODO:暂不支持 create db.tableName (id int) 形式的建表语句
if stmt.Table.Qualifier.String() != "" || stmt.NewName.Qualifier.String() != "" {
if stmt.Table.Qualifier.String() != "" {
common.Log.Error("BuildVirtualEnv DDL Not support '.'")
return false
}
for _, tb := range stmt.FromTables {
if tb.Qualifier.String() != "" {
common.Log.Error("BuildVirtualEnv DDL Not support '.'")
return false
}
}
for _, tb := range stmt.ToTables {
if tb.Qualifier.String() != "" {
common.Log.Error("BuildVirtualEnv DDL Not support '.'")
return false
}
}
// 拉取表结构
table := stmt.Table.Name.String()
if table != "" {
......
......@@ -1016,68 +1016,68 @@
{
"checksumSHA1": "w8FCRjH70gM6QttB9QrEh9Y1x64=",
"path": "vitess.io/vitess",
"revision": "6fca9975675109decbf1c389641597929824eeba",
"revisionTime": "2018-10-31T20:10:04Z"
"revision": "54855ec7b36906b6d53aa5af0f0293a0a73ae928",
"revisionTime": "2018-11-05T03:16:12Z"
},
{
"checksumSHA1": "aKn1oKcY74N8TRLm3Ayt7Q4bbI4=",
"path": "vitess.io/vitess/go/bytes2",
"revision": "6fca9975675109decbf1c389641597929824eeba",
"revisionTime": "2018-10-31T20:10:04Z"
"revision": "54855ec7b36906b6d53aa5af0f0293a0a73ae928",
"revisionTime": "2018-11-05T03:16:12Z"
},
{
"checksumSHA1": "JVCEN4UGRmg3TofIBdzZMZ3G0Ww=",
"path": "vitess.io/vitess/go/hack",
"revision": "6fca9975675109decbf1c389641597929824eeba",
"revisionTime": "2018-10-31T20:10:04Z"
"revision": "54855ec7b36906b6d53aa5af0f0293a0a73ae928",
"revisionTime": "2018-11-05T03:16:12Z"
},
{
"checksumSHA1": "e1WJ7vCnVrlQQQlc6n/FewCDMso=",
"path": "vitess.io/vitess/go/sqltypes",
"revision": "6fca9975675109decbf1c389641597929824eeba",
"revisionTime": "2018-10-31T20:10:04Z"
"revision": "54855ec7b36906b6d53aa5af0f0293a0a73ae928",
"revisionTime": "2018-11-05T03:16:12Z"
},
{
"checksumSHA1": "ntFIQYkBS51G6y+FEkjFW40+HOU=",
"path": "vitess.io/vitess/go/vt/log",
"revision": "6fca9975675109decbf1c389641597929824eeba",
"revisionTime": "2018-10-31T20:10:04Z"
"revision": "54855ec7b36906b6d53aa5af0f0293a0a73ae928",
"revisionTime": "2018-11-05T03:16:12Z"
},
{
"checksumSHA1": "XozR8bmeSR5KTe/nlUJkpJY2HKI=",
"path": "vitess.io/vitess/go/vt/proto/query",
"revision": "6fca9975675109decbf1c389641597929824eeba",
"revisionTime": "2018-10-31T20:10:04Z"
"revision": "54855ec7b36906b6d53aa5af0f0293a0a73ae928",
"revisionTime": "2018-11-05T03:16:12Z"
},
{
"checksumSHA1": "OnWsUHLDKcO3spwH0jD55SvKD24=",
"path": "vitess.io/vitess/go/vt/proto/topodata",
"revision": "6fca9975675109decbf1c389641597929824eeba",
"revisionTime": "2018-10-31T20:10:04Z"
"revision": "54855ec7b36906b6d53aa5af0f0293a0a73ae928",
"revisionTime": "2018-11-05T03:16:12Z"
},
{
"checksumSHA1": "sBAuZ/itMR8U8qbK4yLHxkP6Cpc=",
"path": "vitess.io/vitess/go/vt/proto/vtgate",
"revision": "6fca9975675109decbf1c389641597929824eeba",
"revisionTime": "2018-10-31T20:10:04Z"
"revision": "54855ec7b36906b6d53aa5af0f0293a0a73ae928",
"revisionTime": "2018-11-05T03:16:12Z"
},
{
"checksumSHA1": "pLWM+SPGZs3k+IhjktE/cGUlpM0=",
"path": "vitess.io/vitess/go/vt/proto/vtrpc",
"revision": "6fca9975675109decbf1c389641597929824eeba",
"revisionTime": "2018-10-31T20:10:04Z"
"revision": "54855ec7b36906b6d53aa5af0f0293a0a73ae928",
"revisionTime": "2018-11-05T03:16:12Z"
},
{
"checksumSHA1": "re3V8oX+ujxHbNZuB+QEtrcXxE8=",
"checksumSHA1": "3rucaIfitefjezWeglPndd50Mcw=",
"path": "vitess.io/vitess/go/vt/sqlparser",
"revision": "6fca9975675109decbf1c389641597929824eeba",
"revisionTime": "2018-10-31T20:10:04Z"
"revision": "54855ec7b36906b6d53aa5af0f0293a0a73ae928",
"revisionTime": "2018-11-05T03:16:12Z"
},
{
"checksumSHA1": "oF4XzuOzwvj1iduX/lYqNSyY/HM=",
"path": "vitess.io/vitess/go/vt/vterrors",
"revision": "6fca9975675109decbf1c389641597929824eeba",
"revisionTime": "2018-10-31T20:10:04Z"
"revision": "54855ec7b36906b6d53aa5af0f0293a0a73ae928",
"revisionTime": "2018-11-05T03:16:12Z"
}
],
"rootPath": "github.com/XiaoMi/soar"
......
......@@ -718,21 +718,30 @@ func (node *DBDDL) walkSubtree(visit Visit) error {
return nil
}
// DDL represents a CREATE, ALTER, DROP, RENAME or TRUNCATE statement.
// Table is set for AlterStr, DropStr, RenameStr, TruncateStr
// NewName is set for AlterStr, CreateStr, RenameStr.
// VindexSpec is set for CreateVindexStr, DropVindexStr, AddColVindexStr, DropColVindexStr
// VindexCols is set for AddColVindexStr
// DDL represents a CREATE, ALTER, DROP, RENAME, TRUNCATE or ANALYZE statement.
type DDL struct {
Action string
Table TableName
NewName TableName
Action string
// FromTables is set if Action is RenameStr or DropStr.
FromTables TableNames
// ToTables is set if Action is RenameStr.
ToTables TableNames
// Table is set if Action is other than RenameStr or DropStr.
Table TableName
// The following fields are set if a DDL was fully analyzed.
IfExists bool
TableSpec *TableSpec
OptLike *OptLike
PartitionSpec *PartitionSpec
VindexSpec *VindexSpec
VindexCols []ColIdent
// VindexSpec is set for CreateVindexStr, DropVindexStr, AddColVindexStr, DropColVindexStr.
VindexSpec *VindexSpec
// VindexCols is set for AddColVindexStr.
VindexCols []ColIdent
}
// DDL strings.
......@@ -756,20 +765,23 @@ func (node *DDL) Format(buf *TrackedBuffer) {
switch node.Action {
case CreateStr:
if node.OptLike != nil {
buf.Myprintf("%s table %v %v", node.Action, node.NewName, node.OptLike)
buf.Myprintf("%s table %v %v", node.Action, node.Table, node.OptLike)
} else if node.TableSpec != nil {
buf.Myprintf("%s table %v %v", node.Action, node.NewName, node.TableSpec)
buf.Myprintf("%s table %v %v", node.Action, node.Table, node.TableSpec)
} else {
buf.Myprintf("%s table %v", node.Action, node.NewName)
buf.Myprintf("%s table %v", node.Action, node.Table)
}
case DropStr:
exists := ""
if node.IfExists {
exists = " if exists"
}
buf.Myprintf("%s table%s %v", node.Action, exists, node.Table)
buf.Myprintf("%s table%s %v", node.Action, exists, node.FromTables)
case RenameStr:
buf.Myprintf("%s table %v to %v", node.Action, node.Table, node.NewName)
buf.Myprintf("%s table %v to %v", node.Action, node.FromTables[0], node.ToTables[0])
for i := 1; i < len(node.FromTables); i++ {
buf.Myprintf(", %v to %v", node.FromTables[i], node.ToTables[i])
}
case AlterStr:
if node.PartitionSpec != nil {
buf.Myprintf("%s table %v %v", node.Action, node.Table, node.PartitionSpec)
......@@ -804,11 +816,23 @@ func (node *DDL) walkSubtree(visit Visit) error {
if node == nil {
return nil
}
return Walk(
visit,
node.Table,
node.NewName,
)
for _, t := range node.AffectedTables() {
if err := Walk(visit, t); err != nil {
return err
}
}
return nil
}
// AffectedTables returns the list table names affected by the DDL.
func (node *DDL) AffectedTables() TableNames {
if node.Action == RenameStr || node.Action == DropStr {
list := make(TableNames, 0, len(node.FromTables)+len(node.ToTables))
list = append(list, node.FromTables...)
list = append(list, node.ToTables...)
return list
}
return TableNames{node.Table}
}
// Partition strings
......
......@@ -204,7 +204,7 @@ func skipToEnd(yylex interface{}) {
%type <selStmt> select_statement base_select union_lhs union_rhs
%type <statement> stream_statement insert_statement update_statement delete_statement set_statement
%type <statement> create_statement alter_statement rename_statement drop_statement truncate_statement flush_statement
%type <ddl> create_table_prefix
%type <ddl> create_table_prefix rename_list
%type <statement> analyze_statement show_statement use_statement other_statement
%type <statement> begin_statement commit_statement rollback_statement
%type <bytes2> comment_opt comment_list
......@@ -560,15 +560,15 @@ create_statement:
| CREATE constraint_opt INDEX ID using_opt ON table_name ddl_skip_to_end
{
// Change this to an alter statement
$$ = &DDL{Action: AlterStr, Table: $7, NewName:$7}
$$ = &DDL{Action: AlterStr, Table: $7}
}
| CREATE VIEW table_name ddl_skip_to_end
{
$$ = &DDL{Action: CreateStr, NewName: $3.ToViewName()}
$$ = &DDL{Action: CreateStr, Table: $3.ToViewName()}
}
| CREATE OR REPLACE VIEW table_name ddl_skip_to_end
{
$$ = &DDL{Action: CreateStr, NewName: $5.ToViewName()}
$$ = &DDL{Action: CreateStr, Table: $5.ToViewName()}
}
| CREATE VINDEX sql_id vindex_type_opt vindex_params_opt
{
......@@ -632,7 +632,7 @@ vindex_param:
create_table_prefix:
CREATE TABLE not_exists_opt table_name
{
$$ = &DDL{Action: CreateStr, NewName: $4}
$$ = &DDL{Action: CreateStr, Table: $4}
setDDL(yylex, $$)
}
......@@ -1290,15 +1290,15 @@ table_opt_value:
alter_statement:
ALTER ignore_opt TABLE table_name non_add_drop_or_rename_operation skip_to_end
{
$$ = &DDL{Action: AlterStr, Table: $4, NewName: $4}
$$ = &DDL{Action: AlterStr, Table: $4}
}
| ALTER ignore_opt TABLE table_name ADD alter_object_type skip_to_end
{
$$ = &DDL{Action: AlterStr, Table: $4, NewName: $4}
$$ = &DDL{Action: AlterStr, Table: $4}
}
| ALTER ignore_opt TABLE table_name DROP alter_object_type skip_to_end
{
$$ = &DDL{Action: AlterStr, Table: $4, NewName: $4}
$$ = &DDL{Action: AlterStr, Table: $4}
}
| ALTER ignore_opt TABLE table_name ADD VINDEX sql_id '(' column_list ')' vindex_type_opt vindex_params_opt
{
......@@ -1326,16 +1326,16 @@ alter_statement:
| ALTER ignore_opt TABLE table_name RENAME to_opt table_name
{
// Change this to a rename statement
$$ = &DDL{Action: RenameStr, Table: $4, NewName: $7}
$$ = &DDL{Action: RenameStr, FromTables: TableNames{$4}, ToTables: TableNames{$7}}
}
| ALTER ignore_opt TABLE table_name RENAME index_opt skip_to_end
{
// Rename an index can just be an alter
$$ = &DDL{Action: AlterStr, Table: $4, NewName: $4}
$$ = &DDL{Action: AlterStr, Table: $4}
}
| ALTER VIEW table_name ddl_skip_to_end
{
$$ = &DDL{Action: AlterStr, Table: $3.ToViewName(), NewName: $3.ToViewName()}
$$ = &DDL{Action: AlterStr, Table: $3.ToViewName()}
}
| ALTER ignore_opt TABLE table_name partition_operation
{
......@@ -1382,24 +1382,36 @@ partition_definition:
}
rename_statement:
RENAME TABLE table_name TO table_name
RENAME TABLE rename_list
{
$$ = &DDL{Action: RenameStr, Table: $3, NewName: $5}
$$ = $3
}
rename_list:
table_name TO table_name
{
$$ = &DDL{Action: RenameStr, FromTables: TableNames{$1}, ToTables: TableNames{$3}}
}
| rename_list ',' table_name TO table_name
{
$$ = $1
$$.FromTables = append($$.FromTables, $3)
$$.ToTables = append($$.ToTables, $5)
}
drop_statement:
DROP TABLE exists_opt table_name
DROP TABLE exists_opt table_name_list
{
var exists bool
if $3 != 0 {
exists = true
}
$$ = &DDL{Action: DropStr, Table: $4, IfExists: exists}
$$ = &DDL{Action: DropStr, FromTables: $4, IfExists: exists}
}
| DROP INDEX ID ON table_name ddl_skip_to_end
{
// Change this to an alter statement
$$ = &DDL{Action: AlterStr, Table: $5, NewName: $5}
$$ = &DDL{Action: AlterStr, Table: $5}
}
| DROP VIEW exists_opt table_name ddl_skip_to_end
{
......@@ -1407,7 +1419,7 @@ drop_statement:
if $3 != 0 {
exists = true
}
$$ = &DDL{Action: DropStr, Table: $4.ToViewName(), IfExists: exists}
$$ = &DDL{Action: DropStr, FromTables: TableNames{$4.ToViewName()}, IfExists: exists}
}
| DROP DATABASE exists_opt ID
{
......@@ -1430,7 +1442,7 @@ truncate_statement:
analyze_statement:
ANALYZE TABLE table_name
{
$$ = &DDL{Action: AlterStr, Table: $3, NewName: $3}
$$ = &DDL{Action: AlterStr, Table: $3}
}
show_statement:
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册