Skip to content

Commit

Permalink
This is an automated cherry-pick of pingcap#53268
Browse files Browse the repository at this point in the history
Signed-off-by: ti-chi-bot <[email protected]>
  • Loading branch information
winoros authored and ti-chi-bot committed May 14, 2024
1 parent 1f29133 commit 65f264e
Show file tree
Hide file tree
Showing 12 changed files with 491 additions and 49 deletions.
1 change: 0 additions & 1 deletion build/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,6 @@ nogo(
}) +
select({
"//build:without_rbe": [
"//build/linter/filepermission",
],
"//conditions:default": [],
}),
Expand Down
1 change: 0 additions & 1 deletion pkg/expression/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,6 @@ go_library(
"@com_github_pingcap_tipb//go-tipb",
"@com_github_pkg_errors//:errors",
"@com_github_tikv_client_go_v2//oracle",
"@org_golang_x_tools//container/intsets",
"@org_uber_go_atomic//:atomic",
"@org_uber_go_zap//:zap",
],
Expand Down
10 changes: 5 additions & 5 deletions pkg/expression/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,10 @@ import (
driver "github.com/pingcap/tidb/pkg/types/parser_driver"
"github.com/pingcap/tidb/pkg/util/chunk"
"github.com/pingcap/tidb/pkg/util/collate"
"github.com/pingcap/tidb/pkg/util/intset"
"github.com/pingcap/tidb/pkg/util/logutil"
"github.com/pingcap/tidb/pkg/util/sqlexec"
"go.uber.org/zap"
"golang.org/x/tools/container/intsets"
)

// cowExprRef is a copy-on-write slice ref util using in `ColumnSubstitute`
Expand Down Expand Up @@ -372,15 +372,15 @@ func ExtractColumnsAndCorColumnsFromExpressions(result []*Column, list []Express
}

// ExtractColumnSet extracts the different values of `UniqueId` for columns in expressions.
func ExtractColumnSet(exprs ...Expression) *intsets.Sparse {
set := &intsets.Sparse{}
func ExtractColumnSet(exprs ...Expression) intset.FastIntSet {
set := intset.NewFastIntSet()
for _, expr := range exprs {
extractColumnSet(expr, set)
extractColumnSet(expr, &set)
}
return set
}

func extractColumnSet(expr Expression, set *intsets.Sparse) {
func extractColumnSet(expr Expression, set *intset.FastIntSet) {
switch v := expr.(type) {
case *Column:
set.Insert(int(v.UniqueID))
Expand Down
4 changes: 2 additions & 2 deletions pkg/planner/core/logical_plan_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -6430,8 +6430,8 @@ func (b *PlanBuilder) buildUpdateLists(ctx context.Context, tableList []*ast.Tab
allAssignmentsAreConstant = false
}
p = np
if col, ok := newExpr.(*expression.Column); ok {
b.ctx.GetSessionVars().StmtCtx.ColRefFromUpdatePlan = append(b.ctx.GetSessionVars().StmtCtx.ColRefFromUpdatePlan, col.UniqueID)
if cols := expression.ExtractColumnSet(newExpr); cols.Len() > 0 {
b.ctx.GetSessionVars().StmtCtx.ColRefFromUpdatePlan.UnionWith(cols)
}
newList = append(newList, &expression.Assignment{Col: col, ColName: name.ColName, Expr: newExpr})
dbName := name.DBName.L
Expand Down
12 changes: 5 additions & 7 deletions pkg/planner/core/rule_eliminate_projection.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,13 +80,6 @@ func canProjectionBeEliminatedStrict(p *PhysicalProjection) bool {
if p.Schema().Len() != child.Schema().Len() {
return false
}
for _, ref := range p.SCtx().GetSessionVars().StmtCtx.ColRefFromUpdatePlan {
for _, one := range p.Schema().Columns {
if ref == one.UniqueID {
return false
}
}
}
for i, expr := range p.Exprs {
col, ok := expr.(*expression.Column)
if !ok || !col.Equal(nil, child.Schema().Columns[i]) {
Expand Down Expand Up @@ -140,6 +133,11 @@ func doPhysicalProjectionElimination(p PhysicalPlan) PhysicalPlan {
if childProj, ok := child.(*PhysicalProjection); ok {
childProj.SetSchema(p.Schema())
}
for i, col := range p.Schema().Columns {
if p.SCtx().GetSessionVars().StmtCtx.ColRefFromUpdatePlan.Has(int(col.UniqueID)) && !child.Schema().Columns[i].Equal(nil, col) {
return p
}
}
return child
}

Expand Down
1 change: 1 addition & 0 deletions pkg/sessionctx/stmtctx/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ go_library(
"//pkg/util/disk",
"//pkg/util/execdetails",
"//pkg/util/intest",
"//pkg/util/intset",
"//pkg/util/linter/constructor",
"//pkg/util/memory",
"//pkg/util/nocopy",
Expand Down
3 changes: 2 additions & 1 deletion pkg/sessionctx/stmtctx/stmtctx.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import (
"github.com/pingcap/tidb/pkg/util/disk"
"github.com/pingcap/tidb/pkg/util/execdetails"
"github.com/pingcap/tidb/pkg/util/intest"
"github.com/pingcap/tidb/pkg/util/intset"
"github.com/pingcap/tidb/pkg/util/linter/constructor"
"github.com/pingcap/tidb/pkg/util/memory"
"github.com/pingcap/tidb/pkg/util/nocopy"
Expand Down Expand Up @@ -388,7 +389,7 @@ type StatementContext struct {
// UseDynamicPruneMode indicates whether use UseDynamicPruneMode in query stmt
UseDynamicPruneMode bool
// ColRefFromPlan mark the column ref used by assignment in update statement.
ColRefFromUpdatePlan []int64
ColRefFromUpdatePlan intset.FastIntSet

// RangeFallback indicates that building complete ranges exceeds the memory limit so it falls back to less accurate ranges such as full range.
RangeFallback bool
Expand Down
26 changes: 11 additions & 15 deletions tests/integrationtest/r/planner/core/casetest/integration.result
Original file line number Diff line number Diff line change
Expand Up @@ -1565,18 +1565,14 @@ explain format = brief update tt, (select 1 as c1 ,2 as c2 ,3 as c3, 4 as c4 uni
id estRows task access object operator info
Update N/A root N/A
└─Projection 0.00 root test.tt.a, test.tt.b, test.tt.c, test.tt.d, test.tt.e, Column#18, Column#19, Column#20, Column#21
└─Projection 0.00 root test.tt.a, test.tt.b, test.tt.c, test.tt.d, test.tt.e, Column#18, Column#19, Column#20, Column#21
└─IndexJoin 0.00 root inner join, inner:TableReader, outer key:Column#20, Column#21, inner key:test.tt.c, test.tt.d, equal cond:eq(Column#20, test.tt.c), eq(Column#21, test.tt.d), other cond:or(or(and(eq(Column#20, 11), eq(test.tt.d, 111)), and(eq(Column#20, 22), eq(test.tt.d, 222))), or(and(eq(Column#20, 33), eq(test.tt.d, 333)), and(eq(Column#20, 44), eq(test.tt.d, 444)))), or(or(and(eq(test.tt.c, 11), eq(Column#21, 111)), and(eq(test.tt.c, 22), eq(Column#21, 222))), or(and(eq(test.tt.c, 33), eq(Column#21, 333)), and(eq(test.tt.c, 44), eq(Column#21, 444))))
├─Union(Build) 0.00 root
│ ├─Projection 0.00 root Column#6->Column#18, Column#7->Column#19, Column#8->Column#20, Column#9->Column#21
│ │ └─Projection 0.00 root 1->Column#6, 2->Column#7, 3->Column#8, 4->Column#9
│ │ └─TableDual 0.00 root rows:0
│ ├─Projection 0.00 root Column#10->Column#18, Column#11->Column#19, Column#12->Column#20, Column#13->Column#21
│ │ └─Projection 0.00 root 2->Column#10, 3->Column#11, 4->Column#12, 5->Column#13
│ │ └─TableDual 0.00 root rows:0
│ └─Projection 0.00 root Column#14->Column#18, Column#15->Column#19, Column#16->Column#20, Column#17->Column#21
│ └─Projection 0.00 root 3->Column#14, 4->Column#15, 5->Column#16, 6->Column#17
│ └─TableDual 0.00 root rows:0
└─TableReader(Probe) 0.00 root data:Selection
└─Selection 0.00 cop[tikv] or(or(and(eq(test.tt.c, 11), eq(test.tt.d, 111)), and(eq(test.tt.c, 22), eq(test.tt.d, 222))), or(and(eq(test.tt.c, 33), eq(test.tt.d, 333)), and(eq(test.tt.c, 44), eq(test.tt.d, 444)))), or(or(eq(test.tt.c, 11), eq(test.tt.c, 22)), or(eq(test.tt.c, 33), eq(test.tt.c, 44))), or(or(eq(test.tt.d, 111), eq(test.tt.d, 222)), or(eq(test.tt.d, 333), eq(test.tt.d, 444)))
└─TableRangeScan 0.00 cop[tikv] table:tt range: decided by [eq(test.tt.c, Column#20) eq(test.tt.d, Column#21)], keep order:false, stats:pseudo
└─IndexJoin 0.00 root inner join, inner:TableReader, outer key:Column#20, Column#21, inner key:test.tt.c, test.tt.d, equal cond:eq(Column#20, test.tt.c), eq(Column#21, test.tt.d), other cond:or(or(and(eq(Column#20, 11), eq(test.tt.d, 111)), and(eq(Column#20, 22), eq(test.tt.d, 222))), or(and(eq(Column#20, 33), eq(test.tt.d, 333)), and(eq(Column#20, 44), eq(test.tt.d, 444)))), or(or(and(eq(test.tt.c, 11), eq(Column#21, 111)), and(eq(test.tt.c, 22), eq(Column#21, 222))), or(and(eq(test.tt.c, 33), eq(Column#21, 333)), and(eq(test.tt.c, 44), eq(Column#21, 444))))
├─Union(Build) 0.00 root
│ ├─Projection 0.00 root 1->Column#18, 2->Column#19, 3->Column#20, 4->Column#21
│ │ └─TableDual 0.00 root rows:0
│ ├─Projection 0.00 root 2->Column#18, 3->Column#19, 4->Column#20, 5->Column#21
│ │ └─TableDual 0.00 root rows:0
│ └─Projection 0.00 root 3->Column#18, 4->Column#19, 5->Column#20, 6->Column#21
│ └─TableDual 0.00 root rows:0
└─TableReader(Probe) 0.00 root data:Selection
└─Selection 0.00 cop[tikv] or(or(and(eq(test.tt.c, 11), eq(test.tt.d, 111)), and(eq(test.tt.c, 22), eq(test.tt.d, 222))), or(and(eq(test.tt.c, 33), eq(test.tt.d, 333)), and(eq(test.tt.c, 44), eq(test.tt.d, 444)))), or(or(eq(test.tt.c, 11), eq(test.tt.c, 22)), or(eq(test.tt.c, 33), eq(test.tt.c, 44))), or(or(eq(test.tt.d, 111), eq(test.tt.d, 222)), or(eq(test.tt.d, 333), eq(test.tt.d, 444)))
└─TableRangeScan 0.00 cop[tikv] table:tt range: decided by [eq(test.tt.c, Column#20) eq(test.tt.d, Column#21)], keep order:false, stats:pseudo
15 changes: 7 additions & 8 deletions tests/integrationtest/r/planner/core/cbo.result
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,13 @@ create table t(a int, b int);
explain update t t1, (select distinct b from t) t2 set t1.b = t2.b;
id estRows task access object operator info
Update_7 N/A root N/A
└─Projection_9 80000000.00 root planner__core__cbo.t.a, planner__core__cbo.t.b, planner__core__cbo.t._tidb_rowid, planner__core__cbo.t.b
└─HashJoin_10 80000000.00 root CARTESIAN inner join
├─HashAgg_18(Build) 8000.00 root group by:planner__core__cbo.t.b, funcs:firstrow(planner__core__cbo.t.b)->planner__core__cbo.t.b
│ └─TableReader_19 8000.00 root data:HashAgg_14
│ └─HashAgg_14 8000.00 cop[tikv] group by:planner__core__cbo.t.b,
│ └─TableFullScan_17 10000.00 cop[tikv] table:t keep order:false, stats:pseudo
└─TableReader_13(Probe) 10000.00 root data:TableFullScan_12
└─TableFullScan_12 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo
└─HashJoin_10 80000000.00 root CARTESIAN inner join
├─HashAgg_18(Build) 8000.00 root group by:planner__core__cbo.t.b, funcs:firstrow(planner__core__cbo.t.b)->planner__core__cbo.t.b
│ └─TableReader_19 8000.00 root data:HashAgg_14
│ └─HashAgg_14 8000.00 cop[tikv] group by:planner__core__cbo.t.b,
│ └─TableFullScan_17 10000.00 cop[tikv] table:t keep order:false, stats:pseudo
└─TableReader_13(Probe) 10000.00 root data:TableFullScan_12
└─TableFullScan_12 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo
drop table if exists tb1, tb2;
create table tb1(a int, b int, primary key(a));
create table tb2 (a int, b int, c int, d datetime, primary key(c),key idx_u(a));
Expand Down
220 changes: 220 additions & 0 deletions tests/integrationtest/r/planner/core/issuetest/planner_issue.result
Original file line number Diff line number Diff line change
Expand Up @@ -241,3 +241,223 @@ id value
3 0
4 4
5 5
<<<<<<< HEAD
=======
create table A(a int primary key, b int);
create table B(b int primary key);
create table C(c int primary key, b int);
insert into A values (2, 1), (3, 2);
insert into B values (1), (2);
select b.b
from A a
left join (
B b
left join C c on b.b = c.b)
on b.b = a.b
where a.a in (2, 3);
b
1
2
select b.b
from A a
left join (
B b
left join C c on b.b = c.b)
on b.b = a.b
where a.a in (2, 3, null);
b
1
2
CREATE TABLE `t_o9_7_f` (
`c_ob5k0` int(11) NOT NULL,
`c_r5axbk` tinyint(4) DEFAULT NULL,
`c_fulsthp7e` text DEFAULT NULL,
`c_nylhnz` double DEFAULT NULL,
`c_fd7zeyfs49` int(11) NOT NULL,
`c_wpmmiv` tinyint(4) DEFAULT NULL,
PRIMARY KEY (`c_fd7zeyfs49`) /*T![clustered_index] CLUSTERED */,
UNIQUE KEY `c_ob5k0` (`c_ob5k0`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
CREATE TABLE `t_q1` (
`c__c_r38murv` int(11) NOT NULL,
`c_i93u7f2yma` double NOT NULL,
`c_v5mf4` double DEFAULT NULL,
`c_gprkp` int(11) DEFAULT NULL,
`c_ru` text NOT NULL,
`c_nml` tinyint(4) DEFAULT NULL,
`c_z` text DEFAULT NULL,
`c_ok` double DEFAULT NULL,
PRIMARY KEY (`c__c_r38murv`) /*T![clustered_index] CLUSTERED */,
UNIQUE KEY `c__c_r38murv_2` (`c__c_r38murv`),
UNIQUE KEY `c_nml` (`c_nml`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
CREATE TABLE `t_yzyyqbo2u` (
`c_c4l` int(11) DEFAULT NULL,
`c_yb_` text DEFAULT NULL,
`c_pq4c1la6cv` int(11) NOT NULL,
`c_kbcid` int(11) DEFAULT NULL,
`c_um` double DEFAULT NULL,
`c_zjmgh995_6` text DEFAULT NULL,
`c_fujjmh8m2` double NOT NULL,
`c_qkf4n` double DEFAULT NULL,
`c__x9cqrnb0` double NOT NULL,
`c_b5qjz_jj0` double DEFAULT NULL,
PRIMARY KEY (`c_pq4c1la6cv`) /*T![clustered_index] NONCLUSTERED */,
UNIQUE KEY `c__x9cqrnb0` (`c__x9cqrnb0`),
UNIQUE KEY `c_b5qjz_jj0` (`c_b5qjz_jj0`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin /*T! SHARD_ROW_ID_BITS=4 PRE_SPLIT_REGIONS=2 */;
CREATE TABLE `t_kg74` (
`c_a1tv2` int(11) NOT NULL,
`c_eobbbypzbu` tinyint(4) DEFAULT NULL,
`c_g` double NOT NULL,
`c_ixy` tinyint(4) DEFAULT NULL,
`c_if` text NOT NULL,
`c_obnq8s7_s2` double DEFAULT NULL,
`c_xrgd2snrop` tinyint(4) DEFAULT NULL,
`c_vqafa6o6` text DEFAULT NULL,
`c_ku44klry7o` double NOT NULL,
`c_js835qkmjz` tinyint(4) DEFAULT NULL,
PRIMARY KEY (`c_a1tv2`));
update t_kg74 set
c_eobbbypzbu = (t_kg74.c_js835qkmjz in (
select
(ref_0.c_yb_ <> 'mlp40j') as c0
from
t_yzyyqbo2u as ref_0
where (89.25 && ref_0.c_pq4c1la6cv)
union
(select
((cast(null as double) != 1382756095))
and ((1=1 <> (EXISTS (
select distinct
ref_2.c_zjmgh995_6 as c0,
ref_2.c_zjmgh995_6 as c1,
ref_2.c_kbcid as c2,
ref_1.c_r5axbk as c3,
-633150135 as c4,
ref_2.c_c4l as c5,
ref_1.c_fd7zeyfs49 as c6,
ref_1.c_nylhnz as c7,
ref_2.c_um as c8,
ref_2.c_c4l as c9
from
t_yzyyqbo2u as ref_2
where ((ref_1.c_ob5k0 <= ref_2.c_qkf4n))
and ((EXISTS (
select
ref_3.c_qkf4n as c0,
ref_3.c_kbcid as c1,
ref_3.c_qkf4n as c2,
ref_1.c_wpmmiv as c3,
ref_1.c_fd7zeyfs49 as c4,
ref_3.c_c4l as c5,
ref_1.c_r5axbk as c6,
ref_3.c_kbcid as c7
from
t_yzyyqbo2u as ref_3
where ((ref_2.c_qkf4n >= (
select distinct
ref_4.c_b5qjz_jj0 as c0
from
t_yzyyqbo2u as ref_4
where (ref_3.c__x9cqrnb0 not in (
select
ref_5.c_ok as c0
from
t_q1 as ref_5
where 1=1
union
(select
ref_6.c_b5qjz_jj0 as c0
from
t_yzyyqbo2u as ref_6
where (ref_6.c_qkf4n not in (
select
ref_7.c_um as c0
from
t_yzyyqbo2u as ref_7
where 1=1
union
(select
ref_8.c_b5qjz_jj0 as c0
from
t_yzyyqbo2u as ref_8
where (ref_8.c_yb_ not like 'nrry%m')))))))
union
(select
ref_2.c_fujjmh8m2 as c0
from
t_q1 as ref_9
where (ref_2.c_zjmgh995_6 like 'v8%3xn%_uc'))
order by c0 limit 1)))
or ((ref_1.c_fulsthp7e in (
select
ref_10.c_ru as c0
from
t_q1 as ref_10
where (55.34 >= 1580576276)
union
(select
ref_11.c_ru as c0
from
t_q1 as ref_11
where (ref_11.c_ru in (
select distinct
ref_12.c_zjmgh995_6 as c0
from
t_yzyyqbo2u as ref_12
where 0<>0
union
(select
ref_13.c_zjmgh995_6 as c0
from
t_yzyyqbo2u as ref_13
where ('q2chm8gfsa' = ref_13.c_yb_))))))))))))))) as c0
from
t_o9_7_f as ref_1
where (-9186514464458010455 <> 62.67)))),
c_if = 'u1ah7',
c_vqafa6o6 = (t_kg74.c_a1tv2 + (((t_kg74.c_a1tv2 between t_kg74.c_a1tv2 and t_kg74.c_a1tv2))
or (1=1))
and ((1288561802 <= t_kg74.c_a1tv2))),
c_js835qkmjz = (t_kg74.c_vqafa6o6 in (
select
ref_14.c_z as c0
from
t_q1 as ref_14
where (ref_14.c_z like 'o%fiah')))
where (t_kg74.c_obnq8s7_s2 = case when (t_kg74.c_a1tv2 is NULL) then t_kg74.c_g else t_kg74.c_obnq8s7_s2 end
);
drop table if exists t1, t2;
create table t1(id int primary key, a varchar(128));
create table t2(id int primary key, b varchar(128), c varchar(128));
UPDATE
t1
SET
t1.a = IFNULL(
(
SELECT
t2.c
FROM
t2
WHERE
t2.b = t1.a
ORDER BY
t2.b DESC,
t2.c DESC
LIMIT
1
), ''
)
WHERE
t1.id = 1;
drop table if exists t0, t1;
CREATE TABLE t0(c0 NUMERIC);
CREATE TABLE t1(c0 NUMERIC);
INSERT INTO t0 VALUES (0), (NULL), (1), (2);
INSERT INTO t1(c0) VALUES (NULL), (3), (4), (5);
drop view if exists v0;
CREATE VIEW v0(c0) AS SELECT t0.c0 FROM t0;
SELECT t0.c0 FROM v0, t0 LEFT JOIN t1 ON t0.c0 WHERE ((INET_ATON('5V')) IS NULL);
c0
>>>>>>> acdb6f58e3b (planner: UPDATE's select plan's output col IDs should be stable (#53268))
Loading

0 comments on commit 65f264e

Please sign in to comment.