tags:

views:

489

answers:

6

Howdy. Consider the following:

SQL> DECLARE
  2     b1   BOOLEAN;
  3     b2   BOOLEAN;
  4     FUNCTION checkit RETURN BOOLEAN IS
  5     BEGIN
  6        dbms_output.put_line('inside checkit');
  7        RETURN TRUE;
  8     END checkit;
  9  
 10     PROCEDURE outp(n VARCHAR2, p BOOLEAN) IS
 11     BEGIN
 12        IF p THEN
 13           dbms_output.put_line(n||' is true');
 14        ELSE
 15           dbms_output.put_line(n||' is false');
 16        END IF;
 17     END;
 18  BEGIN
 19     b1 := TRUE OR checkit;
 20     outp('b1',b1);
 21     b2 := checkit OR TRUE;
 22     outp('b2',b2);
 23  END;
 24  /

b1 is true
inside checkit
b2 is true

PL/SQL procedure successfully completed

SQL>

Notice that the results of the OR statements are order dependent. If I place the function call first, then the function is executed regardless of the value of the other term. It appears that an OR statement is evaluated left to right until a TRUE is obtained, at which point processing stops and the result it TRUE.

My question is, is this something I can rely on? Or could this behavior change in future releases of PL/SQL? If it could change, is there a way to force the function to be evaluated that I can rely on (without creating another variable and using a separate assignment statement)?

+6  A: 

Yes. PL/SQL performs short circuit evaluation of logical expressions from left to right.

Justin Cave
Perfecto. Just what I was looking for!
DCookie
My google for "pl/sql complete boolean evaluation" gave me exactly the same link.
JosephStyons
That's a better search than what I tried: "PLSQL force evaluation". Thanks!
DCookie
A: 

This is called "short-circuit evaluation", and it is the norm in most languages, including PL/SQL.

JosephStyons
+1  A: 

If it could change, is there a way to force the function to be evaluated that I can rely on (without creating another variable and using a separate assignment statement)?

If you require that the function must be evaulated even when it is logically superfluous to do so, that implies that it does something other than simply return TRUE or FALSE, e.g. perhaps it updates a table. It isn't considered good practice for PL/SQL functions to have such "side effects".

Tony Andrews
A series of edit functions. Each issue edit messages and return an indicator if the current record should be skipped. The skip flag starts FALSE, and gets set to TRUE if it fails a check. I don't want the skip flag reset to FALSE if it passes any particular check.
DCookie
You could replace these functions by procedures with an IN OUT parameter for the flag. The procedures would set the flag to TRUE if any check failed, but would leave it alone if no checks failed: l_flag := FALSE; do_check1 (l_flag); do_check2 (l_flag); do_check3 (l_flag);
Tony Andrews
+1  A: 

In the documentation it states that short circuit evaluation applies to IF, CASE and CASE expressions: I'd bet that it also applies in the example that you quote but it's technically not documented that it does so. It might be worth raising a ticket with Oracle on this behaviour to get it confirmed.

David Aldridge
A: 

It evaluates OR statements from left to right and AND statements from right to left. I did not find myself any documentation of it.

A: 
mutoss