pg_trigger.tgargs needs detoast

Started by Kenji Kawamuraover 19 years ago3 messageshackers
Jump to latest
#1Kenji Kawamura
kawamura.kenji@oss.ntt.co.jp

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

Attachments:

detoast_pg_trigger_tgargs.patchtext/plain; name=detoast_pg_trigger_tgargs.patchDownload+3-6
#2Bruce Momjian
bruce@momjian.us
In reply to: Kenji Kawamura (#1)
Re: pg_trigger.tgargs needs detoast

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. +

#3Bruce Momjian
bruce@momjian.us
In reply to: Kenji Kawamura (#1)
Re: pg_trigger.tgargs needs detoast

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. +