Skip to content

Commit

Permalink
expression: fix compatibility of extract day_time unit functions (pin…
Browse files Browse the repository at this point in the history
…gcap#21601)

Signed-off-by: lzmhhh123 <[email protected]>
  • Loading branch information
lzmhhh123 authored Dec 11, 2020
1 parent 579022c commit f0c6fa9
Show file tree
Hide file tree
Showing 7 changed files with 61 additions and 6 deletions.
6 changes: 3 additions & 3 deletions cmd/explaintest/r/tpch.result
Original file line number Diff line number Diff line change
Expand Up @@ -446,7 +446,7 @@ id estRows task access object operator info
Sort_22 769.96 root tpch.nation.n_name, tpch.nation.n_name, Column#50
└─Projection_24 769.96 root tpch.nation.n_name, tpch.nation.n_name, Column#50, Column#52
└─HashAgg_27 769.96 root group by:Column#50, tpch.nation.n_name, tpch.nation.n_name, funcs:sum(Column#51)->Column#52, funcs:firstrow(tpch.nation.n_name)->tpch.nation.n_name, funcs:firstrow(tpch.nation.n_name)->tpch.nation.n_name, funcs:firstrow(Column#50)->Column#50
└─Projection_28 1957240.42 root tpch.nation.n_name, tpch.nation.n_name, extract(YEAR, tpch.lineitem.l_shipdate)->Column#50, mul(tpch.lineitem.l_extendedprice, minus(1, tpch.lineitem.l_discount))->Column#51
└─Projection_28 1957240.42 root tpch.nation.n_name, tpch.nation.n_name, extract(YEAR, cast(tpch.lineitem.l_shipdate, var_string(10)))->Column#50, mul(tpch.lineitem.l_extendedprice, minus(1, tpch.lineitem.l_discount))->Column#51
└─HashJoin_40 1957240.42 root inner join, equal:[eq(tpch.customer.c_nationkey, tpch.nation.n_nationkey)], other cond:or(and(eq(tpch.nation.n_name, "JAPAN"), eq(tpch.nation.n_name, "INDIA")), and(eq(tpch.nation.n_name, "INDIA"), eq(tpch.nation.n_name, "JAPAN")))
├─TableReader_94(Build) 2.00 root data:Selection_93
│ └─Selection_93 2.00 cop[tikv] or(eq(tpch.nation.n_name, "INDIA"), eq(tpch.nation.n_name, "JAPAN"))
Expand Down Expand Up @@ -519,7 +519,7 @@ Sort_29 719.02 root Column#62
└─Projection_31 719.02 root Column#62, div(Column#64, Column#65)->Column#66
└─HashAgg_34 719.02 root group by:Column#78, funcs:sum(Column#75)->Column#64, funcs:sum(Column#76)->Column#65, funcs:firstrow(Column#77)->Column#62
└─Projection_123 563136.02 root case(eq(tpch.nation.n_name, INDIA), Column#63, 0)->Column#75, Column#63, Column#62, Column#62
└─Projection_35 563136.02 root extract(YEAR, tpch.orders.o_orderdate)->Column#62, mul(tpch.lineitem.l_extendedprice, minus(1, tpch.lineitem.l_discount))->Column#63, tpch.nation.n_name
└─Projection_35 563136.02 root extract(YEAR, cast(tpch.orders.o_orderdate, var_string(10)))->Column#62, mul(tpch.lineitem.l_extendedprice, minus(1, tpch.lineitem.l_discount))->Column#63, tpch.nation.n_name
└─HashJoin_45 563136.02 root inner join, equal:[eq(tpch.supplier.s_nationkey, tpch.nation.n_nationkey)]
├─TableReader_121(Build) 25.00 root data:TableFullScan_120
│ └─TableFullScan_120 25.00 cop[tikv] table:n2 keep order:false
Expand Down Expand Up @@ -594,7 +594,7 @@ id estRows task access object operator info
Sort_25 2406.00 root tpch.nation.n_name, Column#53:desc
└─Projection_27 2406.00 root tpch.nation.n_name, Column#53, Column#55
└─HashAgg_30 2406.00 root group by:Column#53, tpch.nation.n_name, funcs:sum(Column#54)->Column#55, funcs:firstrow(tpch.nation.n_name)->tpch.nation.n_name, funcs:firstrow(Column#53)->Column#53
└─Projection_31 241379546.70 root tpch.nation.n_name, extract(YEAR, tpch.orders.o_orderdate)->Column#53, minus(mul(tpch.lineitem.l_extendedprice, minus(1, tpch.lineitem.l_discount)), mul(tpch.partsupp.ps_supplycost, tpch.lineitem.l_quantity))->Column#54
└─Projection_31 241379546.70 root tpch.nation.n_name, extract(YEAR, cast(tpch.orders.o_orderdate, var_string(10)))->Column#53, minus(mul(tpch.lineitem.l_extendedprice, minus(1, tpch.lineitem.l_discount)), mul(tpch.partsupp.ps_supplycost, tpch.lineitem.l_quantity))->Column#54
└─HashJoin_42 241379546.70 root inner join, equal:[eq(tpch.lineitem.l_orderkey, tpch.orders.o_orderkey)]
├─TableReader_117(Build) 75000000.00 root data:TableFullScan_116
│ └─TableFullScan_116 75000000.00 cop[tikv] table:orders keep order:false
Expand Down
36 changes: 34 additions & 2 deletions expression/builtin_time.go
Original file line number Diff line number Diff line change
Expand Up @@ -2631,10 +2631,15 @@ func (c *extractFunctionClass) getFunction(ctx sessionctx.Context, args []Expres
}
var bf baseBuiltinFunc
if isDatetimeUnit {
bf, err = newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETInt, types.ETString, types.ETDatetime)
decimalArg1 := int(types.MaxFsp)
if args[1].GetType().EvalType() != types.ETString {
decimalArg1 = 0
}
bf, err = newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETInt, types.ETString, types.ETString)
if err != nil {
return nil, err
}
bf.args[1].GetType().Decimal = decimalArg1
sig = &builtinExtractDatetimeSig{bf}
sig.setPbCode(tipb.ScalarFuncSig_ExtractDatetime)
} else {
Expand Down Expand Up @@ -2665,11 +2670,38 @@ func (b *builtinExtractDatetimeSig) evalInt(row chunk.Row) (int64, bool, error)
if isNull || err != nil {
return 0, isNull, err
}
dt, isNull, err := b.args[1].EvalTime(b.ctx, row)
dtStr, isNull, err := b.args[1].EvalString(b.ctx, row)
if isNull || err != nil {
return 0, isNull, err
}
sc := b.ctx.GetSessionVars().StmtCtx
switch strings.ToUpper(unit) {
case "DAY_MICROSECOND", "DAY_SECOND", "DAY_MINUTE", "DAY_HOUR":
dur, err := types.ParseDuration(sc, dtStr, types.GetFsp(dtStr))
if err != nil {
return 0, true, err
}
res, err := types.ExtractDurationNum(&dur, unit)
if err != nil {
return 0, true, err
}
dt, err := types.ParseDatetime(sc, dtStr)
if err != nil {
return res, false, nil
}
if dt.Hour() == dur.Hour() && dt.Minute() == dur.Minute() && dt.Second() == dur.Second() && dt.Year() > 0 {
res, err = types.ExtractDatetimeNum(&dt, unit)
}
return res, err != nil, err
}
dt, err := types.ParseDatetime(sc, dtStr)
if err != nil {
if !terror.ErrorEqual(err, types.ErrWrongValue) {
return 0, true, err
}
}
if dt.IsZero() {
dt.SetFsp(int8(b.args[1].GetType().Decimal))
if b.ctx.GetSessionVars().SQLMode.HasNoZeroDateMode() {
isNull, err := handleInvalidZeroTime(b.ctx, dt)
return 0, isNull, err
Expand Down
3 changes: 2 additions & 1 deletion expression/builtin_time_vec.go
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,8 @@ func (b *builtinSysDateWithoutFspSig) vecEvalTime(input *chunk.Chunk, result *ch
}

func (b *builtinExtractDatetimeSig) vectorized() bool {
return true
// TODO: to fix https://github.com/pingcap/tidb/issues/9716 in vectorized evaluation.
return false
}

func (b *builtinExtractDatetimeSig) vecEvalInt(input *chunk.Chunk, result *chunk.Column) error {
Expand Down
2 changes: 2 additions & 0 deletions expression/builtin_time_vec_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -548,6 +548,7 @@ var vecBuiltinTimeCases = map[string][]vecExprBenchCase{
ast.LastDay: {
{retEvalType: types.ETDatetime, childrenTypes: []types.EvalType{types.ETDatetime}},
},
/* TODO: to fix https://github.com/pingcap/tidb/issues/9716 in vectorized evaluation.
ast.Extract: {
{retEvalType: types.ETInt, childrenTypes: []types.EvalType{types.ETString, types.ETDatetime}, geners: []dataGenerator{newDateTimeUnitStrGener(), nil}},
{retEvalType: types.ETInt, childrenTypes: []types.EvalType{types.ETString, types.ETDuration},
Expand Down Expand Up @@ -581,6 +582,7 @@ var vecBuiltinTimeCases = map[string][]vecExprBenchCase{
constants: []*Constant{{Value: types.NewStringDatum("HOUR_MINUTE"), RetType: types.NewFieldType(mysql.TypeString)}},
},
},
*/
ast.ConvertTz: {
{retEvalType: types.ETDatetime, childrenTypes: []types.EvalType{types.ETDatetime, types.ETString, types.ETString},
geners: []dataGenerator{nil, newNullWrappedGener(0.2, &tzStrGener{}), newNullWrappedGener(0.2, &tzStrGener{})}},
Expand Down
8 changes: 8 additions & 0 deletions expression/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2065,6 +2065,14 @@ func (s *testIntegrationSuite2) TestTimeBuiltin(c *C) {
// for extract
result = tk.MustQuery(`select extract(day from '800:12:12'), extract(hour from '800:12:12'), extract(month from 20170101), extract(day_second from '2017-01-01 12:12:12')`)
result.Check(testkit.Rows("12 800 1 1121212"))
result = tk.MustQuery("select extract(day_microsecond from '2017-01-01 12:12:12'), extract(day_microsecond from '01 12:12:12'), extract(day_microsecond from '12:12:12'), extract(day_microsecond from '01 00:00:00.89')")
result.Check(testkit.Rows("1121212000000 361212000000 121212000000 240000890000"))
result = tk.MustQuery("select extract(day_second from '2017-01-01 12:12:12'), extract(day_second from '01 12:12:12'), extract(day_second from '12:12:12'), extract(day_second from '01 00:00:00.89')")
result.Check(testkit.Rows("1121212 361212 121212 240000"))
result = tk.MustQuery("select extract(day_minute from '2017-01-01 12:12:12'), extract(day_minute from '01 12:12:12'), extract(day_minute from '12:12:12'), extract(day_minute from '01 00:00:00.89')")
result.Check(testkit.Rows("11212 3612 1212 2400"))
result = tk.MustQuery("select extract(day_hour from '2017-01-01 12:12:12'), extract(day_hour from '01 12:12:12'), extract(day_hour from '12:12:12'), extract(day_hour from '01 00:00:00.89')")
result.Check(testkit.Rows("112 36 12 24"))

// for adddate, subdate
dateArithmeticalTests := []struct {
Expand Down
8 changes: 8 additions & 0 deletions types/time.go
Original file line number Diff line number Diff line change
Expand Up @@ -2175,6 +2175,14 @@ func ExtractDurationNum(d *Duration, unit string) (int64, error) {
return int64(d.Hour())*10000 + int64(d.Minute())*100 + int64(d.Second()), nil
case "HOUR_MINUTE":
return int64(d.Hour())*100 + int64(d.Minute()), nil
case "DAY_MICROSECOND":
return int64(d.Hour()*10000+d.Minute()*100+d.Second())*1000000 + int64(d.MicroSecond()), nil
case "DAY_SECOND":
return int64(d.Hour())*10000 + int64(d.Minute())*100 + int64(d.Second()), nil
case "DAY_MINUTE":
return int64(d.Hour())*100 + int64(d.Minute()), nil
case "DAY_HOUR":
return int64(d.Hour()), nil
default:
return 0, errors.Errorf("invalid unit %s", unit)
}
Expand Down
4 changes: 4 additions & 0 deletions types/time_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1562,6 +1562,10 @@ func (s *testTimeSuite) TestExtractDurationNum(c *C) {
{"HOUR_MICROSECOND", 31536},
{"HOUR_SECOND", 0},
{"HOUR_MINUTE", 0},
{"DAY_MICROSECOND", 31536},
{"DAY_SECOND", 0},
{"DAY_MINUTE", 0},
{"DAY_HOUR", 0},
}

for _, col := range tbl {
Expand Down

0 comments on commit f0c6fa9

Please sign in to comment.