sobota, 22 września 2018

PostgreSQL projection from INT4 x INT4 to INT8, and back again.


From time to time I need to cast (integer,integer) to bigint and bac k.

The rule is simple:

  0001000f
          0001000f
  ================
  0001000f0001000f

SQL functions:

CREATE OR REPLACE FUNCTION
intpair2bigint(integer, integer)
 RETURNS bigint
 IMMUTABLE STRICT

 LANGUAGE sql
AS '

  SELECT (
    $1::bit(32)::bit(64)
    | ($2::bit(32)::bit(64)>>32)
  )::int8
';

CREATE OR REPLACE FUNCTION
bigint2intpair(bigint)
 RETURNS TABLE(high integer, low integer)

 IMMUTABLE STRICT
 LANGUAGE sql
AS '

  SELECT
    $1::bit(64)::bit(32)::int4,
    $1::bit(32)::int4
';

Some tests:

SELECT intpair2bigint( 0, 0 );
0
SELECT intpair2bigint( 0, (2^31-1)::int4 );
2147483647
SELECT intpair2bigint( 0, (-2^31)::int4 );
-2147483648
SELECT intpair2bigint( (2^31-1)::int4, 0 );
140737488289792
SELECT intpair2bigint( (2^31-1)::int4, (2^31-1)::int4  );
140739635773439
SELECT intpair2bigint( (2^31-1)::int4, (-2^31)::int4 );
140735340806144
SELECT intpair2bigint( (-2^31)::int4, 0 );
-140737488355328
SELECT intpair2bigint( (-2^31)::int4, (2^31-1)::int4 );
-140735340871681
SELECT intpair2bigint( (-2^31)::int4, (-2^31)::int4 );
-140739635838976


Voila!

Brak komentarzy:

Prześlij komentarz