/* *build_attrmap_by_position * *Returnapalloc'dbareattributemapfortupleconversion,matchinginput *andoutputcolumnsbyposition.Droppedcolumnsareignoredinbothinput *andoutput,markedas0.Thisisnormallyasubroutinefor *convert_tuples_by_positionintupconvert.c,butitcanbeusedstandalone. * *Note:theerrdetailmessagesspeakofindescasthe"returned"rowtype, *outdescasthe"expected"rowtype.Thisisokayforcurrentusesbut *mightneedgeneralizationinfuture.
*/
AttrMap *
build_attrmap_by_position(TupleDesc indesc,
TupleDesc outdesc, constchar *msg)
{
AttrMap *attrMap; int nincols; int noutcols; int n; int i; int j; bool same;
/* *Thelengthiscomputedasthenumberofattributesoftheexpected *rowtypeasitincludesdroppedattributesinitscount.
*/
n = outdesc->natts;
attrMap = make_attrmap(n);
j = 0; /* j is next physical input attribute */
nincols = noutcols = 0; /* these count non-dropped attributes */
same = true; for (i = 0; i < n; i++)
{
Form_pg_attribute outatt = TupleDescAttr(outdesc, i);
if (outatt->attisdropped) continue; /* attrMap->attnums[i] is already 0 */
noutcols++; for (; j < indesc->natts; j++)
{
Form_pg_attribute inatt = TupleDescAttr(indesc, j);
if (inatt->attisdropped) continue;
nincols++;
/* Found matching column, now check type */ if (outatt->atttypid != inatt->atttypid ||
(outatt->atttypmod != inatt->atttypmod && outatt->atttypmod >= 0))
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
errmsg_internal("%s", _(msg)),
errdetail("Returned type %s does not match expected type %s in column \"%s\" (position %d).",
format_type_with_typemod(inatt->atttypid,
inatt->atttypmod),
format_type_with_typemod(outatt->atttypid,
outatt->atttypmod),
NameStr(outatt->attname),
noutcols)));
attrMap->attnums[i] = (AttrNumber) (j + 1);
j++; break;
} if (attrMap->attnums[i] == 0)
same = false; /* we'll complain below */
}
/* Check for unused input columns */ for (; j < indesc->natts; j++)
{ if (TupleDescCompactAttr(indesc, j)->attisdropped) continue;
nincols++;
same = false; /* we'll complain below */
}
/* Report column count mismatch using the non-dropped-column counts */ if (!same)
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
errmsg_internal("%s", _(msg)),
errdetail("Number of returned columns (%d) does not match " "expected column count (%d).",
nincols, noutcols)));
/* Check if the map has a one-to-one match */ if (check_attrmap_match(indesc, outdesc, attrMap))
{ /* Runtime conversion is not needed */
free_attrmap(attrMap); return NULL;
}
return attrMap;
}
/* *build_attrmap_by_name * *Returnapalloc'dbareattributemapfortupleconversion,matchinginput *andoutputcolumnsbyname.(Droppedcolumnsareignoredinbothinputand *output.)Thisisnormallyasubroutineforconvert_tuples_by_namein *tupconvert.c,butcanbeusedstandalone. * *If'missing_ok'istrue,acolumnfrom'outdesc'notbeingpresentin *'indesc'isnotflaggedasanerror;AttrMap.attnums[]entryforsuchan *outdesccolumnwillbe0inthatcase.
*/
AttrMap *
build_attrmap_by_name(TupleDesc indesc,
TupleDesc outdesc, bool missing_ok)
{
AttrMap *attrMap; int outnatts; int innatts; int i; int nextindesc = -1;
attrMap = make_attrmap(outnatts); for (i = 0; i < outnatts; i++)
{
Form_pg_attribute outatt = TupleDescAttr(outdesc, i); char *attname;
Oid atttypid;
int32 atttypmod; int j;
if (outatt->attisdropped) continue; /* attrMap->attnums[i] is already 0 */
attname = NameStr(outatt->attname);
atttypid = outatt->atttypid;
atttypmod = outatt->atttypmod;
nextindesc++; if (nextindesc >= innatts)
nextindesc = 0;
inatt = TupleDescAttr(indesc, nextindesc); if (inatt->attisdropped) continue; if (strcmp(attname, NameStr(inatt->attname)) == 0)
{ /* Found it, check type */ if (atttypid != inatt->atttypid || atttypmod != inatt->atttypmod)
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
errmsg("could not convert row type"),
errdetail("Attribute \"%s\" of type %s does not match corresponding attribute of type %s.",
attname,
format_type_be(outdesc->tdtypeid),
format_type_be(indesc->tdtypeid))));
attrMap->attnums[i] = inatt->attnum; break;
}
} if (attrMap->attnums[i] == 0 && !missing_ok)
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
errmsg("could not convert row type"),
errdetail("Attribute \"%s\" of type %s does not exist in type %s.",
attname,
format_type_be(outdesc->tdtypeid),
format_type_be(indesc->tdtypeid))));
} return attrMap;
}
/* Check if the map has a one-to-one match */ if (check_attrmap_match(indesc, outdesc, attrMap))
{ /* Runtime conversion is not needed */
free_attrmap(attrMap); return NULL;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.