index bba953cd6e0b42899228ec535fac8122d017910b..d70b64a8cfe839257e39089744765bf20d9e60cf 100644 (file)
@@ -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;
/* 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.",
* 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,
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")));
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)));
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
*/
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
{
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")));
index 8de38abd11dc0244007c80eb6ee139bd0b6021e7..2c90e526a60a96ad31d9c78def19549056b4e512 100644 (file)
int2vectorin(PG_FUNCTION_ARGS)
{
char *intString = PG_GETARG_CSTRING(0);
+ Node *escontext = fcinfo->context;
int2vector *result;
int n;
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)));
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")));
index b5af42234120680b9f153eb1b10c6fea83e9d2d3..9d382b5cb7c151208a1a8bedf7dc61da3010c717 100644 (file)
#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"
* 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")));
char *s = PG_GETARG_CSTRING(0);
Oid result;
- result = oidin_subr(s, NULL);
+ result = oidin_subr(s, NULL, fcinfo->context);
PG_RETURN_OID(result);
}
oidvectorin(PG_FUNCTION_ARGS)
{
char *oidString = PG_GETARG_CSTRING(0);
+ Node *escontext = fcinfo->context;
oidvector *result;
int n;
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")));
* 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));
}
index 15266f36f598372fa3704b9ae059eefbb2c38cd2..316a102ef30963c499617f18ba6c97a99e7981d1 100644 (file)
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)));
index 83ac589f9579939fd46fb126097f35bdc6c80bd3..4dc1b327bf3d7008d196d3ba8ca679eb1a199a7c 100644 (file)
tidin(PG_FUNCTION_ARGS)
{
char *str = PG_GETARG_CSTRING(0);
+ Node *escontext = fcinfo->context;
char *p,
*coord[NTIDARGS];
int i;
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)));
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)));
#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)));
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)));
index d8e40b3b969e4b940589c23a1149929fc482c69c..2093776809f1a3c225573fea0ec84e95146018da 100644 (file)
* parse snapshot from cstring
*/
static pg_snapshot *
-parse_snapshot(const char *str)
+parse_snapshot(const char *str, Node *escontext)
{
FullTransactionId xmin;
FullTransactionId xmax;
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 */
}
/*
char *str = PG_GETARG_CSTRING(0);
pg_snapshot *snap;
- snap = parse_snapshot(str);
+ snap = parse_snapshot(str, fcinfo->context);
PG_RETURN_POINTER(snap);
}
index 08e2f9f9dca372b685d9437a0a62b58865eefd59..08c333b75a2196fc89bfb6dc4a8bde977332ec7d 100644 (file)
@@ -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);
index 890937345367eef97190e7babb44fdc3812f76c0..b664bab5f93480d2270ed0c883f54215bcb917ed 100644 (file)
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
------
index 99a748a6a765168b33d2c32556783deca0836323..01501f8c9bf1a72d86e8f45bd9b8c0f607bc432f 100644 (file)
@@ -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
index 169b364b22fc461b73f8a48305f3e701e0c44e12..34c26a804a7f4567038572fb2f5e6bbe4ea2c735 100644 (file)
@@ -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.
index 8cd6d60595273eae85f1a3d6391a6f63b88ce0b8..ff67ed43f0a1845fa78ba5a74e7bdcea5808e921 100644 (file)
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
index d8e76f3321f809db86035eaaaa03c924b1491dd2..c7b8d299c8479fba25595bb6fb2a7dd48258400a 100644 (file)
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
index ad30c2feaa110b6651b70ba2733841797e60fe1b..a812235ee50fd54a11d6089f8583ea2f7811f966 100644 (file)
@@ -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);
index 25b4b68a6a0e613de1cff5710c0e5114572bdd64..39937c2f1d33ff957df6dab1a1f9f8eb5b208a2f 100644 (file)
@@ -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';
index 615368ba960be3b23d9554e06578085ac9acdfd9..3d57d66e0c0dc8e0c7f5c7b4695bdac6273b501f 100644 (file)
@@ -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;
index b2db1c6dd56b84302dccf9377a7763a9fed603e9..39aa0b4ecf78cdea10d64ff01f0fae85ecc240e0 100644 (file)
@@ -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.
index 990d314a5f8d6baa664a3b81de72c351a9023581..8196194c04ff52746a3d8d91fde4c989f6ca6231 100644 (file)
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
index bee17e63643df6a8ef9e24a43f8bf469859ccbf7..2289803681b5c9266190e0e00a52c0c4eb3abb68 100644 (file)
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