First bits of work on error message editing.

This commit is contained in:
Tom Lane 2003-07-18 23:20:33 +00:00
parent 44f665bf40
commit 216311d590
21 changed files with 1083 additions and 534 deletions

View File

@ -1,5 +1,5 @@
<!-- <!--
$Header: /cvsroot/pgsql/doc/src/sgml/sources.sgml,v 2.8 2003/06/22 16:17:01 tgl Exp $ $Header: /cvsroot/pgsql/doc/src/sgml/sources.sgml,v 2.9 2003/07/18 23:20:32 tgl Exp $
--> -->
<chapter id="source"> <chapter id="source">
@ -125,11 +125,12 @@ less -x4
Here is a more complex example: Here is a more complex example:
<programlisting> <programlisting>
ereport(ERROR, ereport(ERROR,
(errmsg("Unable to identify an operator %s %s %s", (errcode(ERRCODE_AMBIGUOUS_FUNCTION),
format_type_be(arg1), errmsg("function %s is not unique",
NameListToString(op), func_signature_string(funcname, nargs,
format_type_be(arg2)), actual_arg_types)),
errhint("Try explicitly casting the arguments to appropriate types"))); errhint("Unable to choose a best candidate function. "
"You may need to add explicit typecasts.")));
</programlisting> </programlisting>
This illustrates the use of format codes to embed run-time values into This illustrates the use of format codes to embed run-time values into
a message text. Also, an optional <quote>hint</> message is provided. a message text. Also, an optional <quote>hint</> message is provided.
@ -141,11 +142,14 @@ less -x4
<listitem> <listitem>
<para> <para>
<function>errcode</>(sqlerrcode) specifies the SQLSTATE error identifier <function>errcode</>(sqlerrcode) specifies the SQLSTATE error identifier
code for the condition. If this is not specified, it defaults to code for the condition. If this routine is not called, the error
<literal>ERRCODE_INTERNAL_ERROR</>, which is a convenient default since identifier defaults to
a large number of <function>ereport</> calls are in fact for internal <literal>ERRCODE_INTERNAL_ERROR</> when the error level is
<quote>can't happen</> conditions. But never use this default when <literal>ERROR</> or higher, <literal>ERRCODE_WARNING</> when the
reporting user mistakes. error level is <literal>WARNING</>, otherwise (for <literal>NOTICE</>
and below) <literal>ERRCODE_SUCCESSFUL_COMPLETION</>.
While these defaults are often convenient, always think whether they
are appropriate before omitting the <function>errcode</>() call.
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
@ -220,15 +224,25 @@ less -x4
query processing. query processing.
</para> </para>
</listitem> </listitem>
<listitem>
<para>
<function>errcode_for_file_access</>() is a convenience function that
selects an appropriate SQLSTATE error identifier for a failure in a
file-access-related system call. It uses the saved
<literal>errno</> to determine which error code to generate.
Usually this should be used in combination with <literal>%m</> in the
primary error message text.
</para>
</listitem>
</itemizedlist> </itemizedlist>
</para> </para>
<para> <para>
You may also see uses of the older function <function>elog</>. This You may also see uses of the older function <function>elog</>. This
is equivalent to an <function>ereport</> call specifying only severity is equivalent to an <function>ereport</> call specifying only severity
level and primary message. Because the error code always defaults to level and primary message. <function>elog</> should only be used if
<literal>ERRCODE_INTERNAL_ERROR</>, <function>elog</> should only be the default errcode assignment is appropriate; this generally restricts
used for internal errors. its use to internal errors and debug logging output.
</para> </para>
<para> <para>
@ -270,7 +284,7 @@ less -x4
write write
<programlisting> <programlisting>
Primary: could not create shared memory segment: %m Primary: could not create shared memory segment: %m
Detail: Failed syscall was shmget(key=%d, size=%u, 0%o) Detail: Failed syscall was shmget(key=%d, size=%u, 0%o).
Hint: the addendum Hint: the addendum
</programlisting> </programlisting>
</para> </para>

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.99 2003/07/01 01:28:32 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.100 2003/07/18 23:20:32 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -82,8 +82,10 @@ ProcedureCreate(const char *procedureName,
Assert(PointerIsValid(probin)); Assert(PointerIsValid(probin));
if (parameterCount < 0 || parameterCount > FUNC_MAX_ARGS) if (parameterCount < 0 || parameterCount > FUNC_MAX_ARGS)
elog(ERROR, "functions cannot have more than %d arguments", ereport(ERROR,
FUNC_MAX_ARGS); (errcode(ERRCODE_TOO_MANY_ARGUMENTS),
errmsg("functions cannot have more than %d arguments",
FUNC_MAX_ARGS)));
/* /*
* Do not allow return type ANYARRAY or ANYELEMENT unless at least one * Do not allow return type ANYARRAY or ANYELEMENT unless at least one
@ -104,8 +106,9 @@ ProcedureCreate(const char *procedureName,
} }
if (!genericParam) if (!genericParam)
elog(ERROR, "functions returning ANYARRAY or ANYELEMENT must " \ ereport(ERROR,
"have at least one argument of either type"); (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
errmsg("functions returning ANYARRAY or ANYELEMENT must have at least one argument of either type")));
} }
/* Make sure we have a zero-padded param type array */ /* Make sure we have a zero-padded param type array */
@ -156,10 +159,12 @@ ProcedureCreate(const char *procedureName,
* existing attributes of the type * existing attributes of the type
*/ */
if (parameterCount == 1 && OidIsValid(typev[0]) && if (parameterCount == 1 && OidIsValid(typev[0]) &&
(relid = typeidTypeRelid(typev[0])) != 0 && (relid = typeidTypeRelid(typev[0])) != InvalidOid &&
get_attnum(relid, (char *) procedureName) != InvalidAttrNumber) get_attnum(relid, (char *) procedureName) != InvalidAttrNumber)
elog(ERROR, "method %s already an attribute of type %s", ereport(ERROR,
procedureName, format_type_be(typev[0])); (errcode(ERRCODE_DUPLICATE_COLUMN),
errmsg("\"%s\" is already an attribute of type %s",
procedureName, format_type_be(typev[0]))));
/* /*
* All seems OK; prepare the data to be inserted into pg_proc. * All seems OK; prepare the data to be inserted into pg_proc.
@ -208,11 +213,15 @@ ProcedureCreate(const char *procedureName,
Form_pg_proc oldproc = (Form_pg_proc) GETSTRUCT(oldtup); Form_pg_proc oldproc = (Form_pg_proc) GETSTRUCT(oldtup);
if (!replace) if (!replace)
elog(ERROR, "function %s already exists with same argument types", ereport(ERROR,
procedureName); (errcode(ERRCODE_DUPLICATE_FUNCTION),
errmsg("function \"%s\" already exists with same argument types",
procedureName)));
if (GetUserId() != oldproc->proowner && !superuser()) if (GetUserId() != oldproc->proowner && !superuser())
elog(ERROR, "ProcedureCreate: you do not have permission to replace function %s", ereport(ERROR,
procedureName); (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("you do not have permission to replace function \"%s\"",
procedureName)));
/* /*
* Not okay to change the return type of the existing proc, since * Not okay to change the return type of the existing proc, since
@ -220,18 +229,24 @@ ProcedureCreate(const char *procedureName,
*/ */
if (returnType != oldproc->prorettype || if (returnType != oldproc->prorettype ||
returnsSet != oldproc->proretset) returnsSet != oldproc->proretset)
elog(ERROR, "ProcedureCreate: cannot change return type of existing function." ereport(ERROR,
"\n\tUse DROP FUNCTION first."); (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
errmsg("cannot change return type of existing function"),
errhint("Use DROP FUNCTION first.")));
/* Can't change aggregate status, either */ /* Can't change aggregate status, either */
if (oldproc->proisagg != isAgg) if (oldproc->proisagg != isAgg)
{ {
if (oldproc->proisagg) if (oldproc->proisagg)
elog(ERROR, "function %s is an aggregate", ereport(ERROR,
procedureName); (errcode(ERRCODE_WRONG_OBJECT_TYPE),
errmsg("function \"%s\" is an aggregate",
procedureName)));
else else
elog(ERROR, "function %s is not an aggregate", ereport(ERROR,
procedureName); (errcode(ERRCODE_WRONG_OBJECT_TYPE),
errmsg("function \"%s\" is not an aggregate",
procedureName)));
} }
/* do not change existing ownership or permissions, either */ /* do not change existing ownership or permissions, either */
@ -347,8 +362,11 @@ check_sql_fn_retval(Oid rettype, char fn_typtype, List *queryTreeList)
if (queryTreeList == NIL) if (queryTreeList == NIL)
{ {
if (rettype != VOIDOID) if (rettype != VOIDOID)
elog(ERROR, "function declared to return %s, but no SELECT provided", ereport(ERROR,
format_type_be(rettype)); (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
errmsg("return type mismatch in function declared to return %s",
format_type_be(rettype)),
errdetail("Function's final statement must be a SELECT.")));
return; return;
} }
@ -365,14 +383,21 @@ check_sql_fn_retval(Oid rettype, char fn_typtype, List *queryTreeList)
if (rettype == VOIDOID) if (rettype == VOIDOID)
{ {
if (cmd == CMD_SELECT) if (cmd == CMD_SELECT)
elog(ERROR, "function declared to return void, but final statement is a SELECT"); ereport(ERROR,
(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
errmsg("return type mismatch in function declared to return %s",
format_type_be(rettype)),
errdetail("Function's final statement must not be a SELECT.")));
return; return;
} }
/* by here, the function is declared to return some type */ /* by here, the function is declared to return some type */
if (cmd != CMD_SELECT) if (cmd != CMD_SELECT)
elog(ERROR, "function declared to return %s, but final statement is not a SELECT", ereport(ERROR,
format_type_be(rettype)); (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
errmsg("return type mismatch in function declared to return %s",
format_type_be(rettype)),
errdetail("Function's final statement must be a SELECT.")));
/* /*
* Count the non-junk entries in the result targetlist. * Count the non-junk entries in the result targetlist.
@ -392,13 +417,20 @@ check_sql_fn_retval(Oid rettype, char fn_typtype, List *queryTreeList)
* (As of Postgres 7.2, we accept binary-compatible types too.) * (As of Postgres 7.2, we accept binary-compatible types too.)
*/ */
if (tlistlen != 1) if (tlistlen != 1)
elog(ERROR, "function declared to return %s returns multiple columns in final SELECT", ereport(ERROR,
format_type_be(rettype)); (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
errmsg("return type mismatch in function declared to return %s",
format_type_be(rettype)),
errdetail("Final SELECT must return exactly one column.")));
restype = ((TargetEntry *) lfirst(tlist))->resdom->restype; restype = ((TargetEntry *) lfirst(tlist))->resdom->restype;
if (!IsBinaryCoercible(restype, rettype)) if (!IsBinaryCoercible(restype, rettype))
elog(ERROR, "return type mismatch in function: declared to return %s, returns %s", ereport(ERROR,
format_type_be(rettype), format_type_be(restype)); (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
errmsg("return type mismatch in function declared to return %s",
format_type_be(rettype)),
errdetail("Actual return type is %s.",
format_type_be(restype))));
} }
else if (fn_typtype == 'c') else if (fn_typtype == 'c')
{ {
@ -445,8 +477,11 @@ check_sql_fn_retval(Oid rettype, char fn_typtype, List *queryTreeList)
{ {
colindex++; colindex++;
if (colindex > relnatts) if (colindex > relnatts)
elog(ERROR, "function declared to return %s does not SELECT the right number of columns (%d)", ereport(ERROR,
format_type_be(rettype), rellogcols); (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
errmsg("return type mismatch in function declared to return %s",
format_type_be(rettype)),
errdetail("Final SELECT returns too many columns.")));
attr = reln->rd_att->attrs[colindex - 1]; attr = reln->rd_att->attrs[colindex - 1];
} while (attr->attisdropped); } while (attr->attisdropped);
rellogcols++; rellogcols++;
@ -454,11 +489,14 @@ check_sql_fn_retval(Oid rettype, char fn_typtype, List *queryTreeList)
tletype = exprType((Node *) tle->expr); tletype = exprType((Node *) tle->expr);
atttype = attr->atttypid; atttype = attr->atttypid;
if (!IsBinaryCoercible(tletype, atttype)) if (!IsBinaryCoercible(tletype, atttype))
elog(ERROR, "function declared to return %s returns %s instead of %s at column %d", ereport(ERROR,
format_type_be(rettype), (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
format_type_be(tletype), errmsg("return type mismatch in function declared to return %s",
format_type_be(atttype), format_type_be(rettype)),
rellogcols); errdetail("Final SELECT returns %s instead of %s at column %d.",
format_type_be(tletype),
format_type_be(atttype),
rellogcols)));
} }
for (;;) for (;;)
@ -471,8 +509,11 @@ check_sql_fn_retval(Oid rettype, char fn_typtype, List *queryTreeList)
} }
if (tlistlen != rellogcols) if (tlistlen != rellogcols)
elog(ERROR, "function declared to return %s does not SELECT the right number of columns (%d)", ereport(ERROR,
format_type_be(rettype), rellogcols); (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
errmsg("return type mismatch in function declared to return %s",
format_type_be(rettype)),
errdetail("Final SELECT returns too few columns.")));
relation_close(reln, AccessShareLock); relation_close(reln, AccessShareLock);
} }
@ -488,15 +529,16 @@ check_sql_fn_retval(Oid rettype, char fn_typtype, List *queryTreeList)
} }
else if (rettype == ANYARRAYOID || rettype == ANYELEMENTOID) else if (rettype == ANYARRAYOID || rettype == ANYELEMENTOID)
{ {
/* /* This should already have been caught ... */
* This should already have been caught ... ereport(ERROR,
*/ (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
elog(ERROR, "functions returning ANYARRAY or ANYELEMENT must " \ errmsg("functions returning ANYARRAY or ANYELEMENT must have at least one argument of either type")));
"have at least one argument of either type");
} }
else else
elog(ERROR, "return type %s is not supported for SQL functions", ereport(ERROR,
format_type_be(rettype)); (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
errmsg("return type %s is not supported for SQL functions",
format_type_be(rettype))));
} }
@ -521,7 +563,7 @@ fmgr_internal_validator(PG_FUNCTION_ARGS)
ObjectIdGetDatum(funcoid), ObjectIdGetDatum(funcoid),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(tuple)) if (!HeapTupleIsValid(tuple))
elog(ERROR, "cache lookup of function %u failed", funcoid); elog(ERROR, "cache lookup failed for function %u", funcoid);
proc = (Form_pg_proc) GETSTRUCT(tuple); proc = (Form_pg_proc) GETSTRUCT(tuple);
tmp = SysCacheGetAttr(PROCOID, tuple, Anum_pg_proc_prosrc, &isnull); tmp = SysCacheGetAttr(PROCOID, tuple, Anum_pg_proc_prosrc, &isnull);
@ -530,7 +572,10 @@ fmgr_internal_validator(PG_FUNCTION_ARGS)
prosrc = DatumGetCString(DirectFunctionCall1(textout, tmp)); prosrc = DatumGetCString(DirectFunctionCall1(textout, tmp));
if (fmgr_internal_function(prosrc) == InvalidOid) if (fmgr_internal_function(prosrc) == InvalidOid)
elog(ERROR, "there is no built-in function named \"%s\"", prosrc); ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_FUNCTION),
errmsg("there is no built-in function named \"%s\"",
prosrc)));
ReleaseSysCache(tuple); ReleaseSysCache(tuple);
@ -562,7 +607,7 @@ fmgr_c_validator(PG_FUNCTION_ARGS)
ObjectIdGetDatum(funcoid), ObjectIdGetDatum(funcoid),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(tuple)) if (!HeapTupleIsValid(tuple))
elog(ERROR, "cache lookup of function %u failed", funcoid); elog(ERROR, "cache lookup failed for function %u", funcoid);
proc = (Form_pg_proc) GETSTRUCT(tuple); proc = (Form_pg_proc) GETSTRUCT(tuple);
tmp = SysCacheGetAttr(PROCOID, tuple, Anum_pg_proc_prosrc, &isnull); tmp = SysCacheGetAttr(PROCOID, tuple, Anum_pg_proc_prosrc, &isnull);
@ -608,7 +653,7 @@ fmgr_sql_validator(PG_FUNCTION_ARGS)
ObjectIdGetDatum(funcoid), ObjectIdGetDatum(funcoid),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(tuple)) if (!HeapTupleIsValid(tuple))
elog(ERROR, "cache lookup of function %u failed", funcoid); elog(ERROR, "cache lookup failed for function %u", funcoid);
proc = (Form_pg_proc) GETSTRUCT(tuple); proc = (Form_pg_proc) GETSTRUCT(tuple);
functyptype = get_typtype(proc->prorettype); functyptype = get_typtype(proc->prorettype);
@ -620,8 +665,10 @@ fmgr_sql_validator(PG_FUNCTION_ARGS)
proc->prorettype != VOIDOID && proc->prorettype != VOIDOID &&
proc->prorettype != ANYARRAYOID && proc->prorettype != ANYARRAYOID &&
proc->prorettype != ANYELEMENTOID) proc->prorettype != ANYELEMENTOID)
elog(ERROR, "SQL functions cannot return type %s", ereport(ERROR,
format_type_be(proc->prorettype)); (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
errmsg("SQL functions cannot return type %s",
format_type_be(proc->prorettype))));
/* Disallow pseudotypes in arguments */ /* Disallow pseudotypes in arguments */
/* except for ANYARRAY or ANYELEMENT */ /* except for ANYARRAY or ANYELEMENT */
@ -634,8 +681,10 @@ fmgr_sql_validator(PG_FUNCTION_ARGS)
proc->proargtypes[i] == ANYELEMENTOID) proc->proargtypes[i] == ANYELEMENTOID)
haspolyarg = true; haspolyarg = true;
else else
elog(ERROR, "SQL functions cannot have arguments of type %s", ereport(ERROR,
format_type_be(proc->proargtypes[i])); (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
errmsg("SQL functions cannot have arguments of type %s",
format_type_be(proc->proargtypes[i]))));
} }
} }

View File

@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/dbcommands.c,v 1.116 2003/06/27 14:45:27 petere Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/dbcommands.c,v 1.117 2003/07/18 23:20:32 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -98,29 +98,37 @@ createdb(const CreatedbStmt *stmt)
if (strcmp(defel->defname, "owner") == 0) if (strcmp(defel->defname, "owner") == 0)
{ {
if (downer) if (downer)
elog(ERROR, "CREATE DATABASE: conflicting options"); ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("conflicting or redundant options")));
downer = defel; downer = defel;
} }
else if (strcmp(defel->defname, "location") == 0) else if (strcmp(defel->defname, "location") == 0)
{ {
if (dpath) if (dpath)
elog(ERROR, "CREATE DATABASE: conflicting options"); ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("conflicting or redundant options")));
dpath = defel; dpath = defel;
} }
else if (strcmp(defel->defname, "template") == 0) else if (strcmp(defel->defname, "template") == 0)
{ {
if (dtemplate) if (dtemplate)
elog(ERROR, "CREATE DATABASE: conflicting options"); ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("conflicting or redundant options")));
dtemplate = defel; dtemplate = defel;
} }
else if (strcmp(defel->defname, "encoding") == 0) else if (strcmp(defel->defname, "encoding") == 0)
{ {
if (dencoding) if (dencoding)
elog(ERROR, "CREATE DATABASE: conflicting options"); ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("conflicting or redundant options")));
dencoding = defel; dencoding = defel;
} }
else else
elog(ERROR, "CREATE DATABASE: option \"%s\" not recognized", elog(ERROR, "option \"%s\" not recognized",
defel->defname); defel->defname);
} }
@ -140,22 +148,29 @@ createdb(const CreatedbStmt *stmt)
encoding_name = pg_encoding_to_char(encoding); encoding_name = pg_encoding_to_char(encoding);
if (strcmp(encoding_name, "") == 0 || if (strcmp(encoding_name, "") == 0 ||
pg_valid_server_encoding(encoding_name) < 0) pg_valid_server_encoding(encoding_name) < 0)
elog(ERROR, "%d is not a valid encoding code", encoding); ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("%d is not a valid encoding code",
encoding)));
} }
else if (IsA(dencoding->arg, String)) else if (IsA(dencoding->arg, String))
{ {
encoding_name = strVal(dencoding->arg); encoding_name = strVal(dencoding->arg);
if (pg_valid_server_encoding(encoding_name) < 0) if (pg_valid_server_encoding(encoding_name) < 0)
elog(ERROR, "%s is not a valid encoding name", encoding_name); ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("%s is not a valid encoding name",
encoding_name)));
encoding = pg_char_to_encoding(encoding_name); encoding = pg_char_to_encoding(encoding_name);
} }
else else
elog(ERROR, "CREATE DATABASE: bogus encoding parameter"); elog(ERROR, "unrecognized node type: %d",
nodeTag(dencoding->arg));
} }
/* obtain sysid of proposed owner */ /* obtain sysid of proposed owner */
if (dbowner) if (dbowner)
datdba = get_usesysid(dbowner); /* will elog if no such user */ datdba = get_usesysid(dbowner); /* will ereport if no such user */
else else
datdba = GetUserId(); datdba = GetUserId();
@ -163,22 +178,29 @@ createdb(const CreatedbStmt *stmt)
{ {
/* creating database for self: can be superuser or createdb */ /* creating database for self: can be superuser or createdb */
if (!superuser() && !have_createdb_privilege()) if (!superuser() && !have_createdb_privilege())
elog(ERROR, "CREATE DATABASE: permission denied"); ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("permission denied")));
} }
else else
{ {
/* creating database for someone else: must be superuser */ /* creating database for someone else: must be superuser */
/* note that the someone else need not have any permissions */ /* note that the someone else need not have any permissions */
if (!superuser()) if (!superuser())
elog(ERROR, "CREATE DATABASE: permission denied"); ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("permission denied")));
} }
/* don't call this in a transaction block */ /* don't call this in a transaction block */
PreventTransactionChain((void *) stmt, "CREATE DATABASE"); PreventTransactionChain((void *) stmt, "CREATE DATABASE");
/* alternate location requires symlinks */
#ifndef HAVE_SYMLINK #ifndef HAVE_SYMLINK
if (dbpath != NULL) if (dbpath != NULL)
elog(ERROR, "CREATE DATABASE: may not use an alternate location on this platform"); ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("cannot use an alternate location on this platform")));
#endif #endif
/* /*
@ -190,7 +212,9 @@ createdb(const CreatedbStmt *stmt)
* after we grab the exclusive lock. * after we grab the exclusive lock.
*/ */
if (get_db_info(dbname, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL)) if (get_db_info(dbname, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL))
elog(ERROR, "CREATE DATABASE: database \"%s\" already exists", dbname); ereport(ERROR,
(errcode(ERRCODE_DUPLICATE_DATABASE),
errmsg("database \"%s\" already exists", dbname)));
/* /*
* Lookup database (template) to be cloned. * Lookup database (template) to be cloned.
@ -202,8 +226,9 @@ createdb(const CreatedbStmt *stmt)
&src_istemplate, &src_lastsysoid, &src_istemplate, &src_lastsysoid,
&src_vacuumxid, &src_frozenxid, &src_vacuumxid, &src_frozenxid,
src_dbpath)) src_dbpath))
elog(ERROR, "CREATE DATABASE: template \"%s\" does not exist", ereport(ERROR,
dbtemplate); (errcode(ERRCODE_UNDEFINED_DATABASE),
errmsg("template \"%s\" does not exist", dbtemplate)));
/* /*
* Permission check: to copy a DB that's not marked datistemplate, you * Permission check: to copy a DB that's not marked datistemplate, you
@ -212,8 +237,10 @@ createdb(const CreatedbStmt *stmt)
if (!src_istemplate) if (!src_istemplate)
{ {
if (!superuser() && GetUserId() != src_owner) if (!superuser() && GetUserId() != src_owner)
elog(ERROR, "CREATE DATABASE: permission to copy \"%s\" denied", ereport(ERROR,
dbtemplate); (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("permission to copy \"%s\" denied",
dbtemplate)));
} }
/* /*
@ -231,7 +258,10 @@ createdb(const CreatedbStmt *stmt)
* bulletproof, since someone might connect while we are copying... * bulletproof, since someone might connect while we are copying...
*/ */
if (DatabaseHasActiveBackends(src_dboid, true)) if (DatabaseHasActiveBackends(src_dboid, true))
elog(ERROR, "CREATE DATABASE: source database \"%s\" is being accessed by other users", dbtemplate); ereport(ERROR,
(errcode(ERRCODE_OBJECT_IN_USE),
errmsg("source database \"%s\" is being accessed by other users",
dbtemplate)));
/* If encoding is defaulted, use source's encoding */ /* If encoding is defaulted, use source's encoding */
if (encoding < 0) if (encoding < 0)
@ -239,7 +269,9 @@ createdb(const CreatedbStmt *stmt)
/* Some encodings are client only */ /* Some encodings are client only */
if (!PG_VALID_BE_ENCODING(encoding)) if (!PG_VALID_BE_ENCODING(encoding))
elog(ERROR, "CREATE DATABASE: invalid backend encoding"); ereport(ERROR,
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
errmsg("invalid backend encoding %d", encoding)));
/* /*
* Preassign OID for pg_database tuple, so that we can compute db * Preassign OID for pg_database tuple, so that we can compute db
@ -267,11 +299,17 @@ createdb(const CreatedbStmt *stmt)
} }
if (strchr(nominal_loc, '\'')) if (strchr(nominal_loc, '\''))
elog(ERROR, "database path may not contain single quotes"); ereport(ERROR,
(errcode(ERRCODE_INVALID_NAME),
errmsg("database path may not contain single quotes")));
if (alt_loc && strchr(alt_loc, '\'')) if (alt_loc && strchr(alt_loc, '\''))
elog(ERROR, "database path may not contain single quotes"); ereport(ERROR,
(errcode(ERRCODE_INVALID_NAME),
errmsg("database path may not contain single quotes")));
if (strchr(src_loc, '\'')) if (strchr(src_loc, '\''))
elog(ERROR, "database path may not contain single quotes"); ereport(ERROR,
(errcode(ERRCODE_INVALID_NAME),
errmsg("database path may not contain single quotes")));
/* ... otherwise we'd be open to shell exploits below */ /* ... otherwise we'd be open to shell exploits below */
/* /*
@ -294,11 +332,15 @@ createdb(const CreatedbStmt *stmt)
target_dir = alt_loc ? alt_loc : nominal_loc; target_dir = alt_loc ? alt_loc : nominal_loc;
if (mkdir(target_dir, S_IRWXU) != 0) if (mkdir(target_dir, S_IRWXU) != 0)
elog(ERROR, "CREATE DATABASE: unable to create database directory '%s': %m", ereport(ERROR,
target_dir); (errcode_for_file_access(),
errmsg("unable to create database directory \"%s\": %m",
target_dir)));
if (rmdir(target_dir) != 0) if (rmdir(target_dir) != 0)
elog(ERROR, "CREATE DATABASE: unable to remove temp directory '%s': %m", ereport(ERROR,
target_dir); (errcode_for_file_access(),
errmsg("unable to remove temp directory \"%s\": %m",
target_dir)));
/* Make the symlink, if needed */ /* Make the symlink, if needed */
if (alt_loc) if (alt_loc)
@ -306,8 +348,10 @@ createdb(const CreatedbStmt *stmt)
#ifdef HAVE_SYMLINK /* already throws error above */ #ifdef HAVE_SYMLINK /* already throws error above */
if (symlink(alt_loc, nominal_loc) != 0) if (symlink(alt_loc, nominal_loc) != 0)
#endif #endif
elog(ERROR, "CREATE DATABASE: could not link '%s' to '%s': %m", ereport(ERROR,
nominal_loc, alt_loc); (errcode_for_file_access(),
errmsg("could not link \"%s\" to \"%s\": %m",
nominal_loc, alt_loc)));
} }
/* Copy the template database to the new location */ /* Copy the template database to the new location */
@ -319,9 +363,9 @@ createdb(const CreatedbStmt *stmt)
#endif #endif
{ {
if (remove_dbdirs(nominal_loc, alt_loc)) if (remove_dbdirs(nominal_loc, alt_loc))
elog(ERROR, "CREATE DATABASE: could not initialize database directory"); elog(ERROR, "could not initialize database directory");
else else
elog(ERROR, "CREATE DATABASE: could not initialize database directory; delete failed as well"); elog(ERROR, "could not initialize database directory; delete failed as well");
} }
/* /*
@ -335,7 +379,9 @@ createdb(const CreatedbStmt *stmt)
/* Don't hold lock while doing recursive remove */ /* Don't hold lock while doing recursive remove */
heap_close(pg_database_rel, AccessExclusiveLock); heap_close(pg_database_rel, AccessExclusiveLock);
remove_dbdirs(nominal_loc, alt_loc); remove_dbdirs(nominal_loc, alt_loc);
elog(ERROR, "CREATE DATABASE: database \"%s\" already exists", dbname); ereport(ERROR,
(errcode(ERRCODE_DUPLICATE_DATABASE),
errmsg("database \"%s\" already exists", dbname)));
} }
/* /*
@ -411,7 +457,9 @@ dropdb(const char *dbname)
AssertArg(dbname); AssertArg(dbname);
if (strcmp(dbname, get_database_name(MyDatabaseId)) == 0) if (strcmp(dbname, get_database_name(MyDatabaseId)) == 0)
elog(ERROR, "DROP DATABASE: cannot be executed on the currently open database"); ereport(ERROR,
(errcode(ERRCODE_OBJECT_IN_USE),
errmsg("cannot drop the currently open database")));
PreventTransactionChain((void *) dbname, "DROP DATABASE"); PreventTransactionChain((void *) dbname, "DROP DATABASE");
@ -428,10 +476,14 @@ dropdb(const char *dbname)
if (!get_db_info(dbname, &db_id, &db_owner, NULL, if (!get_db_info(dbname, &db_id, &db_owner, NULL,
&db_istemplate, NULL, NULL, NULL, dbpath)) &db_istemplate, NULL, NULL, NULL, dbpath))
elog(ERROR, "DROP DATABASE: database \"%s\" does not exist", dbname); ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_DATABASE),
errmsg("database \"%s\" does not exist", dbname)));
if (GetUserId() != db_owner && !superuser()) if (GetUserId() != db_owner && !superuser())
elog(ERROR, "DROP DATABASE: permission denied"); ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("permission denied")));
/* /*
* Disallow dropping a DB that is marked istemplate. This is just to * Disallow dropping a DB that is marked istemplate. This is just to
@ -439,7 +491,9 @@ dropdb(const char *dbname)
* they can do so if they're really determined ... * they can do so if they're really determined ...
*/ */
if (db_istemplate) if (db_istemplate)
elog(ERROR, "DROP DATABASE: database is marked as a template"); ereport(ERROR,
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
errmsg("cannot drop a template database")));
nominal_loc = GetDatabasePath(db_id); nominal_loc = GetDatabasePath(db_id);
alt_loc = resolve_alt_dbpath(dbpath, db_id); alt_loc = resolve_alt_dbpath(dbpath, db_id);
@ -448,7 +502,10 @@ dropdb(const char *dbname)
* Check for active backends in the target database. * Check for active backends in the target database.
*/ */
if (DatabaseHasActiveBackends(db_id, false)) if (DatabaseHasActiveBackends(db_id, false))
elog(ERROR, "DROP DATABASE: database \"%s\" is being accessed by other users", dbname); ereport(ERROR,
(errcode(ERRCODE_OBJECT_IN_USE),
errmsg("database \"%s\" is being accessed by other users",
dbname)));
/* /*
* Find the database's tuple by OID (should be unique). * Find the database's tuple by OID (should be unique).
@ -465,7 +522,7 @@ dropdb(const char *dbname)
* This error should never come up since the existence of the * This error should never come up since the existence of the
* database is checked earlier * database is checked earlier
*/ */
elog(ERROR, "DROP DATABASE: Database \"%s\" doesn't exist despite earlier reports to the contrary", elog(ERROR, "database \"%s\" doesn't exist despite earlier reports to the contrary",
dbname); dbname);
} }
@ -539,7 +596,7 @@ RenameDatabase(const char *oldname, const char *newname)
tup = systable_getnext(scan); tup = systable_getnext(scan);
if (!HeapTupleIsValid(tup)) if (!HeapTupleIsValid(tup))
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR_OR_ACCESS_RULE_VIOLATION), (errcode(ERRCODE_UNDEFINED_DATABASE),
errmsg("database \"%s\" does not exist", oldname))); errmsg("database \"%s\" does not exist", oldname)));
/* /*
@ -550,7 +607,7 @@ RenameDatabase(const char *oldname, const char *newname)
*/ */
if (HeapTupleGetOid(tup) == MyDatabaseId) if (HeapTupleGetOid(tup) == MyDatabaseId)
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR_OR_ACCESS_RULE_VIOLATION), (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("current database may not be renamed"))); errmsg("current database may not be renamed")));
/* /*
@ -559,18 +616,19 @@ RenameDatabase(const char *oldname, const char *newname)
* operations. * operations.
*/ */
if (DatabaseHasActiveBackends(HeapTupleGetOid(tup), false)) if (DatabaseHasActiveBackends(HeapTupleGetOid(tup), false))
elog(ERROR, "database \"%s\" is being accessed by other users", oldname); ereport(ERROR,
(errcode(ERRCODE_OBJECT_IN_USE),
errmsg("database \"%s\" is being accessed by other users",
oldname)));
/* make sure the new name doesn't exist */ /* make sure the new name doesn't exist */
ScanKeyEntryInitialize(&key2, 0, Anum_pg_database_datname, ScanKeyEntryInitialize(&key2, 0, Anum_pg_database_datname,
F_NAMEEQ, NameGetDatum(newname)); F_NAMEEQ, NameGetDatum(newname));
scan2 = systable_beginscan(rel, DatabaseNameIndex, true, SnapshotNow, 1, &key2); scan2 = systable_beginscan(rel, DatabaseNameIndex, true, SnapshotNow, 1, &key2);
if (HeapTupleIsValid(systable_getnext(scan2))) if (HeapTupleIsValid(systable_getnext(scan2)))
{
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR_OR_ACCESS_RULE_VIOLATION), (errcode(ERRCODE_DUPLICATE_DATABASE),
errmsg("database \"%s\" already exists", newname))); errmsg("database \"%s\" already exists", newname)));
}
systable_endscan(scan2); systable_endscan(scan2);
/* must be owner */ /* must be owner */
@ -579,11 +637,9 @@ RenameDatabase(const char *oldname, const char *newname)
/* must have createdb */ /* must have createdb */
if (!have_createdb_privilege()) if (!have_createdb_privilege())
{
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR_OR_ACCESS_RULE_VIOLATION), (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("permission denied"))); errmsg("permission denied")));
}
/* rename */ /* rename */
newtup = heap_copytuple(tup); newtup = heap_copytuple(tup);
@ -628,11 +684,15 @@ AlterDatabaseSet(AlterDatabaseSetStmt *stmt)
scan = systable_beginscan(rel, DatabaseNameIndex, true, SnapshotNow, 1, &scankey); scan = systable_beginscan(rel, DatabaseNameIndex, true, SnapshotNow, 1, &scankey);
tuple = systable_getnext(scan); tuple = systable_getnext(scan);
if (!HeapTupleIsValid(tuple)) if (!HeapTupleIsValid(tuple))
elog(ERROR, "database \"%s\" does not exist", stmt->dbname); ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_DATABASE),
errmsg("database \"%s\" does not exist", stmt->dbname)));
if (!(superuser() if (!(superuser()
|| ((Form_pg_database) GETSTRUCT(tuple))->datdba == GetUserId())) || ((Form_pg_database) GETSTRUCT(tuple))->datdba == GetUserId()))
elog(ERROR, "ALTER DATABASE SET: permission denied"); ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("permission denied")));
MemSet(repl_repl, ' ', sizeof(repl_repl)); MemSet(repl_repl, ' ', sizeof(repl_repl));
repl_repl[Anum_pg_database_datconfig - 1] = 'r'; repl_repl[Anum_pg_database_datconfig - 1] = 'r';
@ -797,9 +857,13 @@ resolve_alt_dbpath(const char *dbpath, Oid dboid)
if (first_path_separator(dbpath)) if (first_path_separator(dbpath))
{ {
if (!is_absolute_path(dbpath)) if (!is_absolute_path(dbpath))
elog(ERROR, "Relative paths are not allowed as database locations"); ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("relative paths are not allowed as database locations")));
#ifndef ALLOW_ABSOLUTE_DBPATHS #ifndef ALLOW_ABSOLUTE_DBPATHS
elog(ERROR, "Absolute paths are not allowed as database locations"); ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("absolute paths are not allowed as database locations")));
#endif #endif
prefix = dbpath; prefix = dbpath;
} }
@ -809,15 +873,23 @@ resolve_alt_dbpath(const char *dbpath, Oid dboid)
char *var = getenv(dbpath); char *var = getenv(dbpath);
if (!var) if (!var)
elog(ERROR, "Postmaster environment variable '%s' not set", dbpath); ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("postmaster environment variable \"%s\" not found",
dbpath)));
if (!is_absolute_path(var)) if (!is_absolute_path(var))
elog(ERROR, "Postmaster environment variable '%s' must be absolute path", dbpath); ereport(ERROR,
(errcode(ERRCODE_INVALID_NAME),
errmsg("postmaster environment variable \"%s\" must be absolute path",
dbpath)));
prefix = var; prefix = var;
} }
len = strlen(prefix) + 6 + sizeof(Oid) * 8 + 1; len = strlen(prefix) + 6 + sizeof(Oid) * 8 + 1;
if (len >= MAXPGPATH - 100) if (len >= MAXPGPATH - 100)
elog(ERROR, "Alternate path is too long"); ereport(ERROR,
(errcode(ERRCODE_INVALID_NAME),
errmsg("alternate path is too long")));
ret = palloc(len); ret = palloc(len);
snprintf(ret, len, "%s/base/%u", prefix, dboid); snprintf(ret, len, "%s/base/%u", prefix, dboid);
@ -846,7 +918,9 @@ remove_dbdirs(const char *nominal_loc, const char *alt_loc)
/* remove symlink */ /* remove symlink */
if (unlink(nominal_loc) != 0) if (unlink(nominal_loc) != 0)
{ {
elog(WARNING, "could not remove '%s': %m", nominal_loc); ereport(WARNING,
(errcode_for_file_access(),
errmsg("could not remove \"%s\": %m", nominal_loc)));
success = false; success = false;
} }
} }
@ -859,8 +933,10 @@ remove_dbdirs(const char *nominal_loc, const char *alt_loc)
if (system(buf) != 0) if (system(buf) != 0)
{ {
elog(WARNING, "database directory '%s' could not be removed", ereport(WARNING,
target_dir); (errcode_for_file_access(),
errmsg("could not remove database directory \"%s\": %m",
target_dir)));
success = false; success = false;
} }

View File

@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/functioncmds.c,v 1.27 2003/07/04 02:51:33 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/functioncmds.c,v 1.28 2003/07/18 23:20:32 tgl Exp $
* *
* DESCRIPTION * DESCRIPTION
* These routines take the parse tree and pick out the * These routines take the parse tree and pick out the
@ -78,11 +78,15 @@ compute_return_type(TypeName *returnType, Oid languageOid,
if (!get_typisdefined(rettype)) if (!get_typisdefined(rettype))
{ {
if (languageOid == SQLlanguageId) if (languageOid == SQLlanguageId)
elog(ERROR, "SQL function cannot return shell type \"%s\"", ereport(ERROR,
TypeNameToString(returnType)); (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
errmsg("SQL function cannot return shell type %s",
TypeNameToString(returnType))));
else else
elog(NOTICE, "Return type \"%s\" is only a shell", ereport(NOTICE,
TypeNameToString(returnType)); (errcode(ERRCODE_WRONG_OBJECT_TYPE),
errmsg("return type %s is only a shell",
TypeNameToString(returnType))));
} }
} }
else else
@ -100,11 +104,15 @@ compute_return_type(TypeName *returnType, Oid languageOid,
*/ */
if (languageOid != INTERNALlanguageId && if (languageOid != INTERNALlanguageId &&
languageOid != ClanguageId) languageOid != ClanguageId)
elog(ERROR, "Type \"%s\" does not exist", typnam); ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("type %s does not exist", typnam)));
/* Otherwise, go ahead and make a shell type */ /* Otherwise, go ahead and make a shell type */
elog(NOTICE, "ProcedureCreate: type %s is not yet defined", ereport(NOTICE,
typnam); (errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("type %s is not yet defined", typnam),
errdetail("Creating a shell type definition.")));
namespaceId = QualifiedNameGetCreationNamespace(returnType->names, namespaceId = QualifiedNameGetCreationNamespace(returnType->names,
&typname); &typname);
aclresult = pg_namespace_aclcheck(namespaceId, GetUserId(), aclresult = pg_namespace_aclcheck(namespaceId, GetUserId(),
@ -112,8 +120,7 @@ compute_return_type(TypeName *returnType, Oid languageOid,
if (aclresult != ACLCHECK_OK) if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, get_namespace_name(namespaceId)); aclcheck_error(aclresult, get_namespace_name(namespaceId));
rettype = TypeShellMake(typname, namespaceId); rettype = TypeShellMake(typname, namespaceId);
if (!OidIsValid(rettype)) Assert(OidIsValid(rettype));
elog(ERROR, "could not create type %s", typnam);
} }
*prorettype_p = rettype; *prorettype_p = rettype;
@ -137,8 +144,10 @@ compute_parameter_types(List *argTypes, Oid languageOid,
Oid toid; Oid toid;
if (parameterCount >= FUNC_MAX_ARGS) if (parameterCount >= FUNC_MAX_ARGS)
elog(ERROR, "functions cannot have more than %d arguments", ereport(ERROR,
FUNC_MAX_ARGS); (errcode(ERRCODE_TOO_MANY_ARGUMENTS),
errmsg("functions cannot have more than %d arguments",
FUNC_MAX_ARGS)));
toid = LookupTypeName(t); toid = LookupTypeName(t);
if (OidIsValid(toid)) if (OidIsValid(toid))
@ -147,21 +156,29 @@ compute_parameter_types(List *argTypes, Oid languageOid,
{ {
/* As above, hard error if language is SQL */ /* As above, hard error if language is SQL */
if (languageOid == SQLlanguageId) if (languageOid == SQLlanguageId)
elog(ERROR, "SQL function cannot accept shell type \"%s\"", ereport(ERROR,
TypeNameToString(t)); (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
errmsg("SQL function cannot accept shell type %s",
TypeNameToString(t))));
else else
elog(NOTICE, "Argument type \"%s\" is only a shell", ereport(NOTICE,
TypeNameToString(t)); (errcode(ERRCODE_WRONG_OBJECT_TYPE),
errmsg("argument type %s is only a shell",
TypeNameToString(t))));
} }
} }
else else
{ {
elog(ERROR, "Type \"%s\" does not exist", ereport(ERROR,
TypeNameToString(t)); (errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("type %s does not exist",
TypeNameToString(t))));
} }
if (t->setof) if (t->setof)
elog(ERROR, "Functions cannot accept set arguments"); ereport(ERROR,
(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
errmsg("functions cannot accept set arguments")));
parameterTypes[parameterCount++] = toid; parameterTypes[parameterCount++] = toid;
} }
@ -197,46 +214,61 @@ compute_attributes_sql_style(const List *options,
if (strcmp(defel->defname, "as") == 0) if (strcmp(defel->defname, "as") == 0)
{ {
if (as_item) if (as_item)
elog(ERROR, "conflicting or redundant options"); ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("conflicting or redundant options")));
as_item = defel; as_item = defel;
} }
else if (strcmp(defel->defname, "language") == 0) else if (strcmp(defel->defname, "language") == 0)
{ {
if (language_item) if (language_item)
elog(ERROR, "conflicting or redundant options"); ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("conflicting or redundant options")));
language_item = defel; language_item = defel;
} }
else if (strcmp(defel->defname, "volatility") == 0) else if (strcmp(defel->defname, "volatility") == 0)
{ {
if (volatility_item) if (volatility_item)
elog(ERROR, "conflicting or redundant options"); ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("conflicting or redundant options")));
volatility_item = defel; volatility_item = defel;
} }
else if (strcmp(defel->defname, "strict") == 0) else if (strcmp(defel->defname, "strict") == 0)
{ {
if (strict_item) if (strict_item)
elog(ERROR, "conflicting or redundant options"); ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("conflicting or redundant options")));
strict_item = defel; strict_item = defel;
} }
else if (strcmp(defel->defname, "security") == 0) else if (strcmp(defel->defname, "security") == 0)
{ {
if (security_item) if (security_item)
elog(ERROR, "conflicting or redundant options"); ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("conflicting or redundant options")));
security_item = defel; security_item = defel;
} }
else else
elog(ERROR, "invalid CREATE FUNCTION option"); elog(ERROR, "option \"%s\" not recognized",
defel->defname);
} }
if (as_item) if (as_item)
*as = (List *) as_item->arg; *as = (List *) as_item->arg;
else else
elog(ERROR, "no function body specified"); ereport(ERROR,
(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
errmsg("no function body specified")));
if (language_item) if (language_item)
*language = strVal(language_item->arg); *language = strVal(language_item->arg);
else else
elog(ERROR, "no language specified"); ereport(ERROR,
(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
errmsg("no language specified")));
if (volatility_item) if (volatility_item)
{ {
@ -247,7 +279,8 @@ compute_attributes_sql_style(const List *options,
else if (strcmp(strVal(volatility_item->arg), "volatile") == 0) else if (strcmp(strVal(volatility_item->arg), "volatile") == 0)
*volatility_p = PROVOLATILE_VOLATILE; *volatility_p = PROVOLATILE_VOLATILE;
else else
elog(ERROR, "invalid volatility"); elog(ERROR, "invalid volatility \"%s\"",
strVal(volatility_item->arg));
} }
if (strict_item) if (strict_item)
@ -294,8 +327,10 @@ compute_attributes_with_style(List *parameters, bool *isStrict_p, char *volatili
*volatility_p = PROVOLATILE_IMMUTABLE; *volatility_p = PROVOLATILE_IMMUTABLE;
} }
else else
elog(WARNING, "Unrecognized function attribute '%s' ignored", ereport(WARNING,
param->defname); (errcode(ERRCODE_SYNTAX_ERROR),
errmsg("unrecognized function attribute \"%s\" ignored",
param->defname)));
} }
} }
@ -336,8 +371,10 @@ interpret_AS_clause(Oid languageOid, const char *languageName, const List *as,
*probin_str_p = "-"; *probin_str_p = "-";
if (lnext(as) != NIL) if (lnext(as) != NIL)
elog(ERROR, "CREATE FUNCTION: only one AS item needed for %s language", ereport(ERROR,
languageName); (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
errmsg("only one AS item needed for language \"%s\"",
languageName)));
} }
} }
@ -396,7 +433,9 @@ CreateFunction(CreateFunctionStmt *stmt)
PointerGetDatum(languageName), PointerGetDatum(languageName),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(languageTuple)) if (!HeapTupleIsValid(languageTuple))
elog(ERROR, "language \"%s\" does not exist", languageName); ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("language \"%s\" does not exist", languageName)));
languageOid = HeapTupleGetOid(languageTuple); languageOid = HeapTupleGetOid(languageTuple);
languageStruct = (Form_pg_language) GETSTRUCT(languageTuple); languageStruct = (Form_pg_language) GETSTRUCT(languageTuple);
@ -501,8 +540,7 @@ RemoveFunction(RemoveFuncStmt *stmt)
ObjectIdGetDatum(funcOid), ObjectIdGetDatum(funcOid),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(tup)) /* should not happen */ if (!HeapTupleIsValid(tup)) /* should not happen */
elog(ERROR, "RemoveFunction: couldn't find tuple for function %s", elog(ERROR, "cache lookup failed for function %u", funcOid);
NameListToString(functionName));
/* Permission check: must own func or its namespace */ /* Permission check: must own func or its namespace */
if (!pg_proc_ownercheck(funcOid, GetUserId()) && if (!pg_proc_ownercheck(funcOid, GetUserId()) &&
@ -511,15 +549,19 @@ RemoveFunction(RemoveFuncStmt *stmt)
aclcheck_error(ACLCHECK_NOT_OWNER, NameListToString(functionName)); aclcheck_error(ACLCHECK_NOT_OWNER, NameListToString(functionName));
if (((Form_pg_proc) GETSTRUCT(tup))->proisagg) if (((Form_pg_proc) GETSTRUCT(tup))->proisagg)
elog(ERROR, "RemoveFunction: function '%s' is an aggregate" ereport(ERROR,
"\n\tUse DROP AGGREGATE to remove it", (errcode(ERRCODE_WRONG_OBJECT_TYPE),
NameListToString(functionName)); errmsg("\"%s\" is an aggregate function",
NameListToString(functionName)),
errhint("Use DROP AGGREGATE to drop aggregate functions.")));
if (((Form_pg_proc) GETSTRUCT(tup))->prolang == INTERNALlanguageId) if (((Form_pg_proc) GETSTRUCT(tup))->prolang == INTERNALlanguageId)
{ {
/* "Helpful" NOTICE when removing a builtin function ... */ /* "Helpful" NOTICE when removing a builtin function ... */
elog(NOTICE, "Removing built-in function \"%s\"", ereport(NOTICE,
NameListToString(functionName)); (errcode(ERRCODE_WARNING),
errmsg("removing built-in function \"%s\"",
NameListToString(functionName))));
} }
ReleaseSysCache(tup); ReleaseSysCache(tup);
@ -556,8 +598,7 @@ RemoveFunctionById(Oid funcOid)
ObjectIdGetDatum(funcOid), ObjectIdGetDatum(funcOid),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(tup)) /* should not happen */ if (!HeapTupleIsValid(tup)) /* should not happen */
elog(ERROR, "RemoveFunctionById: couldn't find tuple for function %u", elog(ERROR, "cache lookup failed for function %u", funcOid);
funcOid);
isagg = ((Form_pg_proc) GETSTRUCT(tup))->proisagg; isagg = ((Form_pg_proc) GETSTRUCT(tup))->proisagg;
@ -578,8 +619,7 @@ RemoveFunctionById(Oid funcOid)
ObjectIdGetDatum(funcOid), ObjectIdGetDatum(funcOid),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(tup)) /* should not happen */ if (!HeapTupleIsValid(tup)) /* should not happen */
elog(ERROR, "RemoveFunctionById: couldn't find pg_aggregate tuple for %u", elog(ERROR, "cache lookup failed for pg_aggregate tuple for function %u", funcOid);
funcOid);
simple_heap_delete(relation, &tup->t_self); simple_heap_delete(relation, &tup->t_self);
@ -598,11 +638,10 @@ RenameFunction(List *name, List *argtypes, const char *newname)
{ {
Oid procOid; Oid procOid;
Oid namespaceOid; Oid namespaceOid;
Oid oid_array[FUNC_MAX_ARGS];
HeapTuple tup; HeapTuple tup;
Form_pg_proc procForm;
Relation rel; Relation rel;
AclResult aclresult; AclResult aclresult;
int16 nargs;
rel = heap_openr(ProcedureRelationName, RowExclusiveLock); rel = heap_openr(ProcedureRelationName, RowExclusiveLock);
@ -612,29 +651,31 @@ RenameFunction(List *name, List *argtypes, const char *newname)
ObjectIdGetDatum(procOid), ObjectIdGetDatum(procOid),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(tup)) /* should not happen */ if (!HeapTupleIsValid(tup)) /* should not happen */
elog(ERROR, "RenameFunction: couldn't find pg_proc tuple for %s", elog(ERROR, "cache lookup failed for function %u", procOid);
NameListToString(name)); procForm = (Form_pg_proc) GETSTRUCT(tup);
if (((Form_pg_proc) GETSTRUCT(tup))->proisagg) if (procForm->proisagg)
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR_OR_ACCESS_RULE_VIOLATION), (errcode(ERRCODE_WRONG_OBJECT_TYPE),
errmsg("%s is an aggregate function", NameListToString(name)), errmsg("\"%s\" is an aggregate function",
NameListToString(name)),
errhint("Use ALTER AGGREGATE to rename aggregate functions."))); errhint("Use ALTER AGGREGATE to rename aggregate functions.")));
namespaceOid = ((Form_pg_proc) GETSTRUCT(tup))->pronamespace; namespaceOid = procForm->pronamespace;
/* make sure the new name doesn't exist */ /* make sure the new name doesn't exist */
nargs = compute_parameter_types(argtypes, ((Form_pg_proc) GETSTRUCT(tup))->prolang, oid_array);
if (SearchSysCacheExists(PROCNAMENSP, if (SearchSysCacheExists(PROCNAMENSP,
CStringGetDatum(newname), CStringGetDatum(newname),
Int16GetDatum(nargs), Int16GetDatum(procForm->pronargs),
PointerGetDatum(oid_array), PointerGetDatum(procForm->proargtypes),
ObjectIdGetDatum(namespaceOid))) ObjectIdGetDatum(namespaceOid)))
{ {
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR_OR_ACCESS_RULE_VIOLATION), (errcode(ERRCODE_DUPLICATE_FUNCTION),
errmsg("function %s with the same argument types already exists in schema %s", errmsg("function %s already exists",
newname, get_namespace_name(namespaceOid)))); func_signature_string(name,
procForm->pronargs,
procForm->proargtypes))));
} }
/* must be owner */ /* must be owner */
@ -647,7 +688,7 @@ RenameFunction(List *name, List *argtypes, const char *newname)
aclcheck_error(aclresult, get_namespace_name(namespaceOid)); aclcheck_error(aclresult, get_namespace_name(namespaceOid));
/* rename */ /* rename */
namestrcpy(&(((Form_pg_proc) GETSTRUCT(tup))->proname), newname); namestrcpy(&(procForm->proname), newname);
simple_heap_update(rel, &tup->t_self, tup); simple_heap_update(rel, &tup->t_self, tup);
CatalogUpdateIndexes(rel, tup); CatalogUpdateIndexes(rel, tup);
@ -676,13 +717,11 @@ SetFunctionReturnType(Oid funcOid, Oid newRetType)
ObjectIdGetDatum(funcOid), ObjectIdGetDatum(funcOid),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(tup)) /* should not happen */ if (!HeapTupleIsValid(tup)) /* should not happen */
elog(ERROR, "SetFunctionReturnType: couldn't find tuple for function %u", elog(ERROR, "cache lookup failed for function %u", funcOid);
funcOid);
procForm = (Form_pg_proc) GETSTRUCT(tup); procForm = (Form_pg_proc) GETSTRUCT(tup);
if (procForm->prorettype != OPAQUEOID) if (procForm->prorettype != OPAQUEOID) /* caller messed up */
elog(ERROR, "SetFunctionReturnType: function %u doesn't return OPAQUE", elog(ERROR, "function %u doesn't return OPAQUE", funcOid);
funcOid);
/* okay to overwrite copied tuple */ /* okay to overwrite copied tuple */
procForm->prorettype = newRetType; procForm->prorettype = newRetType;
@ -714,14 +753,12 @@ SetFunctionArgType(Oid funcOid, int argIndex, Oid newArgType)
ObjectIdGetDatum(funcOid), ObjectIdGetDatum(funcOid),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(tup)) /* should not happen */ if (!HeapTupleIsValid(tup)) /* should not happen */
elog(ERROR, "SetFunctionArgType: couldn't find tuple for function %u", elog(ERROR, "cache lookup failed for function %u", funcOid);
funcOid);
procForm = (Form_pg_proc) GETSTRUCT(tup); procForm = (Form_pg_proc) GETSTRUCT(tup);
if (argIndex < 0 || argIndex >= procForm->pronargs || if (argIndex < 0 || argIndex >= procForm->pronargs ||
procForm->proargtypes[argIndex] != OPAQUEOID) procForm->proargtypes[argIndex] != OPAQUEOID)
elog(ERROR, "SetFunctionArgType: function %u doesn't take OPAQUE", elog(ERROR, "function %u doesn't take OPAQUE", funcOid);
funcOid);
/* okay to overwrite copied tuple */ /* okay to overwrite copied tuple */
procForm->proargtypes[argIndex] = newArgType; procForm->proargtypes[argIndex] = newArgType;
@ -755,39 +792,56 @@ CreateCast(CreateCastStmt *stmt)
sourcetypeid = LookupTypeName(stmt->sourcetype); sourcetypeid = LookupTypeName(stmt->sourcetype);
if (!OidIsValid(sourcetypeid)) if (!OidIsValid(sourcetypeid))
elog(ERROR, "source data type %s does not exist", ereport(ERROR,
TypeNameToString(stmt->sourcetype)); (errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("source data type %s does not exist",
TypeNameToString(stmt->sourcetype))));
targettypeid = LookupTypeName(stmt->targettype); targettypeid = LookupTypeName(stmt->targettype);
if (!OidIsValid(targettypeid)) if (!OidIsValid(targettypeid))
elog(ERROR, "target data type %s does not exist", ereport(ERROR,
TypeNameToString(stmt->targettype)); (errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("target data type %s does not exist",
TypeNameToString(stmt->targettype))));
if (sourcetypeid == targettypeid) if (sourcetypeid == targettypeid)
elog(ERROR, "source data type and target data type are the same"); ereport(ERROR,
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
errmsg("source data type and target data type are the same")));
/* No shells, no pseudo-types allowed */ /* No shells, no pseudo-types allowed */
if (!get_typisdefined(sourcetypeid)) if (!get_typisdefined(sourcetypeid))
elog(ERROR, "source data type %s is only a shell", ereport(ERROR,
TypeNameToString(stmt->sourcetype)); (errcode(ERRCODE_WRONG_OBJECT_TYPE),
errmsg("source data type %s is only a shell",
TypeNameToString(stmt->sourcetype))));
if (!get_typisdefined(targettypeid)) if (!get_typisdefined(targettypeid))
elog(ERROR, "target data type %s is only a shell", ereport(ERROR,
TypeNameToString(stmt->targettype)); (errcode(ERRCODE_WRONG_OBJECT_TYPE),
errmsg("target data type %s is only a shell",
TypeNameToString(stmt->targettype))));
if (get_typtype(sourcetypeid) == 'p') if (get_typtype(sourcetypeid) == 'p')
elog(ERROR, "source data type %s is a pseudo-type", ereport(ERROR,
TypeNameToString(stmt->sourcetype)); (errcode(ERRCODE_WRONG_OBJECT_TYPE),
errmsg("source data type %s is a pseudo-type",
TypeNameToString(stmt->sourcetype))));
if (get_typtype(targettypeid) == 'p') if (get_typtype(targettypeid) == 'p')
elog(ERROR, "target data type %s is a pseudo-type", ereport(ERROR,
TypeNameToString(stmt->targettype)); (errcode(ERRCODE_WRONG_OBJECT_TYPE),
errmsg("target data type %s is a pseudo-type",
TypeNameToString(stmt->targettype))));
/* Permission check */
if (!pg_type_ownercheck(sourcetypeid, GetUserId()) if (!pg_type_ownercheck(sourcetypeid, GetUserId())
&& !pg_type_ownercheck(targettypeid, GetUserId())) && !pg_type_ownercheck(targettypeid, GetUserId()))
elog(ERROR, "must be owner of type %s or type %s", ereport(ERROR,
TypeNameToString(stmt->sourcetype), (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
TypeNameToString(stmt->targettype)); errmsg("must be owner of type %s or type %s",
TypeNameToString(stmt->sourcetype),
TypeNameToString(stmt->targettype))));
if (stmt->func != NULL) if (stmt->func != NULL)
{ {
@ -801,15 +855,21 @@ CreateCast(CreateCastStmt *stmt)
ObjectIdGetDatum(funcid), ObjectIdGetDatum(funcid),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(tuple)) if (!HeapTupleIsValid(tuple))
elog(ERROR, "cache lookup of function %u failed", funcid); elog(ERROR, "cache lookup failed for function %u", funcid);
procstruct = (Form_pg_proc) GETSTRUCT(tuple); procstruct = (Form_pg_proc) GETSTRUCT(tuple);
if (procstruct->pronargs != 1) if (procstruct->pronargs != 1)
elog(ERROR, "cast function must take 1 argument"); ereport(ERROR,
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
errmsg("cast function must take 1 argument")));
if (procstruct->proargtypes[0] != sourcetypeid) if (procstruct->proargtypes[0] != sourcetypeid)
elog(ERROR, "argument of cast function must match source data type"); ereport(ERROR,
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
errmsg("argument of cast function must match source data type")));
if (procstruct->prorettype != targettypeid) if (procstruct->prorettype != targettypeid)
elog(ERROR, "return data type of cast function must match target data type"); ereport(ERROR,
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
errmsg("return data type of cast function must match target data type")));
/* /*
* Restricting the volatility of a cast function may or may not be * Restricting the volatility of a cast function may or may not be
* a good idea in the abstract, but it definitely breaks many old * a good idea in the abstract, but it definitely breaks many old
@ -817,12 +877,18 @@ CreateCast(CreateCastStmt *stmt)
*/ */
#ifdef NOT_USED #ifdef NOT_USED
if (procstruct->provolatile == PROVOLATILE_VOLATILE) if (procstruct->provolatile == PROVOLATILE_VOLATILE)
elog(ERROR, "cast function must not be volatile"); ereport(ERROR,
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
errmsg("cast function must not be volatile")));
#endif #endif
if (procstruct->proisagg) if (procstruct->proisagg)
elog(ERROR, "cast function must not be an aggregate function"); ereport(ERROR,
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
errmsg("cast function must not be an aggregate function")));
if (procstruct->proretset) if (procstruct->proretset)
elog(ERROR, "cast function must not return a set"); ereport(ERROR,
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
errmsg("cast function must not return a set")));
ReleaseSysCache(tuple); ReleaseSysCache(tuple);
} }
@ -843,7 +909,9 @@ CreateCast(CreateCastStmt *stmt)
* erroneous casts can easily crash the backend. * erroneous casts can easily crash the backend.
*/ */
if (!superuser()) if (!superuser())
elog(ERROR, "Must be superuser to create a cast WITHOUT FUNCTION"); ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("must be superuser to create a cast WITHOUT FUNCTION")));
/* /*
* Also, insist that the types match as to size, alignment, and * Also, insist that the types match as to size, alignment, and
@ -856,7 +924,9 @@ CreateCast(CreateCastStmt *stmt)
if (typ1len != typ2len || if (typ1len != typ2len ||
typ1byval != typ2byval || typ1byval != typ2byval ||
typ1align != typ2align) typ1align != typ2align)
elog(ERROR, "source and target datatypes are not physically compatible"); ereport(ERROR,
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
errmsg("source and target datatypes are not physically compatible")));
} }
/* convert CoercionContext enum to char value for castcontext */ /* convert CoercionContext enum to char value for castcontext */
@ -872,7 +942,7 @@ CreateCast(CreateCastStmt *stmt)
castcontext = COERCION_CODE_EXPLICIT; castcontext = COERCION_CODE_EXPLICIT;
break; break;
default: default:
elog(ERROR, "CreateCast: bogus CoercionContext %c", stmt->context); elog(ERROR, "unrecognized CoercionContext: %d", stmt->context);
castcontext = 0; /* keep compiler quiet */ castcontext = 0; /* keep compiler quiet */
break; break;
} }
@ -889,9 +959,11 @@ CreateCast(CreateCastStmt *stmt)
ObjectIdGetDatum(targettypeid), ObjectIdGetDatum(targettypeid),
0, 0); 0, 0);
if (HeapTupleIsValid(tuple)) if (HeapTupleIsValid(tuple))
elog(ERROR, "cast from data type %s to data type %s already exists", ereport(ERROR,
TypeNameToString(stmt->sourcetype), (errcode(ERRCODE_DUPLICATE_OBJECT),
TypeNameToString(stmt->targettype)); errmsg("cast from data type %s to data type %s already exists",
TypeNameToString(stmt->sourcetype),
TypeNameToString(stmt->targettype))));
/* ready to go */ /* ready to go */
values[Anum_pg_cast_castsource - 1] = ObjectIdGetDatum(sourcetypeid); values[Anum_pg_cast_castsource - 1] = ObjectIdGetDatum(sourcetypeid);
@ -953,29 +1025,37 @@ DropCast(DropCastStmt *stmt)
sourcetypeid = LookupTypeName(stmt->sourcetype); sourcetypeid = LookupTypeName(stmt->sourcetype);
if (!OidIsValid(sourcetypeid)) if (!OidIsValid(sourcetypeid))
elog(ERROR, "source data type %s does not exist", ereport(ERROR,
TypeNameToString(stmt->sourcetype)); (errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("source data type %s does not exist",
TypeNameToString(stmt->sourcetype))));
targettypeid = LookupTypeName(stmt->targettype); targettypeid = LookupTypeName(stmt->targettype);
if (!OidIsValid(targettypeid)) if (!OidIsValid(targettypeid))
elog(ERROR, "target data type %s does not exist", ereport(ERROR,
TypeNameToString(stmt->targettype)); (errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("target data type %s does not exist",
TypeNameToString(stmt->targettype))));
tuple = SearchSysCache(CASTSOURCETARGET, tuple = SearchSysCache(CASTSOURCETARGET,
ObjectIdGetDatum(sourcetypeid), ObjectIdGetDatum(sourcetypeid),
ObjectIdGetDatum(targettypeid), ObjectIdGetDatum(targettypeid),
0, 0); 0, 0);
if (!HeapTupleIsValid(tuple)) if (!HeapTupleIsValid(tuple))
elog(ERROR, "cast from type %s to type %s does not exist", ereport(ERROR,
TypeNameToString(stmt->sourcetype), (errcode(ERRCODE_UNDEFINED_OBJECT),
TypeNameToString(stmt->targettype)); errmsg("cast from type %s to type %s does not exist",
TypeNameToString(stmt->sourcetype),
TypeNameToString(stmt->targettype))));
/* Permission check */ /* Permission check */
if (!pg_type_ownercheck(sourcetypeid, GetUserId()) if (!pg_type_ownercheck(sourcetypeid, GetUserId())
&& !pg_type_ownercheck(targettypeid, GetUserId())) && !pg_type_ownercheck(targettypeid, GetUserId()))
elog(ERROR, "must be owner of type %s or type %s", ereport(ERROR,
TypeNameToString(stmt->sourcetype), (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
TypeNameToString(stmt->targettype)); errmsg("must be owner of type %s or type %s",
TypeNameToString(stmt->sourcetype),
TypeNameToString(stmt->targettype))));
/* /*
* Do the deletion * Do the deletion
@ -1006,10 +1086,9 @@ DropCastById(Oid castOid)
1, F_OIDEQ, ObjectIdGetDatum(castOid)); 1, F_OIDEQ, ObjectIdGetDatum(castOid));
scan = index_beginscan(relation, index, SnapshotNow, 1, &scankey); scan = index_beginscan(relation, index, SnapshotNow, 1, &scankey);
tuple = index_getnext(scan, ForwardScanDirection); tuple = index_getnext(scan, ForwardScanDirection);
if (HeapTupleIsValid(tuple)) if (!HeapTupleIsValid(tuple))
simple_heap_delete(relation, &tuple->t_self);
else
elog(ERROR, "could not find tuple for cast %u", castOid); elog(ERROR, "could not find tuple for cast %u", castOid);
simple_heap_delete(relation, &tuple->t_self);
index_endscan(scan); index_endscan(scan);
index_close(index); index_close(index);

View File

@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/opclasscmds.c,v 1.11 2003/07/04 02:51:33 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/opclasscmds.c,v 1.12 2003/07/18 23:20:32 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -85,8 +85,10 @@ DefineOpClass(CreateOpClassStmt *stmt)
CStringGetDatum(stmt->amname), CStringGetDatum(stmt->amname),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(tup)) if (!HeapTupleIsValid(tup))
elog(ERROR, "DefineOpClass: access method \"%s\" not found", ereport(ERROR,
stmt->amname); (errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("access method \"%s\" does not exist",
stmt->amname)));
amoid = HeapTupleGetOid(tup); amoid = HeapTupleGetOid(tup);
numOperators = ((Form_pg_am) GETSTRUCT(tup))->amstrategies; numOperators = ((Form_pg_am) GETSTRUCT(tup))->amstrategies;
@ -104,7 +106,9 @@ DefineOpClass(CreateOpClassStmt *stmt)
* if it can be done without solving the halting problem :-( * if it can be done without solving the halting problem :-(
*/ */
if (!superuser()) if (!superuser())
elog(ERROR, "Must be superuser to create an operator class"); ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("must be superuser to create an operator class")));
/* Look up the datatype */ /* Look up the datatype */
typeoid = typenameTypeId(stmt->datatype); typeoid = typenameTypeId(stmt->datatype);
@ -143,12 +147,16 @@ DefineOpClass(CreateOpClassStmt *stmt)
{ {
case OPCLASS_ITEM_OPERATOR: case OPCLASS_ITEM_OPERATOR:
if (item->number <= 0 || item->number > numOperators) if (item->number <= 0 || item->number > numOperators)
elog(ERROR, "DefineOpClass: invalid operator number %d," ereport(ERROR,
" must be between 1 and %d", (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
item->number, numOperators); errmsg("invalid operator number %d,"
" must be between 1 and %d",
item->number, numOperators)));
if (operators[item->number - 1] != InvalidOid) if (operators[item->number - 1] != InvalidOid)
elog(ERROR, "DefineOpClass: operator number %d appears more than once", ereport(ERROR,
item->number); (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
errmsg("operator number %d appears more than once",
item->number)));
if (item->args != NIL) if (item->args != NIL)
{ {
TypeName *typeName1 = (TypeName *) lfirst(item->args); TypeName *typeName1 = (TypeName *) lfirst(item->args);
@ -176,12 +184,16 @@ DefineOpClass(CreateOpClassStmt *stmt)
break; break;
case OPCLASS_ITEM_FUNCTION: case OPCLASS_ITEM_FUNCTION:
if (item->number <= 0 || item->number > numProcs) if (item->number <= 0 || item->number > numProcs)
elog(ERROR, "DefineOpClass: invalid procedure number %d," ereport(ERROR,
" must be between 1 and %d", (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
item->number, numProcs); errmsg("invalid procedure number %d,"
" must be between 1 and %d",
item->number, numProcs)));
if (procedures[item->number - 1] != InvalidOid) if (procedures[item->number - 1] != InvalidOid)
elog(ERROR, "DefineOpClass: procedure number %d appears more than once", ereport(ERROR,
item->number); (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
errmsg("DefineOpClass: procedure number %d appears more than once",
item->number)));
funcOid = LookupFuncNameTypeNames(item->name, item->args, funcOid = LookupFuncNameTypeNames(item->name, item->args,
false); false);
/* Caller must have execute permission on functions */ /* Caller must have execute permission on functions */
@ -193,12 +205,13 @@ DefineOpClass(CreateOpClassStmt *stmt)
break; break;
case OPCLASS_ITEM_STORAGETYPE: case OPCLASS_ITEM_STORAGETYPE:
if (OidIsValid(storageoid)) if (OidIsValid(storageoid))
elog(ERROR, "DefineOpClass: storage type specified more than once"); ereport(ERROR,
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
errmsg("storage type specified more than once")));
storageoid = typenameTypeId(item->storedtype); storageoid = typenameTypeId(item->storedtype);
break; break;
default: default:
elog(ERROR, "DefineOpClass: bogus item type %d", elog(ERROR, "unrecognized item type: %d", item->itemtype);
item->itemtype);
break; break;
} }
} }
@ -219,8 +232,10 @@ DefineOpClass(CreateOpClassStmt *stmt)
* favor of adding another boolean column to pg_am ... * favor of adding another boolean column to pg_am ...
*/ */
if (amoid != GIST_AM_OID) if (amoid != GIST_AM_OID)
elog(ERROR, "Storage type may not be different from datatype for access method %s", ereport(ERROR,
stmt->amname); (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
errmsg("storage type may not be different from datatype for access method \"%s\"",
stmt->amname)));
} }
} }
@ -235,8 +250,10 @@ DefineOpClass(CreateOpClassStmt *stmt)
CStringGetDatum(opcname), CStringGetDatum(opcname),
ObjectIdGetDatum(namespaceoid), ObjectIdGetDatum(namespaceoid),
0)) 0))
elog(ERROR, "Operator class \"%s\" already exists for access method \"%s\"", ereport(ERROR,
opcname, stmt->amname); (errcode(ERRCODE_DUPLICATE_OBJECT),
errmsg("operator class \"%s\" already exists for access method \"%s\"",
opcname, stmt->amname)));
/* /*
* If we are creating a default opclass, check there isn't one * If we are creating a default opclass, check there isn't one
@ -259,11 +276,13 @@ DefineOpClass(CreateOpClassStmt *stmt)
Form_pg_opclass opclass = (Form_pg_opclass) GETSTRUCT(tup); Form_pg_opclass opclass = (Form_pg_opclass) GETSTRUCT(tup);
if (opclass->opcintype == typeoid && opclass->opcdefault) if (opclass->opcintype == typeoid && opclass->opcdefault)
elog(ERROR, "Can't add class \"%s\" as default for type %s" ereport(ERROR,
"\n\tclass \"%s\" already is the default", (errcode(ERRCODE_DUPLICATE_OBJECT),
opcname, errmsg("cannot make class \"%s\" be default for type %s",
TypeNameToString(stmt->datatype), opcname,
NameStr(opclass->opcname)); TypeNameToString(stmt->datatype)),
errdetail("class \"%s\" already is the default",
NameStr(opclass->opcname))));
} }
systable_endscan(scan); systable_endscan(scan);
@ -467,8 +486,10 @@ RemoveOpClass(RemoveOpClassStmt *stmt)
CStringGetDatum(stmt->amname), CStringGetDatum(stmt->amname),
0, 0, 0); 0, 0, 0);
if (!OidIsValid(amID)) if (!OidIsValid(amID))
elog(ERROR, "RemoveOpClass: access method \"%s\" not found", ereport(ERROR,
stmt->amname); (errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("access method \"%s\" does not exist",
stmt->amname)));
/* /*
* Look up the opclass. * Look up the opclass.
@ -494,16 +515,20 @@ RemoveOpClass(RemoveOpClassStmt *stmt)
/* Unqualified opclass name, so search the search path */ /* Unqualified opclass name, so search the search path */
opcID = OpclassnameGetOpcid(amID, opcname); opcID = OpclassnameGetOpcid(amID, opcname);
if (!OidIsValid(opcID)) if (!OidIsValid(opcID))
elog(ERROR, "RemoveOpClass: operator class \"%s\" not supported by access method \"%s\"", ereport(ERROR,
opcname, stmt->amname); (errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("operator class \"%s\" does not exist for access method \"%s\"",
opcname, stmt->amname)));
tuple = SearchSysCache(CLAOID, tuple = SearchSysCache(CLAOID,
ObjectIdGetDatum(opcID), ObjectIdGetDatum(opcID),
0, 0, 0); 0, 0, 0);
} }
if (!HeapTupleIsValid(tuple)) if (!HeapTupleIsValid(tuple))
elog(ERROR, "RemoveOpClass: operator class \"%s\" not supported by access method \"%s\"", ereport(ERROR,
NameListToString(stmt->opclassname), stmt->amname); (errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("operator class \"%s\" does not exist for access method \"%s\"",
NameListToString(stmt->opclassname), stmt->amname)));
opcID = HeapTupleGetOid(tuple); opcID = HeapTupleGetOid(tuple);
@ -546,8 +571,7 @@ RemoveOpClassById(Oid opclassOid)
ObjectIdGetDatum(opclassOid), ObjectIdGetDatum(opclassOid),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(tup)) /* should not happen */ if (!HeapTupleIsValid(tup)) /* should not happen */
elog(ERROR, "RemoveOpClassById: couldn't find pg_opclass entry %u", elog(ERROR, "cache lookup failed for opclass %u", opclassOid);
opclassOid);
simple_heap_delete(rel, &tup->t_self); simple_heap_delete(rel, &tup->t_self);
@ -612,7 +636,10 @@ RenameOpClass(List *name, const char *access_method, const char *newname)
CStringGetDatum(access_method), CStringGetDatum(access_method),
0, 0, 0); 0, 0, 0);
if (!OidIsValid(amOid)) if (!OidIsValid(amOid))
elog(ERROR, "access method \"%s\" not found", access_method); ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("access method \"%s\" does not exist",
access_method)));
rel = heap_openr(OperatorClassRelationName, RowExclusiveLock); rel = heap_openr(OperatorClassRelationName, RowExclusiveLock);
@ -631,8 +658,10 @@ RenameOpClass(List *name, const char *access_method, const char *newname)
ObjectIdGetDatum(namespaceOid), ObjectIdGetDatum(namespaceOid),
0); 0);
if (!HeapTupleIsValid(tup)) if (!HeapTupleIsValid(tup))
elog(ERROR, "operator class \"%s\" for access method \"%s\" does not exist", ereport(ERROR,
opcname, access_method); (errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("operator class \"%s\" does not exist for access method \"%s\"",
opcname, access_method)));
opcOid = HeapTupleGetOid(tup); opcOid = HeapTupleGetOid(tup);
} }
@ -640,14 +669,16 @@ RenameOpClass(List *name, const char *access_method, const char *newname)
{ {
opcOid = OpclassnameGetOpcid(amOid, opcname); opcOid = OpclassnameGetOpcid(amOid, opcname);
if (!OidIsValid(opcOid)) if (!OidIsValid(opcOid))
elog(ERROR, "operator class \"%s\" for access method \"%s\" does not exist", ereport(ERROR,
opcname, access_method); (errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("operator class \"%s\" does not exist for access method \"%s\"",
opcname, access_method)));
tup = SearchSysCacheCopy(CLAOID, tup = SearchSysCacheCopy(CLAOID,
ObjectIdGetDatum(opcOid), ObjectIdGetDatum(opcOid),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(tup)) /* should not happen */ if (!HeapTupleIsValid(tup)) /* should not happen */
elog(ERROR, "couldn't find pg_opclass tuple for %u", opcOid); elog(ERROR, "cache lookup failed for opclass %u", opcOid);
namespaceOid = ((Form_pg_opclass) GETSTRUCT(tup))->opcnamespace; namespaceOid = ((Form_pg_opclass) GETSTRUCT(tup))->opcnamespace;
} }
@ -660,9 +691,10 @@ RenameOpClass(List *name, const char *access_method, const char *newname)
0)) 0))
{ {
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR_OR_ACCESS_RULE_VIOLATION), (errcode(ERRCODE_DUPLICATE_OBJECT),
errmsg("operator class \"%s\" for access method \"%s\" already exists in schema \"%s\"", errmsg("operator class \"%s\" for access method \"%s\" already exists in schema \"%s\"",
newname, access_method, get_namespace_name(namespaceOid)))); newname, access_method,
get_namespace_name(namespaceOid))));
} }
/* must be owner */ /* must be owner */

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/proclang.c,v 1.45 2003/07/04 02:51:33 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/proclang.c,v 1.46 2003/07/18 23:20:32 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -58,8 +58,9 @@ CreateProceduralLanguage(CreatePLangStmt *stmt)
* Check permission * Check permission
*/ */
if (!superuser()) if (!superuser())
elog(ERROR, "Only users with superuser privilege are " ereport(ERROR,
"permitted to create procedural languages"); (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("must be superuser to create procedural language")));
/* /*
* Translate the language name and check that this language doesn't * Translate the language name and check that this language doesn't
@ -70,7 +71,9 @@ CreateProceduralLanguage(CreatePLangStmt *stmt)
if (SearchSysCacheExists(LANGNAME, if (SearchSysCacheExists(LANGNAME,
PointerGetDatum(languageName), PointerGetDatum(languageName),
0, 0, 0)) 0, 0, 0))
elog(ERROR, "Language %s already exists", languageName); ereport(ERROR,
(errcode(ERRCODE_DUPLICATE_OBJECT),
errmsg("language \"%s\" already exists", languageName)));
/* /*
* Lookup the PL handler function and check that it is of the expected * Lookup the PL handler function and check that it is of the expected
@ -88,13 +91,17 @@ CreateProceduralLanguage(CreatePLangStmt *stmt)
*/ */
if (funcrettype == OPAQUEOID) if (funcrettype == OPAQUEOID)
{ {
elog(NOTICE, "CreateProceduralLanguage: changing return type of function %s() from OPAQUE to LANGUAGE_HANDLER", ereport(NOTICE,
NameListToString(stmt->plhandler)); (errcode(ERRCODE_WRONG_OBJECT_TYPE),
errmsg("changing return type of function %s() from OPAQUE to LANGUAGE_HANDLER",
NameListToString(stmt->plhandler))));
SetFunctionReturnType(procOid, LANGUAGE_HANDLEROID); SetFunctionReturnType(procOid, LANGUAGE_HANDLEROID);
} }
else else
elog(ERROR, "CreateProceduralLanguage: function %s() must return LANGUAGE_HANDLER", ereport(ERROR,
NameListToString(stmt->plhandler)); (errcode(ERRCODE_WRONG_OBJECT_TYPE),
errmsg("function %s() must return LANGUAGE_HANDLER",
NameListToString(stmt->plhandler))));
} }
/* validate the validator function */ /* validate the validator function */
@ -174,8 +181,9 @@ DropProceduralLanguage(DropPLangStmt *stmt)
* Check permission * Check permission
*/ */
if (!superuser()) if (!superuser())
elog(ERROR, "Only users with superuser privilege are " ereport(ERROR,
"permitted to drop procedural languages"); (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("must be superuser to drop procedural language")));
/* /*
* Translate the language name, check that this language exist and is * Translate the language name, check that this language exist and is
@ -187,7 +195,9 @@ DropProceduralLanguage(DropPLangStmt *stmt)
CStringGetDatum(languageName), CStringGetDatum(languageName),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(langTup)) if (!HeapTupleIsValid(langTup))
elog(ERROR, "Language %s doesn't exist", languageName); ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("language \"%s\" does not exist", languageName)));
object.classId = get_system_catalog_relid(LanguageRelationName); object.classId = get_system_catalog_relid(LanguageRelationName);
object.objectId = HeapTupleGetOid(langTup); object.objectId = HeapTupleGetOid(langTup);
@ -215,9 +225,8 @@ DropProceduralLanguageById(Oid langOid)
langTup = SearchSysCache(LANGOID, langTup = SearchSysCache(LANGOID,
ObjectIdGetDatum(langOid), ObjectIdGetDatum(langOid),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(langTup)) if (!HeapTupleIsValid(langTup)) /* should not happen */
elog(ERROR, "DropProceduralLanguageById: language %u not found", elog(ERROR, "cache lookup failed for language %u", langOid);
langOid);
simple_heap_delete(rel, &langTup->t_self); simple_heap_delete(rel, &langTup->t_self);
@ -242,23 +251,21 @@ RenameLanguage(const char *oldname, const char *newname)
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(tup)) if (!HeapTupleIsValid(tup))
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR_OR_ACCESS_RULE_VIOLATION), (errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("language \"%s\" does not exist", oldname))); errmsg("language \"%s\" does not exist", oldname)));
/* make sure the new name doesn't exist */ /* make sure the new name doesn't exist */
if (SearchSysCacheExists(LANGNAME, if (SearchSysCacheExists(LANGNAME,
CStringGetDatum(newname), CStringGetDatum(newname),
0, 0, 0)) 0, 0, 0))
{
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR_OR_ACCESS_RULE_VIOLATION), (errcode(ERRCODE_DUPLICATE_OBJECT),
errmsg("language \"%s\" already exists", newname))); errmsg("language \"%s\" already exists", newname)));
}
/* must be superuser */ /* must be superuser */
if (!superuser()) if (!superuser())
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR_OR_ACCESS_RULE_VIOLATION), (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("permission denied"))); errmsg("permission denied")));
/* rename */ /* rename */

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/schemacmds.c,v 1.11 2003/06/27 17:05:46 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/schemacmds.c,v 1.12 2003/07/18 23:20:32 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -74,14 +74,16 @@ CreateSchemaCommand(CreateSchemaStmt *stmt)
SetUserId(owner_userid); SetUserId(owner_userid);
} }
else else
/* not superuser */
{ {
/* not superuser */
owner_userid = saved_userid; owner_userid = saved_userid;
owner_name = GetUserNameFromId(owner_userid); owner_name = GetUserNameFromId(owner_userid);
if (strcmp(authId, owner_name) != 0) if (strcmp(authId, owner_name) != 0)
elog(ERROR, "CREATE SCHEMA: permission denied" ereport(ERROR,
"\n\t\"%s\" is not a superuser, so cannot create a schema for \"%s\"", (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
owner_name, authId); errmsg("permission denied"),
errdetail("\"%s\" is not a superuser, so cannot create a schema for \"%s\"",
owner_name, authId)));
} }
/* /*
@ -92,8 +94,10 @@ CreateSchemaCommand(CreateSchemaStmt *stmt)
aclcheck_error(aclresult, get_database_name(MyDatabaseId)); aclcheck_error(aclresult, get_database_name(MyDatabaseId));
if (!allowSystemTableMods && IsReservedName(schemaName)) if (!allowSystemTableMods && IsReservedName(schemaName))
elog(ERROR, "CREATE SCHEMA: Illegal schema name: \"%s\" -- pg_ is reserved for system schemas", ereport(ERROR,
schemaName); (errcode(ERRCODE_RESERVED_NAME),
errmsg("unacceptable schema name \"%s\"", schemaName),
errdetail("The prefix pg_ is reserved for system schemas.")));
/* Create the schema's namespace */ /* Create the schema's namespace */
namespaceId = NamespaceCreate(schemaName, owner_userid); namespaceId = NamespaceCreate(schemaName, owner_userid);
@ -162,14 +166,18 @@ RemoveSchema(List *names, DropBehavior behavior)
ObjectAddress object; ObjectAddress object;
if (length(names) != 1) if (length(names) != 1)
elog(ERROR, "Schema name may not be qualified"); ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("schema name may not be qualified")));
namespaceName = strVal(lfirst(names)); namespaceName = strVal(lfirst(names));
namespaceId = GetSysCacheOid(NAMESPACENAME, namespaceId = GetSysCacheOid(NAMESPACENAME,
CStringGetDatum(namespaceName), CStringGetDatum(namespaceName),
0, 0, 0); 0, 0, 0);
if (!OidIsValid(namespaceId)) if (!OidIsValid(namespaceId))
elog(ERROR, "Schema \"%s\" does not exist", namespaceName); ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_SCHEMA),
errmsg("schema \"%s\" does not exist", namespaceName)));
/* Permission check */ /* Permission check */
if (!pg_namespace_ownercheck(namespaceId, GetUserId())) if (!pg_namespace_ownercheck(namespaceId, GetUserId()))
@ -205,9 +213,8 @@ RemoveSchemaById(Oid schemaOid)
tup = SearchSysCache(NAMESPACEOID, tup = SearchSysCache(NAMESPACEOID,
ObjectIdGetDatum(schemaOid), ObjectIdGetDatum(schemaOid),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(tup)) if (!HeapTupleIsValid(tup)) /* should not happen */
elog(ERROR, "RemoveSchemaById: schema %u not found", elog(ERROR, "cache lookup failed for schema %u", schemaOid);
schemaOid);
simple_heap_delete(relation, &tup->t_self); simple_heap_delete(relation, &tup->t_self);
@ -234,7 +241,7 @@ RenameSchema(const char *oldname, const char *newname)
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(tup)) if (!HeapTupleIsValid(tup))
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR_OR_ACCESS_RULE_VIOLATION), (errcode(ERRCODE_UNDEFINED_SCHEMA),
errmsg("schema \"%s\" does not exist", oldname))); errmsg("schema \"%s\" does not exist", oldname)));
/* make sure the new name doesn't exist */ /* make sure the new name doesn't exist */
@ -242,11 +249,9 @@ RenameSchema(const char *oldname, const char *newname)
SearchSysCache(NAMESPACENAME, SearchSysCache(NAMESPACENAME,
CStringGetDatum(newname), CStringGetDatum(newname),
0, 0, 0))) 0, 0, 0)))
{
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR_OR_ACCESS_RULE_VIOLATION), (errcode(ERRCODE_DUPLICATE_SCHEMA),
errmsg("schema \"%s\" already exists", newname))); errmsg("schema \"%s\" already exists", newname)));
}
/* must be owner */ /* must be owner */
if (!pg_namespace_ownercheck(HeapTupleGetOid(tup), GetUserId())) if (!pg_namespace_ownercheck(HeapTupleGetOid(tup), GetUserId()))
@ -258,8 +263,10 @@ RenameSchema(const char *oldname, const char *newname)
aclcheck_error(aclresult, get_database_name(MyDatabaseId)); aclcheck_error(aclresult, get_database_name(MyDatabaseId));
if (!allowSystemTableMods && IsReservedName(newname)) if (!allowSystemTableMods && IsReservedName(newname))
elog(ERROR, "illegal schema name: \"%s\" -- pg_ is reserved for system schemas", ereport(ERROR,
newname); (errcode(ERRCODE_RESERVED_NAME),
errmsg("unacceptable schema name \"%s\"", newname),
errdetail("The prefix pg_ is reserved for system schemas.")));
/* rename */ /* rename */
namestrcpy(&(((Form_pg_namespace) GETSTRUCT(tup))->nspname), newname); namestrcpy(&(((Form_pg_namespace) GETSTRUCT(tup))->nspname), newname);

View File

@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Header: /cvsroot/pgsql/src/backend/commands/user.c,v 1.118 2003/06/27 14:45:27 petere Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/user.c,v 1.119 2003/07/18 23:20:32 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -144,7 +144,9 @@ write_group_file(Relation grel)
fp = AllocateFile(tempname, "w"); fp = AllocateFile(tempname, "w");
umask(oumask); umask(oumask);
if (fp == NULL) if (fp == NULL)
elog(ERROR, "write_group_file: unable to write %s: %m", tempname); ereport(ERROR,
(errcode_for_file_access(),
errmsg("unable to write temp file \"%s\": %m", tempname)));
/* /*
* Read pg_group and write the file. Note we use SnapshotSelf to ensure * Read pg_group and write the file. Note we use SnapshotSelf to ensure
@ -178,7 +180,7 @@ write_group_file(Relation grel)
i = strcspn(groname, "\n"); i = strcspn(groname, "\n");
if (groname[i] != '\0') if (groname[i] != '\0')
{ {
elog(LOG, "Invalid group name '%s'", groname); elog(LOG, "invalid group name \"%s\"", groname);
continue; continue;
} }
@ -208,7 +210,7 @@ write_group_file(Relation grel)
j = strcspn(usename, "\n"); j = strcspn(usename, "\n");
if (usename[j] != '\0') if (usename[j] != '\0')
{ {
elog(LOG, "Invalid user name '%s'", usename); elog(LOG, "invalid user name \"%s\"", usename);
continue; continue;
} }
@ -239,7 +241,9 @@ write_group_file(Relation grel)
fflush(fp); fflush(fp);
if (ferror(fp)) if (ferror(fp))
elog(ERROR, "%s: %m", tempname); ereport(ERROR,
(errcode_for_file_access(),
errmsg("unable to write temp file \"%s\": %m", tempname)));
FreeFile(fp); FreeFile(fp);
/* /*
@ -247,7 +251,10 @@ write_group_file(Relation grel)
* expect that rename(2) is an atomic action. * expect that rename(2) is an atomic action.
*/ */
if (rename(tempname, filename)) if (rename(tempname, filename))
elog(ERROR, "rename %s to %s: %m", tempname, filename); ereport(ERROR,
(errcode_for_file_access(),
errmsg("could not rename \"%s\" to \"%s\": %m",
tempname, filename)));
pfree((void *) tempname); pfree((void *) tempname);
pfree((void *) filename); pfree((void *) filename);
@ -283,7 +290,9 @@ write_user_file(Relation urel)
fp = AllocateFile(tempname, "w"); fp = AllocateFile(tempname, "w");
umask(oumask); umask(oumask);
if (fp == NULL) if (fp == NULL)
elog(ERROR, "write_user_file: unable to write %s: %m", tempname); ereport(ERROR,
(errcode_for_file_access(),
errmsg("unable to write temp file \"%s\": %m", tempname)));
/* /*
* Read pg_shadow and write the file. Note we use SnapshotSelf to ensure * Read pg_shadow and write the file. Note we use SnapshotSelf to ensure
@ -332,13 +341,13 @@ write_user_file(Relation urel)
i = strcspn(usename, "\n"); i = strcspn(usename, "\n");
if (usename[i] != '\0') if (usename[i] != '\0')
{ {
elog(LOG, "Invalid user name '%s'", usename); elog(LOG, "invalid user name \"%s\"", usename);
continue; continue;
} }
i = strcspn(passwd, "\n"); i = strcspn(passwd, "\n");
if (passwd[i] != '\0') if (passwd[i] != '\0')
{ {
elog(LOG, "Invalid user password '%s'", passwd); elog(LOG, "invalid user password \"%s\"", passwd);
continue; continue;
} }
@ -361,7 +370,9 @@ write_user_file(Relation urel)
fflush(fp); fflush(fp);
if (ferror(fp)) if (ferror(fp))
elog(ERROR, "%s: %m", tempname); ereport(ERROR,
(errcode_for_file_access(),
errmsg("unable to write temp file \"%s\": %m", tempname)));
FreeFile(fp); FreeFile(fp);
/* /*
@ -369,7 +380,10 @@ write_user_file(Relation urel)
* expect that rename(2) is an atomic action. * expect that rename(2) is an atomic action.
*/ */
if (rename(tempname, filename)) if (rename(tempname, filename))
elog(ERROR, "rename %s to %s: %m", tempname, filename); ereport(ERROR,
(errcode_for_file_access(),
errmsg("could not rename \"%s\" to \"%s\": %m",
tempname, filename)));
pfree((void *) tempname); pfree((void *) tempname);
pfree((void *) filename); pfree((void *) filename);
@ -502,7 +516,9 @@ CreateUser(CreateUserStmt *stmt)
strcmp(defel->defname, "unencryptedPassword") == 0) strcmp(defel->defname, "unencryptedPassword") == 0)
{ {
if (dpassword) if (dpassword)
elog(ERROR, "CREATE USER: conflicting options"); ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("conflicting or redundant options")));
dpassword = defel; dpassword = defel;
if (strcmp(defel->defname, "encryptedPassword") == 0) if (strcmp(defel->defname, "encryptedPassword") == 0)
encrypt_password = true; encrypt_password = true;
@ -512,35 +528,45 @@ CreateUser(CreateUserStmt *stmt)
else if (strcmp(defel->defname, "sysid") == 0) else if (strcmp(defel->defname, "sysid") == 0)
{ {
if (dsysid) if (dsysid)
elog(ERROR, "CREATE USER: conflicting options"); ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("conflicting or redundant options")));
dsysid = defel; dsysid = defel;
} }
else if (strcmp(defel->defname, "createdb") == 0) else if (strcmp(defel->defname, "createdb") == 0)
{ {
if (dcreatedb) if (dcreatedb)
elog(ERROR, "CREATE USER: conflicting options"); ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("conflicting or redundant options")));
dcreatedb = defel; dcreatedb = defel;
} }
else if (strcmp(defel->defname, "createuser") == 0) else if (strcmp(defel->defname, "createuser") == 0)
{ {
if (dcreateuser) if (dcreateuser)
elog(ERROR, "CREATE USER: conflicting options"); ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("conflicting or redundant options")));
dcreateuser = defel; dcreateuser = defel;
} }
else if (strcmp(defel->defname, "groupElts") == 0) else if (strcmp(defel->defname, "groupElts") == 0)
{ {
if (dgroupElts) if (dgroupElts)
elog(ERROR, "CREATE USER: conflicting options"); ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("conflicting or redundant options")));
dgroupElts = defel; dgroupElts = defel;
} }
else if (strcmp(defel->defname, "validUntil") == 0) else if (strcmp(defel->defname, "validUntil") == 0)
{ {
if (dvalidUntil) if (dvalidUntil)
elog(ERROR, "CREATE USER: conflicting options"); ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("conflicting or redundant options")));
dvalidUntil = defel; dvalidUntil = defel;
} }
else else
elog(ERROR, "CREATE USER: option \"%s\" not recognized", elog(ERROR, "option \"%s\" not recognized",
defel->defname); defel->defname);
} }
@ -552,7 +578,9 @@ CreateUser(CreateUserStmt *stmt)
{ {
sysid = intVal(dsysid->arg); sysid = intVal(dsysid->arg);
if (sysid <= 0) if (sysid <= 0)
elog(ERROR, "user id must be positive"); ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("user id must be positive")));
havesysid = true; havesysid = true;
} }
if (dvalidUntil) if (dvalidUntil)
@ -567,11 +595,15 @@ CreateUser(CreateUserStmt *stmt)
CheckPgUserAclNotNull(); CheckPgUserAclNotNull();
if (!superuser()) if (!superuser())
elog(ERROR, "CREATE USER: permission denied"); ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("permission denied")));
if (strcmp(stmt->user, "public") == 0) if (strcmp(stmt->user, "public") == 0)
elog(ERROR, "CREATE USER: user name \"%s\" is reserved", ereport(ERROR,
stmt->user); (errcode(ERRCODE_RESERVED_NAME),
errmsg("user name \"%s\" is reserved",
stmt->user)));
/* /*
* Scan the pg_shadow relation to be certain the user or id doesn't * Scan the pg_shadow relation to be certain the user or id doesn't
@ -605,10 +637,14 @@ CreateUser(CreateUserStmt *stmt)
heap_endscan(scan); heap_endscan(scan);
if (user_exists) if (user_exists)
elog(ERROR, "CREATE USER: user name \"%s\" already exists", ereport(ERROR,
stmt->user); (errcode(ERRCODE_DUPLICATE_OBJECT),
errmsg("user \"%s\" already exists",
stmt->user)));
if (sysid_exists) if (sysid_exists)
elog(ERROR, "CREATE USER: sysid %d is already assigned", sysid); ereport(ERROR,
(errcode(ERRCODE_DUPLICATE_OBJECT),
errmsg("sysid %d is already assigned", sysid)));
/* If no sysid given, use max existing id + 1 */ /* If no sysid given, use max existing id + 1 */
if (!havesysid) if (!havesysid)
@ -639,7 +675,7 @@ CreateUser(CreateUserStmt *stmt)
{ {
if (!EncryptMD5(password, stmt->user, strlen(stmt->user), if (!EncryptMD5(password, stmt->user, strlen(stmt->user),
encrypted_password)) encrypted_password))
elog(ERROR, "CREATE USER: password encryption failed"); elog(ERROR, "password encryption failed");
new_record[Anum_pg_shadow_passwd - 1] = new_record[Anum_pg_shadow_passwd - 1] =
DirectFunctionCall1(textin, CStringGetDatum(encrypted_password)); DirectFunctionCall1(textin, CStringGetDatum(encrypted_password));
} }
@ -730,7 +766,9 @@ AlterUser(AlterUserStmt *stmt)
strcmp(defel->defname, "unencryptedPassword") == 0) strcmp(defel->defname, "unencryptedPassword") == 0)
{ {
if (dpassword) if (dpassword)
elog(ERROR, "ALTER USER: conflicting options"); ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("conflicting or redundant options")));
dpassword = defel; dpassword = defel;
if (strcmp(defel->defname, "encryptedPassword") == 0) if (strcmp(defel->defname, "encryptedPassword") == 0)
encrypt_password = true; encrypt_password = true;
@ -740,23 +778,29 @@ AlterUser(AlterUserStmt *stmt)
else if (strcmp(defel->defname, "createdb") == 0) else if (strcmp(defel->defname, "createdb") == 0)
{ {
if (dcreatedb) if (dcreatedb)
elog(ERROR, "ALTER USER: conflicting options"); ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("conflicting or redundant options")));
dcreatedb = defel; dcreatedb = defel;
} }
else if (strcmp(defel->defname, "createuser") == 0) else if (strcmp(defel->defname, "createuser") == 0)
{ {
if (dcreateuser) if (dcreateuser)
elog(ERROR, "ALTER USER: conflicting options"); ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("conflicting or redundant options")));
dcreateuser = defel; dcreateuser = defel;
} }
else if (strcmp(defel->defname, "validUntil") == 0) else if (strcmp(defel->defname, "validUntil") == 0)
{ {
if (dvalidUntil) if (dvalidUntil)
elog(ERROR, "ALTER USER: conflicting options"); ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("conflicting or redundant options")));
dvalidUntil = defel; dvalidUntil = defel;
} }
else else
elog(ERROR, "ALTER USER: option \"%s\" not recognized", elog(ERROR, "option \"%s\" not recognized",
defel->defname); defel->defname);
} }
@ -779,7 +823,9 @@ AlterUser(AlterUserStmt *stmt)
!validUntil && !validUntil &&
password && password &&
strcmp(GetUserNameFromId(GetUserId()), stmt->user) == 0)) strcmp(GetUserNameFromId(GetUserId()), stmt->user) == 0))
elog(ERROR, "ALTER USER: permission denied"); ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("permission denied")));
/* /*
* Scan the pg_shadow relation to be certain the user exists. Note we * Scan the pg_shadow relation to be certain the user exists. Note we
@ -793,7 +839,9 @@ AlterUser(AlterUserStmt *stmt)
PointerGetDatum(stmt->user), PointerGetDatum(stmt->user),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(tuple)) if (!HeapTupleIsValid(tuple))
elog(ERROR, "ALTER USER: user \"%s\" does not exist", stmt->user); ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("user \"%s\" does not exist", stmt->user)));
/* /*
* Build an updated tuple, perusing the information just obtained * Build an updated tuple, perusing the information just obtained
@ -840,7 +888,7 @@ AlterUser(AlterUserStmt *stmt)
{ {
if (!EncryptMD5(password, stmt->user, strlen(stmt->user), if (!EncryptMD5(password, stmt->user, strlen(stmt->user),
encrypted_password)) encrypted_password))
elog(ERROR, "CREATE USER: password encryption failed"); elog(ERROR, "password encryption failed");
new_record[Anum_pg_shadow_passwd - 1] = new_record[Anum_pg_shadow_passwd - 1] =
DirectFunctionCall1(textin, CStringGetDatum(encrypted_password)); DirectFunctionCall1(textin, CStringGetDatum(encrypted_password));
} }
@ -904,11 +952,15 @@ AlterUserSet(AlterUserSetStmt *stmt)
PointerGetDatum(stmt->user), PointerGetDatum(stmt->user),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(oldtuple)) if (!HeapTupleIsValid(oldtuple))
elog(ERROR, "user \"%s\" does not exist", stmt->user); ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("user \"%s\" does not exist", stmt->user)));
if (!(superuser() if (!(superuser()
|| ((Form_pg_shadow) GETSTRUCT(oldtuple))->usesysid == GetUserId())) || ((Form_pg_shadow) GETSTRUCT(oldtuple))->usesysid == GetUserId()))
elog(ERROR, "ALTER USER SET: permission denied"); ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("permission denied")));
for (i = 0; i < Natts_pg_shadow; i++) for (i = 0; i < Natts_pg_shadow; i++)
repl_repl[i] = ' '; repl_repl[i] = ' ';
@ -965,7 +1017,9 @@ DropUser(DropUserStmt *stmt)
List *item; List *item;
if (!superuser()) if (!superuser())
elog(ERROR, "DROP USER: permission denied"); ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("permission denied")));
/* /*
* Scan the pg_shadow relation to find the usesysid of the user to be * Scan the pg_shadow relation to find the usesysid of the user to be
@ -990,19 +1044,20 @@ DropUser(DropUserStmt *stmt)
PointerGetDatum(user), PointerGetDatum(user),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(tuple)) if (!HeapTupleIsValid(tuple))
{ ereport(ERROR,
if (length(stmt->users) > 1) (errcode(ERRCODE_UNDEFINED_OBJECT),
elog(ERROR, "DROP USER: user \"%s\" does not exist (no users removed)", user); errmsg("user \"%s\" does not exist", user)));
else
elog(ERROR, "DROP USER: user \"%s\" does not exist", user);
}
usesysid = ((Form_pg_shadow) GETSTRUCT(tuple))->usesysid; usesysid = ((Form_pg_shadow) GETSTRUCT(tuple))->usesysid;
if (usesysid == GetUserId()) if (usesysid == GetUserId())
elog(ERROR, "current user cannot be dropped"); ereport(ERROR,
(errcode(ERRCODE_OBJECT_IN_USE),
errmsg("current user cannot be dropped")));
if (usesysid == GetSessionUserId()) if (usesysid == GetSessionUserId())
elog(ERROR, "session user cannot be dropped"); ereport(ERROR,
(errcode(ERRCODE_OBJECT_IN_USE),
errmsg("session user cannot be dropped")));
/* /*
* Check if user still owns a database. If so, error out. * Check if user still owns a database. If so, error out.
@ -1026,9 +1081,10 @@ DropUser(DropUserStmt *stmt)
char *dbname; char *dbname;
dbname = NameStr(((Form_pg_database) GETSTRUCT(tmp_tuple))->datname); dbname = NameStr(((Form_pg_database) GETSTRUCT(tmp_tuple))->datname);
elog(ERROR, "DROP USER: user \"%s\" owns database \"%s\", cannot be removed%s", ereport(ERROR,
user, dbname, (errcode(ERRCODE_OBJECT_IN_USE),
(length(stmt->users) > 1) ? " (no users removed)" : ""); errmsg("user \"%s\" cannot be dropped", user),
errdetail("The user owns database \"%s\".", dbname)));
} }
heap_endscan(scan); heap_endscan(scan);
@ -1108,7 +1164,7 @@ RenameUser(const char *oldname, const char *newname)
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(tup)) if (!HeapTupleIsValid(tup))
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR_OR_ACCESS_RULE_VIOLATION), (errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("user \"%s\" does not exist", oldname))); errmsg("user \"%s\" does not exist", oldname)));
/* /*
@ -1119,23 +1175,21 @@ RenameUser(const char *oldname, const char *newname)
*/ */
if (((Form_pg_shadow) GETSTRUCT(tup))->usesysid == GetSessionUserId()) if (((Form_pg_shadow) GETSTRUCT(tup))->usesysid == GetSessionUserId())
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR_OR_ACCESS_RULE_VIOLATION), (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("session user may not be renamed"))); errmsg("session user may not be renamed")));
/* make sure the new name doesn't exist */ /* make sure the new name doesn't exist */
if (SearchSysCacheExists(SHADOWNAME, if (SearchSysCacheExists(SHADOWNAME,
CStringGetDatum(newname), CStringGetDatum(newname),
0, 0, 0)) 0, 0, 0))
{
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR_OR_ACCESS_RULE_VIOLATION), (errcode(ERRCODE_DUPLICATE_OBJECT),
errmsg("user \"%s\" already exists", newname))); errmsg("user \"%s\" already exists", newname)));
}
/* must be superuser */ /* must be superuser */
if (!superuser()) if (!superuser())
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR_OR_ACCESS_RULE_VIOLATION), (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("permission denied"))); errmsg("permission denied")));
/* rename */ /* rename */
@ -1163,16 +1217,17 @@ CheckPgUserAclNotNull(void)
htup = SearchSysCache(RELOID, htup = SearchSysCache(RELOID,
ObjectIdGetDatum(RelOid_pg_shadow), ObjectIdGetDatum(RelOid_pg_shadow),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(htup)) if (!HeapTupleIsValid(htup)) /* should not happen, we hope */
elog(ERROR, "CheckPgUserAclNotNull: \"%s\" not found", elog(ERROR, "cache lookup failed for relation %u", RelOid_pg_shadow);
ShadowRelationName);
if (heap_attisnull(htup, Anum_pg_class_relacl)) if (heap_attisnull(htup, Anum_pg_class_relacl))
elog(ERROR, ereport(ERROR,
"To use passwords, you have to revoke permissions on %s " (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
"so normal users cannot read the passwords. " errmsg("before using passwords you must revoke permissions on %s",
"Try 'REVOKE ALL ON \"%s\" FROM PUBLIC'.", ShadowRelationName),
ShadowRelationName, ShadowRelationName); errdetail("This restriction is to prevent unprivileged users from reading the passwords."),
errhint("Try 'REVOKE ALL ON \"%s\" FROM PUBLIC'.",
ShadowRelationName)));
ReleaseSysCache(htup); ReleaseSysCache(htup);
} }
@ -1211,17 +1266,21 @@ CreateGroup(CreateGroupStmt *stmt)
if (strcmp(defel->defname, "sysid") == 0) if (strcmp(defel->defname, "sysid") == 0)
{ {
if (dsysid) if (dsysid)
elog(ERROR, "CREATE GROUP: conflicting options"); ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("conflicting or redundant options")));
dsysid = defel; dsysid = defel;
} }
else if (strcmp(defel->defname, "userElts") == 0) else if (strcmp(defel->defname, "userElts") == 0)
{ {
if (duserElts) if (duserElts)
elog(ERROR, "CREATE GROUP: conflicting options"); ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("conflicting or redundant options")));
duserElts = defel; duserElts = defel;
} }
else else
elog(ERROR, "CREATE GROUP: option \"%s\" not recognized", elog(ERROR, "option \"%s\" not recognized",
defel->defname); defel->defname);
} }
@ -1229,7 +1288,9 @@ CreateGroup(CreateGroupStmt *stmt)
{ {
sysid = intVal(dsysid->arg); sysid = intVal(dsysid->arg);
if (sysid <= 0) if (sysid <= 0)
elog(ERROR, "group id must be positive"); ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("group id must be positive")));
havesysid = true; havesysid = true;
} }
@ -1240,11 +1301,15 @@ CreateGroup(CreateGroupStmt *stmt)
* Make sure the user can do this. * Make sure the user can do this.
*/ */
if (!superuser()) if (!superuser())
elog(ERROR, "CREATE GROUP: permission denied"); ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("permission denied")));
if (strcmp(stmt->name, "public") == 0) if (strcmp(stmt->name, "public") == 0)
elog(ERROR, "CREATE GROUP: group name \"%s\" is reserved", ereport(ERROR,
stmt->name); (errcode(ERRCODE_RESERVED_NAME),
errmsg("group name \"%s\" is reserved",
stmt->name)));
/* /*
* Scan the pg_group relation to be certain the group or id doesn't * Scan the pg_group relation to be certain the group or id doesn't
@ -1278,12 +1343,16 @@ CreateGroup(CreateGroupStmt *stmt)
heap_endscan(scan); heap_endscan(scan);
if (group_exists) if (group_exists)
elog(ERROR, "CREATE GROUP: group name \"%s\" already exists", ereport(ERROR,
stmt->name); (errcode(ERRCODE_DUPLICATE_OBJECT),
errmsg("group \"%s\" already exists",
stmt->name)));
if (sysid_exists) if (sysid_exists)
elog(ERROR, "CREATE GROUP: group sysid %d is already assigned", ereport(ERROR,
sysid); (errcode(ERRCODE_DUPLICATE_OBJECT),
errmsg("sysid %d is already assigned", sysid)));
/* If no sysid given, use max existing id + 1 */
if (!havesysid) if (!havesysid)
sysid = max_id + 1; sysid = max_id + 1;
@ -1359,7 +1428,9 @@ AlterGroup(AlterGroupStmt *stmt, const char *tag)
* Make sure the user can do this. * Make sure the user can do this.
*/ */
if (!superuser()) if (!superuser())
elog(ERROR, "%s: permission denied", tag); ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("permission denied")));
/* /*
* Secure exclusive lock to protect our update of the flat group file. * Secure exclusive lock to protect our update of the flat group file.
@ -1374,7 +1445,9 @@ AlterGroup(AlterGroupStmt *stmt, const char *tag)
PointerGetDatum(stmt->name), PointerGetDatum(stmt->name),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(group_tuple)) if (!HeapTupleIsValid(group_tuple))
elog(ERROR, "%s: group \"%s\" does not exist", tag, stmt->name); ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("group \"%s\" does not exist", stmt->name)));
/* Fetch old group membership. */ /* Fetch old group membership. */
datum = heap_getattr(group_tuple, Anum_pg_group_grolist, datum = heap_getattr(group_tuple, Anum_pg_group_grolist,
@ -1415,20 +1488,17 @@ AlterGroup(AlterGroupStmt *stmt, const char *tag)
} }
else else
{ {
elog(ERROR, "AlterGroup: unknown tag %s", tag); elog(ERROR, "unexpected tag: \"%s\"", tag);
sysid = 0; /* keep compiler quiet */ sysid = 0; /* keep compiler quiet */
} }
if (!intMember(sysid, newlist)) if (!intMember(sysid, newlist))
newlist = lappendi(newlist, sysid); newlist = lappendi(newlist, sysid);
else else
ereport(WARNING,
/* (errcode(ERRCODE_DUPLICATE_OBJECT),
* we silently assume here that this error will only come errmsg("user \"%s\" is already in group \"%s\"",
* up in a ALTER GROUP statement strVal(lfirst(item)), stmt->name)));
*/
elog(WARNING, "%s: user \"%s\" is already in group \"%s\"",
tag, strVal(lfirst(item)), stmt->name);
} }
/* Do the update */ /* Do the update */
@ -1442,7 +1512,10 @@ AlterGroup(AlterGroupStmt *stmt, const char *tag)
if (newlist == NIL) if (newlist == NIL)
{ {
if (!is_dropuser) if (!is_dropuser)
elog(WARNING, "ALTER GROUP: group \"%s\" does not have any members", stmt->name); ereport(WARNING,
(errcode(ERRCODE_WARNING),
errmsg("group \"%s\" does not have any members",
stmt->name)));
} }
else else
{ {
@ -1467,7 +1540,10 @@ AlterGroup(AlterGroupStmt *stmt, const char *tag)
if (intMember(sysid, newlist)) if (intMember(sysid, newlist))
newlist = lremovei(sysid, newlist); newlist = lremovei(sysid, newlist);
else if (!is_dropuser) else if (!is_dropuser)
elog(WARNING, "ALTER GROUP: user \"%s\" is not in group \"%s\"", strVal(lfirst(item)), stmt->name); ereport(WARNING,
(errcode(ERRCODE_WARNING),
errmsg("user \"%s\" is not in group \"%s\"",
strVal(lfirst(item)), stmt->name)));
} }
/* Do the update */ /* Do the update */
@ -1596,7 +1672,9 @@ DropGroup(DropGroupStmt *stmt)
* Make sure the user can do this. * Make sure the user can do this.
*/ */
if (!superuser()) if (!superuser())
elog(ERROR, "DROP GROUP: permission denied"); ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("permission denied")));
/* /*
* Secure exclusive lock to protect our update of the flat group file. * Secure exclusive lock to protect our update of the flat group file.
@ -1609,7 +1687,9 @@ DropGroup(DropGroupStmt *stmt)
PointerGetDatum(stmt->name), PointerGetDatum(stmt->name),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(tuple)) if (!HeapTupleIsValid(tuple))
elog(ERROR, "DROP GROUP: group \"%s\" does not exist", stmt->name); ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("group \"%s\" does not exist", stmt->name)));
simple_heap_delete(pg_group_rel, &tuple->t_self); simple_heap_delete(pg_group_rel, &tuple->t_self);
@ -1643,23 +1723,21 @@ RenameGroup(const char *oldname, const char *newname)
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(tup)) if (!HeapTupleIsValid(tup))
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR_OR_ACCESS_RULE_VIOLATION), (errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("group \"%s\" does not exist", oldname))); errmsg("group \"%s\" does not exist", oldname)));
/* make sure the new name doesn't exist */ /* make sure the new name doesn't exist */
if (SearchSysCacheExists(GRONAME, if (SearchSysCacheExists(GRONAME,
CStringGetDatum(newname), CStringGetDatum(newname),
0, 0, 0)) 0, 0, 0))
{
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR_OR_ACCESS_RULE_VIOLATION), (errcode(ERRCODE_DUPLICATE_OBJECT),
errmsg("a group \"%s\" already exists", newname))); errmsg("group \"%s\" already exists", newname)));
}
/* must be superuser */ /* must be superuser */
if (!superuser()) if (!superuser())
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR_OR_ACCESS_RULE_VIOLATION), (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("permission denied"))); errmsg("permission denied")));
/* rename */ /* rename */

View File

@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.279 2003/07/16 17:25:48 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.280 2003/07/18 23:20:32 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -3095,11 +3095,15 @@ check_parameter_resolution_walker(Node *node,
if (paramno <= 0 || /* shouldn't happen, but... */ if (paramno <= 0 || /* shouldn't happen, but... */
paramno > context->numParams) paramno > context->numParams)
elog(ERROR, "Parameter '$%d' is out of range", paramno); ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_PARAMETER),
errmsg("there is no parameter $%d", paramno)));
if (param->paramtype != context->paramTypes[paramno-1]) if (param->paramtype != context->paramTypes[paramno-1])
elog(ERROR, "Could not determine datatype of parameter $%d", ereport(ERROR,
paramno); (errcode(ERRCODE_AMBIGUOUS_PARAMETER),
errmsg("could not determine datatype of parameter $%d",
paramno)));
} }
return false; return false;
} }

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/parse_coerce.c,v 2.103 2003/07/03 19:07:48 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/parser/parse_coerce.c,v 2.104 2003/07/18 23:20:32 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -228,7 +228,9 @@ coerce_type(ParseState *pstate, Node *node,
if (paramno <= 0 || /* shouldn't happen, but... */ if (paramno <= 0 || /* shouldn't happen, but... */
paramno > toppstate->p_numparams) paramno > toppstate->p_numparams)
elog(ERROR, "Parameter '$%d' is out of range", paramno); ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_PARAMETER),
errmsg("there is no parameter $%d", paramno)));
if (toppstate->p_paramtypes[paramno-1] == UNKNOWNOID) if (toppstate->p_paramtypes[paramno-1] == UNKNOWNOID)
{ {
@ -242,11 +244,13 @@ coerce_type(ParseState *pstate, Node *node,
else else
{ {
/* Ooops */ /* Ooops */
elog(ERROR, "Inconsistent types deduced for parameter '$%d'" ereport(ERROR,
"\n\tCould be either %s or %s", (errcode(ERRCODE_AMBIGUOUS_PARAMETER),
paramno, errmsg("inconsistent types deduced for parameter $%d",
format_type_be(toppstate->p_paramtypes[paramno-1]), paramno),
format_type_be(targetTypeId)); errdetail("Could be either %s or %s.",
format_type_be(toppstate->p_paramtypes[paramno-1]),
format_type_be(targetTypeId))));
} }
param->paramtype = targetTypeId; param->paramtype = targetTypeId;

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.155 2003/07/03 16:34:16 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.156 2003/07/18 23:20:32 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -128,13 +128,16 @@ transformExpr(ParseState *pstate, Node *expr)
/* Check parameter number is in range */ /* Check parameter number is in range */
if (paramno <= 0) /* probably can't happen? */ if (paramno <= 0) /* probably can't happen? */
elog(ERROR, "Parameter '$%d' is out of range", ereport(ERROR,
paramno); (errcode(ERRCODE_UNDEFINED_PARAMETER),
errmsg("there is no parameter $%d", paramno)));
if (paramno > toppstate->p_numparams) if (paramno > toppstate->p_numparams)
{ {
if (!toppstate->p_variableparams) if (!toppstate->p_variableparams)
elog(ERROR, "Parameter '$%d' is out of range", ereport(ERROR,
paramno); (errcode(ERRCODE_UNDEFINED_PARAMETER),
errmsg("there is no parameter $%d",
paramno)));
/* Okay to enlarge param array */ /* Okay to enlarge param array */
if (toppstate->p_paramtypes) if (toppstate->p_paramtypes)
toppstate->p_paramtypes = toppstate->p_paramtypes =

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.153 2003/07/04 02:51:33 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.154 2003/07/18 23:20:32 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -84,15 +84,15 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs,
* function, but the test doesn't hurt. * function, but the test doesn't hurt.
*/ */
if (nargs > FUNC_MAX_ARGS) if (nargs > FUNC_MAX_ARGS)
elog(ERROR, "Cannot pass more than %d arguments to a function", ereport(ERROR,
FUNC_MAX_ARGS); (errcode(ERRCODE_TOO_MANY_ARGUMENTS),
errmsg("cannot pass more than %d arguments to a function",
FUNC_MAX_ARGS)));
if (fargs) if (fargs)
{ {
first_arg = lfirst(fargs); first_arg = lfirst(fargs);
if (first_arg == NULL) /* should not happen */ Assert(first_arg != NULL);
elog(ERROR, "Function '%s' does not allow NULL input",
NameListToString(funcname));
} }
/* /*
@ -179,7 +179,7 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs,
case RTE_RELATION: case RTE_RELATION:
toid = get_rel_type_id(rte->relid); toid = get_rel_type_id(rte->relid);
if (!OidIsValid(toid)) if (!OidIsValid(toid))
elog(ERROR, "Cannot find type OID for relation %u", elog(ERROR, "cannot find type OID for relation %u",
rte->relid); rte->relid);
/* replace RangeVar in the arg list */ /* replace RangeVar in the arg list */
lfirst(i) = makeVar(vnum, lfirst(i) = makeVar(vnum,
@ -219,8 +219,10 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs,
unknown_attribute(schemaname, relname, unknown_attribute(schemaname, relname,
strVal(lfirst(funcname))); strVal(lfirst(funcname)));
else else
elog(ERROR, "Cannot pass result of sub-select or join %s to a function", ereport(ERROR,
relname); (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("cannot pass result of sub-select or join %s to a function",
relname)));
toid = InvalidOid; /* keep compiler quiet */ toid = InvalidOid; /* keep compiler quiet */
break; break;
} }
@ -258,11 +260,16 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs,
* an aggregate? * an aggregate?
*/ */
if (agg_star) if (agg_star)
elog(ERROR, "%s(*) specified, but %s is not an aggregate function", ereport(ERROR,
NameListToString(funcname), NameListToString(funcname)); (errcode(ERRCODE_WRONG_OBJECT_TYPE),
errmsg("%s(*) specified, but %s is not an aggregate function",
NameListToString(funcname),
NameListToString(funcname))));
if (agg_distinct) if (agg_distinct)
elog(ERROR, "DISTINCT specified, but %s is not an aggregate function", ereport(ERROR,
NameListToString(funcname)); (errcode(ERRCODE_WRONG_OBJECT_TYPE),
errmsg("DISTINCT specified, but %s is not an aggregate function",
NameListToString(funcname))));
} }
else if (fdresult != FUNCDETAIL_AGGREGATE) else if (fdresult != FUNCDETAIL_AGGREGATE)
{ {
@ -284,11 +291,15 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs,
colname); colname);
relTypeId = exprType(first_arg); relTypeId = exprType(first_arg);
if (!ISCOMPLEX(relTypeId)) if (!ISCOMPLEX(relTypeId))
elog(ERROR, "Attribute notation .%s applied to type %s, which is not a complex type", ereport(ERROR,
colname, format_type_be(relTypeId)); (errcode(ERRCODE_WRONG_OBJECT_TYPE),
errmsg("attribute notation .%s applied to type %s, which is not a complex type",
colname, format_type_be(relTypeId))));
else else
elog(ERROR, "Attribute \"%s\" not found in datatype %s", ereport(ERROR,
colname, format_type_be(relTypeId)); (errcode(ERRCODE_UNDEFINED_COLUMN),
errmsg("attribute \"%s\" not found in datatype %s",
colname, format_type_be(relTypeId))));
} }
/* /*
@ -302,7 +313,6 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs,
actual_arg_types)), actual_arg_types)),
errhint("Unable to choose a best candidate function. " errhint("Unable to choose a best candidate function. "
"You may need to add explicit typecasts."))); "You may need to add explicit typecasts.")));
else else
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_FUNCTION), (errcode(ERRCODE_UNDEFINED_FUNCTION),
@ -356,7 +366,9 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs,
retval = (Node *) aggref; retval = (Node *) aggref;
if (retset) if (retset)
elog(ERROR, "Aggregates may not return sets"); ereport(ERROR,
(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
errmsg("aggregates may not return sets")));
} }
return retval; return retval;
@ -921,7 +933,7 @@ func_get_detail(List *funcname,
ObjectIdGetDatum(best_candidate->oid), ObjectIdGetDatum(best_candidate->oid),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(ftup)) /* should not happen */ if (!HeapTupleIsValid(ftup)) /* should not happen */
elog(ERROR, "cache lookup of function %u failed", elog(ERROR, "cache lookup failed for function %u",
best_candidate->oid); best_candidate->oid);
pform = (Form_pg_proc) GETSTRUCT(ftup); pform = (Form_pg_proc) GETSTRUCT(ftup);
*rettype = pform->prorettype; *rettype = pform->prorettype;
@ -1249,8 +1261,10 @@ setup_field_select(Node *input, char *attname, Oid relid)
attno = get_attnum(relid, attname); attno = get_attnum(relid, attname);
if (attno == InvalidAttrNumber) if (attno == InvalidAttrNumber)
elog(ERROR, "Relation \"%s\" has no column \"%s\"", ereport(ERROR,
get_rel_name(relid), attname); (errcode(ERRCODE_UNDEFINED_COLUMN),
errmsg("relation \"%s\" has no column \"%s\"",
get_rel_name(relid), attname)));
fselect->arg = (Expr *) input; fselect->arg = (Expr *) input;
fselect->fieldnum = attno; fselect->fieldnum = attno;
@ -1323,18 +1337,22 @@ ParseComplexProjection(char *funcname, Node *first_arg)
} }
/* /*
* Simple helper routine for delivering "No such attribute" error message * Simple helper routine for delivering "no such attribute" error message
*/ */
static void static void
unknown_attribute(const char *schemaname, const char *relname, unknown_attribute(const char *schemaname, const char *relname,
const char *attname) const char *attname)
{ {
if (schemaname) if (schemaname)
elog(ERROR, "No such attribute %s.%s.%s", ereport(ERROR,
schemaname, relname, attname); (errcode(ERRCODE_UNDEFINED_COLUMN),
errmsg("no such attribute %s.%s.%s",
schemaname, relname, attname)));
else else
elog(ERROR, "No such attribute %s.%s", ereport(ERROR,
relname, attname); (errcode(ERRCODE_UNDEFINED_COLUMN),
errmsg("no such attribute %s.%s",
relname, attname)));
} }
/* /*
@ -1389,11 +1407,16 @@ find_aggregate_func(List *aggname, Oid basetype, bool noError)
if (noError) if (noError)
return InvalidOid; return InvalidOid;
if (basetype == ANYOID) if (basetype == ANYOID)
elog(ERROR, "aggregate %s(*) does not exist", ereport(ERROR,
NameListToString(aggname)); (errcode(ERRCODE_UNDEFINED_FUNCTION),
errmsg("aggregate %s(*) does not exist",
NameListToString(aggname))));
else else
elog(ERROR, "aggregate %s(%s) does not exist", ereport(ERROR,
NameListToString(aggname), format_type_be(basetype)); (errcode(ERRCODE_UNDEFINED_FUNCTION),
errmsg("aggregate %s(%s) does not exist",
NameListToString(aggname),
format_type_be(basetype))));
} }
/* Make sure it's an aggregate */ /* Make sure it's an aggregate */
@ -1401,7 +1424,7 @@ find_aggregate_func(List *aggname, Oid basetype, bool noError)
ObjectIdGetDatum(oid), ObjectIdGetDatum(oid),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(ftup)) /* should not happen */ if (!HeapTupleIsValid(ftup)) /* should not happen */
elog(ERROR, "function %u not found", oid); elog(ERROR, "cache lookup failed for function %u", oid);
pform = (Form_pg_proc) GETSTRUCT(ftup); pform = (Form_pg_proc) GETSTRUCT(ftup);
if (!pform->proisagg) if (!pform->proisagg)
@ -1410,8 +1433,10 @@ find_aggregate_func(List *aggname, Oid basetype, bool noError)
if (noError) if (noError)
return InvalidOid; return InvalidOid;
/* we do not use the (*) notation for functions... */ /* we do not use the (*) notation for functions... */
elog(ERROR, "function %s(%s) is not an aggregate", ereport(ERROR,
NameListToString(aggname), format_type_be(basetype)); (errcode(ERRCODE_WRONG_OBJECT_TYPE),
errmsg("function %s(%s) is not an aggregate",
NameListToString(aggname), format_type_be(basetype))));
} }
ReleaseSysCache(ftup); ReleaseSysCache(ftup);
@ -1445,8 +1470,10 @@ LookupFuncName(List *funcname, int nargs, const Oid *argtypes, bool noError)
} }
if (!noError) if (!noError)
elog(ERROR, "function %s does not exist", ereport(ERROR,
func_signature_string(funcname, nargs, argtypes)); (errcode(ERRCODE_UNDEFINED_FUNCTION),
errmsg("function %s does not exist",
func_signature_string(funcname, nargs, argtypes))));
return InvalidOid; return InvalidOid;
} }
@ -1466,8 +1493,10 @@ LookupFuncNameTypeNames(List *funcname, List *argtypes, bool noError)
MemSet(argoids, 0, FUNC_MAX_ARGS * sizeof(Oid)); MemSet(argoids, 0, FUNC_MAX_ARGS * sizeof(Oid));
argcount = length(argtypes); argcount = length(argtypes);
if (argcount > FUNC_MAX_ARGS) if (argcount > FUNC_MAX_ARGS)
elog(ERROR, "functions cannot have more than %d arguments", ereport(ERROR,
FUNC_MAX_ARGS); (errcode(ERRCODE_TOO_MANY_ARGUMENTS),
errmsg("functions cannot have more than %d arguments",
FUNC_MAX_ARGS)));
for (i = 0; i < argcount; i++) for (i = 0; i < argcount; i++)
{ {
@ -1476,8 +1505,10 @@ LookupFuncNameTypeNames(List *funcname, List *argtypes, bool noError)
argoids[i] = LookupTypeName(t); argoids[i] = LookupTypeName(t);
if (!OidIsValid(argoids[i])) if (!OidIsValid(argoids[i]))
elog(ERROR, "Type \"%s\" does not exist", ereport(ERROR,
TypeNameToString(t)); (errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("type \"%s\" does not exist",
TypeNameToString(t))));
argtypes = lnext(argtypes); argtypes = lnext(argtypes);
} }

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/parse_oper.c,v 1.69 2003/07/04 02:51:33 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/parser/parse_oper.c,v 1.70 2003/07/18 23:20:32 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -107,8 +107,10 @@ LookupOperNameTypeNames(List *opername, TypeName *oprleft,
{ {
leftoid = LookupTypeName(oprleft); leftoid = LookupTypeName(oprleft);
if (!OidIsValid(leftoid)) if (!OidIsValid(leftoid))
elog(ERROR, "type %s does not exist", ereport(ERROR,
TypeNameToString(oprleft)); (errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("type %s does not exist",
TypeNameToString(oprleft))));
} }
if (oprright == NULL) if (oprright == NULL)
rightoid = InvalidOid; rightoid = InvalidOid;
@ -116,8 +118,10 @@ LookupOperNameTypeNames(List *opername, TypeName *oprleft,
{ {
rightoid = LookupTypeName(oprright); rightoid = LookupTypeName(oprright);
if (!OidIsValid(rightoid)) if (!OidIsValid(rightoid))
elog(ERROR, "type %s does not exist", ereport(ERROR,
TypeNameToString(oprright)); (errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("type %s does not exist",
TypeNameToString(oprright))));
} }
return LookupOperName(opername, leftoid, rightoid, noError); return LookupOperName(opername, leftoid, rightoid, noError);
@ -178,8 +182,10 @@ equality_oper(Oid argtype, bool noError)
} }
} }
if (!noError) if (!noError)
elog(ERROR, "unable to identify an equality operator for type %s", ereport(ERROR,
format_type_be(argtype)); (errcode(ERRCODE_UNDEFINED_FUNCTION),
errmsg("unable to identify an equality operator for type %s",
format_type_be(argtype))));
return NULL; return NULL;
} }
@ -239,9 +245,11 @@ ordering_oper(Oid argtype, bool noError)
} }
} }
if (!noError) if (!noError)
elog(ERROR, "unable to identify an ordering operator for type %s" ereport(ERROR,
"\n\tUse an explicit ordering operator or modify the query", (errcode(ERRCODE_UNDEFINED_FUNCTION),
format_type_be(argtype)); errmsg("unable to identify an ordering operator for type %s",
format_type_be(argtype)),
errhint("Use an explicit ordering operator or modify the query.")));
return NULL; return NULL;
} }
@ -483,8 +491,10 @@ compatible_oper(List *op, Oid arg1, Oid arg2, bool noError)
ReleaseSysCache(optup); ReleaseSysCache(optup);
if (!noError) if (!noError)
elog(ERROR, "operator requires run-time type coercion: %s", ereport(ERROR,
op_signature_string(op, 'b', arg1, arg2)); (errcode(ERRCODE_UNDEFINED_FUNCTION),
errmsg("operator requires run-time type coercion: %s",
op_signature_string(op, 'b', arg1, arg2))));
return (Operator) NULL; return (Operator) NULL;
} }
@ -773,7 +783,9 @@ make_scalar_array_op(ParseState *pstate, List *opname,
{ {
rtypeId = get_element_type(atypeId); rtypeId = get_element_type(atypeId);
if (!OidIsValid(rtypeId)) if (!OidIsValid(rtypeId))
elog(ERROR, "op ANY/ALL (array) requires array on right side"); ereport(ERROR,
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
errmsg("op ANY/ALL (array) requires array on right side")));
} }
/* Now resolve the operator */ /* Now resolve the operator */
@ -800,9 +812,13 @@ make_scalar_array_op(ParseState *pstate, List *opname,
* Check that operator result is boolean * Check that operator result is boolean
*/ */
if (rettype != BOOLOID) if (rettype != BOOLOID)
elog(ERROR, "op ANY/ALL (array) requires operator to yield boolean"); ereport(ERROR,
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
errmsg("op ANY/ALL (array) requires operator to yield boolean")));
if (get_func_retset(opform->oprcode)) if (get_func_retset(opform->oprcode))
elog(ERROR, "op ANY/ALL (array) requires operator not to return a set"); ereport(ERROR,
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
errmsg("op ANY/ALL (array) requires operator not to return a set")));
/* /*
* Now switch back to the array type on the right, arranging for * Now switch back to the array type on the right, arranging for
@ -810,8 +826,10 @@ make_scalar_array_op(ParseState *pstate, List *opname,
*/ */
res_atypeId = get_array_type(declared_arg_types[1]); res_atypeId = get_array_type(declared_arg_types[1]);
if (!OidIsValid(res_atypeId)) if (!OidIsValid(res_atypeId))
elog(ERROR, "unable to find datatype for array of %s", ereport(ERROR,
format_type_be(declared_arg_types[1])); (errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("unable to find datatype for array of %s",
format_type_be(declared_arg_types[1]))));
actual_arg_types[1] = atypeId; actual_arg_types[1] = atypeId;
declared_arg_types[1] = res_atypeId; declared_arg_types[1] = res_atypeId;

View File

@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/scan.l,v 1.108 2003/06/19 23:22:40 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/parser/scan.l,v 1.109 2003/07/18 23:20:32 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -403,8 +403,10 @@ other .
len = pg_mbcliplen(literalbuf, literallen, len = pg_mbcliplen(literalbuf, literallen,
NAMEDATALEN-1); NAMEDATALEN-1);
elog(NOTICE, "identifier \"%s\" will be truncated to \"%.*s\"", ereport(NOTICE,
literalbuf, len, literalbuf); (errcode(ERRCODE_NAME_TOO_LONG),
errmsg("identifier \"%s\" will be truncated to \"%.*s\"",
literalbuf, len, literalbuf)));
literalbuf[len] = '\0'; literalbuf[len] = '\0';
literallen = len; literallen = len;
} }
@ -559,8 +561,10 @@ other .
int len; int len;
len = pg_mbcliplen(ident, i, NAMEDATALEN-1); len = pg_mbcliplen(ident, i, NAMEDATALEN-1);
elog(NOTICE, "identifier \"%s\" will be truncated to \"%.*s\"", ereport(NOTICE,
ident, len, ident); (errcode(ERRCODE_NAME_TOO_LONG),
errmsg("identifier \"%s\" will be truncated to \"%.*s\"",
ident, len, ident)));
ident[len] = '\0'; ident[len] = '\0';
} }
yylval.str = ident; yylval.str = ident;
@ -582,16 +586,18 @@ yyerror(const char *message)
if (*loc == YY_END_OF_BUFFER_CHAR) if (*loc == YY_END_OF_BUFFER_CHAR)
{ {
/* translator: %s is typically "syntax error" */
ereport(ERROR, ereport(ERROR,
(errmsg("%s at end of input", message), (errcode(ERRCODE_SYNTAX_ERROR),
/* translator: %s is typically "syntax error" */
errmsg("%s at end of input", message),
errposition(cursorpos))); errposition(cursorpos)));
} }
else else
{ {
/* translator: first %s is typically "syntax error" */
ereport(ERROR, ereport(ERROR,
(errmsg("%s at or near \"%s\"", message, loc), (errcode(ERRCODE_SYNTAX_ERROR),
/* translator: first %s is typically "syntax error" */
errmsg("%s at or near \"%s\"", message, loc),
errposition(cursorpos))); errposition(cursorpos)));
} }
} }

View File

@ -37,7 +37,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/error/elog.c,v 1.112 2003/06/30 16:47:01 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/error/elog.c,v 1.113 2003/07/18 23:20:32 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -288,7 +288,13 @@ errstart(int elevel, const char *filename, int lineno,
edata->filename = filename; edata->filename = filename;
edata->lineno = lineno; edata->lineno = lineno;
edata->funcname = funcname; edata->funcname = funcname;
edata->sqlerrcode = ERRCODE_INTERNAL_ERROR; /* default errcode */ /* Select default errcode based on elevel */
if (elevel >= ERROR)
edata->sqlerrcode = ERRCODE_INTERNAL_ERROR;
else if (elevel == WARNING)
edata->sqlerrcode = ERRCODE_WARNING;
else
edata->sqlerrcode = ERRCODE_SUCCESSFUL_COMPLETION;
/* errno is saved here so that error parameter eval can't change it */ /* errno is saved here so that error parameter eval can't change it */
edata->saved_errno = errno; edata->saved_errno = errno;
@ -497,6 +503,76 @@ errcode(int sqlerrcode)
} }
/*
* errcode_for_file_access --- add SQLSTATE error code to the current error
*
* The SQLSTATE code is chosen based on the saved errno value. We assume
* that the failing operation was some type of disk file access.
*
* NOTE: the primary error message string should generally include %m
* when this is used.
*/
int
errcode_for_file_access(void)
{
ErrorData *edata = &errordata[errordata_stack_depth];
/* we don't bother incrementing recursion_depth */
CHECK_STACK_DEPTH();
switch (edata->saved_errno)
{
/* Permission-denied failures */
case EPERM: /* Not super-user */
case EACCES: /* Permission denied */
#ifdef EROFS
case EROFS: /* Read only file system */
#endif
edata->sqlerrcode = ERRCODE_INSUFFICIENT_PRIVILEGE;
break;
/* Object not found */
case ENOENT: /* No such file or directory */
edata->sqlerrcode = ERRCODE_UNDEFINED_OBJECT;
break;
/* Duplicate object */
case EEXIST: /* File exists */
edata->sqlerrcode = ERRCODE_DUPLICATE_OBJECT;
break;
/* Wrong object type or state */
case ENOTDIR: /* Not a directory */
case EISDIR: /* Is a directory */
case ENOTEMPTY: /* Directory not empty */
edata->sqlerrcode = ERRCODE_WRONG_OBJECT_TYPE;
break;
/* Insufficient resources */
case ENOSPC: /* No space left on device */
edata->sqlerrcode = ERRCODE_DISK_FULL;
break;
case ENFILE: /* File table overflow */
case EMFILE: /* Too many open files */
edata->sqlerrcode = ERRCODE_INSUFFICIENT_RESOURCES;
break;
/* Hardware failure */
case EIO: /* I/O error */
edata->sqlerrcode = ERRCODE_IO_ERROR;
break;
/* All else is classified as internal errors */
default:
edata->sqlerrcode = ERRCODE_INTERNAL_ERROR;
break;
}
return 0; /* return value does not matter */
}
/* /*
* This macro handles expansion of a format string and associated parameters; * This macro handles expansion of a format string and associated parameters;
* it's common code for errmsg(), errdetail(), etc. Must be called inside * it's common code for errmsg(), errdetail(), etc. Must be called inside
@ -759,7 +835,8 @@ DebugFileOpen(void)
if ((fd = open(OutputFileName, O_CREAT | O_APPEND | O_WRONLY, if ((fd = open(OutputFileName, O_CREAT | O_APPEND | O_WRONLY,
0666)) < 0) 0666)) < 0)
ereport(FATAL, ereport(FATAL,
(errmsg("failed to open %s: %m", OutputFileName))); (errcode_for_file_access(),
errmsg("failed to open \"%s\": %m", OutputFileName)));
istty = isatty(fd); istty = isatty(fd);
close(fd); close(fd);
@ -768,7 +845,8 @@ DebugFileOpen(void)
*/ */
if (!freopen(OutputFileName, "a", stderr)) if (!freopen(OutputFileName, "a", stderr))
ereport(FATAL, ereport(FATAL,
(errmsg("failed to reopen %s as stderr: %m", (errcode_for_file_access(),
errmsg("failed to reopen \"%s\" as stderr: %m",
OutputFileName))); OutputFileName)));
/* /*
@ -780,7 +858,8 @@ DebugFileOpen(void)
if (istty && IsUnderPostmaster) if (istty && IsUnderPostmaster)
if (!freopen(OutputFileName, "a", stdout)) if (!freopen(OutputFileName, "a", stdout))
ereport(FATAL, ereport(FATAL,
(errmsg("failed to reopen %s as stdout: %m", (errcode_for_file_access(),
errmsg("failed to reopen \"%s\" as stdout: %m",
OutputFileName))); OutputFileName)));
} }
} }

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/fmgr/dfmgr.c,v 1.60 2003/05/27 17:49:46 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/fmgr/dfmgr.c,v 1.61 2003/07/18 23:20:32 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -58,7 +58,7 @@ static char *substitute_libpath_macro(const char *name);
* *
* If the function is not found, we raise an error if signalNotFound is true, * If the function is not found, we raise an error if signalNotFound is true,
* else return (PGFunction) NULL. Note that errors in loading the library * else return (PGFunction) NULL. Note that errors in loading the library
* will provoke elog regardless of signalNotFound. * will provoke ereport() regardless of signalNotFound.
* *
* If filehandle is not NULL, then *filehandle will be set to a handle * If filehandle is not NULL, then *filehandle will be set to a handle
* identifying the library file. The filehandle can be used with * identifying the library file. The filehandle can be used with
@ -94,7 +94,9 @@ load_external_function(char *filename, char *funcname,
* Check for same files - different paths (ie, symlink or link) * Check for same files - different paths (ie, symlink or link)
*/ */
if (stat(fullname, &stat_buf) == -1) if (stat(fullname, &stat_buf) == -1)
elog(ERROR, "stat failed on file '%s': %m", fullname); ereport(ERROR,
(errcode_for_file_access(),
errmsg("could not access file \"%s\": %m", fullname)));
for (file_scanner = file_list; for (file_scanner = file_list;
file_scanner != (DynamicFileList *) NULL && file_scanner != (DynamicFileList *) NULL &&
@ -111,7 +113,9 @@ load_external_function(char *filename, char *funcname,
file_scanner = (DynamicFileList *) file_scanner = (DynamicFileList *)
malloc(sizeof(DynamicFileList) + strlen(fullname)); malloc(sizeof(DynamicFileList) + strlen(fullname));
if (file_scanner == NULL) if (file_scanner == NULL)
elog(ERROR, "Out of memory in load_external_function"); ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_RESOURCES),
errmsg("out of memory")));
MemSet((char *) file_scanner, 0, sizeof(DynamicFileList)); MemSet((char *) file_scanner, 0, sizeof(DynamicFileList));
strcpy(file_scanner->filename, fullname); strcpy(file_scanner->filename, fullname);
@ -124,7 +128,11 @@ load_external_function(char *filename, char *funcname,
{ {
load_error = (char *) pg_dlerror(); load_error = (char *) pg_dlerror();
free((char *) file_scanner); free((char *) file_scanner);
elog(ERROR, "Load of file %s failed: %s", fullname, load_error); /* errcode_for_file_access might not be appropriate here? */
ereport(ERROR,
(errcode_for_file_access(),
errmsg("could not load library \"%s\": %s",
fullname, load_error)));
} }
/* OK to link it into list */ /* OK to link it into list */
@ -151,7 +159,10 @@ load_external_function(char *filename, char *funcname,
retval = pg_dlsym(file_scanner->handle, funcname); retval = pg_dlsym(file_scanner->handle, funcname);
if (retval == (PGFunction) NULL && signalNotFound) if (retval == (PGFunction) NULL && signalNotFound)
elog(ERROR, "Can't find function %s in file %s", funcname, fullname); ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_FUNCTION),
errmsg("could not find function \"%s\" in file \"%s\"",
funcname, fullname)));
pfree(fullname); pfree(fullname);
return retval; return retval;
@ -181,7 +192,9 @@ load_file(char *filename)
* good error message if bogus file name given. * good error message if bogus file name given.
*/ */
if (stat(fullname, &stat_buf) == -1) if (stat(fullname, &stat_buf) == -1)
elog(ERROR, "LOAD: could not open file '%s': %m", fullname); ereport(ERROR,
(errcode_for_file_access(),
errmsg("could not access file \"%s\": %m", fullname)));
if (file_list != (DynamicFileList *) NULL) if (file_list != (DynamicFileList *) NULL)
{ {
@ -236,7 +249,9 @@ file_exists(const char *name)
if (stat(name, &st) == 0) if (stat(name, &st) == 0)
return S_ISDIR(st.st_mode) ? false : true; return S_ISDIR(st.st_mode) ? false : true;
else if (!(errno == ENOENT || errno == ENOTDIR || errno == EACCES)) else if (!(errno == ENOENT || errno == ENOTDIR || errno == EACCES))
elog(ERROR, "stat failed on %s: %s", name, strerror(errno)); ereport(ERROR,
(errcode_for_file_access(),
errmsg("could not access file \"%s\": %m", name)));
return false; return false;
} }
@ -335,7 +350,9 @@ substitute_libpath_macro(const char *name)
if (strncmp(name, "$libdir", macroname_len) == 0) if (strncmp(name, "$libdir", macroname_len) == 0)
replacement = PKGLIBDIR; replacement = PKGLIBDIR;
else else
elog(ERROR, "invalid macro name in dynamic library path"); ereport(ERROR,
(errcode(ERRCODE_INVALID_NAME),
errmsg("invalid macro name in dynamic library path")));
if (name[macroname_len] == '\0') if (name[macroname_len] == '\0')
return pstrdup(replacement); return pstrdup(replacement);
@ -385,7 +402,9 @@ find_in_dynamic_libpath(const char *basename)
len = strcspn(p, ":"); len = strcspn(p, ":");
if (len == 0) if (len == 0)
elog(ERROR, "zero length dynamic_library_path component"); ereport(ERROR,
(errcode(ERRCODE_INVALID_NAME),
errmsg("zero-length component in DYNAMIC_LIBRARY_PATH")));
piece = palloc(len + 1); piece = palloc(len + 1);
strncpy(piece, p, len); strncpy(piece, p, len);
@ -396,13 +415,15 @@ find_in_dynamic_libpath(const char *basename)
/* only absolute paths */ /* only absolute paths */
if (!is_absolute_path(mangled)) if (!is_absolute_path(mangled))
elog(ERROR, "dynamic_library_path component is not absolute"); ereport(ERROR,
(errcode(ERRCODE_INVALID_NAME),
errmsg("DYNAMIC_LIBRARY_PATH component is not absolute")));
full = palloc(strlen(mangled) + 1 + baselen + 1); full = palloc(strlen(mangled) + 1 + baselen + 1);
sprintf(full, "%s/%s", mangled, basename); sprintf(full, "%s/%s", mangled, basename);
pfree(mangled); pfree(mangled);
elog(DEBUG3, "find_in_dynamic_libpath: trying %s", full); elog(DEBUG3, "find_in_dynamic_libpath: trying \"%s\"", full);
if (file_exists(full)) if (file_exists(full))
return full; return full;

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: elog.h,v 1.47 2003/07/14 23:36:15 tgl Exp $ * $Id: elog.h,v 1.48 2003/07/18 23:20:32 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -177,31 +177,62 @@
#define ERRCODE_INTERNAL_ERROR MAKE_SQLSTATE('X','X', '0','0','0') #define ERRCODE_INTERNAL_ERROR MAKE_SQLSTATE('X','X', '0','0','0')
#define ERRCODE_INSUFFICIENT_PRIVILEGE MAKE_SQLSTATE('4','2', '5','0','1') #define ERRCODE_INSUFFICIENT_PRIVILEGE MAKE_SQLSTATE('4','2', '5','0','1')
#define ERRCODE_SYNTAX_ERROR MAKE_SQLSTATE('4','2', '6','0','1') #define ERRCODE_SYNTAX_ERROR MAKE_SQLSTATE('4','2', '6','0','1')
#define ERRCODE_INVALID_NAME MAKE_SQLSTATE('4','2', '6','0','2')
#define ERRCODE_NAME_TOO_LONG MAKE_SQLSTATE('4','2', '6','2','2')
#define ERRCODE_RESERVED_NAME MAKE_SQLSTATE('4','2', '9','3','9')
#define ERRCODE_UNTERMINATED_LITERAL MAKE_SQLSTATE('4','2', '6','0','3') #define ERRCODE_UNTERMINATED_LITERAL MAKE_SQLSTATE('4','2', '6','0','3')
#define ERRCODE_INVALID_LITERAL MAKE_SQLSTATE('4','2', '6','0','6') #define ERRCODE_INVALID_LITERAL MAKE_SQLSTATE('4','2', '6','0','6')
#define ERRCODE_STATEMENT_TOO_COMPLEX MAKE_SQLSTATE('5','4', '0','0','1')
#define ERRCODE_TOO_MANY_ARGUMENTS MAKE_SQLSTATE('4','2', '6','0','5') #define ERRCODE_TOO_MANY_ARGUMENTS MAKE_SQLSTATE('4','2', '6','0','5')
#define ERRCODE_UNDEFINED_COLUMN MAKE_SQLSTATE('4','2', '7','0','3') #define ERRCODE_TOO_MANY_COLUMNS MAKE_SQLSTATE('5','4', '0','1','1')
/* /*
* Note: use the above SQL-standard error codes for undefined catalog, schema, * Note: use the above SQL-standard error codes for undefined catalog, schema,
* prepared statement, or cursor names. Curiously, they don't define error * prepared statement, and cursor names. Curiously, they don't define error
* codes for any other kinds of objects. We choose to define an errcode for * codes for any other kinds of objects. We choose to define separate error
* undefined tables, as well as one for functions (also used for operators); * codes for undefined table and column names, as well as one for functions
* all other names (rules, triggers, etc) are lumped as UNDEFINED_OBJECT. * (also used for operators). All other names (rules, triggers, etc) are
* The same breakdown is used for "ambiguous" and "duplicate" complaints. * lumped as UNDEFINED_OBJECT.
* The same breakdown is used for "ambiguous" and "duplicate" complaints,
* as well as complaints associated with incorrect declarations.
*/ */
#define ERRCODE_UNDEFINED_TABLE MAKE_SQLSTATE('4','2', '7','0','4') #define ERRCODE_UNDEFINED_COLUMN MAKE_SQLSTATE('4','2', '7','0','3')
#define ERRCODE_UNDEFINED_CURSOR ERRCODE_INVALID_CURSOR_NAME
#define ERRCODE_UNDEFINED_DATABASE ERRCODE_INVALID_CATALOG_NAME
#define ERRCODE_UNDEFINED_FUNCTION MAKE_SQLSTATE('4','2', '8','8','3') #define ERRCODE_UNDEFINED_FUNCTION MAKE_SQLSTATE('4','2', '8','8','3')
#define ERRCODE_UNDEFINED_PSTATEMENT ERRCODE_INVALID_SQL_STATEMENT_NAME
#define ERRCODE_UNDEFINED_SCHEMA ERRCODE_INVALID_SCHEMA_NAME
#define ERRCODE_UNDEFINED_TABLE MAKE_SQLSTATE('4','2', '7','0','4')
#define ERRCODE_UNDEFINED_OBJECT MAKE_SQLSTATE('4','2', '7','0','5') #define ERRCODE_UNDEFINED_OBJECT MAKE_SQLSTATE('4','2', '7','0','5')
#define ERRCODE_UNDEFINED_PARAMETER MAKE_SQLSTATE('4','2', '7','1','5')
#define ERRCODE_AMBIGUOUS_COLUMN MAKE_SQLSTATE('4','2', '7','0','2') #define ERRCODE_AMBIGUOUS_COLUMN MAKE_SQLSTATE('4','2', '7','0','2')
#define ERRCODE_AMBIGUOUS_FUNCTION MAKE_SQLSTATE('4','2', '7','2','5') #define ERRCODE_AMBIGUOUS_FUNCTION MAKE_SQLSTATE('4','2', '7','2','5')
#define ERRCODE_AMBIGUOUS_PARAMETER MAKE_SQLSTATE('4','2', '7','1','6')
#define ERRCODE_DUPLICATE_COLUMN MAKE_SQLSTATE('4','2', '7','1','1') #define ERRCODE_DUPLICATE_COLUMN MAKE_SQLSTATE('4','2', '7','1','1')
#define ERRCODE_DUPLICATE_TABLE MAKE_SQLSTATE('4','2', '7','2','2') #define ERRCODE_DUPLICATE_CURSOR ERRCODE_DUPLICATE_OBJECT
#define ERRCODE_DUPLICATE_DATABASE ERRCODE_DUPLICATE_OBJECT
#define ERRCODE_DUPLICATE_FUNCTION MAKE_SQLSTATE('4','2', '7','2','3') #define ERRCODE_DUPLICATE_FUNCTION MAKE_SQLSTATE('4','2', '7','2','3')
#define ERRCODE_DUPLICATE_PSTATEMENT ERRCODE_DUPLICATE_OBJECT
#define ERRCODE_DUPLICATE_SCHEMA ERRCODE_DUPLICATE_OBJECT
#define ERRCODE_DUPLICATE_TABLE MAKE_SQLSTATE('4','2', '7','2','2')
#define ERRCODE_DUPLICATE_OBJECT MAKE_SQLSTATE('4','2', '7','1','0') #define ERRCODE_DUPLICATE_OBJECT MAKE_SQLSTATE('4','2', '7','1','0')
#define ERRCODE_INVALID_COLUMN_DEFINITION MAKE_SQLSTATE('4','2', 'A','0','1')
#define ERRCODE_INVALID_CURSOR_DEFINITION MAKE_SQLSTATE('4','2', 'A','0','2')
#define ERRCODE_INVALID_DATABASE_DEFINITION MAKE_SQLSTATE('4','2', 'A','0','3')
#define ERRCODE_INVALID_FUNCTION_DEFINITION MAKE_SQLSTATE('4','2', 'A','0','4')
#define ERRCODE_INVALID_PSTATEMENT_DEFINITION MAKE_SQLSTATE('4','2', 'A','0','5')
#define ERRCODE_INVALID_SCHEMA_DEFINITION MAKE_SQLSTATE('4','2', 'A','0','6')
#define ERRCODE_INVALID_TABLE_DEFINITION MAKE_SQLSTATE('4','2', 'A','0','7')
#define ERRCODE_INVALID_OBJECT_DEFINITION MAKE_SQLSTATE('4','2', 'A','0','8')
#define ERRCODE_WRONG_OBJECT_TYPE MAKE_SQLSTATE('4','2', '8','0','9')
#define ERRCODE_OBJECT_IN_USE MAKE_SQLSTATE('5','5', '0','0','6')
#define ERRCODE_GROUPING_ERROR MAKE_SQLSTATE('4','2', '8','0','3') #define ERRCODE_GROUPING_ERROR MAKE_SQLSTATE('4','2', '8','0','3')
#define ERRCODE_TYPE_MISMATCH MAKE_SQLSTATE('4','2', '8','0','4') #define ERRCODE_TYPE_MISMATCH MAKE_SQLSTATE('4','2', '8','0','4')
#define ERRCODE_CANNOT_COERCE MAKE_SQLSTATE('4','2', '8','4','6') #define ERRCODE_CANNOT_COERCE MAKE_SQLSTATE('4','2', '8','4','6')
#define ERRCODE_INVALID_FOREIGN_KEY MAKE_SQLSTATE('4','2', '8','3','0') #define ERRCODE_INVALID_FOREIGN_KEY MAKE_SQLSTATE('4','2', '8','3','0')
#define ERRCODE_TOO_MANY_CONNECTIONS MAKE_SQLSTATE('5','7', '0','3','2')
#define ERRCODE_DISK_FULL MAKE_SQLSTATE('5','4', '1','0','0')
#define ERRCODE_INSUFFICIENT_RESOURCES MAKE_SQLSTATE('5','4', '2','0','0')
#define ERRCODE_IO_ERROR MAKE_SQLSTATE('5','8', '0','3','0')
/* Which __func__ symbol do we have, if any? */ /* Which __func__ symbol do we have, if any? */
@ -219,13 +250,15 @@
/*---------- /*----------
* New-style error reporting API: to be used in this way: * New-style error reporting API: to be used in this way:
* ereport(ERROR, * ereport(ERROR,
* (errcode(ERRCODE_INVALID_CURSOR_NAME), * (errcode(ERRCODE_UNDEFINED_CURSOR),
* errmsg("portal \"%s\" not found", stmt->portalname), * errmsg("portal \"%s\" not found", stmt->portalname),
* ... other errxxx() fields as needed ...)); * ... other errxxx() fields as needed ...));
* *
* The error level is required, and so is a primary error message (errmsg * The error level is required, and so is a primary error message (errmsg
* or errmsg_internal). All else is optional. errcode() defaults to * or errmsg_internal). All else is optional. errcode() defaults to
* ERRCODE_INTERNAL_ERROR. * ERRCODE_INTERNAL_ERROR if elevel is ERROR or more, ERRCODE_WARNING
* if elevel is WARNING, or ERRCODE_SUCCESSFUL_COMPLETION if elevel is
* NOTICE or below.
*---------- *----------
*/ */
#define ereport(elevel, rest) \ #define ereport(elevel, rest) \
@ -238,6 +271,8 @@ extern void errfinish(int dummy, ...);
extern int errcode(int sqlerrcode); extern int errcode(int sqlerrcode);
extern int errcode_for_file_access(void);
extern int errmsg(const char *fmt, ...) extern int errmsg(const char *fmt, ...)
/* This extension allows gcc to check the format string for consistency with /* This extension allows gcc to check the format string for consistency with
the supplied arguments. */ the supplied arguments. */

View File

@ -775,7 +775,7 @@ select atacc1.* from atacc1;
select a from atacc1; select a from atacc1;
ERROR: Attribute "a" not found ERROR: Attribute "a" not found
select atacc1.a from atacc1; select atacc1.a from atacc1;
ERROR: No such attribute atacc1.a ERROR: no such attribute atacc1.a
select b,c,d from atacc1; select b,c,d from atacc1;
b | c | d b | c | d
---+---+--- ---+---+---
@ -789,7 +789,7 @@ ERROR: Attribute "a" not found
select "........pg.dropped.1........" from atacc1; select "........pg.dropped.1........" from atacc1;
ERROR: Attribute "........pg.dropped.1........" not found ERROR: Attribute "........pg.dropped.1........" not found
select atacc1."........pg.dropped.1........" from atacc1; select atacc1."........pg.dropped.1........" from atacc1;
ERROR: No such attribute atacc1.........pg.dropped.1........ ERROR: no such attribute atacc1.........pg.dropped.1........
select "........pg.dropped.1........",b,c,d from atacc1; select "........pg.dropped.1........",b,c,d from atacc1;
ERROR: Attribute "........pg.dropped.1........" not found ERROR: Attribute "........pg.dropped.1........" not found
select * from atacc1 where "........pg.dropped.1........" = 1; select * from atacc1 where "........pg.dropped.1........" = 1;

View File

@ -19,22 +19,24 @@ CREATE FUNCTION int42_in(cstring)
RETURNS int42 RETURNS int42
AS 'int4in' AS 'int4in'
LANGUAGE 'internal' WITH (isStrict); LANGUAGE 'internal' WITH (isStrict);
NOTICE: ProcedureCreate: type int42 is not yet defined NOTICE: type int42 is not yet defined
DETAIL: Creating a shell type definition.
CREATE FUNCTION int42_out(int42) CREATE FUNCTION int42_out(int42)
RETURNS cstring RETURNS cstring
AS 'int4out' AS 'int4out'
LANGUAGE 'internal' WITH (isStrict); LANGUAGE 'internal' WITH (isStrict);
NOTICE: Argument type "int42" is only a shell NOTICE: argument type int42 is only a shell
CREATE FUNCTION text_w_default_in(cstring) CREATE FUNCTION text_w_default_in(cstring)
RETURNS text_w_default RETURNS text_w_default
AS 'textin' AS 'textin'
LANGUAGE 'internal' WITH (isStrict); LANGUAGE 'internal' WITH (isStrict);
NOTICE: ProcedureCreate: type text_w_default is not yet defined NOTICE: type text_w_default is not yet defined
DETAIL: Creating a shell type definition.
CREATE FUNCTION text_w_default_out(text_w_default) CREATE FUNCTION text_w_default_out(text_w_default)
RETURNS cstring RETURNS cstring
AS 'textout' AS 'textout'
LANGUAGE 'internal' WITH (isStrict); LANGUAGE 'internal' WITH (isStrict);
NOTICE: Argument type "text_w_default" is only a shell NOTICE: argument type text_w_default is only a shell
CREATE TYPE int42 ( CREATE TYPE int42 (
internallength = 4, internallength = 4,
input = int42_in, input = int42_in,

View File

@ -6,12 +6,12 @@ CREATE USER regressuser2;
CREATE USER regressuser3; CREATE USER regressuser3;
CREATE USER regressuser4; CREATE USER regressuser4;
CREATE USER regressuser4; -- duplicate CREATE USER regressuser4; -- duplicate
ERROR: CREATE USER: user name "regressuser4" already exists ERROR: user "regressuser4" already exists
CREATE GROUP regressgroup1; CREATE GROUP regressgroup1;
CREATE GROUP regressgroup2 WITH USER regressuser1, regressuser2; CREATE GROUP regressgroup2 WITH USER regressuser1, regressuser2;
ALTER GROUP regressgroup1 ADD USER regressuser4; ALTER GROUP regressgroup1 ADD USER regressuser4;
ALTER GROUP regressgroup2 ADD USER regressuser2; -- duplicate ALTER GROUP regressgroup2 ADD USER regressuser2; -- duplicate
WARNING: ALTER GROUP: user "regressuser2" is already in group "regressgroup2" WARNING: user "regressuser2" is already in group "regressgroup2"
ALTER GROUP regressgroup2 DROP USER regressuser2; ALTER GROUP regressgroup2 DROP USER regressuser2;
ALTER GROUP regressgroup2 ADD USER regressuser4; ALTER GROUP regressgroup2 ADD USER regressuser4;
-- test owner privileges -- test owner privileges

View File

@ -5,22 +5,24 @@ CREATE FUNCTION widget_in(cstring)
RETURNS widget RETURNS widget
AS '@abs_builddir@/regress@DLSUFFIX@' AS '@abs_builddir@/regress@DLSUFFIX@'
LANGUAGE 'c'; LANGUAGE 'c';
NOTICE: ProcedureCreate: type widget is not yet defined NOTICE: type widget is not yet defined
DETAIL: Creating a shell type definition.
CREATE FUNCTION widget_out(widget) CREATE FUNCTION widget_out(widget)
RETURNS cstring RETURNS cstring
AS '@abs_builddir@/regress@DLSUFFIX@' AS '@abs_builddir@/regress@DLSUFFIX@'
LANGUAGE 'c'; LANGUAGE 'c';
NOTICE: Argument type "widget" is only a shell NOTICE: argument type widget is only a shell
CREATE FUNCTION int44in(cstring) CREATE FUNCTION int44in(cstring)
RETURNS city_budget RETURNS city_budget
AS '@abs_builddir@/regress@DLSUFFIX@' AS '@abs_builddir@/regress@DLSUFFIX@'
LANGUAGE 'c'; LANGUAGE 'c';
NOTICE: ProcedureCreate: type city_budget is not yet defined NOTICE: type city_budget is not yet defined
DETAIL: Creating a shell type definition.
CREATE FUNCTION int44out(city_budget) CREATE FUNCTION int44out(city_budget)
RETURNS cstring RETURNS cstring
AS '@abs_builddir@/regress@DLSUFFIX@' AS '@abs_builddir@/regress@DLSUFFIX@'
LANGUAGE 'c'; LANGUAGE 'c';
NOTICE: Argument type "city_budget" is only a shell NOTICE: argument type city_budget is only a shell
CREATE FUNCTION check_primary_key () CREATE FUNCTION check_primary_key ()
RETURNS trigger RETURNS trigger
AS '@abs_builddir@/../../../contrib/spi/refint@DLSUFFIX@' AS '@abs_builddir@/../../../contrib/spi/refint@DLSUFFIX@'
@ -48,25 +50,27 @@ CREATE FUNCTION set_ttdummy (int4)
-- Things that shouldn't work: -- Things that shouldn't work:
CREATE FUNCTION test1 (int) RETURNS int LANGUAGE sql CREATE FUNCTION test1 (int) RETURNS int LANGUAGE sql
AS 'SELECT ''not an integer'';'; AS 'SELECT ''not an integer'';';
ERROR: return type mismatch in function: declared to return integer, returns "unknown" ERROR: return type mismatch in function declared to return integer
DETAIL: Actual return type is "unknown".
CREATE FUNCTION test1 (int) RETURNS int LANGUAGE sql CREATE FUNCTION test1 (int) RETURNS int LANGUAGE sql
AS 'not even SQL'; AS 'not even SQL';
ERROR: syntax error at or near "not" at character 1 ERROR: syntax error at or near "not" at character 1
CREATE FUNCTION test1 (int) RETURNS int LANGUAGE sql CREATE FUNCTION test1 (int) RETURNS int LANGUAGE sql
AS 'SELECT 1, 2, 3;'; AS 'SELECT 1, 2, 3;';
ERROR: function declared to return integer returns multiple columns in final SELECT ERROR: return type mismatch in function declared to return integer
DETAIL: Final SELECT must return exactly one column.
CREATE FUNCTION test1 (int) RETURNS int LANGUAGE sql CREATE FUNCTION test1 (int) RETURNS int LANGUAGE sql
AS 'SELECT $2;'; AS 'SELECT $2;';
ERROR: Parameter '$2' is out of range ERROR: there is no parameter $2
CREATE FUNCTION test1 (int) RETURNS int LANGUAGE sql CREATE FUNCTION test1 (int) RETURNS int LANGUAGE sql
AS 'a', 'b'; AS 'a', 'b';
ERROR: CREATE FUNCTION: only one AS item needed for sql language ERROR: only one AS item needed for language "sql"
CREATE FUNCTION test1 (int) RETURNS int LANGUAGE c CREATE FUNCTION test1 (int) RETURNS int LANGUAGE c
AS 'nosuchfile'; AS 'nosuchfile';
ERROR: stat failed on file 'nosuchfile': No such file or directory ERROR: could not access file "nosuchfile": No such file or directory
CREATE FUNCTION test1 (int) RETURNS int LANGUAGE c CREATE FUNCTION test1 (int) RETURNS int LANGUAGE c
AS '@abs_builddir@/regress@DLSUFFIX@', 'nosuchsymbol'; AS '@abs_builddir@/regress@DLSUFFIX@', 'nosuchsymbol';
ERROR: Can't find function nosuchsymbol in file @abs_builddir@/regress@DLSUFFIX@ ERROR: could not find function "nosuchsymbol" in file "@abs_builddir@/regress@DLSUFFIX@"
CREATE FUNCTION test1 (int) RETURNS int LANGUAGE internal CREATE FUNCTION test1 (int) RETURNS int LANGUAGE internal
AS 'nosuch'; AS 'nosuch';
ERROR: there is no built-in function named "nosuch" ERROR: there is no built-in function named "nosuch"