@ -220,41 +220,63 @@ logicalrep_rel_att_by_name(LogicalRepRelation *remoterel, const char *attname)
}
}
/*
/*
* Report error with names of the missing local relation column ( s ) , if any .
* Returns a comma - separated string of attribute names based on the provided
* relation and bitmap indicating which attributes to include .
*/
*/
static void
static char *
logicalrep_report_missing_attrs ( LogicalRepRelation * remoterel ,
logicalrep_get_attrs_str ( LogicalRepRelation * remoterel , Bitmapset * atts )
Bitmapset * missingatts )
{
{
if ( ! bms_is_empty ( missingatts ) )
StringInfoData attsbuf ;
int attcnt = 0 ;
int i = - 1 ;
Assert ( ! bms_is_empty ( atts ) ) ;
initStringInfo ( & attsbuf ) ;
while ( ( i = bms_next_member ( atts , i ) ) > = 0 )
{
{
StringInfoData missingattsbuf ;
attcnt + + ;
int missingattcnt = 0 ;
if ( attcnt > 1 )
int i ;
appendStringInfo ( & attsbuf , _ ( " , " ) ) ;
initStringInfo ( & missingattsbuf ) ;
appendStringInfo ( & attsbuf , _ ( " \" %s \" " ) , remoterel - > attnames [ i ] ) ;
}
i = - 1 ;
return attsbuf . data ;
while ( ( i = bms_next_member ( missingatts , i ) ) > = 0 )
}
{
missingattcnt + + ;
if ( missingattcnt = = 1 )
appendStringInfo ( & missingattsbuf , _ ( " \" %s \" " ) ,
remoterel - > attnames [ i ] ) ;
else
appendStringInfo ( & missingattsbuf , _ ( " , \" %s \" " ) ,
remoterel - > attnames [ i ] ) ;
}
/*
* If attempting to replicate missing or generated columns , report an error .
* Prioritize ' missing ' errors if both occur though the prioritization is
* arbitrary .
*/
static void
logicalrep_report_missing_or_gen_attrs ( LogicalRepRelation * remoterel ,
Bitmapset * missingatts ,
Bitmapset * generatedatts )
{
if ( ! bms_is_empty ( missingatts ) )
ereport ( ERROR ,
ereport ( ERROR ,
( errcode ( ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE ) ,
errcode ( ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE ) ,
errmsg_plural ( " logical replication target relation \" %s.%s \" is missing replicated column: %s " ,
errmsg_plural ( " logical replication target relation \" %s.%s \" is missing replicated column: %s " ,
" logical replication target relation \" %s.%s \" is missing replicated columns: %s " ,
" logical replication target relation \" %s.%s \" is missing replicated columns: %s " ,
missingattcnt ,
bms_num_members ( missingatts ) ,
remoterel - > nspname ,
remoterel - > nspname ,
remoterel - > relname ,
remoterel - > relname ,
missingattsbuf . data ) ) ) ;
logicalrep_get_attrs_str ( remoterel ,
}
missingatts ) ) ) ;
if ( ! bms_is_empty ( generatedatts ) )
ereport ( ERROR ,
errcode ( ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE ) ,
errmsg_plural ( " logical replication target relation \" %s.%s \" has incompatible generated column: %s " ,
" logical replication target relation \" %s.%s \" has incompatible generated columns: %s " ,
bms_num_members ( generatedatts ) ,
remoterel - > nspname ,
remoterel - > relname ,
logicalrep_get_attrs_str ( remoterel ,
generatedatts ) ) ) ;
}
}
/*
/*
@ -380,6 +402,7 @@ logicalrep_rel_open(LogicalRepRelId remoteid, LOCKMODE lockmode)
MemoryContext oldctx ;
MemoryContext oldctx ;
int i ;
int i ;
Bitmapset * missingatts ;
Bitmapset * missingatts ;
Bitmapset * generatedattrs = NULL ;
/* Release the no-longer-useful attrmap, if any. */
/* Release the no-longer-useful attrmap, if any. */
if ( entry - > attrmap )
if ( entry - > attrmap )
@ -421,7 +444,7 @@ logicalrep_rel_open(LogicalRepRelId remoteid, LOCKMODE lockmode)
int attnum ;
int attnum ;
Form_pg_attribute attr = TupleDescAttr ( desc , i ) ;
Form_pg_attribute attr = TupleDescAttr ( desc , i ) ;
if ( attr - > attisdropped | | attr - > attgenerated )
if ( attr - > attisdropped )
{
{
entry - > attrmap - > attnums [ i ] = - 1 ;
entry - > attrmap - > attnums [ i ] = - 1 ;
continue ;
continue ;
@ -432,12 +455,20 @@ logicalrep_rel_open(LogicalRepRelId remoteid, LOCKMODE lockmode)
entry - > attrmap - > attnums [ i ] = attnum ;
entry - > attrmap - > attnums [ i ] = attnum ;
if ( attnum > = 0 )
if ( attnum > = 0 )
{
/* Remember which subscriber columns are generated. */
if ( attr - > attgenerated )
generatedattrs = bms_add_member ( generatedattrs , attnum ) ;
missingatts = bms_del_member ( missingatts , attnum ) ;
missingatts = bms_del_member ( missingatts , attnum ) ;
}
}
}
logicalrep_report_missing_attrs ( remoterel , missingatts ) ;
logicalrep_report_missing_or_gen_attrs ( remoterel , missingatts ,
generatedattrs ) ;
/* be tidy */
/* be tidy */
bms_free ( generatedattrs ) ;
bms_free ( missingatts ) ;
bms_free ( missingatts ) ;
/*
/*