diff options
Diffstat (limited to 'src/backend/commands')
| -rw-r--r-- | src/backend/commands/analyze.c | 14 | ||||
| -rw-r--r-- | src/backend/commands/indexcmds.c | 66 |
2 files changed, 68 insertions, 12 deletions
diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index 102be0d96fe..c568f04284c 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/analyze.c,v 1.102 2007/01/05 22:19:25 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/commands/analyze.c,v 1.103 2007/01/09 02:14:11 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -1297,7 +1297,7 @@ typedef struct typedef struct { FmgrInfo *cmpFn; - SortFunctionKind cmpFnKind; + int cmpFlags; int *tupnoLink; } CompareScalarsContext; @@ -1747,8 +1747,8 @@ compute_scalar_stats(VacAttrStatsP stats, bool is_varwidth = (!stats->attr->attbyval && stats->attr->attlen < 0); double corr_xysum; - RegProcedure cmpFn; - SortFunctionKind cmpFnKind; + Oid cmpFn; + int cmpFlags; FmgrInfo f_cmpfn; ScalarItem *values; int values_cnt = 0; @@ -1763,7 +1763,7 @@ compute_scalar_stats(VacAttrStatsP stats, tupnoLink = (int *) palloc(samplerows * sizeof(int)); track = (ScalarMCVItem *) palloc(num_mcv * sizeof(ScalarMCVItem)); - SelectSortFunction(mystats->ltopr, &cmpFn, &cmpFnKind); + SelectSortFunction(mystats->ltopr, false, &cmpFn, &cmpFlags); fmgr_info(cmpFn, &f_cmpfn); /* Initial scan to find sortable values */ @@ -1833,7 +1833,7 @@ compute_scalar_stats(VacAttrStatsP stats, /* Sort the collected values */ cxt.cmpFn = &f_cmpfn; - cxt.cmpFnKind = cmpFnKind; + cxt.cmpFlags = cmpFlags; cxt.tupnoLink = tupnoLink; qsort_arg((void *) values, values_cnt, sizeof(ScalarItem), compare_scalars, (void *) &cxt); @@ -2203,7 +2203,7 @@ compare_scalars(const void *a, const void *b, void *arg) CompareScalarsContext *cxt = (CompareScalarsContext *) arg; int32 compare; - compare = ApplySortFunction(cxt->cmpFn, cxt->cmpFnKind, + compare = ApplySortFunction(cxt->cmpFn, cxt->cmpFlags, da, false, db, false); if (compare != 0) return compare; diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c index e35d6479db6..bbaa34f758a 100644 --- a/src/backend/commands/indexcmds.c +++ b/src/backend/commands/indexcmds.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/indexcmds.c,v 1.151 2007/01/05 22:19:26 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/commands/indexcmds.c,v 1.152 2007/01/09 02:14:11 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -49,10 +49,13 @@ /* non-export function prototypes */ static void CheckPredicate(Expr *predicate); -static void ComputeIndexAttrs(IndexInfo *indexInfo, Oid *classOidP, +static void ComputeIndexAttrs(IndexInfo *indexInfo, + Oid *classOidP, + int16 *colOptionP, List *attList, Oid relId, char *accessMethodName, Oid accessMethodId, + bool amcanorder, bool isconstraint); static Oid GetIndexOpClass(List *opclass, Oid attrType, char *accessMethodName, Oid accessMethodId); @@ -115,8 +118,10 @@ DefineIndex(RangeVar *heapRelation, Relation rel; HeapTuple tuple; Form_pg_am accessMethodForm; + bool amcanorder; RegProcedure amoptions; Datum reloptions; + int16 *coloptions; IndexInfo *indexInfo; int numberOfAttributes; List *old_xact_list; @@ -290,6 +295,8 @@ DefineIndex(RangeVar *heapRelation, errmsg("access method \"%s\" does not support multicolumn indexes", accessMethodName))); + amcanorder = (accessMethodForm->amorderstrategy > 0); + amoptions = accessMethodForm->amoptions; ReleaseSysCache(tuple); @@ -419,9 +426,10 @@ DefineIndex(RangeVar *heapRelation, indexInfo->ii_Concurrent = concurrent; classObjectId = (Oid *) palloc(numberOfAttributes * sizeof(Oid)); - ComputeIndexAttrs(indexInfo, classObjectId, attributeList, + coloptions = (int16 *) palloc(numberOfAttributes * sizeof(int16)); + ComputeIndexAttrs(indexInfo, classObjectId, coloptions, attributeList, relationId, accessMethodName, accessMethodId, - isconstraint); + amcanorder, isconstraint); heap_close(rel, NoLock); @@ -439,7 +447,7 @@ DefineIndex(RangeVar *heapRelation, indexRelationId = index_create(relationId, indexRelationName, indexRelationId, indexInfo, accessMethodId, tablespaceId, classObjectId, - reloptions, primary, isconstraint, + coloptions, reloptions, primary, isconstraint, allowSystemTableMods, skip_build, concurrent); if (!concurrent) @@ -585,13 +593,19 @@ CheckPredicate(Expr *predicate) errmsg("functions in index predicate must be marked IMMUTABLE"))); } +/* + * Compute per-index-column information, including indexed column numbers + * or index expressions, opclasses, and indoptions. + */ static void ComputeIndexAttrs(IndexInfo *indexInfo, Oid *classOidP, + int16 *colOptionP, List *attList, /* list of IndexElem's */ Oid relId, char *accessMethodName, Oid accessMethodId, + bool amcanorder, bool isconstraint) { ListCell *rest; @@ -605,6 +619,9 @@ ComputeIndexAttrs(IndexInfo *indexInfo, IndexElem *attribute = (IndexElem *) lfirst(rest); Oid atttype; + /* + * Process the column-or-expression to be indexed. + */ if (attribute->name != NULL) { /* Simple index attribute */ @@ -674,10 +691,49 @@ ComputeIndexAttrs(IndexInfo *indexInfo, errmsg("functions in index expression must be marked IMMUTABLE"))); } + /* + * Identify the opclass to use. + */ classOidP[attn] = GetIndexOpClass(attribute->opclass, atttype, accessMethodName, accessMethodId); + + /* + * Set up the per-column options (indoption field). For now, this + * is zero for any un-ordered index, while ordered indexes have DESC + * and NULLS FIRST/LAST options. + */ + colOptionP[attn] = 0; + if (amcanorder) + { + /* default ordering is ASC */ + if (attribute->ordering == SORTBY_DESC) + colOptionP[attn] |= INDOPTION_DESC; + /* default null ordering is LAST for ASC, FIRST for DESC */ + if (attribute->nulls_ordering == SORTBY_NULLS_DEFAULT) + { + if (attribute->ordering == SORTBY_DESC) + colOptionP[attn] |= INDOPTION_NULLS_FIRST; + } + else if (attribute->nulls_ordering == SORTBY_NULLS_FIRST) + colOptionP[attn] |= INDOPTION_NULLS_FIRST; + } + else + { + /* index AM does not support ordering */ + if (attribute->ordering != SORTBY_DEFAULT) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("access method \"%s\" does not support ASC/DESC options", + accessMethodName))); + if (attribute->nulls_ordering != SORTBY_NULLS_DEFAULT) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("access method \"%s\" does not support NULLS FIRST/LAST options", + accessMethodName))); + } + attn++; } } |
