(sctx table.MutateContext, txn kv.Transaction, indexedValue []types.Datum, h kv.Handle, handleRestoreData []types.Datum, untouched bool, opt *table.CreateIdxOpt)
| 198 | } |
| 199 | |
| 200 | func (c *index) create(sctx table.MutateContext, txn kv.Transaction, indexedValue []types.Datum, h kv.Handle, handleRestoreData []types.Datum, untouched bool, opt *table.CreateIdxOpt) (kv.Handle, error) { |
| 201 | if c.Meta().Unique { |
| 202 | txn.CacheTableInfo(c.phyTblID, c.tblInfo) |
| 203 | } |
| 204 | indexedValues := c.getIndexedValue(indexedValue) |
| 205 | ctx := opt.Ctx() |
| 206 | if ctx != nil { |
| 207 | var r tracing.Region |
| 208 | r, ctx = tracing.StartRegionEx(ctx, "index.Create") |
| 209 | defer r.End() |
| 210 | } else { |
| 211 | ctx = context.TODO() |
| 212 | } |
| 213 | writeBufs := sctx.GetMutateBuffers().GetWriteStmtBufs() |
| 214 | skipCheck := opt.DupKeyCheck() == table.DupKeyCheckSkip |
| 215 | allowOverwriteOfOldGlobalIndex := false |
| 216 | if c.idxInfo.Global && c.tblInfo.Partition.DDLState == model.StateDeleteReorganization && |
| 217 | // TODO: Also do the same for DROP PARTITION |
| 218 | c.tblInfo.Partition.DDLAction == model.ActionTruncateTablePartition { |
| 219 | allowOverwriteOfOldGlobalIndex = true |
| 220 | if len(c.tblInfo.Partition.DroppingDefinitions) > 0 { |
| 221 | skipCheck = false |
| 222 | } |
| 223 | } |
| 224 | evalCtx := sctx.GetExprCtx().GetEvalCtx() |
| 225 | loc, ec := evalCtx.Location(), evalCtx.ErrCtx() |
| 226 | for _, value := range indexedValues { |
| 227 | key, distinct, err := c.GenIndexKey(ec, loc, value, h, writeBufs.IndexKeyBuf) |
| 228 | if err != nil { |
| 229 | return nil, err |
| 230 | } |
| 231 | |
| 232 | var ( |
| 233 | tempKey []byte |
| 234 | keyVer byte |
| 235 | keyIsTempIdxKey bool |
| 236 | hasTempKey bool |
| 237 | ) |
| 238 | if !opt.FromBackFill() { |
| 239 | key, tempKey, keyVer = GenTempIdxKeyByState(c.idxInfo, key) |
| 240 | if keyVer == tablecodec.TempIndexKeyTypeBackfill || keyVer == tablecodec.TempIndexKeyTypeDelete { |
| 241 | key, tempKey = tempKey, nil |
| 242 | keyIsTempIdxKey = true |
| 243 | } |
| 244 | hasTempKey = keyIsTempIdxKey || len(tempKey) > 0 |
| 245 | } |
| 246 | |
| 247 | if txn.IsPipelined() { |
| 248 | // For pipelined DML, disable the untouched optimization to avoid extra RPCs for MemBuffer.Get(). |
| 249 | // TODO: optimize this. |
| 250 | untouched = false |
| 251 | } |
| 252 | |
| 253 | if untouched { |
| 254 | // If the index kv was untouched(unchanged), and the key/value already exists in mem-buffer, |
| 255 | // should not overwrite the key with un-commit flag. |
| 256 | // So if the key exists, just do nothing and return. |
| 257 | v, err := kv.GetValue(ctx, txn.GetMemBuffer(), key) |
no test coverage detected