create-table-like-comment-fix.patch
text/x-patch
Filename: create-table-like-comment-fix.patch
Type: text/x-patch
Part: 0
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: unified
| File | + | − |
|---|---|---|
| src/backend/bootstrap/bootparse.y | 0 | 0 |
| src/backend/commands/indexcmds.c | 0 | 0 |
| src/backend/commands/tablecmds.c | 0 | 0 |
| src/backend/nodes/copyfuncs.c | 0 | 0 |
| src/backend/nodes/equalfuncs.c | 0 | 0 |
| src/backend/nodes/outfuncs.c | 0 | 0 |
| src/backend/parser/gram.y | 0 | 0 |
| src/backend/parser/parse_utilcmd.c | 0 | 0 |
| src/backend/tcop/utility.c | 0 | 0 |
| src/include/commands/defrem.h | 0 | 0 |
| src/include/nodes/parsenodes.h | 0 | 0 |
diff --git a/src/backend/bootstrap/bootparse.y b/src/backend/bootstrap/bootparse.y
index 18f0add852e7832739e3877811e385abcb540fab..ec634f1660e0be883b451abbb380d6dc30e69b93 100644
*** a/src/backend/bootstrap/bootparse.y
--- b/src/backend/bootstrap/bootparse.y
*************** Boot_InsertStmt:
*** 279,296 ****
Boot_DeclareIndexStmt:
XDECLARE INDEX boot_ident oidspec ON boot_ident USING boot_ident LPAREN boot_index_params RPAREN
{
do_start();
! DefineIndex(makeRangeVar(NULL, $6, -1),
! $3,
$4,
! InvalidOid,
! $8,
! NULL,
! $10,
! NULL, NIL, NIL,
! false, false, false, false, false,
! false, false, true, false, false);
do_end();
}
;
--- 279,312 ----
Boot_DeclareIndexStmt:
XDECLARE INDEX boot_ident oidspec ON boot_ident USING boot_ident LPAREN boot_index_params RPAREN
{
+ IndexStmt *stmt = makeNode(IndexStmt);
+
do_start();
! stmt->idxname = $3;
! stmt->relation = makeRangeVar(NULL, $6, -1);
! stmt->accessMethod = $8;
! stmt->tableSpace = NULL;
! stmt->indexParams = $10;
! stmt->options = NIL;
! stmt->whereClause = NULL;
! stmt->excludeOpNames = NIL;
! stmt->idxcomment = NULL;
! stmt->indexOid = InvalidOid;
! stmt->oldNode = InvalidOid;
! stmt->unique = false;
! stmt->primary = false;
! stmt->isconstraint = false;
! stmt->deferrable = false;
! stmt->initdeferred = false;
! stmt->concurrent = false;
!
! DefineIndex(stmt,
$4,
! false,
! false,
! true, /* skip_build */
! false);
do_end();
}
;
*************** Boot_DeclareIndexStmt:
*** 298,315 ****
Boot_DeclareUniqueIndexStmt:
XDECLARE UNIQUE INDEX boot_ident oidspec ON boot_ident USING boot_ident LPAREN boot_index_params RPAREN
{
do_start();
! DefineIndex(makeRangeVar(NULL, $7, -1),
! $4,
$5,
! InvalidOid,
! $9,
! NULL,
! $11,
! NULL, NIL, NIL,
! true, false, false, false, false,
! false, false, true, false, false);
do_end();
}
;
--- 314,347 ----
Boot_DeclareUniqueIndexStmt:
XDECLARE UNIQUE INDEX boot_ident oidspec ON boot_ident USING boot_ident LPAREN boot_index_params RPAREN
{
+ IndexStmt *stmt = makeNode(IndexStmt);
+
do_start();
! stmt->idxname = $4;
! stmt->relation = makeRangeVar(NULL, $7, -1);
! stmt->accessMethod = $9;
! stmt->tableSpace = NULL;
! stmt->indexParams = $11;
! stmt->options = NIL;
! stmt->whereClause = NULL;
! stmt->excludeOpNames = NIL;
! stmt->idxcomment = NULL;
! stmt->indexOid = InvalidOid;
! stmt->oldNode = InvalidOid;
! stmt->unique = true;
! stmt->primary = false;
! stmt->isconstraint = false;
! stmt->deferrable = false;
! stmt->initdeferred = false;
! stmt->concurrent = false;
!
! DefineIndex(stmt,
$5,
! false,
! false,
! true, /* skip_build */
! false);
do_end();
}
;
diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index e5d1d8b699ad6d37cd3dd9e19b1d76ba97c01eaa..f315ab60154d6c6aa3c96f05babb8e79945f70b8 100644
*** a/src/backend/commands/indexcmds.c
--- b/src/backend/commands/indexcmds.c
***************
*** 24,29 ****
--- 24,30 ----
#include "catalog/pg_opfamily.h"
#include "catalog/pg_tablespace.h"
#include "catalog/pg_type.h"
+ #include "commands/comment.h"
#include "commands/dbcommands.h"
#include "commands/defrem.h"
#include "commands/tablecmds.h"
*************** static void ComputeIndexAttrs(IndexInfo
*** 65,71 ****
--- 66,76 ----
bool isconstraint);
static Oid GetIndexOpClass(List *opclass, Oid attrType,
char *accessMethodName, Oid accessMethodId);
+ static char *ChooseIndexName(const char *tabname, Oid namespaceId,
+ List *colnames, List *exclusionOpNames,
+ bool primary, bool isconstraint);
static char *ChooseIndexNameAddition(List *colnames);
+ static List *ChooseIndexColumnNames(List *indexElems);
static void RangeVarCallbackForReindexIndex(const RangeVar *relation,
Oid relId, Oid oldRelId, void *arg);
*************** CheckIndexCompatible(Oid oldId,
*** 268,327 ****
* DefineIndex
* Creates a new index.
*
! * 'heapRelation': the relation the index will apply to.
! * 'indexRelationName': the name for the new index, or NULL to indicate
! * that a nonconflicting default name should be picked.
* 'indexRelationId': normally InvalidOid, but during bootstrap can be
* nonzero to specify a preselected OID for the index.
- * 'relFileNode': normally InvalidOid, but can be nonzero to specify existing
- * storage constituting a valid build of this index.
- * 'accessMethodName': name of the AM to use.
- * 'tableSpaceName': name of the tablespace to create the index in.
- * NULL specifies using the appropriate default.
- * 'attributeList': a list of IndexElem specifying columns and expressions
- * to index on.
- * 'predicate': the partial-index condition, or NULL if none.
- * 'options': reloptions from WITH (in list-of-DefElem form).
- * 'exclusionOpNames': list of names of exclusion-constraint operators,
- * or NIL if not an exclusion constraint.
- * 'unique': make the index enforce uniqueness.
- * 'primary': mark the index as a primary key in the catalogs.
- * 'isconstraint': index is for a PRIMARY KEY or UNIQUE constraint,
- * so build a pg_constraint entry for it.
- * 'deferrable': constraint is DEFERRABLE.
- * 'initdeferred': constraint is INITIALLY DEFERRED.
* 'is_alter_table': this is due to an ALTER rather than a CREATE operation.
* 'check_rights': check for CREATE rights in the namespace. (This should
* be true except when ALTER is deleting/recreating an index.)
* 'skip_build': make the catalog entries but leave the index file empty;
* it will be filled later.
* 'quiet': suppress the NOTICE chatter ordinarily provided for constraints.
- * 'concurrent': avoid blocking writers to the table while building.
*
* Returns the OID of the created index.
*/
Oid
! DefineIndex(RangeVar *heapRelation,
! char *indexRelationName,
Oid indexRelationId,
- Oid relFileNode,
- char *accessMethodName,
- char *tableSpaceName,
- List *attributeList,
- Expr *predicate,
- List *options,
- List *exclusionOpNames,
- bool unique,
- bool primary,
- bool isconstraint,
- bool deferrable,
- bool initdeferred,
bool is_alter_table,
bool check_rights,
bool skip_build,
! bool quiet,
! bool concurrent)
{
Oid *typeObjectId;
Oid *collationObjectId;
Oid *classObjectId;
--- 273,300 ----
* DefineIndex
* Creates a new index.
*
! * 'stmt': IndexStmt describing the properties of the new index.
* 'indexRelationId': normally InvalidOid, but during bootstrap can be
* nonzero to specify a preselected OID for the index.
* 'is_alter_table': this is due to an ALTER rather than a CREATE operation.
* 'check_rights': check for CREATE rights in the namespace. (This should
* be true except when ALTER is deleting/recreating an index.)
* 'skip_build': make the catalog entries but leave the index file empty;
* it will be filled later.
* 'quiet': suppress the NOTICE chatter ordinarily provided for constraints.
*
* Returns the OID of the created index.
*/
Oid
! DefineIndex(IndexStmt *stmt,
Oid indexRelationId,
bool is_alter_table,
bool check_rights,
bool skip_build,
! bool quiet)
{
+ char *indexRelationName;
+ char *accessMethodName;
Oid *typeObjectId;
Oid *collationObjectId;
Oid *classObjectId;
*************** DefineIndex(RangeVar *heapRelation,
*** 354,360 ****
/*
* count attributes in index
*/
! numberOfAttributes = list_length(attributeList);
if (numberOfAttributes <= 0)
ereport(ERROR,
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
--- 327,333 ----
/*
* count attributes in index
*/
! numberOfAttributes = list_length(stmt->indexParams);
if (numberOfAttributes <= 0)
ereport(ERROR,
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
*************** DefineIndex(RangeVar *heapRelation,
*** 372,379 ****
* index build; but for concurrent builds we allow INSERT/UPDATE/DELETE
* (but not VACUUM).
*/
! rel = heap_openrv(heapRelation,
! (concurrent ? ShareUpdateExclusiveLock : ShareLock));
relationId = RelationGetRelid(rel);
namespaceId = RelationGetNamespace(rel);
--- 345,352 ----
* index build; but for concurrent builds we allow INSERT/UPDATE/DELETE
* (but not VACUUM).
*/
! rel = heap_openrv(stmt->relation,
! (stmt->concurrent ? ShareUpdateExclusiveLock : ShareLock));
relationId = RelationGetRelid(rel);
namespaceId = RelationGetNamespace(rel);
*************** DefineIndex(RangeVar *heapRelation,
*** 389,400 ****
ereport(ERROR,
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
errmsg("cannot create index on foreign table \"%s\"",
! heapRelation->relname)));
else
ereport(ERROR,
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
errmsg("\"%s\" is not a table",
! heapRelation->relname)));
}
/*
--- 362,373 ----
ereport(ERROR,
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
errmsg("cannot create index on foreign table \"%s\"",
! stmt->relation->relname)));
else
ereport(ERROR,
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
errmsg("\"%s\" is not a table",
! stmt->relation->relname)));
}
/*
*************** DefineIndex(RangeVar *heapRelation,
*** 426,434 ****
* Select tablespace to use. If not specified, use default tablespace
* (which may in turn default to database's default).
*/
! if (tableSpaceName)
{
! tablespaceId = get_tablespace_oid(tableSpaceName, false);
}
else
{
--- 399,407 ----
* Select tablespace to use. If not specified, use default tablespace
* (which may in turn default to database's default).
*/
! if (stmt->tableSpace)
{
! tablespaceId = get_tablespace_oid(stmt->tableSpace, false);
}
else
{
*************** DefineIndex(RangeVar *heapRelation,
*** 463,484 ****
/*
* Choose the index column names.
*/
! indexColNames = ChooseIndexColumnNames(attributeList);
/*
* Select name for index if caller didn't specify
*/
if (indexRelationName == NULL)
indexRelationName = ChooseIndexName(RelationGetRelationName(rel),
namespaceId,
indexColNames,
! exclusionOpNames,
! primary,
! isconstraint);
/*
* look up the access method, verify it can handle the requested features
*/
tuple = SearchSysCache1(AMNAME, PointerGetDatum(accessMethodName));
if (!HeapTupleIsValid(tuple))
{
--- 436,459 ----
/*
* Choose the index column names.
*/
! indexColNames = ChooseIndexColumnNames(stmt->indexParams);
/*
* Select name for index if caller didn't specify
*/
+ indexRelationName = stmt->idxname;
if (indexRelationName == NULL)
indexRelationName = ChooseIndexName(RelationGetRelationName(rel),
namespaceId,
indexColNames,
! stmt->excludeOpNames,
! stmt->primary,
! stmt->isconstraint);
/*
* look up the access method, verify it can handle the requested features
*/
+ accessMethodName = stmt->accessMethod;
tuple = SearchSysCache1(AMNAME, PointerGetDatum(accessMethodName));
if (!HeapTupleIsValid(tuple))
{
*************** DefineIndex(RangeVar *heapRelation,
*** 503,509 ****
accessMethodId = HeapTupleGetOid(tuple);
accessMethodForm = (Form_pg_am) GETSTRUCT(tuple);
! if (unique && !accessMethodForm->amcanunique)
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("access method \"%s\" does not support unique indexes",
--- 478,484 ----
accessMethodId = HeapTupleGetOid(tuple);
accessMethodForm = (Form_pg_am) GETSTRUCT(tuple);
! if (stmt->unique && !accessMethodForm->amcanunique)
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("access method \"%s\" does not support unique indexes",
*************** DefineIndex(RangeVar *heapRelation,
*** 513,519 ****
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("access method \"%s\" does not support multicolumn indexes",
accessMethodName)));
! if (exclusionOpNames != NIL && !OidIsValid(accessMethodForm->amgettuple))
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("access method \"%s\" does not support exclusion constraints",
--- 488,494 ----
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("access method \"%s\" does not support multicolumn indexes",
accessMethodName)));
! if (stmt->excludeOpNames && !OidIsValid(accessMethodForm->amgettuple))
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("access method \"%s\" does not support exclusion constraints",
*************** DefineIndex(RangeVar *heapRelation,
*** 527,539 ****
/*
* Validate predicate, if given
*/
! if (predicate)
! CheckPredicate(predicate);
/*
* Parse AM-specific options, convert to text array form, validate.
*/
! reloptions = transformRelOptions((Datum) 0, options, NULL, NULL, false, false);
(void) index_reloptions(amoptions, reloptions, true);
--- 502,515 ----
/*
* Validate predicate, if given
*/
! if (stmt->whereClause)
! CheckPredicate((Expr *) stmt->whereClause);
/*
* Parse AM-specific options, convert to text array form, validate.
*/
! reloptions = transformRelOptions((Datum) 0, stmt->options,
! NULL, NULL, false, false);
(void) index_reloptions(amoptions, reloptions, true);
*************** DefineIndex(RangeVar *heapRelation,
*** 545,559 ****
indexInfo->ii_NumIndexAttrs = numberOfAttributes;
indexInfo->ii_Expressions = NIL; /* for now */
indexInfo->ii_ExpressionsState = NIL;
! indexInfo->ii_Predicate = make_ands_implicit(predicate);
indexInfo->ii_PredicateState = NIL;
indexInfo->ii_ExclusionOps = NULL;
indexInfo->ii_ExclusionProcs = NULL;
indexInfo->ii_ExclusionStrats = NULL;
! indexInfo->ii_Unique = unique;
/* In a concurrent build, mark it not-ready-for-inserts */
! indexInfo->ii_ReadyForInserts = !concurrent;
! indexInfo->ii_Concurrent = concurrent;
indexInfo->ii_BrokenHotChain = false;
typeObjectId = (Oid *) palloc(numberOfAttributes * sizeof(Oid));
--- 521,535 ----
indexInfo->ii_NumIndexAttrs = numberOfAttributes;
indexInfo->ii_Expressions = NIL; /* for now */
indexInfo->ii_ExpressionsState = NIL;
! indexInfo->ii_Predicate = make_ands_implicit((Expr *) stmt->whereClause);
indexInfo->ii_PredicateState = NIL;
indexInfo->ii_ExclusionOps = NULL;
indexInfo->ii_ExclusionProcs = NULL;
indexInfo->ii_ExclusionStrats = NULL;
! indexInfo->ii_Unique = stmt->unique;
/* In a concurrent build, mark it not-ready-for-inserts */
! indexInfo->ii_ReadyForInserts = !stmt->concurrent;
! indexInfo->ii_Concurrent = stmt->concurrent;
indexInfo->ii_BrokenHotChain = false;
typeObjectId = (Oid *) palloc(numberOfAttributes * sizeof(Oid));
*************** DefineIndex(RangeVar *heapRelation,
*** 562,591 ****
coloptions = (int16 *) palloc(numberOfAttributes * sizeof(int16));
ComputeIndexAttrs(indexInfo,
typeObjectId, collationObjectId, classObjectId,
! coloptions, attributeList,
! exclusionOpNames, relationId,
accessMethodName, accessMethodId,
! amcanorder, isconstraint);
/*
* Extra checks when creating a PRIMARY KEY index.
*/
! if (primary)
index_check_primary_key(rel, indexInfo, is_alter_table);
/*
* Report index creation if appropriate (delay this till after most of the
* error checks)
*/
! if (isconstraint && !quiet)
{
const char *constraint_type;
! if (primary)
constraint_type = "PRIMARY KEY";
! else if (unique)
constraint_type = "UNIQUE";
! else if (exclusionOpNames != NIL)
constraint_type = "EXCLUDE";
else
{
--- 538,567 ----
coloptions = (int16 *) palloc(numberOfAttributes * sizeof(int16));
ComputeIndexAttrs(indexInfo,
typeObjectId, collationObjectId, classObjectId,
! coloptions, stmt->indexParams,
! stmt->excludeOpNames, relationId,
accessMethodName, accessMethodId,
! amcanorder, stmt->isconstraint);
/*
* Extra checks when creating a PRIMARY KEY index.
*/
! if (stmt->primary)
index_check_primary_key(rel, indexInfo, is_alter_table);
/*
* Report index creation if appropriate (delay this till after most of the
* error checks)
*/
! if (stmt->isconstraint && !quiet)
{
const char *constraint_type;
! if (stmt->primary)
constraint_type = "PRIMARY KEY";
! else if (stmt->unique)
constraint_type = "UNIQUE";
! else if (stmt->excludeOpNames != NIL)
constraint_type = "EXCLUDE";
else
{
*************** DefineIndex(RangeVar *heapRelation,
*** 601,627 ****
}
/*
! * A valid relFileNode implies that we already have a built form of the
* index. The caller should also decline any index build.
*/
! Assert(!OidIsValid(relFileNode) || (skip_build && !concurrent));
/*
* Make the catalog entries for the index, including constraints. Then, if
* not skip_build || concurrent, actually build the index.
*/
indexRelationId =
! index_create(rel, indexRelationName, indexRelationId, relFileNode,
indexInfo, indexColNames,
accessMethodId, tablespaceId,
collationObjectId, classObjectId,
! coloptions, reloptions, primary,
! isconstraint, deferrable, initdeferred,
allowSystemTableMods,
! skip_build || concurrent,
! concurrent);
! if (!concurrent)
{
/* Close the heap and we're done, in the non-concurrent case */
heap_close(rel, NoLock);
--- 577,607 ----
}
/*
! * A valid stmt->oldNode implies that we already have a built form of the
* index. The caller should also decline any index build.
*/
! Assert(!OidIsValid(stmt->oldNode) || (skip_build && !stmt->concurrent));
/*
* Make the catalog entries for the index, including constraints. Then, if
* not skip_build || concurrent, actually build the index.
*/
indexRelationId =
! index_create(rel, indexRelationName, indexRelationId, stmt->oldNode,
indexInfo, indexColNames,
accessMethodId, tablespaceId,
collationObjectId, classObjectId,
! coloptions, reloptions, stmt->primary,
! stmt->isconstraint, stmt->deferrable, stmt->initdeferred,
allowSystemTableMods,
! skip_build || stmt->concurrent,
! stmt->concurrent);
! if (stmt->idxcomment != NULL)
! CreateComments(indexRelationId, RelationRelationId, 0,
! stmt->idxcomment);
!
! if (!stmt->concurrent)
{
/* Close the heap and we're done, in the non-concurrent case */
heap_close(rel, NoLock);
*************** DefineIndex(RangeVar *heapRelation,
*** 709,715 ****
*/
/* Open and lock the parent heap relation */
! rel = heap_openrv(heapRelation, ShareUpdateExclusiveLock);
/* And the target index relation */
indexRelation = index_open(indexRelationId, RowExclusiveLock);
--- 689,695 ----
*/
/* Open and lock the parent heap relation */
! rel = heap_openrv(stmt->relation, ShareUpdateExclusiveLock);
/* And the target index relation */
indexRelation = index_open(indexRelationId, RowExclusiveLock);
*************** DefineIndex(RangeVar *heapRelation,
*** 724,730 ****
indexInfo->ii_BrokenHotChain = false;
/* Now build the index */
! index_build(rel, indexRelation, indexInfo, primary, false);
/* Close both the relations, but keep the locks */
heap_close(rel, NoLock);
--- 704,710 ----
indexInfo->ii_BrokenHotChain = false;
/* Now build the index */
! index_build(rel, indexRelation, indexInfo, stmt->primary, false);
/* Close both the relations, but keep the locks */
heap_close(rel, NoLock);
*************** ChooseRelationName(const char *name1, co
*** 1594,1600 ****
*
* The argument list is pretty ad-hoc :-(
*/
! char *
ChooseIndexName(const char *tabname, Oid namespaceId,
List *colnames, List *exclusionOpNames,
bool primary, bool isconstraint)
--- 1574,1580 ----
*
* The argument list is pretty ad-hoc :-(
*/
! static char *
ChooseIndexName(const char *tabname, Oid namespaceId,
List *colnames, List *exclusionOpNames,
bool primary, bool isconstraint)
*************** ChooseIndexNameAddition(List *colnames)
*** 1676,1682 ****
*
* Returns a List of plain strings (char *, not String nodes).
*/
! List *
ChooseIndexColumnNames(List *indexElems)
{
List *result = NIL;
--- 1656,1662 ----
*
* Returns a List of plain strings (char *, not String nodes).
*/
! static List *
ChooseIndexColumnNames(List *indexElems)
{
List *result = NIL;
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index d69809a2f866de511e7ce278b8dca9bf9db33d40..70e408cb6ea1fc6a80b943f22d3a91d226226bb8 100644
*** a/src/backend/commands/tablecmds.c
--- b/src/backend/commands/tablecmds.c
*************** ATExecAddIndex(AlteredTableInfo *tab, Re
*** 5389,5394 ****
--- 5389,5395 ----
Oid new_index;
Assert(IsA(stmt, IndexStmt));
+ Assert(!stmt->concurrent);
/* suppress schema rights check when rebuilding existing index */
check_rights = !is_rebuild;
*************** ATExecAddIndex(AlteredTableInfo *tab, Re
*** 5399,5424 ****
/* The IndexStmt has already been through transformIndexStmt */
! new_index = DefineIndex(stmt->relation, /* relation */
! stmt->idxname, /* index name */
InvalidOid, /* no predefined OID */
- stmt->oldNode,
- stmt->accessMethod, /* am name */
- stmt->tableSpace,
- stmt->indexParams, /* parameters */
- (Expr *) stmt->whereClause,
- stmt->options,
- stmt->excludeOpNames,
- stmt->unique,
- stmt->primary,
- stmt->isconstraint,
- stmt->deferrable,
- stmt->initdeferred,
true, /* is_alter_table */
check_rights,
skip_build,
! quiet,
! false);
/*
* If TryReuseIndex() stashed a relfilenode for us, we used it for the new
--- 5400,5411 ----
/* The IndexStmt has already been through transformIndexStmt */
! new_index = DefineIndex(stmt,
InvalidOid, /* no predefined OID */
true, /* is_alter_table */
check_rights,
skip_build,
! quiet);
/*
* If TryReuseIndex() stashed a relfilenode for us, we used it for the new
*************** ATPostAlterTypeParse(Oid oldId, char *cm
*** 7968,7974 ****
static void
TryReuseIndex(Oid oldId, IndexStmt *stmt)
{
-
if (CheckIndexCompatible(oldId,
stmt->relation,
stmt->accessMethod,
--- 7955,7960 ----
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c
index 1743b8fdc89735f0f619c290e7286be23f3e72e6..9bac99452d334b6e7a92c662b1287d552945c6d9 100644
*** a/src/backend/nodes/copyfuncs.c
--- b/src/backend/nodes/copyfuncs.c
*************** _copyIndexStmt(const IndexStmt *from)
*** 2826,2831 ****
--- 2826,2832 ----
COPY_NODE_FIELD(options);
COPY_NODE_FIELD(whereClause);
COPY_NODE_FIELD(excludeOpNames);
+ COPY_STRING_FIELD(idxcomment);
COPY_SCALAR_FIELD(indexOid);
COPY_SCALAR_FIELD(oldNode);
COPY_SCALAR_FIELD(unique);
diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c
index f19ad7702618dcfb7f3be416dc535e6ac11b1b5e..2171d8d018bab95e0ed118384ddf8416502a86e8 100644
*** a/src/backend/nodes/equalfuncs.c
--- b/src/backend/nodes/equalfuncs.c
*************** _equalIndexStmt(const IndexStmt *a, cons
*** 1250,1255 ****
--- 1250,1256 ----
COMPARE_NODE_FIELD(options);
COMPARE_NODE_FIELD(whereClause);
COMPARE_NODE_FIELD(excludeOpNames);
+ COMPARE_STRING_FIELD(idxcomment);
COMPARE_SCALAR_FIELD(indexOid);
COMPARE_SCALAR_FIELD(oldNode);
COMPARE_SCALAR_FIELD(unique);
diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c
index d6dff9de47a982d6e41ea191af2f0415be181d7f..91b54265afe6dadb4f171ec9abdf5ff7ec9c69c5 100644
*** a/src/backend/nodes/outfuncs.c
--- b/src/backend/nodes/outfuncs.c
*************** _outIndexStmt(StringInfo str, const Inde
*** 1994,1999 ****
--- 1994,2000 ----
WRITE_NODE_FIELD(options);
WRITE_NODE_FIELD(whereClause);
WRITE_NODE_FIELD(excludeOpNames);
+ WRITE_STRING_FIELD(idxcomment);
WRITE_OID_FIELD(indexOid);
WRITE_OID_FIELD(oldNode);
WRITE_BOOL_FIELD(unique);
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 7e6ceedc42af9362a6dbdb49c6373dcf02eecfb6..1a17337a7ec6a80353e6391964e12c0242a55854 100644
*** a/src/backend/parser/gram.y
--- b/src/backend/parser/gram.y
*************** IndexStmt: CREATE opt_unique INDEX opt_c
*** 5837,5843 ****
--- 5837,5850 ----
n->options = $12;
n->tableSpace = $13;
n->whereClause = $14;
+ n->excludeOpNames = NIL;
+ n->idxcomment = NULL;
n->indexOid = InvalidOid;
+ n->oldNode = InvalidOid;
+ n->primary = false;
+ n->isconstraint = false;
+ n->deferrable = false;
+ n->initdeferred = false;
$$ = (Node *)n;
}
;
diff --git a/src/backend/parser/parse_utilcmd.c b/src/backend/parser/parse_utilcmd.c
index e01e103774ea2c6b1d429eb12e716b5da54bc4f9..c22c6ed21f76e0846da1d2886e4371501878af2f 100644
*** a/src/backend/parser/parse_utilcmd.c
--- b/src/backend/parser/parse_utilcmd.c
*************** static void transformTableLikeClause(Cre
*** 106,112 ****
TableLikeClause *table_like_clause);
static void transformOfType(CreateStmtContext *cxt,
TypeName *ofTypename);
- static char *chooseIndexName(const RangeVar *relation, IndexStmt *index_stmt);
static IndexStmt *generateClonedIndexStmt(CreateStmtContext *cxt,
Relation source_idx,
const AttrNumber *attmap, int attmap_length);
--- 106,111 ----
*************** transformTableLikeClause(CreateStmtConte
*** 872,904 ****
index_stmt = generateClonedIndexStmt(cxt, parent_index,
attmap, tupleDesc->natts);
! /* Copy comment on index */
if (table_like_clause->options & CREATE_TABLE_LIKE_COMMENTS)
{
comment = GetComment(parent_index_oid, RelationRelationId, 0);
! if (comment != NULL)
! {
! CommentStmt *stmt;
!
! /*
! * We have to assign the index a name now, so that we can
! * reference it in CommentStmt.
! */
! if (index_stmt->idxname == NULL)
! index_stmt->idxname = chooseIndexName(cxt->relation,
! index_stmt);
!
! stmt = makeNode(CommentStmt);
! stmt->objtype = OBJECT_INDEX;
! stmt->objname =
! list_make2(makeString(cxt->relation->schemaname),
! makeString(index_stmt->idxname));
! stmt->objargs = NIL;
! stmt->comment = comment;
!
! cxt->alist = lappend(cxt->alist, stmt);
! }
}
/* Save it in the inh_indexes list for the time being */
--- 871,886 ----
index_stmt = generateClonedIndexStmt(cxt, parent_index,
attmap, tupleDesc->natts);
! /* Copy comment on index, if requested */
if (table_like_clause->options & CREATE_TABLE_LIKE_COMMENTS)
{
comment = GetComment(parent_index_oid, RelationRelationId, 0);
! /*
! * We make use of IndexStmt's idxcomment option, so as not to
! * need to know now what name the index will have.
! */
! index_stmt->idxcomment = comment;
}
/* Save it in the inh_indexes list for the time being */
*************** transformOfType(CreateStmtContext *cxt,
*** 961,989 ****
}
/*
- * chooseIndexName
- *
- * Compute name for an index. This must match code in indexcmds.c.
- *
- * XXX this is inherently broken because the indexes aren't created
- * immediately, so we fail to resolve conflicts when the same name is
- * derived for multiple indexes. However, that's a reasonably uncommon
- * situation, so we'll live with it for now.
- */
- static char *
- chooseIndexName(const RangeVar *relation, IndexStmt *index_stmt)
- {
- Oid namespaceId;
- List *colnames;
-
- namespaceId = RangeVarGetCreationNamespace(relation);
- colnames = ChooseIndexColumnNames(index_stmt->indexParams);
- return ChooseIndexName(relation->relname, namespaceId,
- colnames, index_stmt->excludeOpNames,
- index_stmt->primary, index_stmt->isconstraint);
- }
-
- /*
* Generate an IndexStmt node using information from an already existing index
* "source_idx". Attribute numbers should be adjusted according to attmap.
*/
--- 943,948 ----
*************** generateClonedIndexStmt(CreateStmtContex
*** 1046,1052 ****
--- 1005,1014 ----
index->tableSpace = get_tablespace_name(idxrelrec->reltablespace);
else
index->tableSpace = NULL;
+ index->excludeOpNames = NIL;
+ index->idxcomment = NULL;
index->indexOid = InvalidOid;
+ index->oldNode = InvalidOid;
index->unique = idxrec->indisunique;
index->primary = idxrec->indisprimary;
index->concurrent = false;
*************** transformIndexConstraint(Constraint *con
*** 1504,1510 ****
--- 1466,1474 ----
index->whereClause = constraint->where_clause;
index->indexParams = NIL;
index->excludeOpNames = NIL;
+ index->idxcomment = NULL;
index->indexOid = InvalidOid;
+ index->oldNode = InvalidOid;
index->concurrent = false;
/*
diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c
index 33b292e6b7a9c1e47fb34de126cbc34dc5246693..7f36a09f46d297d4e98782c842a0a0f9d7ccb8e7 100644
*** a/src/backend/tcop/utility.c
--- b/src/backend/tcop/utility.c
*************** standard_ProcessUtility(Node *parsetree,
*** 921,946 ****
stmt = transformIndexStmt(stmt, queryString);
/* ... and do it */
! DefineIndex(stmt->relation, /* relation */
! stmt->idxname, /* index name */
InvalidOid, /* no predefined OID */
- InvalidOid, /* no previous storage */
- stmt->accessMethod, /* am name */
- stmt->tableSpace,
- stmt->indexParams, /* parameters */
- (Expr *) stmt->whereClause,
- stmt->options,
- stmt->excludeOpNames,
- stmt->unique,
- stmt->primary,
- stmt->isconstraint,
- stmt->deferrable,
- stmt->initdeferred,
false, /* is_alter_table */
true, /* check_rights */
false, /* skip_build */
! false, /* quiet */
! stmt->concurrent); /* concurrent */
}
break;
--- 921,932 ----
stmt = transformIndexStmt(stmt, queryString);
/* ... and do it */
! DefineIndex(stmt,
InvalidOid, /* no predefined OID */
false, /* is_alter_table */
true, /* check_rights */
false, /* skip_build */
! false); /* quiet */
}
break;
diff --git a/src/include/commands/defrem.h b/src/include/commands/defrem.h
index 8f3d2c358dceb73587a934284fb6340b91d91cb4..9b6d57a21e23c38688874bef9fe4a423c6d49289 100644
*** a/src/include/commands/defrem.h
--- b/src/include/commands/defrem.h
***************
*** 20,45 ****
extern void RemoveObjects(DropStmt *stmt);
/* commands/indexcmds.c */
! extern Oid DefineIndex(RangeVar *heapRelation,
! char *indexRelationName,
Oid indexRelationId,
- Oid relFileNode,
- char *accessMethodName,
- char *tableSpaceName,
- List *attributeList,
- Expr *predicate,
- List *options,
- List *exclusionOpNames,
- bool unique,
- bool primary,
- bool isconstraint,
- bool deferrable,
- bool initdeferred,
bool is_alter_table,
bool check_rights,
bool skip_build,
! bool quiet,
! bool concurrent);
extern void ReindexIndex(RangeVar *indexRelation);
extern void ReindexTable(RangeVar *relation);
extern void ReindexDatabase(const char *databaseName,
--- 20,31 ----
extern void RemoveObjects(DropStmt *stmt);
/* commands/indexcmds.c */
! extern Oid DefineIndex(IndexStmt *stmt,
Oid indexRelationId,
bool is_alter_table,
bool check_rights,
bool skip_build,
! bool quiet);
extern void ReindexIndex(RangeVar *indexRelation);
extern void ReindexTable(RangeVar *relation);
extern void ReindexDatabase(const char *databaseName,
*************** extern char *makeObjectName(const char *
*** 48,57 ****
const char *label);
extern char *ChooseRelationName(const char *name1, const char *name2,
const char *label, Oid namespaceid);
- extern char *ChooseIndexName(const char *tabname, Oid namespaceId,
- List *colnames, List *exclusionOpNames,
- bool primary, bool isconstraint);
- extern List *ChooseIndexColumnNames(List *indexElems);
extern bool CheckIndexCompatible(Oid oldId,
RangeVar *heapRelation,
char *accessMethodName,
--- 34,39 ----
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index 50111cba3c0eca1f5abe341bbee6bb0464b0439f..a4591cc9aa4060ebbc569d014f0404eadbe8af56 100644
*** a/src/include/nodes/parsenodes.h
--- b/src/include/nodes/parsenodes.h
*************** typedef struct FetchStmt
*** 2018,2027 ****
* Create Index Statement
*
* This represents creation of an index and/or an associated constraint.
! * If indexOid isn't InvalidOid, we are not creating an index, just a
! * UNIQUE/PKEY constraint using an existing index. isconstraint must always
! * be true in this case, and the fields describing the index properties are
! * empty.
* ----------------------
*/
typedef struct IndexStmt
--- 2018,2028 ----
* Create Index Statement
*
* This represents creation of an index and/or an associated constraint.
! * If isconstraint is true, we should create a pg_constraint entry along
! * with the index. But if indexOid isn't InvalidOid, we are not creating an
! * index, just a UNIQUE/PKEY constraint using an existing index. isconstraint
! * must always be true in this case, and the fields describing the index
! * properties are empty.
* ----------------------
*/
typedef struct IndexStmt
*************** typedef struct IndexStmt
*** 2031,2045 ****
RangeVar *relation; /* relation to build index on */
char *accessMethod; /* name of access method (eg. btree) */
char *tableSpace; /* tablespace, or NULL for default */
! List *indexParams; /* a list of IndexElem */
! List *options; /* options from WITH clause */
Node *whereClause; /* qualification (partial-index predicate) */
List *excludeOpNames; /* exclusion operator names, or NIL if none */
Oid indexOid; /* OID of an existing index, if any */
! Oid oldNode; /* relfilenode of my former self */
bool unique; /* is index unique? */
! bool primary; /* is index on primary key? */
! bool isconstraint; /* is it from a CONSTRAINT clause? */
bool deferrable; /* is the constraint DEFERRABLE? */
bool initdeferred; /* is the constraint INITIALLY DEFERRED? */
bool concurrent; /* should this be a concurrent index build? */
--- 2032,2047 ----
RangeVar *relation; /* relation to build index on */
char *accessMethod; /* name of access method (eg. btree) */
char *tableSpace; /* tablespace, or NULL for default */
! List *indexParams; /* columns to index: a list of IndexElem */
! List *options; /* WITH clause options: a list of DefElem */
Node *whereClause; /* qualification (partial-index predicate) */
List *excludeOpNames; /* exclusion operator names, or NIL if none */
+ char *idxcomment; /* comment to apply to index, or NULL */
Oid indexOid; /* OID of an existing index, if any */
! Oid oldNode; /* relfilenode of existing storage, if any */
bool unique; /* is index unique? */
! bool primary; /* is index a primary key? */
! bool isconstraint; /* is it for a pkey/unique constraint? */
bool deferrable; /* is the constraint DEFERRABLE? */
bool initdeferred; /* is the constraint INITIALLY DEFERRED? */
bool concurrent; /* should this be a concurrent index build? */