Skip to content

Commit

Permalink
expression,planner/core: support unix_timestamp() function in partiti…
Browse files Browse the repository at this point in the history
…on pruning (#12035)
  • Loading branch information
tiancaiamao authored Sep 12, 2019
1 parent cbf4ddc commit 81cc7bc
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 4 deletions.
24 changes: 21 additions & 3 deletions expression/constant_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,22 @@ func newLonglong(value int64) *Constant {
}

func newDate(year, month, day int) *Constant {
return newTimeConst(year, month, day, 0, 0, 0, mysql.TypeDate)
}

func newTimestamp(yy, mm, dd, hh, min, ss int) *Constant {
return newTimeConst(yy, mm, dd, hh, min, ss, mysql.TypeTimestamp)
}

func newTimeConst(yy, mm, dd, hh, min, ss int, tp uint8) *Constant {
var tmp types.Datum
tmp.SetMysqlTime(types.Time{
Time: types.FromDate(year, month, day, 0, 0, 0, 0),
Type: mysql.TypeDate,
Time: types.FromDate(yy, mm, dd, 0, 0, 0, 0),
Type: tp,
})
return &Constant{
Value: tmp,
RetType: types.NewFieldType(mysql.TypeDate),
RetType: types.NewFieldType(tp),
}
}

Expand Down Expand Up @@ -202,6 +210,7 @@ func (*testExpressionSuite) TestConstantPropagation(c *C) {
func (*testExpressionSuite) TestConstraintPropagation(c *C) {
defer testleak.AfterTest(c)()
col1 := newColumnWithType(1, types.NewFieldType(mysql.TypeDate))
col2 := newColumnWithType(2, types.NewFieldType(mysql.TypeTimestamp))
tests := []struct {
solver constraintSolver
conditions []Expression
Expand Down Expand Up @@ -267,6 +276,15 @@ func (*testExpressionSuite) TestConstraintPropagation(c *C) {
},
result: "0",
},
{
solver: newConstraintSolver(ruleColumnOPConst),
// col2 > unixtimestamp('2008-05-01 00:00:00') and unixtimestamp(col2) < unixtimestamp('2008-04-01 00:00:00') => false
conditions: []Expression{
newFunction(ast.GT, col2, newTimestamp(2008, 5, 1, 0, 0, 0)),
newFunction(ast.LT, newFunction(ast.UnixTimestamp, col2), newLonglong(1206979200)),
},
result: "0",
},
}
for _, tt := range tests {
ctx := mock.NewContext()
Expand Down
3 changes: 2 additions & 1 deletion expression/constraint_propagation.go
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,8 @@ func negOP(cmp string) string {

// monotoneIncFuncs are those functions that for any x y, if x > y => f(x) > f(y)
var monotoneIncFuncs = map[string]struct{}{
ast.ToDays: {},
ast.ToDays: {},
ast.UnixTimestamp: {},
}

// compareConstant compares two expressions. c1 and c2 should be constant with the same type.
Expand Down
5 changes: 5 additions & 0 deletions expression/simple_rewriter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,4 +165,9 @@ func (s *testEvaluatorSuite) TestSimpleRewriter(c *C) {
c.Assert(err, IsNil)
num, _, _ = exprs[0].EvalInt(ctx, chunk.Row{})
c.Assert(num, Equals, int64(31842))

exprs, err = ParseSimpleExprsWithSchema(ctx, "unix_timestamp('2008-05-01 00:00:00')", sch)
c.Assert(err, IsNil)
num, _, _ = exprs[0].EvalInt(ctx, chunk.Row{})
c.Assert(num, Equals, int64(1209571200))
}
37 changes: 37 additions & 0 deletions planner/core/partition_pruning_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,41 @@ func (s *testPartitionPruningSuite) TestCanBePrune(c *C) {
succ, err = s.canBePruned(ctx, nil, partitionExpr[0], queryExpr)
c.Assert(err, IsNil)
c.Assert(succ, IsTrue)

// For the following case:
// CREATE TABLE quarterly_report_status (
// report_id INT NOT NULL,
// report_status VARCHAR(20) NOT NULL,
// report_updated TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP)
// PARTITION BY RANGE (UNIX_TIMESTAMP(report_updated)) (
// PARTITION p0 VALUES LESS THAN (UNIX_TIMESTAMP('2008-01-01 00:00:00')),
// PARTITION p1 VALUES LESS THAN (UNIX_TIMESTAMP('2008-04-01 00:00:00')),
// PARTITION p2 VALUES LESS THAN (UNIX_TIMESTAMP('2010-01-01 00:00:00')),
// PARTITION p3 VALUES LESS THAN (MAXVALUE)
// );
stmt, err = p.ParseOneStmt("create table t (report_updated timestamp)", "", "")
c.Assert(err, IsNil)
tblInfo, err = ddl.BuildTableInfoFromAST(stmt.(*ast.CreateTableStmt))
c.Assert(err, IsNil)
columns = expression.ColumnInfos2ColumnsWithDBName(ctx, model.NewCIStr("t"), tblInfo.Name, tblInfo.Columns)
schema = expression.NewSchema(columns...)

partitionExpr, err = expression.ParseSimpleExprsWithSchema(ctx, "unix_timestamp(report_updated) < unix_timestamp('2008-04-01') and unix_timestamp(report_updated) >= unix_timestamp('2008-01-01')", schema)
c.Assert(err, IsNil)
queryExpr, err = expression.ParseSimpleExprsWithSchema(ctx, "report_updated > '2008-05-01 00:00:00'", schema)
c.Assert(err, IsNil)
succ, err = s.canBePruned(ctx, nil, partitionExpr[0], queryExpr)
c.Assert(err, IsNil)
c.Assert(succ, IsTrue)

queryExpr, err = expression.ParseSimpleExprsWithSchema(ctx, "report_updated > unix_timestamp('2008-05-01 00:00:00')", schema)
c.Assert(err, IsNil)
succ, err = s.canBePruned(ctx, nil, partitionExpr[0], queryExpr)
c.Assert(err, IsNil)
_ = succ
// c.Assert(succ, IsTrue)
// TODO: Uncomment the check after fixing issue https://github.com/pingcap/tidb/issues/12028
// report_updated > unix_timestamp('2008-05-01 00:00:00') is converted to gt(t.t.report_updated, <nil>)
// Because unix_timestamp('2008-05-01 00:00:00') is fold to constant int 1564761600, and compare it with timestamp (report_updated)
// need to convert 1564761600 to a timestamp, during that step, an error happen and the result is set to <nil>
}

0 comments on commit 81cc7bc

Please sign in to comment.