From b824e351b96d3e8644e9134ac2dbfc3d93d887fd Mon Sep 17 00:00:00 2001 From: dsdashun Date: Thu, 12 May 2022 14:04:35 +0800 Subject: [PATCH] lightning: support null value for auto-incr column on local backend (#34552) close pingcap/tidb#34208 --- br/pkg/lightning/backend/kv/sql2kv.go | 97 +++++++++++++------ br/pkg/lightning/backend/kv/sql2kv_test.go | 92 +++++++++++++++++- br/tests/lightning_auto_columns/config.toml | 2 + .../lightning_auto_cols-schema-create.sql | 1 + ...lightning_auto_cols.t_auto_incr-schema.sql | 3 + .../data/lightning_auto_cols.t_auto_incr.sql | 8 ++ ...ghtning_auto_cols.t_auto_random-schema.sql | 3 + .../lightning_auto_cols.t_auto_random.sql | 8 ++ br/tests/lightning_auto_columns/run.sh | 38 ++++++++ 9 files changed, 219 insertions(+), 33 deletions(-) create mode 100644 br/tests/lightning_auto_columns/config.toml create mode 100644 br/tests/lightning_auto_columns/data/lightning_auto_cols-schema-create.sql create mode 100644 br/tests/lightning_auto_columns/data/lightning_auto_cols.t_auto_incr-schema.sql create mode 100644 br/tests/lightning_auto_columns/data/lightning_auto_cols.t_auto_incr.sql create mode 100644 br/tests/lightning_auto_columns/data/lightning_auto_cols.t_auto_random-schema.sql create mode 100644 br/tests/lightning_auto_columns/data/lightning_auto_cols.t_auto_random.sql create mode 100755 br/tests/lightning_auto_columns/run.sh diff --git a/br/pkg/lightning/backend/kv/sql2kv.go b/br/pkg/lightning/backend/kv/sql2kv.go index cfee7eceaea7a..4dc80e0c17ce2 100644 --- a/br/pkg/lightning/backend/kv/sql2kv.go +++ b/br/pkg/lightning/backend/kv/sql2kv.go @@ -356,50 +356,27 @@ func (kvcodec *tableKVEncoder) Encode( } meta := kvcodec.tbl.Meta() - isAutoRandom := meta.PKIsHandle && meta.ContainsAutoRandomBits() for i, col := range cols { + var theDatum *types.Datum = nil j := columnPermutation[i] - isAutoIncCol := mysql.HasAutoIncrementFlag(col.GetFlag()) - isPk := mysql.HasPriKeyFlag(col.GetFlag()) - switch { - case j >= 0 && j < len(row): - value, err = table.CastValue(kvcodec.se, row[j], col.ToInfo(), false, false) - if err == nil { - err = col.HandleBadNull(&value, kvcodec.se.vars.StmtCtx) - } - case isAutoIncCol: - // we still need a conversion, e.g. to catch overflow with a TINYINT column. - value, err = table.CastValue(kvcodec.se, types.NewIntDatum(rowID), col.ToInfo(), false, false) - case isAutoRandom && isPk: - var val types.Datum - realRowID := kvcodec.autoIDFn(rowID) - if mysql.HasUnsignedFlag(col.GetFlag()) { - val = types.NewUintDatum(uint64(realRowID)) - } else { - val = types.NewIntDatum(realRowID) - } - value, err = table.CastValue(kvcodec.se, val, col.ToInfo(), false, false) - case col.IsGenerated(): - // inject some dummy value for gen col so that MutRowFromDatums below sees a real value instead of nil. - // if MutRowFromDatums sees a nil it won't initialize the underlying storage and cause SetDatum to panic. - value = types.GetMinValue(&col.FieldType) - default: - value, err = table.GetColDefaultValue(kvcodec.se, col.ToInfo()) + if j >= 0 && j < len(row) { + theDatum = &row[j] } + value, err = kvcodec.getActualDatum(rowID, i, theDatum) if err != nil { return nil, logKVConvertFailed(logger, row, j, col.ToInfo(), err) } record = append(record, value) - if isAutoRandom && isPk { + if isTableAutoRandom(meta) && isPKCol(col.ToInfo()) { incrementalBits := autoRandomIncrementBits(col, int(meta.AutoRandomBits)) alloc := kvcodec.tbl.Allocators(kvcodec.se).Get(autoid.AutoRandomType) if err := alloc.Rebase(context.Background(), value.GetInt64()&((1<