Обсуждение: Maximum limit on int in plpgsql

Поиск
Список
Период
Сортировка

Maximum limit on int in plpgsql

От
deepthi@granwill.com
Дата:
Hello,

I am passing the ip address as a varchar. Eg: 133.9.4.11

Later on i am splitting the ip address with the delimiter as '.'


ip1t:= split_part($1,'.',1); // returns a text value
ip2t:= split_part($1,'.',2); // returns a text value
ip3t:= split_part($1,'.',3);
ip4t:= split_part($1,'.',4);

Then i am type casting it into an integer

select into ip1 cast(ip1t as integer);
select into ip2 cast(ip2t as integer);
select into ip3 cast(ip3t as integer);
select into ip4 cast(ip4t as integer);

The i am taking the sum using this formula

out_sum=ip1*256*256*256+ip2*256*256+ip3*256+ip4;

When i run the procedure i am getting following error
pg_atoi : Numerical result out of range

I tried all possible datatypes but still i am getting the same error.

Is it the problem of typecasting or the limits on datatype?

Thank you in advance,
deepthi

Re: Maximum limit on int in plpgsql

От
Tino Wildenhain
Дата:
Hi,

Am Dienstag, den 30.11.2004, 02:29 -0800 schrieb deepthi@granwill.com:
> Hello,
>
> I am passing the ip address as a varchar. Eg: 133.9.4.11
>
> Later on i am splitting the ip address with the delimiter as '.'
>
>
> ip1t:= split_part($1,'.',1); // returns a text value
> ip2t:= split_part($1,'.',2); // returns a text value
> ip3t:= split_part($1,'.',3);
> ip4t:= split_part($1,'.',4);
>
> Then i am type casting it into an integer
>
> select into ip1 cast(ip1t as integer);
> select into ip2 cast(ip2t as integer);
> select into ip3 cast(ip3t as integer);
> select into ip4 cast(ip4t as integer);
>
> The i am taking the sum using this formula
>
> out_sum=ip1*256*256*256+ip2*256*256+ip3*256+ip4;
>
> When i run the procedure i am getting following error
> pg_atoi : Numerical result out of range
>
> I tried all possible datatypes but still i am getting the same error.
>
> Is it the problem of typecasting or the limits on datatype?

integer means int4 iirc.
Which is 32 bit, but signed so you only have 2^31-1 as maxint
Did you try int8 here too?
btw. there are IP datatypes in PG as well. Otoh, they dont support
ip->int8 conversion. It depends on what are your plans once you
have that number.

Regards
Tino


Re: Maximum limit on int in plpgsql

От
Richard Huxton
Дата:
deepthi@granwill.com wrote:
> The i am taking the sum using this formula
>
> out_sum=ip1*256*256*256+ip2*256*256+ip3*256+ip4;
>
> When i run the procedure i am getting following error
> pg_atoi : Numerical result out of range
>
> I tried all possible datatypes but still i am getting the same error.
>
> Is it the problem of typecasting or the limits on datatype?

Type integer=int4 and is signed. IP addresses are unsigned. You'll need
to use an int8 to hold them.

--
   Richard Huxton
   Archonet Ltd

Re: Maximum limit on int in plpgsql

От
Richard Huxton
Дата:
deepthi@granwill.com wrote:
> I have tried using the int8 also, even then i am having the problem.

Please CC the list.

The following works for me. I suspect your equivalent of "i" is an int4.

CREATE OR REPLACE FUNCTION test_int8(text) RETURNS int8 AS '
DECLARE
   i   int8;
   tot int8;
BEGIN
     i := CAST($1 AS int8);
     tot := (i * 256 * 256 * 256) + (i * 256 * 256) + (i * 256) + i;
     RETURN tot;
END;
' LANGUAGE plpgsql;

SELECT test_int8('255');

--
   Richard Huxton
   Archonet Ltd

Re: Maximum limit on int in plpgsql

От
Steve Atkins
Дата:
On Tue, Nov 30, 2004 at 11:18:44AM +0000, Richard Huxton wrote:
> deepthi@granwill.com wrote:
> >The i am taking the sum using this formula
> >
> >out_sum=ip1*256*256*256+ip2*256*256+ip3*256+ip4;
> >
> >When i run the procedure i am getting following error
> >pg_atoi : Numerical result out of range
> >
> >I tried all possible datatypes but still i am getting the same error.
> >
> >Is it the problem of typecasting or the limits on datatype?
>
> Type integer=int4 and is signed. IP addresses are unsigned. You'll need
> to use an int8 to hold them.

Or use a 2^31 bias and use a signed int4. These functions map between
dotted-quads and int4s in this way, to maintain ordering. (Not as convenient
as the inet or cidr types, or just cobbling together a simple ip type as
a C function, but sometimes you have to do the inelegant approach...)

create or replace function ip2int(text) returns int as '
DECLARE
  a int;
  b int;
  c int;
  d int;
BEGIN
  a := split_part($1, ''.'', 1);
  b := split_part($1, ''.'', 2);
  c := split_part($1, ''.'', 3);
  d := split_part($1, ''.'', 4);
  RETURN (a-128) * 16777216 + b * 65536 + c * 256 + d;
END;
' LANGUAGE plpgsql IMMUTABLE;

create or replace function int2ip(int) returns text as '
DECLARE
  a int;
  b int;
  c int;
  d int;
BEGIN
   a := (($1 >> 24) & 255) # 128;
   b := ($1 >> 16) & 255;
   c := ($1 >> 8) & 255;
   d := $1 & 255;
  RETURN to_char(a, ''FM999'') || ''.'' || to_char(b, ''FM999'') || ''.'' || to_char(c, ''FM999
'') || ''.'' || to_char(d, ''FM999'');
END;
' LANGUAGE plpgsql IMMUTABLE;

Cheers,
  Steve