TestUniqueGlobalIndexKeyWithNullValues tests that for unique global indexes on non-clustered tables: - Non-NULL values do NOT have partition ID in the key (distinct = true) - NULL values DO have partition ID in the key (distinct = false) - Partition ID is always in the value for global indexes This
(t *testing.T)
| 824 | // - Partition ID is always in the value for global indexes |
| 825 | // This is critical after EXCHANGE PARTITION where duplicate _tidb_rowid values can exist. |
| 826 | func TestUniqueGlobalIndexKeyWithNullValues(t *testing.T) { |
| 827 | tableID := int64(100) |
| 828 | partitionID := int64(42) |
| 829 | handleID := int64(999) |
| 830 | |
| 831 | // Build a simple TableInfo and IndexInfo for a unique global index |
| 832 | // on a non-clustered table (no clustered index) |
| 833 | tblInfo := &model.TableInfo{ |
| 834 | ID: tableID, |
| 835 | Name: pmodel.NewCIStr("test_table"), |
| 836 | Columns: []*model.ColumnInfo{ |
| 837 | { |
| 838 | ID: 1, |
| 839 | Name: pmodel.NewCIStr("a"), |
| 840 | Offset: 0, |
| 841 | FieldType: *types.NewFieldType(mysql.TypeLong), |
| 842 | }, |
| 843 | { |
| 844 | ID: 2, |
| 845 | Name: pmodel.NewCIStr("b"), |
| 846 | Offset: 1, |
| 847 | FieldType: *types.NewFieldType(mysql.TypeLong), |
| 848 | }, |
| 849 | }, |
| 850 | // Non-clustered table (PKIsHandle = false, IsCommonHandle = false) |
| 851 | PKIsHandle: false, |
| 852 | IsCommonHandle: false, |
| 853 | } |
| 854 | |
| 855 | idxInfo := &model.IndexInfo{ |
| 856 | ID: 1, |
| 857 | Name: pmodel.NewCIStr("idx_b"), |
| 858 | Columns: []*model.IndexColumn{ |
| 859 | { |
| 860 | Name: pmodel.NewCIStr("b"), |
| 861 | Offset: 1, |
| 862 | Length: types.UnspecifiedLength, |
| 863 | }, |
| 864 | }, |
| 865 | Unique: true, |
| 866 | Global: true, |
| 867 | GlobalIndexVersion: model.GlobalIndexVersionV1, |
| 868 | State: model.StatePublic, |
| 869 | } |
| 870 | |
| 871 | loc := time.UTC |
| 872 | |
| 873 | // For unique index with non-NULL values, distinct = true, |
| 874 | // so the handle is NOT encoded in the key at all. |
| 875 | indexedValues := []types.Datum{types.NewIntDatum(123)} |
| 876 | handle := kv.NewPartitionHandle(partitionID, kv.IntHandle(handleID)) |
| 877 | |
| 878 | key, distinct, err := GenIndexKey(loc, tblInfo, idxInfo, tableID, indexedValues, handle, nil) |
| 879 | require.NoError(t, err) |
| 880 | require.True(t, distinct, "unique index with non-NULL value should be distinct") |
| 881 | |
| 882 | // The key should NOT contain the partition ID flag since distinct = true |
| 883 | // means no handle (and thus no partition ID) is encoded in the key |
nothing calls this directly
no test coverage detected