LevelDB storage engine (MDEV-3841)

[MDEV-4094] LevelDB: Wrong result on SELECT and ER_KEY_NOT_FOUND on DELETE with search by NULL-able secondary key after updating PK Created: 2013-01-26  Updated: 2013-01-28  Resolved: 2013-01-28

Status: Closed
Project: MariaDB Server
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Technical task Priority: Minor
Reporter: Elena Stepanova Assignee: Sergei Petrunia
Resolution: Fixed Votes: 0
Labels: leveldb

Issue Links:
Relates

 Description   

CREATE TABLE t1 (pk INT PRIMARY KEY, a INT, b CHAR(1), KEY(a)) ENGINE=LevelDB;
INSERT INTO t1 VALUES (1,8,'g'),(2,9,'x');
UPDATE t1 SET pk = 10 WHERE a = 8;
REPLACE INTO t1 ( a ) VALUES ( 8 );
Warnings:
Warning	1364	Field 'pk' doesn't have a default value
REPLACE INTO t1 ( b ) VALUES ( 'y' );
Warnings:
Warning	1364	Field 'pk' doesn't have a default value
SELECT * FROM t1;
pk	a	b
0	NULL	y
2	9	x
10	8	g
EXPLAIN EXTENDED
SELECT * FROM t1 WHERE a = 8;
id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
1	SIMPLE	t1	ref	a	a	5	const	10	100.00	NULL
Warnings:
Note	1003	/* select#1 */ select `test`.`t1`.`pk` AS `pk`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where (`test`.`t1`.`a` = 8)
SELECT * FROM t1 WHERE a = 8;
pk	a	b
0	NULL	y
EXPLAIN EXTENDED
DELETE FROM t1 WHERE a = 8;
id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
1	SIMPLE	t1	range	PRIMARY,a	a	5	NULL	10	100.00	Using where

query 'DELETE FROM t1 WHERE a = 8' failed: 1032: Can't find record in 't1'

Test case:

CREATE TABLE t1 (pk INT PRIMARY KEY, a INT, b CHAR(1), KEY(a)) ENGINE=LevelDB;
INSERT INTO t1 VALUES (1,8,'g'),(2,9,'x');
UPDATE t1 SET pk = 10 WHERE a = 8;
REPLACE INTO t1 ( a ) VALUES ( 8 );
REPLACE INTO t1 ( b ) VALUES ( 'y' );
SELECT * FROM t1 WHERE a = 8;
DELETE FROM t1 WHERE a = 8;

revision-id: psergey@askmonty.org-20130125200959-a7gq7phbaiajqs12
revno: 4519
branch-nick: mysql-5.6-leveldb



 Comments   
Comment by Sergei Petrunia [ 2013-01-28 ]

The problem is casused by this statement:

UPDATE t1 SET pk = 10 WHERE a = 8;

It doesn't delete entries in the secondary index. leveldb contents after the statement:

"j2.t1\1\0\0\0\0\2" -> "-7\2\0\0\0\9\0\0\0x"
"j2.t1\1\0\0\0\0\10" -> "-7\10\0\0\0\8\0\0\0g"
"j2.t1\2\0\1\0\0\0\8\0\0\0\1" -> ""
"j2.t1\2\0\1\0\0\0\8\0\0\0\10" -> ""
"j2.t1\2\0\1\0\0\0\9\0\0\0\2" -> ""

Note

  • two records, but three index entries
  • two secondary index entries with a=8.

This happens because this function from sql/key.cc:

void key_copy(uchar *to_key, uchar *from_record, KEY *key_info,
uint key_length)

pretends to accept a parameter 'from_record', while internally it calls

uint bytes= field->get_key_image(to_key, length, Field::itRAW);

And 'field' normally points to table->record[0].

This is why LevelDB SE is trying to delete a wrong entry in the secondary index (which succeeds, because LevelDB's Delete() calls dont fail)

Generated at Thu Feb 08 06:53:40 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.