Sorpresas con comparaciones en columnas TIMESTAMP WITH DEFAULT

18 septiembre \18\UTC 2014

A veces te encuentras sorpresas en el día a día. Hoy di con algo sorprendente respecto de las comparaciones con timestamps:

Vamos a hacer una pequeña prueba de comparaciones de TIMESTAMPs con mayor estricto para colunas definidas con ‘WITH DEFAULT':

 BTEQ -- Enter your SQL request or BTEQ command:
CREATE MULTISET TABLE CARLOS.PRUEBA01
   ( ID_N INTEGER NOT NULL,
     TS_TIMESTAMP TIMESTAMP(0) NOT NULL WITH DEFAULT )
;


 *** Table has been created.
 *** Total elapsed time was 1 second.


 BTEQ -- Enter your SQL request or BTEQ command:


INSERT INTO CARLOS.PRUEBA01(ID_N) VALUES ( 1 )
;INSERT INTO CARLOS.PRUEBA01(ID_N) VALUES ( 2 )
;INSERT INTO CARLOS.PRUEBA01(ID_N) VALUES ( 3 )
;


 *** Insert completed. One row added.
 *** Total elapsed time was 1 second.

 *** Insert completed. One row added.

 *** Insert completed. One row added.

 BTEQ -- Enter your SQL request or BTEQ command:


SELECT *
  FROM CARLOS.PRUEBA01
;


 *** Query completed. 3 rows found. 2 columns returned.
 *** Total elapsed time was 1 second.

       ID_N         TS_TIMESTAMP
-----------  -------------------
          3  2014-09-18 18:27:58
          2  2014-09-18 18:27:58
          1  2014-09-18 18:27:58

 BTEQ -- Enter your SQL request or BTEQ command:
INSERT INTO CARLOS.PRUEBA01(ID_N) VALUES ( 4 );


 *** Insert completed. One row added.
 *** Total elapsed time was 1 second.


 BTEQ -- Enter your SQL request or BTEQ command:


SELECT *
  FROM CARLOS.PRUEBA01
;


 *** Query completed. 4 rows found. 2 columns returned.
 *** Total elapsed time was 1 second.

       ID_N         TS_TIMESTAMP
-----------  -------------------
          3  2014-09-18 18:27:58
          4  2014-09-18 18:28:52
          2  2014-09-18 18:27:58
          1  2014-09-18 18:27:58

 BTEQ -- Enter your SQL request or BTEQ command:
SELECT *
  FROM CARLOS.PRUEBA01
 WHERE TS_TIMESTAMP > TIMESTAMP '2014-09-18 18:27:58'
;


 *** Query completed. One row found. 2 columns returned.
 *** Total elapsed time was 1 second.

       ID_N         TS_TIMESTAMP
-----------  -------------------
          4  2014-09-18 18:28:52

Todo perfecto: Las filas reciben el CURRENT_TIMESTAMP(0) para la columna TS_TIMESTAMP y la comparación en la ‘query’ final sólo devuelve una fila estrictamente mayor a TIMESTAMP ‘2014-09-18 18:27:58′ (como debe ser).

Ahora empieza lo divertido:

Vamos a crear la misma tabla sin la columna TS_TIMESTAMP. Haremos las inserciones y después añadiremos la columna TS_TIMESTAMP con el NOT NULL WITH DEFAULT (esto debe hacer que todas las filas tomen el TIMESTAMP del momento del ALTER TABLE para la nueva columna):

 BTEQ -- Enter your SQL request or BTEQ command:
DROP TABLE CARLOS.PRUEBA01;


 *** Table has been dropped.
 *** Total elapsed time was 2 seconds.


 BTEQ -- Enter your SQL request or BTEQ command:
CREATE MULTISET TABLE CARLOS.PRUEBA01
   ( ID_N INTEGER NOT NULL)
;


 *** Table has been created.
 *** Total elapsed time was 1 second.


 BTEQ -- Enter your SQL request or BTEQ command:


INSERT INTO CARLOS.PRUEBA01(ID_N) VALUES ( 1 )
;INSERT INTO CARLOS.PRUEBA01(ID_N) VALUES ( 2 )
;INSERT INTO CARLOS.PRUEBA01(ID_N) VALUES ( 3 )
;


 *** Insert completed. One row added.
 *** Total elapsed time was 1 second.

 *** Insert completed. One row added.

 *** Insert completed. One row added.

 BTEQ -- Enter your SQL request or BTEQ command:
ALTER TABLE CARLOS.PRUEBA01
ADD TS_TIMESTAMP TIMESTAMP(0) NOT NULL WITH DEFAULT;


 *** Table has been modified.
 *** Total elapsed time was 1 second.


 BTEQ -- Enter your SQL request or BTEQ command:
SELECT *
  FROM CARLOS.PRUEBA01
;


 *** Query completed. 3 rows found. 2 columns returned.
 *** Total elapsed time was 1 second.

       ID_N         TS_TIMESTAMP
-----------  -------------------
          3  2014-09-18 18:34:03
          2  2014-09-18 18:34:03
          1  2014-09-18 18:34:03

Añadimos una fila más como marcador:

BTEQ -- Enter your SQL request or BTEQ command:
INSERT INTO CARLOS.PRUEBA01(ID_N) VALUES ( 4 );

*** Insert completed. One row added.
*** Total elapsed time was 1 second.

BTEQ -- Enter your SQL request or BTEQ command:

SELECT *
FROM CARLOS.PRUEBA01
;

*** Query completed. 4 rows found. 2 columns returned.
*** Total elapsed time was 1 second.

ID_N TS_TIMESTAMP
----------- -------------------
3 2014-09-18 18:34:03
4 2014-09-18 18:34:19
2 2014-09-18 18:34:03
1 2014-09-18 18:34:03

Si hacemos la misma comparación con el mayor estricto para el TIMESTAMP vemos que:

 BTEQ -- Enter your SQL request or BTEQ command:
SELECT *
  FROM CARLOS.PRUEBA01
 WHERE TS_TIMESTAMP > TIMESTAMP '2014-09-18 18:34:03'
;


 *** Query completed. 4 rows found. 2 columns returned.
 *** Total elapsed time was 1 second.

       ID_N         TS_TIMESTAMP
-----------  -------------------
          3  2014-09-18 18:34:03
          4  2014-09-18 18:34:19
          2  2014-09-18 18:34:03
          1  2014-09-18 18:34:03

Y aunque hemos comparado con un mayor estricto, la ‘SELECT’ devuelve valores como si fuera un mayor o igual.

Pero esto sólo ocurre para las filas que fueron afectadas por el ALTER TABLE, ya que la fila que se insertó con la columna TS_TIMESTAMP ya incorporada, se comporta bien en las comparaciones con mayor estricto:

 BTEQ -- Enter your SQL request or BTEQ command:
SELECT *
  FROM CARLOS.PRUEBA01
WHERE TS_TIMESTAMP > TIMESTAMP '2014-09-18 18:34:19';


 *** Query completed. No rows found.
 *** Total elapsed time was 1 second.

Como los buenos prestidigitadores, mostramos la estructura de la tabla para demostrar que no hay trampa ni cartón:

 BTEQ -- Enter your SQL request or BTEQ command:
SHOW TABLE CARLOS.PRUEBA01;


 *** Text of DDL statement returned.
 *** Total elapsed time was 1 second.

-----------------------------------------------------------------------
CREATE MULTISET TABLE CARLOS.PRUEBA01 ,NO FALLBACK ,
     NO BEFORE JOURNAL,
     NO AFTER JOURNAL,
     CHECKSUM = DEFAULT,
     DEFAULT MERGEBLOCKRATIO
     (
      ID_N INTEGER NOT NULL,
      TS_TIMESTAMP TIMESTAMP(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0))
PRIMARY INDEX ( ID_N );

A mí esto me suena a ‘bug‘… y ocurre en las versiones 13.10 y 14.10 (¡!).

Así que, cuidadito con los ALTER TABLE añadiendo columnas TIMESTAMP WITH DEFAULT, te puedes llevar la misma sorpresa que me llevé yo hoy…

Saludos.

Carlos.


Windows is still Windows…

10 septiembre \10\UTC 2014

Hacía mucho que no…

image

BSoD

Saludos.

Carlos.


Et in arcadia ego…

4 septiembre \04\UTC 2014

Un clásico.

image

Saludos.

Carlos.


400.000

2 septiembre \02\UTC 2014

400.000 visitas.  Quién me lo iba a decir…

400.000 Saludos.

Carlos.


¿Sistema sobrecargado?

21 agosto \21\UTC 2014

-“¿Crees que el sistema está sobrecargado?”

-“Un poco sí, ¿no?”

CPU 100%

CPU 100%

Saludos.

Carlos.


Se ha muerto Johnny Winter…

17 julio \17\UTC 2014

Se ha muerto Johnny Winter, guitarrista salvaje y leyenda del blues y del rock.

Bye, bye illustrated man

Saludos.

Carlos


Teradata Express 15 for VMware disponible.

10 julio \10\UTC 2014

Teradata Express 15 for VMware (15.00.00.08) está disponible para descarga.

Se presenta en tres versiones a elegir:

  • TERADATA 15 sobre SLES 11 sin ViewPoint.
  • TERADATA 15 sobre SLES 10 con ViewPoint.
  • TERADATA 15 sobre SLES 10 sin ViewPoint.

No doy abasto…

Saludos.

Carlos

 


Seguir

Recibe cada nueva publicación en tu buzón de correo electrónico.

Únete a otros 44 seguidores