@@ -103,7 +103,7 @@ static void run_worker(BackgroundWorker *worker, WorkerTask *task,
103103 bool nowait );
104104
105105static void check_prerequisites (Relation rel );
106- static LogicalDecodingContext * setup_decoding (Oid relid , TupleDesc tup_desc );
106+ static LogicalDecodingContext * setup_decoding (Oid relid );
107107static void decoding_cleanup (LogicalDecodingContext * ctx );
108108static CatalogState * get_catalog_state (Oid relid );
109109static void get_pg_class_info (Oid relid , TransactionId * xmin ,
@@ -736,6 +736,13 @@ rewrite_worker_main(Datum main_arg)
736736 MemoryContext old_context = CurrentMemoryContext ;
737737 ErrorData * edata ;
738738
739+ /*
740+ * If the backend is not waiting for our exit, make sure the error is
741+ * logged.
742+ */
743+ if (MyWorkerTask -> nowait )
744+ PG_RE_THROW ();
745+
739746 HOLD_INTERRUPTS ();
740747
741748 /*
@@ -846,7 +853,6 @@ rewrite_table_impl(char *relschema_src, char *relname_src,
846853 LogicalDecodingContext * ctx ;
847854 ReplicationSlot * slot ;
848855 Snapshot snap_hist ;
849- TupleDesc tup_desc_src ;
850856 CatalogState * cat_state ;
851857 XLogRecPtr end_of_wal ;
852858 XLogRecPtr xlog_insert_ptr ;
@@ -906,14 +912,6 @@ rewrite_table_impl(char *relschema_src, char *relname_src,
906912
907913 relid_src = RelationGetRelid (rel_src );
908914
909- /*
910- * Info to initialize the tuplestore we'll use during logical decoding.
911- *
912- * Copy is needed because we'll close the relation before using the tuple
913- * descriptor.
914- */
915- tup_desc_src = CreateTupleDescCopy (RelationGetDescr (rel_src ));
916-
917915 /*
918916 * Get ready for the subsequent calls of
919917 * pg_rewrite_check_catalog_changes().
@@ -959,7 +957,7 @@ rewrite_table_impl(char *relschema_src, char *relname_src,
959957 for (i = 0 ; i < nindexes ; i ++ )
960958 indexes_src [i ] = cat_state -> indexes [i ].oid ;
961959
962- ctx = setup_decoding (relid_src , tup_desc_src );
960+ ctx = setup_decoding (relid_src );
963961
964962 /*
965963 * The destination table should not be accessed by anyone during our
@@ -969,7 +967,8 @@ rewrite_table_impl(char *relschema_src, char *relname_src,
969967 * until the processing is done.
970968 *
971969 * This cannot be done before the call of setup_decoding() as the
972- * exclusive lock does assign XID.
970+ * exclusive lock does assign XID. (setup_decoding() would then wait for
971+ * our transaction to complete.)
973972 */
974973 relrv = makeRangeVar (relschema_dst , relname_dst , -1 );
975974 rel_dst = table_openrv (relrv , AccessExclusiveLock );
@@ -984,6 +983,12 @@ rewrite_table_impl(char *relschema_src, char *relname_src,
984983 (errcode (ERRCODE_WRONG_OBJECT_TYPE ),
985984 errmsg ("\"%s\" is not a permanent table" , relname_dst )));
986985
986+ /*
987+ * Now that we have locked rel_dst, get its tuple descriptor.
988+ */
989+ ((DecodingOutputState * ) ctx -> output_writer_private )-> tupdesc =
990+ RelationGetDescr (rel_dst );
991+
987992 /*
988993 * Build a "historic snapshot", i.e. one that reflect the table state at
989994 * the moment the snapshot builder reached SNAPBUILD_CONSISTENT state.
@@ -1527,7 +1532,7 @@ check_prerequisites(Relation rel)
15271532 * and FATAL should lead to cleanup even before the cluster goes down.)
15281533 */
15291534static LogicalDecodingContext *
1530- setup_decoding (Oid relid , TupleDesc tup_desc )
1535+ setup_decoding (Oid relid )
15311536{
15321537 StringInfo buf ;
15331538 LogicalDecodingContext * ctx ;
@@ -1598,7 +1603,6 @@ setup_decoding(Oid relid, TupleDesc tup_desc)
15981603 dstate -> relid = relid ;
15991604 dstate -> tstore = tuplestore_begin_heap (false, false,
16001605 maintenance_work_mem );
1601- dstate -> tupdesc = tup_desc ;
16021606
16031607 /* Initialize the descriptor to store the changes ... */
16041608 dstate -> tupdesc_change = CreateTemplateTupleDesc (1 );
@@ -1626,7 +1630,6 @@ decoding_cleanup(LogicalDecodingContext *ctx)
16261630
16271631 ExecDropSingleTupleTableSlot (dstate -> tsslot );
16281632 FreeTupleDesc (dstate -> tupdesc_change );
1629- FreeTupleDesc (dstate -> tupdesc );
16301633 tuplestore_end (dstate -> tstore );
16311634
16321635 FreeDecodingContext (ctx );
@@ -2104,6 +2107,7 @@ get_modify_table_state(EState *estate, Relation rel, CmdType operation)
21042107 ResultRelInfo * rri = makeNode (ResultRelInfo );
21052108
21062109 InitResultRelInfo (rri , rel , 0 , NULL , 0 );
2110+ ExecOpenIndices (rri , false);
21072111
21082112 result -> ps .plan = NULL ;
21092113 result -> ps .state = estate ;
@@ -2119,6 +2123,7 @@ get_modify_table_state(EState *estate, Relation rel, CmdType operation)
21192123static void
21202124free_modify_table_state (ModifyTableState * mtstate )
21212125{
2126+ ExecCloseIndices (mtstate -> resultRelInfo );
21222127 pfree (mtstate -> resultRelInfo );
21232128 pfree (mtstate );
21242129}
0 commit comments