Re: Allow CLUSTER, VACUUM FULL and REINDEX to change tablespace on the fly
On 2020-12-11 21:27, Alvaro Herrera wrote:
By the way-- What did you think of the idea of explictly marking the
types used for bitmasks using types bits32 and friends, instead of plain
int, which is harder to spot?
If we want to make it clearer, why not turn the thing into a struct, as
in the attached patch, and avoid the bit fiddling altogether.
From d3125b3bfb8a3dc23e38f38bcf850ca6fc36f492 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut
Date: Sat, 12 Dec 2020 09:17:55 +0100
Subject: [PATCH] Convert reindex options to struct
---
src/backend/catalog/index.c | 19 ---
src/backend/commands/cluster.c | 2 +-
src/backend/commands/indexcmds.c | 94
src/backend/commands/tablecmds.c | 2 +-
src/backend/tcop/utility.c | 4 +-
src/include/catalog/index.h | 16 +++---
src/include/commands/defrem.h| 9 +--
7 files changed, 74 insertions(+), 72 deletions(-)
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 731610c701..06342fddf1 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3594,7 +3594,7 @@ IndexGetRelation(Oid indexId, bool missing_ok)
*/
void
reindex_index(Oid indexId, bool skip_constraint_checks, char persistence,
- int options)
+ ReindexOptions options)
{
RelationiRel,
heapRelation;
@@ -3602,7 +3602,7 @@ reindex_index(Oid indexId, bool skip_constraint_checks,
char persistence,
IndexInfo *indexInfo;
volatile bool skipped_constraint = false;
PGRUsageru0;
- boolprogress = (options & REINDEXOPT_REPORT_PROGRESS) != 0;
+ boolprogress = options.REINDEXOPT_REPORT_PROGRESS;
pg_rusage_init(&ru0);
@@ -3611,12 +3611,12 @@ reindex_index(Oid indexId, bool skip_constraint_checks,
char persistence,
* we only need to be sure no schema or data changes are going on.
*/
heapId = IndexGetRelation(indexId,
- (options &
REINDEXOPT_MISSING_OK) != 0);
+
options.REINDEXOPT_MISSING_OK);
/* if relation is missing, leave */
if (!OidIsValid(heapId))
return;
- if ((options & REINDEXOPT_MISSING_OK) != 0)
+ if (options.REINDEXOPT_MISSING_OK)
heapRelation = try_table_open(heapId, ShareLock);
else
heapRelation = table_open(heapId, ShareLock);
@@ -3792,7 +3792,7 @@ reindex_index(Oid indexId, bool skip_constraint_checks,
char persistence,
}
/* Log what we did */
- if (options & REINDEXOPT_VERBOSE)
+ if (options.REINDEXOPT_VERBOSE)
ereport(INFO,
(errmsg("index \"%s\" was reindexed",
get_rel_name(indexId)),
@@ -3846,7 +3846,7 @@ reindex_index(Oid indexId, bool skip_constraint_checks,
char persistence,
* index rebuild.
*/
bool
-reindex_relation(Oid relid, int flags, int options)
+reindex_relation(Oid relid, int flags, ReindexOptions options)
{
Relationrel;
Oid toast_relid;
@@ -3861,7 +3861,7 @@ reindex_relation(Oid relid, int flags, int options)
* to prevent schema and data changes in it. The lock level used here
* should match ReindexTable().
*/
- if ((options & REINDEXOPT_MISSING_OK) != 0)
+ if (options.REINDEXOPT_MISSING_OK)
rel = try_table_open(relid, ShareLock);
else
rel = table_open(relid, ShareLock);
@@ -3965,8 +3965,9 @@ reindex_relation(Oid relid, int flags, int options)
* Note that this should fail if the toast relation is missing,
so
* reset REINDEXOPT_MISSING_OK.
*/
- result |= reindex_relation(toast_relid, flags,
- options &
~(REINDEXOPT_MISSING_OK));
+ ReindexOptions newoptions = options;
+ newoptions.REINDEXOPT_MISSING_OK = false;
+ result |= reindex_relation(toast_relid, flags, newoptions);
}
return result;
diff --git a/src/backend/commands/cluster.c b/src/backend/commands/cluster.c
index fd5a6eec86..b0aa3536d1 100644
--- a/src/backend/commands/cluster.c
+++ b/src/backend/commands/cluster.c
@@ -1412,7 +1412,7 @@ finish_heap_swap(Oid OIDOldHeap, Oid OIDNewHeap,
pgstat_progress_update_param(PROGRESS_CLUSTER_PHASE,
PROGRESS_CLUSTER_PHASE_REBUILD_INDEX);
- reindex_relation(OIDOldHeap, reindex_flags, 0);
+ reindex_relation(OIDOldHeap, reindex_flags, (ReindexOptions){});
/* Report that we are now doing clean up */
pgstat_progress_update_param(PROGRESS_CLUSTER_PHASE
Suggestion: optionally return default value instead of error on failed cast
Hi, currently a failed cast throws an error. It would be useful to have a way to get a default value instead. T-SQL has try_cast [1] Oracle has CAST(... AS .. DEFAULT ... ON CONVERSION ERROR) [2] The DEFAULT ... ON CONVERSION ERROR syntax seems like it could be implemented in PostgreSQL. Even if only DEFAULT NULL was supported (at first) that would already help. The short syntax could be extended for the DEFAULT NULL case, too: SELECT '...'::type -- throws error SELECT '...':::type -- returns NULL I couldn't find any previous discussion on this, please advise in case I just missed it. Thoughts? Best Wolfgang [1]: https://docs.microsoft.com/en-us/sql/t-sql/functions/try-cast-transact-sql [2]: https://docs.oracle.com/en/database/oracle/oracle-database/12.2/sqlrf/CAST.html
Re: Asynchronous Append on postgres_fdw nodes.
On Fri, Nov 20, 2020 at 3:51 PM Kyotaro Horiguchi wrote: > At Tue, 17 Nov 2020 18:56:02 +0900, Etsuro Fujita > wrote in > > * In Robert's patch [1] (and Horiguchi-san's, which was created based > > on Robert's), ExecAppend() was modified to retrieve tuples from > > async-aware children *before* the tuples will be needed, but I don't > > The "retrieve" means the move of a tuple from fdw to executor > (ExecAppend or ExecAsync) layer? Yes, that's what I mean. > > think that's really a good idea, because the query might complete > > before returning the tuples. So I modified that function so that a > > I'm not sure how it matters. Anyway the fdw holds up to tens of tuples > before the executor actually make requests for them. The reason for > the early fetching is letting fdw send the next request as early as > possible. (However, I didn't measure the effect of the > nodeAppend-level prefetching.) I agree that that would lead to an improved efficiency in some cases, but I still think that that would be useless in some other cases like SELECT * FROM sharded_table LIMIT 1. Also, I think the situation would get worse if we support Append on top of joins or aggregates over ForeignScans, which would be more expensive to perform than these ForeignScans. If we do prefetching, I think it would be better that it’s the responsibility of the FDW to do prefetching, and I think that that could be done by letting the FDW to start another data fetch, independently of the core, in the ForeignAsyncNotify callback routine, which I revived from Robert's original patch. I think that that would be more efficient, because the FDW would no longer need to wait until all buffered tuples are returned to the core. In the WIP patch, I only allowed the callback routine to put the corresponding ForeignScan node into a state where it’s either ready for a new request or needing a callback for another data fetch, but I think we could probably relax the restriction so that the ForeignScan node can be put into another state where it’s ready for a new request while needing a callback for the prefetch. > > tuple is retrieved from an async-aware child *when* it is needed, like > > Thomas' patch. I used FDW callback functions proposed by Robert, but > > introduced another FDW callback function ForeignAsyncBegin() for each > > async-aware child to start an asynchronous data fetch at the first > > call to ExecAppend() after ExecInitAppend() or ExecReScanAppend(). > > Even though the terminology is not officially determined, in the past > discussions "async-aware" meant "can handle async-capable subnodes" > and "async-capable" is used as "can run asynchronously". Thanks for the explanation! > Likewise you > seem to have changed the meaning of as_needrequest from "subnodes that > needs to request for the next tuple" to "subnodes that already have > got query-send request and waiting for the result to come". No. I think I might slightly change the original definition of as_needrequest, though. > I would > argue to use the words and variables (names) in such meanings. I think the word "aware" has a broader meaning, so the naming as proposed would be OK IMO. But actually, I don't have any strong opinion about that, so I'll change it as explained. > > * For EvalPlanQual, I modified the patch so that async-aware children > > are treated as if they were synchronous when executing EvalPlanQual. > > Doesn't async execution accelerate the epq-fetching? Or does > async-execution goes into trouble in the EPQ path? The reason why I disabled async execution when executing EPQ is to avoid sending asynchronous queries to the remote sides, which would be useless, because scan tuples for an EPQ recheck are obtained in a dedicated way. > > * In Robert's patch, all async-aware children below Append nodes in > > the query waiting for events to occur were managed by a single EState, > > but I modified the patch so that such children are managed by each > > Append node, like Horiguchi-san's patch and Thomas'. > > Managing in Estate give advantage for push-up style executor but > managing in node_state is simpler. What do you mean by "push-up style executor"? Thanks for the review! Sorry for the delay. Best regards, Etsuro Fujita
Re: Asynchronous Append on postgres_fdw nodes.
On Fri, Nov 20, 2020 at 8:16 PM Kyotaro Horiguchi
wrote:
> I looked through the nodeAppend.c and postgres_fdw.c part and those
> are I think the core of this patch.
Thanks again for the review!
> -* figure out which subplan we are currently processing
> +* try to get a tuple from async subplans
> +*/
> + if (!bms_is_empty(node->as_needrequest) ||
> + (node->as_syncdone &&
> !bms_is_empty(node->as_asyncpending)))
> + {
> + if (ExecAppendAsyncGetNext(node, &result))
> + return result;
>
> The function ExecAppendAsyncGetNext() is a function called only here,
> and contains only 31 lines. It doesn't seem to me that the separation
> makes the code more readable.
Considering the original ExecAppend() is about 50 lines long, 31 lines
of code would not be small. So I'd vote for separating it into
another function as proposed.
> - /* choose new subplan; if none, we're done */
> - if (!node->choose_next_subplan(node))
> + /* wait or poll async events */
> + if (!bms_is_empty(node->as_asyncpending))
> + {
> + Assert(!node->as_syncdone);
> + Assert(bms_is_empty(node->as_needrequest));
> + ExecAppendAsyncEventWait(node);
>
> You moved the function to wait for events from execAsync to
> nodeAppend. The former is a generic module that can be used from any
> kind of executor nodes, but the latter is specialized for nodeAppend.
> In other words, the abstraction level is lowered here. What is the
> reason for the change?
The reason is just because that function is only called from
ExecAppend(). I put some functions only called from nodeAppend.c in
execAsync.c, though.
> + /* Perform the actual callback. */
> + ExecAsyncRequest(areq);
> + if (ExecAppendAsyncResponse(areq))
> + {
> + Assert(!TupIsNull(areq->result));
> + *result = areq->result;
>
> Putting aside the name of the functions, the first two function are
> used only this way at only two places. ExecAsyncRequest(areq) tells
> fdw to store the first tuple among the already received ones to areq,
> and ExecAppendAsyncResponse(areq) is checking the result is actually
> set. Finally the result is retrieved directory from areq->result.
> What is the reason that the two functions are separately exists?
I think that when an async-aware node gets a tuple from an
async-capable node, they should use ExecAsyncRequest() /
ExecAyncHogeResponse() rather than ExecProcNode() [1]. I modified the
patch so that ExecAppendAsyncResponse() is called from Append, but to
support bubbling up the plan tree discussed in [2], I think it should
be called from ForeignScans (the sides of async-capable nodes). Am I
right? Anyway, I’ll rename ExecAppendAyncResponse() to the one
proposed in Robert’s original patch.
> + /* Perform the actual callback. */
> + ExecAsyncNotify(areq);
>
> Mmm. The usage of the function (or its name) looks completely reverse
> to me. I think FDW should NOTIFY to exec nodes that the new tuple
> gets available but the reverse is nonsense. What the function is
> actually doing is to REQUEST fdw to fetch tuples that are expected to
> have arrived, which is different from what the name suggests.
As mentioned in a previous email, this is an FDW callback routine
revived from Robert’s patch. I think the naming is reasonable,
because the callback routine notifies the FDW of readiness of a file
descriptor. And actually, the callback routine tells the core whether
the corresponding ForeignScan node is ready for a new request or not,
by setting the callback_pending flag accordingly.
> postgres_fdw.c
>
> > postgresIterateForeignScan(ForeignScanState *node)
> > {
> > PgFdwScanState *fsstate = (PgFdwScanState *) node->fdw_state;
> > TupleTableSlot *slot = node->ss.ss_ScanTupleSlot;
> >
> > /*
> >* If this is the first call after Begin or ReScan, we need to create
> > the
> >* cursor on the remote side.
> >*/
> > if (!fsstate->cursor_exists)
> > create_cursor(node);
>
> With the patch, cursors are also created in another place so at least
> the comment is wrong.
Good catch! Will fix.
> That being said, I think we should unify the
> code except the differences between async and sync. For example, if
> the fetch_more_data_begin() needs to be called only for async
> fetching, the cursor should be created before calling the function, in
> the code path common with sync fetching.
I think that that would make the code easier to understand, but I’m
not 100% sure we really need to do so.
Best regards,
Etsuro Fujita
[1]
https://www.postgresql.org/message-id/CA%2BTgmoYrbgTBnLwnr1v%3Dp
Re: Feature Proposal: Add ssltermination parameter for SNI-based LoadBalancing
Thanks for the provided ideas :) I use HaProxy for my load-balancing and unfortunately I can't define that I want to listen on a port for both ssl and non ssl requests. That means if I try to return a fixed response 'S' on the SSLRequest it fails with an SSL-Handshake failure cause the server expects a ssl message. I searched for some way to forward to a default backend on ssl failure but this seems to be no use-case for haproxy and isn't supported. I also didn't find any other tcp-loadbalancer, which could handle this type of ssl-failure fallback. My only option would therefore be to write a custom loadbalancer for this usecase, which is not really feasible given the amount of features of haproxy I plan to use. I have to say the psql ssl handshake procedure is really unique and challenging :D The tool stunnel is capable of this protocol but I can't do sni-based loadbalancing with it so this is kind of a dead end here. Lukas Am 11-Dec-20 um 16:44 schrieb Heikki Linnakangas: On 11/12/2020 16:46, Lukas Meisegeier wrote: Hey Heikki, thanks for providing feedback :) The traffic between proxy and psql-server is unencrypted thats why I don't need to patch the server. Ok. I tried returning a fixed response on the first plain SSLRequest forwarding it to a psql-server with ssl enabled an tried to switch then on the ssl connection startup but that didn't work out. I guess its because the psql-server won't accept an ssl connection if its not requested via SSLRequest. Your proxy could receive the client's SSLRequest message, and respond with a single byte 'S'. You don't need to forward that to the real PostgreSQL server, since the connection to the PostgreSQL server is unencrypted. Then perform the TLS handshake, and forward all traffic to the real server only after that. Client: -> SSLRequest Proxy: <- 'S' Client: -> TLS ClientHello Proxy: [finish TLS handshake] - Heikki
Re: Insert Documentation - Returning Clause and Order
On Friday, December 11, 2020, David G. Johnston wrote: > > On Fri, Dec 11, 2020 at 6:24 AM Ashutosh Bapat > wrote: >> >> On Thu, Dec 10, 2020 at 7:49 PM David G. Johnston >> wrote: >> >> > Yeah, the ongoing work on parallel inserts would seem to be an issue. We >> > should probably document that though. And maybe as part of parallel >> > inserts patch provide a user-specifiable way to ask for such a guarantee >> > if needed. ‘Insert returning ordered” >> >> I am curious about the usecase which needs that guarantee? Don't you >> have a column on which you can ORDER BY so that it returns the same >> order as INSERT? > > > This comes up periodically in the context of auto-generated keys being > returned - specifically on the JDBC project list (maybe elsewhere...). If > one adds 15 VALUES entries to an insert and then sends them in bulk to the > server it would be helpful if the generated keys could be matched up > one-to-one with the keyless objects in the client. Basically "pipelining" > the client and server. That’s a great use case. It’s not so much about ordering, per se, but about identity. Certainly almost every ORM, and maybe even other forms of application code, need to be able to associate the serial column value returned with what it inserted. I'd expect something like that (whether by ordering explicitly or by providing some kind of mapping between indexes in the statement data and the inserted/returned row values). James
Re: Insert Documentation - Returning Clause and Order
On Sat, Dec 12, 2020 at 7:02 AM James Coleman wrote: > > Certainly almost every ORM, and maybe even other forms of application > code, need to be able to associate the serial column value returned > with what it inserted. > Yet most ORM would perform single inserts at a time, not in bulk, making such a feature irrelevant to them. I don't think having such a feature is all that important personally, but the question comes every so often and it would be nice to be able to point at the documentation for a definitive answer - not just one inferred from a lack of documentation - especially since the observed behavior is that order is preserved today. David J.
Re: pglz compression performance, take two
> 9 дек. 2020 г., в 12:44, Andrey Borodin написал(а): > PFA the patch with some editorialisation by me. > I saw some reports of bottlenecking in pglz WAL compression [1]. I've checked that on my machine simple test echo "wal_compression = on" >> $PGDATA/postgresql.conf pgbench -i -s 20 && pgbench -T 30 shows ~2-3% of improvement, but the result is not very stable, deviation is comparable. In fact, bottleneck is just shifted from pglz, thus impact is not that measurable. I've found out that the patch continues ideas from thread [0] and commit 031cc55 [1], but in much more shotgun-surgery way. Out of curiosity I've rerun tests from that thread postgres=# with patched as (select testname, avg(seconds) patched from testresults0 group by testname),unpatched as (select testname, avg(seconds) unpatched from testresults group by testname) select * from unpatched join patched using (testname); testname | unpatched|patched ---++ 512b random | 4.55680150 | 4.35129800 100k random | 1.03342300 | 1.00326200 100k of same byte | 2.16897150 | 2.09581550 2k random | 3.16138150 | 3.18613500 512b text | 5.72336000 | 5.36023300 5k text | 1.70448350 | 1.80867700 (6 rows) Results of direct call are somewhat more clear. Unpatched: testname | auto ---+--- 5k text | 1100.705 512b text | 240.585 2k random | 106.865 100k random | 2.663 512b random | 145.736 100k of same byte | 13426.880 (6 rows) Patched: testname | auto ---+-- 5k text | 767.535 512b text | 159.076 2k random | 77.126 100k random |1.698 512b random | 95.768 100k of same byte | 6035.159 (6 rows) Thanks! Best regards, Andrey Borodin. [0] https://www.postgresql.org/message-id/flat/5130C914.8080106%40vmware.com [1] https://github.com/x4m/postgres_g/commit/031cc55bbea6b3a6b67c700498a78fb1d4399476
Re: Allow CLUSTER, VACUUM FULL and REINDEX to change tablespace on the fly
On Sat, Dec 12, 2020 at 09:20:35AM +0100, Peter Eisentraut wrote:
> On 2020-12-11 21:27, Alvaro Herrera wrote:
> > By the way-- What did you think of the idea of explictly marking the
> > types used for bitmasks using types bits32 and friends, instead of plain
> > int, which is harder to spot?
>
> If we want to make it clearer, why not turn the thing into a struct, as in
> the attached patch, and avoid the bit fiddling altogether.
I like this.
It's a lot like what I wrote as [PATCH v31 1/5] ExecReindex and ReindexParams
In my v31 patch, I moved ReindexOptions to a private structure in indexcmds.c,
with an "int options" bitmask which is passed to reindex_index() et al. Your
patch keeps/puts ReindexOptions index.h, so it also applies to reindex_index,
which I think is good.
So I've rebased this branch on your patch.
Some thoughts:
- what about removing the REINDEXOPT_* prefix ?
- You created local vars with initialization like "={}". But I thought it's
needed to include at least one struct member like "={false}", or else
they're not guaranteed to be zerod ?
- You passed the structure across function calls. The usual convention is to
pass a pointer.
I also changed the errcode and detail for this one.
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("incompatible TABLESPACE option"),
errdetail("TABLESPACE can only be used with VACUUM FULL.")));
--
Justin
>From 3d84ec564a1ad3df50967153d2acbd443a04b864 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut
Date: Sat, 12 Dec 2020 09:17:55 +0100
Subject: [PATCH v34 1/8] Convert reindex options to struct
---
src/backend/catalog/index.c | 19 ---
src/backend/commands/cluster.c | 2 +-
src/backend/commands/indexcmds.c | 94
src/backend/commands/tablecmds.c | 2 +-
src/backend/tcop/utility.c | 4 +-
src/include/catalog/index.h | 16 +++---
src/include/commands/defrem.h| 9 +--
7 files changed, 74 insertions(+), 72 deletions(-)
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 731610c701..06342fddf1 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3594,7 +3594,7 @@ IndexGetRelation(Oid indexId, bool missing_ok)
*/
void
reindex_index(Oid indexId, bool skip_constraint_checks, char persistence,
- int options)
+ ReindexOptions options)
{
Relation iRel,
heapRelation;
@@ -3602,7 +3602,7 @@ reindex_index(Oid indexId, bool skip_constraint_checks, char persistence,
IndexInfo *indexInfo;
volatile bool skipped_constraint = false;
PGRUsage ru0;
- bool progress = (options & REINDEXOPT_REPORT_PROGRESS) != 0;
+ bool progress = options.REINDEXOPT_REPORT_PROGRESS;
pg_rusage_init(&ru0);
@@ -3611,12 +3611,12 @@ reindex_index(Oid indexId, bool skip_constraint_checks, char persistence,
* we only need to be sure no schema or data changes are going on.
*/
heapId = IndexGetRelation(indexId,
- (options & REINDEXOPT_MISSING_OK) != 0);
+ options.REINDEXOPT_MISSING_OK);
/* if relation is missing, leave */
if (!OidIsValid(heapId))
return;
- if ((options & REINDEXOPT_MISSING_OK) != 0)
+ if (options.REINDEXOPT_MISSING_OK)
heapRelation = try_table_open(heapId, ShareLock);
else
heapRelation = table_open(heapId, ShareLock);
@@ -3792,7 +3792,7 @@ reindex_index(Oid indexId, bool skip_constraint_checks, char persistence,
}
/* Log what we did */
- if (options & REINDEXOPT_VERBOSE)
+ if (options.REINDEXOPT_VERBOSE)
ereport(INFO,
(errmsg("index \"%s\" was reindexed",
get_rel_name(indexId)),
@@ -3846,7 +3846,7 @@ reindex_index(Oid indexId, bool skip_constraint_checks, char persistence,
* index rebuild.
*/
bool
-reindex_relation(Oid relid, int flags, int options)
+reindex_relation(Oid relid, int flags, ReindexOptions options)
{
Relation rel;
Oid toast_relid;
@@ -3861,7 +3861,7 @@ reindex_relation(Oid relid, int flags, int options)
* to prevent schema and data changes in it. The lock level used here
* should match ReindexTable().
*/
- if ((options & REINDEXOPT_MISSING_OK) != 0)
+ if (options.REINDEXOPT_MISSING_OK)
rel = try_table_open(relid, ShareLock);
else
rel = table_open(relid, ShareLock);
@@ -3965,8 +3965,9 @@ reindex_relation(Oid relid, int flags, int options)
* Note that this should fail if the toast relation is missing, so
* reset REINDEXOPT_MISSING_OK.
*/
- result |= reindex_relation(toast_relid, flags,
- options & ~(REINDEXOPT_MISSING_OK));
+ ReindexOptions newoptions = options;
+ newoptions.REINDEXOPT_MISSING_OK = false;
+ result |= reindex_relation(toast_relid, flags, newoptions);
}
return result;
diff --git a/src/backend/commands/cluster.c b/src/backend/commands/cluster.c
index fd5a6eec86..b0aa3536d1 100644
--- a/src/backend/commands/cluster.c
+++ b/src/backend/commands/cluster.c
@@ -1412,7 +1412,7 @@ finish_heap_swap(Oid OIDOldHeap, Oid OIDNewHeap,
pgsta
Re: Allow CLUSTER, VACUUM FULL and REINDEX to change tablespace on the fly
On Sat, Dec 12, 2020 at 01:45:26PM -0600, Justin Pryzby wrote:
> On Sat, Dec 12, 2020 at 09:20:35AM +0100, Peter Eisentraut wrote:
> > On 2020-12-11 21:27, Alvaro Herrera wrote:
> > > By the way-- What did you think of the idea of explictly marking the
> > > types used for bitmasks using types bits32 and friends, instead of plain
> > > int, which is harder to spot?
> >
> > If we want to make it clearer, why not turn the thing into a struct, as in
> > the attached patch, and avoid the bit fiddling altogether.
>
> I like this.
> It's a lot like what I wrote as [PATCH v31 1/5] ExecReindex and ReindexParams
> In my v31 patch, I moved ReindexOptions to a private structure in indexcmds.c,
> with an "int options" bitmask which is passed to reindex_index() et al. Your
> patch keeps/puts ReindexOptions index.h, so it also applies to reindex_index,
> which I think is good.
>
> So I've rebased this branch on your patch.
Also, the cfbot's windows VS compilation failed due to "compound literal",
which I don't think is used anywhere else.
https://ci.appveyor.com/project/postgresql-cfbot/postgresql/build/1.0.120108
src/backend/commands/cluster.c(1580): warning C4133: 'return' : incompatible
types - from 'List *' to 'int *' [C:\projects\postgresql\postgres.vcxproj]
"C:\projects\postgresql\pgsql.sln" (default target) (1) ->
"C:\projects\postgresql\cyrillic_and_mic.vcxproj" (default target) (5) ->
"C:\projects\postgresql\postgres.vcxproj" (default target) (6) ->
(ClCompile target) ->
src/backend/commands/cluster.c(1415): error C2059: syntax error : '}'
[C:\projects\postgresql\postgres.vcxproj]
src/backend/commands/cluster.c(1534): error C2143: syntax error : missing '{'
before '*' [C:\projects\postgresql\postgres.vcxproj]
src/backend/commands/cluster.c(1536): error C2371: 'get_tables_to_cluster' :
redefinition; different basic types [C:\projects\postgresql\postgres.vcxproj]
src/backend/commands/indexcmds.c(2462): error C2059: syntax error : '}'
[C:\projects\postgresql\postgres.vcxproj]
src/backend/commands/tablecmds.c(1894): error C2059: syntax error : '}'
[C:\projects\postgresql\postgres.vcxproj]
My fix! patch resolves that.
--
Justin
Re: Insert Documentation - Returning Clause and Order
On Sat, Dec 12, 2020 at 10:11 AM David G. Johnston wrote: > > On Sat, Dec 12, 2020 at 7:02 AM James Coleman wrote: >> >> >> Certainly almost every ORM, and maybe even other forms of application >> code, need to be able to associate the serial column value returned >> with what it inserted. > > > Yet most ORM would perform single inserts at a time, not in bulk, making such > a feature irrelevant to them. I think that's a pretty hasty generalization. It's the majority of use cases in an ORM, sure, but plenty of ORMs (and libraries or applications using them) support inserting batches where performance requires it. Rails/ActiveRecord is actually integrating that feature into core (though many Ruby libraries already add that support, as does, for example, the application I spend the majority of time working on). James
