Compare commits

...

3 Commits

Author SHA1 Message Date
Tom Lane a916b47e23 Clean up usage of bison precedence for non-operator keywords.
Assigning a precedence to a keyword that isn't a kind of expression
operator is rather dangerous, because it might mask grammar
ambiguities that we'd rather know about.  It's much safer to attach
explicit precedences to individual rules, which will affect the
behavior of only that one rule.  Moreover, when we do have to give
a precedence to a non-operator keyword, we should try to give it the
same precedence as IDENT, thereby reducing the risk of surprising
side-effects.

Apply this hard-won knowledge to SET (which I misassigned ages ago
in commit 2647ad658) and some SQL/JSON-related productions
(from commits 6ee30209a, 71bfd1543).

Patch HEAD only, since there's no evidence of actual bugs here.

Discussion: https://postgr.es/m/CADT4RqBPdbsZW7HS1jJP319TMRHs1hzUiP=iRJYR6UqgHCrgNQ@mail.gmail.com
2023-11-28 13:32:15 -05:00
Tom Lane c82207a548 Use BIO_{get,set}_app_data instead of BIO_{get,set}_data.
We should have done it this way all along, but we accidentally got
away with using the wrong BIO field up until OpenSSL 3.2.  There,
the library's BIO routines that we rely on use the "data" field
for their own purposes, and our conflicting use causes assorted
weird behaviors up to and including core dumps when SSL connections
are attempted.  Switch to using the approved field for the purpose,
i.e. app_data.

While at it, remove our configure probes for BIO_get_data as well
as the fallback implementation.  BIO_{get,set}_app_data have been
there since long before any OpenSSL version that we still support,
even in the back branches.

Also, update src/test/ssl/t/001_ssltests.pl to allow for a minor
change in an error message spelling that evidently came in with 3.2.

Tristan Partin and Bo Andreson.  Back-patch to all supported branches.

Discussion: https://postgr.es/m/CAN55FZ1eDDYsYaL7mv+oSLUij2h_u6hvD4Qmv-7PK7jkji0uyQ@mail.gmail.com
2023-11-28 12:34:03 -05:00
Heikki Linnakangas 10a59925a3 Fix comment about ressortgrouprefs being unique in setop plans.
Author: Richard Guo, Tom Lane
Discussion: https://www.postgresql.org/message-id/CAMbWs49rAfFS-yd7=QxtDUrZDFfRBGy4rGBJNyGDH7=CLipFPg@mail.gmail.com
2023-11-28 14:15:14 +02:00
10 changed files with 63 additions and 45 deletions

2
configure vendored
View File

@ -12836,7 +12836,7 @@ done
# defines OPENSSL_VERSION_NUMBER to claim version 2.0.0, even though it
# doesn't have these OpenSSL 1.1.0 functions. So check for individual
# functions.
for ac_func in OPENSSL_init_ssl BIO_get_data BIO_meth_new ASN1_STRING_get0_data HMAC_CTX_new HMAC_CTX_free
for ac_func in OPENSSL_init_ssl BIO_meth_new ASN1_STRING_get0_data HMAC_CTX_new HMAC_CTX_free
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"

View File

@ -1367,7 +1367,7 @@ if test "$with_ssl" = openssl ; then
# defines OPENSSL_VERSION_NUMBER to claim version 2.0.0, even though it
# doesn't have these OpenSSL 1.1.0 functions. So check for individual
# functions.
AC_CHECK_FUNCS([OPENSSL_init_ssl BIO_get_data BIO_meth_new ASN1_STRING_get0_data HMAC_CTX_new HMAC_CTX_free])
AC_CHECK_FUNCS([OPENSSL_init_ssl BIO_meth_new ASN1_STRING_get0_data HMAC_CTX_new HMAC_CTX_free])
# OpenSSL versions before 1.1.0 required setting callback functions, for
# thread-safety. In 1.1.0, it's no longer required, and CRYPTO_lock()
# function was removed.

View File

@ -1285,7 +1285,6 @@ if sslopt in ['auto', 'openssl']
# doesn't have these OpenSSL 1.1.0 functions. So check for individual
# functions.
['OPENSSL_init_ssl'],
['BIO_get_data'],
['BIO_meth_new'],
['ASN1_STRING_get0_data'],
['HMAC_CTX_new'],

View File

@ -842,11 +842,6 @@ be_tls_write(Port *port, void *ptr, size_t len, int *waitfor)
* see sock_read() and sock_write() in OpenSSL's crypto/bio/bss_sock.c.
*/
#ifndef HAVE_BIO_GET_DATA
#define BIO_get_data(bio) (bio->ptr)
#define BIO_set_data(bio, data) (bio->ptr = data)
#endif
static BIO_METHOD *my_bio_methods = NULL;
static int
@ -856,7 +851,7 @@ my_sock_read(BIO *h, char *buf, int size)
if (buf != NULL)
{
res = secure_raw_read(((Port *) BIO_get_data(h)), buf, size);
res = secure_raw_read(((Port *) BIO_get_app_data(h)), buf, size);
BIO_clear_retry_flags(h);
if (res <= 0)
{
@ -876,7 +871,7 @@ my_sock_write(BIO *h, const char *buf, int size)
{
int res = 0;
res = secure_raw_write(((Port *) BIO_get_data(h)), buf, size);
res = secure_raw_write(((Port *) BIO_get_app_data(h)), buf, size);
BIO_clear_retry_flags(h);
if (res <= 0)
{
@ -952,7 +947,7 @@ my_SSL_set_fd(Port *port, int fd)
SSLerr(SSL_F_SSL_SET_FD, ERR_R_BUF_LIB);
goto err;
}
BIO_set_data(bio, port);
BIO_set_app_data(bio, port);
BIO_set_fd(bio, fd, BIO_NOCLOSE);
SSL_set_bio(port->ssl, bio, bio);

View File

@ -2936,7 +2936,14 @@ search_indexed_tlist_for_sortgroupref(Expr *node,
{
TargetEntry *tle = (TargetEntry *) lfirst(lc);
/* The equal() check should be redundant, but let's be paranoid */
/*
* Usually the equal() check is redundant, but in setop plans it may
* not be, since prepunion.c assigns ressortgroupref equal to the
* column resno without regard to whether that matches the topmost
* level's sortgrouprefs and without regard to whether any implicit
* coercions are added in the setop tree. We might have to clean that
* up someday; but for now, just ignore any false matches.
*/
if (tle->ressortgroupref == sortgroupref &&
equal(node, tle->expr))
{

View File

@ -810,7 +810,6 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
/* Precedence: lowest to highest */
%nonassoc SET /* see relation_expr_opt_alias */
%left UNION EXCEPT
%left INTERSECT
%left OR
@ -821,18 +820,23 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
%nonassoc BETWEEN IN_P LIKE ILIKE SIMILAR NOT_LA
%nonassoc ESCAPE /* ESCAPE must be just above LIKE/ILIKE/SIMILAR */
/* SQL/JSON related keywords */
%nonassoc UNIQUE JSON
%nonassoc KEYS OBJECT_P SCALAR VALUE_P
%nonassoc WITH WITHOUT
/*
* To support target_el without AS, it used to be necessary to assign IDENT an
* explicit precedence just less than Op. While that's not really necessary
* since we removed postfix operators, it's still helpful to do so because
* there are some other unreserved keywords that need precedence assignments.
* If those keywords have the same precedence as IDENT then they clearly act
* the same as non-keywords, reducing the risk of unwanted precedence effects.
* Sometimes it is necessary to assign precedence to keywords that are not
* really part of the operator hierarchy, in order to resolve grammar
* ambiguities. It's best to avoid doing so whenever possible, because such
* assignments have global effect and may hide ambiguities besides the one
* you intended to solve. (Attaching a precedence to a single rule with
* %prec is far safer and should be preferred.) If you must give precedence
* to a new keyword, try very hard to give it the same precedence as IDENT.
* If the keyword has IDENT's precedence then it clearly acts the same as
* non-keywords and other similar keywords, thus reducing the risk of
* unexpected precedence effects.
*
* We used to need to assign IDENT an explicit precedence just less than Op,
* to support target_el without AS. While that's not really necessary since
* we removed postfix operators, we continue to do so because it provides a
* reference point for a precedence level that we can assign to other
* keywords that lack a natural precedence level.
*
* We need to do this for PARTITION, RANGE, ROWS, and GROUPS to support
* opt_existing_window_name (see comment there).
@ -850,9 +854,18 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
* an explicit priority lower than '(', so that a rule with CUBE '(' will shift
* rather than reducing a conflicting rule that takes CUBE as a function name.
* Using the same precedence as IDENT seems right for the reasons given above.
*
* SET is likewise assigned the same precedence as IDENT, to support the
* relation_expr_opt_alias production (see comment there).
*
* KEYS, OBJECT_P, SCALAR, VALUE_P, WITH, and WITHOUT are similarly assigned
* the same precedence as IDENT. This allows resolving conflicts in the
* json_predicate_type_constraint and json_key_uniqueness_constraint_opt
* productions (see comments there).
*/
%nonassoc UNBOUNDED /* ideally would have same precedence as IDENT */
%nonassoc IDENT PARTITION RANGE ROWS GROUPS PRECEDING FOLLOWING CUBE ROLLUP
SET KEYS OBJECT_P SCALAR VALUE_P WITH WITHOUT
%left Op OPERATOR /* multi-character ops and user-defined operators */
%left '+' '-'
%left '*' '/' '%'
@ -16519,21 +16532,35 @@ json_returning_clause_opt:
| /* EMPTY */ { $$ = NULL; }
;
/*
* We must assign the only-JSON production a precedence less than IDENT in
* order to favor shifting over reduction when JSON is followed by VALUE_P,
* OBJECT_P, or SCALAR. (ARRAY doesn't need that treatment, because it's a
* fully reserved word.) Because json_predicate_type_constraint is always
* followed by json_key_uniqueness_constraint_opt, we also need the only-JSON
* production to have precedence less than WITH and WITHOUT. UNBOUNDED isn't
* really related to this syntax, but it's a convenient choice because it
* already has a precedence less than IDENT for other reasons.
*/
json_predicate_type_constraint:
JSON { $$ = JS_TYPE_ANY; }
JSON %prec UNBOUNDED { $$ = JS_TYPE_ANY; }
| JSON VALUE_P { $$ = JS_TYPE_ANY; }
| JSON ARRAY { $$ = JS_TYPE_ARRAY; }
| JSON OBJECT_P { $$ = JS_TYPE_OBJECT; }
| JSON SCALAR { $$ = JS_TYPE_SCALAR; }
;
/* KEYS is a noise word here */
/*
* KEYS is a noise word here. To avoid shift/reduce conflicts, assign the
* KEYS-less productions a precedence less than IDENT (i.e., less than KEYS).
* This prevents reducing them when the next token is KEYS.
*/
json_key_uniqueness_constraint_opt:
WITH UNIQUE KEYS { $$ = true; }
| WITH UNIQUE { $$ = true; }
| WITH UNIQUE %prec UNBOUNDED { $$ = true; }
| WITHOUT UNIQUE KEYS { $$ = false; }
| WITHOUT UNIQUE { $$ = false; }
| /* EMPTY */ %prec KEYS { $$ = false; }
| WITHOUT UNIQUE %prec UNBOUNDED { $$ = false; }
| /* EMPTY */ %prec UNBOUNDED { $$ = false; }
;
json_name_and_value_list:

View File

@ -66,9 +66,6 @@
/* Define to 1 if you have the `backtrace_symbols' function. */
#undef HAVE_BACKTRACE_SYMBOLS
/* Define to 1 if you have the `BIO_get_data' function. */
#undef HAVE_BIO_GET_DATA
/* Define to 1 if you have the `BIO_meth_new' function. */
#undef HAVE_BIO_METH_NEW

View File

@ -1815,11 +1815,6 @@ PQsslAttribute(PGconn *conn, const char *attribute_name)
* see sock_read() and sock_write() in OpenSSL's crypto/bio/bss_sock.c.
*/
#ifndef HAVE_BIO_GET_DATA
#define BIO_get_data(bio) (bio->ptr)
#define BIO_set_data(bio, data) (bio->ptr = data)
#endif
/* protected by ssl_config_mutex */
static BIO_METHOD *my_bio_methods;
@ -1828,7 +1823,7 @@ my_sock_read(BIO *h, char *buf, int size)
{
int res;
res = pqsecure_raw_read((PGconn *) BIO_get_data(h), buf, size);
res = pqsecure_raw_read((PGconn *) BIO_get_app_data(h), buf, size);
BIO_clear_retry_flags(h);
if (res < 0)
{
@ -1858,7 +1853,7 @@ my_sock_write(BIO *h, const char *buf, int size)
{
int res;
res = pqsecure_raw_write((PGconn *) BIO_get_data(h), buf, size);
res = pqsecure_raw_write((PGconn *) BIO_get_app_data(h), buf, size);
BIO_clear_retry_flags(h);
if (res < 0)
{
@ -1968,7 +1963,7 @@ my_SSL_set_fd(PGconn *conn, int fd)
SSLerr(SSL_F_SSL_SET_FD, ERR_R_BUF_LIB);
goto err;
}
BIO_set_data(bio, conn);
BIO_set_app_data(bio, conn);
SSL_set_bio(conn->ssl, bio, bio);
BIO_set_fd(bio, fd, BIO_NOCLOSE);

View File

@ -776,7 +776,7 @@ $node->connect_fails(
"$common_connstr user=ssltestuser sslcert=ssl/client-revoked.crt "
. sslkey('client-revoked.key'),
"certificate authorization fails with revoked client cert",
expected_stderr => qr/SSL error: sslv3 alert certificate revoked/,
expected_stderr => qr|SSL error: ssl[a-z0-9/]* alert certificate revoked|,
# temporarily(?) skip this check due to timing issue
# log_like => [
# qr{Client certificate verification failed at depth 0: certificate revoked},
@ -881,7 +881,7 @@ $node->connect_fails(
"$common_connstr user=ssltestuser sslcert=ssl/client-revoked.crt "
. sslkey('client-revoked.key'),
"certificate authorization fails with revoked client cert with server-side CRL directory",
expected_stderr => qr/SSL error: sslv3 alert certificate revoked/,
expected_stderr => qr|SSL error: ssl[a-z0-9/]* alert certificate revoked|,
# temporarily(?) skip this check due to timing issue
# log_like => [
# qr{Client certificate verification failed at depth 0: certificate revoked},
@ -894,7 +894,7 @@ $node->connect_fails(
"$common_connstr user=ssltestuser sslcert=ssl/client-revoked-utf8.crt "
. sslkey('client-revoked-utf8.key'),
"certificate authorization fails with revoked UTF-8 client cert with server-side CRL directory",
expected_stderr => qr/SSL error: sslv3 alert certificate revoked/,
expected_stderr => qr|SSL error: ssl[a-z0-9/]* alert certificate revoked|,
# temporarily(?) skip this check due to timing issue
# log_like => [
# qr{Client certificate verification failed at depth 0: certificate revoked},

View File

@ -224,7 +224,6 @@ sub GenerateFiles
HAVE_ATOMICS => 1,
HAVE_ATOMIC_H => undef,
HAVE_BACKTRACE_SYMBOLS => undef,
HAVE_BIO_GET_DATA => undef,
HAVE_BIO_METH_NEW => undef,
HAVE_COMPUTED_GOTO => undef,
HAVE_COPYFILE => undef,
@ -502,7 +501,6 @@ sub GenerateFiles
|| ($digit1 >= '1' && $digit2 >= '1' && $digit3 >= '0'))
{
$define{HAVE_ASN1_STRING_GET0_DATA} = 1;
$define{HAVE_BIO_GET_DATA} = 1;
$define{HAVE_BIO_METH_NEW} = 1;
$define{HAVE_HMAC_CTX_FREE} = 1;
$define{HAVE_HMAC_CTX_NEW} = 1;