Repository: pingcap/tidb (Go)

Issue:
planner: don't reset optFlag when build DataSource from View
## Bug Report

Please answer these questions before submitting your issue. Thanks!

### 1. What did you do?

<!-- If possible, provide a recipe for reproducing the error. -->
```
mysql> create table pt (a int primary key, b int)
 partition by range (a)
 (partition p0 values less than(10), 
partition p1 values less than(20), 
partition p2 values less than(30));
Query OK, 0 rows affected (0.04 sec)

mysql> insert into pt values(1, 1), (11, 11), (21, 21);

mysql> select * from t;
+------+------+
| a    | b    |
+------+------+
|    1 |    1 |
+------+------+
1 row in set (0.00 sec)
Query OK, 3 rows affected (0.01 sec)
Records: 3  Duplicates: 0  Warnings: 0

mysql> create view vt (a, b) as select a, b from t;
Query OK, 0 rows affected (0.00 sec)
```

```
mysql> select * from pt, t where pt.a < 10 and pt.b = t.b;
+---+------+------+------+
| a | b    | a    | b    |
+---+------+------+------+
| 1 |    1 |    1 |    1 |
+---+------+------+------+
1 row in set (0.01 sec)

mysql> select * from pt, vt where pt.a < 10 and pt.b = vt.b;
Empty set (0.00 sec)
```
### 2. What did you expect to see?
The two queries above should have the same result `1, 1, 1, 1`.
### 3. What did you see instead?
When we use the view `vt`, the result set is empty.
### 4. What version of TiDB are you using? (`tidb-server -V` or run `select tidb_version();` on TiDB)
4.0-beta


Discussion:
The root cause is when we build DataSource from a View, we reset the `optFlag`.



Patch:
diff --git a/planner/core/planbuilder.go b/planner/core/planbuilder.go
index ec0787d756848..9d2a9c77a5b18 100644
--- a/planner/core/planbuilder.go
+++ b/planner/core/planbuilder.go
@@ -397,7 +397,7 @@ func NewPlanBuilder(sctx sessionctx.Context, is infoschema.InfoSchema, processor
 
 // Build builds the ast node to a Plan.
 func (b *PlanBuilder) Build(ctx context.Context, node ast.Node) (Plan, error) {
-	b.optFlag = flagPrunColumns
+	b.optFlag |= flagPrunColumns
 	defer func() {
 		// if there is something after flagPrunColumns, do flagPrunColumnsAgain
 		if b.optFlag&flagPrunColumns > 0 && b.optFlag-flagPrunColumns > flagPrunColumns {


Test patch:
diff --git a/planner/core/integration_test.go b/planner/core/integration_test.go
index fe0fd05a972fb..2bfe3e798e596 100644
--- a/planner/core/integration_test.go
+++ b/planner/core/integration_test.go
@@ -624,3 +624,17 @@ func (s *testIntegrationSuite) TestSubqueryWithTopN(c *C) {
 		tk.MustQuery(tt).Check(testkit.Rows(output[i].Plan...))
 	}
 }
+
+func (s *testIntegrationSuite) TestIssue15546(c *C) {
+	tk := testkit.NewTestKit(c, s.store)
+
+	tk.MustExec("use test")
+	tk.MustExec("drop table if exists t, pt, vt")
+	tk.MustExec("create table t(a int, b int)")
+	tk.MustExec("insert into t values(1, 1)")
+	tk.MustExec("create table pt(a int primary key, b int) partition by range(a) (" +
+		"PARTITION `p0` VALUES LESS THAN (10), PARTITION `p1` VALUES LESS THAN (20), PARTITION `p2` VALUES LESS THAN (30))")
+	tk.MustExec("insert into pt values(1, 1), (11, 11), (21, 21)")
+	tk.MustExec("create definer='root'@'localhost' view vt(a, b) as select a, b from t")
+	tk.MustQuery("select * from pt, vt where pt.a = vt.a").Check(testkit.Rows("1 1 1 1"))
+}