----------------------------------------------------------------------------------
[ENHANCED] VFP 9.0 FIX - RUSHMORE QUERY OPTIMIZATION IN THE WHERE CLAUSE
January 2026
----------------------------------------------------------------------------------
CCB
1. BUG:
In vfp9 (and vfp6, vfp7, vfp8), we can use SET OPTIMIZE ON|OFF to globally enable or disable Rushmore Query Optimization in the FOR clause,
it always enables Rushmore Query Optimization in the WHERE clause.
In VFP Advanced, we can use SET OPTIMIZE ON|OFF to globally enable or disable Rushmore Query Optimization in the FOR clause,
we can also use SYS(9166,1|0) to globally enable or disable Rushmore Query Optimization in the WHERE clause.
2. CAUSE:
There are some BUGs in the following code.
3. RESOLUTION:
We can write some code to fix the BUG.
CallBack5379e0 :: ; proc near
mov ecx , edi ;0x005379e0 : 8bcf
Label5379e2 ::
mov edx , dword ptr [ ebx + 0C4h ] ;0x005379e2 : 8b93c4000000
lea ecx , dword ptr [ ecx + 8 * ecx ] ;0x005379e8 : 8d0cc9
lea esi , dword ptr [ edx + 4 * ecx ] ;0x005379eb : 8d348a
mov edx , dword ptr [ edx + eax ] ;0x005379ee : 8b1402
cmp byte ptr [edx] , 0D1h ;0x005379f1 : 803ad1
mov ecx , dword ptr [ esi + 8 ] ;0x005379f4 : 8b4e08
mov esi , dword ptr [ esi + 12 ] ;0x005379f7 : 8b760c
je Label5cd133 ;0x005379fa : 0f8433570900
Label537a00 ::
test ecx , ecx ;0x00537a00 : 85c9
jl Label5cd13d ;0x00537a02 : 0f8c35570900
Label537a08 ::
mov edx , dword ptr [ esp + 24 ] ;0x00537a08 : 8b542418
push ecx ;0x00537a0c : 51
push ebp ;0x00537a0d : 55
mov ecx , ebx ;0x00537a0e : 8bcb
call Fun53234e ;0x00537a10 : e839a9ffff
mov ecx , dword ptr [ ebp + 0 ] ;0x00537a15 : 8b4d00
mov eax , dword ptr [ ecx - 4 ] ;0x00537a18 : 8b41fc
lea edx , dword ptr [ eax - 8 ] ;0x00537a1b : 8d50f8
call Fun5320f8 ;0x00537a1e : e8d5a6ffff
;
; -----------------------------------------------------------------------
; VFP 9.0 FIX - RUSHMORE QUERY OPTIMIZATION IN THE WHERE CLAUSE
; September 2024
; -----------------------------------------------------------------------
; CCB
;
; In vfp9 (and vfp6, vfp7, vfp8), if the expression includes UDFs (user-defined functions)
; or some functions which support an optional alias or work area in the WHERE clause,
; it is an optimizable expression, but in fact, it is NOT an optimizable expression! sometimes it returns incorrect data!
; In Visual FoxPro Advanced, if the expression includes UDFs (user-defined functions)
; or some functions which support an optional alias or work area in the WHERE clause,
; we can set SYS(9166,0) to globally disable Rushmore Query Optimization in the WHERE clause (as a temporary solution),
; it is not an optimizable expression, it returns correct data.
;
; 2024/9/2, by ccb
;
Label537a20_start ::
cmp dword ptr vfpa_sys9166_data,00h
jne Label537a20_end
inc eax
jmp Label537a23
Label537a20_end ::
Label537a23 ::
mov edi , eax ;0x00537a23 : 8bf8
dec edi ;0x00537a25 : 4f
test esi , esi ;0x00537a26 : 85f6
jl Label4d379c ;0x00537a28 : 0f8c6ebdf9ff
mov edx , dword ptr [ esp + 20 ] ;0x00537a2e : 8b542414
push esi ;0x00537a32 : 56
mov esi , dword ptr [ esp + 20 ] ;0x00537a33 : 8b742414
push esi ;0x00537a37 : 56
mov ecx , ebx ;0x00537a38 : 8bcb
call Fun53234e ;0x00537a3a : e80fa9ffff
mov ecx , dword ptr [esi] ;0x00537a3f : 8b0e
mov eax , dword ptr [ ecx - 4 ] ;0x00537a41 : 8b41fc
lea edx , dword ptr [ eax - 8 ] ;0x00537a44 : 8d50f8
call Fun5320f8 ;0x00537a47 : e8aca6ffff
;
; -----------------------------------------------------------------------
; VFP 9.0 FIX - RUSHMORE QUERY OPTIMIZATION IN THE WHERE CLAUSE
; September 2024
; -----------------------------------------------------------------------
; CCB
;
; In vfp9 (and vfp6, vfp7, vfp8), if the expression includes UDFs (user-defined functions)
; or some functions which support an optional alias or work area in the WHERE clause,
; it is an optimizable expression, but in fact, it is NOT an optimizable expression! sometimes it returns incorrect data!
; In Visual FoxPro Advanced, if the expression includes UDFs (user-defined functions)
; or some functions which support an optional alias or work area in the WHERE clause,
; we can set SYS(9166,0) to globally disable Rushmore Query Optimization in the WHERE clause (as a temporary solution),
; it is not an optimizable expression, it returns correct data.
;
; 2024/9/2, by ccb
;
Label537a49_start ::
cmp dword ptr vfpa_sys9166_data,00h
jne Label537a49_end
inc eax
jmp Label537a4c
Label537a49_end ::
Label537a4c ::
dec eax ;0x00537a4c : 48
Label537a4d ::
test edi , edi ;0x00537a4d : 85ff
je Label4d377b ;0x00537a4f : 0f8426bdf9ff
test eax , eax ;0x00537a55 : 85c0
jne Label537eb2 ;0x00537a57 : 0f8555040000
Label537a5d ::
mov esi , dword ptr [ esp + 36 ] ;0x00537a5d : 8b742424
mov edx , dword ptr [ ebx + 0CCh ] ;0x00537a61 : 8b93cc000000
imul esi , esi , 02Ch ;0x00537a67 : 6bf62c
mov dword ptr [ esi + edx ] , 03h ;0x00537a6a : c7041603000000
Label537a71 ::
mov eax , dword ptr [ esp + 16 ] ;0x00537a71 : 8b442410
mov ecx , dword ptr [ ebp + 0 ] ;0x00537a75 : 8b4d00
mov eax , dword ptr [eax] ;0x00537a78 : 8b00
mov edx , dword ptr [ ecx - 4 ] ;0x00537a7a : 8b51fc
mov edi , dword ptr [ eax - 4 ] ;0x00537a7d : 8b78fc
sub edx , 08h ;0x00537a80 : 83ea08
sub edi , 08h ;0x00537a83 : 83ef08
cmp edx , edi ;0x00537a86 : 3bd7
jb Label537a8c ;0x00537a88 : 7202
mov edx , edi ;0x00537a8a : 8bd7
Label537a8c ::
add edx , eax ;0x00537a8c : 03d0
cmp eax , edx ;0x00537a8e : 3bc2
jnb Label537aa0 ;0x00537a90 : 730e
Label537a92 ::
mov edi , dword ptr [eax] ;0x00537a92 : 8b38
or dword ptr [ecx] , edi ;0x00537a94 : 0939
add eax , 04h ;0x00537a96 : 83c004
add ecx , 04h ;0x00537a99 : 83c104
cmp eax , edx ;0x00537a9c : 3bc2
jb Label537a92 ;0x00537a9e : 72f2
Label537aa0 ::
mov ecx , dword ptr [ ebx + 0CCh ] ;0x00537aa0 : 8b8bcc000000
mov dword ptr [ esi + ecx + 36 ] , ebp ;0x00537aa6 : 896c0e24
mov ecx , dword ptr [ esp + 16 ] ;0x00537aaa : 8b4c2410
mov eax , ebx ;0x00537aae : 8bc3
call Fun541571 ;0x00537ab0 : e8bc9a0000
mov edx , dword ptr [ esp + 20 ] ;0x00537ab5 : 8b542414
mov ebp , dword ptr [ esp + 24 ] ;0x00537ab9 : 8b6c2418
mov eax , dword ptr [edx] ;0x00537abd : 8b02
mov edi , dword ptr [ ebp + 0 ] ;0x00537abf : 8b7d00
mov ecx , dword ptr [ edi - 4 ] ;0x00537ac2 : 8b4ffc
mov edx , dword ptr [ eax - 4 ] ;0x00537ac5 : 8b50fc
sub ecx , 08h ;0x00537ac8 : 83e908
sub edx , 08h ;0x00537acb : 83ea08
cmp ecx , edx ;0x00537ace : 3bca
jb Label537ad4 ;0x00537ad0 : 7202
mov ecx , edx ;0x00537ad2 : 8bca
Label537ad4 ::
add ecx , eax ;0x00537ad4 : 03c8
cmp eax , ecx ;0x00537ad6 : 3bc1
jnb Label537aeb ;0x00537ad8 : 7311
lea esp , dword ptr [ esp ] ;0x00537ada : 8d2424
Label537add ::
mov edx , dword ptr [eax] ;0x00537add : 8b10
or dword ptr [edi] , edx ;0x00537adf : 0917
add eax , 04h ;0x00537ae1 : 83c004
add edi , 04h ;0x00537ae4 : 83c704
cmp eax , ecx ;0x00537ae7 : 3bc1
jb Label537add ;0x00537ae9 : 72f2
Label537aeb ::
mov eax , dword ptr [ ebx + 0CCh ] ;0x00537aeb : 8b83cc000000
mov ecx , dword ptr [ esp + 20 ] ;0x00537af1 : 8b4c2414
mov dword ptr [ esi + eax + 32 ] , ebp ;0x00537af5 : 896c0620
mov eax , ebx ;0x00537af9 : 8bc3
call Fun541571 ;0x00537afb : e8719a0000
mov ecx , dword ptr [ esp + 32 ] ;0x00537b00 : 8b4c2420
mov edx , dword ptr [ ebx + 0C8h ] ;0x00537b04 : 8b93c8000000
imul ecx , ecx , 0A4h ;0x00537b0a : 69c9a4000000
mov eax , dword ptr [ edx + ecx + 24 ] ;0x00537b10 : 8b440a18
test eax , eax ;0x00537b14 : 85c0
jne Label5cd144 ;0x00537b16 : 0f8528560900
Label537b1c ::
mov edx , dword ptr [ ebx + 0C8h ] ;0x00537b1c : 8b93c8000000
mov ecx , dword ptr [ ecx + edx + 28 ] ;0x00537b22 : 8b4c111c
test ecx , ecx ;0x00537b26 : 85c9
jne Label5cd17a ;0x00537b28 : 0f854c560900
Label537b2e ::
pop edi ;0x00537b2e : 5f
pop esi ;0x00537b2f : 5e
pop ebp ;0x00537b30 : 5d
pop ebx ;0x00537b31 : 5b
add esp , 0Ch ;0x00537b32 : 83c40c
ret 08h ;0x00537b35 : c20800
4. APPLIES TO:
VFP 6.0.8167.0
VFP 6.0.8961.0 (SP5)
VFP 7.0.0.9262
VFP 7.0.0.9465 (SP1)
VFP 8.0.0.2521
VFP 8.0.0.3117 (SP1)
VFP 9.0.0.2412
VFP 9.0.0.3504 (SP1)
VFP 9.0.0.4611 (SP2)
VFP 9.0.0.5015 (SP2)
VFP 9.0.0.5411 (SP2)
VFP 9.0.0.5721 (SP2)
VFP 9.0.0.5815 (SP2)
VFP 9.0.0.6303 (SP2)
VFP 9.0.0.6602 (SP2)
VFP 9.0.0.7423 (SP2)
The bug has been fixed in VFP Advanced.
IMPORTANT NOTE:
In VFP Advanced and vfp9 (and vfp6, vfp7, vfp8), if the expression includes UDFs (user-defined functions)
or some functions which support an optional alias or work area in the WHERE clause:
ALIAS() function
BOF() function
DELETED() function
EOF() function
FCOUNT() function
FIELD() function
FLOCK() function
FOUND() function
LUPDATE() function
NDX() function
RECCOUNT() function
RECNO() function
RECSIZE() function
RLOCK() function
ORDER() function
FILTER() function
HEADER() function
USED() function
ISBLANK() function
GETFLDSTATE() function
it is an optimizable expression, but in fact, it is NOT an optimizable expression! sometimes it returns incorrect data!
For example,
SELECT * FROM tmp1 WHERE fld1=test_subproc("aaa") INTO CURSOR tmp2 nofilter && it returns incorrect data!
SELECT * FROM tmp1 WHERE fld1=REPL(CHR(97+RECN()-1),3) INTO CURSOR tmp2 nofilter && it returns incorrect data!
In VFP Advanced, we can set SYS(9166,0) to globally disable Rushmore Query Optimization in the WHERE clause (as a temporary solution) to fix the bug:
PRIVATE m.q_oldsys9166
m.q_oldsys9166=VAL(SYS(9166))
=SYS(9166,0) && Disables Rushmore Query Optimization in the WHERE clause (as a temporary solution)
SELECT * FROM tmp1 WHERE fld1=test_subproc("aaa") INTO CURSOR tmp2 nofilter && it returns correct data.
SELECT * FROM tmp1 WHERE fld1=REPL(CHR(97+RECN()-1),3) INTO CURSOR tmp2 nofilter && it returns correct data.
=SYS(9166,m.q_oldsys9166)
5. REFERENCE WEBSITES:
1, baiyujia.com:
http://www.baiyujia.com
http://www.baiyujia.com/vfpdocuments/f_vfp9fix340.asp
http://www.baiyujia.com/vfpdocuments/f_vfp9fix326.asp
http://www.baiyujia.com/vfpdocuments/f_vfp9fix327.asp
http://www.baiyujia.com/vfpdocuments/f_vfp9fix328.asp
http://www.baiyujia.com/vfpdocuments/f_vfp9fix329.asp
http://www.baiyujia.com/vfpdocuments/f_vfp9fix330.asp
6. OTHER:
For reference only, there is no guarantees.
Any questions or suggestions, please send me an email at ccb2000@163.com.
|