Обсуждение: Writing and Reading bytea

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

Writing and Reading bytea

От
Amit Gupta
Дата:
We need insert rows to a catalog table that would store partitions info:

CATALOG(pg_partition,2336) BKI_WITHOUT_OIDS
{   Oid         partrelid;      /* partition table Oid */   Oid         parentrelid;    /* Parent table Oid */   int2
    parttype;       /* Type of partition, list, hash, range */   int2        partkey;        /* partition key */   Oid
      keytype;        /* type of partition key */   int2        keyorder;       /* order of the key in multi-key
partitions*/   bytea       minval;   bytea       maxval;             /* min and max for range partition */   bytea
listval;   int2        hashval;            /* hash value */
 
} FormData_pg_partition;



The following code is used to write bytea:   ...   min_ba = (bytea *) palloc(len+VARHDRSZ);   memcpy(VARDATA(min_ba),
&b_min,len);   SET_VARSIZE(min_ba, len+VARHDRSZ);   values[Anum_pg_partition_minval        -1]= (Datum)min_ba ;
 
...   Relation r = heap_open(PartitionRelationId, RowExclusiveLock);  TupleDesc tupDesc = r->rd_att;   HeapTuple tup =
heap_form_tuple(tupDesc,values, nulls);   simple_heap_insert(r, tup);   CatalogUpdateIndexes(r, tup);   heap_close(r,
RowExclusiveLock);

We can see the correct bytes in the pg_partition table after exectuing
the above code. However, retrieving the bytea datatypes seems
problematic.
The following code didn't work:
....   pg_partrel = heap_open(PartitionRelationId, AccessShareLock);   pg_partscan = systable_beginscan(pg_partrel,
PartitionParentIndexId,true,                               SnapshotNow, 1, &skey);   while
(HeapTupleIsValid(pg_parttup=systable_getnext(pg_partscan)))   {       Form_pg_partition pg_part = (Form_pg_partition)
GETSTRUCT(pg_parttup);      Datum attr = heap_getattr(tuple, pg_part->partkey, rel->rd_att, &isnull)       Datum
min_part_attr= (Datum) (&pg_part->minval);       Datum max_part_attr = (Datum) (&pg_part->maxval); ......
 

}

max_part_attr is not poining to right mem location.  After doing some
investgation, we found since minval extends to 10 bytes (instead of 5
bytes occupied by struct varlena), max_part_attr value is not correct.
We also tried doing a hack:
max_ part_attr = (Datum)
(((void*)(&pg_part->minval))+VARSIZE_ANY(&pg_part->minval));

but still we are facing problems.

Any pointers in this respect will be helpful.

Thanks,
Amit
Persistent Systems


Re: Writing and Reading bytea

От
Heikki Linnakangas
Дата:
Amit Gupta wrote:
> The following code didn't work:
> ....
>     pg_partrel = heap_open(PartitionRelationId, AccessShareLock);
>     pg_partscan = systable_beginscan(pg_partrel, PartitionParentIndexId, true,
>                                 SnapshotNow, 1, &skey);
>     while (HeapTupleIsValid(pg_parttup= systable_getnext(pg_partscan)))
>     {
>         Form_pg_partition pg_part = (Form_pg_partition) GETSTRUCT(pg_parttup);
>         Datum attr = heap_getattr(tuple, pg_part->partkey, rel->rd_att, &isnull)
>         Datum min_part_attr = (Datum) (&pg_part->minval);
>         Datum max_part_attr = (Datum) (&pg_part->maxval);
>   ......
> 
> }

You need to use heap_getattr to access columns after the first variable 
length column.

--   Heikki Linnakangas  EnterpriseDB   http://www.enterprisedb.com


Re: Writing and Reading bytea

От
Heikki Linnakangas
Дата:
Amit Gupta wrote:
> We need insert rows to a catalog table that would store partitions info:
> 
> CATALOG(pg_partition,2336) BKI_WITHOUT_OIDS
> {
>     Oid         partrelid;      /* partition table Oid */
>     Oid         parentrelid;    /* Parent table Oid */
>     int2        parttype;       /* Type of partition, list, hash, range */
>     int2        partkey;        /* partition key */
>     Oid         keytype;        /* type of partition key */
>     int2        keyorder;       /* order of the key in multi-key partitions */
>     bytea       minval;
>     bytea       maxval;             /* min and max for range partition */
>     bytea       listval;
>     int2        hashval;            /* hash value */
> } FormData_pg_partition;

I realize you're still in early phase of hacking, but let me just point 
out that bytea is hardly the right data type for min/max value, unless 
the partitioning key is actually a bytea column. I can't suggest a 
better alternative off the top of my head. We have hacked around that 
problem in pg_statistic stavalues columns, but it really is a hack.

--   Heikki Linnakangas  EnterpriseDB   http://www.enterprisedb.com