Hi,
as you might know, Postgres-R relies on primary keys to address tuples
of a table. It cannot replicate tables without a primary key.
Primary keys currently aren't really used within the executor, so I had
to extended and modify Postgres here and there, to get the required
information. To ease reviewing I have split out these modifications and
present them here as two separate little patches.
The first one, get_pkey_index_oid.diff, changes the function
relationHasPrimaryKey into GetPrimaryKeyIndexOid, which now returns an
index oid instead of just a boolean. It works pretty much the same,
except from returning an oid instead of just a boolean. (In the current
Postgres-R code, I've duplicated that code to
src/backend/replication/recovery.c)
And secondly, the add_pkey_info.diff patch adds a boolean field
ii_Primary to the IndexInfo struct and ri_PrimaryKey to the
ResultRelInfo struct, which is an index into the indexInfoArray.
I think these are relatively trivial modifications which could be
helpful for other purposes as well. So I suggest to apply them to
mainline whenever appropriate (read: choose the appropriate commit fest).
This also raises the more general question of how to start collaborating
on Postgres-R. I realize that it's a pretty huge project. However, I'm
unsure on how to ease reviewing for others, so if you have any ideas or
questions, please don't hesitate to ask.
Regards
Markus
============================================================
*** src/backend/commands/indexcmds.c 61a8b3774b682554e8670624583ab4cf4b9dbdb9
--- src/backend/commands/indexcmds.c dc6fc2a3fbce90748bcf4cd7a60ea2ea887bc97f
*************** static Oid GetIndexOpClass(List *opclass
*** 64,70 ****
bool isconstraint);
static Oid GetIndexOpClass(List *opclass, Oid attrType,
char *accessMethodName, Oid accessMethodId);
- static bool relationHasPrimaryKey(Relation rel);
/*
--- 64,69 ----
*************** DefineIndex(RangeVar *heapRelation,
*** 324,330 ****
* it's no problem either.
*/
if (is_alter_table &&
! relationHasPrimaryKey(rel))
{
ereport(ERROR,
(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
--- 323,329 ----
* it's no problem either.
*/
if (is_alter_table &&
! (GetPrimaryKeyIndexOid(rel) != InvalidOid))
{
ereport(ERROR,
(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
*************** ChooseRelationName(const char *name1, co
*** 1216,1229 ****
}
/*
! * relationHasPrimaryKey -
*
! * See whether an existing relation has a primary key.
*/
! static bool
! relationHasPrimaryKey(Relation rel)
{
! bool result = false;
List *indexoidlist;
ListCell *indexoidscan;
--- 1215,1229 ----
}
/*
! * GetPrimaryKeyIndexOid
*
! * Returns the oid of the primary key index of the relation, if any,
! * otherwise InvalidOid is returned.
*/
! Oid
! GetPrimaryKeyIndexOid(Relation rel)
{
! Oid result = InvalidOid;
List *indexoidlist;
ListCell *indexoidscan;
*************** relationHasPrimaryKey(Relation rel)
*** 1244,1257 ****
0, 0, 0);
if (!HeapTupleIsValid(indexTuple)) /* should not happen */
elog(ERROR, "cache lookup failed for index %u", indexoid);
! result = ((Form_pg_index) GETSTRUCT(indexTuple))->indisprimary;
ReleaseSysCache(indexTuple);
! if (result)
break;
}
list_free(indexoidlist);
-
return result;
}
--- 1244,1260 ----
0, 0, 0);
if (!HeapTupleIsValid(indexTuple)) /* should not happen */
elog(ERROR, "cache lookup failed for index %u", indexoid);
!
! if (((Form_pg_index) GETSTRUCT(indexTuple))->indisprimary)
! result = indexoid;
!
ReleaseSysCache(indexTuple);
!
! if (result != InvalidOid)
break;
}
list_free(indexoidlist);
return result;
}
============================================================
*** src/include/commands/defrem.h e2384af33d917bff68234bbe407ea16e3ec43123
--- src/include/commands/defrem.h 58bb763402c9bef8ead035a3524505ad8fe58de5
***************
*** 15,22 ****
#define DEFREM_H
#include "nodes/parsenodes.h"
-
/* commands/indexcmds.c */
extern void DefineIndex(RangeVar *heapRelation,
char *indexRelationName,
--- 15,22 ----
#define DEFREM_H
#include "nodes/parsenodes.h"
+ #include "utils/relcache.h"
/* commands/indexcmds.c */
extern void DefineIndex(RangeVar *heapRelation,
char *indexRelationName,
*************** extern Oid GetDefaultOpClass(Oid type_id
*** 43,48 ****
--- 43,49 ----
extern char *ChooseRelationName(const char *name1, const char *name2,
const char *label, Oid namespace);
extern Oid GetDefaultOpClass(Oid type_id, Oid am_id);
+ extern Oid GetPrimaryKeyIndexOid(Relation rel);
/* commands/functioncmds.c */
extern void CreateFunction(CreateFunctionStmt *stmt);
============================================================
*** src/backend/catalog/index.c c360fcfd1002ffa557c1a376d3e74c9c2a0924db
--- src/backend/catalog/index.c 7201f06c5c1ad213a6acb6b694b666dd38358234
*************** BuildIndexInfo(Relation index)
*** 999,1004 ****
--- 999,1005 ----
/* other info */
ii->ii_Unique = indexStruct->indisunique;
+ ii->ii_Primary = indexStruct->indisprimary;
ii->ii_ReadyForInserts = indexStruct->indisready;
/* initialize index-build state to default */
============================================================
*** src/backend/executor/execUtils.c 54719433b61db70e6b433cd165c9c7a7b15e6531
--- src/backend/executor/execUtils.c 62756367e3fb34d96e0bb8c1bff4ee25f6402a4a
*************** ExecOpenIndices(ResultRelInfo *resultRel
*** 935,940 ****
--- 935,943 ----
/* extract index key information from the index's pg_index info */
ii = BuildIndexInfo(indexDesc);
+ if (ii->ii_Primary)
+ resultRelInfo->ri_PrimaryKey = i;
+
relationDescs[i] = indexDesc;
indexInfoArray[i] = ii;
i++;
============================================================
*** src/include/nodes/execnodes.h 9c75d10763d7bedc0a4db62a319d31e1549ad542
--- src/include/nodes/execnodes.h 3bc5ba3ad42bfdb298878f69ea3538fa96ba0815
*************** typedef struct IndexInfo
*** 59,64 ****
--- 59,65 ----
List *ii_Predicate; /* list of Expr */
List *ii_PredicateState; /* list of ExprState */
bool ii_Unique;
+ bool ii_Primary;
bool ii_ReadyForInserts;
bool ii_Concurrent;
bool ii_BrokenHotChain;
*************** typedef struct ResultRelInfo
*** 289,294 ****
--- 290,296 ----
Index ri_RangeTableIndex;
Relation ri_RelationDesc;
int ri_NumIndices;
+ int ri_PrimaryKey;
RelationPtr ri_IndexRelationDescs;
IndexInfo **ri_IndexRelationInfo;
TriggerDesc *ri_TrigDesc;
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers