Re: How to write such a query?

2022-01-06 Thread Dmitry Igrishin
On Thu, Jan 6, 2022, 09:40 Igor Korot  wrote:

> Hi, ALL,
> In SQLite you can write:
>
> SELECT a, b, c FROM foo WHERE id = :id;
>
> where ":id" is the named parameter.
>
> The query above is similar to
>
> SELECT a,b,c FROM foo WHERE id = ?;
>
> except that the parameter has a name.
>
> Is there a way to write such a SELECT statement with the
> named parameter in PostgreSQL?
>
Named parameters of prepared statements are implemented in my C++ library
Pgfe.


Re: md5 issues Postgres14 on OL7

2022-01-06 Thread Michael Paquier
On Wed, Jan 05, 2022 at 04:09:12PM +0900, Michael Paquier wrote:
> In order to make things portable with 14 in cryptohash.c, we don't
> have any need to change the existing cryptohash APIs.  We could just
> store in each implementation context a location to a static string,
> and add a new routine to extract it if there is an error, defaulting
> to OOM.

I have been looking at that, and finished with the attached.  It is
close to the end of the day, so this needs an extra lookup, but I have
finished by using the idea of an extra routine, called
pg_cryptohash_error(), able to grab the error saved in the private
contexts, so as any callers from the backend or the frontend can feed
on that.  This way, it is possible to make the difference between
several class of errors: OOMs, a too short destination buffer, OpenSSL
internal error, etc.

There are a couple of things worth noting here:
- Two code paths of src/backend/libpq/crypt.c rely on the result of
pg_md5_encrypt() to always be an OOM, so as this skips one
psnprintf().  This has been let as-is in the backend for now, but we
don't pfree() the *logdetail strings passed across the various layers,
so we could just pass down the cryptohash error as-is..  We'd better
mention that logdetail may not be palloc'd all the time, once we do
that.  libpq is able to use that properly.
- The routines of md5_common.c need to pass down an extra *errstr for
their respective callers.  That's an ABI breakage but I'd like to
think that nobody uses that out-of-core.  (I need to double-check this
part, as well).
- HMAC (hmac_openssl.c and hmac.c) could use the same infra, but I did
not see a use for that yet.  It is possible to compile HMACs with MD5s,
but we don't have any in-core callers, and failures are just part of
the SCRAM workflow with dedicated error messages.

I am still not sure about the FIPS part, as per the argument of
OpenSSL using something different in 3.0.0, and Fedora that patches 
upstream in its own way, but this could be extended in
cryptohash_openssl.c to provide even more context.  For now, this
allows reports about OpenSSL internal failures, taking care of the
disturbance.

Thoughts?
--
Michael
From 064ef97fd2a171485ff408550380515493ce0072 Mon Sep 17 00:00:00 2001
From: Michael Paquier 
Date: Thu, 6 Jan 2022 17:13:55 +0900
Subject: [PATCH] Improve error reporting for cryptohashes

---
 src/include/common/cryptohash.h   |  1 +
 src/include/common/md5.h  |  8 ++-
 src/backend/libpq/auth.c  | 14 +++--
 src/backend/libpq/crypt.c | 20 ---
 src/backend/replication/backup_manifest.c |  9 ++-
 src/backend/utils/adt/cryptohashfuncs.c   | 25 ++---
 src/common/cryptohash.c   | 57 ++-
 src/common/cryptohash_openssl.c   | 68 +++
 src/common/md5_common.c   | 20 +--
 src/interfaces/libpq/fe-auth.c| 22 ++--
 contrib/uuid-ossp/uuid-ossp.c | 18 --
 11 files changed, 219 insertions(+), 43 deletions(-)

diff --git a/src/include/common/cryptohash.h b/src/include/common/cryptohash.h
index 541dc844c8..61d74e1195 100644
--- a/src/include/common/cryptohash.h
+++ b/src/include/common/cryptohash.h
@@ -34,5 +34,6 @@ extern int	pg_cryptohash_init(pg_cryptohash_ctx *ctx);
 extern int	pg_cryptohash_update(pg_cryptohash_ctx *ctx, const uint8 *data, size_t len);
 extern int	pg_cryptohash_final(pg_cryptohash_ctx *ctx, uint8 *dest, size_t len);
 extern void pg_cryptohash_free(pg_cryptohash_ctx *ctx);
+extern char *pg_cryptohash_error(pg_cryptohash_ctx *ctx);
 
 #endif			/* PG_CRYPTOHASH_H */
diff --git a/src/include/common/md5.h b/src/include/common/md5.h
index 62a31e6ed4..1db2855d95 100644
--- a/src/include/common/md5.h
+++ b/src/include/common/md5.h
@@ -26,9 +26,11 @@
 #define MD5_PASSWD_LEN	35
 
 /* Utilities common to all the MD5 implementations, as of md5_common.c */
-extern bool pg_md5_hash(const void *buff, size_t len, char *hexsum);
-extern bool pg_md5_binary(const void *buff, size_t len, void *outbuf);
+extern bool pg_md5_hash(const void *buff, size_t len, char *hexsum,
+		char **errstr);
+extern bool pg_md5_binary(const void *buff, size_t len, void *outbuf,
+		  char **errstr);
 extern bool pg_md5_encrypt(const char *passwd, const char *salt,
-		   size_t salt_len, char *buf);
+		   size_t salt_len, char *buf, char **errstr);
 
 #endif			/* PG_MD5_H */
diff --git a/src/backend/libpq/auth.c b/src/backend/libpq/auth.c
index 7bcf52523b..9f118ec546 100644
--- a/src/backend/libpq/auth.c
+++ b/src/backend/libpq/auth.c
@@ -3085,6 +3085,8 @@ PerformRadiusTransaction(const char *server, const char *secret, const char *por
 	md5trailer = packet->vector;
 	for (i = 0; i < encryptedpasswordlen; i += RADIUS_VECTOR_LENGTH)
 	{
+		char	   *errstr = NULL;
+
 		memcpy(cryptvector + strlen(secret), md5trailer, RADIUS_VECTOR_LENGTH);
 
 		/*
@@ -3093,10 +3095,12 @@ PerformRadiusTransaction(const char *

Getting json-value as varchar

2022-01-06 Thread Andreas Joseph Krogh

Hi, in PG-14 this query returns "value" (with double-quotes): 
SELECT ('{"key":"value"}'::jsonb)['key']; 
 ┌─┐
 │ jsonb │
 ├─┤
 │ "value" │
 └─┘
 (1 row)


and this returns 'value' (without the quotes): 
SELECT ('{"key":"value"}'::jsonb)->> 'key'; 
 ┌──┐
 │ ?column? │
 ├──┤
 │ value │
 └──┘
 (1 row)

 How to I use the subscript syntax and get the result as varchar instead of 
JSONB, assuming Iknow the JSON-field is a String? 



-- 
Andreas Joseph Krogh 
CTO / Partner - Visena AS 
Mobile: +47 909 56 963 
andr...@visena.com  
www.visena.com  
  

Re: Getting json-value as varchar

2022-01-06 Thread Thomas Markus

Hi,

Am 06.01.22 um 13:28 schrieb Andreas Joseph Krogh:

Hi, in PG-14 this query returns "value" (with double-quotes):
SELECT ('{"key":"value"}'::jsonb)['key'];
┌─┐
│  jsonb  │
├─┤
│ "value" │
└─┘
(1 row)

and this returns 'value' (without the quotes):
SELECT ('{"key":"value"}'::jsonb)->> 'key';
┌──┐
│ ?column? │
├──┤
│ value    │
└──┘
(1 row)

How to I use the subscript syntax and get the result as varchar 
instead of JSONB, assuming I /know/ the JSON-field is a String?

simply cast your value
SELECT (('{"key":"value"}'::jsonb)->> 'key')::text;

best regards
Thomas

--
*Andreas Joseph Krogh*
CTO / Partner - Visena AS
Mobile: +47 909 56 963
andr...@visena.com
www.visena.com 



Re: Getting json-value as varchar

2022-01-06 Thread Andreas Joseph Krogh

På torsdag 06. januar 2022 kl. 13:31:19, skrev Thomas Markus <
t.mar...@proventis.net >: Hi,

Am 06.01.22 um 13:28 schrieb Andreas Joseph Krogh: 
Hi, in PG-14 this query returns "value" (with double-quotes): 
SELECT ('{"key":"value"}'::jsonb)['key']; 
 ┌─┐
 │ jsonb │
 ├─┤
 │ "value" │
 └─┘
 (1 row)


and this returns 'value' (without the quotes): 
SELECT ('{"key":"value"}'::jsonb)->> 'key'; 
 ┌──┐
 │ ?column? │
 ├──┤
 │ value │
 └──┘
 (1 row)

 How to I use the subscript syntax and get the result as varchar instead of 
JSONB, assuming Iknow the JSON-field is a String?  simply cast your value
 SELECT (('{"key":"value"}'::jsonb)->> 'key')::text;

 best regards
 Thoma 

I think you misread my message. What I want is for the subscript-version: 
('{"key":"value"}'::jsonb)['key'] 
to return: 

┌──┐ 
 │ ?column? │
 ├──┤
 │ value │
 └──┘

 instead of 

┌─┐ 
 │ jsonb │
 ├─┤
 │ "value" │
 └─┘





-- 
Andreas Joseph Krogh 
CTO / Partner - Visena AS 
Mobile: +47 909 56 963 
andr...@visena.com  
www.visena.com  
  


Recommended storage hardware

2022-01-06 Thread Levente Birta

Hi all

What storage is recommended nowdays?

Currently I'm using two of SSD DC P3700 Series add in card 
(SSDPEDMD400G4) in soft raid 1, but it's pretty old and I have to 
replace the whole server.


Before, I used Intel too and I'm very satisfied, but now that intel sold 
the ssd business looks like I have to choose something else.


Or how about the optane? Is worth it?

Thanks
Levi









Re: Getting json-value as varchar

2022-01-06 Thread David G. Johnston
On Thursday, January 6, 2022, Andreas Joseph Krogh 
wrote:

>
>
> I think you misread my message. What I want is for the subscript-version:
>
> ('{"key":"value"}'::jsonb)['key']
>
> to return:
>
> ┌──┐
> │ ?column? │
> ├──┤
> │ value│
> └──┘
>
> instead of
>
> ┌─┐
> │  jsonb  │
> ├─┤
> │ "value" │
> └─
>
>
 A given syntax/operator can only return one thing so what you want is
fundamentally not possible.

David J.


Sv: Recommended storage hardware

2022-01-06 Thread Andreas Joseph Krogh

På torsdag 06. januar 2022 kl. 13:53:21, skrev Levente Birta <
blevi.li...@gmail.com >: 
Hi all

 What storage is recommended nowdays?

 Currently I'm using two of SSD DC P3700 Series add in card
 (SSDPEDMD400G4) in soft raid 1, but it's pretty old and I have to
 replace the whole server.

 Before, I used Intel too and I'm very satisfied, but now that intel sold
 the ssd business looks like I have to choose something else.

 Or how about the optane? Is worth it? 

We use Micron 9300: 
https://www.micron.com/products/ssd/product-lines/9300 

...with software RAID10 on Linux and XFS. 

Works very well! 



-- 
Andreas Joseph Krogh 
CTO / Partner - Visena AS 
Mobile: +47 909 56 963 
andr...@visena.com  
www.visena.com  
  


Re: Getting json-value as varchar

2022-01-06 Thread Andreas Joseph Krogh

På torsdag 06. januar 2022 kl. 14:13:40, skrev David G. Johnston <
david.g.johns...@gmail.com >: On Thursday, 
January 6, 2022, Andreas Joseph Krogh mailto:andr...@visena.com>> wrote: 


I think you misread my message. What I want is for the subscript-version: 
('{"key":"value"}'::jsonb)['key'] 
to return: 

┌──┐ 
 │ ?column? │
 ├──┤
 │ value │
 └──┘

 instead of 

┌─┐ 
 │ jsonb │
 ├─┤
 │ "value" │
 └─ 


 A given syntax/operator can only return one thing so what you want is 
fundamentally not possible. 

That's not very helpful 
Apparently I'm after a solution which either casts this to varchar or a 
function that takes JSONB as argument and outputs the first field-value as 
varchar. 



-- 
Andreas Joseph Krogh 
CTO / Partner - Visena AS 
Mobile: +47 909 56 963 
andr...@visena.com  
www.visena.com  
  


Re: Getting json-value as varchar

2022-01-06 Thread Thomas Markus

Hi,

Am 06.01.22 um 13:36 schrieb Andreas Joseph Krogh:
På torsdag 06. januar 2022 kl. 13:31:19, skrev Thomas Markus 
:


Hi,
Am 06.01.22 um 13:28 schrieb Andreas Joseph Krogh:

Hi, in PG-14 this query returns "value" (with double-quotes):
SELECT ('{"key":"value"}'::jsonb)['key'];
┌─┐
│  jsonb  │
├─┤
│ "value" │
└─┘
(1 row)

and this returns 'value' (without the quotes):
SELECT ('{"key":"value"}'::jsonb)->> 'key';
┌──┐
│ ?column? │
├──┤
│ value    │
└──┘
(1 row)

How to I use the subscript syntax and get the result as varchar
instead of JSONB, assuming I /know/ the JSON-field is a String?

simply cast your value
SELECT (('{"key":"value"}'::jsonb)->> 'key')::text;

best regards
Thoma

I think you misread my message. What I want is for the subscript-version:

('{"key":"value"}'::jsonb)['key']

to return:
┌──┐
│ ?column? │
├──┤
│ value    │
└──┘

instead of
┌─┐
│  jsonb  │
├─┤
│ "value" │
└─┘

yeah right :(

complicated but this should do:
SELECT  jsonb_build_array( ('{"key":"value"}'::jsonb)['key'] ) ->> 0;




--
*Andreas Joseph Krogh*
CTO / Partner - Visena AS
Mobile: +47 909 56 963
andr...@visena.com
www.visena.com 



Re: Getting json-value as varchar

2022-01-06 Thread David G. Johnston
On Thursday, January 6, 2022, Andreas Joseph Krogh 
wrote:

>
> Apparently I'm after a solution which either casts this to varchar or a
> function that takes JSONB as argument and outputs the first field-value as
> varchar.
>
>

You can try casting the value though IIRC it doesn’t actually work
(limitation of the feature).  The fact is that the ‘ - - > ‘ operator gives
you the needed output.

David J.


Re: Getting json-value as varchar

2022-01-06 Thread Andreas Joseph Krogh

På torsdag 06. januar 2022 kl. 14:29:12, skrev David G. Johnston <
david.g.johns...@gmail.com >: 
[..] 
The fact is that the ‘ - - > ‘ operator gives you the needed output. 

David J. 

Yeah, I think that's the correct answer for this use-case. 



-- 
Andreas Joseph Krogh 
CTO / Partner - Visena AS 
Mobile: +47 909 56 963 
andr...@visena.com  
www.visena.com  
  


Re: Getting json-value as varchar

2022-01-06 Thread Pavel Stehule
Hi

čt 6. 1. 2022 v 14:33 odesílatel Andreas Joseph Krogh 
napsal:

> På torsdag 06. januar 2022 kl. 14:29:12, skrev David G. Johnston <
> david.g.johns...@gmail.com>:
>
> [..]
> The fact is that the ‘ - - > ‘ operator gives you the needed output.
>
> David J.
>
>
> Yeah, I think that's the correct answer for this use-case.
>

It is true that some other casting function is missing. I am not sure if
this is part of ANSI/SQL json support.

Now, you can use helper function

CREATE OR REPLACE FUNCTION public.to_text(jsonb)
 RETURNS text
 LANGUAGE sql
AS $function$
select jsonb_array_element_text($1, 0)
$function$

postgres=# select to_text((jsonb '{"a":"Ahoj"}')['a']);
┌─┐
│ to_text │
╞═╡
│ Ahoj│
└─┘
(1 row)

Regards

Pavel



>
> --
> *Andreas Joseph Krogh*
> CTO / Partner - Visena AS
> Mobile: +47 909 56 963
> andr...@visena.com
> www.visena.com
> 
>
>


Re: Getting json-value as varchar

2022-01-06 Thread Andreas Joseph Krogh

På torsdag 06. januar 2022 kl. 14:42:21, skrev Pavel Stehule <
pavel.steh...@gmail.com >: 

Hi 

čt 6. 1. 2022 v 14:33 odesílatel Andreas Joseph Krogh mailto:andr...@visena.com>> napsal: 
På torsdag 06. januar 2022 kl. 14:29:12, skrev David G. Johnston <
david.g.johns...@gmail.com >: 
[..] 
The fact is that the ‘ - - > ‘ operator gives you the needed output. 

David J. 

Yeah, I think that's the correct answer for this use-case. 

It is true that some other casting function is missing. I am not sure if this 
is part of ANSI/SQL json support. 

Now, you can use helper function 

CREATE OR REPLACE FUNCTION public.to_text(jsonb)
 RETURNS text
 LANGUAGE sql
 AS $function$
 select jsonb_array_element_text($1, 0)
 $function$ 

postgres=# select to_text((jsonb '{"a":"Ahoj"}')['a']);
 ┌─┐
 │ to_text │
 ╞═╡
 │ Ahoj │
 └─┘
 (1 row) 

Regards 

Pavel 

Thanks! 



-- 
Andreas Joseph Krogh 
CTO / Partner - Visena AS 
Mobile: +47 909 56 963 
andr...@visena.com  
www.visena.com  
  


pg_dump parameter

2022-01-06 Thread Augusto Mossambani

Hi.

Is there a way when using pg_dump, inform a parameter to "clean" a 
certain column (ByteA) of a table, similar to oracle(Blob)? Oracle 
Example: Remap_data=TABLE.COLUMN_NAME:clear_blob_pack.clear_blob


Re: pg_dump parameter

2022-01-06 Thread David G. Johnston
On Thursday, January 6, 2022, Augusto Mossambani 
wrote:

> Hi.
>
> Is there a way when using pg_dump, inform a parameter to "clean" a certain 
> column (ByteA) of a table, similar to oracle(Blob)?
>
> Oracle Example:
> Remap_data=TABLE.COLUMN_NAME:clear_blob_pack.clear_blob
>
>
Not that I’m aware of.

 David J.


Re: Getting json-value as varchar

2022-01-06 Thread Thomas Kellerer

Andreas Joseph Krogh schrieb am 06.01.2022 um 13:28:

Hi, in PG-14 this query returns "value" (with double-quotes):
SELECT ('{"key":"value"}'::jsonb)['key'];
┌─┐
│  jsonb  │
├─┤
│ "value" │
└─┘
(1 row)

and this returns 'value' (without the quotes):
SELECT ('{"key":"value"}'::jsonb)->> 'key';
┌──┐
│ ?column? │
├──┤
│ value    │
└──┘
(1 row)



Unfortunately there isn't a direct cast from jsonb to text, but the #>> 
operator can be (mis)used for this:

SELECT ('{"key":"value"}'::jsonb)['key'] #>> '{}'


you can put that into a function if you need that frequently.





Re: md5 issues Postgres14 on OL7

2022-01-06 Thread Tom Lane
Michael Paquier  writes:
> I have been looking at that, and finished with the attached.  It is
> close to the end of the day, so this needs an extra lookup, but I have
> finished by using the idea of an extra routine, called
> pg_cryptohash_error(), able to grab the error saved in the private
> contexts, so as any callers from the backend or the frontend can feed
> on that.  This way, it is possible to make the difference between
> several class of errors: OOMs, a too short destination buffer, OpenSSL
> internal error, etc.

I don't like the end result of this at all:

postgres=# select md5('foo');
ERROR:  could not compute MD5 hash: OpenSSL failure

Maybe we've successfully laid off blame somewhere else, but this
doesn't move the user one inch towards understanding the cause.
I think we need to report the actual OpenSSL error reason.

I experimented with the attached, very rough delta on top of your
patch, and got

postgres=# select md5('foo');
ERROR:  could not compute MD5 hash: disabled for FIPS

which seems far better, plus it'd work for other sorts of OpenSSL
failures.

There are two problems with my delta as it stands:

1. It draws a cast-away-const warning.  We'd have to make the result
of pg_cryptohash_error be "const char *", which would be better
practice anyway, but that propagates into some other APIs and I didn't
take the trouble to chase it to the end.

2. It feels a bit bogus to be fetching ERR_get_error() at this point.
Maybe it's all right to assume that the OpenSSL error stack won't
change state before we get to pg_cryptohash_error, but I don't like
the idea much.  I think it'd be better to capture ERR_get_error()
sooner and store it in an additional field in pg_cryptohash_ctx.

Also, I wonder if this shouldn't be unified with the SSLerrmessage()
support found in be-secure-openssl.c and fe-secure-openssl.c.

regards, tom lane

diff -u cryptohash_openssl.c.orig cryptohash_openssl.c
--- cryptohash_openssl.c.orig	2022-01-06 11:15:59.268256281 -0500
+++ cryptohash_openssl.c	2022-01-06 11:22:28.602734304 -0500
@@ -21,6 +21,7 @@
 #include "postgres_fe.h"
 #endif
 
+#include 
 #include 
 
 #include "common/cryptohash.h"
@@ -309,7 +310,14 @@
 		case PG_CRYPTOHASH_ERROR_DEST_LEN:
 			return _("destination buffer too small");
 		case PG_CRYPTOHASH_ERROR_OPENSSL:
-			return _("OpenSSL failure");
+			{
+unsigned long ecode = ERR_get_error();
+const char *errreason = ERR_reason_error_string(ecode);
+
+if (errreason)
+	return errreason;
+return _("OpenSSL failure");
+			}
 	}
 
 	/* assume that the default is out-of-memory, anyway */


Re: md5 issues Postgres14 on OL7

2022-01-06 Thread Michael Paquier
On Thu, Jan 06, 2022 at 11:40:04AM -0500, Tom Lane wrote:
> 1. It draws a cast-away-const warning.  We'd have to make the result
> of pg_cryptohash_error be "const char *", which would be better
> practice anyway, but that propagates into some other APIs and I didn't
> take the trouble to chase it to the end.

Yeah.  I wanted to switch all those routines to use a const here
anyway, just did not have the time to tackle that yesterday with the
rest of the issues I could think about.  Looking at that today, I
don't see any problems in switching to const in all those places, so
done this way (two places in crypt.c are more picky, though, for
logdetail).

> 2. It feels a bit bogus to be fetching ERR_get_error() at this point.
> Maybe it's all right to assume that the OpenSSL error stack won't
> change state before we get to pg_cryptohash_error, but I don't like
> the idea much.  I think it'd be better to capture ERR_get_error()
> sooner and store it in an additional field in pg_cryptohash_ctx.

Right, I forgot about the ERR_get_error() piece of it.  Thanks!  I'd
also rather have the check done just after the OpenSSL call.  If hash
computations are split across multiple code paths, this could lead to
issues.  We don't have any problems currently in the core code, but I
see no reason to not make that safer in the long run.  And the
structure is flexible enough, so that's not an issue.

> Also, I wonder if this shouldn't be unified with the SSLerrmessage()
> support found in be-secure-openssl.c and fe-secure-openssl.c.

Guess so.  HEAD could be poked at for this part.  I recall looking at
that once by that did not seem worth the complications.

I have also looked at the ABI part of the patch.  I cannot spot any
public trace of pg_md5_hash() and pg_md5_binary().  pgbouncer and
pgpool2 have each a copy of pg_md5_encrypt(), but they just share the
API name with PG, nothing more.  So that looks reasonably safe to
change.

The last thing I have on my notes is to assign logdetail in
md5_crypt_verify() and plain_crypt_verify() to feed back a LOG entry
to the postmaster on those failures, and saw that it is safe to assign
directly the error returned by the cryptohash APIs, avoiding the
extra psprintf call that could become an issue under memory pressure.

What do you think?
--
Michael
From 62ecfb1a77a58f6e056822e3a7a0b3052fcf9e46 Mon Sep 17 00:00:00 2001
From: Michael Paquier 
Date: Fri, 7 Jan 2022 11:08:17 +0900
Subject: [PATCH v2] Improve error reporting for cryptohashes

---
 src/include/common/cryptohash.h   |  1 +
 src/include/common/md5.h  |  9 ++-
 src/backend/libpq/auth.c  | 14 ++--
 src/backend/libpq/crypt.c | 40 +++-
 src/backend/replication/backup_manifest.c |  9 ++-
 src/backend/utils/adt/cryptohashfuncs.c   | 25 ---
 src/common/cryptohash.c   | 57 +++-
 src/common/cryptohash_openssl.c   | 80 +++
 src/common/md5_common.c   | 20 --
 src/interfaces/libpq/fe-auth.c| 22 +--
 contrib/uuid-ossp/uuid-ossp.c | 18 +++--
 11 files changed, 244 insertions(+), 51 deletions(-)

diff --git a/src/include/common/cryptohash.h b/src/include/common/cryptohash.h
index 541dc844c8..c62c350d57 100644
--- a/src/include/common/cryptohash.h
+++ b/src/include/common/cryptohash.h
@@ -34,5 +34,6 @@ extern int	pg_cryptohash_init(pg_cryptohash_ctx *ctx);
 extern int	pg_cryptohash_update(pg_cryptohash_ctx *ctx, const uint8 *data, size_t len);
 extern int	pg_cryptohash_final(pg_cryptohash_ctx *ctx, uint8 *dest, size_t len);
 extern void pg_cryptohash_free(pg_cryptohash_ctx *ctx);
+extern const char *pg_cryptohash_error(pg_cryptohash_ctx *ctx);
 
 #endif			/* PG_CRYPTOHASH_H */
diff --git a/src/include/common/md5.h b/src/include/common/md5.h
index 62a31e6ed4..cc43fc6606 100644
--- a/src/include/common/md5.h
+++ b/src/include/common/md5.h
@@ -26,9 +26,12 @@
 #define MD5_PASSWD_LEN	35
 
 /* Utilities common to all the MD5 implementations, as of md5_common.c */
-extern bool pg_md5_hash(const void *buff, size_t len, char *hexsum);
-extern bool pg_md5_binary(const void *buff, size_t len, void *outbuf);
+extern bool pg_md5_hash(const void *buff, size_t len, char *hexsum,
+		const char **errstr);
+extern bool pg_md5_binary(const void *buff, size_t len, void *outbuf,
+		  const char **errstr);
 extern bool pg_md5_encrypt(const char *passwd, const char *salt,
-		   size_t salt_len, char *buf);
+		   size_t salt_len, char *buf,
+		   const char **errstr);
 
 #endif			/* PG_MD5_H */
diff --git a/src/backend/libpq/auth.c b/src/backend/libpq/auth.c
index 7bcf52523b..eea933f41e 100644
--- a/src/backend/libpq/auth.c
+++ b/src/backend/libpq/auth.c
@@ -3085,6 +3085,8 @@ PerformRadiusTransaction(const char *server, const char *secret, const char *por
 	md5trailer = packet->vector;
 	for (i = 0; i < encryptedpasswordlen; i += RADIUS_VECTOR_LENGTH)
 	{
+		const char