diff options
author | Neil Conway | 2005-02-23 22:46:17 +0000 |
---|---|---|
committer | Neil Conway | 2005-02-23 22:46:17 +0000 |
commit | 4921024a0a9319c2ebd377cc2e2b9ec073844ef5 (patch) | |
tree | 1873927226e4cdef9f3591f9a46604434a672de6 | |
parent | dc773ee7de51cd950900c4351ecd14f5f18a3832 (diff) |
This patch optimizes the md5_text() function (which is used to
implement the md5() SQL-level function). The old code did the
following:
1. de-toast the datum
2. convert it to a cstring via textout()
3. get the length of the cstring via strlen()
Since we are treating the datum context as a blob of binary data,
the latter two steps are unnecessary. Once the data has been
detoasted, we can just use it as-is, and derive its length from
the varlena metadata.
This patch improves some run-of-the-mill md5() computations by
just under 10% in my limited tests, and passes the regression tests.
I also noticed that md5_text() wasn't checking the return value
of md5_hash(); encountering OOM at precisely the right moment
could result in returning a random md5 hash. This patch corrects
that. A better fix would be to make md5_hash() only return on
success (and/or allocate via palloc()), but since it's used in
the frontend as well I don't see an easy way to do that.
-rw-r--r-- | src/backend/libpq/md5.c | 4 | ||||
-rw-r--r-- | src/backend/utils/adt/varlena.c | 12 |
2 files changed, 11 insertions, 5 deletions
diff --git a/src/backend/libpq/md5.c b/src/backend/libpq/md5.c index c0405199f9..8855905e6b 100644 --- a/src/backend/libpq/md5.c +++ b/src/backend/libpq/md5.c @@ -289,8 +289,8 @@ bytesToHex(uint8 b[16], char *s) * characters. you thus need to provide an array * of 33 characters, including the trailing '\0'. * - * RETURNS 0 on failure (out of memory for internal buffers) or - * non-zero on success. + * RETURNS false on failure (out of memory for internal buffers) or + * true on success. * * STANDARDS MD5 is described in RFC 1321. * diff --git a/src/backend/utils/adt/varlena.c b/src/backend/utils/adt/varlena.c index 66c9a6a16c..d2b674477c 100644 --- a/src/backend/utils/adt/varlena.c +++ b/src/backend/utils/adt/varlena.c @@ -2310,16 +2310,22 @@ to_hex64(PG_FUNCTION_ARGS) Datum md5_text(PG_FUNCTION_ARGS) { - char *buff = PG_TEXT_GET_STR(PG_GETARG_TEXT_P(0)); - size_t len = strlen(buff); + text *in_text = PG_GETARG_TEXT_P(0); + size_t len; char *hexsum; text *result_text; + /* Calculate the length of the buffer using varlena metadata */ + len = VARSIZE(in_text) - VARHDRSZ; + /* leave room for the terminating '\0' */ hexsum = (char *) palloc(MD5_HASH_LEN + 1); /* get the hash result */ - md5_hash((void *) buff, len, hexsum); + if (md5_hash(VARDATA(in_text), len, hexsum) == false) + ereport(ERROR, + (errcode(ERRCODE_OUT_OF_MEMORY), + errmsg("out of memory"))); /* convert to text and return it */ result_text = PG_STR_GET_TEXT(hexsum); |