|
|
|
|
@@ -33,6 +33,7 @@
|
|
|
|
|
#include "catalog/heap.h"
|
|
|
|
|
#include "catalog/index.h"
|
|
|
|
|
#include "catalog/namespace.h"
|
|
|
|
|
#include "catalog/pg_collation.h"
|
|
|
|
|
#include "catalog/pg_constraint.h"
|
|
|
|
|
#include "catalog/pg_opclass.h"
|
|
|
|
|
#include "catalog/pg_operator.h"
|
|
|
|
|
@@ -111,6 +112,7 @@ static void transformOfType(CreateStmtContext *cxt,
|
|
|
|
|
static char *chooseIndexName(const RangeVar *relation, IndexStmt *index_stmt);
|
|
|
|
|
static IndexStmt *generateClonedIndexStmt(CreateStmtContext *cxt,
|
|
|
|
|
Relation parent_index, AttrNumber *attmap);
|
|
|
|
|
static List *get_collation(Oid collation, Oid actual_datatype);
|
|
|
|
|
static List *get_opclass(Oid opclass, Oid actual_datatype);
|
|
|
|
|
static void transformIndexConstraints(CreateStmtContext *cxt);
|
|
|
|
|
static IndexStmt *transformIndexConstraint(Constraint *constraint,
|
|
|
|
|
@@ -904,6 +906,7 @@ generateClonedIndexStmt(CreateStmtContext *cxt, Relation source_idx,
|
|
|
|
|
Form_pg_class idxrelrec;
|
|
|
|
|
Form_pg_index idxrec;
|
|
|
|
|
Form_pg_am amrec;
|
|
|
|
|
oidvector *indcollation;
|
|
|
|
|
oidvector *indclass;
|
|
|
|
|
IndexStmt *index;
|
|
|
|
|
List *indexprs;
|
|
|
|
|
@@ -931,6 +934,12 @@ generateClonedIndexStmt(CreateStmtContext *cxt, Relation source_idx,
|
|
|
|
|
/* Fetch pg_am tuple for source index from relcache entry */
|
|
|
|
|
amrec = source_idx->rd_am;
|
|
|
|
|
|
|
|
|
|
/* Extract indcollation from the pg_index tuple */
|
|
|
|
|
datum = SysCacheGetAttr(INDEXRELID, ht_idx,
|
|
|
|
|
Anum_pg_index_indcollation, &isnull);
|
|
|
|
|
Assert(!isnull);
|
|
|
|
|
indcollation = (oidvector *) DatumGetPointer(datum);
|
|
|
|
|
|
|
|
|
|
/* Extract indclass from the pg_index tuple */
|
|
|
|
|
datum = SysCacheGetAttr(INDEXRELID, ht_idx,
|
|
|
|
|
Anum_pg_index_indclass, &isnull);
|
|
|
|
|
@@ -1094,6 +1103,9 @@ generateClonedIndexStmt(CreateStmtContext *cxt, Relation source_idx,
|
|
|
|
|
/* Copy the original index column name */
|
|
|
|
|
iparam->indexcolname = pstrdup(NameStr(attrs[keyno]->attname));
|
|
|
|
|
|
|
|
|
|
/* Add the collation name, if non-default */
|
|
|
|
|
iparam->collation = get_collation(indcollation->values[keyno], keycoltype);
|
|
|
|
|
|
|
|
|
|
/* Add the operator class name, if non-default */
|
|
|
|
|
iparam->opclass = get_opclass(indclass->values[keyno], keycoltype);
|
|
|
|
|
|
|
|
|
|
@@ -1152,7 +1164,41 @@ generateClonedIndexStmt(CreateStmtContext *cxt, Relation source_idx,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* get_opclass - fetch name of an index operator class
|
|
|
|
|
* get_collation - fetch qualified name of a collation
|
|
|
|
|
*
|
|
|
|
|
* If collation is InvalidOid or is the default for the given actual_datatype,
|
|
|
|
|
* then the return value is NIL.
|
|
|
|
|
*/
|
|
|
|
|
static List *
|
|
|
|
|
get_collation(Oid collation, Oid actual_datatype)
|
|
|
|
|
{
|
|
|
|
|
List *result;
|
|
|
|
|
HeapTuple ht_coll;
|
|
|
|
|
Form_pg_collation coll_rec;
|
|
|
|
|
char *nsp_name;
|
|
|
|
|
char *coll_name;
|
|
|
|
|
|
|
|
|
|
if (!OidIsValid(collation))
|
|
|
|
|
return NIL; /* easy case */
|
|
|
|
|
if (collation == get_typcollation(actual_datatype))
|
|
|
|
|
return NIL; /* just let it default */
|
|
|
|
|
|
|
|
|
|
ht_coll = SearchSysCache1(COLLOID, ObjectIdGetDatum(collation));
|
|
|
|
|
if (!HeapTupleIsValid(ht_coll))
|
|
|
|
|
elog(ERROR, "cache lookup failed for collation %u", collation);
|
|
|
|
|
coll_rec = (Form_pg_collation) GETSTRUCT(ht_coll);
|
|
|
|
|
|
|
|
|
|
/* For simplicity, we always schema-qualify the name */
|
|
|
|
|
nsp_name = get_namespace_name(coll_rec->collnamespace);
|
|
|
|
|
coll_name = pstrdup(NameStr(coll_rec->collname));
|
|
|
|
|
result = list_make2(makeString(nsp_name), makeString(coll_name));
|
|
|
|
|
|
|
|
|
|
ReleaseSysCache(ht_coll);
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* get_opclass - fetch qualified name of an index operator class
|
|
|
|
|
*
|
|
|
|
|
* If the opclass is the default for the given actual_datatype, then
|
|
|
|
|
* the return value is NIL.
|
|
|
|
|
@@ -1160,9 +1206,9 @@ generateClonedIndexStmt(CreateStmtContext *cxt, Relation source_idx,
|
|
|
|
|
static List *
|
|
|
|
|
get_opclass(Oid opclass, Oid actual_datatype)
|
|
|
|
|
{
|
|
|
|
|
List *result = NIL;
|
|
|
|
|
HeapTuple ht_opc;
|
|
|
|
|
Form_pg_opclass opc_rec;
|
|
|
|
|
List *result = NIL;
|
|
|
|
|
|
|
|
|
|
ht_opc = SearchSysCache1(CLAOID, ObjectIdGetDatum(opclass));
|
|
|
|
|
if (!HeapTupleIsValid(ht_opc))
|
|
|
|
|
@@ -1663,6 +1709,7 @@ transformIndexConstraint(Constraint *constraint, CreateStmtContext *cxt)
|
|
|
|
|
iparam->name = pstrdup(key);
|
|
|
|
|
iparam->expr = NULL;
|
|
|
|
|
iparam->indexcolname = NULL;
|
|
|
|
|
iparam->collation = NIL;
|
|
|
|
|
iparam->opclass = NIL;
|
|
|
|
|
iparam->ordering = SORTBY_DEFAULT;
|
|
|
|
|
iparam->nulls_ordering = SORTBY_NULLS_DEFAULT;
|
|
|
|
|
|