Skip to content

Commit

Permalink
util: fix build ranger's collation (pingcap#31226)
Browse files Browse the repository at this point in the history
  • Loading branch information
wjhuang2016 authored Jan 4, 2022
1 parent c884230 commit e3124ae
Show file tree
Hide file tree
Showing 5 changed files with 29 additions and 13 deletions.
9 changes: 9 additions & 0 deletions cmd/explaintest/r/collation_check_use_collation.result
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,13 @@ a
select a as a_col from t where t.a = (select a collate utf8mb4_general_ci from t1);
a_col
a
drop table if exists tbl_2;
create table tbl_2 ( col_20 bigint not null , col_21 smallint not null , col_22 decimal(24,10) default null , col_23 tinyint default 71 not null , col_24 bigint not null , col_25 tinyint default 18 , col_26 varchar(330) collate utf8_bin not null , col_27 char(77) collate utf8mb4_unicode_ci , col_28 char(46) collate utf8_general_ci not null , col_29 smallint unsigned not null , primary key idx_13 ( col_27(5) ) , key idx_14 ( col_24 ) , unique key idx_15 ( col_23,col_21,col_28,col_29,col_24 ) ) collate utf8_bin ;
insert ignore into tbl_2 values ( 5888267793391993829,5371,94.63,-109,5728076076919247337,89,'WUicqUTgdGJcjbC','SapBPqczTWWSN','xUSwH',49462 );
select col_25 from tbl_2 where ( tbl_2.col_27 > 'nSWYrpTH' or not( tbl_2.col_27 between 'CsWIuxlSjU' and 'SfwoyjUEzgg' ) ) and ( tbl_2.col_23 <= -95);
col_25
89
select col_25 from tbl_2 use index(primary) where ( tbl_2.col_27 > 'nSWYrpTH' or not( tbl_2.col_27 between 'CsWIuxlSjU' and 'SfwoyjUEzgg' ) ) and ( tbl_2.col_23 <= -95);
col_25
89
use test
6 changes: 6 additions & 0 deletions cmd/explaintest/t/collation_check_use_collation.test
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,11 @@ select a as a_col from t where t.a <= all (select a collate utf8mb4_general_ci f
select a as a_col from t where t.a <= any (select a collate utf8mb4_general_ci from t1);
select a as a_col from t where t.a = (select a collate utf8mb4_general_ci from t1);

drop table if exists tbl_2;
create table tbl_2 ( col_20 bigint not null , col_21 smallint not null , col_22 decimal(24,10) default null , col_23 tinyint default 71 not null , col_24 bigint not null , col_25 tinyint default 18 , col_26 varchar(330) collate utf8_bin not null , col_27 char(77) collate utf8mb4_unicode_ci , col_28 char(46) collate utf8_general_ci not null , col_29 smallint unsigned not null , primary key idx_13 ( col_27(5) ) , key idx_14 ( col_24 ) , unique key idx_15 ( col_23,col_21,col_28,col_29,col_24 ) ) collate utf8_bin ;
insert ignore into tbl_2 values ( 5888267793391993829,5371,94.63,-109,5728076076919247337,89,'WUicqUTgdGJcjbC','SapBPqczTWWSN','xUSwH',49462 );
select col_25 from tbl_2 where ( tbl_2.col_27 > 'nSWYrpTH' or not( tbl_2.col_27 between 'CsWIuxlSjU' and 'SfwoyjUEzgg' ) ) and ( tbl_2.col_23 <= -95);
select col_25 from tbl_2 use index(primary) where ( tbl_2.col_27 > 'nSWYrpTH' or not( tbl_2.col_27 between 'CsWIuxlSjU' and 'SfwoyjUEzgg' ) ) and ( tbl_2.col_23 <= -95);

# cleanup environment
use test
7 changes: 4 additions & 3 deletions util/ranger/detacher.go
Original file line number Diff line number Diff line change
Expand Up @@ -529,11 +529,12 @@ func ExtractEqAndInCondition(sctx sessionctx.Context, conditions []expression.Ex
}
// Multiple Eq/In conditions for one column in CNF, apply intersection on them
// Lazily compute the points for the previously visited Eq/In
collator := collate.GetCollator(cols[offset].GetType().Collate)
if mergedAccesses[offset] == nil {
mergedAccesses[offset] = accesses[offset]
points[offset] = rb.build(accesses[offset])
points[offset] = rb.build(accesses[offset], collator)
}
points[offset] = rb.intersection(points[offset], rb.build(cond), collate.GetCollator(cols[offset].GetType().Collate))
points[offset] = rb.intersection(points[offset], rb.build(cond, collator), collator)
if len(points[offset]) == 0 { // Early termination if false expression found
if expression.MaybeOverOptimized4PlanCache(sctx, conditions) {
// cannot return an empty-range for plan-cache since the range may become non-empty as parameters change
Expand Down Expand Up @@ -665,7 +666,7 @@ func (d *rangeDetacher) detachDNFCondAndBuildRangeForIndex(condition *expression
hasResidual = true
firstColumnChecker.shouldReserve = d.lengths[0] != types.UnspecifiedLength
}
points := rb.build(item)
points := rb.build(item, collate.GetCollator(newTpSlice[0].Collate))
ranges, err := points2Ranges(d.sctx, points, newTpSlice[0])
if err != nil {
return nil, nil, nil, false, errors.Trace(err)
Expand Down
12 changes: 5 additions & 7 deletions util/ranger/points.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,12 +185,12 @@ type builder struct {
sc *stmtctx.StatementContext
}

func (r *builder) build(expr expression.Expression) []*point {
func (r *builder) build(expr expression.Expression, collator collate.Collator) []*point {
switch x := expr.(type) {
case *expression.Column:
return r.buildFromColumn(x)
case *expression.ScalarFunction:
return r.buildFromScalarFunc(x)
return r.buildFromScalarFunc(x, collator)
case *expression.Constant:
return r.buildFromConstant(x)
}
Expand Down Expand Up @@ -762,16 +762,14 @@ func (r *builder) buildFromNot(expr *expression.ScalarFunction) []*point {
return getFullRange()
}

func (r *builder) buildFromScalarFunc(expr *expression.ScalarFunction) []*point {
_, coll := expr.CharsetAndCollation()
collator := collate.GetCollator(coll)
func (r *builder) buildFromScalarFunc(expr *expression.ScalarFunction, collator collate.Collator) []*point {
switch op := expr.FuncName.L; op {
case ast.GE, ast.GT, ast.LT, ast.LE, ast.EQ, ast.NE, ast.NullEQ:
return r.buildFromBinOp(expr)
case ast.LogicAnd:
return r.intersection(r.build(expr.GetArgs()[0]), r.build(expr.GetArgs()[1]), collator)
return r.intersection(r.build(expr.GetArgs()[0], collator), r.build(expr.GetArgs()[1], collator), collator)
case ast.LogicOr:
return r.union(r.build(expr.GetArgs()[0]), r.build(expr.GetArgs()[1]), collator)
return r.union(r.build(expr.GetArgs()[0], collator), r.build(expr.GetArgs()[1], collator), collator)
case ast.IsTruthWithoutNull:
return r.buildFromIsTrue(expr, 0, false)
case ast.IsTruthWithNull:
Expand Down
8 changes: 5 additions & 3 deletions util/ranger/ranger.go
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,8 @@ func buildColumnRange(accessConditions []expression.Expression, sctx sessionctx.
rb := builder{sc: sctx.GetSessionVars().StmtCtx}
rangePoints := getFullRange()
for _, cond := range accessConditions {
rangePoints = rb.intersection(rangePoints, rb.build(cond), collate.GetCollator(tp.Collate))
collator := collate.GetCollator(tp.Collate)
rangePoints = rb.intersection(rangePoints, rb.build(cond, collator), collator)
if rb.err != nil {
return nil, errors.Trace(rb.err)
}
Expand Down Expand Up @@ -372,7 +373,7 @@ func (d *rangeDetacher) buildCNFIndexRange(newTp []*types.FieldType,
}
for i := 0; i < eqAndInCount; i++ {
// Build ranges for equal or in access conditions.
point := rb.build(accessCondition[i])
point := rb.build(accessCondition[i], collate.GetCollator(newTp[i].Collate))
if rb.err != nil {
return nil, errors.Trace(rb.err)
}
Expand All @@ -388,7 +389,8 @@ func (d *rangeDetacher) buildCNFIndexRange(newTp []*types.FieldType,
rangePoints := getFullRange()
// Build rangePoints for non-equal access conditions.
for i := eqAndInCount; i < len(accessCondition); i++ {
rangePoints = rb.intersection(rangePoints, rb.build(accessCondition[i]), collate.GetCollator(newTp[eqAndInCount].Collate))
collator := collate.GetCollator(newTp[eqAndInCount].Collate)
rangePoints = rb.intersection(rangePoints, rb.build(accessCondition[i], collator), collator)
if rb.err != nil {
return nil, errors.Trace(rb.err)
}
Expand Down

0 comments on commit e3124ae

Please sign in to comment.