Обсуждение: Writing and Reading bytea
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
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
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