diff --git a/executor/executor_test.go b/executor/executor_test.go index 8157730a544f8..31efebdbccd34 100644 --- a/executor/executor_test.go +++ b/executor/executor_test.go @@ -3747,14 +3747,13 @@ func (s *testSuite3) TestForSelectScopeInUnion(c *C) { c.Assert(err, NotNil) tk1.MustExec("begin") - // 'For update' would be ignored if 'order by' or 'limit' exists. tk1.MustQuery("select 1 as a union select a from t limit 5 for update") tk1.MustQuery("select 1 as a union select a from t order by a for update") tk2.MustExec("update t set a = a + 1") _, err = tk1.Exec("commit") - c.Assert(err, IsNil) + c.Assert(err, NotNil) } func (s *testSuite3) TestUnsignedDecimalOverflow(c *C) { diff --git a/executor/testdata/executor_suite_in.json b/executor/testdata/executor_suite_in.json index 3d7e697e0999b..c4ba3926468d8 100644 --- a/executor/testdata/executor_suite_in.json +++ b/executor/testdata/executor_suite_in.json @@ -10,7 +10,11 @@ "select * from t1 union all select * from t2 except select * from t3", "select * from t1 intersect select * from t2 intersect select * from t1", "select * from t1 union all select * from t2 intersect select * from t3", - "select * from t1 except select * from t2 intersect select * from t3" + "select * from t1 except select * from t2 intersect select * from t3", + "select * from t1 intersect (select * from t2 except (select * from t3))", + "select * from t1 union all (select * from t2 except select * from t3)", + "select * from t1 union (select * from t2 union all select * from t3)", + "(select * from t1 intersect select * from t1) except (select * from t2 union select * from t3)" ] }, { diff --git a/executor/testdata/executor_suite_out.json b/executor/testdata/executor_suite_out.json index 5650a09324983..f147eed700107 100644 --- a/executor/testdata/executor_suite_out.json +++ b/executor/testdata/executor_suite_out.json @@ -174,6 +174,87 @@ "3", "" ] + }, + { + "SQL": "select * from t1 intersect (select * from t2 except (select * from t3))", + "Plan": [ + "HashJoin_11 6400.00 root semi join, equal:[nulleq(test.t1.a, test.t2.a)]", + "├─HashJoin_20(Build) 6400.00 root anti semi join, equal:[nulleq(test.t2.a, test.t3.a)]", + "│ ├─TableReader_31(Build) 10000.00 root data:TableFullScan_30", + "│ │ └─TableFullScan_30 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo", + "│ └─HashAgg_23(Probe) 8000.00 root group by:test.t2.a, funcs:firstrow(test.t2.a)->test.t2.a", + "│ └─TableReader_28 10000.00 root data:TableFullScan_27", + "│ └─TableFullScan_27 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", + "└─HashAgg_14(Probe) 8000.00 root group by:test.t1.a, funcs:firstrow(test.t1.a)->test.t1.a", + " └─TableReader_19 10000.00 root data:TableFullScan_18", + " └─TableFullScan_18 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + ], + "Res": [ + "1", + "" + ] + }, + { + "SQL": "select * from t1 union all (select * from t2 except select * from t3)", + "Plan": [ + "Union_12 16400.00 root ", + "├─TableReader_15 10000.00 root data:TableFullScan_14", + "│ └─TableFullScan_14 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "└─HashJoin_17 6400.00 root anti semi join, equal:[nulleq(test.t2.a, test.t3.a)]", + " ├─TableReader_27(Build) 10000.00 root data:TableFullScan_26", + " │ └─TableFullScan_26 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo", + " └─HashAgg_20(Probe) 8000.00 root group by:test.t2.a, funcs:firstrow(test.t2.a)->test.t2.a", + " └─TableReader_25 10000.00 root data:TableFullScan_24", + " └─TableFullScan_24 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo" + ], + "Res": [ + "1", + "1", + "1", + "2", + "3", + "", + "" + ] + }, + { + "SQL": "select * from t1 union (select * from t2 union all select * from t3)", + "Plan": [ + "HashAgg_16 24000.00 root group by:Column#8, funcs:firstrow(Column#8)->Column#8", + "└─Union_17 30000.00 root ", + " ├─TableReader_20 10000.00 root data:TableFullScan_19", + " │ └─TableFullScan_19 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + " └─Union_22 20000.00 root ", + " ├─TableReader_25 10000.00 root data:TableFullScan_24", + " │ └─TableFullScan_24 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", + " └─TableReader_28 10000.00 root data:TableFullScan_27", + " └─TableFullScan_27 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo" + ], + "Res": [ + "1", + "2", + "3", + "" + ] + }, + { + "SQL": "(select * from t1 intersect select * from t1) except (select * from t2 union select * from t3)", + "Plan": [ + "HashJoin_18 5120.00 root anti semi join, equal:[nulleq(test.t1.a, Column#9)]", + "├─HashAgg_33(Build) 16000.00 root group by:Column#9, funcs:firstrow(Column#9)->Column#9", + "│ └─Union_34 20000.00 root ", + "│ ├─TableReader_37 10000.00 root data:TableFullScan_36", + "│ │ └─TableFullScan_36 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", + "│ └─TableReader_40 10000.00 root data:TableFullScan_39", + "│ └─TableFullScan_39 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo", + "└─HashJoin_20(Probe) 6400.00 root semi join, equal:[nulleq(test.t1.a, test.t1.a)]", + " ├─TableReader_30(Build) 10000.00 root data:TableFullScan_29", + " │ └─TableFullScan_29 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + " └─HashAgg_23(Probe) 8000.00 root group by:test.t1.a, funcs:firstrow(test.t1.a)->test.t1.a", + " └─TableReader_28 10000.00 root data:TableFullScan_27", + " └─TableFullScan_27 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + ], + "Res": null } ] }, diff --git a/go.mod b/go.mod index 2731294426812..9f1b584ca2eac 100644 --- a/go.mod +++ b/go.mod @@ -20,7 +20,6 @@ require ( github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4 github.com/iancoleman/strcase v0.0.0-20191112232945-16388991a334 github.com/juju/errors v0.0.0-20181118221551-089d3ea4e4d5 - github.com/juju/testing v0.0.0-20200706033705-4c23f9c453cd // indirect github.com/klauspost/cpuid v1.2.1 github.com/ngaut/pools v0.0.0-20180318154953-b7bc8c42aac7 github.com/ngaut/sync2 v0.0.0-20141008032647-7a24ed77b2ef @@ -28,8 +27,8 @@ require ( github.com/opentracing/basictracer-go v1.0.0 github.com/opentracing/opentracing-go v1.1.0 github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2 - github.com/pingcap/br v0.0.0-20200915060630-cc1a3924f33e github.com/pingcap/badger v1.5.1-0.20200908111422-2e78ee155d19 + github.com/pingcap/br v0.0.0-20200918114808-5af97a1a579f github.com/pingcap/check v0.0.0-20200212061837-5e12011dc712 github.com/pingcap/errors v0.11.5-0.20200902104258-eba4f1d8f6de github.com/pingcap/failpoint v0.0.0-20200702092429-9f69995143ce @@ -37,7 +36,7 @@ require ( github.com/pingcap/goleveldb v0.0.0-20191226122134-f82aafb29989 github.com/pingcap/kvproto v0.0.0-20200828054126-d677e6fd224a github.com/pingcap/log v0.0.0-20200828042413-fce0951f1463 - github.com/pingcap/parser v0.0.0-20200918092742-715be3ca6376 + github.com/pingcap/parser v0.0.0-20200921041333-cd2542b7a8a2 github.com/pingcap/sysutil v0.0.0-20200715082929-4c47bcac246a github.com/pingcap/tidb-tools v4.0.5-0.20200820092506-34ea90c93237+incompatible github.com/pingcap/tipb v0.0.0-20200618092958-4fad48b4c8c3 @@ -52,7 +51,6 @@ require ( github.com/twmb/murmur3 v1.1.3 github.com/uber-go/atomic v1.3.2 github.com/uber/jaeger-client-go v2.22.1+incompatible - github.com/zhangjinpeng1987/raft v0.0.0-20200819064223-df31bb68a018 // indirect go.etcd.io/etcd v0.5.0-alpha.5.0.20191023171146-3cf2f69b5738 go.uber.org/atomic v1.6.0 go.uber.org/automaxprocs v1.2.0 diff --git a/go.sum b/go.sum index d472dd63918fb..928d5a25418a0 100644 --- a/go.sum +++ b/go.sum @@ -399,6 +399,8 @@ github.com/ngaut/unistore v0.0.0-20200604061006-d8e9dc0ad154/go.mod h1:YGQzxn9cV github.com/ngaut/unistore v0.0.0-20200630072006-0c4035925f69/go.mod h1:Hxlp5VAoPOHwcXLUw/E+P3XjJX1EP38NWjXPpc4nuOE= github.com/ngaut/unistore v0.0.0-20200803051709-607d96233b1d/go.mod h1:2QAH8tXCjeHuCSLEWKLYAzHPz2dB59VnhpPA2IDVeW4= github.com/ngaut/unistore v0.0.0-20200806113332-5b9f73333a19/go.mod h1:RtZJKyiaHRiII+b9/g/4339rSikSvfrUJmIbrUkYVi4= +github.com/ngaut/unistore v0.0.0-20200820080223-c734bcc4ea53/go.mod h1:85S5ZgzoHtTMyaEYhaWnxv9OWMBfyhTNuWypXCfVn/0= +github.com/ngaut/unistore v0.0.0-20200828072424-1c0ede06a3fc/go.mod h1:iSlx5Ub/926GvQn6+d2B2C16wJJwgQIsi6k/bEU0vl4= github.com/ngaut/unistore v0.0.0-20200917091459-ad75c60139c1 h1:qrWHSES31nbJpn/KcBkp07Y+FVqGbh0aO0iYoSR/38s= github.com/ngaut/unistore v0.0.0-20200917091459-ad75c60139c1/go.mod h1:ZR3NH+HzqfiYetwdoAivApnIy8iefPZHTMLfrFNm8g4= github.com/nicksnyder/go-i18n v1.10.0/go.mod h1:HrK7VCrbOvQoUAQ7Vpy7i87N7JZZZ7R2xBGjv0j365Q= @@ -439,6 +441,7 @@ github.com/pingcap-incubator/tidb-dashboard v0.0.0-20200807020752-01f0abe88e93/g github.com/pingcap/badger v1.5.1-0.20200604041313-19c397305fcc/go.mod h1:LyrqUOHZrUDf9oGi1yoz1+qw9ckSIhQb5eMa1acOLNQ= github.com/pingcap/badger v1.5.1-0.20200714132513-80ba2000f159 h1:cmZSuRbdfOJd3kJjRIClrLbt3nD0xi4oqYR1c/ZrPKg= github.com/pingcap/badger v1.5.1-0.20200714132513-80ba2000f159/go.mod h1:LyrqUOHZrUDf9oGi1yoz1+qw9ckSIhQb5eMa1acOLNQ= +github.com/pingcap/badger v1.5.1-0.20200810065601-8c92a97807f9/go.mod h1:LyrqUOHZrUDf9oGi1yoz1+qw9ckSIhQb5eMa1acOLNQ= github.com/pingcap/badger v1.5.1-0.20200908111422-2e78ee155d19 h1:IXpGy7y9HyoShAFmzW2OPF0xCA5EOoSTyZHwsgYk9Ro= github.com/pingcap/badger v1.5.1-0.20200908111422-2e78ee155d19/go.mod h1:LyrqUOHZrUDf9oGi1yoz1+qw9ckSIhQb5eMa1acOLNQ= github.com/pingcap/br v0.0.0-20200426093517-dd11ae28b885/go.mod h1:4w3meMnk7HDNpNgjuRAxavruTeKJvUiXxoEWTjzXPnA= @@ -450,8 +453,8 @@ github.com/pingcap/br v0.0.0-20200803052654-e6f63fc1807a/go.mod h1:8j7vGUfHCETYb github.com/pingcap/br v0.0.0-20200805121136-181c081ba6ac/go.mod h1:9P24mNzNmXjggYBm4pnb08slSbua8FA6QIyg68GpuhQ= github.com/pingcap/br v0.0.0-20200820083933-d9d6207c0aa7 h1:7YWkuK/QY7/nz819lnxb0qDXqLrApDjZHjYPo+tduGA= github.com/pingcap/br v0.0.0-20200820083933-d9d6207c0aa7/go.mod h1:5ri8663t7CtJuG0kiOKKoBmwk9HOCX5MoKpmh1fW4CE= -github.com/pingcap/br v0.0.0-20200915060630-cc1a3924f33e h1:OwuX87FvesIE0HMz7RznDY++QWBqSUveociglqKenNA= -github.com/pingcap/br v0.0.0-20200915060630-cc1a3924f33e/go.mod h1:DGsMcZVYt2haeDF/xGerf77c2RpTymgYY5+bMg8uArA= +github.com/pingcap/br v0.0.0-20200918114808-5af97a1a579f h1:zyeF39OhLcFH4Aeal9o11L4fIHgylTvKqfYK/dRoasQ= +github.com/pingcap/br v0.0.0-20200918114808-5af97a1a579f/go.mod h1:DGsMcZVYt2haeDF/xGerf77c2RpTymgYY5+bMg8uArA= github.com/pingcap/check v0.0.0-20190102082844-67f458068fc8/go.mod h1:B1+S9LNcuMyLH/4HMTViQOJevkGiik3wW2AN9zb2fNQ= github.com/pingcap/check v0.0.0-20191107115940-caf2b9e6ccf4/go.mod h1:PYMCGwN0JHjoqGr3HrZoD+b8Tgx8bKnArhSq8YVzUMc= github.com/pingcap/check v0.0.0-20191216031241-8a5a85928f12/go.mod h1:PYMCGwN0JHjoqGr3HrZoD+b8Tgx8bKnArhSq8YVzUMc= @@ -510,8 +513,9 @@ github.com/pingcap/parser v0.0.0-20200623082809-b74301ac298b/go.mod h1:vQdbJqobJ github.com/pingcap/parser v0.0.0-20200730092557-34a468e9b774/go.mod h1:vQdbJqobJAgFyiRNNtXahpMoGWwPEuWciVEK5A20NS0= github.com/pingcap/parser v0.0.0-20200731033026-84f62115187c/go.mod h1:vQdbJqobJAgFyiRNNtXahpMoGWwPEuWciVEK5A20NS0= github.com/pingcap/parser v0.0.0-20200813083329-a4bff035d3e2/go.mod h1:vQdbJqobJAgFyiRNNtXahpMoGWwPEuWciVEK5A20NS0= -github.com/pingcap/parser v0.0.0-20200918092742-715be3ca6376 h1:0j5pdKdpPj2g4UiNVKXkc5qBv6Ci57fymWIChAV2ZVk= -github.com/pingcap/parser v0.0.0-20200918092742-715be3ca6376/go.mod h1:RlLfMRJwFBSiXd2lUaWdV5pSXtrpyvZM8k5bbZWsheU= +github.com/pingcap/parser v0.0.0-20200821073936-cf85e80665c4/go.mod h1:vQdbJqobJAgFyiRNNtXahpMoGWwPEuWciVEK5A20NS0= +github.com/pingcap/parser v0.0.0-20200921041333-cd2542b7a8a2 h1:LsLCF+s7FNV009UqJfp/wEU6CYHLXluhoa2/3F5X5/M= +github.com/pingcap/parser v0.0.0-20200921041333-cd2542b7a8a2/go.mod h1:RlLfMRJwFBSiXd2lUaWdV5pSXtrpyvZM8k5bbZWsheU= github.com/pingcap/pd/v4 v4.0.0-rc.1.0.20200422143320-428acd53eba2/go.mod h1:s+utZtXDznOiL24VK0qGmtoHjjXNsscJx3m1n8cC56s= github.com/pingcap/pd/v4 v4.0.0-rc.2.0.20200520083007-2c251bd8f181/go.mod h1:q4HTx/bA8aKBa4S7L+SQKHvjRPXCRV0tA0yRw0qkZSA= github.com/pingcap/pd/v4 v4.0.0-rc.2.0.20200714122454-1a64f969cb3c/go.mod h1:v/dY4mVkt3dh/Liphhk0E4ScOkZpIk0m0GvWJ9FapDs= @@ -534,6 +538,8 @@ github.com/pingcap/tidb v1.1.0-beta.0.20200803051932-e291f8fbd1e0/go.mod h1:YFuu github.com/pingcap/tidb v1.1.0-beta.0.20200805053026-cd3e5ed82671/go.mod h1:+r9tlyUKG2zYzs2ajvEHiQlTx6WM0K2L1yabCHZwgGw= github.com/pingcap/tidb v1.1.0-beta.0.20200806060043-574540aa06ba/go.mod h1:NHcZH46dkYwDd2IWUJaLOB0m54j7v2P5WdS4FvPR81w= github.com/pingcap/tidb v1.1.0-beta.0.20200810064414-d81150394f9d/go.mod h1:vLYo4E7Q6kzKYTskhP2MHBsodmZIRRUU63qdiFjlULA= +github.com/pingcap/tidb v1.1.0-beta.0.20200820085534-0d997f2b8b3c/go.mod h1:z7Hn1KY8Crt9cHhWtbGPKMBcjvmSJXIoOjO4rMk165w= +github.com/pingcap/tidb v1.1.0-beta.0.20200831085451-438945d2948e/go.mod h1:VXxiC2f+HY3/5phR1841YJrX4on56kTEXrtEzRezcj4= github.com/pingcap/tidb-tools v4.0.0-beta.1.0.20200306084441-875bd09aa3d5+incompatible/go.mod h1:XGdcy9+yqlDSEMTpOXnwf3hiTeqrV6MN/u1se9N8yIM= github.com/pingcap/tidb-tools v4.0.0-rc.1.0.20200421113014-507d2bb3a15e+incompatible/go.mod h1:XGdcy9+yqlDSEMTpOXnwf3hiTeqrV6MN/u1se9N8yIM= github.com/pingcap/tidb-tools v4.0.0-rc.1.0.20200514040632-f76b3e428e19+incompatible/go.mod h1:XGdcy9+yqlDSEMTpOXnwf3hiTeqrV6MN/u1se9N8yIM= diff --git a/planner/core/logical_plan_builder.go b/planner/core/logical_plan_builder.go index 6f6c5f4a8972b..30f4ec7d6fd28 100644 --- a/planner/core/logical_plan_builder.go +++ b/planner/core/logical_plan_builder.go @@ -1171,8 +1171,22 @@ func (b *PlanBuilder) buildSetOpr(ctx context.Context, setOpr *ast.SetOprStmt) ( afterSetOprs := make([]*ast.SetOprType, 0, len(setOpr.SelectList.Selects)) selects := setOpr.SelectList.Selects for i := 0; i < len(selects); i++ { - intersects := []*ast.SelectStmt{selects[i]} - for i+1 < len(selects) && *selects[i+1].AfterSetOperator == ast.Intersect { + intersects := []ast.Node{selects[i]} + for i+1 < len(selects) { + breakIteration := false + switch x := selects[i+1].(type) { + case *ast.SelectStmt: + if *x.AfterSetOperator != ast.Intersect && *x.AfterSetOperator != ast.IntersectAll { + breakIteration = true + } + case *ast.SetOprSelectList: + if *x.AfterSetOperator != ast.Intersect && *x.AfterSetOperator != ast.IntersectAll { + breakIteration = true + } + } + if breakIteration { + break + } intersects = append(intersects, selects[i+1]) i++ } @@ -1255,18 +1269,42 @@ func (b *PlanBuilder) buildSemiJoinForSetOperator( // buildIntersect build the set operator for 'intersect'. It is called before buildExcept and buildUnion because of its // higher precedence. -func (b *PlanBuilder) buildIntersect(ctx context.Context, selects []*ast.SelectStmt) (LogicalPlan, *ast.SetOprType, error) { - leftPlan, err := b.buildSelect(ctx, selects[0]) +func (b *PlanBuilder) buildIntersect(ctx context.Context, selects []ast.Node) (LogicalPlan, *ast.SetOprType, error) { + var leftPlan LogicalPlan + var err error + var afterSetOperator *ast.SetOprType + switch x := selects[0].(type) { + case *ast.SelectStmt: + afterSetOperator = x.AfterSetOperator + leftPlan, err = b.buildSelect(ctx, x) + case *ast.SetOprSelectList: + afterSetOperator = x.AfterSetOperator + leftPlan, err = b.buildSetOpr(ctx, &ast.SetOprStmt{SelectList: x}) + } if err != nil { return nil, nil, err } if len(selects) == 1 { - return leftPlan, selects[0].AfterSetOperator, nil + return leftPlan, afterSetOperator, nil } columnNums := leftPlan.Schema().Len() for i := 1; i < len(selects); i++ { - rightPlan, err := b.buildSelect(ctx, selects[i]) + var rightPlan LogicalPlan + switch x := selects[i].(type) { + case *ast.SelectStmt: + if *x.AfterSetOperator == ast.IntersectAll { + // TODO: support intersect all + return nil, nil, errors.Errorf("TiDB do not support intersect all") + } + rightPlan, err = b.buildSelect(ctx, x) + case *ast.SetOprSelectList: + if *x.AfterSetOperator == ast.IntersectAll { + // TODO: support intersect all + return nil, nil, errors.Errorf("TiDB do not support intersect all") + } + rightPlan, err = b.buildSetOpr(ctx, &ast.SetOprStmt{SelectList: x}) + } if err != nil { return nil, nil, err } @@ -1278,7 +1316,7 @@ func (b *PlanBuilder) buildIntersect(ctx context.Context, selects []*ast.SelectS return nil, nil, err } } - return leftPlan, selects[0].AfterSetOperator, nil + return leftPlan, afterSetOperator, nil } // buildExcept build the set operators for 'except', and in this function, it calls buildUnion at the same time. Because @@ -1303,6 +1341,9 @@ func (b *PlanBuilder) buildExcept(ctx context.Context, selects []LogicalPlan, af } unionPlans = []LogicalPlan{leftPlan} tmpAfterSetOpts = []*ast.SetOprType{nil} + } else if *afterSetOpts[i] == ast.ExceptAll { + // TODO: support except all. + return nil, errors.Errorf("TiDB do not support except all") } else { unionPlans = append(unionPlans, rightPlan) tmpAfterSetOpts = append(tmpAfterSetOpts, afterSetOpts[i]) diff --git a/planner/core/preprocess.go b/planner/core/preprocess.go index a3db024dcc546..57bc27c4cc916 100644 --- a/planner/core/preprocess.go +++ b/planner/core/preprocess.go @@ -409,16 +409,21 @@ func (p *preprocessor) checkAutoIncrement(stmt *ast.CreateTableStmt) { // "To apply ORDER BY or LIMIT to an individual SELECT, place the clause inside the parentheses that enclose the SELECT." func (p *preprocessor) checkSetOprSelectList(stmt *ast.SetOprSelectList) { for _, sel := range stmt.Selects[:len(stmt.Selects)-1] { - if sel.IsInBraces { - continue - } - if sel.Limit != nil { - p.err = ErrWrongUsage.GenWithStackByArgs("UNION", "LIMIT") - return - } - if sel.OrderBy != nil { - p.err = ErrWrongUsage.GenWithStackByArgs("UNION", "ORDER BY") - return + switch s := sel.(type) { + case *ast.SelectStmt: + if s.IsInBraces { + continue + } + if s.Limit != nil { + p.err = ErrWrongUsage.GenWithStackByArgs("UNION", "LIMIT") + return + } + if s.OrderBy != nil { + p.err = ErrWrongUsage.GenWithStackByArgs("UNION", "ORDER BY") + return + } + case *ast.SetOprSelectList: + p.checkSetOprSelectList(s) } } } @@ -513,14 +518,21 @@ func (p *preprocessor) checkCreateViewGrammar(stmt *ast.CreateViewStmt) { } } -func (p *preprocessor) checkCreateViewWithSelect(stmt *ast.SelectStmt) { - if stmt.SelectIntoOpt != nil { - p.err = ddl.ErrViewSelectClause.GenWithStackByArgs("INFO") - return - } - if stmt.LockInfo != nil && stmt.LockInfo.LockType != ast.SelectLockNone { - stmt.LockInfo.LockType = ast.SelectLockNone - return +func (p *preprocessor) checkCreateViewWithSelect(stmt ast.Node) { + switch s := stmt.(type) { + case *ast.SelectStmt: + if s.SelectIntoOpt != nil { + p.err = ddl.ErrViewSelectClause.GenWithStackByArgs("INFO") + return + } + if s.LockInfo != nil && s.LockInfo.LockType != ast.SelectLockNone { + s.LockInfo.LockType = ast.SelectLockNone + return + } + case *ast.SetOprSelectList: + for _, sel := range s.Selects { + p.checkCreateViewWithSelect(sel) + } } } diff --git a/tidb-server/main.go b/tidb-server/main.go index 0c96b4a7c518e..e43834c1b3418 100644 --- a/tidb-server/main.go +++ b/tidb-server/main.go @@ -419,7 +419,7 @@ func overrideConfig(cfg *config.Config) { if actualFlags[nmAdvertiseAddress] { cfg.AdvertiseAddress = *advertiseAddress } - if len(cfg.AdvertiseAddress) == 0 { + if len(cfg.AdvertiseAddress) == 0 && cfg.Host == "0.0.0.0" { cfg.AdvertiseAddress = util.GetLocalIP() } if len(cfg.AdvertiseAddress) == 0 { diff --git a/util/misc.go b/util/misc.go index b27c4d6fc5f4e..2d731f48bbcc7 100644 --- a/util/misc.go +++ b/util/misc.go @@ -440,7 +440,8 @@ type SequenceSchema interface { SequenceByName(schema, sequence model.CIStr) (SequenceTable, error) } -// SequenceTable is implemented by tableCommon, and it is specialised in handling sequence operation. +// SequenceTable is implemented by tableCommon, +// and it is specialised in handling sequence operation. // Otherwise calling table will cause import cycle problem. type SequenceTable interface { GetSequenceID() int64