diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/utils/adt/acl.c | 62 | ||||
-rw-r--r-- | src/backend/utils/adt/int.c | 9 | ||||
-rw-r--r-- | src/backend/utils/adt/oid.c | 37 | ||||
-rw-r--r-- | src/backend/utils/adt/pg_lsn.c | 2 | ||||
-rw-r--r-- | src/backend/utils/adt/tid.c | 9 | ||||
-rw-r--r-- | src/backend/utils/adt/xid8funcs.c | 7 | ||||
-rw-r--r-- | src/test/regress/expected/int2.out | 19 | ||||
-rw-r--r-- | src/test/regress/expected/oid.out | 62 | ||||
-rw-r--r-- | src/test/regress/expected/pg_lsn.out | 13 | ||||
-rw-r--r-- | src/test/regress/expected/privileges.out | 43 | ||||
-rw-r--r-- | src/test/regress/expected/tid.out | 25 | ||||
-rw-r--r-- | src/test/regress/expected/xid.out | 31 | ||||
-rw-r--r-- | src/test/regress/sql/int2.sql | 5 | ||||
-rw-r--r-- | src/test/regress/sql/oid.sql | 14 | ||||
-rw-r--r-- | src/test/regress/sql/pg_lsn.sql | 4 | ||||
-rw-r--r-- | src/test/regress/sql/privileges.sql | 9 | ||||
-rw-r--r-- | src/test/regress/sql/tid.sql | 6 | ||||
-rw-r--r-- | src/test/regress/sql/xid.sql | 7 |
18 files changed, 323 insertions, 41 deletions
diff --git a/src/backend/utils/adt/acl.c b/src/backend/utils/adt/acl.c index bba953cd6e0..d70b64a8cfe 100644 --- a/src/backend/utils/adt/acl.c +++ b/src/backend/utils/adt/acl.c @@ -81,11 +81,11 @@ static List *cached_roles[] = {NIL, NIL, NIL}; static uint32 cached_db_hash; -static const char *getid(const char *s, char *n); +static const char *getid(const char *s, char *n, Node *escontext); static void putid(char *p, const char *s); static Acl *allocacl(int n); static void check_acl(const Acl *acl); -static const char *aclparse(const char *s, AclItem *aip); +static const char *aclparse(const char *s, AclItem *aip, Node *escontext); static bool aclitem_match(const AclItem *a1, const AclItem *a2); static int aclitemComparator(const void *arg1, const void *arg2); static void check_circularity(const Acl *old_acl, const AclItem *mod_aip, @@ -135,9 +135,12 @@ static void RoleMembershipCacheCallback(Datum arg, int cacheid, uint32 hashvalue * in 's', after any quotes. Also: * - loads the identifier into 'n'. (If no identifier is found, 'n' * contains an empty string.) 'n' must be NAMEDATALEN bytes. + * + * Errors are reported via ereport, unless escontext is an ErrorSaveData node, + * in which case we log the error there and return NULL. */ static const char * -getid(const char *s, char *n) +getid(const char *s, char *n, Node *escontext) { int len = 0; bool in_quotes = false; @@ -169,7 +172,7 @@ getid(const char *s, char *n) /* Add the character to the string */ if (len >= NAMEDATALEN - 1) - ereport(ERROR, + ereturn(escontext, NULL, (errcode(ERRCODE_NAME_TOO_LONG), errmsg("identifier too long"), errdetail("Identifier must be less than %d characters.", @@ -236,9 +239,12 @@ putid(char *p, const char *s) * specification. Also: * - loads the structure pointed to by 'aip' with the appropriate * UID/GID, id type identifier and mode type values. + * + * Errors are reported via ereport, unless escontext is an ErrorSaveData node, + * in which case we log the error there and return NULL. */ static const char * -aclparse(const char *s, AclItem *aip) +aclparse(const char *s, AclItem *aip, Node *escontext) { AclMode privs, goption, @@ -248,25 +254,30 @@ aclparse(const char *s, AclItem *aip) Assert(s && aip); - s = getid(s, name); + s = getid(s, name, escontext); + if (s == NULL) + return NULL; if (*s != '=') { /* we just read a keyword, not a name */ if (strcmp(name, "group") != 0 && strcmp(name, "user") != 0) - ereport(ERROR, + ereturn(escontext, NULL, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("unrecognized key word: \"%s\"", name), errhint("ACL key word must be \"group\" or \"user\"."))); - s = getid(s, name); /* move s to the name beyond the keyword */ + /* move s to the name beyond the keyword */ + s = getid(s, name, escontext); + if (s == NULL) + return NULL; if (name[0] == '\0') - ereport(ERROR, + ereturn(escontext, NULL, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("missing name"), errhint("A name must follow the \"group\" or \"user\" key word."))); } if (*s != '=') - ereport(ERROR, + ereturn(escontext, NULL, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("missing \"=\" sign"))); @@ -328,7 +339,7 @@ aclparse(const char *s, AclItem *aip) read = 0; break; default: - ereport(ERROR, + ereturn(escontext, NULL, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("invalid mode character: must be one of \"%s\"", ACL_ALL_RIGHTS_STR))); @@ -340,7 +351,13 @@ aclparse(const char *s, AclItem *aip) if (name[0] == '\0') aip->ai_grantee = ACL_ID_PUBLIC; else - aip->ai_grantee = get_role_oid(name, false); + { + aip->ai_grantee = get_role_oid(name, true); + if (!OidIsValid(aip->ai_grantee)) + ereturn(escontext, NULL, + (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("role \"%s\" does not exist", name))); + } /* * XXX Allow a degree of backward compatibility by defaulting the grantor @@ -348,12 +365,18 @@ aclparse(const char *s, AclItem *aip) */ if (*s == '/') { - s = getid(s + 1, name2); + s = getid(s + 1, name2, escontext); + if (s == NULL) + return NULL; if (name2[0] == '\0') - ereport(ERROR, + ereturn(escontext, NULL, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("a name must follow the \"/\" sign"))); - aip->ai_grantor = get_role_oid(name2, false); + aip->ai_grantor = get_role_oid(name2, true); + if (!OidIsValid(aip->ai_grantor)) + ereturn(escontext, NULL, + (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("role \"%s\" does not exist", name2))); } else { @@ -569,14 +592,19 @@ Datum aclitemin(PG_FUNCTION_ARGS) { const char *s = PG_GETARG_CSTRING(0); + Node *escontext = fcinfo->context; AclItem *aip; aip = (AclItem *) palloc(sizeof(AclItem)); - s = aclparse(s, aip); + + s = aclparse(s, aip, escontext); + if (s == NULL) + PG_RETURN_NULL(); + while (isspace((unsigned char) *s)) ++s; if (*s) - ereport(ERROR, + ereturn(escontext, (Datum) 0, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("extra garbage at the end of the ACL specification"))); diff --git a/src/backend/utils/adt/int.c b/src/backend/utils/adt/int.c index 8de38abd11d..2c90e526a60 100644 --- a/src/backend/utils/adt/int.c +++ b/src/backend/utils/adt/int.c @@ -141,6 +141,7 @@ Datum int2vectorin(PG_FUNCTION_ARGS) { char *intString = PG_GETARG_CSTRING(0); + Node *escontext = fcinfo->context; int2vector *result; int n; @@ -160,19 +161,19 @@ int2vectorin(PG_FUNCTION_ARGS) l = strtol(intString, &endp, 10); if (intString == endp) - ereport(ERROR, + ereturn(escontext, (Datum) 0, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("invalid input syntax for type %s: \"%s\"", "smallint", intString))); if (errno == ERANGE || l < SHRT_MIN || l > SHRT_MAX) - ereport(ERROR, + ereturn(escontext, (Datum) 0, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("value \"%s\" is out of range for type %s", intString, "smallint"))); if (*endp && *endp != ' ') - ereport(ERROR, + ereturn(escontext, (Datum) 0, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("invalid input syntax for type %s: \"%s\"", "integer", intString))); @@ -183,7 +184,7 @@ int2vectorin(PG_FUNCTION_ARGS) while (*intString && isspace((unsigned char) *intString)) intString++; if (*intString) - ereport(ERROR, + ereturn(escontext, (Datum) 0, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("int2vector has too many elements"))); diff --git a/src/backend/utils/adt/oid.c b/src/backend/utils/adt/oid.c index b5af4223412..9d382b5cb7c 100644 --- a/src/backend/utils/adt/oid.c +++ b/src/backend/utils/adt/oid.c @@ -19,6 +19,7 @@ #include "catalog/pg_type.h" #include "libpq/pqformat.h" +#include "nodes/miscnodes.h" #include "nodes/value.h" #include "utils/array.h" #include "utils/builtins.h" @@ -31,15 +32,26 @@ * USER I/O ROUTINES * *****************************************************************************/ +/* + * Parse a single OID and return its value. + * + * If endloc isn't NULL, store a pointer to the rest of the string there, + * so that caller can parse the rest. Otherwise, it's an error if anything + * but whitespace follows. + * + * If escontext points to an ErrorSaveContext node, that is filled instead + * of throwing an error; the caller must check SOFT_ERROR_OCCURRED() + * to detect errors. + */ static Oid -oidin_subr(const char *s, char **endloc) +oidin_subr(const char *s, char **endloc, Node *escontext) { unsigned long cvt; char *endptr; Oid result; if (*s == '\0') - ereport(ERROR, + ereturn(escontext, InvalidOid, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("invalid input syntax for type %s: \"%s\"", "oid", s))); @@ -53,19 +65,19 @@ oidin_subr(const char *s, char **endloc) * handled by the second "if" consistent across platforms. */ if (errno && errno != ERANGE && errno != EINVAL) - ereport(ERROR, + ereturn(escontext, InvalidOid, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("invalid input syntax for type %s: \"%s\"", "oid", s))); if (endptr == s && *s != '\0') - ereport(ERROR, + ereturn(escontext, InvalidOid, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("invalid input syntax for type %s: \"%s\"", "oid", s))); if (errno == ERANGE) - ereport(ERROR, + ereturn(escontext, InvalidOid, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("value \"%s\" is out of range for type %s", s, "oid"))); @@ -81,7 +93,7 @@ oidin_subr(const char *s, char **endloc) while (*endptr && isspace((unsigned char) *endptr)) endptr++; if (*endptr) - ereport(ERROR, + ereturn(escontext, InvalidOid, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("invalid input syntax for type %s: \"%s\"", "oid", s))); @@ -104,7 +116,7 @@ oidin_subr(const char *s, char **endloc) #if OID_MAX != ULONG_MAX if (cvt != (unsigned long) result && cvt != (unsigned long) ((int) result)) - ereport(ERROR, + ereturn(escontext, InvalidOid, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("value \"%s\" is out of range for type %s", s, "oid"))); @@ -119,7 +131,7 @@ oidin(PG_FUNCTION_ARGS) char *s = PG_GETARG_CSTRING(0); Oid result; - result = oidin_subr(s, NULL); + result = oidin_subr(s, NULL, fcinfo->context); PG_RETURN_OID(result); } @@ -194,6 +206,7 @@ Datum oidvectorin(PG_FUNCTION_ARGS) { char *oidString = PG_GETARG_CSTRING(0); + Node *escontext = fcinfo->context; oidvector *result; int n; @@ -205,12 +218,14 @@ oidvectorin(PG_FUNCTION_ARGS) oidString++; if (*oidString == '\0') break; - result->values[n] = oidin_subr(oidString, &oidString); + result->values[n] = oidin_subr(oidString, &oidString, escontext); + if (SOFT_ERROR_OCCURRED(escontext)) + PG_RETURN_NULL(); } while (*oidString && isspace((unsigned char) *oidString)) oidString++; if (*oidString) - ereport(ERROR, + ereturn(escontext, (Datum) 0, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("oidvector has too many elements"))); @@ -324,7 +339,7 @@ oidparse(Node *node) * constants by the lexer. Accept these if they are valid OID * strings. */ - return oidin_subr(castNode(Float, node)->fval, NULL); + return oidin_subr(castNode(Float, node)->fval, NULL, NULL); default: elog(ERROR, "unrecognized node type: %d", (int) nodeTag(node)); } diff --git a/src/backend/utils/adt/pg_lsn.c b/src/backend/utils/adt/pg_lsn.c index 15266f36f59..316a102ef30 100644 --- a/src/backend/utils/adt/pg_lsn.c +++ b/src/backend/utils/adt/pg_lsn.c @@ -69,7 +69,7 @@ pg_lsn_in(PG_FUNCTION_ARGS) result = pg_lsn_in_internal(str, &have_error); if (have_error) - ereport(ERROR, + ereturn(fcinfo->context, (Datum) 0, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("invalid input syntax for type %s: \"%s\"", "pg_lsn", str))); diff --git a/src/backend/utils/adt/tid.c b/src/backend/utils/adt/tid.c index 83ac589f957..4dc1b327bf3 100644 --- a/src/backend/utils/adt/tid.c +++ b/src/backend/utils/adt/tid.c @@ -57,6 +57,7 @@ Datum tidin(PG_FUNCTION_ARGS) { char *str = PG_GETARG_CSTRING(0); + Node *escontext = fcinfo->context; char *p, *coord[NTIDARGS]; int i; @@ -71,7 +72,7 @@ tidin(PG_FUNCTION_ARGS) coord[i++] = p + 1; if (i < NTIDARGS) - ereport(ERROR, + ereturn(escontext, (Datum) 0, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("invalid input syntax for type %s: \"%s\"", "tid", str))); @@ -79,7 +80,7 @@ tidin(PG_FUNCTION_ARGS) errno = 0; cvt = strtoul(coord[0], &badp, 10); if (errno || *badp != DELIM) - ereport(ERROR, + ereturn(escontext, (Datum) 0, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("invalid input syntax for type %s: \"%s\"", "tid", str))); @@ -93,7 +94,7 @@ tidin(PG_FUNCTION_ARGS) #if SIZEOF_LONG > 4 if (cvt != (unsigned long) blockNumber && cvt != (unsigned long) ((int32) blockNumber)) - ereport(ERROR, + ereturn(escontext, (Datum) 0, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("invalid input syntax for type %s: \"%s\"", "tid", str))); @@ -102,7 +103,7 @@ tidin(PG_FUNCTION_ARGS) cvt = strtoul(coord[1], &badp, 10); if (errno || *badp != RDELIM || cvt > USHRT_MAX) - ereport(ERROR, + ereturn(escontext, (Datum) 0, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("invalid input syntax for type %s: \"%s\"", "tid", str))); diff --git a/src/backend/utils/adt/xid8funcs.c b/src/backend/utils/adt/xid8funcs.c index d8e40b3b969..2093776809f 100644 --- a/src/backend/utils/adt/xid8funcs.c +++ b/src/backend/utils/adt/xid8funcs.c @@ -285,7 +285,7 @@ buf_finalize(StringInfo buf) * parse snapshot from cstring */ static pg_snapshot * -parse_snapshot(const char *str) +parse_snapshot(const char *str, Node *escontext) { FullTransactionId xmin; FullTransactionId xmax; @@ -341,11 +341,10 @@ parse_snapshot(const char *str) return buf_finalize(buf); bad_format: - ereport(ERROR, + ereturn(escontext, NULL, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("invalid input syntax for type %s: \"%s\"", "pg_snapshot", str_start))); - return NULL; /* keep compiler quiet */ } /* @@ -447,7 +446,7 @@ pg_snapshot_in(PG_FUNCTION_ARGS) char *str = PG_GETARG_CSTRING(0); pg_snapshot *snap; - snap = parse_snapshot(str); + snap = parse_snapshot(str, fcinfo->context); PG_RETURN_POINTER(snap); } diff --git a/src/test/regress/expected/int2.out b/src/test/regress/expected/int2.out index 08e2f9f9dca..08c333b75a2 100644 --- a/src/test/regress/expected/int2.out +++ b/src/test/regress/expected/int2.out @@ -70,6 +70,25 @@ SELECT pg_input_error_message('50000', 'int2'); value "50000" is out of range for type smallint (1 row) +-- While we're here, check int2vector as well +SELECT pg_input_is_valid(' 1 3 5 ', 'int2vector'); + pg_input_is_valid +------------------- + t +(1 row) + +SELECT pg_input_error_message('1 asdf', 'int2vector'); + pg_input_error_message +------------------------------------------------ + invalid input syntax for type smallint: "asdf" +(1 row) + +SELECT pg_input_error_message('50000', 'int2vector'); + pg_input_error_message +------------------------------------------------- + value "50000" is out of range for type smallint +(1 row) + SELECT * FROM INT2_TBL AS f(a, b); ERROR: table "f" has 1 columns available but 2 columns specified SELECT * FROM (TABLE int2_tbl) AS s (a, b); diff --git a/src/test/regress/expected/oid.out b/src/test/regress/expected/oid.out index 89093734536..b664bab5f93 100644 --- a/src/test/regress/expected/oid.out +++ b/src/test/regress/expected/oid.out @@ -65,6 +65,68 @@ SELECT * FROM OID_TBL; 15 (8 rows) +-- Also try it with non-error-throwing API +SELECT pg_input_is_valid('1234', 'oid'); + pg_input_is_valid +------------------- + t +(1 row) + +SELECT pg_input_is_valid('01XYZ', 'oid'); + pg_input_is_valid +------------------- + f +(1 row) + +SELECT pg_input_error_message('01XYZ', 'oid'); + pg_input_error_message +-------------------------------------------- + invalid input syntax for type oid: "01XYZ" +(1 row) + +SELECT pg_input_is_valid('9999999999', 'oid'); + pg_input_is_valid +------------------- + f +(1 row) + +SELECT pg_input_error_message('9999999999', 'oid'); + pg_input_error_message +------------------------------------------------- + value "9999999999" is out of range for type oid +(1 row) + +-- While we're here, check oidvector as well +SELECT pg_input_is_valid(' 1 2 4 ', 'oidvector'); + pg_input_is_valid +------------------- + t +(1 row) + +SELECT pg_input_is_valid('01 01XYZ', 'oidvector'); + pg_input_is_valid +------------------- + f +(1 row) + +SELECT pg_input_error_message('01 01XYZ', 'oidvector'); + pg_input_error_message +------------------------------------------ + invalid input syntax for type oid: "XYZ" +(1 row) + +SELECT pg_input_is_valid('01 9999999999', 'oidvector'); + pg_input_is_valid +------------------- + f +(1 row) + +SELECT pg_input_error_message('01 9999999999', 'oidvector'); + pg_input_error_message +------------------------------------------------- + value "9999999999" is out of range for type oid +(1 row) + SELECT o.* FROM OID_TBL o WHERE o.f1 = 1234; f1 ------ diff --git a/src/test/regress/expected/pg_lsn.out b/src/test/regress/expected/pg_lsn.out index 99a748a6a76..01501f8c9bf 100644 --- a/src/test/regress/expected/pg_lsn.out +++ b/src/test/regress/expected/pg_lsn.out @@ -26,6 +26,19 @@ INSERT INTO PG_LSN_TBL VALUES ('/ABCD'); ERROR: invalid input syntax for type pg_lsn: "/ABCD" LINE 1: INSERT INTO PG_LSN_TBL VALUES ('/ABCD'); ^ +-- Also try it with non-error-throwing API +SELECT pg_input_is_valid('16AE7F7', 'pg_lsn'); + pg_input_is_valid +------------------- + f +(1 row) + +SELECT pg_input_error_message('16AE7F7', 'pg_lsn'); + pg_input_error_message +------------------------------------------------- + invalid input syntax for type pg_lsn: "16AE7F7" +(1 row) + -- Min/Max aggregation SELECT MIN(f1), MAX(f1) FROM PG_LSN_TBL; min | max diff --git a/src/test/regress/expected/privileges.out b/src/test/regress/expected/privileges.out index 169b364b22f..34c26a804a7 100644 --- a/src/test/regress/expected/privileges.out +++ b/src/test/regress/expected/privileges.out @@ -2233,6 +2233,49 @@ SELECT makeaclitem('regress_priv_user1'::regrole, 'regress_priv_user2'::regrole, SELECT makeaclitem('regress_priv_user1'::regrole, 'regress_priv_user2'::regrole, 'SELECT, fake_privilege', FALSE); -- error ERROR: unrecognized privilege type: "fake_privilege" +-- Test non-throwing aclitem I/O +SELECT pg_input_is_valid('regress_priv_user1=r/regress_priv_user2', 'aclitem'); + pg_input_is_valid +------------------- + t +(1 row) + +SELECT pg_input_is_valid('regress_priv_user1=r/', 'aclitem'); + pg_input_is_valid +------------------- + f +(1 row) + +SELECT pg_input_error_message('regress_priv_user1=r/', 'aclitem'); + pg_input_error_message +--------------------------------- + a name must follow the "/" sign +(1 row) + +SELECT pg_input_is_valid('regress_priv_user1=r/regress_no_such_user', 'aclitem'); + pg_input_is_valid +------------------- + f +(1 row) + +SELECT pg_input_error_message('regress_priv_user1=r/regress_no_such_user', 'aclitem'); + pg_input_error_message +-------------------------------------------- + role "regress_no_such_user" does not exist +(1 row) + +SELECT pg_input_is_valid('regress_priv_user1=rY', 'aclitem'); + pg_input_is_valid +------------------- + f +(1 row) + +SELECT pg_input_error_message('regress_priv_user1=rY', 'aclitem'); + pg_input_error_message +---------------------------------------------------------- + invalid mode character: must be one of "arwdDxtXUCTcsAm" +(1 row) + -- -- Testing blanket default grants is very hazardous since it might change -- the privileges attached to objects created by concurrent regression tests. diff --git a/src/test/regress/expected/tid.out b/src/test/regress/expected/tid.out index 8cd6d605952..ff67ed43f0a 100644 --- a/src/test/regress/expected/tid.out +++ b/src/test/regress/expected/tid.out @@ -17,6 +17,31 @@ SELECT '(1,65536)'::tid; -- error ERROR: invalid input syntax for type tid: "(1,65536)" LINE 1: SELECT '(1,65536)'::tid; ^ +-- Also try it with non-error-throwing API +SELECT pg_input_is_valid('(0)', 'tid'); + pg_input_is_valid +------------------- + f +(1 row) + +SELECT pg_input_error_message('(0)', 'tid'); + pg_input_error_message +------------------------------------------ + invalid input syntax for type tid: "(0)" +(1 row) + +SELECT pg_input_is_valid('(0,-1)', 'tid'); + pg_input_is_valid +------------------- + f +(1 row) + +SELECT pg_input_error_message('(0,-1)', 'tid'); + pg_input_error_message +--------------------------------------------- + invalid input syntax for type tid: "(0,-1)" +(1 row) + -- tests for functions related to TID handling CREATE TABLE tid_tab (a int); -- min() and max() for TIDs diff --git a/src/test/regress/expected/xid.out b/src/test/regress/expected/xid.out index d8e76f3321f..c7b8d299c84 100644 --- a/src/test/regress/expected/xid.out +++ b/src/test/regress/expected/xid.out @@ -181,6 +181,37 @@ select '12:16:14,13'::pg_snapshot; ERROR: invalid input syntax for type pg_snapshot: "12:16:14,13" LINE 1: select '12:16:14,13'::pg_snapshot; ^ +-- also try it with non-error-throwing API +select pg_input_is_valid('12:13:', 'pg_snapshot'); + pg_input_is_valid +------------------- + t +(1 row) + +select pg_input_is_valid('31:12:', 'pg_snapshot'); + pg_input_is_valid +------------------- + f +(1 row) + +select pg_input_error_message('31:12:', 'pg_snapshot'); + pg_input_error_message +----------------------------------------------------- + invalid input syntax for type pg_snapshot: "31:12:" +(1 row) + +select pg_input_is_valid('12:16:14,13', 'pg_snapshot'); + pg_input_is_valid +------------------- + f +(1 row) + +select pg_input_error_message('12:16:14,13', 'pg_snapshot'); + pg_input_error_message +---------------------------------------------------------- + invalid input syntax for type pg_snapshot: "12:16:14,13" +(1 row) + create temp table snapshot_test ( nr integer, snap pg_snapshot diff --git a/src/test/regress/sql/int2.sql b/src/test/regress/sql/int2.sql index ad30c2feaa1..a812235ee50 100644 --- a/src/test/regress/sql/int2.sql +++ b/src/test/regress/sql/int2.sql @@ -23,6 +23,11 @@ SELECT pg_input_is_valid('asdf', 'int2'); SELECT pg_input_is_valid('50000', 'int2'); SELECT pg_input_error_message('50000', 'int2'); +-- While we're here, check int2vector as well +SELECT pg_input_is_valid(' 1 3 5 ', 'int2vector'); +SELECT pg_input_error_message('1 asdf', 'int2vector'); +SELECT pg_input_error_message('50000', 'int2vector'); + SELECT * FROM INT2_TBL AS f(a, b); SELECT * FROM (TABLE int2_tbl) AS s (a, b); diff --git a/src/test/regress/sql/oid.sql b/src/test/regress/sql/oid.sql index 25b4b68a6a0..39937c2f1d3 100644 --- a/src/test/regress/sql/oid.sql +++ b/src/test/regress/sql/oid.sql @@ -28,6 +28,20 @@ INSERT INTO OID_TBL(f1) VALUES ('-23582358720398502385'); SELECT * FROM OID_TBL; +-- Also try it with non-error-throwing API +SELECT pg_input_is_valid('1234', 'oid'); +SELECT pg_input_is_valid('01XYZ', 'oid'); +SELECT pg_input_error_message('01XYZ', 'oid'); +SELECT pg_input_is_valid('9999999999', 'oid'); +SELECT pg_input_error_message('9999999999', 'oid'); + +-- While we're here, check oidvector as well +SELECT pg_input_is_valid(' 1 2 4 ', 'oidvector'); +SELECT pg_input_is_valid('01 01XYZ', 'oidvector'); +SELECT pg_input_error_message('01 01XYZ', 'oidvector'); +SELECT pg_input_is_valid('01 9999999999', 'oidvector'); +SELECT pg_input_error_message('01 9999999999', 'oidvector'); + SELECT o.* FROM OID_TBL o WHERE o.f1 = 1234; SELECT o.* FROM OID_TBL o WHERE o.f1 <> '1234'; diff --git a/src/test/regress/sql/pg_lsn.sql b/src/test/regress/sql/pg_lsn.sql index 615368ba960..3d57d66e0c0 100644 --- a/src/test/regress/sql/pg_lsn.sql +++ b/src/test/regress/sql/pg_lsn.sql @@ -15,6 +15,10 @@ INSERT INTO PG_LSN_TBL VALUES (' 0/12345678'); INSERT INTO PG_LSN_TBL VALUES ('ABCD/'); INSERT INTO PG_LSN_TBL VALUES ('/ABCD'); +-- Also try it with non-error-throwing API +SELECT pg_input_is_valid('16AE7F7', 'pg_lsn'); +SELECT pg_input_error_message('16AE7F7', 'pg_lsn'); + -- Min/Max aggregation SELECT MIN(f1), MAX(f1) FROM PG_LSN_TBL; diff --git a/src/test/regress/sql/privileges.sql b/src/test/regress/sql/privileges.sql index b2db1c6dd56..39aa0b4ecf7 100644 --- a/src/test/regress/sql/privileges.sql +++ b/src/test/regress/sql/privileges.sql @@ -1430,6 +1430,15 @@ SELECT makeaclitem('regress_priv_user1'::regrole, 'regress_priv_user2'::regrole, SELECT makeaclitem('regress_priv_user1'::regrole, 'regress_priv_user2'::regrole, 'SELECT, fake_privilege', FALSE); -- error +-- Test non-throwing aclitem I/O +SELECT pg_input_is_valid('regress_priv_user1=r/regress_priv_user2', 'aclitem'); +SELECT pg_input_is_valid('regress_priv_user1=r/', 'aclitem'); +SELECT pg_input_error_message('regress_priv_user1=r/', 'aclitem'); +SELECT pg_input_is_valid('regress_priv_user1=r/regress_no_such_user', 'aclitem'); +SELECT pg_input_error_message('regress_priv_user1=r/regress_no_such_user', 'aclitem'); +SELECT pg_input_is_valid('regress_priv_user1=rY', 'aclitem'); +SELECT pg_input_error_message('regress_priv_user1=rY', 'aclitem'); + -- -- Testing blanket default grants is very hazardous since it might change -- the privileges attached to objects created by concurrent regression tests. diff --git a/src/test/regress/sql/tid.sql b/src/test/regress/sql/tid.sql index 990d314a5f8..8196194c04f 100644 --- a/src/test/regress/sql/tid.sql +++ b/src/test/regress/sql/tid.sql @@ -9,6 +9,12 @@ SELECT SELECT '(4294967296,1)'::tid; -- error SELECT '(1,65536)'::tid; -- error +-- Also try it with non-error-throwing API +SELECT pg_input_is_valid('(0)', 'tid'); +SELECT pg_input_error_message('(0)', 'tid'); +SELECT pg_input_is_valid('(0,-1)', 'tid'); +SELECT pg_input_error_message('(0,-1)', 'tid'); + -- tests for functions related to TID handling diff --git a/src/test/regress/sql/xid.sql b/src/test/regress/sql/xid.sql index bee17e63643..2289803681b 100644 --- a/src/test/regress/sql/xid.sql +++ b/src/test/regress/sql/xid.sql @@ -68,6 +68,13 @@ select '0:1:'::pg_snapshot; select '12:13:0'::pg_snapshot; select '12:16:14,13'::pg_snapshot; +-- also try it with non-error-throwing API +select pg_input_is_valid('12:13:', 'pg_snapshot'); +select pg_input_is_valid('31:12:', 'pg_snapshot'); +select pg_input_error_message('31:12:', 'pg_snapshot'); +select pg_input_is_valid('12:16:14,13', 'pg_snapshot'); +select pg_input_error_message('12:16:14,13', 'pg_snapshot'); + create temp table snapshot_test ( nr integer, snap pg_snapshot |