Re: Verbosity of Function Return Type Checks - Mailing list pgsql-hackers
From | Volkan YAZICI |
---|---|
Subject | Re: Verbosity of Function Return Type Checks |
Date | |
Msg-id | 871vzzf70b.fsf@alamut.mobiliz.com.tr Whole thread Raw |
In response to | Re: Verbosity of Function Return Type Checks (Tom Lane <tgl@sss.pgh.pa.us>) |
Responses |
Re: Verbosity of Function Return Type Checks
|
List | pgsql-hackers |
On Thu, 04 Sep 2008, Tom Lane <tgl@sss.pgh.pa.us> writes: > This is not ready to go: you've lost the ability to localize most of > the error message strings. How can I make this available? What's your suggestion? > Also, "char *msg" should be "const char *msg" Done. > if you're going to pass literal constants to it, and this gives me the > willies even though the passed-in strings are supposedly all fixed: > errmsg(msg), > Use > errmsg("%s", msg), > to be safe. Done. > Actually, the entire concept of varying the main message to suit the > context exactly, while the detail messages are *not* changing, seems > pretty bogus... I share your concerns but couldn't come up with a better approach. I'd be happy to hear your suggestions. > Another problem with it is it's likely going to fail completely on > dropped columns (which will have atttypid = 0). Is it ok if I'd replace if (td1->attrs[i]->atttypid != td2->attrs[i]->atttypid) line in validate_tupdesc_compat with if (td1->attrs[i]->atttypid && td2->attrs[i]->atttypid && td1->attrs[i]->atttypid != td2->attrs[i]->atttypid) expression to fix this? Regards. Index: src/pl/plpgsql/src/pl_exec.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/pl/plpgsql/src/pl_exec.c,v retrieving revision 1.219 diff -c -r1.219 pl_exec.c *** src/pl/plpgsql/src/pl_exec.c 1 Sep 2008 22:30:33 -0000 1.219 --- src/pl/plpgsql/src/pl_exec.c 5 Sep 2008 06:13:18 -0000 *************** *** 188,194 **** Oid reqtype, int32 reqtypmod, bool isnull); static void exec_init_tuple_store(PLpgSQL_execstate *estate); ! static bool compatible_tupdesc(TupleDesc td1, TupleDesc td2); static void exec_set_found(PLpgSQL_execstate *estate, bool state); static void plpgsql_create_econtext(PLpgSQL_execstate *estate); static void free_var(PLpgSQL_var *var); --- 188,195 ---- Oid reqtype, int32 reqtypmod, bool isnull); static void exec_init_tuple_store(PLpgSQL_execstate *estate); ! static void validate_tupdesc_compat(TupleDesc td1, TupleDesc td2, ! const char *msg); static void exec_set_found(PLpgSQL_execstate *estate, bool state); static void plpgsql_create_econtext(PLpgSQL_execstate *estate); static void free_var(PLpgSQL_var *var); *************** *** 384,394 **** { case TYPEFUNC_COMPOSITE: /* got the expected result rowtype, now check it */ ! if (estate.rettupdesc == NULL || ! !compatible_tupdesc(estate.rettupdesc, tupdesc)) ! ereport(ERROR, ! (errcode(ERRCODE_DATATYPE_MISMATCH), ! errmsg("returned record type does not match expected record type"))); break; case TYPEFUNC_RECORD: --- 385,393 ---- { case TYPEFUNC_COMPOSITE: /* got the expected result rowtype, now check it */ ! validate_tupdesc_compat(tupdesc, estate.rettupdesc, ! "returned record type does not " ! "match expected record type"); break; case TYPEFUNC_RECORD: *************** *** 705,715 **** rettup = NULL; else { ! if (!compatible_tupdesc(estate.rettupdesc, ! trigdata->tg_relation->rd_att)) ! ereport(ERROR, ! (errcode(ERRCODE_DATATYPE_MISMATCH), ! errmsg("returned tuple structure does not match table of trigger event"))); /* Copy tuple to upper executor memory */ rettup = SPI_copytuple((HeapTuple) DatumGetPointer(estate.retval)); } --- 704,713 ---- rettup = NULL; else { ! validate_tupdesc_compat(trigdata->tg_relation->rd_att, ! estate.rettupdesc, ! "returned tuple structure does not match " ! "table of trigger event"); /* Copy tuple to upper executor memory */ rettup = SPI_copytuple((HeapTuple) DatumGetPointer(estate.retval)); } *************** *** 2199,2209 **** (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), errmsg("record \"%s\" is not assigned yet", rec->refname), ! errdetail("The tuple structure of a not-yet-assigned record is indeterminate."))); ! if (!compatible_tupdesc(tupdesc, rec->tupdesc)) ! ereport(ERROR, ! (errcode(ERRCODE_DATATYPE_MISMATCH), ! errmsg("wrong record type supplied in RETURN NEXT"))); tuple = rec->tup; } break; --- 2197,2207 ---- (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), errmsg("record \"%s\" is not assigned yet", rec->refname), ! errdetail("The tuple structure of a not-yet-assigned" ! " record is indeterminate."))); ! validate_tupdesc_compat(rec->tupdesc, tupdesc, ! "wrong record type supplied in " ! "RETURN NEXT"); tuple = rec->tup; } break; *************** *** 2309,2318 **** stmt->params); } ! if (!compatible_tupdesc(estate->rettupdesc, portal->tupDesc)) ! ereport(ERROR, ! (errcode(ERRCODE_DATATYPE_MISMATCH), ! errmsg("structure of query does not match function result type"))); while (true) { --- 2307,2315 ---- stmt->params); } ! validate_tupdesc_compat(portal->tupDesc, estate->rettupdesc, ! "structure of query does not match function " ! "result type"); while (true) { *************** *** 5145,5167 **** } /* ! * Check two tupledescs have matching number and types of attributes */ ! static bool ! compatible_tupdesc(TupleDesc td1, TupleDesc td2) { ! int i; if (td1->natts != td2->natts) ! return false; for (i = 0; i < td1->natts; i++) - { if (td1->attrs[i]->atttypid != td2->attrs[i]->atttypid) ! return false; ! } ! ! return true; } /* ---------- --- 5142,5178 ---- } /* ! * Validates compatibility of supplied TupleDesc couple by checking # and type ! * of available arguments. */ ! static void ! validate_tupdesc_compat(TupleDesc td1, TupleDesc td2, const char *msg) { ! int i; ! ! if (!td1 || !td2) ! ereport(ERROR, (errcode(ERRCODE_DATATYPE_MISMATCH), errmsg(msg))); if (td1->natts != td2->natts) ! ereport(ERROR, ! (errcode(ERRCODE_DATATYPE_MISMATCH), ! errmsg("%s", msg), ! errdetail("Number of returned columns (%d) does not match " ! "expected column count (%d).", ! td1->natts, td2->natts))); for (i = 0; i < td1->natts; i++) if (td1->attrs[i]->atttypid != td2->attrs[i]->atttypid) ! ereport(ERROR, ! (errcode(ERRCODE_DATATYPE_MISMATCH), ! errmsg("%s", msg), ! errdetail("Returned record type (%s) does not match " ! "expected record type (%s) in column %d (%s).", ! format_type_with_typemod(td1->attrs[i]->atttypid, ! td1->attrs[i]->atttypmod), ! format_type_with_typemod(td2->attrs[i]->atttypid, ! td2->attrs[i]->atttypmod), ! (1+i), NameStr(td2->attrs[i]->attname)))); } /* ----------
pgsql-hackers by date: