Thread: create a new GIN index for my own type
Hi:
I created a new data type, and then I wanted to create a GIN index for it, but when I created the index, the program would crash 。
The version of postgresql is 9.6。
The following is part of the code, and I also refer to the code of intarray.
```sql
CREATE OR REPLACE FUNCTION geomgrid_in(cstring)
RETURNS geomgrid
AS '$libdir/module-1.0','geomgrid_in'
LANGUAGE 'c' NOT FENCED IMMUTABLE STRICT ;
CREATE OR REPLACE FUNCTION geomgrid_out(geomgrid)
RETURNS cstring
AS '$libdir/module-1.0','geomgrid_out'
LANGUAGE 'c' NOT FENCED IMMUTABLE STRICT ;
CREATE OR REPLACE FUNCTION geomgrid_recv(internal)
RETURNS geomgrid
AS '$libdir/module-1.0','geomgrid_recv'
LANGUAGE 'c' NOT FENCED IMMUTABLE STRICT ;
CREATE OR REPLACE FUNCTION geomgrid_send(geomgrid)
RETURNS bytea
AS '$libdir/module-1.0','geomgrid_send'
LANGUAGE 'c' NOT FENCED IMMUTABLE STRICT ;
CREATE TYPE geomgrid(
internallength = 8,
input = geomgrid_in,
output = geomgrid_out,
send = geomgrid_send,
receive = geomgrid_recv,
alignment = double,
PASSEDBYVALUE = true,
storage = plain
);
CREATE OPERATOR CLASS gin_grid_ops
DEFAULT FOR TYPE _geomgrid USING gin
AS
OPERATOR 3 &&,
OPERATOR 6 = (anyarray, anyarray),
OPERATOR 7 @>,
OPERATOR 8 <@,
FUNCTION 1 grid_cmp(geomgrid,geomgrid),
FUNCTION 2 gridarray_extract (anyarray, internal, internal),
FUNCTION 3 gridarray_queryextract (geomgrid, internal, int2, internal, internal, internal, internal),
```
```c
Datum geomgrid_in(PG_FUNCTION_ARGS)
{
char *input = PG_GETARG_CSTRING(0);
int len = strlen(input);
if (len != 16)
PG_RETURN_NULL();
char *data = palloc(len / 2 );
for (int i = 0, j = 7; i < len; i += 2, j--)
{
data[j] = Char2Hex(input + i);
}
int64_t* return_data = (int64_t*)data;
PG_RETURN_INT64(*return_data);
}
Datum geomgrid_out(PG_FUNCTION_ARGS)
{
int64_t out_data = PG_GETARG_INT64(0);
char* buf_data = (char*)(&out_data);
unsigned char dst[2] = {0};
char *result = palloc(16 + 1);
memset(result, 0, 16 + 1);
for (int i = 7, j = 0; i >= 0; i--, j++)
{
Hex2Char((unsigned char)buf_data[i], dst);
result[j * 2 + 1] = dst[0];
result[j * 2] = dst[1];
}
PG_RETURN_CSTRING(result);
}
```
```c
Datum gridarray_extract(PG_FUNCTION_ARGS)
{
ArrayType *array = PG_GETARG_ARRAYTYPE_P_COPY(0);
int size = VARSIZE(array);
int32 *nkeys = (int32 *)PG_GETARG_POINTER(1);
bool **nullFlags = (bool **)PG_GETARG_POINTER(2);
if (array == NULL || nkeys == NULL || nullFlags == NULL)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("Invalid arguments for function gridarray_extract")));
int16 elmlen;
bool elmbyval = false;
char elmalign;
Datum *elems = NULL;
bool *nulls = NULL;
int nelems;
get_typlenbyvalalign(ARR_ELEMTYPE(array), &elmlen, &elmbyval, &elmalign);
deconstruct_array(array, ARR_ELEMTYPE(array), elmlen, elmbyval, elmalign, &elems, &nulls, &nelems);
*nkeys = nelems;
*nullFlags = nulls;
PG_RETURN_POINTER(elems);
}
```
On 10/4/21 8:30 AM, huangning290@yahoo.com wrote: > Hi: > I created a new data type, and then I wanted to create a GIN index for > it, but when I created the index, the program would crash 。 > The version of postgresql is 9.6。 > > The following is part of the code, and I also refer to the code of intarray. > I doubt anyone is going to investigate this unless you provide a more complete example - something like an extension where people can do "make install" without having to fill in various pieces of code. To investigate the crash, you need to attach a debugger to the backend and run the CREATE INDEX (or whatever triggers the crash). The debugger should catch the segfault and you'll be able to identify where exactly it crashes and why (and investigate). 1) first get PID of the backend SELECT pg_backend_pid(); 2) then attach a debugger to the backend gdb -p $PID (gdb) c 3) run the CREATE INDEX query 4) get backtrace from the debugger (gdb) bt regards -- Tomas Vondra EnterpriseDB: http://www.enterprisedb.com The Enterprise PostgreSQL Company
On 10/4/21 3:32 PM, huangning290@yahoo.com wrote: > I have already debugged the program according to this step, but I found > that in the DataCopy function, the variable typlen should be 8, but it > is -1, > Well, if you have debugged this, it'd be nice if you could share more information (e.g. backtraces, etc.) otherwise others can just guess what you saw. And that makes it much harder to help you. I see you defined the data type as PASSEDBYVALUE, but you haven't specified INTERNALLENGTH, so it's -1 (i.e. variable length). Obviously, that can't be passed by value - not sure if this is intentional or just a case of CREATE TYPE not checking it. BTW it's customary not to top post - inline replies are much easier to follow, as it makes clearer which parts you respond to. And please make sure that you're responding to the mailing list, not just directly to the other person. regards -- Tomas Vondra EnterpriseDB: http://www.enterprisedb.com The Enterprise PostgreSQL Company
Thanks for you reply.This is my stack information.

Another question is, I have already set INTERNALLENGTH in CREATE TYPE, do I need to set it elsewhere?
On Monday, October 4, 2021, 09:51:38 PM GMT+8, Tomas Vondra <tomas.vondra@enterprisedb.com> wrote:
On 10/4/21 3:32 PM, huangning290@yahoo.com wrote:
> I have already debugged the program according to this step, but I found
> that in the DataCopy function, the variable typlen should be 8, but it
> is -1,
>
Well, if you have debugged this, it'd be nice if you could share more
information (e.g. backtraces, etc.) otherwise others can just guess what
you saw. And that makes it much harder to help you.
I see you defined the data type as PASSEDBYVALUE, but you haven't
specified INTERNALLENGTH, so it's -1 (i.e. variable length). Obviously,
that can't be passed by value - not sure if this is intentional or just
a case of CREATE TYPE not checking it.
BTW it's customary not to top post - inline replies are much easier to
follow, as it makes clearer which parts you respond to. And please make
sure that you're responding to the mailing list, not just directly to
the other person.
> I have already debugged the program according to this step, but I found
> that in the DataCopy function, the variable typlen should be 8, but it
> is -1,
>
Well, if you have debugged this, it'd be nice if you could share more
information (e.g. backtraces, etc.) otherwise others can just guess what
you saw. And that makes it much harder to help you.
I see you defined the data type as PASSEDBYVALUE, but you haven't
specified INTERNALLENGTH, so it's -1 (i.e. variable length). Obviously,
that can't be passed by value - not sure if this is intentional or just
a case of CREATE TYPE not checking it.
BTW it's customary not to top post - inline replies are much easier to
follow, as it makes clearer which parts you respond to. And please make
sure that you're responding to the mailing list, not just directly to
the other person.