Обсуждение: pg_trigger.tgargs needs detoast
Hello,
This patch fixes a bug of case of extraction of pg_trigger.tgargs.
There was a problem when we used a long argument in defining trigger,
possibly resulting in a server crash.
Example:
We defined a CREATE TRIGGER such as follows and registered trigger.
In this case, the argument value which we received in the trigger
procedure was not right.
CREATE TRIGGER trigger_test BEFORE INSERT OR UPDATE ON sample FOR EACH
ROW EXECUTE PROCEDURE sample_trig('XXX...(more than 1823 characters)');
The trigger procedure which receives the argument:
Datum sample_trig(PG_FUNCTION_ARGS)
{
TriggerData* trigdata = (TriggerData*)fcinfo->context;
char** args = trigdata->tg_trigger->tgargs;
int nargs = trigdata->tg_trigger->tgnargs;
int i;
for (i = 0; i < nargs; i++) {
elog(LOG, "%s", args[i]);
}
...
}
Result:
Before: LOG: (the character that is not right, for example '%')
After : LOG: XXX...(more than 1823 characters)
Regards,
---
Kenji Kawamura
NTT Open Source Center, Japan
Index: src/backend/commands/tablecmds.c
===================================================================
--- src/backend/commands/tablecmds.c (HEAD)
+++ src/backend/commands/tablecmds.c (modified)
@@ -1800,8 +1800,7 @@
* line; so does trigger.c ...
*/
tgnargs = pg_trigger->tgnargs;
- val = (bytea *)
- DatumGetPointer(fastgetattr(tuple,
+ val = DatumGetByteaP(fastgetattr(tuple,
Anum_pg_trigger_tgargs,
tgrel->rd_att, &isnull));
if (isnull || tgnargs < RI_FIRST_ATTNAME_ARGNO ||
Index: src/backend/commands/trigger.c
===================================================================
--- src/backend/commands/trigger.c (HEAD)
+++ src/backend/commands/trigger.c (modified)
@@ -906,8 +906,7 @@
char *p;
int i;
- val = (bytea *)
- DatumGetPointer(fastgetattr(htup,
+ val = DatumGetByteaP(fastgetattr(htup,
Anum_pg_trigger_tgargs,
tgrel->rd_att, &isnull));
if (isnull)
Index: src/backend/utils/adt/ruleutils.c
===================================================================
--- src/backend/utils/adt/ruleutils.c (HEAD)
+++ src/backend/utils/adt/ruleutils.c (modified)
@@ -521,8 +521,7 @@
char *p;
int i;
- val = (bytea *)
- DatumGetPointer(fastgetattr(ht_trig,
+ val = DatumGetByteaP(fastgetattr(ht_trig,
Anum_pg_trigger_tgargs,
tgrel->rd_att, &isnull));
if (isnull)
Your patch has been added to the PostgreSQL unapplied patches list at: http://momjian.postgresql.org/cgi-bin/pgpatches It will be applied as soon as one of the PostgreSQL committers reviews and approves it. --------------------------------------------------------------------------- Kenji Kawamura wrote: > Hello, > > This patch fixes a bug of case of extraction of pg_trigger.tgargs. > There was a problem when we used a long argument in defining trigger, > possibly resulting in a server crash. > > Example: > > We defined a CREATE TRIGGER such as follows and registered trigger. > In this case, the argument value which we received in the trigger > procedure was not right. > > CREATE TRIGGER trigger_test BEFORE INSERT OR UPDATE ON sample FOR EACH > ROW EXECUTE PROCEDURE sample_trig('XXX...(more than 1823 characters)'); > > The trigger procedure which receives the argument: > > Datum sample_trig(PG_FUNCTION_ARGS) > { > TriggerData* trigdata = (TriggerData*)fcinfo->context; > char** args = trigdata->tg_trigger->tgargs; > int nargs = trigdata->tg_trigger->tgnargs; > > int i; > for (i = 0; i < nargs; i++) { > elog(LOG, "%s", args[i]); > } > ... > } > > Result: > > Before: LOG: (the character that is not right, for example '%') > After : LOG: XXX...(more than 1823 characters) > > Regards, > > --- > Kenji Kawamura > NTT Open Source Center, Japan > > Index: src/backend/commands/tablecmds.c > =================================================================== > --- src/backend/commands/tablecmds.c (HEAD) > +++ src/backend/commands/tablecmds.c (modified) > @@ -1800,8 +1800,7 @@ > * line; so does trigger.c ... > */ > tgnargs = pg_trigger->tgnargs; > - val = (bytea *) > - DatumGetPointer(fastgetattr(tuple, > + val = DatumGetByteaP(fastgetattr(tuple, > Anum_pg_trigger_tgargs, > tgrel->rd_att, &isnull)); > if (isnull || tgnargs < RI_FIRST_ATTNAME_ARGNO || > Index: src/backend/commands/trigger.c > =================================================================== > --- src/backend/commands/trigger.c (HEAD) > +++ src/backend/commands/trigger.c (modified) > @@ -906,8 +906,7 @@ > char *p; > int i; > > - val = (bytea *) > - DatumGetPointer(fastgetattr(htup, > + val = DatumGetByteaP(fastgetattr(htup, > Anum_pg_trigger_tgargs, > tgrel->rd_att, &isnull)); > if (isnull) > Index: src/backend/utils/adt/ruleutils.c > =================================================================== > --- src/backend/utils/adt/ruleutils.c (HEAD) > +++ src/backend/utils/adt/ruleutils.c (modified) > @@ -521,8 +521,7 @@ > char *p; > int i; > > - val = (bytea *) > - DatumGetPointer(fastgetattr(ht_trig, > + val = DatumGetByteaP(fastgetattr(ht_trig, > Anum_pg_trigger_tgargs, > tgrel->rd_att, &isnull)); > if (isnull) > > ---------------------------(end of broadcast)--------------------------- > TIP 7: You can help support the PostgreSQL project by donating at > > http://www.postgresql.org/about/donate -- Bruce Momjian bruce@momjian.us EnterpriseDB http://www.enterprisedb.com + If your life is a hard drive, Christ can be your backup. +
Patch applied. Thanks.
Backpached to 8.2.X. If it needs to be backpatched to older releases,
someone needs to research that.
---------------------------------------------------------------------------
Kenji Kawamura wrote:
> Hello,
>
> This patch fixes a bug of case of extraction of pg_trigger.tgargs.
> There was a problem when we used a long argument in defining trigger,
> possibly resulting in a server crash.
>
> Example:
>
> We defined a CREATE TRIGGER such as follows and registered trigger.
> In this case, the argument value which we received in the trigger
> procedure was not right.
>
> CREATE TRIGGER trigger_test BEFORE INSERT OR UPDATE ON sample FOR EACH
> ROW EXECUTE PROCEDURE sample_trig('XXX...(more than 1823 characters)');
>
> The trigger procedure which receives the argument:
>
> Datum sample_trig(PG_FUNCTION_ARGS)
> {
> TriggerData* trigdata = (TriggerData*)fcinfo->context;
> char** args = trigdata->tg_trigger->tgargs;
> int nargs = trigdata->tg_trigger->tgnargs;
>
> int i;
> for (i = 0; i < nargs; i++) {
> elog(LOG, "%s", args[i]);
> }
> ...
> }
>
> Result:
>
> Before: LOG: (the character that is not right, for example '%')
> After : LOG: XXX...(more than 1823 characters)
>
> Regards,
>
> ---
> Kenji Kawamura
> NTT Open Source Center, Japan
>
> Index: src/backend/commands/tablecmds.c
> ===================================================================
> --- src/backend/commands/tablecmds.c (HEAD)
> +++ src/backend/commands/tablecmds.c (modified)
> @@ -1800,8 +1800,7 @@
> * line; so does trigger.c ...
> */
> tgnargs = pg_trigger->tgnargs;
> - val = (bytea *)
> - DatumGetPointer(fastgetattr(tuple,
> + val = DatumGetByteaP(fastgetattr(tuple,
> Anum_pg_trigger_tgargs,
> tgrel->rd_att, &isnull));
> if (isnull || tgnargs < RI_FIRST_ATTNAME_ARGNO ||
> Index: src/backend/commands/trigger.c
> ===================================================================
> --- src/backend/commands/trigger.c (HEAD)
> +++ src/backend/commands/trigger.c (modified)
> @@ -906,8 +906,7 @@
> char *p;
> int i;
>
> - val = (bytea *)
> - DatumGetPointer(fastgetattr(htup,
> + val = DatumGetByteaP(fastgetattr(htup,
> Anum_pg_trigger_tgargs,
> tgrel->rd_att, &isnull));
> if (isnull)
> Index: src/backend/utils/adt/ruleutils.c
> ===================================================================
> --- src/backend/utils/adt/ruleutils.c (HEAD)
> +++ src/backend/utils/adt/ruleutils.c (modified)
> @@ -521,8 +521,7 @@
> char *p;
> int i;
>
> - val = (bytea *)
> - DatumGetPointer(fastgetattr(ht_trig,
> + val = DatumGetByteaP(fastgetattr(ht_trig,
> Anum_pg_trigger_tgargs,
> tgrel->rd_att, &isnull));
> if (isnull)
>
> ---------------------------(end of broadcast)---------------------------
> TIP 7: You can help support the PostgreSQL project by donating at
>
> http://www.postgresql.org/about/donate
-- Bruce Momjian bruce@momjian.us EnterpriseDB http://www.enterprisedb.com
+ If your life is a hard drive, Christ can be your backup. +