Skip to content

Commit

Permalink
fix timezone.
Browse files Browse the repository at this point in the history
  • Loading branch information
3AceShowHand committed Mar 25, 2024
1 parent cb833a0 commit 51de2d6
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 21 deletions.
15 changes: 9 additions & 6 deletions cdc/entry/mounter.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (
"github.com/pingcap/tidb/kv"
timodel "github.com/pingcap/tidb/parser/model"
"github.com/pingcap/tidb/parser/mysql"
"github.com/pingcap/tidb/sessionctx/stmtctx"
"github.com/pingcap/tidb/table"
"github.com/pingcap/tidb/tablecodec"
"github.com/pingcap/tidb/types"
Expand Down Expand Up @@ -277,7 +278,7 @@ func parseJob(v []byte, startTs, CRTs uint64) (*timodel.Job, error) {
}

func datum2Column(
tableInfo *model.TableInfo, datums map[int64]types.Datum,
tableInfo *model.TableInfo, datums map[int64]types.Datum, tz *time.Location,
) ([]*model.Column, []types.Datum, []rowcodec.ColInfo, error) {
cols := make([]*model.Column, len(tableInfo.RowColumnsOffset))
rawCols := make([]types.Datum, len(tableInfo.RowColumnsOffset))
Expand Down Expand Up @@ -306,7 +307,7 @@ func datum2Column(
if exist {
colValue, size, warn, err = formatColVal(colDatums, colInfo)
} else {
colDatums, colValue, size, warn, err = getDefaultOrZeroValue(colInfo)
colDatums, colValue, size, warn, err = getDefaultOrZeroValue(colInfo, tz)
}
if err != nil {
return nil, nil, nil, errors.Trace(err)
Expand Down Expand Up @@ -348,7 +349,7 @@ func (m *mounter) mountRowKVEntry(tableInfo *model.TableInfo, row *rowKVEntry, d
if row.PreRowExist {
// FIXME(leoppro): using pre table info to mounter pre column datum
// the pre column and current column in one event may using different table info
preCols, preRawCols, extendColumnInfos, err = datum2Column(tableInfo, row.PreRow)
preCols, preRawCols, extendColumnInfos, err = datum2Column(tableInfo, row.PreRow, m.tz)
if err != nil {
return nil, rawRow, errors.Trace(err)
}
Expand All @@ -357,7 +358,7 @@ func (m *mounter) mountRowKVEntry(tableInfo *model.TableInfo, row *rowKVEntry, d
var cols []*model.Column
var rawCols []types.Datum
if row.RowExist {
cols, rawCols, extendColumnInfos, err = datum2Column(tableInfo, row.Row)
cols, rawCols, extendColumnInfos, err = datum2Column(tableInfo, row.Row, m.tz)
if err != nil {
return nil, rawRow, errors.Trace(err)
}
Expand Down Expand Up @@ -493,7 +494,7 @@ func formatColVal(datum types.Datum, col *timodel.ColumnInfo) (
// https://github.com/golang/go/blob/go1.17.4/src/database/sql/driver/types.go#L236
// Supported type is: nil, basic type(Int, Int8,..., Float32, Float64, String), Slice(uint8), other types not support
// TODO: Check default expr support
func getDefaultOrZeroValue(col *timodel.ColumnInfo) (types.Datum, any, int, string, error) {
func getDefaultOrZeroValue(col *timodel.ColumnInfo, tz *time.Location) (types.Datum, any, int, string, error) {
var (
d types.Datum
err error
Expand All @@ -506,7 +507,9 @@ func getDefaultOrZeroValue(col *timodel.ColumnInfo) (types.Datum, any, int, stri
// Ref: https://github.com/pingcap/tidb/blob/d2c352980a43bb593db81fd1db996f47af596d91/table/column.go#L489
if col.GetOriginDefaultValue() != nil {
datum := types.NewDatum(col.GetOriginDefaultValue())
d, err = datum.ConvertTo(types.DefaultStmtNoWarningContext, &col.FieldType)
sctx := new(stmtctx.StatementContext)
sctx.TimeZone = tz
d, err = datum.ConvertTo(sctx, &col.FieldType)
if err != nil {
return d, d.GetValue(), sizeOfDatum(d), "", errors.Trace(err)
}
Expand Down
32 changes: 17 additions & 15 deletions cdc/entry/mounter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import (
timodel "github.com/pingcap/tidb/parser/model"
"github.com/pingcap/tidb/parser/mysql"
"github.com/pingcap/tidb/session"
"github.com/pingcap/tidb/sessionctx/stmtctx"
"github.com/pingcap/tidb/store/mockstore"
"github.com/pingcap/tidb/testkit"
"github.com/pingcap/tidb/types"
Expand Down Expand Up @@ -848,33 +849,32 @@ func TestGetDefaultZeroValue(t *testing.T) {
},
}

tz, err := util.GetTimezone(config.GetGlobalServerConfig().TZ)
require.NoError(t, err)
for _, tc := range testCases {
_, val, _, _, _ := getDefaultOrZeroValue(&tc.ColInfo)
_, val, _, _, _ := getDefaultOrZeroValue(&tc.ColInfo, tz)
require.Equal(t, tc.Res, val, tc.Name)
<<<<<<< HEAD
val = GetDDLDefaultDefinition(&tc.ColInfo)
require.Equal(t, tc.Default, val, tc.Name)
=======
>>>>>>> 99b3eb43e1 (mounter(ticdc): default value convert to the correct data type (#10804))
}

colInfo := timodel.ColumnInfo{
OriginDefaultValue: "-3.14", // no float
FieldType: *ftTypeNewDecimalNotNull,
}
_, val, _, _, _ := getDefaultOrZeroValue(&colInfo)
_, val, _, _, _ := getDefaultOrZeroValue(&colInfo, tz)
decimal := new(types.MyDecimal)
err := decimal.FromString([]byte("-3.14"))
err = decimal.FromString([]byte("-3.14"))
require.NoError(t, err)
require.Equal(t, decimal.String(), val, "mysql.TypeNewDecimal + notnull + default")

colInfo = timodel.ColumnInfo{
OriginDefaultValue: "2020-11-19 12:12:12",
FieldType: *ftTypeTimestampNotNull,
}
_, val, _, _, _ = getDefaultOrZeroValue(&colInfo)
_, val, _, _, _ = getDefaultOrZeroValue(&colInfo, tz)
sc := new(stmtctx.StatementContext)
sc.TimeZone = tz
expected, err := types.ParseTimeFromFloatString(
types.DefaultStmtNoWarningContext,
sc,
"2020-11-19 12:12:12", colInfo.FieldType.GetType(), colInfo.FieldType.GetDecimal())
require.NoError(t, err)
require.Equal(t, expected.String(), val, "mysql.TypeTimestamp + notnull + default")
Expand All @@ -883,9 +883,9 @@ func TestGetDefaultZeroValue(t *testing.T) {
OriginDefaultValue: "2020-11-19 12:12:12",
FieldType: *ftTypeTimestampNull,
}
_, val, _, _, _ = getDefaultOrZeroValue(&colInfo)
_, val, _, _, _ = getDefaultOrZeroValue(&colInfo, tz)
expected, err = types.ParseTimeFromFloatString(
types.DefaultStmtNoWarningContext,
sc,
"2020-11-19 12:12:12", colInfo.FieldType.GetType(), colInfo.FieldType.GetDecimal())
require.NoError(t, err)
require.Equal(t, expected.String(), val, "mysql.TypeTimestamp + null + default")
Expand All @@ -894,7 +894,7 @@ func TestGetDefaultZeroValue(t *testing.T) {
OriginDefaultValue: "e1",
FieldType: *ftTypeEnumNotNull,
}
_, val, _, _, _ = getDefaultOrZeroValue(&colInfo)
_, val, _, _, _ = getDefaultOrZeroValue(&colInfo, tz)
expectedEnum, err := types.ParseEnumName(colInfo.FieldType.GetElems(), "e1", colInfo.FieldType.GetCollate())
require.NoError(t, err)
require.Equal(t, expectedEnum.Value, val, "mysql.TypeEnum + notnull + default")
Expand All @@ -903,7 +903,7 @@ func TestGetDefaultZeroValue(t *testing.T) {
OriginDefaultValue: "1,e",
FieldType: *ftTypeSetNotNull,
}
_, val, _, _, _ = getDefaultOrZeroValue(&colInfo)
_, val, _, _, _ = getDefaultOrZeroValue(&colInfo, tz)
expectedSet, err := types.ParseSetName(colInfo.FieldType.GetElems(), "1,e", colInfo.FieldType.GetCollate())
require.NoError(t, err)
require.Equal(t, expectedSet.Value, val, "mysql.TypeSet + notnull + default")
Expand Down Expand Up @@ -1145,14 +1145,16 @@ func TestBuildTableInfo(t *testing.T) {
") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin",
},
}
tz, err := util.GetTimezone(config.GetGlobalServerConfig().TZ)
require.NoError(t, err)
p := parser.New()
for i, c := range cases {
stmt, err := p.ParseOneStmt(c.origin, "", "")
require.NoError(t, err)
originTI, err := ddl.BuildTableInfoFromAST(stmt.(*ast.CreateTableStmt))
require.NoError(t, err)
cdcTableInfo := model.WrapTableInfo(0, "test", 0, originTI)
cols, _, _, err := datum2Column(cdcTableInfo, map[int64]types.Datum{})
cols, _, _, err := datum2Column(cdcTableInfo, map[int64]types.Datum{}, tz)
require.NoError(t, err)
recoveredTI := model.BuildTiDBTableInfo(cols, cdcTableInfo.IndexColumnsOffset)
handle := sqlmodel.GetWhereHandle(recoveredTI, recoveredTI)
Expand Down

0 comments on commit 51de2d6

Please sign in to comment.