Lists: | pgsql-hackers |
---|
From: | Misa Simic <misa(dot)simic(at)gmail(dot)com> |
---|---|
To: | pgsql-hackers(at)postgresql(dot)org |
Subject: | UUID datatype GiST index support |
Date: | 2011-08-22 10:54:52 |
Message-ID: | CAH3i69njJ9AX1fzHwt6uoUzCMBqnaDBwhmAPhRQzzLWifb2WOA@mail.gmail.com |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Lists: | pgsql-hackers |
Hi,
Hopefully someone can help me and point me in right direction :)
I have been looking for GiST support extension for UUID datatype... since I
could not find it... I wanted to write it myself.
I need it more for EXCLUSION constraint - than to use GIST index just on
UUID column...
i.e:
CREATE TABLE test_exclude
(
id serial NOT NULL,
guid uuid NOT NULL,
valid_period period NOT NULL,
CONSTRAINT "test_excludepk" PRIMARY KEY (id),
EXCLUDE USING gist (guid WITH =, valid_period WITH &&) --for the same guid,
period must not overlap...
)
Has taken a look on btree_gist contrib source code... there are Gist support
functions for many datatypes, so I wanted to take the same "pattern" and
make it...
however, problem happend in first line of code :) (tough I am comming from
totally different world - .Net)
pattern is:
typedef struct
{
ADTdataType lower;
ADTdataType upper;
} datatypeKEY;
i.e. for Date:
typedef struct
{
DateADT lower;
DateADT upper;
} dateKEY;
So I guessed for uuid would be:
typedef struct
{
pg_uuid_t lower;
pg_uuid_t upper;
} uuidKEY;
because of in pg uuid.h says:
* In C, we use the name pg_uuid_t,
* to avoid conflicts with any uuid_t type that might be defined by the
system headers...
and there is:
/* opaque struct; defined in uuid.c */
typedef struct pg_uuid_t pg_uuid_t;
But compiler shows error: Field lower (and upper) has incopmplete
datatype....
Succeded to avoid error with adding:
struct pg_uuid_t
{
unsigned char data[UUID_LEN];
}
but then getting errors in "compare" functions:
i.e.
static int
m4_uuidkey_cmp(const void *a, const void *b)
{
uuidKEY *ia = (uuidKEY *) (((Usrt *) a)->t);
uuidKEY *ib = (uuidKEY *) (((Usrt *) b)->t);
int res;
res = DatumGetInt32(DirectFunctionCall2(uuid_cmp, UUIDPGetDatum(ia->upper),
UUIDPGetDatum(ia->upper)));
if (res == 0)
return DatumGetInt32(DirectFunctionCall2(uuid_cmp, UUIDPGetDatum(ia->upper),
UUIDPGetDatum(ib->upper)));
return res;
}
Getting error: aggregate error used where an integer was expected!
It would be a lot appreciated if anyone could help me and suggest the best
way to make Gist support for UUID datatype...
Many thanks,
Misa
From: | Alexander Korotkov <aekorotkov(at)gmail(dot)com> |
---|---|
To: | Misa Simic <misa(dot)simic(at)gmail(dot)com> |
Cc: | pgsql-hackers(at)postgresql(dot)org |
Subject: | Re: UUID datatype GiST index support |
Date: | 2011-08-22 12:05:47 |
Message-ID: | CAPpHfduv+n_WBxopz8_=kSapxjWZAd7U7LqHGv-6fHB6ioCBPg@mail.gmail.com |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Lists: | pgsql-hackers |
Hi!
On Mon, Aug 22, 2011 at 2:54 PM, Misa Simic <misa(dot)simic(at)gmail(dot)com> wrote:
> static int
> m4_uuidkey_cmp(const void *a, const void *b)
> {
> uuidKEY *ia = (uuidKEY *) (((Usrt *) a)->t);
> uuidKEY *ib = (uuidKEY *) (((Usrt *) b)->t);
> int res;
>
> res = DatumGetInt32(DirectFunctionCall2(uuid_cmp, UUIDPGetDatum(ia->upper),
> UUIDPGetDatum(ia->upper)));
> if (res == 0)
> return DatumGetInt32(DirectFunctionCall2(uuid_cmp,
> UUIDPGetDatum(ia->upper), UUIDPGetDatum(ib->upper)));
>
> return res;
> }
>
>
> Getting error: aggregate error used where an integer was expected!
>
Seems that you need the address-of operator before ia->upper and ia->lower
(likely one of operands should be "ia->lower"). UUIDPGetDatum except pointer
as an argument, i.e. UUIDPGetDatum(&ia->upper).
> It would be a lot appreciated if anyone could help me and suggest the best
> way to make Gist support for UUID datatype...
>
I think you're on the right way. btree_gist is an extension which provides
GiST indexing of scalar datatype. UUID is one of them. So, the module you
are writing should be quite similar.
------
With best regards,
Alexander Korotkov.
From: | Misa Simic <misa(dot)simic(at)gmail(dot)com> |
---|---|
To: | Alexander Korotkov <aekorotkov(at)gmail(dot)com> |
Cc: | pgsql-hackers(at)postgresql(dot)org |
Subject: | Re: UUID datatype GiST index support |
Date: | 2011-08-22 12:52:53 |
Message-ID: | CAH3i69kKeQjp0jNKvpOC0f4=jkm1NEYOWnYnKq_j64Afxbvn-w@mail.gmail.com |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Lists: | pgsql-hackers |
Thanks Alexander,
'Scalar datatype' - given me a hint...
Looking further in btree_gist source, for inet datatype, which seems a bit
complexier then uuid... (char, char, char[16]) structure for inet, compared
to jut char[16] for uuid.
GiST pattern works with double datatype... and there is method
convert_network_to_scalar(Datum, Oid), whick converts an inet value - to
scalar value... and then all index compare functions are based on the
doubles.... which leads me to conclusion (maybe is wrong) if I can convert
UUID value to double it would make a "job" a lot easier... and pretty
straight forward...
Any suggestion, how to convert UUID (char[16]) to scalar?
looking into convert inet to scalar, what confuses me, even there is
char[16] for an ip address... code is:
if (ip_family <http://doxygen.postgresql.org/network_8c.html#a7dc77a7bc93b675d36eca352d589b314>(ip)
== PGSQL_AF_INET
<http://doxygen.postgresql.org/utils_2inet_8h.html#a8ba3e5fe500d587d3eb8699968450b18>)
len = 4;
else
len = 5;
res = ip_family
<http://doxygen.postgresql.org/network_8c.html#a7dc77a7bc93b675d36eca352d589b314>(ip);
for (i = 0; i < len; i++)
{
res *= 256;
res += ip_addr
<http://doxygen.postgresql.org/network_8c.html#a54558e944989cddebdb93f2f6cd965a4>(ip)[i];
}
return res;
takes just first 4, or 5 values from ipaddres even there is 16 - (decalred
as char[16])
Many thanks,
Misa
2011/8/22 Alexander Korotkov <aekorotkov(at)gmail(dot)com>
> Hi!
>
> On Mon, Aug 22, 2011 at 2:54 PM, Misa Simic <misa(dot)simic(at)gmail(dot)com> wrote:
>
>> static int
>> m4_uuidkey_cmp(const void *a, const void *b)
>> {
>> uuidKEY *ia = (uuidKEY *) (((Usrt *) a)->t);
>> uuidKEY *ib = (uuidKEY *) (((Usrt *) b)->t);
>> int res;
>>
>> res = DatumGetInt32(DirectFunctionCall2(uuid_cmp,
>> UUIDPGetDatum(ia->upper), UUIDPGetDatum(ia->upper)));
>> if (res == 0)
>> return DatumGetInt32(DirectFunctionCall2(uuid_cmp,
>> UUIDPGetDatum(ia->upper), UUIDPGetDatum(ib->upper)));
>>
>> return res;
>> }
>>
>>
>> Getting error: aggregate error used where an integer was expected!
>>
> Seems that you need the address-of operator before ia->upper and ia->lower
> (likely one of operands should be "ia->lower"). UUIDPGetDatum except pointer
> as an argument, i.e. UUIDPGetDatum(&ia->upper).
>
>
>> It would be a lot appreciated if anyone could help me and suggest the best
>> way to make Gist support for UUID datatype...
>>
> I think you're on the right way. btree_gist is an extension which provides
> GiST indexing of scalar datatype. UUID is one of them. So, the module you
> are writing should be quite similar.
>
> ------
> With best regards,
> Alexander Korotkov.