Plateforme Level Extreme
Abonnement
Profil corporatif
Produits & Services
Support
Légal
English
Always stops evaluating if..?
Message
De
16/08/2005 11:56:44
 
 
À
16/08/2005 11:00:10
Information générale
Forum:
Visual FoxPro
Catégorie:
Codage, syntaxe et commandes
Versions des environnements
Visual FoxPro:
VFP 7 SP1
Divers
Thread ID:
01041159
Message ID:
01041358
Vues:
20
>>>>>>>As far as I know, vfp always stops evaluating the right remainder of a logical expression if the left part evaluates to an logical value that cannot be changed anymore by the right remainder. For example, in the case of IF A OR B, the B is no longer evaluated if A evaluates to True. In a same vein, in the case of IF A=0 or BB(), the function BB is not visited if A=0.
>>>>>>>
>>>>>>>But now I am confronted with a case in a select-sql WHERE expression, where the part to the right of the OR is visited anyhow, notwithstanding the result of the left expression.
WHERE ( MOD(A,1000)#0 OR THERMO(A) )
>>>>>>>
>>>>>>>Does this sound familiar to anyone here?
>>>>>>
>>>>>>You ignores the phase of analysis,
>>>>>>and
>>>>>>Check A, it should to be NULL.
>>>>>
>>>>>It is never NULL.
>>>>
>>>>Post more info.
>>>>Look this:
>>>>
>>>>clear
>>>>SET NULLDISPLAY TO "I'm null"
>>>>CREATE CURSOR myTest (A I NULL)
>>>>INSERT INTO myTest VALUES (5)
>>>>INSERT INTO myTest VALUES (0)
>>>>INSERT INTO myTest VALUES (0)
>>>>INSERT INTO myTest VALUES (null)
>>>>INSERT INTO myTest VALUES (2)	&& VFP don't visit THERMO here
>>>>INSERT INTO myTest VALUES (1)	&& VFP don't visit THERMO here
>>>>INSERT INTO myTest VALUES (7)	&& VFP don't visit THERMO here
>>>>INSERT INTO myTest VALUES (0)
>>>>
>>>>SELECT 0
>>>>
>>>>SELECT * FROM myTest;
>>>>	WHERE (MOD(A,1000)#0 OR THERMO(A));
>>>>	INTO CURSOR rrr
>>>>
>>>>PROCEDURE THERMO(vValue)
>>>>	? "recno()=",RECNO(),"A=",vValue
>>>>
>>>
>>>Here's what I get.
>>>
>>> recno()= 1 A= 5
>>> recno()= 1 A= 5
>>> recno()= 1 A= 5
>>> recno()= 2 A= 0
>>> recno()= 3 A= 0
>>> recno()= 4 A= I'm null
>>> recno()= 5 A= 2
>>> recno()= 6 A= 1
>>> recno()= 7 A= 7
>>> recno()= 8 A= 0
>>>
>>>Two remarkable things:
>>>1 The first record is processed 3 times!
>>>2 Thermo() is processed EACH record, no matter the result of MOD(A,1000)#0. The A=0 lines should not have been in the list.
>>>
>>>I get the same result if there is no NULL record.
>>>
>>>The second result is what I am bringing to our attention. I actually thought that I would not be able to reproduce it with such simple code, but you did.
>>
>>Found: Message #1041266
>
>
>I also discovered a thread you wrote some months ago about the triple processing of the first record.
>BUG: SQL SELECT Statement UDF Executes Triple On First Recor Thread #1022053 Message #1022053

Yes. This is a parser bug.
Try this:
CLEAR	
CREATE CURSOR SQLUDF ( nField1 N(10,0) )
INSERT INTO SQLUDF VALUES ( 1 )

FOR k=0 TO 5
   nRunningTot = 0        && initialize running total to 0
   eSum = "Add_Em(nField1)" + REPLICATE(" + 0",K)
   ? "EXPRESSION: ",eSum
   SELECT &eSum as nRunTotal FROM SQLUDF INTO CURSOR temp
   ? "RESULT",TEMP.nRunTotal
NEXT

CREATE CURSOR SQLUDF ( nField1 N(10,0) )
?
? "eval left to right "

FOR k=0 TO 5
   nRunningCount = 0        && initialize running total to 0
   eWhere = "udfWhere(nField1)" + REPLICATE(" OR .T.",K)
   ? "EXPRESSION: ",eWhere
   SELECT 1  FROM SQLUDF WHERE &eWhere INTO CURSOR temp
   ? "RESULT",m.nRunningCount 
NEXT

?
? "eval right to left "
FOR k=1 TO 5
   nRunningCount = 0        && initialize running total to 0
   eWhere = "udfWhere(nField1) OR (.T. " + REPLICATE("OR .T.",K)+")"
   ? "EXPRESSION: ",eWhere
   SELECT 1  FROM SQLUDF WHERE &eWhere INTO CURSOR temp
   ? "RESULT",m.nRunningCount 
NEXT

PROCEDURE Add_Em
    LPARAMETERS tnFld1
       nRunningTot=nRunningTot + tnFld1     && Calculate running total
   RETURN nRunningTot
END PROCEDURE


PROCEDURE udfWhere
    LPARAMETERS tnFld1
       nRunningCount =nRunningCount + 1  && count calls
   RETURN .t.
END PROCEDURE
The parser use a bad stateless Valuer;
it repeat the eval process with this rule:
* EXP=M1+M2+M3+... +Mn
* ((((M1)+M2)+M3)+....+Mn)
when you force the stack order with the parentheses
the bug 2 calls it is reduced to.
Précédent
Répondre
Fil
Voir

Click here to load this message in the networking platform