From 6d7af1f78505c08fb205a56bd1ba3cb951f04002 Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Thu, 9 Nov 2023 14:11:34 +0100 Subject: [PATCH] fixup! Add temporal PRIMARY KEY and UNIQUE constraints --- doc/src/sgml/catalogs.sgml | 8 +-- doc/src/sgml/ref/create_table.sgml | 68 ++++++++----------- src/backend/catalog/heap.c | 4 +- src/backend/catalog/index.c | 14 ++-- src/backend/catalog/pg_constraint.c | 4 +- src/backend/commands/indexcmds.c | 30 ++++---- src/backend/commands/tablecmds.c | 16 ++--- src/backend/commands/trigger.c | 2 +- src/backend/commands/typecmds.c | 2 +- src/backend/parser/gram.y | 19 +++--- src/backend/parser/parse_utilcmd.c | 28 ++++++-- src/backend/utils/adt/ruleutils.c | 27 +++----- src/backend/utils/cache/relcache.c | 16 +++-- src/bin/pg_dump/pg_dump.c | 33 +++------ src/bin/pg_dump/pg_dump.h | 2 +- src/bin/pg_dump/t/002_pg_dump.pl | 14 ++-- src/bin/psql/describe.c | 10 +-- src/include/catalog/index.h | 2 +- src/include/catalog/pg_constraint.h | 11 +-- src/include/commands/defrem.h | 2 +- src/include/nodes/parsenodes.h | 6 +- .../regress/expected/without_overlaps.out | 8 +-- src/test/regress/parallel_schedule | 4 +- 23 files changed, 148 insertions(+), 182 deletions(-) diff --git a/doc/src/sgml/catalogs.sgml b/doc/src/sgml/catalogs.sgml index 5412f2daa0..618a05ac89 100644 --- a/doc/src/sgml/catalogs.sgml +++ b/doc/src/sgml/catalogs.sgml @@ -2711,13 +2711,11 @@ <structname>pg_constraint</structname> Columns - contemporal bool + conwithoutoverlaps bool - This constraint is a application-time temporal constraint, - defined with WITHOUT OVERLAPS (for primary - key and unique constraints) or PERIOD (for - foreign keys). + This constraint is defined with WITHOUT OVERLAPS + (for primary keys and unique constraints). diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index ad5bf21453..a0bd2b8adc 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -78,8 +78,8 @@ [ CONSTRAINT constraint_name ] { CHECK ( expression ) [ NO INHERIT ] | NOT NULL column_name [ NO INHERIT ] | - UNIQUE [ NULLS [ NOT ] DISTINCT ] ( column_name [, ... ] [, temporal_interval WITHOUT OVERLAPS ] ) index_parameters | - PRIMARY KEY ( column_name [, ... ] [, temporal_interval WITHOUT OVERLAPS ] ) index_parameters | + UNIQUE [ NULLS [ NOT ] DISTINCT ] ( column_name [, ... ] [, column_name WITHOUT OVERLAPS ] ) index_parameters | + PRIMARY KEY ( column_name [, ... ] [, column_name WITHOUT OVERLAPS ] ) index_parameters | EXCLUDE [ USING index_method ] ( exclude_element WITH operator [, ... ] ) index_parameters [ WHERE ( predicate ) ] | FOREIGN KEY ( column_name [, ... ] ) REFERENCES reftable [ ( refcolumn [, ... ] ) ] [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ] [ ON DELETE column_name | ( expression ) } [ opclass ] [ ASC | DESC ] [ NULLS { FIRST | LAST } ] -temporal_interval in a PRIMARY KEY, UNIQUE, or FOREIGN KEY constraint is: - -range_column_name - referential_action in a FOREIGN KEY/REFERENCES constraint is: { NO ACTION | RESTRICT | CASCADE | SET NULL [ ( column_name [, ... ] ) ] | SET DEFAULT [ ( column_name [, ... ] ) ] } @@ -969,7 +965,7 @@ Parameters UNIQUE [ NULLS [ NOT ] DISTINCT ] (column constraint) - UNIQUE [ NULLS [ NOT ] DISTINCT ] ( column_name [, ... ] ) + UNIQUE [ NULLS [ NOT ] DISTINCT ] ( column_name [, ... ] [, column_name WITHOUT OVERLAPS ] ) INCLUDE ( column_name [, ...]) (table constraint) @@ -983,6 +979,26 @@ Parameters of these columns. + + If the WITHOUT OVERLAPS option is specified for the + last column, then that column is checked for overlaps instead of + equality. In that case, the other columns of the constraint will allow + duplicates so long as the duplicates don't overlap in the + WITHOUT OVERLAPS column. (This is sometimes called a + temporal key, if the column is a range of dates or timestamps, but + PostgreSQL allows ranges over any base type.) In effect, such a + constraint is enforced with an EXCLUDE constraint + rather than a UNIQUE constraint. So for example + UNIQUE (id, valid_at WITHOUT OVERLAPS) behaves like + EXCLUDE USING GIST (id WITH =, valid_at WITH + &&). The WITHOUT OVERLAPS column + must have a range type. The non-WITHOUT OVERLAPS + columns of the constraint can be any type that can be compared for + equality in a GiST index. By default only range types are supported, but + you can use other types by adding the + extension (which is the expected way to use this feature). + + For the purpose of a unique constraint, null values are not considered equal, unless NULLS NOT DISTINCT is @@ -1007,8 +1023,7 @@ Parameters Adding a unique constraint will automatically create a unique btree index on the column or group of columns used in the constraint. But if the constraint includes a WITHOUT OVERLAPS clause, - it will use a GiST index and behave like a temporal PRIMARY - KEY: preventing duplicates only in overlapping time periods. + it will use a GiST index. @@ -1026,8 +1041,7 @@ Parameters PRIMARY KEY (column constraint) - PRIMARY KEY ( column_name [, ... ] - [, temporal_interval WITHOUT OVERLAPS ] ) + PRIMARY KEY ( column_name [, ... ] [, column_name WITHOUT OVERLAPS ] ) INCLUDE ( column_name [, ...]) (table constraint) @@ -1060,9 +1074,10 @@ Parameters - Adding a PRIMARY KEY constraint will automatically - create a unique btree index (or GiST if temporal) on the column or group of - columns used in the constraint. + As with a UNIQUE constraint, adding a + PRIMARY KEY constraint will automatically create a + unique btree index, or GiST if WITHOUT OVERLAPS was + specified, on the column or group of columns used in the constraint. @@ -1075,31 +1090,6 @@ Parameters (e.g., DROP COLUMN) can cause cascaded constraint and index deletion. - - - A PRIMARY KEY with a WITHOUT OVERLAPS option - is a temporal primary key. - The WITHOUT OVERLAPS column - must be a range type or a PERIOD - and is used to constrain the record's applicability - to just that range/period (usually a range of dates or timestamps, - although Postgres allows a range/period over any base type). - - - - The non-WITHOUT OVERLAPS part(s) of the key can be any - type that can be compared for equality in a GiST index. By default - only range types are supported, but you can use other types by - adding the extension - (which is the expected way to use this feature). - These ordinary parts of the primary key do allow duplicates, - so long as the duplicates don't overlap in the - WITHOUT OVERLAPS column. - In effect a temporal PRIMARY KEY is enforced with an - EXCLUDE constraint rather than a UNIQUE - constraint. So for example PRIMARY KEY (id, valid_at WITHOUT OVERLAPS) - behaves like EXCLUDE USING GIST (id WITH =, valid_at WITH &&). - diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c index 3e9cc4bb10..f126d8e676 100644 --- a/src/backend/catalog/heap.c +++ b/src/backend/catalog/heap.c @@ -2140,7 +2140,7 @@ StoreRelCheck(Relation rel, const char *ccname, Node *expr, is_local, /* conislocal */ inhcount, /* coninhcount */ is_no_inherit, /* connoinherit */ - false, /* contemporal */ + false, /* conwithoutoverlaps */ is_internal); /* internally constructed? */ pfree(ccbin); @@ -2191,7 +2191,7 @@ StoreRelNotNull(Relation rel, const char *nnname, AttrNumber attnum, is_local, inhcount, is_no_inherit, - false, /* contemporal */ + false, /* conwithoutoverlaps */ false); return constrOid; } diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 2f1ec3b0ac..8444d768e5 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -254,8 +254,8 @@ index_check_primary_key(Relation heapRel, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("primary keys cannot be expressions"))); - /* System attributes are never null, so no need to check. */ - if (attnum <= 0) + /* System attributes are never null, so no need to check */ + if (attnum < 0) continue; atttuple = SearchSysCache2(ATTNUM, @@ -1326,7 +1326,7 @@ index_concurrently_create_copy(Relation heapRelation, Oid oldIndexId, Anum_pg_index_indoption); indcoloptions = (int2vector *) DatumGetPointer(colOptionDatum); - /* Fetch options of index if any */ + /* Fetch reloptions of index if any */ classTuple = SearchSysCache1(RELOID, ObjectIdGetDatum(oldIndexId)); if (!HeapTupleIsValid(classTuple)) elog(ERROR, "cache lookup failed for relation %u", oldIndexId); @@ -1895,7 +1895,7 @@ index_concurrently_set_dead(Oid heapId, Oid indexId) * INDEX_CONSTR_CREATE_UPDATE_INDEX: update the pg_index row * INDEX_CONSTR_CREATE_REMOVE_OLD_DEPS: remove existing dependencies * of index on table's columns - * INDEX_CONSTR_CREATE_TEMPORAL: constraint is for a temporal primary key + * INDEX_CONSTR_CREATE_WITHOUT_OVERLAPS: constraint uses WITHOUT OVERLAPS * allow_system_table_mods: allow table to be a system catalog * is_internal: index is constructed due to internal process */ @@ -1919,13 +1919,13 @@ index_constraint_create(Relation heapRelation, bool mark_as_primary; bool islocal; bool noinherit; - bool is_temporal; + bool is_without_overlaps; int inhcount; deferrable = (constr_flags & INDEX_CONSTR_CREATE_DEFERRABLE) != 0; initdeferred = (constr_flags & INDEX_CONSTR_CREATE_INIT_DEFERRED) != 0; mark_as_primary = (constr_flags & INDEX_CONSTR_CREATE_MARK_AS_PRIMARY) != 0; - is_temporal = (constr_flags & INDEX_CONSTR_CREATE_TEMPORAL) != 0; + is_without_overlaps = (constr_flags & INDEX_CONSTR_CREATE_WITHOUT_OVERLAPS) != 0; /* constraint creation support doesn't work while bootstrapping */ Assert(!IsBootstrapProcessingMode()); @@ -2002,7 +2002,7 @@ index_constraint_create(Relation heapRelation, islocal, inhcount, noinherit, - is_temporal, /* contemporal */ + is_without_overlaps, is_internal); /* diff --git a/src/backend/catalog/pg_constraint.c b/src/backend/catalog/pg_constraint.c index d5329ca8c9..ffd340a2e4 100644 --- a/src/backend/catalog/pg_constraint.c +++ b/src/backend/catalog/pg_constraint.c @@ -78,7 +78,7 @@ CreateConstraintEntry(const char *constraintName, bool conIsLocal, int conInhCount, bool conNoInherit, - bool conTemporal, + bool conWithoutOverlaps, bool is_internal) { Relation conDesc; @@ -194,7 +194,7 @@ CreateConstraintEntry(const char *constraintName, values[Anum_pg_constraint_conislocal - 1] = BoolGetDatum(conIsLocal); values[Anum_pg_constraint_coninhcount - 1] = Int16GetDatum(conInhCount); values[Anum_pg_constraint_connoinherit - 1] = BoolGetDatum(conNoInherit); - values[Anum_pg_constraint_contemporal - 1] = BoolGetDatum(conTemporal); + values[Anum_pg_constraint_conwithoutoverlaps - 1] = BoolGetDatum(conWithoutOverlaps); if (conkeyArray) values[Anum_pg_constraint_conkey - 1] = PointerGetDatum(conkeyArray); diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c index e9d1b17935..d56db81fa1 100644 --- a/src/backend/commands/indexcmds.c +++ b/src/backend/commands/indexcmds.c @@ -91,7 +91,7 @@ static void ComputeIndexAttrs(IndexInfo *indexInfo, Oid accessMethodId, bool amcanorder, bool isconstraint, - bool istemporal, + bool iswithoutoverlaps, Oid ddl_userid, int ddl_sec_context, int *ddl_save_nestlevel); @@ -149,7 +149,7 @@ typedef struct ReindexErrorInfo * to index on. * 'exclusionOpNames': list of names of exclusion-constraint operators, * or NIL if not an exclusion constraint. - * 'istemporal': true iff this index has a WITHOUT OVERLAPS clause. + * 'isWithoutOverlaps': true iff this index has a WITHOUT OVERLAPS clause. * * This is tailored to the needs of ALTER TABLE ALTER TYPE, which recreates * any indexes that depended on a changing column from their pg_get_indexdef @@ -180,7 +180,7 @@ CheckIndexCompatible(Oid oldId, const char *accessMethodName, const List *attributeList, const List *exclusionOpNames, - bool istemporal) + bool isWithoutOverlaps) { bool isconstraint; Oid *typeIds; @@ -255,7 +255,7 @@ CheckIndexCompatible(Oid oldId, coloptions, attributeList, exclusionOpNames, relationId, accessMethodName, accessMethodId, - amcanorder, isconstraint, istemporal, InvalidOid, + amcanorder, isconstraint, isWithoutOverlaps, InvalidOid, 0, NULL); /* Get the soon-obsolete pg_index tuple. */ @@ -689,7 +689,7 @@ DefineIndex(Oid tableId, * It has exclusion constraint behavior if it's an EXCLUDE constraint * or a temporal PRIMARY KEY/UNIQUE constraint */ - exclusion = stmt->excludeOpNames || stmt->istemporal; + exclusion = stmt->excludeOpNames || stmt->iswithoutoverlaps; /* Ensure that it makes sense to index this kind of relation */ switch (rel->rd_rel->relkind) @@ -859,7 +859,7 @@ DefineIndex(Oid tableId, pgstat_progress_update_param(PROGRESS_CREATEIDX_ACCESS_METHOD_OID, accessMethodId); - if (stmt->unique && !stmt->istemporal && !amRoutine->amcanunique) + if (stmt->unique && !stmt->iswithoutoverlaps && !amRoutine->amcanunique) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("access method \"%s\" does not support unique indexes", @@ -927,7 +927,7 @@ DefineIndex(Oid tableId, coloptions, allIndexParams, stmt->excludeOpNames, tableId, accessMethodName, accessMethodId, - amcanorder, stmt->isconstraint, stmt->istemporal, + amcanorder, stmt->isconstraint, stmt->iswithoutoverlaps, root_save_userid, root_save_sec_context, &root_save_nestlevel); @@ -955,8 +955,6 @@ DefineIndex(Oid tableId, if (stmt->primary) constraint_type = "PRIMARY KEY"; - else if (stmt->unique && stmt->istemporal) - constraint_type = "temporal UNIQUE"; else if (stmt->unique) constraint_type = "UNIQUE"; else if (stmt->excludeOpNames) @@ -1006,7 +1004,7 @@ DefineIndex(Oid tableId, * we have an exclusion constraint (or a temporal PK), it already * knows the operators, so we don't have to infer them. */ - if (stmt->unique && !stmt->istemporal && accessMethodId != BTREE_AM_OID) + if (stmt->unique && !stmt->iswithoutoverlaps && accessMethodId != BTREE_AM_OID) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("cannot match partition key to an index using access method \"%s\"", @@ -1039,7 +1037,7 @@ DefineIndex(Oid tableId, { Oid idx_eqop = InvalidOid; - if (stmt->unique && !stmt->istemporal) + if (stmt->unique && !stmt->iswithoutoverlaps) idx_eqop = get_opfamily_member(idx_opfamily, idx_opcintype, idx_opcintype, @@ -1197,8 +1195,8 @@ DefineIndex(Oid tableId, constr_flags |= INDEX_CONSTR_CREATE_DEFERRABLE; if (stmt->initdeferred) constr_flags |= INDEX_CONSTR_CREATE_INIT_DEFERRED; - if (stmt->istemporal) - constr_flags |= INDEX_CONSTR_CREATE_TEMPORAL; + if (stmt->iswithoutoverlaps) + constr_flags |= INDEX_CONSTR_CREATE_WITHOUT_OVERLAPS; indexRelationId = index_create(rel, indexRelationName, indexRelationId, parentIndexId, @@ -1975,7 +1973,7 @@ ComputeIndexAttrs(IndexInfo *indexInfo, Oid accessMethodId, bool amcanorder, bool isconstraint, - bool istemporal, + bool iswithoutoverlaps, Oid ddl_userid, int ddl_sec_context, int *ddl_save_nestlevel) @@ -2000,7 +1998,7 @@ ComputeIndexAttrs(IndexInfo *indexInfo, nextExclOp = NULL; /* exclusionOpNames can be non-NIL if we are creating a partition */ - if (istemporal && exclusionOpNames == NIL) + if (iswithoutoverlaps && exclusionOpNames == NIL) { indexInfo->ii_ExclusionOps = palloc_array(Oid, nkeycols); indexInfo->ii_ExclusionProcs = palloc_array(Oid, nkeycols); @@ -2283,7 +2281,7 @@ ComputeIndexAttrs(IndexInfo *indexInfo, indexInfo->ii_ExclusionStrats[attn] = strat; nextExclOp = lnext(exclusionOpNames, nextExclOp); } - else if (istemporal) + else if (iswithoutoverlaps) { int strat; Oid opid; diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 4cc645282a..04527a3540 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -208,7 +208,6 @@ typedef struct NewConstraint Oid refrelid; /* PK rel, if FOREIGN */ Oid refindid; /* OID of PK's index, if FOREIGN */ Oid conid; /* OID of pg_constraint entry, if FOREIGN */ - bool contemporal; /* Whether the new constraint is temporal */ Node *qual; /* Check expr or CONSTR_FOREIGN Constraint */ ExprState *qualstate; /* Execution state for CHECK expr */ } NewConstraint; @@ -10094,7 +10093,7 @@ addFkRecurseReferenced(List **wqueue, Constraint *fkconstraint, Relation rel, conislocal, /* islocal */ coninhcount, /* inhcount */ connoinherit, /* conNoInherit */ - false, /* conTemporal */ + false, /* conWithoutOverlaps */ false); /* is_internal */ ObjectAddressSet(address, ConstraintRelationId, constrOid); @@ -10393,7 +10392,7 @@ addFkRecurseReferencing(List **wqueue, Constraint *fkconstraint, Relation rel, false, 1, false, - false, /* conTemporal */ + false, /* conWithoutOverlaps */ false); /* @@ -10899,7 +10898,7 @@ CloneFkReferencing(List **wqueue, Relation parentRel, Relation partRel) false, /* islocal */ 1, /* inhcount */ false, /* conNoInherit */ - false, /* conTemporal */ + false, /* conWithoutOverlaps */ true); /* Set up partition dependencies for the new constraint */ @@ -11574,7 +11573,6 @@ ATExecValidateConstraint(List **wqueue, Relation rel, char *constrName, newcon->refrelid = con->confrelid; newcon->refindid = con->conindid; newcon->conid = con->oid; - newcon->contemporal = con->contemporal; newcon->qual = (Node *) fkconstraint; /* Find or create work queue entry for this table */ @@ -11741,12 +11739,10 @@ transformColumnNameList(Oid relId, List *colList, * * Look up the names, attnums, and types of the primary key attributes * for the pkrel. Also return the index OID and index opclasses of the - * index supporting the primary key. If this is a temporal primary key, - * also set the WITHOUT OVERLAPS attribute name, attnum, and atttypid. + * index supporting the primary key. * * All parameters except pkrel are output parameters. Also, the function - * return value is the number of attributes in the primary key, - * not including the WITHOUT OVERLAPS if any. + * return value is the number of attributes in the primary key. * * Used when the column list in the REFERENCES specification is omitted. */ @@ -14292,7 +14288,7 @@ TryReuseIndex(Oid oldId, IndexStmt *stmt) stmt->accessMethod, stmt->indexParams, stmt->excludeOpNames, - stmt->istemporal)) + stmt->iswithoutoverlaps)) { Relation irel = index_open(oldId, NoLock); diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c index 0577b60415..a10a42b97f 100644 --- a/src/backend/commands/trigger.c +++ b/src/backend/commands/trigger.c @@ -841,7 +841,7 @@ CreateTriggerFiringOn(CreateTrigStmt *stmt, const char *queryString, true, /* islocal */ 0, /* inhcount */ true, /* noinherit */ - false, /* contemporal */ + false, /* conwithoutoverlaps */ isInternal); /* is_internal */ } diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c index 1773556053..2470019818 100644 --- a/src/backend/commands/typecmds.c +++ b/src/backend/commands/typecmds.c @@ -3544,7 +3544,7 @@ domainAddConstraint(Oid domainOid, Oid domainNamespace, Oid baseTypeOid, true, /* is local */ 0, /* inhcount */ false, /* connoinherit */ - false, /* contemporal */ + false, /* conwithoutoverlaps */ false); /* is_internal */ if (constrAddr) ObjectAddressSet(*constrAddr, ConstraintRelationId, ccoid); diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 14d4e24fcc..ff4add6225 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -523,13 +523,12 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); %type TableElement TypedTableElement ConstraintElem TableFuncElement %type columnDef columnOptions %type def_elem reloption_elem old_aggr_elem operator_def_elem -%type def_arg columnElem without_overlaps_clause - where_clause where_or_current_clause +%type def_arg columnElem where_clause where_or_current_clause a_expr b_expr c_expr AexprConst indirection_el opt_slice_bound columnref in_expr having_clause func_table xmltable array_expr OptWhereClause operator_def_arg %type rowsfrom_item rowsfrom_list opt_col_def_list -%type opt_ordinality +%type opt_ordinality opt_without_overlaps %type ExclusionConstraintList ExclusionConstraintElem %type func_arg_list func_arg_list_opt %type func_arg_expr @@ -4105,7 +4104,7 @@ ConstraintElem: n->initially_valid = true; $$ = (Node *) n; } - | UNIQUE opt_unique_null_treatment '(' columnList without_overlaps_clause ')' opt_c_include opt_definition OptConsTableSpace + | UNIQUE opt_unique_null_treatment '(' columnList opt_without_overlaps ')' opt_c_include opt_definition OptConsTableSpace ConstraintAttributeSpec { Constraint *n = makeNode(Constraint); @@ -4140,7 +4139,7 @@ ConstraintElem: NULL, yyscanner); $$ = (Node *) n; } - | PRIMARY KEY '(' columnList without_overlaps_clause ')' opt_c_include opt_definition OptConsTableSpace + | PRIMARY KEY '(' columnList opt_without_overlaps ')' opt_c_include opt_definition OptConsTableSpace ConstraintAttributeSpec { Constraint *n = makeNode(Constraint); @@ -4221,6 +4220,11 @@ opt_no_inherit: NO INHERIT { $$ = true; } | /* EMPTY */ { $$ = false; } ; +opt_without_overlaps: + WITHOUT OVERLAPS { $$ = true; } + | /*EMPTY*/ { $$ = false; } + ; + opt_column_list: '(' columnList ')' { $$ = $2; } | /*EMPTY*/ { $$ = NIL; } @@ -4231,11 +4235,6 @@ columnList: | columnList ',' columnElem { $$ = lappend($1, $3); } ; -without_overlaps_clause: - ',' columnElem WITHOUT OVERLAPS { $$ = $2; } - | /*EMPTY*/ { $$ = NULL; } - ; - columnElem: ColId { $$ = (Node *) makeString($1); diff --git a/src/backend/parser/parse_utilcmd.c b/src/backend/parser/parse_utilcmd.c index f4705ecc2b..547e3058b9 100644 --- a/src/backend/parser/parse_utilcmd.c +++ b/src/backend/parser/parse_utilcmd.c @@ -124,7 +124,7 @@ static List *get_opclass(Oid opclass, Oid actual_datatype); static void transformIndexConstraints(CreateStmtContext *cxt); static IndexStmt *transformIndexConstraint(Constraint *constraint, CreateStmtContext *cxt); -static void validateWithoutOverlaps(CreateStmtContext *cxt, char *colname, int location); +static void validateWithoutOverlaps(CreateStmtContext *cxt, const char *colname, int location); static void transformExtendedStatistics(CreateStmtContext *cxt); static void transformFKConstraints(CreateStmtContext *cxt, bool skipValidation, @@ -1717,7 +1717,7 @@ generateClonedIndexStmt(RangeVar *heapRel, Relation source_idx, index->unique = idxrec->indisunique; index->nulls_not_distinct = idxrec->indnullsnotdistinct; index->primary = idxrec->indisprimary; - index->istemporal = (idxrec->indisprimary || idxrec->indisunique) && idxrec->indisexclusion; + index->iswithoutoverlaps = (idxrec->indisprimary || idxrec->indisunique) && idxrec->indisexclusion; index->transformed = true; /* don't need transformIndexStmt */ index->concurrent = false; index->if_not_exists = false; @@ -1768,7 +1768,7 @@ generateClonedIndexStmt(RangeVar *heapRel, Relation source_idx, int i; Assert(conrec->contype == CONSTRAINT_EXCLUSION || - (index->istemporal && + (index->iswithoutoverlaps && (conrec->contype == CONSTRAINT_PRIMARY || conrec->contype == CONSTRAINT_UNIQUE))); /* Extract operator OIDs from the pg_constraint tuple */ datum = SysCacheGetAttrNotNull(CONSTROID, ht_constr, @@ -2309,7 +2309,7 @@ transformIndexConstraint(Constraint *constraint, CreateStmtContext *cxt) } index->nulls_not_distinct = constraint->nulls_not_distinct; index->isconstraint = true; - index->istemporal = constraint->without_overlaps != NULL; + index->iswithoutoverlaps = constraint->without_overlaps; index->deferrable = constraint->deferrable; index->initdeferred = constraint->initdeferred; @@ -2555,6 +2555,10 @@ transformIndexConstraint(Constraint *constraint, CreateStmtContext *cxt) ListCell *columns; IndexElem *iparam; + /* handled below */ + if (constraint->without_overlaps && lc == list_last_cell(constraint->keys)) + break; + /* Make sure referenced column exists. */ foreach(columns, cxt->columns) { @@ -2688,11 +2692,21 @@ transformIndexConstraint(Constraint *constraint, CreateStmtContext *cxt) * Anything in without_overlaps should be included, * but with the overlaps operator (&&) instead of equality. */ - if (constraint->without_overlaps != NULL) + if (constraint->without_overlaps) { - char *without_overlaps_str = strVal(constraint->without_overlaps); + char *without_overlaps_str = strVal(llast(constraint->keys)); IndexElem *iparam = makeNode(IndexElem); + /* + * This enforces that there is at last one equality column besides + * the WITHOUT OVERLAPS columns. This is per SQL standard. XXX + * Do we need this? + */ + if (list_length(constraint->keys) < 2) + ereport(ERROR, + errcode(ERRCODE_SYNTAX_ERROR), + errmsg("constraint using WITHOUT OVERLAPS needs at least two columns")); + /* * Iterate through the table's columns * (like just a little bit above). @@ -2855,7 +2869,7 @@ transformIndexConstraint(Constraint *constraint, CreateStmtContext *cxt) * and the new ones. Raises an error if we can't find one or it's not a range type. */ static void -validateWithoutOverlaps(CreateStmtContext *cxt, char *colname, int location) +validateWithoutOverlaps(CreateStmtContext *cxt, const char *colname, int location) { /* Check the new columns first in case their type is changing. */ diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index f2da27eb50..25ac0ad1bc 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -338,7 +338,7 @@ static char *deparse_expression_pretty(Node *expr, List *dpcontext, static char *pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn); static char *pg_get_triggerdef_worker(Oid trigid, bool pretty); -static int decompile_column_index_array(Datum column_index_array, Oid relId, Oid indexId, +static int decompile_column_index_array(Datum column_index_array, Oid relId, bool withoutOverlaps, StringInfo buf); static char *pg_get_ruledef_worker(Oid ruleoid, int prettyFlags); static char *pg_get_indexdef_worker(Oid indexrelid, int colno, @@ -2247,7 +2247,7 @@ pg_get_constraintdef_worker(Oid constraintId, bool fullCommand, val = SysCacheGetAttrNotNull(CONSTROID, tup, Anum_pg_constraint_conkey); - decompile_column_index_array(val, conForm->conrelid, conForm->conindid, false, &buf); + decompile_column_index_array(val, conForm->conrelid, false, &buf); /* add foreign relation name */ appendStringInfo(&buf, ") REFERENCES %s(", @@ -2258,7 +2258,7 @@ pg_get_constraintdef_worker(Oid constraintId, bool fullCommand, val = SysCacheGetAttrNotNull(CONSTROID, tup, Anum_pg_constraint_confkey); - decompile_column_index_array(val, conForm->confrelid, conForm->conindid, false, &buf); + decompile_column_index_array(val, conForm->confrelid, false, &buf); appendStringInfoChar(&buf, ')'); @@ -2344,7 +2344,7 @@ pg_get_constraintdef_worker(Oid constraintId, bool fullCommand, if (!isnull) { appendStringInfoString(&buf, " ("); - decompile_column_index_array(val, conForm->conrelid, InvalidOid, false, &buf); + decompile_column_index_array(val, conForm->conrelid, false, &buf); appendStringInfoChar(&buf, ')'); } @@ -2357,7 +2357,6 @@ pg_get_constraintdef_worker(Oid constraintId, bool fullCommand, Oid indexId; int keyatts; HeapTuple indtup; - bool isnull; /* Start off the constraint definition */ if (conForm->contype == CONSTRAINT_PRIMARY) @@ -2380,14 +2379,7 @@ pg_get_constraintdef_worker(Oid constraintId, bool fullCommand, val = SysCacheGetAttrNotNull(CONSTROID, tup, Anum_pg_constraint_conkey); - /* - * If it has exclusion-style operator OIDs - * then it uses WITHOUT OVERLAPS. - */ - indexId = conForm->conindid; - SysCacheGetAttr(CONSTROID, tup, - Anum_pg_constraint_conexclop, &isnull); - keyatts = decompile_column_index_array(val, conForm->conrelid, indexId, !isnull, &buf); + keyatts = decompile_column_index_array(val, conForm->conrelid, conForm->conwithoutoverlaps, &buf); appendStringInfoChar(&buf, ')'); @@ -2582,7 +2574,7 @@ pg_get_constraintdef_worker(Oid constraintId, bool fullCommand, * of keys. */ static int -decompile_column_index_array(Datum column_index_array, Oid relId, Oid indexId, +decompile_column_index_array(Datum column_index_array, Oid relId, bool withoutOverlaps, StringInfo buf) { Datum *keys; @@ -2596,17 +2588,16 @@ decompile_column_index_array(Datum column_index_array, Oid relId, Oid indexId, for (j = 0; j < nKeys; j++) { char *colName; - int colid = DatumGetInt16(keys[j]); - colName = get_attname(relId, colid, false); + colName = get_attname(relId, DatumGetInt16(keys[j]), false); if (j == 0) appendStringInfoString(buf, quote_identifier(colName)); - else if (withoutOverlaps && j == nKeys - 1) - appendStringInfo(buf, ", %s WITHOUT OVERLAPS", quote_identifier(colName)); else appendStringInfo(buf, ", %s", quote_identifier(colName)); } + if (withoutOverlaps) + appendStringInfoString(buf, " WITHOUT OVERLAPS"); return nKeys; } diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c index 45810ac35f..f341c5c370 100644 --- a/src/backend/utils/cache/relcache.c +++ b/src/backend/utils/cache/relcache.c @@ -5568,12 +5568,14 @@ RelationGetIdentityKeyBitmap(Relation relation) /* * RelationGetExclusionInfo -- get info about index's exclusion constraint * - * This should be called only for an index that is known to have an - * associated exclusion constraint or temporal primary key/unique - * constraint. It returns arrays (palloc'd in caller's context) - * of the exclusion operator OIDs, their underlying functions' - * OIDs, and their strategy numbers in the index's opclasses. We cache - * all this information since it requires a fair amount of work to get. + * This should be called only for an index that is known to have an associated + * exclusion constraint or primary key/unique constraint using WITHOUT + * OVERLAPS. + + * It returns arrays (palloc'd in caller's context) of the exclusion operator + * OIDs, their underlying functions' OIDs, and their strategy numbers in the + * index's opclasses. We cache all this information since it requires a fair + * amount of work to get. */ void RelationGetExclusionInfo(Relation indexRelation, @@ -5638,7 +5640,7 @@ RelationGetExclusionInfo(Relation indexRelation, /* We want the exclusion constraint owning the index */ if ((conform->contype != CONSTRAINT_EXCLUSION && - !(conform->contemporal && ( + !(conform->conwithoutoverlaps && ( conform->contype == CONSTRAINT_PRIMARY || conform->contype == CONSTRAINT_UNIQUE))) || conform->conindid != RelationGetRelid(indexRelation)) diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index 54a15cf64a..c89b6da8b2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -6983,14 +6983,14 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) i_conname, i_condeferrable, i_condeferred, + i_conwithoutoverlaps, i_contableoid, i_conoid, i_condef, i_tablespace, i_indreloptions, i_indstatcols, - i_indstatvals, - i_withoutoverlaps; + i_indstatvals; /* * We want to perform just one query against pg_index. However, we @@ -7072,10 +7072,10 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) if (fout->remoteVersion >= 170000) appendPQExpBufferStr(query, - "c.conexclop IS NOT NULL AS withoutoverlaps "); + "c.conwithoutoverlaps "); else appendPQExpBufferStr(query, - "null AS withoutoverlaps "); + "NULL AS conwithoutoverlaps "); /* * The point of the messy-looking outer join is to find a constraint that @@ -7143,6 +7143,7 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) i_conname = PQfnumber(res, "conname"); i_condeferrable = PQfnumber(res, "condeferrable"); i_condeferred = PQfnumber(res, "condeferred"); + i_conwithoutoverlaps = PQfnumber(res, "conwithoutoverlaps"); i_contableoid = PQfnumber(res, "contableoid"); i_conoid = PQfnumber(res, "conoid"); i_condef = PQfnumber(res, "condef"); @@ -7150,7 +7151,6 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) i_indreloptions = PQfnumber(res, "indreloptions"); i_indstatcols = PQfnumber(res, "indstatcols"); i_indstatvals = PQfnumber(res, "indstatvals"); - i_withoutoverlaps = PQfnumber(res, "withoutoverlaps"); indxinfo = (IndxInfo *) pg_malloc(ntups * sizeof(IndxInfo)); @@ -7251,9 +7251,9 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) constrinfo->conindex = indxinfo[j].dobj.dumpId; constrinfo->condeferrable = *(PQgetvalue(res, j, i_condeferrable)) == 't'; constrinfo->condeferred = *(PQgetvalue(res, j, i_condeferred)) == 't'; + constrinfo->conwithoutoverlaps = *(PQgetvalue(res, j, i_conwithoutoverlaps)) == 't'; constrinfo->conislocal = true; constrinfo->separate = true; - constrinfo->withoutoverlaps = *(PQgetvalue(res, j, i_withoutoverlaps)) == 't'; indxinfo[j].indexconstraint = constrinfo->dobj.dumpId; } @@ -16949,23 +16949,12 @@ dumpConstraint(Archive *fout, const ConstraintInfo *coninfo) break; attname = getAttrName(indkey, tbinfo); - if (k == 0) - { - appendPQExpBuffer(q, "%s", - fmtId(attname)); - } - else if (k == indxinfo->indnkeyattrs - 1 && - coninfo->withoutoverlaps) - { - appendPQExpBuffer(q, ", %s WITHOUT OVERLAPS", - fmtId(attname)); - } - else - { - appendPQExpBuffer(q, ", %s", - fmtId(attname)); - } + appendPQExpBuffer(q, "%s%s", + (k == 0) ? "" : ", ", + fmtId(attname)); } + if (coninfo->conwithoutoverlaps) + appendPQExpBufferStr(q, " WITHOUT OVERLAPS"); if (indxinfo->indnkeyattrs < indxinfo->indnattrs) appendPQExpBufferStr(q, ") INCLUDE ("); diff --git a/src/bin/pg_dump/pg_dump.h b/src/bin/pg_dump/pg_dump.h index ad7cc85b8c..cbf4b5e179 100644 --- a/src/bin/pg_dump/pg_dump.h +++ b/src/bin/pg_dump/pg_dump.h @@ -487,9 +487,9 @@ typedef struct _constraintInfo DumpId conindex; /* identifies associated index if any */ bool condeferrable; /* true if constraint is DEFERRABLE */ bool condeferred; /* true if constraint is INITIALLY DEFERRED */ + bool conwithoutoverlaps; /* true if the constraint is WITHOUT OVERLAPS */ bool conislocal; /* true if constraint has local definition */ bool separate; /* true if must dump as separate item */ - bool withoutoverlaps; /* true if the last elem is WITHOUT OVERLAPS */ } ConstraintInfo; typedef struct _procLangInfo diff --git a/src/bin/pg_dump/t/002_pg_dump.pl b/src/bin/pg_dump/t/002_pg_dump.pl index eb35d5ef60..8584a4b406 100644 --- a/src/bin/pg_dump/t/002_pg_dump.pl +++ b/src/bin/pg_dump/t/002_pg_dump.pl @@ -1015,12 +1015,11 @@ }, }, - 'ALTER TABLE ONLY test_table_tpk ADD CONSTRAINT ... PRIMARY KEY (..., ... WITHOUT OVERLAPS)' => { + 'CONSTRAINT PRIMARY KEY / WITHOUT OVERLAPS' => { create_sql => 'CREATE TABLE dump_test.test_table_tpk ( col1 int4range, col2 tstzrange, - CONSTRAINT test_table_tpk_pkey PRIMARY KEY - (col1, col2 WITHOUT OVERLAPS));', + CONSTRAINT test_table_tpk_pkey PRIMARY KEY (col1, col2 WITHOUT OVERLAPS));', regexp => qr/^ \QALTER TABLE ONLY dump_test.test_table_tpk\E \n^\s+ \QADD CONSTRAINT test_table_tpk_pkey PRIMARY KEY (col1, col2 WITHOUT OVERLAPS);\E @@ -1029,21 +1028,18 @@ %full_runs, %dump_test_schema_runs, section_post_data => 1, - exclude_test_table => 1, }, unlike => { - only_dump_test_table => 1, exclude_dump_test_schema => 1, only_dump_measurement => 1, }, }, - 'ALTER TABLE ONLY test_table_tuq ADD CONSTRAINT ... UNIQUE (..., ... WITHOUT OVERLAPS)' => { + 'CONSTRAINT UNIQUE / WITHOUT OVERLAPS' => { create_sql => 'CREATE TABLE dump_test.test_table_tuq ( col1 int4range, col2 tstzrange, - CONSTRAINT test_table_tuq_uq UNIQUE - (col1, col2 WITHOUT OVERLAPS));', + CONSTRAINT test_table_tuq_uq UNIQUE (col1, col2 WITHOUT OVERLAPS));', regexp => qr/^ \QALTER TABLE ONLY dump_test.test_table_tuq\E \n^\s+ \QADD CONSTRAINT test_table_tuq_uq UNIQUE (col1, col2 WITHOUT OVERLAPS);\E @@ -1052,10 +1048,8 @@ %full_runs, %dump_test_schema_runs, section_post_data => 1, - exclude_test_table => 1, }, unlike => { - only_dump_test_table => 1, exclude_dump_test_schema => 1, only_dump_measurement => 1, }, diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c index 4fbfc07460..135585411a 100644 --- a/src/bin/psql/describe.c +++ b/src/bin/psql/describe.c @@ -2384,10 +2384,10 @@ describeOneTableDetails(const char *schemaname, else appendPQExpBufferStr(&buf, ", false AS indisreplident"); appendPQExpBufferStr(&buf, ", c2.reltablespace"); - if (pset.sversion >= 160000) - appendPQExpBufferStr(&buf, ", con.contemporal"); + if (pset.sversion >= 170000) + appendPQExpBufferStr(&buf, ", con.conwithoutoverlaps"); else - appendPQExpBufferStr(&buf, ", false AS contemporal"); + appendPQExpBufferStr(&buf, ", false AS conwithoutoverlaps"); appendPQExpBuffer(&buf, "\nFROM pg_catalog.pg_class c, pg_catalog.pg_class c2, pg_catalog.pg_index i\n" " LEFT JOIN pg_catalog.pg_constraint con ON (conrelid = i.indrelid AND conindid = i.indexrelid AND contype IN ('p','u','x'))\n" @@ -2410,8 +2410,8 @@ describeOneTableDetails(const char *schemaname, PQgetvalue(result, i, 0)); /* - * If exclusion constraint or temporal PK/UNIQUE constraint, - * print the constraintdef + * If exclusion constraint or PK/UNIQUE constraint WITHOUT + * OVERLAPS, print the constraintdef */ if (strcmp(PQgetvalue(result, i, 7), "x") == 0 || strcmp(PQgetvalue(result, i, 12), "t") == 0) diff --git a/src/include/catalog/index.h b/src/include/catalog/index.h index 1a858c3897..0fccff9c05 100644 --- a/src/include/catalog/index.h +++ b/src/include/catalog/index.h @@ -92,7 +92,7 @@ extern Oid index_create(Relation heapRelation, #define INDEX_CONSTR_CREATE_INIT_DEFERRED (1 << 2) #define INDEX_CONSTR_CREATE_UPDATE_INDEX (1 << 3) #define INDEX_CONSTR_CREATE_REMOVE_OLD_DEPS (1 << 4) -#define INDEX_CONSTR_CREATE_TEMPORAL (1 << 5) +#define INDEX_CONSTR_CREATE_WITHOUT_OVERLAPS (1 << 5) extern Oid index_concurrently_create_copy(Relation heapRelation, Oid oldIndexId, diff --git a/src/include/catalog/pg_constraint.h b/src/include/catalog/pg_constraint.h index 98a560741d..c17b1e9d31 100644 --- a/src/include/catalog/pg_constraint.h +++ b/src/include/catalog/pg_constraint.h @@ -108,10 +108,10 @@ CATALOG(pg_constraint,2606,ConstraintRelationId) bool connoinherit; /* - * For primary and foreign keys, signifies the last column is a range - * and should use overlaps instead of equals. + * For primary keys and unique constraints, signifies the last column uses + * overlaps instead of equals. */ - bool contemporal; + bool conwithoutoverlaps; #ifdef CATALOG_VARLEN /* variable-length fields start here */ @@ -152,7 +152,8 @@ CATALOG(pg_constraint,2606,ConstraintRelationId) /* * If an exclusion constraint, the OIDs of the exclusion operators for - * each column of the constraint. Also set for temporal primary keys. + * each column of the constraint. Also set for unique constraints/primary + * keys using WITHOUT OVERLAPS. */ Oid conexclop[1] BKI_LOOKUP(pg_operator); @@ -242,7 +243,7 @@ extern Oid CreateConstraintEntry(const char *constraintName, bool conIsLocal, int conInhCount, bool conNoInherit, - bool conTemporal, + bool conWithoutOverlaps, bool is_internal); extern bool ConstraintNameIsUsed(ConstraintCategory conCat, Oid objId, diff --git a/src/include/commands/defrem.h b/src/include/commands/defrem.h index f10886f6ca..25f55c181b 100644 --- a/src/include/commands/defrem.h +++ b/src/include/commands/defrem.h @@ -45,7 +45,7 @@ extern bool CheckIndexCompatible(Oid oldId, const char *accessMethodName, const List *attributeList, const List *exclusionOpNames, - bool istemporal); + bool isWithoutOverlaps); extern Oid GetDefaultOpClass(Oid type_id, Oid am_id); extern Oid ResolveOpClass(const List *opclass, Oid attrType, const char *accessMethodName, Oid accessMethodId); diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index ff65db2db1..098990dd16 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -2589,6 +2589,7 @@ typedef struct Constraint bool nulls_not_distinct; /* null treatment for UNIQUE constraints */ List *keys; /* String nodes naming referenced key * column(s); also used for NOT NULL */ + bool without_overlaps; /* WITHOUT OVERLAPS specified */ List *including; /* String nodes naming referenced nonkey * column(s) */ @@ -2617,9 +2618,6 @@ typedef struct Constraint Oid old_pktable_oid; /* pg_constraint.confrelid of my former * self */ - /* Fields used for temporal PRIMARY KEY and FOREIGN KEY constraints: */ - Node *without_overlaps; /* String node naming range column */ - /* Fields used for constraints that allow a NOT VALID specification */ bool skip_validation; /* skip validation of existing rows? */ bool initially_valid; /* mark the new constraint as valid? */ @@ -3221,7 +3219,7 @@ typedef struct IndexStmt bool nulls_not_distinct; /* null treatment for UNIQUE constraints */ bool primary; /* is index a primary key? */ bool isconstraint; /* is it for a pkey/unique constraint? */ - bool istemporal; /* is it for a temporal pkey? */ + bool iswithoutoverlaps; /* is the constraint WITHOUT OVERLAPS? */ bool deferrable; /* is the constraint DEFERRABLE? */ bool initdeferred; /* is the constraint INITIALLY DEFERRED? */ bool transformed; /* true when transformIndexStmt is finished */ diff --git a/src/test/regress/expected/without_overlaps.out b/src/test/regress/expected/without_overlaps.out index 36aebc452f..e565490a38 100644 --- a/src/test/regress/expected/without_overlaps.out +++ b/src/test/regress/expected/without_overlaps.out @@ -11,9 +11,7 @@ CREATE TABLE temporal_rng ( valid_at tsrange, CONSTRAINT temporal_rng_pk PRIMARY KEY (valid_at WITHOUT OVERLAPS) ); -ERROR: syntax error at or near "WITHOUT" -LINE 3: CONSTRAINT temporal_rng_pk PRIMARY KEY (valid_at WITHOUT OV... - ^ +ERROR: constraint using WITHOUT OVERLAPS needs at least two columns -- PK with a range column/PERIOD that isn't there: CREATE TABLE temporal_rng ( id INTEGER, @@ -106,9 +104,7 @@ CREATE TABLE temporal_rng3 ( valid_at tsrange, CONSTRAINT temporal_rng3_uq UNIQUE (valid_at WITHOUT OVERLAPS) ); -ERROR: syntax error at or near "WITHOUT" -LINE 3: CONSTRAINT temporal_rng3_uq UNIQUE (valid_at WITHOUT OVERLA... - ^ +ERROR: constraint using WITHOUT OVERLAPS needs at least two columns -- UNIQUE with a range column/PERIOD that isn't there: CREATE TABLE temporal_rng3 ( id INTEGER, diff --git a/src/test/regress/parallel_schedule b/src/test/regress/parallel_schedule index 16683148d2..b08aaae44b 100644 --- a/src/test/regress/parallel_schedule +++ b/src/test/regress/parallel_schedule @@ -28,7 +28,7 @@ test: strings md5 numerology point lseg line box path polygon circle date time t # geometry depends on point, lseg, line, box, path, polygon, circle # horology depends on date, time, timetz, timestamp, timestamptz, interval # ---------- -test: geometry horology tstypes regex type_sanity opr_sanity misc_sanity comments expressions unicode xid mvcc without_overlaps +test: geometry horology tstypes regex type_sanity opr_sanity misc_sanity comments expressions unicode xid mvcc # ---------- # Load huge amounts of data @@ -78,7 +78,7 @@ test: brin_bloom brin_multi # psql depends on create_am # amutils depends on geometry, create_index_spgist, hash_index, brin # ---------- -test: create_table_like alter_generic alter_operator misc async dbsize merge misc_functions sysviews tsrf tid tidscan tidrangescan collate.icu.utf8 incremental_sort create_role +test: create_table_like alter_generic alter_operator misc async dbsize merge misc_functions sysviews tsrf tid tidscan tidrangescan collate.icu.utf8 incremental_sort create_role without_overlaps # collate.*.utf8 tests cannot be run in parallel with each other test: rules psql psql_crosstab amutils stats_ext collate.linux.utf8 collate.windows.win1252 -- 2.42.0