From 3b76622e04d8656fb44e7c932cb243e2d92fe40e Mon Sep 17 00:00:00 2001 From: Andrew Dunstan Date: Wed, 28 Dec 2022 09:53:00 -0500 Subject: [PATCH] Convert contrib/intarray's bqarr_in() to report errors softly Reviewed by Tom Lane and Amul Sul Discussion: https://postgr.es/m/49e598c2-cfe8-0928-b6fb-d0cc51aab626@dunslane.net --- contrib/intarray/_int_bool.c | 15 +++++++++------ contrib/intarray/expected/_int.out | 15 +++++++++++++++ contrib/intarray/sql/_int.sql | 11 +++++++++++ 3 files changed, 35 insertions(+), 6 deletions(-) diff --git a/contrib/intarray/_int_bool.c b/contrib/intarray/_int_bool.c index 3ed88af76d..8fc6ad87fc 100644 --- a/contrib/intarray/_int_bool.c +++ b/contrib/intarray/_int_bool.c @@ -35,6 +35,7 @@ typedef struct char *buf; int32 state; int32 count; + struct Node *escontext; /* reverse polish notation in list (for temporary usage) */ NODE *str; /* number in str */ @@ -179,7 +180,7 @@ makepol(WORKSTATE *state) else { if (lenstack == STACKDEPTH) - ereport(ERROR, + ereturn(state->escontext, ERR, (errcode(ERRCODE_STATEMENT_TOO_COMPLEX), errmsg("statement too complex"))); stack[lenstack] = val; @@ -206,10 +207,9 @@ makepol(WORKSTATE *state) break; case ERR: default: - ereport(ERROR, + ereturn(state->escontext, ERR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("syntax error"))); - return ERR; } } @@ -483,6 +483,7 @@ bqarr_in(PG_FUNCTION_ARGS) ITEM *ptr; NODE *tmp; int32 pos = 0; + struct Node *escontext = fcinfo->context; #ifdef BS_DEBUG StringInfoData pbuf; @@ -493,16 +494,18 @@ bqarr_in(PG_FUNCTION_ARGS) state.count = 0; state.num = 0; state.str = NULL; + state.escontext = escontext; /* make polish notation (postfix, but in reverse order) */ - makepol(&state); + if (makepol(&state) == ERR) + PG_RETURN_NULL(); if (!state.num) - ereport(ERROR, + ereturn(escontext, (Datum) 0, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("empty query"))); if (state.num > QUERYTYPEMAXITEMS) - ereport(ERROR, + ereturn(escontext, (Datum) 0, (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), errmsg("number of query items (%d) exceeds the maximum allowed (%d)", state.num, (int) QUERYTYPEMAXITEMS))); diff --git a/contrib/intarray/expected/_int.out b/contrib/intarray/expected/_int.out index a09d40efa1..c953065a5c 100644 --- a/contrib/intarray/expected/_int.out +++ b/contrib/intarray/expected/_int.out @@ -398,6 +398,21 @@ SELECT '1&(2&(4&(5|!6)))'::query_int; 1 & 2 & 4 & ( 5 | !6 ) (1 row) +-- test non-error-throwing input +SELECT str as "query_int", + pg_input_is_valid(str,'query_int') as ok, + pg_input_error_message(str,'query_int') as errmsg +FROM (VALUES ('1&(2&(4&(5|6)))'), + ('1#(2&(4&(5&6)))'), + ('foo')) + AS a(str); + query_int | ok | errmsg +-----------------+----+-------------- + 1&(2&(4&(5|6))) | t | + 1#(2&(4&(5&6))) | f | syntax error + foo | f | syntax error +(3 rows) + CREATE TABLE test__int( a int[] ); \copy test__int from 'data/test__int.data' ANALYZE test__int; diff --git a/contrib/intarray/sql/_int.sql b/contrib/intarray/sql/_int.sql index b26fc57e4d..4c9ba4c1fb 100644 --- a/contrib/intarray/sql/_int.sql +++ b/contrib/intarray/sql/_int.sql @@ -75,6 +75,17 @@ SELECT '1&2&4&5&6'::query_int; SELECT '1&(2&(4&(5|6)))'::query_int; SELECT '1&(2&(4&(5|!6)))'::query_int; +-- test non-error-throwing input + +SELECT str as "query_int", + pg_input_is_valid(str,'query_int') as ok, + pg_input_error_message(str,'query_int') as errmsg +FROM (VALUES ('1&(2&(4&(5|6)))'), + ('1#(2&(4&(5&6)))'), + ('foo')) + AS a(str); + + CREATE TABLE test__int( a int[] ); \copy test__int from 'data/test__int.data'