Обсуждение: GIN index

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

GIN index

От
"huangning290@yahoo.com"
Дата:
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);
}
```

then i debug it . this is my debug info.

Inline image

thank you!
Вложения

Re: GIN index

От
Tomas Vondra
Дата:
Hi,

Why exactly are you starting a new thread again, instead of continuing 
in the thread you started a couple days ago?

A couple recommendations:

1) I find it unlikely you'll get a lot of help unless you provide a way 
to reproduce the issue easily. That is, something people can build and 
test on their own. Posting incomplete chunks of code means we'd have to 
spend time filling in the gaps, etc. Sorry, not going to happen.

Create an extension that we can build/install easily, include a SQL 
script reproducing the issue.


2) The code is incomplete, e.g. hex2char/char2hex are missing. And the 
calls seems to be the other way around. I'd expect geomgrid_in to 
transform hex string to binary, but it calls Char2Hex.


3) AFIAK there's nothing like CREATE FUNCTION ... NOT FENCED ..., so it 
seems you're using some sort of fork. In that case you should probably 
ask them.


4) Don't post backtraces as screenshots. Copy them as text, attach them 
as a text file.


5) Continue in the thread you already started, otherwise it's impossible 
to follow the discussion.


regards

-- 
Tomas Vondra
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company