Am 2014-05-01 18:50, schrieb Jan Engelhardt:
> I have identified another bug and prepared a patch for
> dbd_mysql/dbd_msql. The purpose of result->currowidx was not totally
> clear-cut, so I am posting this patch for potential comments.
> 
> 
> parent 1619049a1e0eb018cdc8490f3cf344b4f2f53b0f ()
> commit 537c2673f36465c2700829130da4054f53354a00
> Author: Jan Engelhardt <jeng...@inai.de>
> Date:   Thu May 1 18:04:47 2014 +0200
> 
> dbd_mysql, dbd_msql: resolve bogus seeking and a crash
> 
> I have a query result that, when iteratively seeked with
> dbi_result_next_row() and read with dbi_result_get_string(), yields
> these 15 values (1-based row indices shown in parentheses):
> 
>       B-W(1) BAY(2) BER(3) BRE(4) HAM(5) HES(6) M-V(7) NDS(8)
>       NRW(9) RLP(10) SAR(11) SAC(12) S-A(13) S-H(14) THU(15)
> 
> Now, when using dbi_result_seek_row() to seek to arbitrary rows
> (given in parentheses), dbi_result_get_string() can return incorrect
> values. In particular, I have observed:
> 
>       B-W(1) S-H(14) B-W(1) THU(2)
> 
> What happens:
> 
> * row 1 is not already present, dbd_goto_row(1) is executed,
>   the row data retrieved, and result->currowidx set to 1
> * row 14 is not already present, a goto_row(14) is executed,
>   the row data retrieved, and result->currowidx set to 14
> * row 1 is already present, result->currowidx set to 1
> * row 2 is not already present, dbd_goto_row(2) is NOT executed,
>   because of rowidx == currowidx + 1 [2 == 2].
>   So the next mysql row fetched is row 15, rather than 2.
> 
> Now, if my seek order was {1, 15, 1, 2}, then mysql_fetch_row()
> called from function dbd_mysql.c:_get_row_data() will return NULL
> because there are no more rows. There will be a subsequent NULL
> dereference and crash.
> 
> It seems that result->currowidx is a high-level pointer, and is not
> synchronized to the current DBD row pointer.
> 
> As such, these checks should be killed and a goto_row always
> performed when so requested; the other DBD backends do the same.
> 
> After applying this patch, the seeked results correctly yield:
> 
>       B-W(1) S-H(14) B-W(1) BAY(2)

Hi,

I can't offer a better solution off the top of my head, but you 
essentially revert a patch which was designed to avoid an expensive call 
to mysql_data_seek() in *every single* iteration of stepping through a 
result set. There are data in the mailing list archives which show that 
MySQL is slowed down abysmally in large result sets when accessed 
through libdbi in comparison to libmysqlclient. It would be great if we 
could find a way to synchronize result->currowidx with the DBD row 
pointer in a cheaper way.

regards,
Markus

-- 
Markus Hoenicka
http://www.mhoenicka.de
AQ score 38


------------------------------------------------------------------------------
"Accelerate Dev Cycles with Automated Cross-Browser Testing - For FREE
Instantly run your Selenium tests across 300+ browser/OS combos.  Get 
unparalleled scalability from the best Selenium testing platform available.
Simple to use. Nothing to install. Get started now for free."
http://p.sf.net/sfu/SauceLabs
_______________________________________________
Libdbi-drivers-devel mailing list
Libdbi-drivers-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/libdbi-drivers-devel

Reply via email to