diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2015-08-02 23:49:19 -0400 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2015-08-02 23:49:19 -0400 |
commit | 09cecdf285ea9f51aed669f9ea1ba840197d49d0 (patch) | |
tree | 3ae143caf62089b9579acee6b52a92ad2975a6d8 /src/backend | |
parent | 690ed2b76ab91eb79ea04ee2bfbdc8a2693f2a37 (diff) | |
download | postgresql-09cecdf285ea9f51aed669f9ea1ba840197d49d0.tar.gz postgresql-09cecdf285ea9f51aed669f9ea1ba840197d49d0.zip |
Fix a number of places that produced XX000 errors in the regression tests.
It's against project policy to use elog() for user-facing errors, or to
omit an errcode() selection for errors that aren't supposed to be "can't
happen" cases. Fix all the violations of this policy that result in
ERRCODE_INTERNAL_ERROR log entries during the standard regression tests,
as errors that can reliably be triggered from SQL surely should be
considered user-facing.
I also looked through all the files touched by this commit and fixed
other nearby problems of the same ilk. I do not claim to have fixed
all violations of the policy, just the ones in these files.
In a few places I also changed existing ERRCODE choices that didn't
seem particularly appropriate; mainly replacing ERRCODE_SYNTAX_ERROR
by something more specific.
Back-patch to 9.5, but no further; changing ERRCODE assignments in
stable branches doesn't seem like a good idea.
Diffstat (limited to 'src/backend')
-rw-r--r-- | src/backend/access/common/reloptions.c | 19 | ||||
-rw-r--r-- | src/backend/access/heap/heapam.c | 8 | ||||
-rw-r--r-- | src/backend/commands/copy.c | 32 | ||||
-rw-r--r-- | src/backend/commands/vacuum.c | 5 | ||||
-rw-r--r-- | src/backend/executor/execQual.c | 6 | ||||
-rw-r--r-- | src/backend/utils/adt/txid.c | 13 |
6 files changed, 56 insertions, 27 deletions
diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 8176b6a6d41..180f529060d 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -484,7 +484,7 @@ allocate_reloption(bits32 kinds, int type, char *name, char *desc) size = sizeof(relopt_string); break; default: - elog(ERROR, "unsupported option type"); + elog(ERROR, "unsupported reloption type %d", type); return NULL; /* keep compiler quiet */ } @@ -1016,7 +1016,8 @@ parse_one_reloption(relopt_value *option, char *text_str, int text_len, parsed = parse_bool(value, &option->values.bool_val); if (validate && !parsed) ereport(ERROR, - (errmsg("invalid value for boolean option \"%s\": %s", + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("invalid value for boolean option \"%s\": %s", option->gen->name, value))); } break; @@ -1027,12 +1028,14 @@ parse_one_reloption(relopt_value *option, char *text_str, int text_len, parsed = parse_int(value, &option->values.int_val, 0, NULL); if (validate && !parsed) ereport(ERROR, - (errmsg("invalid value for integer option \"%s\": %s", + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("invalid value for integer option \"%s\": %s", option->gen->name, value))); if (validate && (option->values.int_val < optint->min || option->values.int_val > optint->max)) ereport(ERROR, - (errmsg("value %s out of bounds for option \"%s\"", + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("value %s out of bounds for option \"%s\"", value, option->gen->name), errdetail("Valid values are between \"%d\" and \"%d\".", optint->min, optint->max))); @@ -1045,12 +1048,14 @@ parse_one_reloption(relopt_value *option, char *text_str, int text_len, parsed = parse_real(value, &option->values.real_val); if (validate && !parsed) ereport(ERROR, - (errmsg("invalid value for floating point option \"%s\": %s", + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("invalid value for floating point option \"%s\": %s", option->gen->name, value))); if (validate && (option->values.real_val < optreal->min || option->values.real_val > optreal->max)) ereport(ERROR, - (errmsg("value %s out of bounds for option \"%s\"", + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("value %s out of bounds for option \"%s\"", value, option->gen->name), errdetail("Valid values are between \"%f\" and \"%f\".", optreal->min, optreal->max))); @@ -1168,7 +1173,7 @@ fillRelOptions(void *rdopts, Size basesize, } break; default: - elog(ERROR, "unrecognized reloption type %c", + elog(ERROR, "unsupported reloption type %d", options[i].gen->type); break; } diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index 050efdc4806..3701d8e59d5 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -2801,7 +2801,9 @@ l1: if (result == HeapTupleInvisible) { UnlockReleaseBuffer(buffer); - elog(ERROR, "attempted to delete invisible tuple"); + ereport(ERROR, + (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), + errmsg("attempted to delete invisible tuple"))); } else if (result == HeapTupleBeingUpdated && wait) { @@ -3343,7 +3345,9 @@ l2: if (result == HeapTupleInvisible) { UnlockReleaseBuffer(buffer); - elog(ERROR, "attempted to update invisible tuple"); + ereport(ERROR, + (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), + errmsg("attempted to update invisible tuple"))); } else if (result == HeapTupleBeingUpdated && wait) { diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c index 47dd3accafe..8db1b35fe82 100644 --- a/src/backend/commands/copy.c +++ b/src/backend/commands/copy.c @@ -1422,9 +1422,9 @@ BeginCopy(bool is_from, * in any RLS clauses. * * When this happens, we are passed in the relid of the originally - * found relation (which we have locked). As the planner will look - * up the relation again, we double-check here to make sure it found - * the same one that we have locked. + * found relation (which we have locked). As the planner will look up + * the relation again, we double-check here to make sure it found the + * same one that we have locked. */ if (queryRelId != InvalidOid) { @@ -1603,10 +1603,12 @@ ClosePipeToProgram(CopyState cstate) pclose_rc = ClosePipeStream(cstate->copy_file); if (pclose_rc == -1) ereport(ERROR, - (errmsg("could not close pipe to external command: %m"))); + (errcode_for_file_access(), + errmsg("could not close pipe to external command: %m"))); else if (pclose_rc != 0) ereport(ERROR, - (errmsg("program \"%s\" failed", + (errcode(ERRCODE_EXTERNAL_ROUTINE_EXCEPTION), + errmsg("program \"%s\" failed", cstate->filename), errdetail_internal("%s", wait_result_to_str(pclose_rc)))); } @@ -1703,7 +1705,8 @@ BeginCopyTo(Relation rel, cstate->copy_file = OpenPipeStream(cstate->filename, PG_BINARY_W); if (cstate->copy_file == NULL) ereport(ERROR, - (errmsg("could not execute command \"%s\": %m", + (errcode_for_file_access(), + errmsg("could not execute command \"%s\": %m", cstate->filename))); } else @@ -1730,7 +1733,10 @@ BeginCopyTo(Relation rel, cstate->filename))); if (fstat(fileno(cstate->copy_file), &st)) - elog(ERROR, "could not stat file \"%s\": %m", cstate->filename); + ereport(ERROR, + (errcode_for_file_access(), + errmsg("could not stat file \"%s\": %m", + cstate->filename))); if (S_ISDIR(st.st_mode)) ereport(ERROR, @@ -2271,13 +2277,13 @@ CopyFrom(CopyState cstate) { if (!ThereAreNoPriorRegisteredSnapshots() || !ThereAreNoReadyPortals()) ereport(ERROR, - (ERRCODE_INVALID_TRANSACTION_STATE, + (errcode(ERRCODE_INVALID_TRANSACTION_STATE), errmsg("cannot perform FREEZE because of prior transaction activity"))); if (cstate->rel->rd_createSubid != GetCurrentSubTransactionId() && cstate->rel->rd_newRelfilenodeSubid != GetCurrentSubTransactionId()) ereport(ERROR, - (ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE, + (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), errmsg("cannot perform FREEZE because the table was not created or truncated in the current subtransaction"))); hi_options |= HEAP_INSERT_FROZEN; @@ -2737,7 +2743,8 @@ BeginCopyFrom(Relation rel, cstate->copy_file = OpenPipeStream(cstate->filename, PG_BINARY_R); if (cstate->copy_file == NULL) ereport(ERROR, - (errmsg("could not execute command \"%s\": %m", + (errcode_for_file_access(), + errmsg("could not execute command \"%s\": %m", cstate->filename))); } else @@ -2752,7 +2759,10 @@ BeginCopyFrom(Relation rel, cstate->filename))); if (fstat(fileno(cstate->copy_file), &st)) - elog(ERROR, "could not stat file \"%s\": %m", cstate->filename); + ereport(ERROR, + (errcode_for_file_access(), + errmsg("could not stat file \"%s\": %m", + cstate->filename))); if (S_ISDIR(st.st_mode)) ereport(ERROR, diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index baf66f1e6c0..85b04832479 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -180,7 +180,10 @@ vacuum(int options, RangeVar *relation, Oid relid, VacuumParams *params, * calls a hostile index expression that itself calls ANALYZE. */ if (in_vacuum) - elog(ERROR, "%s cannot be executed from VACUUM or ANALYZE", stmttype); + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("%s cannot be executed from VACUUM or ANALYZE", + stmttype))); /* * Send info about dead objects to the statistics collector, unless we are diff --git a/src/backend/executor/execQual.c b/src/backend/executor/execQual.c index 0f911f210bf..16bc8fa5f6c 100644 --- a/src/backend/executor/execQual.c +++ b/src/backend/executor/execQual.c @@ -631,7 +631,8 @@ ExecEvalScalarVar(ExprState *exprstate, ExprContext *econtext, { if (variable->vartype != attr->atttypid) ereport(ERROR, - (errmsg("attribute %d has wrong type", attnum), + (errcode(ERRCODE_DATATYPE_MISMATCH), + errmsg("attribute %d has wrong type", attnum), errdetail("Table has type %s, but query expects %s.", format_type_be(attr->atttypid), format_type_be(variable->vartype)))); @@ -4111,7 +4112,8 @@ ExecEvalFieldSelect(FieldSelectState *fstate, /* As in ExecEvalScalarVar, we should but can't check typmod */ if (fselect->resulttype != attr->atttypid) ereport(ERROR, - (errmsg("attribute %d has wrong type", fieldnum), + (errcode(ERRCODE_DATATYPE_MISMATCH), + errmsg("attribute %d has wrong type", fieldnum), errdetail("Table has type %s, but query expects %s.", format_type_be(attr->atttypid), format_type_be(fselect->resulttype)))); diff --git a/src/backend/utils/adt/txid.c b/src/backend/utils/adt/txid.c index ce1d9abddea..ba4b48298fd 100644 --- a/src/backend/utils/adt/txid.c +++ b/src/backend/utils/adt/txid.c @@ -334,8 +334,11 @@ parse_snapshot(const char *str) return buf_finalize(buf); bad_format: - elog(ERROR, "invalid input for txid_snapshot: \"%s\"", str_start); - return NULL; + ereport(ERROR, + (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("invalid input syntax for type txid_snapshot: \"%s\"", + str_start))); + return NULL; /* keep compiler quiet */ } /* @@ -526,8 +529,10 @@ txid_snapshot_recv(PG_FUNCTION_ARGS) PG_RETURN_POINTER(snap); bad_format: - elog(ERROR, "invalid snapshot data"); - return (Datum) NULL; + ereport(ERROR, + (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION), + errmsg("invalid external txid_snapshot data"))); + PG_RETURN_POINTER(NULL); /* keep compiler quiet */ } /* |