<pre>


                 -------------------------------------------------------
                     VFP 9.0 FIX - INVALID RELATIONALEXPR EXPRESSION
                                     March 2012
                 -------------------------------------------------------
                                        CCB



1. BUG:

     In vfp9 (and vfp6, vfp7, vfp8), if the RelationalExpr expression include Evaluate() function, vfp will crash.

     1, If the RelationalExpr expression include macro substitution,
     vfp will occur an error: Relational expression is not valid (Error 1555).

     *PROC testrelationalexpr_macro

     SET STEP OFF
     SET ECHO OFF
     SET DEBUG OFF
     SET ESCAPE OFF
     SET TALK OFF
     SET SAFETY OFF

     _SCREEN.VISIBLE=.T.
     _SCREEN.WINDOWSTATE=2

     SET EXCLUSIVE OFF
     SET MULTILOCK ON
     SET COLLATE TO "MACHINE"

     CLOSE DATABASES ALL
     CLOSE TABLES ALL

     PUBLIC x1
     x1="CHR(65)"

     DO FORM testrelationalexpr_macro.scx

     CLOSE DATABASES ALL
     CLOSE TABLES ALL

     RETURN

     * END OF PROC TESTRELATIONALEXPR_MACRO.

     In the testrelationalexpr_macro.scx:

     relation1.RelationalExpr = "fld1+LEFT(&x1,0)"


     2, If the RelationalExpr expression include Evaluate() function, vfp will crash.

     *PROC testrelationalexpr_evaluate

     SET STEP OFF
     SET ECHO OFF
     SET DEBUG OFF
     SET ESCAPE OFF
     SET TALK OFF
     SET SAFETY OFF

     _SCREEN.VISIBLE=.T.
     _SCREEN.WINDOWSTATE=2

     SET EXCLUSIVE OFF
     SET MULTILOCK ON
     SET COLLATE TO "MACHINE"

     CLOSE DATABASES ALL
     CLOSE TABLES ALL

     DO FORM testrelationalexpr_evaluate.scx

     CLOSE DATABASES ALL
     CLOSE TABLES ALL

     RETURN

     * END OF PROC TESTRELATIONALEXPR_evaluate.

     In the testrelationalexpr_evaluate.scx:

     relation1.RelationalExpr = "fld1+EVALUATE('LEFT(CHR(65),0)')"


     3, If the RelationalExpr expression include user-defined function and the user-defined function
     include Evaluate() function, vfp will crash too.

     *PROC testrelationalexpr_udf_evaluate

     SET STEP OFF
     SET ECHO OFF
     SET DEBUG OFF
     SET ESCAPE OFF
     SET TALK OFF
     SET SAFETY OFF

     _SCREEN.VISIBLE=.T.
     _SCREEN.WINDOWSTATE=2

     SET EXCLUSIVE OFF
     SET MULTILOCK ON
     SET COLLATE TO "MACHINE"

     CLOSE DATABASES ALL
     CLOSE TABLES ALL

     DO FORM testrelationalexpr_udf_evaluate.scx

     CLOSE DATABASES ALL
     CLOSE TABLES ALL

     RETURN

     FUNCTION testrelationalexpr_udf_evaluate2

     PRIVATE x2
     x2=EVALUATE('LEFT(CHR(65),0)')

     RETU ""

     * END OF FUNCTION TESTRELATIONALEXPR_UDF_EVALUATE2.

     * END OF PROC TESTRELATIONALEXPR_UDF_EVALUATE.

     In the testrelationalexpr_udf_evaluate.scx:

     relation1.RelationalExpr = "fld1+testrelationalexpr_udf_evaluate2()"


     4, If the RelationalExpr expression include user-defined function and the user-defined function
     does not include Evaluate() function, vfp will run correctly.


     5, If we don't set RelationalExpr expression at design-time, we can set RelationalExpr expression at run time.
     For example,

     THISFORM.DATAENVIRONMENT.ADDOBJECT("Relation1","Relation")
     THISFORM.DATAENVIRONMENT.relation1.PARENTALIAS = "testa"
     THISFORM.DATAENVIRONMENT.relation1.RELATIONALEXPR = "fld1+EVALUATE('LEFT(CHR(65),0)')"
     THISFORM.DATAENVIRONMENT.relation1.CHILDALIAS = "testb"
     THISFORM.DATAENVIRONMENT.relation1.CHILDORDER = "fld1"

     vfp will not crash, BUT vfp run incorrectly:
     now the RELATION(1) is not equal to "fld1+EVALUATE('LEFT(CHR(65),0)')",
     it is changed to "LEFT(CHR(65),0)" (it is seems equal to the parameter passed to the Evaluate() function)?


     6, If we don't use the relation object, we can use SET RELATION TO statement instead of the relation object,
     then there is no any problem.


2. CAUSE:

     UNKNOWN.

     Perhaps when vfp call Evaluate() function (and _Evaluate() API function, _Execute() API function),
     vfp will compile the expression to p-code first, then some error occur ...


3. RESOLUTION:

     GOOD LUCKY! We can use Execscript() function instead of Evaluate() function and vfp will run correctly.

     For example,
     RelationalExpr = "fld1+EVALUATE('LEFT(CHR(65),0)')"
     we can change it to:
     RelationalExpr = "fld1+EXECSCRIPT('RETURN '+'LEFT(CHR(65),0)')"

     VFP Compiler frequently use _Evaluate() and _Execute() API function,
     so if the RelationalExpr expression include user-defined function,
     we MUST set VFP Compiler does not compile the user-defined function.
     For example, we can change it to:

     FUNCTION testrelationalexpr_udf_evaluate2

     =[FOXRUN OFF]

     PRIVATE x2
     x2=EVALUATE('LEFT(CHR(65),0)')

     RETU ""

     =[FOXRUN ON]

     * END OF FUNCTION TESTRELATIONALEXPR_UDF_EVALUATE2.


4. APPLIES TO:

     VFP 6.0 (all version)
     VFP 7.0 (all version)
     VFP 8.0 (all version)
     VFP 9.0 (all version)


5. REFERENCE WEBSITES:

     1, baiyujia.com:
     <a href="http://www.baiyujia.com/" target="_blank">http://www.baiyujia.com</a>


6. OTHER:

     For reference only, there is no guarantees.

     Any questions or suggestions, please e-mail to ccb2000@163.com.


</pre>

Last edited Apr 22, 2012 at 4:40 AM by ccb2000, version 1

Comments

No comments yet.