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

Commit219dfae

Browse files
committed
Make plpgsql provide the typmods for its variables to the main parser.
Historically we didn't do this, even though we had the information, becauseplpgsql passed its Params via SPI APIs that only include type OIDs nottypmods. Now that plpgsql uses parser callbacks to create Params, it'seasy to insert the right typmod. This should generally result in lowersurprise factors, because a plpgsql variable that is declared with a typmodwill now work more like a table column with the same typmod. In particularit's the "right" way to fix bug #6020, in which plpgsql's attempt to returnan anonymous record type is defeated by stricter record-type matchingchecks that were added in 9.0. However, it's not impossible that thiscould result in subtle behavioral changes that could break somebody'sexisting plpgsql code, so I'm afraid to back-patch this change intoreleased branches. In those branches we'll have to lobotomize therecord-type checks instead.
1 parentfae625e commit219dfae

File tree

3 files changed

+64
-21
lines changed

3 files changed

+64
-21
lines changed

‎src/pl/plpgsql/src/pl_comp.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1267,9 +1267,11 @@ make_datum_param(PLpgSQL_expr *expr, int dno, int location)
12671267
param=makeNode(Param);
12681268
param->paramkind=PARAM_EXTERN;
12691269
param->paramid=dno+1;
1270-
param->paramtype=exec_get_datum_type(estate,datum);
1271-
param->paramtypmod=-1;
1272-
param->paramcollid=exec_get_datum_collation(estate,datum);
1270+
exec_get_datum_type_info(estate,
1271+
datum,
1272+
&param->paramtype,
1273+
&param->paramtypmod,
1274+
&param->paramcollid);
12731275
param->location=location;
12741276

12751277
return (Node*)param;

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

Lines changed: 56 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4307,29 +4307,63 @@ exec_get_datum_type(PLpgSQL_execstate *estate,
43074307
}
43084308

43094309
/*
4310-
* exec_get_datum_collationGet collation of a PLpgSQL_datum
4310+
* exec_get_datum_type_infoGet datatype etc of a PLpgSQL_datum
4311+
*
4312+
* An extended version of exec_get_datum_type, which also retrieves the
4313+
* typmod and collation of the datum.
43114314
*/
4312-
Oid
4313-
exec_get_datum_collation(PLpgSQL_execstate*estate,
4314-
PLpgSQL_datum*datum)
4315+
void
4316+
exec_get_datum_type_info(PLpgSQL_execstate*estate,
4317+
PLpgSQL_datum*datum,
4318+
Oid*typeid,int32*typmod,Oid*collation)
43154319
{
4316-
Oidcollid;
4317-
43184320
switch (datum->dtype)
43194321
{
43204322
casePLPGSQL_DTYPE_VAR:
43214323
{
43224324
PLpgSQL_var*var= (PLpgSQL_var*)datum;
43234325

4324-
collid=var->datatype->collation;
4326+
*typeid=var->datatype->typoid;
4327+
*typmod=var->datatype->atttypmod;
4328+
*collation=var->datatype->collation;
43254329
break;
43264330
}
43274331

43284332
casePLPGSQL_DTYPE_ROW:
4333+
{
4334+
PLpgSQL_row*row= (PLpgSQL_row*)datum;
4335+
4336+
if (!row->rowtupdesc)/* should not happen */
4337+
elog(ERROR,"row variable has no tupdesc");
4338+
/* Make sure we have a valid type/typmod setting */
4339+
BlessTupleDesc(row->rowtupdesc);
4340+
*typeid=row->rowtupdesc->tdtypeid;
4341+
/* do NOT return the mutable typmod of a RECORD variable */
4342+
*typmod=-1;
4343+
/* composite types are never collatable */
4344+
*collation=InvalidOid;
4345+
break;
4346+
}
4347+
43294348
casePLPGSQL_DTYPE_REC:
4330-
/* composite types are never collatable */
4331-
collid=InvalidOid;
4332-
break;
4349+
{
4350+
PLpgSQL_rec*rec= (PLpgSQL_rec*)datum;
4351+
4352+
if (rec->tupdesc==NULL)
4353+
ereport(ERROR,
4354+
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
4355+
errmsg("record \"%s\" is not assigned yet",
4356+
rec->refname),
4357+
errdetail("The tuple structure of a not-yet-assigned record is indeterminate.")));
4358+
/* Make sure we have a valid type/typmod setting */
4359+
BlessTupleDesc(rec->tupdesc);
4360+
*typeid=rec->tupdesc->tdtypeid;
4361+
/* do NOT return the mutable typmod of a RECORD variable */
4362+
*typmod=-1;
4363+
/* composite types are never collatable */
4364+
*collation=InvalidOid;
4365+
break;
4366+
}
43334367

43344368
casePLPGSQL_DTYPE_RECFIELD:
43354369
{
@@ -4350,21 +4384,27 @@ exec_get_datum_collation(PLpgSQL_execstate *estate,
43504384
(errcode(ERRCODE_UNDEFINED_COLUMN),
43514385
errmsg("record \"%s\" has no field \"%s\"",
43524386
rec->refname,recfield->fieldname)));
4353-
/* XXX there's no SPI_getcollid, as yet */
4387+
*typeid=SPI_gettypeid(rec->tupdesc,fno);
4388+
/* XXX there's no SPI_gettypmod, for some reason */
4389+
if (fno>0)
4390+
*typmod=rec->tupdesc->attrs[fno-1]->atttypmod;
4391+
else
4392+
*typmod=-1;
4393+
/* XXX there's no SPI_getcollation either */
43544394
if (fno>0)
4355-
collid=rec->tupdesc->attrs[fno-1]->attcollation;
4395+
*collation=rec->tupdesc->attrs[fno-1]->attcollation;
43564396
else/* no system column types have collation */
4357-
collid=InvalidOid;
4397+
*collation=InvalidOid;
43584398
break;
43594399
}
43604400

43614401
default:
43624402
elog(ERROR,"unrecognized dtype: %d",datum->dtype);
4363-
collid=InvalidOid;/* keep compiler quiet */
4403+
*typeid=InvalidOid;/* keep compiler quiet */
4404+
*typmod=-1;
4405+
*collation=InvalidOid;
43644406
break;
43654407
}
4366-
4367-
returncollid;
43684408
}
43694409

43704410
/* ----------

‎src/pl/plpgsql/src/plpgsql.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -905,8 +905,9 @@ extern void plpgsql_subxact_cb(SubXactEvent event, SubTransactionId mySubid,
905905
SubTransactionIdparentSubid,void*arg);
906906
externOidexec_get_datum_type(PLpgSQL_execstate*estate,
907907
PLpgSQL_datum*datum);
908-
externOidexec_get_datum_collation(PLpgSQL_execstate*estate,
909-
PLpgSQL_datum*datum);
908+
externvoidexec_get_datum_type_info(PLpgSQL_execstate*estate,
909+
PLpgSQL_datum*datum,
910+
Oid*typeid,int32*typmod,Oid*collation);
910911

911912
/* ----------
912913
* Functions for namespace handling in pl_funcs.c

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp