Re: Newbie, Howto access Array-Slots in user defined functions?

From: 100(dot)179370(at)germanynet(dot)de (Martin Jacobs)
To: PGSQL Mailinglist <pgsql-general(at)hub(dot)org>
Subject: Re: Newbie, Howto access Array-Slots in user defined functions?
Date: 2000-10-07 10:57:53
Message-ID: m13hrft-000QZZC@Schnecke.Windsbach.de
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-general

Tom Lane wrote:
>
> 100(dot)179370(at)germanynet(dot)de (Martin Jacobs) writes:
> > CREATE FUNCTION lessbyte (_bytea, _bytea) RETURNS bool
> > AS
> > 'SELECT $1[1] < $2[1];' LANGUAGE 'sql';
> > ERROR: Unable to identify an operator '<' for types 'bytea'
> > and 'bytea'
> > You will have to retype this query using an explicit
> > cast
>
> There is nothing wrong with your syntax --- you've declared a function
> that takes two arrays of bytea, selects the first element of each, and
> compares 'em. But bytea doesn't support comparison operators ... or
> much of anything, actually. There is a get_byte function, so you could
> conceivably build what you want starting with
>
> create function lessbyte(bytea, bytea) returns bool as
> 'select get_byte($1,0) < get_byte($2,0)' language 'sql';

Thank your for this hint, but my 6.3.2 installation does not know
a function get_byte(). Instead it knows functions byteaGetByte,
byteaSetByte, ...

Sorry, but that don't work either. New problems come up, see
below.

>
> However, I don't see any reasonable way to deal with variable-length
> inputs without a loop, and SQL functions don't have looping
> constructs.
>
> Given the lack of operators, type bytea isn't currently useful for
> much except plain storage and retrieval of raw byte sequences.
> Have you got a strong reason for using bytea, rather than some
> better-supported type like text? Heck, even array of char
> would work better:
>
> regression=# CREATE FUNCTION lessbyte(_char, _char) returns > bool as
> regression-# 'SELECT $1[1] < $2[1];' LANGUAGE 'sql';
> CREATE

Playing with some homebrown databases I tried to collect ip
adresses in a table. One possibility would be to store them in a
character array, but then I would have to enter them in escaped
notation and would see characters instead of numbers when doing a
plain select in pgsql or pgaccess.

(I know, that postgreSQL supports a native data type supporting
internet and mac adresses.)

Try the following:

internetaccess=> create table iptest (ip bytea[4]);
CREATE
internetaccess=> insert into iptest (ip) values ('{192,147,68,5}');
INSERT 44085 1
internetaccess=> insert into iptest (ip) values ('{191,146,67,1}');
INSERT 44086 1
internetaccess=> select * from iptest;
ip
----------------------
{"192","147","68","5"}
{"191","146","67","1"}
(2 rows)

So far it's what I expected. Now let's extract the class A part
of the address:

internetaccess=> select ip[1] from iptest;
ERROR: type name lookup of ip failed

Uhh, what's this? What's going wrong now? Another approach:

internetaccess=> select "byteaGetByte"(ip,1) from iptest;
ERROR: function byteaGetByte(_bytea, int4) does not
exist

Ok, \df command shows that there is a function byteaGetByte which
expects as first argument a bytea and as second an int4 value.
But how can I use this function if the parser generates
references to bytea (_bytea) instead of the object itself?

> ...

Back to your question: Ip addresses are not of variable length.
Therefor it should be possible to implement the missing compare
operators for <, <=, >, >= ... by unrolling the loop by hand. I
know this is not optimal but I thought of this being an exercise
for myself to lern about PostgreSQL extensions with functions and
operators without having to implement external moduls using C/C++
and gcc.

Martin Jacobs

In response to

Responses

Browse pgsql-general by date

  From Date Subject
Next Message Michael Meskes 2000-10-07 11:00:53 Re: Using UnixODBC and postgresql
Previous Message Anton Kalauzky 2000-10-07 08:58:42 PostgreSQL encoding question