Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit0f059e1

Browse files
committed
Allow plpgsql to pass composite-type arguments (ie, whole-row variables)
into SQL expressions. At present this only works usefully for variablesof named rowtypes, not RECORD variables, since the SQL parser can't inferanything about datatypes from a RECORD Param. Still, it's a step forward.
1 parent724c706 commit0f059e1

File tree

2 files changed

+71
-28
lines changed

2 files changed

+71
-28
lines changed

‎src/pl/plpgsql/src/gram.y

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* procedural language
55
*
66
* IDENTIFICATION
7-
* $PostgreSQL: pgsql/src/pl/plpgsql/src/gram.y,v 1.54 2004/06/03 22:56:43 tgl Exp $
7+
* $PostgreSQL: pgsql/src/pl/plpgsql/src/gram.y,v 1.55 2004/06/04 00:07:52 tgl Exp $
88
*
99
* This software is copyrighted by Jan Wieck - Hamburg.
1010
*
@@ -1589,17 +1589,15 @@ read_sql_construct(int until,
15891589
break;
15901590

15911591
case T_ROW:
1592-
/* XXX make this work someday*/
1593-
ereport(ERROR,
1594-
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1595-
errmsg("passing a whole row variable into a SQL command is not implemented")));
1592+
params[nparams] = yylval.row->rowno;
1593+
snprintf(buf, sizeof(buf), " $%d ", ++nparams);
1594+
plpgsql_dstring_append(&ds, buf);
15961595
break;
15971596

15981597
case T_RECORD:
1599-
/* XXX make this work someday*/
1600-
ereport(ERROR,
1601-
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1602-
errmsg("passing a whole record variable into a SQL command is not implemented")));
1598+
params[nparams] = yylval.rec->recno;
1599+
snprintf(buf, sizeof(buf), " $%d ", ++nparams);
1600+
plpgsql_dstring_append(&ds, buf);
16031601
break;
16041602

16051603
default:
@@ -1810,17 +1808,15 @@ make_select_stmt(void)
18101808
break;
18111809

18121810
case T_ROW:
1813-
/* XXX make this work someday*/
1814-
ereport(ERROR,
1815-
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1816-
errmsg("passing a whole row variable into a SQL command is not implemented")));
1811+
params[nparams] = yylval.row->rowno;
1812+
snprintf(buf, sizeof(buf), " $%d ", ++nparams);
1813+
plpgsql_dstring_append(&ds, buf);
18171814
break;
18181815

18191816
case T_RECORD:
1820-
/* XXX make this work someday*/
1821-
ereport(ERROR,
1822-
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1823-
errmsg("passing a whole record variable into a SQL command is not implemented")));
1817+
params[nparams] = yylval.rec->recno;
1818+
snprintf(buf, sizeof(buf), " $%d ", ++nparams);
1819+
plpgsql_dstring_append(&ds, buf);
18241820
break;
18251821

18261822
default:

‎src/pl/plpgsql/src/pl_exec.c

Lines changed: 58 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* procedural language
44
*
55
* IDENTIFICATION
6-
* $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.102 2004/05/30 23:40:41 neilc Exp $
6+
* $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.103 2004/06/04 00:07:52 tgl Exp $
77
*
88
* This software is copyrighted by Jan Wieck - Hamburg.
99
*
@@ -2969,17 +2969,12 @@ exec_eval_datum(PLpgSQL_execstate * estate,
29692969
Datum*value,
29702970
bool*isnull)
29712971
{
2972-
PLpgSQL_var*var;
2973-
PLpgSQL_rec*rec;
2974-
PLpgSQL_recfield*recfield;
2975-
PLpgSQL_trigarg*trigarg;
2976-
inttgargno;
2977-
intfno;
2978-
29792972
switch (datum->dtype)
29802973
{
29812974
casePLPGSQL_DTYPE_VAR:
2982-
var= (PLpgSQL_var*)datum;
2975+
{
2976+
PLpgSQL_var*var= (PLpgSQL_var*)datum;
2977+
29832978
*typeid=var->datatype->typoid;
29842979
*value=var->value;
29852980
*isnull=var->isnull;
@@ -2989,9 +2984,56 @@ exec_eval_datum(PLpgSQL_execstate * estate,
29892984
errmsg("type of \"%s\" does not match that when preparing the plan",
29902985
var->refname)));
29912986
break;
2987+
}
2988+
2989+
casePLPGSQL_DTYPE_ROW:
2990+
{
2991+
PLpgSQL_row*row= (PLpgSQL_row*)datum;
2992+
HeapTupletup;
2993+
2994+
if (!row->rowtupdesc)/* should not happen */
2995+
elog(ERROR,"row variable has no tupdesc");
2996+
tup=make_tuple_from_row(estate,row,row->rowtupdesc);
2997+
if (tup==NULL)/* should not happen */
2998+
elog(ERROR,"row not compatible with its own tupdesc");
2999+
*typeid=row->rowtupdesc->tdtypeid;
3000+
*value=HeapTupleGetDatum(tup);
3001+
*isnull= false;
3002+
if (expectedtypeid!=InvalidOid&&expectedtypeid!=*typeid)
3003+
ereport(ERROR,
3004+
(errcode(ERRCODE_DATATYPE_MISMATCH),
3005+
errmsg("type of \"%s\" does not match that when preparing the plan",
3006+
row->refname)));
3007+
break;
3008+
}
3009+
3010+
casePLPGSQL_DTYPE_REC:
3011+
{
3012+
PLpgSQL_rec*rec= (PLpgSQL_rec*)datum;
3013+
3014+
if (!HeapTupleIsValid(rec->tup))
3015+
ereport(ERROR,
3016+
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
3017+
errmsg("record \"%s\" is not assigned yet",
3018+
rec->refname),
3019+
errdetail("The tuple structure of a not-yet-assigned record is indeterminate.")));
3020+
*typeid=rec->tupdesc->tdtypeid;
3021+
*value=HeapTupleGetDatum(rec->tup);
3022+
*isnull= false;
3023+
if (expectedtypeid!=InvalidOid&&expectedtypeid!=*typeid)
3024+
ereport(ERROR,
3025+
(errcode(ERRCODE_DATATYPE_MISMATCH),
3026+
errmsg("type of \"%s\" does not match that when preparing the plan",
3027+
rec->refname)));
3028+
break;
3029+
}
29923030

29933031
casePLPGSQL_DTYPE_RECFIELD:
2994-
recfield= (PLpgSQL_recfield*)datum;
3032+
{
3033+
PLpgSQL_recfield*recfield= (PLpgSQL_recfield*)datum;
3034+
PLpgSQL_rec*rec;
3035+
intfno;
3036+
29953037
rec= (PLpgSQL_rec*) (estate->datums[recfield->recparentno]);
29963038
if (!HeapTupleIsValid(rec->tup))
29973039
ereport(ERROR,
@@ -3013,9 +3055,13 @@ exec_eval_datum(PLpgSQL_execstate * estate,
30133055
errmsg("type of \"%s.%s\" does not match that when preparing the plan",
30143056
rec->refname,recfield->fieldname)));
30153057
break;
3058+
}
30163059

30173060
casePLPGSQL_DTYPE_TRIGARG:
3018-
trigarg= (PLpgSQL_trigarg*)datum;
3061+
{
3062+
PLpgSQL_trigarg*trigarg= (PLpgSQL_trigarg*)datum;
3063+
inttgargno;
3064+
30193065
*typeid=TEXTOID;
30203066
tgargno=exec_eval_integer(estate,trigarg->argnum,isnull);
30213067
if (*isnull||tgargno<0||tgargno >=estate->trig_nargs)
@@ -3034,6 +3080,7 @@ exec_eval_datum(PLpgSQL_execstate * estate,
30343080
errmsg("type of tgargv[%d] does not match that when preparing the plan",
30353081
tgargno)));
30363082
break;
3083+
}
30373084

30383085
default:
30393086
elog(ERROR,"unrecognized dtype: %d",datum->dtype);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp