Skip to content

Commit a04c63b

Browse files
committed
Merge branch 'master' into fdw-extension-support
2 parents 5e495de + b943f50 commit a04c63b

File tree

112 files changed

+5530
-465
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

112 files changed

+5530
-465
lines changed

contrib/earthdistance/expected/earthdistance.out

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
--
1010
CREATE EXTENSION earthdistance; -- fail, must install cube first
1111
ERROR: required extension "cube" is not installed
12+
HINT: Use CREATE EXTENSION CASCADE to install required extensions too.
1213
CREATE EXTENSION cube;
1314
CREATE EXTENSION earthdistance;
1415
--

contrib/hstore_plperl/expected/hstore_plperl.out

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
CREATE EXTENSION hstore;
2-
CREATE EXTENSION plperl;
3-
CREATE EXTENSION hstore_plperl;
1+
CREATE EXTENSION hstore_plperl CASCADE;
2+
NOTICE: installing required extension "hstore"
3+
NOTICE: installing required extension "plperl"
44
SELECT transforms.udt_schema, transforms.udt_name,
55
routine_schema, routine_name,
66
group_name, transform_type

contrib/hstore_plperl/expected/hstore_plperlu.out

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
CREATE EXTENSION hstore;
2-
CREATE EXTENSION plperlu;
3-
CREATE EXTENSION hstore_plperlu;
1+
CREATE EXTENSION hstore_plperlu CASCADE;
2+
NOTICE: installing required extension "hstore"
3+
NOTICE: installing required extension "plperlu"
44
SELECT transforms.udt_schema, transforms.udt_name,
55
routine_schema, routine_name,
66
group_name, transform_type

contrib/hstore_plperl/sql/hstore_plperl.sql

+1-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
CREATE EXTENSION hstore;
2-
CREATE EXTENSION plperl;
3-
CREATE EXTENSION hstore_plperl;
1+
CREATE EXTENSION hstore_plperl CASCADE;
42

53
SELECT transforms.udt_schema, transforms.udt_name,
64
routine_schema, routine_name,

contrib/hstore_plperl/sql/hstore_plperlu.sql

+1-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
CREATE EXTENSION hstore;
2-
CREATE EXTENSION plperlu;
3-
CREATE EXTENSION hstore_plperlu;
1+
CREATE EXTENSION hstore_plperlu CASCADE;
42

53
SELECT transforms.udt_schema, transforms.udt_name,
64
routine_schema, routine_name,

contrib/hstore_plpython/expected/hstore_plpython.out

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
CREATE EXTENSION plpython2u;
2-
CREATE EXTENSION hstore_plpython2u;
1+
CREATE EXTENSION hstore_plpython2u CASCADE;
2+
NOTICE: installing required extension "plpython2u"
33
-- test hstore -> python
44
CREATE FUNCTION test1(val hstore) RETURNS int
55
LANGUAGE plpythonu

contrib/hstore_plpython/sql/hstore_plpython.sql

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
CREATE EXTENSION plpython2u;
2-
CREATE EXTENSION hstore_plpython2u;
1+
CREATE EXTENSION hstore_plpython2u CASCADE;
32

43

54
-- test hstore -> python

contrib/intarray/_int_bool.c

+3
Original file line numberDiff line numberDiff line change
@@ -564,6 +564,9 @@ typedef struct
564564
static void
565565
infix(INFIX *in, bool first)
566566
{
567+
/* since this function recurses, it could be driven to stack overflow. */
568+
check_stack_depth();
569+
567570
if (in->curpol->type == VAL)
568571
{
569572
RESIZEBUF(in, 11);

contrib/ltree/ltxtquery_io.c

+3
Original file line numberDiff line numberDiff line change
@@ -416,6 +416,9 @@ while( ( (inf)->cur - (inf)->buf ) + (addsize) + 1 >= (inf)->buflen ) \
416416
static void
417417
infix(INFIX *in, bool first)
418418
{
419+
/* since this function recurses, it could be driven to stack overflow. */
420+
check_stack_depth();
421+
419422
if (in->curpol->type == VAL)
420423
{
421424
char *op = in->op + in->curpol->distance;

contrib/ltree/ltxtquery_op.c

+4
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <ctype.h>
99

1010
#include "ltree.h"
11+
#include "miscadmin.h"
1112

1213
PG_FUNCTION_INFO_V1(ltxtq_exec);
1314
PG_FUNCTION_INFO_V1(ltxtq_rexec);
@@ -18,6 +19,9 @@ PG_FUNCTION_INFO_V1(ltxtq_rexec);
1819
bool
1920
ltree_execute(ITEM *curitem, void *checkval, bool calcnot, bool (*chkcond) (void *checkval, ITEM *val))
2021
{
22+
/* since this function recurses, it could be driven to stack overflow */
23+
check_stack_depth();
24+
2125
if (curitem->type == VAL)
2226
return (*chkcond) (checkval, curitem);
2327
else if (curitem->val == (int32) '!')

contrib/ltree_plpython/expected/ltree_plpython.out

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
CREATE EXTENSION plpython2u;
2-
CREATE EXTENSION ltree_plpython2u;
1+
CREATE EXTENSION ltree_plpython2u CASCADE;
2+
NOTICE: installing required extension "plpython2u"
33
CREATE FUNCTION test1(val ltree) RETURNS int
44
LANGUAGE plpythonu
55
TRANSFORM FOR TYPE ltree

contrib/ltree_plpython/sql/ltree_plpython.sql

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
CREATE EXTENSION plpython2u;
2-
CREATE EXTENSION ltree_plpython2u;
1+
CREATE EXTENSION ltree_plpython2u CASCADE;
32

43

54
CREATE FUNCTION test1(val ltree) RETURNS int

contrib/pg_stat_statements/pg_stat_statements.c

+75-18
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ typedef struct pgssEntry
170170
pgssHashKey key; /* hash key of entry - MUST BE FIRST */
171171
Counters counters; /* the statistics for this query */
172172
Size query_offset; /* query text offset in external file */
173-
int query_len; /* # of valid bytes in query string */
173+
int query_len; /* # of valid bytes in query string, or -1 */
174174
int encoding; /* query text encoding */
175175
slock_t mutex; /* protects the counters only */
176176
} pgssEntry;
@@ -1705,7 +1705,8 @@ entry_cmp(const void *lhs, const void *rhs)
17051705
}
17061706

17071707
/*
1708-
* Deallocate least used entries.
1708+
* Deallocate least-used entries.
1709+
*
17091710
* Caller must hold an exclusive lock on pgss->lock.
17101711
*/
17111712
static void
@@ -1716,17 +1717,27 @@ entry_dealloc(void)
17161717
pgssEntry *entry;
17171718
int nvictims;
17181719
int i;
1719-
Size totlen = 0;
1720+
Size tottextlen;
1721+
int nvalidtexts;
17201722

17211723
/*
17221724
* Sort entries by usage and deallocate USAGE_DEALLOC_PERCENT of them.
17231725
* While we're scanning the table, apply the decay factor to the usage
1724-
* values.
1726+
* values, and update the mean query length.
1727+
*
1728+
* Note that the mean query length is almost immediately obsolete, since
1729+
* we compute it before not after discarding the least-used entries.
1730+
* Hopefully, that doesn't affect the mean too much; it doesn't seem worth
1731+
* making two passes to get a more current result. Likewise, the new
1732+
* cur_median_usage includes the entries we're about to zap.
17251733
*/
17261734

17271735
entries = palloc(hash_get_num_entries(pgss_hash) * sizeof(pgssEntry *));
17281736

17291737
i = 0;
1738+
tottextlen = 0;
1739+
nvalidtexts = 0;
1740+
17301741
hash_seq_init(&hash_seq, pgss_hash);
17311742
while ((entry = hash_seq_search(&hash_seq)) != NULL)
17321743
{
@@ -1736,20 +1747,27 @@ entry_dealloc(void)
17361747
entry->counters.usage *= STICKY_DECREASE_FACTOR;
17371748
else
17381749
entry->counters.usage *= USAGE_DECREASE_FACTOR;
1739-
/* Accumulate total size, too. */
1740-
totlen += entry->query_len + 1;
1750+
/* In the mean length computation, ignore dropped texts. */
1751+
if (entry->query_len >= 0)
1752+
{
1753+
tottextlen += entry->query_len + 1;
1754+
nvalidtexts++;
1755+
}
17411756
}
17421757

1758+
/* Sort into increasing order by usage */
17431759
qsort(entries, i, sizeof(pgssEntry *), entry_cmp);
17441760

1761+
/* Record the (approximate) median usage */
17451762
if (i > 0)
1746-
{
1747-
/* Record the (approximate) median usage */
17481763
pgss->cur_median_usage = entries[i / 2]->counters.usage;
1749-
/* Record the mean query length */
1750-
pgss->mean_query_len = totlen / i;
1751-
}
1764+
/* Record the mean query length */
1765+
if (nvalidtexts > 0)
1766+
pgss->mean_query_len = tottextlen / nvalidtexts;
1767+
else
1768+
pgss->mean_query_len = ASSUMED_LENGTH_INIT;
17521769

1770+
/* Now zap an appropriate fraction of lowest-usage entries */
17531771
nvictims = Max(10, i * USAGE_DEALLOC_PERCENT / 100);
17541772
nvictims = Min(nvictims, i);
17551773

@@ -1892,15 +1910,17 @@ qtext_load_file(Size *buffer_size)
18921910
}
18931911

18941912
/* Allocate buffer; beware that off_t might be wider than size_t */
1895-
if (stat.st_size <= MaxAllocSize)
1913+
if (stat.st_size <= MaxAllocHugeSize)
18961914
buf = (char *) malloc(stat.st_size);
18971915
else
18981916
buf = NULL;
18991917
if (buf == NULL)
19001918
{
19011919
ereport(LOG,
19021920
(errcode(ERRCODE_OUT_OF_MEMORY),
1903-
errmsg("out of memory")));
1921+
errmsg("out of memory"),
1922+
errdetail("Could not allocate enough memory to read pg_stat_statement file \"%s\".",
1923+
PGSS_TEXT_FILE)));
19041924
CloseTransientFile(fd);
19051925
return NULL;
19061926
}
@@ -2002,13 +2022,17 @@ need_gc_qtexts(void)
20022022
* occur in the foreseeable future.
20032023
*
20042024
* The caller must hold an exclusive lock on pgss->lock.
2025+
*
2026+
* At the first sign of trouble we unlink the query text file to get a clean
2027+
* slate (although existing statistics are retained), rather than risk
2028+
* thrashing by allowing the same problem case to recur indefinitely.
20052029
*/
20062030
static void
20072031
gc_qtexts(void)
20082032
{
20092033
char *qbuffer;
20102034
Size qbuffer_size;
2011-
FILE *qfile;
2035+
FILE *qfile = NULL;
20122036
HASH_SEQ_STATUS hash_seq;
20132037
pgssEntry *entry;
20142038
Size extent;
@@ -2023,12 +2047,15 @@ gc_qtexts(void)
20232047
return;
20242048

20252049
/*
2026-
* Load the old texts file. If we fail (out of memory, for instance) just
2027-
* skip the garbage collection.
2050+
* Load the old texts file. If we fail (out of memory, for instance),
2051+
* invalidate query texts. Hopefully this is rare. It might seem better
2052+
* to leave things alone on an OOM failure, but the problem is that the
2053+
* file is only going to get bigger; hoping for a future non-OOM result is
2054+
* risky and can easily lead to complete denial of service.
20282055
*/
20292056
qbuffer = qtext_load_file(&qbuffer_size);
20302057
if (qbuffer == NULL)
2031-
return;
2058+
goto gc_fail;
20322059

20332060
/*
20342061
* We overwrite the query texts file in place, so as to reduce the risk of
@@ -2063,6 +2090,7 @@ gc_qtexts(void)
20632090
/* Trouble ... drop the text */
20642091
entry->query_offset = 0;
20652092
entry->query_len = -1;
2093+
/* entry will not be counted in mean query length computation */
20662094
continue;
20672095
}
20682096

@@ -2147,7 +2175,36 @@ gc_qtexts(void)
21472175
entry->query_len = -1;
21482176
}
21492177

2150-
/* Seems like a good idea to bump the GC count even though we failed */
2178+
/*
2179+
* Destroy the query text file and create a new, empty one
2180+
*/
2181+
(void) unlink(PGSS_TEXT_FILE);
2182+
qfile = AllocateFile(PGSS_TEXT_FILE, PG_BINARY_W);
2183+
if (qfile == NULL)
2184+
ereport(LOG,
2185+
(errcode_for_file_access(),
2186+
errmsg("could not write new pg_stat_statement file \"%s\": %m",
2187+
PGSS_TEXT_FILE)));
2188+
else
2189+
FreeFile(qfile);
2190+
2191+
/* Reset the shared extent pointer */
2192+
pgss->extent = 0;
2193+
2194+
/* Reset mean_query_len to match the new state */
2195+
pgss->mean_query_len = ASSUMED_LENGTH_INIT;
2196+
2197+
/*
2198+
* Bump the GC count even though we failed.
2199+
*
2200+
* This is needed to make concurrent readers of file without any lock on
2201+
* pgss->lock notice existence of new version of file. Once readers
2202+
* subsequently observe a change in GC count with pgss->lock held, that
2203+
* forces a safe reopen of file. Writers also require that we bump here,
2204+
* of course. (As required by locking protocol, readers and writers don't
2205+
* trust earlier file contents until gc_count is found unchanged after
2206+
* pgss->lock acquired in shared or exclusive mode respectively.)
2207+
*/
21512208
record_gc_qtexts();
21522209
}
21532210

contrib/pgcrypto/crypt-blowfish.c

+17-2
Original file line numberDiff line numberDiff line change
@@ -602,6 +602,17 @@ _crypt_blowfish_rn(const char *key, const char *setting,
602602
if (size < 7 + 22 + 31 + 1)
603603
return NULL;
604604

605+
/*
606+
* Blowfish salt value must be formatted as follows: "$2a$" or "$2x$", a
607+
* two digit cost parameter, "$", and 22 digits from the alphabet
608+
* "./0-9A-Za-z". -- from the PHP crypt docs. Apparently we enforce a few
609+
* more restrictions on the count in the salt as well.
610+
*/
611+
if (strlen(setting) < 29)
612+
ereport(ERROR,
613+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
614+
errmsg("invalid salt")));
615+
605616
if (setting[0] != '$' ||
606617
setting[1] != '2' ||
607618
(setting[2] != 'a' && setting[2] != 'x') ||
@@ -611,14 +622,18 @@ _crypt_blowfish_rn(const char *key, const char *setting,
611622
(setting[4] == '3' && setting[5] > '1') ||
612623
setting[6] != '$')
613624
{
614-
return NULL;
625+
ereport(ERROR,
626+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
627+
errmsg("invalid salt")));
615628
}
616629

617630
count = (BF_word) 1 << ((setting[4] - '0') * 10 + (setting[5] - '0'));
618631
if (count < 16 || BF_decode(data.binary.salt, &setting[7], 16))
619632
{
620633
px_memset(data.binary.salt, 0, sizeof(data.binary.salt));
621-
return NULL;
634+
ereport(ERROR,
635+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
636+
errmsg("invalid salt")));
622637
}
623638
BF_swap(data.binary.salt, 4);
624639

contrib/pgcrypto/crypt-des.c

+19-3
Original file line numberDiff line numberDiff line change
@@ -681,9 +681,19 @@ px_crypt_des(const char *key, const char *setting)
681681
if (*setting == _PASSWORD_EFMT1)
682682
{
683683
/*
684-
* "new"-style: setting - underscore, 4 bytes of count, 4 bytes of
685-
* salt key - unlimited characters
684+
* "new"-style: setting must be a 9-character (underscore, then 4
685+
* bytes of count, then 4 bytes of salt) string. See CRYPT(3) under
686+
* the "Extended crypt" heading for further details.
687+
*
688+
* Unlimited characters of the input key are used. This is known as
689+
* the "Extended crypt" DES method.
690+
*
686691
*/
692+
if (strlen(setting) < 9)
693+
ereport(ERROR,
694+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
695+
errmsg("invalid salt")));
696+
687697
for (i = 1, count = 0L; i < 5; i++)
688698
count |= ascii_to_bin(setting[i]) << (i - 1) * 6;
689699

@@ -722,10 +732,16 @@ px_crypt_des(const char *key, const char *setting)
722732
#endif /* !DISABLE_XDES */
723733
{
724734
/*
725-
* "old"-style: setting - 2 bytes of salt key - up to 8 characters
735+
* "old"-style: setting - 2 bytes of salt key - only up to the first 8
736+
* characters of the input key are used.
726737
*/
727738
count = 25;
728739

740+
if (strlen(setting) < 2)
741+
ereport(ERROR,
742+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
743+
errmsg("invalid salt")));
744+
729745
salt = (ascii_to_bin(setting[1]) << 6)
730746
| ascii_to_bin(setting[0]);
731747

contrib/pgcrypto/expected/crypt-blowfish.out

+9
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,15 @@ SELECT crypt('foox', '$2a$06$RQiOJ.3ELirrXwxIZY8q0O');
1313
$2a$06$RQiOJ.3ELirrXwxIZY8q0OR3CVJrAfda1z26CCHPnB6mmVZD8p0/C
1414
(1 row)
1515

16+
-- error, salt too short:
17+
SELECT crypt('foox', '$2a$');
18+
ERROR: invalid salt
19+
-- error, first digit of count in salt invalid
20+
SELECT crypt('foox', '$2a$40$RQiOJ.3ELirrXwxIZY8q0O');
21+
ERROR: invalid salt
22+
-- error, count in salt too small
23+
SELECT crypt('foox', '$2a$00$RQiOJ.3ELirrXwxIZY8q0O');
24+
ERROR: invalid salt
1625
CREATE TABLE ctest (data text, res text, salt text);
1726
INSERT INTO ctest VALUES ('password', '', '');
1827
UPDATE ctest SET salt = gen_salt('bf', 8);

0 commit comments

Comments
 (0)