Bug #47124 Why do I need another rnd_next call to give EOF to the server?
| Submitted: | 4 Sep 2009 7:52 | Modified: | 21 Nov 2014 8:55 |
|---|---|---|---|
| Reporter: | Horst Hunger | Email Updates: | |
| Status: | Not a Bug | Impact on me: | |
| Category: | MySQL Server: Storage Engine API | Severity: | S3 (Non-critical) |
| Version: | 5.0, 5.1, azalea bzr | OS: | Any |
| Assigned to: | Magnus Blåudd | CPU Architecture: | Any |
| Tags: | API, plugin, storage engine | ||
[4 Sep 2009 9:32]
Sveta Smirnova
Thank you for the report. Verified as described using following test: create table t1(f1 int not null) engine=csv; insert into t1 values(1),(2),(3),(4),(5),(6),(7),(8),(9); select * from t1; Run it as $./mtr bug47124 --debug, then count: $cat var/log/mysqld.1.trace | grep rnd_next | wc -l 20 As this is exists in version 5.0 as well probably this should be not SE bug, but optimizer?
[21 Nov 2014 8:52]
Magnus Blåudd
This is by design and it's totally normally you need to return HA_ERR_END_OF_FILE when there are no more records. It's not possible to return a record AND returnh HA_ERR_END_OF_FILE. If there is a record in the buffer you return 0! As an example think about the case where there are no records at all in the table: rnd_init() - returns zero, indicating no error rnd_next() - return HA_ERR_END_OF_FILE, there are no record(s) rnd_end() Or where there are one record: rnd_init() - returns zero, indicating no error rnd_next() - filld in the record and return 0 to indicate there is a record. rnd_next() - return HA_ERR_END_OF_FILE, there are no record(s) rnd_end() How would you distinguish the case where there is a record and also returned HA_ERR_END_OF_FILE? I mean even if you are at the end, the HA_ERR_END_OF_FILE must not be return until next call.
Portions of this website are copyright © 2001, 2002 The PHP Group
Page generated in 0.055 sec. using MySQL 8.4.7-u6-cloud
Timestamp references displayed by the system are UTC.
Content reproduced on this site is the property of the
respective copyright holders.
It is not reviewed in advance
by Oracle and does not necessarily represent the opinion of
Oracle or any other party.
Description: That's only a small thing, but should not be forgotten. The following shows the method calls made during a nine-row table scan and shows a separate rnd_next call to give EOF (HA_ERR_END_OF_FILE) to the server: store_lock external_lock info rnd_init extra - ENUM HA_EXTRA_CACHE Cache record in HA_rrnd() rnd_next rnd_next rnd_next rnd_next rnd_next rnd_next rnd_next rnd_next rnd_next rnd_next (delivers only HA_ERR_END_OF_FILE, no values) extra - ENUM HA_EXTRA_NO_CACHE End caching of records (def) external_lock extra - ENUM HA_EXTRA_RESET Reset database to after open Please, check if it is possible to check EOF with the last rnd_next giving values, so that indeed only 9 rnd_next calls will be needed to give 9 rows to the server. How to repeat: Look into the TSE code and change it as described below: int ha_tse::rnd_next(uchar *buf) { int rc= 0; DBUG_ENTER("ha_tse::rnd_next"); int size; int i; int line_begin; int line_end; ... for (Field **field=table->field ; *field ; field++) { ... } ... if (next_position >= local_saved_data_file_length) DBUG_RETURN(HA_ERR_END_OF_FILE); stats.records++; next_position= line_begin; DBUG_RETURN(rc); } instead of int ha_tse::rnd_next(uchar *buf) { int rc= 0; DBUG_ENTER("ha_tse::rnd_next"); int size; int i; int line_begin; int line_end; ... if (next_position >= local_saved_data_file_length) DBUG_RETURN(HA_ERR_END_OF_FILE); ... for (Field **field=table->field ; *field ; field++) { ... } ... stats.records++; next_position= line_begin; DBUG_RETURN(rc); }