Обсуждение: Problems with simple_heap_update and Form_pg_relcheck

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

Problems with simple_heap_update and Form_pg_relcheck

От
Holger Krug
Дата:
If have some problem with updating `pg_relcheck' entries. Who can help ?

PostgreSQL version:
  CVS of Jan 03 with some additions for my CREATE ERROR TRIGGER project  (announced on this list). Among those is the
followingchange in  pg_relcheck:
 
    NameData    rcname;    text        rcbin;    text        rcsrc;
+    int2        rcerrhandlers;/* # of ON ERROR triggers,
+                     * currently on 0 or 1 is supported */} FormData_pg_relcheck;  rcerrhandlers is the number of
errorhandlers for a CHECK constraint,  i.e. the number of procedures to be called if a CHECK constraint fails.  Error
handlersare stored in pg_triggers like normal triggers. They  reference CHECK constraints by OID in the same way as
normaltriggers  reference relations by OID. For this to work I have still to add an OID  to pg_relcheck, but the
currentquestion does not depend on this.
 

Error handlers are created by the following statement:

=# create table mytab (arg text CHECK (length(arg)>10));
CREATE
=# CREATE ERROR TRIGGER ehtest on CONSTRAINT CHECK mytab_arg FOR EACH ROW EXECUTE PROCEDURE __proc('arg');
CREATE

In executing the CREATE ERROR TRIGGER command I have to update the entry
of the CHECK constraint in pg_relcheck and ro add an entry to pg_trigger.
The problem I have is related to updating the pg_relcheck entry.

For this I use the following code:
/* Grab an exclusive lock on the pg_relcheck relation */rcrel = heap_openr(RelCheckRelationName, RowExclusiveLock);
/* * Create the scan key. We  need to match the name of the CHECK * constraint. */ScanKeyEntryInitialize(&key, 0,
Anum_pg_relcheck_rcname,              F_NAMEEQ, PointerGetDatum(constrName));/* * Begin scanning the heap */rcscan =
heap_beginscan(rcrel,0, SnapshotNow, 1, &key);
 
/* * We take the first CHECK constraint we can find. */
if (! HeapTupleIsValid(rctup = heap_getnext(rcscan, 0))){  elog(ERROR,"CreateErrorHandler: CHECK constraint \"%s\" does
notexist",       constrName);}
 
/** *  Copy the tuple to be able to end the scan. */rctup = heap_copytuple(rctup);
heap_endscan(rcscan);

[snip]
/** *  update the error handler counter of the constraint */((Form_pg_relcheck) GETSTRUCT(rctup))->rcerrhandlers =
found+ 1;simple_heap_update(rcrel, &rctup->t_self, rctup);            /** * update the indices, too */
 
[snip]heap_freetuple(rctup);
heap_close(rcrel, RowExclusiveLock);


pg_relcheck before the update is done:

# select * from pg_relcheck where rcname='mytab_arg';
rcrelid |  rcname   | rcbin ..  | rcsrc .. | rcerrhandlers 16570 | mytab_arg | ({ EXPR :typeOid 16  :opType op :oper {
OPER:opno 521 :opid 147 :opresulttype 16 } :args ({ EXPR :typeOid 23  :opType func :oper { FUNC :funcid 1317 :functype
23} :args ({ VAR :varno 1 :varattno 1 :vartype 25 :vartypmod -1  :varlevelsup 0 :varnoold 1 :varoattno 1})} { CONST
:consttype23 :constlen 4 :constbyval true :constisnull false :constvalue  4 [ 10 0 0 0 ] })}) | (length(arg) > 10) |
        0
 
(1 row)

pg_relcheck after the update is done:

=# select * from pg_relcheck where rcname='mytab_arg';rcrelid |  rcname   |     rcbin     |       rcsrc        |
rcerrhandlers
 
---------+-----------+---------------+--------------------+---------------  16564 | mytab_arg | ({ EXPR :typ |
(length(arg)> 10) |             0
 
(1 row)

Furthermore when I abort the transaction (with `elog') after the code
segment shown above is executed, the entry in pg_relcheck even vanishes !

I'm really puzzled.

-- 
Holger Krug
hkrug@rationalizer.com


Re: Problems with simple_heap_update and Form_pg_relcheck

От
Holger Krug
Дата:
On Fri, Jan 11, 2002 at 11:52:39AM +0100, Holger Krug wrote:
> Furthermore when I abort the transaction (with `elog') after the code
> segment shown above is executed, the entry in pg_relcheck even vanishes !

This remark applies to a slightly different version of the code, when
I do not heap_copytuple but modify the value in place. OK, that's
understandable, so please forget it. But the problem, that
`rcerrhandlers' is not updated, remains.

-- 
Holger Krug
hkrug@rationalizer.com


Re: Problems with simple_heap_update and Form_pg_relcheck

От
Tom Lane
Дата:
Holger Krug <hkrug@rationalizer.com> writes:
>     ((Form_pg_relcheck) GETSTRUCT(rctup))->rcerrhandlers = found + 1;

What's an "rcerrhandlers"?  It doesn't appear in current sources.

> pg_relcheck after the update is done:
> [rcbin is messed up]

I have a feeling you added rcerrhandlers after the variable-length
fields.  Not good, at least not if you want to access it via a C
struct.  See, eg,
http://developer.postgresql.org/cvsweb.cgi/pgsql/src/backend/catalog/README
        regards, tom lane


Re: Problems with simple_heap_update and Form_pg_relcheck

От
Holger Krug
Дата:
On Fri, Jan 11, 2002 at 11:57:27AM -0500, Tom Lane wrote:
> Holger Krug <hkrug@rationalizer.com> writes:
> >     ((Form_pg_relcheck) GETSTRUCT(rctup))->rcerrhandlers = found + 1;
> 
> What's an "rcerrhandlers"?  It doesn't appear in current sources.

Yes, it's part of my project to add error handlers. It's the number
of error handlers for this constraint, currently my code allows
as values either 0 or 1.

> I have a feeling you added rcerrhandlers after the variable-length
> fields.  Not good, at least not if you want to access it via a C
> struct.  See, eg,
> http://developer.postgresql.org/cvsweb.cgi/pgsql/src/backend/catalog/README

I have that feeling, too. Thanks for the prompt help. 

-- 
Holger Krug
hkrug@rationalizer.com