martes, 18 de noviembre de 2014

OR No Es Siempre Conmutativa

Hallé la idea para este ejemplo aquí y decidí traducirlo para los hispanohablantes. La palabra OR suele ser conmutativa en Oracle y por eso los resultados de los comandos siguientes deberían ser iguales: 

select * from t where p=q or not p=q

y

select * from t where not p=q or p=q 

Pero en Oracle 9.2.0.7 y Oracle 10.2.0.3 los dos comandos daban resultados diferentes como se puede ver en el ejemplo que sigue: 

SQL> col p format a20
SQL> col q format a20
SQL> create type point as object (x real, y real)
  2  /
 
Type created.
 
SQL> create table t (p point, q point)
  2  /
 
Table created.
 
SQL> insert into t values
  2  (point(null, null), point(null,null))
  3  /
 
1 row created.
 
SQL> insert into t values
  2  (point(1, null), point(1,null))
  3  /
 
1 row created.
 
SQL> insert into t values (point(1, 2), point(1,2))
  2  /
 
1 row created.
 
SQL> select * from t
  2  /
 
P(X, Y)              Q(X, Y)
-------------------- --------------------
POINT(NULL, NULL)    POINT(NULL, NULL)
POINT(1, NULL)       POINT(1, NULL)
POINT(1, 2)          POINT(1, 2)
 
SQL> select * from t where p=q or not p=q
  2  /
 
P(X, Y)              Q(X, Y)
-------------------- --------------------
POINT(1, 2)          POINT(1, 2)
 
SQL> select * from t where not p=q or p=q
  2  /
 
P(X, Y)              Q(X, Y)
-------------------- --------------------
POINT(1, NULL)       POINT(1, NULL)
POINT(1, 2)          POINT(1, 2)
 
SQL> 

Creo que fuese causado por un error porque en Oracle 11.2.0.1, el problema había desaparecido: 

SQL> col p format a20
SQL> col q format a20
SQL> create type point as object (x real, y real)
  2  /
 
Type created.
 
SQL> create table t (p point, q point)
  2  /
 
Table created.
 
SQL> insert into t values
  2  (point(null, null), point(null,null))
  3  /
 
1 row created.
 
SQL> insert into t values
  2  (point(1, null), point(1,null))
  3  /
 
1 row created.
 
SQL> insert into t values (point(1, 2), point(1,2))
  2  /
 
1 row created.
 
SQL> select * from t
  2  /
 
P(X, Y)              Q(X, Y)
-------------------- --------------------
POINT(NULL, NULL)    POINT(NULL, NULL)
POINT(1, NULL)       POINT(1, NULL)
POINT(1, 2)          POINT(1, 2)
 
SQL> select * from t where p=q or not p=q
  2  /
 
P(X, Y)              Q(X, Y)
-------------------- --------------------
POINT(1, 2)          POINT(1, 2)
 
SQL> select * from t where not p=q or p=q
  2  /
 
P(X, Y)              Q(X, Y)
-------------------- --------------------
POINT(1, 2)          POINT(1, 2)
 
SQL>

No hay comentarios:

Publicar un comentario