diff --git a/expression/integration_test.go b/expression/integration_test.go index fa73529b01083..e6fdbbe3db8fe 100644 --- a/expression/integration_test.go +++ b/expression/integration_test.go @@ -5033,16 +5033,23 @@ func (s *testIntegrationSuite) TestTiDBInternalFunc(c *C) { tk := testkit.NewTestKit(c, s.store) defer s.cleanEnv(c) var result *testkit.Result + + // Row Keys result = tk.MustQuery("select tidb_decode_key( '74800000000000002B5F72800000000000A5D3' )") result.Check(testkit.Rows(`{"_tidb_rowid":42451,"table_id":"43"}`)) result = tk.MustQuery("select tidb_decode_key( '7480000000000000325f7205bff199999999999a013131000000000000f9' )") result.Check(testkit.Rows(`{"handle":"{1.1, 11}","table_id":50}`)) + // Index Keys result = tk.MustQuery("select tidb_decode_key( '74800000000000019B5F698000000000000001015257303100000000FB013736383232313130FF3900000000000000F8010000000000000000F7' )") result.Check(testkit.Rows(`{"index_id":1,"index_vals":"RW01, 768221109, ","table_id":411}`)) result = tk.MustQuery("select tidb_decode_key( '7480000000000000695F698000000000000001038000000000004E20' )") result.Check(testkit.Rows(`{"index_id":1,"index_vals":"20000","table_id":105}`)) + // Table keys + result = tk.MustQuery("select tidb_decode_key( '7480000000000000FF4700000000000000F8' )") + result.Check(testkit.Rows(`{"table_id":71}`)) + // Test invalid record/index key. result = tk.MustQuery("select tidb_decode_key( '7480000000000000FF2E5F728000000011FFE1A3000000000000' )") result.Check(testkit.Rows("7480000000000000FF2E5F728000000011FFE1A3000000000000")) diff --git a/planner/core/expression_rewriter.go b/planner/core/expression_rewriter.go index 0581301d1a791..b2c270b923431 100644 --- a/planner/core/expression_rewriter.go +++ b/planner/core/expression_rewriter.go @@ -2007,6 +2007,13 @@ func decodeKeyFromString(ctx sessionctx.Context, s string) string { return s } return ret + } else if tablecodec.IsTableKey(key) { + ret, err := decodeTableKey(key, tableID, tbl, loc) + if err != nil { + ctx.GetSessionVars().StmtCtx.AppendWarning(err) + return s + } + return ret } ctx.GetSessionVars().StmtCtx.AppendWarning(errors.Errorf("invalid record/index key: %X", key)) return s @@ -2150,6 +2157,15 @@ func decodeIndexKey(key []byte, tableID int64, tbl table.Table, loc *time.Locati return string(retStr), nil } +func decodeTableKey(key []byte, tableID int64, tbl table.Table, loc *time.Location) (string, error) { + ret := map[string]int64{"table_id": tableID} + retStr, err := json.Marshal(ret) + if err != nil { + return "", errors.Trace(err) + } + return string(retStr), nil +} + func datumToJSONObject(d *types.Datum) (interface{}, error) { if d.IsNull() { return nil, nil diff --git a/tablecodec/tablecodec.go b/tablecodec/tablecodec.go index 79c73713583e1..48b4eda5410ee 100644 --- a/tablecodec/tablecodec.go +++ b/tablecodec/tablecodec.go @@ -980,6 +980,11 @@ func IsIndexKey(k []byte) bool { return len(k) > 11 && k[0] == 't' && k[10] == 'i' } +// IsTableKey is used to check whether the key is a table key. +func IsTableKey(k []byte) bool { + return len(k) == 9 && k[0] == 't' +} + // IsUntouchedIndexKValue uses to check whether the key is index key, and the value is untouched, // since the untouched index key/value is no need to commit. func IsUntouchedIndexKValue(k, v []byte) bool {