Skip to content

[pull] master from postgres:master #1017

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jul 3, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions doc/src/sgml/ref/create_trigger.sgml
Original file line number Diff line number Diff line change
Expand Up @@ -324,9 +324,11 @@ UPDATE OF <replaceable>column_name1</replaceable> [, <replaceable>column_name2</
<varlistentry>
<term><literal>ENFORCED</literal></term>
<listitem>
This is a noise word. Constraint triggers are always enforced.
<para>
This is a noise word. Constraint triggers are always enforced.
</para>
</listitem>
</varlistitem>
</varlistentry>

<varlistentry>
<term><literal>REFERENCING</literal></term>
Expand Down
10 changes: 4 additions & 6 deletions doc/src/sgml/system-views.sgml
Original file line number Diff line number Diff line change
Expand Up @@ -2819,20 +2819,18 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx
<para>
<literal>unreserved</literal> means that the slot no longer
retains the required WAL files and some of them are to be removed at
the next checkpoint. This state can return
the next checkpoint. This typically occurs when
<xref linkend="guc-max-slot-wal-keep-size"/> is set to
a non-negative value. This state can return
to <literal>reserved</literal> or <literal>extended</literal>.
</para>
</listitem>
<listitem>
<para>
<literal>lost</literal> means that some required WAL files have
been removed and this slot is no longer usable.
<literal>lost</literal> means that this slot is no longer usable.
</para>
</listitem>
</itemizedlist>
The last two states are seen only when
<xref linkend="guc-max-slot-wal-keep-size"/> is
non-negative.
</para></entry>
</row>

Expand Down
22 changes: 22 additions & 0 deletions src/backend/commands/tablecmds.c
Original file line number Diff line number Diff line change
Expand Up @@ -15487,6 +15487,14 @@ ATPostAlterTypeCleanup(List **wqueue, AlteredTableInfo *tab, LOCKMODE lockmode)
Oid relid;

relid = IndexGetRelation(oldId, false);

/*
* As above, make sure we have lock on the index's table if it's not
* the same table.
*/
if (relid != tab->relid)
LockRelationOid(relid, AccessExclusiveLock);

ATPostAlterTypeParse(oldId, relid, InvalidOid,
(char *) lfirst(def_item),
wqueue, lockmode, tab->rewrite);
Expand All @@ -15503,6 +15511,20 @@ ATPostAlterTypeCleanup(List **wqueue, AlteredTableInfo *tab, LOCKMODE lockmode)
Oid relid;

relid = StatisticsGetRelation(oldId, false);

/*
* As above, make sure we have lock on the statistics object's table
* if it's not the same table. However, we take
* ShareUpdateExclusiveLock here, aligning with the lock level used in
* CreateStatistics and RemoveStatisticsById.
*
* CAUTION: this should be done after all cases that grab
* AccessExclusiveLock, else we risk causing deadlock due to needing
* to promote our table lock.
*/
if (relid != tab->relid)
LockRelationOid(relid, ShareUpdateExclusiveLock);

ATPostAlterTypeParse(oldId, relid, InvalidOid,
(char *) lfirst(def_item),
wqueue, lockmode, tab->rewrite);
Expand Down
17 changes: 12 additions & 5 deletions src/bin/psql/tab-complete.in.c
Original file line number Diff line number Diff line change
Expand Up @@ -2733,17 +2733,24 @@ match_previous_words(int pattern_id,
/* ALTER TABLE xxx ADD */
else if (Matches("ALTER", "TABLE", MatchAny, "ADD"))
{
/* make sure to keep this list and the !Matches() below in sync */
COMPLETE_WITH("COLUMN", "CONSTRAINT", "CHECK", "UNIQUE", "PRIMARY KEY",
"EXCLUDE", "FOREIGN KEY");
/*
* make sure to keep this list and the MatchAnyExcept() below in sync
*/
COMPLETE_WITH("COLUMN", "CONSTRAINT", "CHECK (", "NOT NULL", "UNIQUE",
"PRIMARY KEY", "EXCLUDE", "FOREIGN KEY");
}
/* ALTER TABLE xxx ADD [COLUMN] yyy */
else if (Matches("ALTER", "TABLE", MatchAny, "ADD", "COLUMN", MatchAny) ||
Matches("ALTER", "TABLE", MatchAny, "ADD", MatchAnyExcept("COLUMN|CONSTRAINT|CHECK|UNIQUE|PRIMARY|EXCLUDE|FOREIGN")))
Matches("ALTER", "TABLE", MatchAny, "ADD", MatchAnyExcept("COLUMN|CONSTRAINT|CHECK|UNIQUE|PRIMARY|NOT|EXCLUDE|FOREIGN")))
COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_datatypes);
/* ALTER TABLE xxx ADD CONSTRAINT yyy */
else if (Matches("ALTER", "TABLE", MatchAny, "ADD", "CONSTRAINT", MatchAny))
COMPLETE_WITH("CHECK", "UNIQUE", "PRIMARY KEY", "EXCLUDE", "FOREIGN KEY");
COMPLETE_WITH("CHECK (", "NOT NULL", "UNIQUE", "PRIMARY KEY", "EXCLUDE", "FOREIGN KEY");
/* ALTER TABLE xxx ADD NOT NULL */
else if (Matches("ALTER", "TABLE", MatchAny, "ADD", "NOT", "NULL"))
COMPLETE_WITH_ATTR(prev4_wd);
else if (Matches("ALTER", "TABLE", MatchAny, "ADD", "CONSTRAINT", MatchAny, "NOT", "NULL"))
COMPLETE_WITH_ATTR(prev6_wd);
/* ALTER TABLE xxx ADD [CONSTRAINT yyy] (PRIMARY KEY|UNIQUE) */
else if (Matches("ALTER", "TABLE", MatchAny, "ADD", "PRIMARY", "KEY") ||
Matches("ALTER", "TABLE", MatchAny, "ADD", "UNIQUE") ||
Expand Down
11 changes: 0 additions & 11 deletions src/include/access/commit_ts.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,17 +46,6 @@ extern int committssyncfiletag(const FileTag *ftag, char *path);
#define COMMIT_TS_ZEROPAGE 0x00
#define COMMIT_TS_TRUNCATE 0x10

typedef struct xl_commit_ts_set
{
TimestampTz timestamp;
RepOriginId nodeid;
TransactionId mainxid;
/* subxact Xids follow */
} xl_commit_ts_set;

#define SizeOfCommitTsSet (offsetof(xl_commit_ts_set, mainxid) + \
sizeof(TransactionId))

typedef struct xl_commit_ts_truncate
{
int64 pageno;
Expand Down
8 changes: 8 additions & 0 deletions src/test/regress/expected/alter_table.out
Original file line number Diff line number Diff line change
Expand Up @@ -4750,6 +4750,14 @@ create table attbl(a int);
create table atref(b attbl check ((b).a is not null));
alter table attbl alter column a type numeric; -- someday this should work
ERROR: cannot alter table "attbl" because column "atref.b" uses its row type
alter table atref drop constraint atref_b_check;
create statistics atref_stat on ((b).a is not null) from atref;
alter table attbl alter column a type numeric; -- someday this should work
ERROR: cannot alter table "attbl" because column "atref.b" uses its row type
drop statistics atref_stat;
create index atref_idx on atref (((b).a));
alter table attbl alter column a type numeric; -- someday this should work
ERROR: cannot alter table "attbl" because column "atref.b" uses its row type
drop table attbl, atref;
/* End test case for bug #18970 */
-- Test that ALTER TABLE rewrite preserves a clustered index
Expand Down
12 changes: 12 additions & 0 deletions src/test/regress/expected/generated_stored.out
Original file line number Diff line number Diff line change
Expand Up @@ -1313,6 +1313,18 @@ CREATE TABLE gtest31_1 (a int, b text GENERATED ALWAYS AS ('hello') STORED, c te
CREATE TABLE gtest31_2 (x int, y gtest31_1);
ALTER TABLE gtest31_1 ALTER COLUMN b TYPE varchar; -- fails
ERROR: cannot alter table "gtest31_1" because column "gtest31_2.y" uses its row type
-- bug #18970: these cases are unsupported, but make sure they fail cleanly
ALTER TABLE gtest31_2 ADD CONSTRAINT cc CHECK ((y).b IS NOT NULL);
ALTER TABLE gtest31_1 ALTER COLUMN b SET EXPRESSION AS ('hello1');
ERROR: cannot alter table "gtest31_1" because column "gtest31_2.y" uses its row type
ALTER TABLE gtest31_2 DROP CONSTRAINT cc;
CREATE STATISTICS gtest31_2_stat ON ((y).b is not null) FROM gtest31_2;
ALTER TABLE gtest31_1 ALTER COLUMN b SET EXPRESSION AS ('hello2');
ERROR: cannot alter table "gtest31_1" because column "gtest31_2.y" uses its row type
DROP STATISTICS gtest31_2_stat;
CREATE INDEX gtest31_2_y_idx ON gtest31_2(((y).b));
ALTER TABLE gtest31_1 ALTER COLUMN b SET EXPRESSION AS ('hello3');
ERROR: cannot alter table "gtest31_1" because column "gtest31_2.y" uses its row type
DROP TABLE gtest31_1, gtest31_2;
-- Check it for a partitioned table, too
CREATE TABLE gtest31_1 (a int, b text GENERATED ALWAYS AS ('hello') STORED, c text) PARTITION BY LIST (a);
Expand Down
9 changes: 9 additions & 0 deletions src/test/regress/expected/generated_virtual.out
Original file line number Diff line number Diff line change
Expand Up @@ -1283,6 +1283,15 @@ CREATE TABLE gtest31_1 (a int, b text GENERATED ALWAYS AS ('hello') VIRTUAL, c t
CREATE TABLE gtest31_2 (x int, y gtest31_1);
ALTER TABLE gtest31_1 ALTER COLUMN b TYPE varchar; -- fails
ERROR: cannot alter table "gtest31_1" because column "gtest31_2.y" uses its row type
-- bug #18970
ALTER TABLE gtest31_2 ADD CONSTRAINT cc CHECK ((y).b IS NOT NULL);
ALTER TABLE gtest31_1 ALTER COLUMN b SET EXPRESSION AS ('hello1');
ALTER TABLE gtest31_2 DROP CONSTRAINT cc;
CREATE STATISTICS gtest31_2_stat ON ((y).b is not null) FROM gtest31_2;
ALTER TABLE gtest31_1 ALTER COLUMN b SET EXPRESSION AS ('hello2');
DROP STATISTICS gtest31_2_stat;
CREATE INDEX gtest31_2_y_idx ON gtest31_2(((y).b));
ALTER TABLE gtest31_1 ALTER COLUMN b SET EXPRESSION AS ('hello3');
DROP TABLE gtest31_1, gtest31_2;
-- Check it for a partitioned table, too
CREATE TABLE gtest31_1 (a int, b text GENERATED ALWAYS AS ('hello') VIRTUAL, c text) PARTITION BY LIST (a);
Expand Down
8 changes: 8 additions & 0 deletions src/test/regress/sql/alter_table.sql
Original file line number Diff line number Diff line change
Expand Up @@ -3074,6 +3074,14 @@ drop table attbl, atref;
create table attbl(a int);
create table atref(b attbl check ((b).a is not null));
alter table attbl alter column a type numeric; -- someday this should work
alter table atref drop constraint atref_b_check;

create statistics atref_stat on ((b).a is not null) from atref;
alter table attbl alter column a type numeric; -- someday this should work
drop statistics atref_stat;

create index atref_idx on atref (((b).a));
alter table attbl alter column a type numeric; -- someday this should work
drop table attbl, atref;

/* End test case for bug #18970 */
Expand Down
13 changes: 13 additions & 0 deletions src/test/regress/sql/generated_stored.sql
Original file line number Diff line number Diff line change
Expand Up @@ -595,6 +595,19 @@ ALTER TABLE gtest30_1 ALTER COLUMN b DROP EXPRESSION; -- error
CREATE TABLE gtest31_1 (a int, b text GENERATED ALWAYS AS ('hello') STORED, c text);
CREATE TABLE gtest31_2 (x int, y gtest31_1);
ALTER TABLE gtest31_1 ALTER COLUMN b TYPE varchar; -- fails

-- bug #18970: these cases are unsupported, but make sure they fail cleanly
ALTER TABLE gtest31_2 ADD CONSTRAINT cc CHECK ((y).b IS NOT NULL);
ALTER TABLE gtest31_1 ALTER COLUMN b SET EXPRESSION AS ('hello1');
ALTER TABLE gtest31_2 DROP CONSTRAINT cc;

CREATE STATISTICS gtest31_2_stat ON ((y).b is not null) FROM gtest31_2;
ALTER TABLE gtest31_1 ALTER COLUMN b SET EXPRESSION AS ('hello2');
DROP STATISTICS gtest31_2_stat;

CREATE INDEX gtest31_2_y_idx ON gtest31_2(((y).b));
ALTER TABLE gtest31_1 ALTER COLUMN b SET EXPRESSION AS ('hello3');

DROP TABLE gtest31_1, gtest31_2;

-- Check it for a partitioned table, too
Expand Down
13 changes: 13 additions & 0 deletions src/test/regress/sql/generated_virtual.sql
Original file line number Diff line number Diff line change
Expand Up @@ -646,6 +646,19 @@ ALTER TABLE gtest30_1 ALTER COLUMN b DROP EXPRESSION; -- error
CREATE TABLE gtest31_1 (a int, b text GENERATED ALWAYS AS ('hello') VIRTUAL, c text);
CREATE TABLE gtest31_2 (x int, y gtest31_1);
ALTER TABLE gtest31_1 ALTER COLUMN b TYPE varchar; -- fails

-- bug #18970
ALTER TABLE gtest31_2 ADD CONSTRAINT cc CHECK ((y).b IS NOT NULL);
ALTER TABLE gtest31_1 ALTER COLUMN b SET EXPRESSION AS ('hello1');
ALTER TABLE gtest31_2 DROP CONSTRAINT cc;

CREATE STATISTICS gtest31_2_stat ON ((y).b is not null) FROM gtest31_2;
ALTER TABLE gtest31_1 ALTER COLUMN b SET EXPRESSION AS ('hello2');
DROP STATISTICS gtest31_2_stat;

CREATE INDEX gtest31_2_y_idx ON gtest31_2(((y).b));
ALTER TABLE gtest31_1 ALTER COLUMN b SET EXPRESSION AS ('hello3');

DROP TABLE gtest31_1, gtest31_2;

-- Check it for a partitioned table, too
Expand Down