Re: Improve search for missing parent downlinks in amcheck

2019-04-27 Thread Peter Geoghegan
On Sat, Apr 27, 2019 at 5:13 PM Alexander Korotkov
 wrote:
> Yes, increasing of Bloom filter size also helps.  But my intention was
> to make non-lossy check here.

Why is that your intention? Do you want to do this as a feature for
Postgres 13, or do you want to treat this as a bug that we need to
backpatch a fix for?

Can we avoid the problem you saw with the Bloom filter approach by
using the real size of the index (i.e.
smgrnblocks()/RelationGetNumberOfBlocks()) to size the Bloom filter,
and/or by rethinking the work_mem cap? Maybe we can have a WARNING
that advertises that work_mem is probably too low?

The  state->downlinkfilter Bloom filter should be small in almost all
cases, so I still don't fully understand your concern. With a 100GB
index, we'll have ~13 million blocks. We only need a Bloom filter that
is ~250MB to have less than a 1% chance of missing inconsistencies
even with such a large index. I admit that its unfriendly that users
are not warned about the shortage currently, but that is something we
can probably find a simple (backpatchable) fix for.

-- 
Peter Geoghegan




Re: Race conditions with checkpointer and shutdown

2019-04-27 Thread Tom Lane
I have spent a fair amount of time trying to replicate these failures
locally, with little success.  I now think that the most promising theory
is Munro's idea in [1] that the walreceiver is hanging up during its
unsafe attempt to do ereport(FATAL) from inside a signal handler.  It's
extremely plausible that that could result in a deadlock inside libc's
malloc/free, or some similar place.  Moreover, if that's what's causing
it, then the windows for trouble are fixed by the length of time that
malloc might hold internal locks, which fits with the results I've gotten
that inserting delays in various promising-looking places doesn't do a
thing towards making this reproducible.

Even if that isn't the proximate cause of the current reports, it's
clearly trouble waiting to happen, and we should get rid of it.
Accordingly, see attached proposed patch.  This just flushes the
"immediate interrupt" stuff in favor of making sure that
libpqwalreceiver.c will take care of any signals received while
waiting for input.

The existing code does not use PQsetnonblocking, which means that it's
theoretically at risk of blocking while pushing out data to the remote
server.  In practice I think that risk is negligible because (IIUC) we
don't send very large amounts of data at one time.  So I didn't bother to
change that.  Note that for the most part, if that happened, the existing
code was at risk of slow response to SIGTERM anyway since it didn't have
Enable/DisableWalRcvImmediateExit around the places that send data.

My thought is to apply this only to HEAD for now; it's kind of a large
change to shove into the back branches to handle a failure mode that's
not been reported from the field.  Maybe we could back-patch after we
have more confidence in it.

regards, tom lane

[1] 
https://www.postgresql.org/message-id/CA%2BhUKG%2B%3D1G98m61VjNS-qGboJPwdZcF%2BrAPu2eC4XuWRTR3UPw%40mail.gmail.com

diff --git a/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c b/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c
index 7123d41..765d58d 100644
--- a/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c
+++ b/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c
@@ -99,6 +99,7 @@ static WalReceiverFunctionsType PQWalReceiverFunctions = {
 
 /* Prototypes for private functions */
 static PGresult *libpqrcv_PQexec(PGconn *streamConn, const char *query);
+static PGresult *libpqrcv_PQgetResult(PGconn *streamConn);
 static char *stringlist_to_identifierstr(PGconn *conn, List *strings);
 
 /*
@@ -196,7 +197,7 @@ libpqrcv_connect(const char *conninfo, bool logical, const char *appname,
 		if (rc & WL_LATCH_SET)
 		{
 			ResetLatch(MyLatch);
-			CHECK_FOR_INTERRUPTS();
+			ProcessWalRcvInterrupts();
 		}
 
 		/* If socket is ready, advance the libpq state machine */
@@ -456,6 +457,10 @@ libpqrcv_endstreaming(WalReceiverConn *conn, TimeLineID *next_tli)
 {
 	PGresult   *res;
 
+	/*
+	 * Send copy-end message.  As in libpqrcv_PQexec, this could theoretically
+	 * block, but the risk seems small.
+	 */
 	if (PQputCopyEnd(conn->streamConn, NULL) <= 0 ||
 		PQflush(conn->streamConn))
 		ereport(ERROR,
@@ -472,7 +477,7 @@ libpqrcv_endstreaming(WalReceiverConn *conn, TimeLineID *next_tli)
 	 * If we had not yet received CopyDone from the backend, PGRES_COPY_OUT is
 	 * also possible in case we aborted the copy in mid-stream.
 	 */
-	res = PQgetResult(conn->streamConn);
+	res = libpqrcv_PQgetResult(conn->streamConn);
 	if (PQresultStatus(res) == PGRES_TUPLES_OK)
 	{
 		/*
@@ -486,7 +491,7 @@ libpqrcv_endstreaming(WalReceiverConn *conn, TimeLineID *next_tli)
 		PQclear(res);
 
 		/* the result set should be followed by CommandComplete */
-		res = PQgetResult(conn->streamConn);
+		res = libpqrcv_PQgetResult(conn->streamConn);
 	}
 	else if (PQresultStatus(res) == PGRES_COPY_OUT)
 	{
@@ -499,7 +504,7 @@ libpqrcv_endstreaming(WalReceiverConn *conn, TimeLineID *next_tli)
 			pchomp(PQerrorMessage(conn->streamConn);
 
 		/* CommandComplete should follow */
-		res = PQgetResult(conn->streamConn);
+		res = libpqrcv_PQgetResult(conn->streamConn);
 	}
 
 	if (PQresultStatus(res) != PGRES_COMMAND_OK)
@@ -509,7 +514,7 @@ libpqrcv_endstreaming(WalReceiverConn *conn, TimeLineID *next_tli)
 	PQclear(res);
 
 	/* Verify that there are no more results */
-	res = PQgetResult(conn->streamConn);
+	res = libpqrcv_PQgetResult(conn->streamConn);
 	if (res != NULL)
 		ereport(ERROR,
 (errmsg("unexpected result after CommandComplete: %s",
@@ -572,12 +577,11 @@ libpqrcv_readtimelinehistoryfile(WalReceiverConn *conn,
  * The function is modeled on PQexec() in libpq, but only implements
  * those parts that are in use in the walreceiver api.
  *
- * Queries are always executed on the connection in streamConn.
+ * May return NULL, rather than an error result, on failure.
  */
 static PGresult *
 libpqrcv_PQexec(PGconn *streamConn, const char *query)
 {
-	PGresult   *result = NULL;
 	PGresult   *lastResult = 

Re: Improve search for missing parent downlinks in amcheck

2019-04-27 Thread Peter Geoghegan
On Sat, Apr 27, 2019 at 5:13 PM Alexander Korotkov
 wrote:
> Yes, increasing of Bloom filter size also helps.  But my intention was
> to make non-lossy check here.

I agree that that might be a good goal, but I am interested in knowing
if there is something naive about how the downlinkfilter Bloom filter
is sized. I think that we could probably do better than this without
much work:

/*
 * Extra readonly downlink check.
 *
 * In readonly case, we know that there cannot be a concurrent
 * page split or a concurrent page deletion, which gives us the
 * opportunity to verify that every non-ignorable page had a
 * downlink one level up.  We must be tolerant of interrupted page
 * splits and page deletions, though.  This is taken care of in
 * bt_downlink_missing_check().
 */
total_pages = (int64) state->rel->rd_rel->relpages;
state->downlinkfilter = bloom_create(total_pages, work_mem, seed);

Maybe we could use "smgrnblocks(index->rd_smgr, MAIN_FORKNUM))"
instead of relpages, for example.

> It wouldn't be really wasteful, because the same children were
> accessed recently.  So, they are likely not yet evicted from
> shared_buffers.  I think we can fit both checks into one loop over
> downlinks instead of two.

I see your point, but if we're going to treat this as a bug then I
would prefer a simple fix.

> Yes, we can do more checks with bloom filter.  But assuming that we
> anyway iterate over children for each non-leaf page, can we do:
> 1) All the checks, which bt_downlink_check() does for now
> 2) Check there are no missing downlinks
> 3) Check hikeys
> in one pass, can't we?

We can expect every high key in a page to have a copy contained within
its parent, either as one of the keys, or as parent's own high key
(assuming no concurrent or interrupted page splits or page deletions).
This is true today, even though we truncate negative infinity items in
internal pages.

I think that the simple answer to your question is yes. It would be
more complicated that way, and the only extra check would be the check
of high keys against their parent, but overall this does seem
possible.

-- 
Peter Geoghegan




Re: Improve search for missing parent downlinks in amcheck

2019-04-27 Thread Alexander Korotkov
On Tue, Apr 16, 2019 at 10:00 PM Peter Geoghegan  wrote:
>
> On Mon, Apr 15, 2019 at 7:30 PM Alexander Korotkov
>  wrote:
> > Currently we amcheck supports lossy checking for missing parent
> > downlinks.  It collects bitmap of downlink hashes and use it to check
> > subsequent tree level.  We've experienced some large corrupted indexes
> > which pass this check due to its looseness.
>
> Can you be more specific? What was the cause of the corruption? I'm
> always very interested in hearing about cases that amcheck could have
> detected, but didn't.

AFAIR, the cause of corruption in this case was our (Postgres Pro)
modification.  Not something really present in PostgreSQL core.

>
> Was the issue that the Bloom filter was simply undersized/ineffective?

Yes, increasing of Bloom filter size also helps.  But my intention was
to make non-lossy check here.

>
> > However, it seems to me we can implement this check in non-lossy
> > manner without making it significantly slower.  We anyway traverse
> > downlinks from parent to children in order to verify that hikeys are
> > corresponding to downlink keys.
>
> Actually, we don't check the high keys in children against the parent
> (all other items are checked, though). We probably *should* do
> something with the high key when verifying consistency across levels,
> but currently we don't. (We only use the high key for the same-page
> high key check -- more on this below.)

Nice idea.

> > We can also traverse from one
> > downlink to subsequent using rightlinks.  So, if there are some
> > intermediate pages between them, they are candidates to have missing
> > parent downlinks.  The patch is attached.
> >
> > With this patch amcheck could successfully detect corruption for our
> > customer, which unpatched amcheck couldn't find.
>
> Maybe we can be a lot less conservative about sizing the Bloom filter
> instead? That would be an easier fix IMV -- we can probably change
> that logic to be a lot more aggressive without anybody noticing, since
> the Bloom filter is already usually tiny. We are already not very
> careful about saving work within bt_index_parent_check(), but with
> this patch we follow each downlink twice instead of once. That seems
> wasteful.

It wouldn't be really wasteful, because the same children were
accessed recently.  So, they are likely not yet evicted from
shared_buffers.  I think we can fit both checks into one loop over
downlinks instead of two.

> The reason I used a Bloom filter here is because I would eventually
> like the missing downlink check to fingerprint entire tuples, not just
> block numbers. In L terms, the check could in the future fingerprint
> the separator key and the downlink at the same time, not just the
> downlink. That way, we could probe the Bloom filter on the next level
> down for its high key (with the right sibling pointer set to be
> consistent with the parent) iff we don't see that the page split was
> interrupted (i.e. iff P_INCOMPLETE_SPLIT() bit is not set). Obviously
> this would be a more effective form of verification, since we would
> notice high key values that don't agree with the parent's values for
> the same sibling/cousin/child block.
>
> I didn't do it that way for v11 because of "minus infinity" items on
> internal pages, which don't store the original key (the key remains
> the high key of the left sibling page, but we truncate the original to
> 0 attributes in _bt_pgaddtup()). I think that we should eventually
> stop truncating minus infinity items, and actually store a "low key"
> at P_FIRSTDATAKEY() within internal pages instead. That would be
> useful for other things anyway (e.g. prefix compression).

Yes, we can do more checks with bloom filter.  But assuming that we
anyway iterate over children for each non-leaf page, can we do:
1) All the checks, which bt_downlink_check() does for now
2) Check there are no missing downlinks
3) Check hikeys
in one pass, can't we?

--
Alexander Korotkov
Postgres Professional: http://www.postgrespro.com
The Russian Postgres Company




Re: Improve search for missing parent downlinks in amcheck

2019-04-27 Thread Peter Geoghegan
On Sat, Apr 27, 2019 at 4:57 PM Alexander Korotkov
 wrote:
> "rootdescend" is cool type of check.  Thank you for noticing, I wasn't aware 
> of it.
> But can it detect the missing downlink in following situation?
>
> A
>  / \
>   B <-> C <-> D
>
> Here A has downlinks to B and D, which downlink to C is missing,
> while B, C and D are correctly connected with leftlinks and rightlinks.
> I can see "rootdescend" calls _bt_search(), which would just step
> right from C to D as if it was concurrent split.

There is a comment about this scenario above bt_rootdescend() in amcheck.

You're right -- this is a kind of corruption that even the new
rootdescend verification option would miss. We can imagine a version
of rootdescend verification that tells the core code to only move
right when there was an *interrupted* page split (i.e.
P_INCOMPLETE_SPLIT() flag bit is set), but that isn't what happens
right now.

That said, the lossy downlink check that you want to improve on
*should* already catch this situation. Of course it might not because
it is lossy (uses a Bloom filter), but I think that that's very
unlikely. That's why I would like to understand the problem that you
found with the check.

-- 
Peter Geoghegan




Re: Improve search for missing parent downlinks in amcheck

2019-04-27 Thread Alexander Korotkov
On Tue, Apr 16, 2019 at 10:04 PM Peter Geoghegan  wrote:
>
> On Tue, Apr 16, 2019 at 12:00 PM Peter Geoghegan  wrote:
> > Can you be more specific? What was the cause of the corruption? I'm
> > always very interested in hearing about cases that amcheck could have
> > detected, but didn't.
>
> FWIW, v4 indexes in Postgres 12 will support the new "rootdescend"
> verification option, which isn't lossy, and would certainly have
> detected your customer issue in practice. Admittedly the new check is
> quite expensive, even compared to the other bt_index_parent_check()
> checks, but it is nice that we now have a verification option that is
> *extremely* thorough, and uses _bt_search() directly.

"rootdescend" is cool type of check.  Thank you for noticing, I wasn't
aware of it.
But can it detect the missing downlink in following situation?

A
 / \
  B <-> C <-> D

Here A has downlinks to B and D, which downlink to C is missing,
while B, C and D are correctly connected with leftlinks and rightlinks.
I can see "rootdescend" calls _bt_search(), which would just step
right from C to D as if it was concurrent split.

--
Alexander Korotkov
Postgres Professional: http://www.postgrespro.com
The Russian Postgres Company


Re: speeding up planning with partitions

2019-04-27 Thread Tom Lane
Amit Langote  writes:
> On 2019/04/23 7:08, Tom Lane wrote:
>> [ a bunch of stuff ]

> Not sure if you'll like it but maybe we could ignore even regular
> inheritance child targets that are proven to be empty (is_dummy_rel()) for
> a given query during the initial SELECT planning.  That way, we can avoid
> re-running relation_excluded_by_constraints() a second time for *all*
> child target relations.

My thought was to keep traditional inheritance working more or less
as it has.  To do what you're suggesting, we'd have to move generic
constraint-exclusion logic up into the RTE expansion phase, and I don't
think that's a particularly great idea.  I think what we should be
doing is applying partition pruning (which is a very specialized form
of constraint exclusion) during RTE expansion, then applying generic
constraint exclusion in relation_excluded_by_constraints, and not
examining partition constraints again there if we already used them.

> Do you want me to update my patch considering the above summary?

Yes please.  However, I wonder whether you're thinking differently in
light of what you wrote in [1]:

>>> Pruning in 10.2 works using internally generated partition constraints
>>> (which for this purpose are same as CHECK constraints).  With the new
>>> pruning logic introduced in 11, planner no longer considers partition
>>> constraint because it's redundant to check them in most cases, because
>>> pruning would've selected the right set of partitions.  Given that the new
>>> pruning logic is still unable to handle the cases like above, maybe we
>>> could change the planner to consider them, at least until we fix the
>>> pruning logic to handle such cases.

If we take that seriously then it would suggest not ignoring partition
constraints in relation_excluded_by_constraints.  However, I'm of the
opinion that we shouldn't let temporary deficiencies in the
partition-pruning logic drive what we do here.  I don't think the set
of cases where we could get a win by reconsidering the partition
constraints is large enough to justify the cycles expended in doing so;
and it'll get even smaller as pruning gets smarter.

regards, tom lane

[1] 
https://www.postgresql.org/message-id/358cd54d-c018-60f8-7d76-55780eef6...@lab.ntt.co.jp




pg_ssl

2019-04-27 Thread Steve
As you might know, generating SSL certificates for postgres (to be used 
by pgadmin, for example...) can be quite a bear; especially if you need 
more than one, since they are based on the username of the postgres user.


I have made two command-line utilities written in python 3.6 to do just 
that (I, as a number of other developers do, appreciate python for its 
ease of code inspection...); one is called *pg_ssl_server*, and the 
other is called *pg_ssl_client*. Packaged together, they are referred to 
by the name "*pg_ssl*". They are issued under the postgres license.


They have been tested out on Ubuntu 18 and python 3.6.7 with postgres 
11. They were designed to be cross-platform, but they have not been 
tested yet on Windows, OSx, BSD, or distros other than Ubuntu. [My 
immediate concern is with their ability to run cross-platform; as for 
downlevel versions of postgres or python, that is not a priority right 
now. The "subprocess" module in python used by the utilities has 
inconsistencies working cross-platform in older versions of python; _for 
now_, people should just upgrade if they really need to use them...]


If anyone would be interested in testing these and sending back a notice 
as to what problems were encountered on their platform, it would be much 
appreciated. The availability of these utilities will remove a rather 
rough spot from the administration of postgres. To keep noise on this 
mail thread to a minimum, please report any problems encountered 
directly to my address.


Also, if anyone is a security fanatic and facile with python, a code 
review would not be a bad idea (the two utilities check in at ~1,500 
lines; but since it's python, it's an easy read...)


The latest version of the utility can be retrieved here: 
https://osfda.org/downloads/pg_ssl.zip


You can also use the Contact Form at osfda.org to report issues.




Re: nRe: [PATCH v1] Show whether tables are logged in \dt+

2019-04-27 Thread Fabien COELHO


Hello David,

Patch applies. There seems to be a compilation issue:

 describe.c:5974:1: error: expected declaration or statement at end of
 input
  }

Also there is an added indentation problem: the size & description stuff 
have been moved left but it should still in the verbose case, and a } is 
missing after them, which fixes the compilation.



Make check fails because of my temp schema was numbered 4 instead of 3, and
I'm "fabien" rather than "shackle".


I think the way forward is to test this with TAP rather than the
fixed-string method.


Ok.


Checks removed while I figure out a new TAP test.



I only have packages down to pg 9.3, so I could not test prior 9.1.
By looking at the online documentation, is seems that relistemp
appears in pg 8.4, so the corresponding extraction should be guarded
by this version.  Before that, temporary objects existed but were
identified indirectly, possibly because they were stored in a
temporary schema. I suggest not to try to address cases prior 8.4.


Done.


After some checking, I think that there is an issue with the version 
numbers:

 - 9.1 is 90100, not 91000
 - 8.4 is 80400, not 84000

Also, it seems that describes builds queries with uppercase keywords, so 
probably the new additions should follow that style: case -> CASE (and 
also when then else end as…)


--
Fabien.

Re: [PATCH v1] Add \echo_stderr to psql

2019-04-27 Thread Fabien COELHO



Hello David,

About v3. Applies, compiles, global & local make check are ok. doc gen ok.


I'd put the commands in alphabetical order (echo, qecho, warn) instead of
e/w/q in the condition.


Done.


Cannot see it:

  + else if (strcmp(cmd, "echo") == 0 || strcmp(cmd, "warn") == 0 || strcmp(cmd, 
"qecho") == 0)


The -n trick does not appear in the help lines, ISTM that it could fit, so
maybe it could be added, possibly something like:

 \echo [-n] [TEXT]  write string to stdout, possibly without trailing newline

and same for \warn and \qecho?


Makes sense, but I put it there just for \echo to keep lines short.


I think that putting together the 3 echo variants help makes sense, but 
maybe someone will object about breaking the abc order.



How might we test this portably?


Hmmm... TAP tests are expected to be portable. Attached a simple POC, which
could be extended to test many more things which are currently out of
coverage (src/bin/psql stuff is covered around 40% only).


Thanks for putting this together. I've added this test, and agree that
increasing coverage is important for another patch.


Yep.

--
Fabien.




Re: Failure in contrib test _int on loach

2019-04-27 Thread Tom Lane
Anastasia Lubennikova  writes:
> So it is possible, but it doesn't require any extra algorithm changes.
> I didn't manage to generate dataset to reproduce grandparent split.
> Though, I do agree that it's worth checking out. Do you have any ideas?

Ping?  This thread has gone cold, but the bug is still there, and
IMV it's a beta blocker.

regards, tom lane




Re: nRe: [PATCH v1] Show whether tables are logged in \dt+

2019-04-27 Thread David Fetter
On Sat, Apr 27, 2019 at 09:19:57AM +0200, Fabien COELHO wrote:
> 
> Hello David,
> 
> Patch v3 applies, but compiles for me with a warning because the indentation
> of the following size block has been changed:
> 
> describe.c: In function ‘listTables’:
> describe.c:3705:7: warning: this ‘if’ clause does not guard...
> [-Wmisleading-indentation]
>   else if (pset.sversion >= 80100)
>^~
> describe.c:3710:3: note: ...this statement, but the latter is misleadingly
> indented as if it were guarded by the ‘if’
>appendPQExpBuffer(,
>^

Fixed.

> Make check fails because of my temp schema was numbered 4 instead of 3, and
> I'm "fabien" rather than "shackle".

I think the way forward is to test this with TAP rather than the
fixed-string method.

> > > > > > Included, but they're not stable for temp tables. I'm a little 
> > > > > > stumped
> > > > > > as to how to either stabilize them or test some other way.
> > > > > 
> > > > > Hmmm. First there is the username which appears, so there should be a
> > > > > dedicated user for the test.
> > > > > 
> > > > > I'm unsure how to work around the temporary schema number, which is
> > > > > undeterministic with parallel execution it. I'm afraid the only viable
> > > > > approach is not to show temporary tables, too bad:-(
> 
> The tests have not been fixed.
> 
> I think that they need a dedicated user to replace "shackle", and I'm afraid
> that there temporary test schema instability cannot be easily fixed at the
> "psql" level, but would require some kind of TAP tests instead if it is to
> be checked. In the short term, do not.

Checks removed while I figure out a new TAP test.

> I checked that the \di+ works, though. I've played with temporary views and
> \dv as well.

Great!

> I discovered that you cannot have temporary unlogged objects, nor
> temporary or unlogged materialized views. Intuitively I'd have
> thought that these features would be orthogonal, but they are not.

This seems like material for a different patch.

> Also I created an unlogged table with a SERIAL which created a
> sequence. The table is unlogged but the sequence is permanent, which
> is probably ok.

> I only have packages down to pg 9.3, so I could not test prior 9.1.
> By looking at the online documentation, is seems that relistemp
> appears in pg 8.4, so the corresponding extraction should be guarded
> by this version.  Before that, temporary objects existed but were
> identified indirectly, possibly because they were stored in a
> temporary schema. I suggest not to try to address cases prior 8.4.

Done.

Best,
David.
-- 
David Fetter  http://fetter.org/
Phone: +1 415 235 3778

Remember to vote!
Consider donating to Postgres: http://www.postgresql.org/about/donate
>From fd0b8215ca6bbdebc0924efaba95944731890dc9 Mon Sep 17 00:00:00 2001
From: David Fetter 
Date: Mon, 22 Apr 2019 17:50:48 -0700
Subject: [PATCH v4] Show detailed table persistence in \dt+
To: hackers
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="2.20.1"

This is a multi-part message in MIME format.
--2.20.1
Content-Type: text/plain; charset=UTF-8; format=fixed
Content-Transfer-Encoding: 8bit


\d would show this for individual tables, but there wasn't an
overarching view of all tables. Now, there is.

diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c
index ee00c5da08..4aa06a417c 100644
--- a/src/bin/psql/describe.c
+++ b/src/bin/psql/describe.c
@@ -3631,7 +3631,7 @@ listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSys
 	PQExpBufferData buf;
 	PGresult   *res;
 	printQueryOpt myopt = pset.popt;
-	static const bool translate_columns[] = {false, false, true, false, false, false, false};
+	static const bool translate_columns[] = {false, false, true, false, false, false, false, false};
 
 	/* If tabtypes is empty, we default to \dtvmsE (but see also command.c) */
 	if (!(showTables || showIndexes || showViews || showMatViews || showSeq || showForeign))
@@ -3680,22 +3680,36 @@ listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSys
 	if (verbose)
 	{
 		/*
-		 * As of PostgreSQL 9.0, use pg_table_size() to show a more accurate
-		 * size of a table, including FSM, VM and TOAST tables.
+		 * Show whether a table is permanent, temporary, or unlogged.
+		 * Indexes are not, as of this writing, tables.
 		 */
-		if (pset.sversion >= 9)
-			appendPQExpBuffer(,
-			  ",\n  pg_catalog.pg_size_pretty(pg_catalog.pg_table_size(c.oid)) as \"%s\"",
-			  gettext_noop("Size"));
-		else if (pset.sversion >= 80100)
-			appendPQExpBuffer(,
-			  ",\n  pg_catalog.pg_size_pretty(pg_catalog.pg_relation_size(c.oid)) as \"%s\"",
-			  gettext_noop("Size"));
+		if (!showIndexes)
+		{
+			if (pset.sversion >= 91000)
+appendPQExpBuffer(,
+  ",\n  CASE c.relpersistence WHEN 'p' THEN 'permanent' WHEN 't' THEN 'temporary' WHEN 'u' THEN 'unlogged' ELSE 'unknown' END as \"%s\"",
+  

Re: [PATCH v1] Add \echo_stderr to psql

2019-04-27 Thread David Fetter
On Sat, Apr 27, 2019 at 04:05:20PM +0200, Fabien COELHO wrote:
> 
> Hello David,
> 
> > Please find attached v2, name is now \warn.
> 
> Patch applies cleanly, compiles, "make check ok", although there are no
> tests. Doc gen ok.
> 
> Code is pretty straightforward.
> 
> I'd put the commands in alphabetical order (echo, qecho, warn) instead of
> e/w/q in the condition.

Done.

> The -n trick does not appear in the help lines, ISTM that it could fit, so
> maybe it could be added, possibly something like:
> 
>  \echo [-n] [TEXT]  write string to stdout, possibly without trailing newline
> 
> and same for \warn and \qecho?

Makes sense, but I put it there just for \echo to keep lines short.

> > How might we test this portably?
> 
> Hmmm... TAP tests are expected to be portable. Attached a simple POC, which
> could be extended to test many more things which are currently out of
> coverage (src/bin/psql stuff is covered around 40% only).

Thanks for putting this together. I've added this test, and agree that
increasing coverage is important for another patch.

Best,
David.
-- 
David Fetter  http://fetter.org/
Phone: +1 415 235 3778

Remember to vote!
Consider donating to Postgres: http://www.postgresql.org/about/donate
>From 2f7cbf9980c5ce1049728a0e2a3444cbd106f253 Mon Sep 17 00:00:00 2001
From: David Fetter 
Date: Sun, 21 Apr 2019 11:08:40 -0700
Subject: [PATCH v3] Add \warn to psql
To: hackers
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="2.20.1"

This is a multi-part message in MIME format.
--2.20.1
Content-Type: text/plain; charset=UTF-8; format=fixed
Content-Transfer-Encoding: 8bit


- Does what it says on the label
- Adds TAP tests for same
- In passing, expose the -n option for \echo, \qecho, and \warn in \? output

 create mode 100644 src/bin/psql/t/001_psql.pl


--2.20.1
Content-Type: text/x-patch; name="v3-0001-Add-warn-to-psql.patch"
Content-Transfer-Encoding: 8bit
Content-Disposition: attachment; filename="v3-0001-Add-warn-to-psql.patch"

diff --git a/doc/src/sgml/ref/psql-ref.sgml b/doc/src/sgml/ref/psql-ref.sgml
index b86764003d..4edf8e67a1 100644
--- a/doc/src/sgml/ref/psql-ref.sgml
+++ b/doc/src/sgml/ref/psql-ref.sgml
@@ -1879,6 +1879,26 @@ Tue Oct 26 21:40:57 CEST 1999
 
   
 
+  
+\warn text [ ... ]
+
+
+Prints the arguments to the standard error, separated by one
+space and followed by a newline. This can be useful to
+intersperse information in the output of scripts when not polluting
+standard output is desired. For example:
+
+
+= \echo :variable
+= \warn `date`
+Sun Apr 21 10:48:11 PDT 2019
+
+If the first argument is an unquoted -n the trailing
+newline is not written.
+
+
+  
+
   
 \ef  function_description   line_number   
 
diff --git a/src/bin/psql/.gitignore b/src/bin/psql/.gitignore
index c2862b12d6..d324c1c1fa 100644
--- a/src/bin/psql/.gitignore
+++ b/src/bin/psql/.gitignore
@@ -3,3 +3,4 @@
 /sql_help.c
 
 /psql
+/tmp_check
diff --git a/src/bin/psql/Makefile b/src/bin/psql/Makefile
index 69bb297fe7..9473ab01cb 100644
--- a/src/bin/psql/Makefile
+++ b/src/bin/psql/Makefile
@@ -60,8 +60,15 @@ uninstall:
 
 clean distclean:
 	rm -f psql$(X) $(OBJS) lex.backup
+	rm -rf tmp_check
 
 # files removed here are supposed to be in the distribution tarball,
 # so do not clean them in the clean/distclean rules
 maintainer-clean: distclean
 	rm -f sql_help.h sql_help.c psqlscanslash.c
+
+check:
+	$(prove_check)
+
+installcheck:
+	$(prove_installcheck)
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c
index 8254d61099..9425f02005 100644
--- a/src/bin/psql/command.c
+++ b/src/bin/psql/command.c
@@ -319,7 +319,7 @@ exec_command(const char *cmd,
 		status = exec_command_ef_ev(scan_state, active_branch, query_buf, true);
 	else if (strcmp(cmd, "ev") == 0)
 		status = exec_command_ef_ev(scan_state, active_branch, query_buf, false);
-	else if (strcmp(cmd, "echo") == 0 || strcmp(cmd, "qecho") == 0)
+	else if (strcmp(cmd, "echo") == 0 || strcmp(cmd, "warn") == 0 || strcmp(cmd, "qecho") == 0)
 		status = exec_command_echo(scan_state, active_branch, cmd);
 	else if (strcmp(cmd, "elif") == 0)
 		status = exec_command_elif(scan_state, cstack, query_buf);
@@ -1114,7 +1114,7 @@ exec_command_ef_ev(PsqlScanState scan_state, bool active_branch,
 }
 
 /*
- * \echo and \qecho -- echo arguments to stdout or query output
+ * \echo, \warn and \qecho -- echo arguments to stdout or query output
  */
 static backslashResult
 exec_command_echo(PsqlScanState scan_state, bool active_branch, const char *cmd)
@@ -1129,6 +1129,8 @@ exec_command_echo(PsqlScanState scan_state, bool active_branch, const char *cmd)
 
 		if (strcmp(cmd, "qecho") == 0)
 			fout = pset.queryFout;
+		else if (strcmp(cmd, "warn") == 0)
+			fout = stderr;
 		else
 			fout = stdout;
 
diff --git a/src/bin/psql/help.c b/src/bin/psql/help.c
index d6d41b51d5..434388608a 

Re: generate documentation keywords table automatically

2019-04-27 Thread Tom Lane
Peter Eisentraut  writes:
> The SQL keywords table in the documentation had until now been generated
> by me every year by some ad hoc scripting outside the source tree once
> for each major release.  This patch changes it to an automated process.

Didn't test this, but +1 for the concept.

Would it make more sense to have just one source file per SQL standard
version, and distinguish the keyword types by labels within the file?
The extreme version of that would be to format the standards-info files
just like parser/kwlist.h, which perhaps would even save a bit of
parsing code in the Perl script.  I don't insist you have to go that
far, but lists of keywords-and-categories seem to make sense.

The thing in the back of my mind here is that at some point the SQL
standard might have more than two keyword categories.  What you've got
here would take some effort to handle that, whereas it'd be an entirely
trivial data change in the scheme I'm thinking of.

A policy issue, independent of this mechanism, is how many different
SQL spec versions we want to show in the table.  HEAD currently shows just
three (2011, 2008, SQL92), and it doesn't look to me like the table can
accommodate more than one or at most two more columns without getting
too wide for most output formats.  We could buy back some space by making
the "cannot be X" annotations for PG keywords more compact, but I fear
that'd still not be enough for the seven spec versions you propose to
show in this patch.  (And, presumably, the committee's not done.)
Can we pick a different table layout?

regards, tom lane




Re: clean up docs for v12

2019-04-27 Thread Tom Lane
Michael Paquier  writes:
> On Fri, Apr 26, 2019 at 09:56:47PM -0500, Justin Pryzby wrote:
>> -all autovacuum actions. Minus-one (the default) disables logging
>> +all autovacuum actions. -1 (the default) 
>> disables logging
>> 
>> There's nothing else that says "minus-one" anywhere else on that page.  I 
>> just
>> found one in auto-explain.sgml, which I changed.

> That's one of these I am not sure about.

FWIW, I think we generally write this the way Justin suggests.  It's
more precise, at least if you're reading it in a way that makes
 text distinguishable from plain text: what to put into
the config file is exactly "-1", and not for instance "minus-one".

regards, tom lane




Re: BUG #15781: subselect on foreign table (postgres_fdw) can crash (segfault)

2019-04-27 Thread Tom Lane
Etsuro Fujita  writes:
> On Sat, Apr 27, 2019 at 2:10 AM Tom Lane  wrote:
>> If we don't want to change what the core code does with fdw_exprs,
>> I think the only way to fix it is to hack postgres_fdw so that it
>> won't generate plans involving the problematic case.

> Seems reasonable.

>> See attached.

> I read the patch.  It looks good to me.  I didn't test it, though.

Thanks for looking!  Have a good vacation ...

regards, tom lane




Re: [PATCH v1] Add \echo_stderr to psql

2019-04-27 Thread Fabien COELHO


Hello David,


Please find attached v2, name is now \warn.


Patch applies cleanly, compiles, "make check ok", although there are no 
tests. Doc gen ok.


Code is pretty straightforward.

I'd put the commands in alphabetical order (echo, qecho, warn) instead of 
e/w/q in the condition.


The -n trick does not appear in the help lines, ISTM that it could fit, so 
maybe it could be added, possibly something like:


 \echo [-n] [TEXT]  write string to stdout, possibly without trailing newline

and same for \warn and \qecho?


How might we test this portably?


Hmmm... TAP tests are expected to be portable. Attached a simple POC, 
which could be extended to test many more things which are currently out 
of coverage (src/bin/psql stuff is covered around 40% only).


--
Fabien.diff --git a/src/bin/psql/.gitignore b/src/bin/psql/.gitignore
index c2862b12d6..d324c1c1fa 100644
--- a/src/bin/psql/.gitignore
+++ b/src/bin/psql/.gitignore
@@ -3,3 +3,4 @@
 /sql_help.c
 
 /psql
+/tmp_check
diff --git a/src/bin/psql/Makefile b/src/bin/psql/Makefile
index 69bb297fe7..9473ab01cb 100644
--- a/src/bin/psql/Makefile
+++ b/src/bin/psql/Makefile
@@ -60,8 +60,15 @@ uninstall:
 
 clean distclean:
 	rm -f psql$(X) $(OBJS) lex.backup
+	rm -rf tmp_check
 
 # files removed here are supposed to be in the distribution tarball,
 # so do not clean them in the clean/distclean rules
 maintainer-clean: distclean
 	rm -f sql_help.h sql_help.c psqlscanslash.c
+
+check:
+	$(prove_check)
+
+installcheck:
+	$(prove_installcheck)
diff --git a/src/bin/psql/t/001_psql.pl b/src/bin/psql/t/001_psql.pl
new file mode 100644
index 00..32dd43279b
--- /dev/null
+++ b/src/bin/psql/t/001_psql.pl
@@ -0,0 +1,32 @@
+use strict;
+use warnings;
+
+use PostgresNode;
+use TestLib;
+use Test::More;
+
+my $node = get_new_node('main');
+$node->init();
+$node->start();
+
+# invoke psql
+# - opts: space-separated options and arguments
+# - stat: expected exit status
+# - in: input stream
+# - out: list of re to check on stdout
+# - err: list of re to check on stderr
+# - name: of the test
+sub psql
+{
+	local $Test::Builder::Level = $Test::Builder::Level + 1;
+	my ($opts, $stat, $in, $out, $err, $name) = @_;
+	my @cmd = ('psql', split /\s+/, $opts);
+	$node->command_checks_all(\@cmd, $stat, $out, $err, $name, $in);
+	return;
+}
+
+psql('-c \\q', 0, '', [ qr{^$} ], [ qr{^$} ], 'psql -c');
+psql('', 0,"\\echo hello\n\\warn world\n\\q\n", [ qr{^hello$} ], [ qr{^world$} ], 'psql in/out/err');
+
+$node->stop();
+done_testing();
diff --git a/src/test/perl/TestLib.pm b/src/test/perl/TestLib.pm
index a164cdbd8c..6ad7f681ae 100644
--- a/src/test/perl/TestLib.pm
+++ b/src/test/perl/TestLib.pm
@@ -519,22 +519,24 @@ sub command_fails_like
 }
 
 # Run a command and check its status and outputs.
-# The 5 arguments are:
+# The 5 to 6 arguments are:
 # - cmd: ref to list for command, options and arguments to run
 # - ret: expected exit status
 # - out: ref to list of re to be checked against stdout (all must match)
 # - err: ref to list of re to be checked against stderr (all must match)
 # - test_name: name of test
+# - in: standard input
 sub command_checks_all
 {
 	local $Test::Builder::Level = $Test::Builder::Level + 1;
 
-	my ($cmd, $expected_ret, $out, $err, $test_name) = @_;
+	my ($cmd, $expected_ret, $out, $err, $test_name, $in) = @_;
+	$in = '' if not defined $in;
 
 	# run command
 	my ($stdout, $stderr);
 	print("# Running: " . join(" ", @{$cmd}) . "\n");
-	IPC::Run::run($cmd, '>', \$stdout, '2>', \$stderr);
+	IPC::Run::run($cmd, '<', \$in, '>', \$stdout, '2>', \$stderr);
 
 	# See http://perldoc.perl.org/perlvar.html#%24CHILD_ERROR
 	my $ret = $?;


Re: BUG #15781: subselect on foreign table (postgres_fdw) can crash (segfault)

2019-04-27 Thread Etsuro Fujita
On Sat, Apr 27, 2019 at 2:10 AM Tom Lane  wrote:

> > (2019/04/26 3:24), Tom Lane wrote:
> >> If we do leave it like this, then the only way for postgres_fdw to
> >> avoid trouble is to not have any entries in fdw_exprs that exactly
> >> match entries in fdw_scan_tlist.  So that pretty much devolves back
> >> to what I said before: don't ship values to the far end that are
> >> just going to be fed back as-is.  But now it's a correctness
> >> requirement not just an optimization.

> Well, the releases are coming up fast, so I spent some time on this.
> If we don't want to change what the core code does with fdw_exprs,
> I think the only way to fix it is to hack postgres_fdw so that it
> won't generate plans involving the problematic case.

Seems reasonable.

> See attached.

I read the patch.  It looks good to me.  I didn't test it, though.

> We end up with slightly weird-looking plans if the troublesome Param
> is actually a GROUP BY expression, but if it's not, I think things
> are fine.  Maybe we could do something smarter about the GROUP BY case,
> but it seems weird enough to maybe not be worth additional trouble.

Agreed.

Thanks for working on this!

Best regards,
Etsuro Fujita




Re: Identity columns should own only one sequence

2019-04-27 Thread Peter Eisentraut
On 2019-04-26 15:37, Laurenz Albe wrote:
> What do you think of the patch I just posted on this thread to
> remove ownership automatically when the default is dropped, as Michael
> suggested?  I think that would make things much more intuitive from
> the user's perspective.

I think that adds more nonstandard behavior on top of an already
confusing and obsolescent feature, so I can't get too excited about it.

A more forward-looking fix would be your other idea of having
getOwnedSequence() only deal with identity sequences (not serial
sequences).  See attached patch for a draft.

-- 
Peter Eisentraut  http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
From b0a9c3402847f846d6d133cb9eced56ea9634a30 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut 
Date: Sat, 27 Apr 2019 14:12:03 +0200
Subject: [PATCH] Untangle some stuff about identity sequences

XXX draft XXX
---
 src/backend/catalog/pg_depend.c  | 26 +++---
 src/backend/commands/tablecmds.c |  2 +-
 src/backend/parser/parse_utilcmd.c   | 12 +---
 src/backend/rewrite/rewriteHandler.c |  2 +-
 src/include/catalog/dependency.h |  2 +-
 5 files changed, 27 insertions(+), 17 deletions(-)

diff --git a/src/backend/catalog/pg_depend.c b/src/backend/catalog/pg_depend.c
index f7caedcc02..63c94cfbe6 100644
--- a/src/backend/catalog/pg_depend.c
+++ b/src/backend/catalog/pg_depend.c
@@ -707,8 +707,8 @@ sequenceIsOwned(Oid seqId, char deptype, Oid *tableId, 
int32 *colId)
  * Collect a list of OIDs of all sequences owned by the specified relation,
  * and column if specified.
  */
-List *
-getOwnedSequences(Oid relid, AttrNumber attnum)
+static List *
+getOwnedSequences_internal(Oid relid, AttrNumber attnum, char deptype)
 {
List   *result = NIL;
RelationdepRel;
@@ -750,7 +750,8 @@ getOwnedSequences(Oid relid, AttrNumber attnum)
(deprec->deptype == DEPENDENCY_AUTO || deprec->deptype 
== DEPENDENCY_INTERNAL) &&
get_rel_relkind(deprec->objid) == RELKIND_SEQUENCE)
{
-   result = lappend_oid(result, deprec->objid);
+   if (!deptype || deprec->deptype == deptype)
+   result = lappend_oid(result, deprec->objid);
}
}
 
@@ -761,18 +762,29 @@ getOwnedSequences(Oid relid, AttrNumber attnum)
return result;
 }
 
+List *
+getOwnedSequences(Oid relid, AttrNumber attnum)
+{
+   return getOwnedSequences_internal(relid, attnum, 0);
+}
+
 /*
- * Get owned sequence, error if not exactly one.
+ * Get owned identity sequence, error if not exactly one.
  */
 Oid
-getOwnedSequence(Oid relid, AttrNumber attnum)
+getIdentitySequence(Oid relid, AttrNumber attnum, bool missing_ok)
 {
-   List   *seqlist = getOwnedSequences(relid, attnum);
+   List   *seqlist = getOwnedSequences_internal(relid, attnum, 
DEPENDENCY_INTERNAL);
 
if (list_length(seqlist) > 1)
elog(ERROR, "more than one owned sequence found");
else if (list_length(seqlist) < 1)
-   elog(ERROR, "no owned sequence found");
+   {
+   if (missing_ok)
+   return InvalidOid;
+   else
+   elog(ERROR, "no owned sequence found");
+   }
 
return linitial_oid(seqlist);
 }
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 14fcad9034..53dc72f7d6 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -6607,7 +6607,7 @@ ATExecDropIdentity(Relation rel, const char *colName, 
bool missing_ok, LOCKMODE
table_close(attrelation, RowExclusiveLock);
 
/* drop the internal sequence */
-   seqid = getOwnedSequence(RelationGetRelid(rel), attnum);
+   seqid = getIdentitySequence(RelationGetRelid(rel), attnum, false);
deleteDependencyRecordsForClass(RelationRelationId, seqid,

RelationRelationId, DEPENDENCY_INTERNAL);
CommandCounterIncrement();
diff --git a/src/backend/parser/parse_utilcmd.c 
b/src/backend/parser/parse_utilcmd.c
index 4564c0ae81..a3c5b005d5 100644
--- a/src/backend/parser/parse_utilcmd.c
+++ b/src/backend/parser/parse_utilcmd.c
@@ -1083,7 +1083,7 @@ transformTableLikeClause(CreateStmtContext *cxt, 
TableLikeClause *table_like_cla
 * find sequence owned by old column; extract sequence 
parameters;
 * build new create sequence command
 */
-   seq_relid = 
getOwnedSequence(RelationGetRelid(relation), attribute->attnum);
+   seq_relid = 
getIdentitySequence(RelationGetRelid(relation), attribute->attnum, false);
seq_options = sequence_options(seq_relid);
generateSerialExtraStmts(cxt, 

Re: Optimizer items in the release notes

2019-04-27 Thread Bruce Momjian
On Sat, Apr 27, 2019 at 02:47:44PM +1200, David Rowley wrote:
> On Sat, 27 Apr 2019 at 14:22, Bruce Momjian  wrote:
> > > > *  They are hard to explain
> > >
> > > That can be true, but we generally get there if not the first time
> > > then after a few iterations. Authors and committers of the
> > > improvements are likely to be able to help find suitable wording.
> >
> > It is not the text that is hard, but hard to explain the concept in a
> > way that relates to anything a normal user is familiar with.
> 
> Yeah, that's no doubt often going to be a struggle, but we can't
> expect every person who reads the release notes to understand
> everything. You could probably say the same for any internal
> implementation change we make though. I don't think the planner is
> unique in this regard, so I don't think it needs any special

I do believe the planner is unique in this regard in the sense that the
changes can make 100x difference in performance, and it is often unclear
from the user interface exactly what is happening.

> treatment. I also don't think we need to go into great detail. The
> item could be as light on detail as:
> 
> * Improve query planner's ability to push LIMIT through Sort nodes.
> 
> If you don't know what LIMIT is or what a Sort node is, then you're
> probably not going to care about the change. They can keep reading on
> the next line, but if the reader happens to have suffered some pain on
> that during their migration attempt, then they might be quite happy to
> see those words. If they want more details then they might be savvy
> enough to hunt those down, or perhaps they'll come asking.

Uh, that is not clear to me so I am not sure the average user would know
about it.  I would probably try to explain that one in a way that can be
understood, like LIMIT in subqueries affecting the outer query sort
performance.

-- 
  Bruce Momjian  http://momjian.us
  EnterpriseDB http://enterprisedb.com

+ As you are, so once was I.  As I am, so you will be. +
+  Ancient Roman grave inscription +




nRe: [PATCH v1] Show whether tables are logged in \dt+

2019-04-27 Thread Fabien COELHO


Hello David,

Patch v3 applies, but compiles for me with a warning because the 
indentation of the following size block has been changed:


describe.c: In function ‘listTables’:
describe.c:3705:7: warning: this ‘if’ clause does not guard... 
[-Wmisleading-indentation]

  else if (pset.sversion >= 80100)
   ^~
describe.c:3710:3: note: ...this statement, but the latter is misleadingly 
indented as if it were guarded by the ‘if’

   appendPQExpBuffer(,
   ^

Make check fails because of my temp schema was numbered 4 instead of 3, 
and I'm "fabien" rather than "shackle".



Included, but they're not stable for temp tables. I'm a little stumped
as to how to either stabilize them or test some other way.


Hmmm. First there is the username which appears, so there should be a
dedicated user for the test.

I'm unsure how to work around the temporary schema number, which is
undeterministic with parallel execution it. I'm afraid the only viable
approach is not to show temporary tables, too bad:-(


The tests have not been fixed.

I think that they need a dedicated user to replace "shackle", and I'm 
afraid that there temporary test schema instability cannot be easily fixed 
at the "psql" level, but would require some kind of TAP tests instead if 
it is to be checked. In the short term, do not.


I checked that the \di+ works, though. I've played with temporary views 
and \dv as well.


I discovered that you cannot have temporary unlogged objects, nor 
temporary or unlogged materialized views. Intuitively I'd have thought 
that these features would be orthogonal, but they are not. Also I created 
an unlogged table with a SERIAL which created a sequence. The table is 
unlogged but the sequence is permanent, which is probably ok.


I only have packages down to pg 9.3, so I could not test prior 9.1. By 
looking at the online documentation, is seems that relistemp appears in pg 
8.4, so the corresponding extraction should be guarded by this version. 
Before that, temporary objects existed but were identified indirectly, 
possibly because they were stored in a temporary schema. I suggest not to 
try to address cases prior 8.4.


--
Fabien.