*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/commands/indexcmds.c,v 1.21 2000/02/18 09:29:37 inoue Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/indexcmds.c,v 1.22 2000/02/25 02:58:48 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include "optimizer/planmain.h"
#include "optimizer/prep.h"
#include "parser/parsetree.h"
+#include "parser/parse_func.h"
#include "utils/builtins.h"
#include "utils/syscache.h"
#include "miscadmin.h" /* ReindexDatabase() */
#include "utils/portal.h" /* ReindexDatabase() */
#include "catalog/catalog.h" /* ReindexDatabase() */
-#define IsFuncIndex(ATTR_LIST) (((IndexElem*)lfirst(ATTR_LIST))->args!=NULL)
+#define IsFuncIndex(ATTR_LIST) (((IndexElem*)lfirst(ATTR_LIST))->args != NIL)
/* non-export function prototypes */
static void CheckPredicate(List *predList, List *rangeTable, Oid baseRelOid);
-static void CheckPredExpr(Node *predicate, List *rangeTable,
- Oid baseRelOid);
-static void
- CheckPredClause(Expr *predicate, List *rangeTable, Oid baseRelOid);
-static void FuncIndexArgs(IndexElem *funcIndex, AttrNumber *attNumP,
- Oid *argTypes, Oid *opOidP, Oid relId);
+static void CheckPredExpr(Node *predicate, List *rangeTable, Oid baseRelOid);
+static void CheckPredClause(Expr *predicate, List *rangeTable, Oid baseRelOid);
+static void FuncIndexArgs(IndexElem *funcIndex, FuncIndexInfo *funcInfo,
+ AttrNumber *attNumP, Oid *opOidP, Oid relId);
static void NormIndexAttrs(List *attList, AttrNumber *attNumP,
- Oid *opOidP, Oid relId);
+ Oid *opOidP, Oid relId);
+static void ProcessAttrTypename(IndexElem *attribute,
+ Oid defType, int32 defTypmod);
+static Oid GetAttrOpClass(IndexElem *attribute, Oid attrType);
static char *GetDefaultOpClass(Oid atttypid);
/*
FIsetnArgs(&fInfo, nargs);
- strcpy(FIgetname(&fInfo), funcIndex->name);
-
- attributeNumberA = (AttrNumber *) palloc(nargs * sizeof attributeNumberA[0]);
+ namestrcpy(&fInfo.funcName, funcIndex->name);
- classObjectId = (Oid *) palloc(sizeof classObjectId[0]);
+ attributeNumberA = (AttrNumber *) palloc(nargs *
+ sizeof attributeNumberA[0]);
+ classObjectId = (Oid *) palloc(sizeof(Oid));
- FuncIndexArgs(funcIndex, attributeNumberA,
- &(FIgetArg(&fInfo, 0)),
+ FuncIndexArgs(funcIndex, &fInfo, attributeNumberA,
classObjectId, relationId);
index_create(heapRelationName,
indexRelationName,
&fInfo, NULL, accessMethodId,
numberOfAttributes, attributeNumberA,
- classObjectId, parameterCount, parameterA, (Node *) cnfPred,
+ classObjectId, parameterCount, parameterA,
+ (Node *) cnfPred,
lossy, unique, primary);
}
else
{
attributeNumberA = (AttrNumber *) palloc(numberOfAttributes *
- sizeof attributeNumberA[0]);
+ sizeof attributeNumberA[0]);
- classObjectId = (Oid *) palloc(numberOfAttributes * sizeof classObjectId[0]);
+ classObjectId = (Oid *) palloc(numberOfAttributes * sizeof(Oid));
NormIndexAttrs(attributeList, attributeNumberA,
classObjectId, relationId);
index_create(heapRelationName, indexRelationName, NULL,
attributeList,
accessMethodId, numberOfAttributes, attributeNumberA,
- classObjectId, parameterCount, parameterA, (Node *) cnfPred,
+ classObjectId, parameterCount, parameterA,
+ (Node *) cnfPred,
lossy, unique, primary);
}
+
setRelhasindexInplace(relationId, true, false);
}
if (indproc != InvalidOid)
{
funcInfo = &fInfo;
-/* FIgetnArgs(funcInfo) = numberOfAttributes; */
FIsetnArgs(funcInfo, numberOfAttributes);
tuple = SearchSysCacheTuple(PROCOID,
static void
FuncIndexArgs(IndexElem *funcIndex,
+ FuncIndexInfo *funcInfo,
AttrNumber *attNumP,
- Oid *argTypes,
Oid *opOidP,
Oid relId)
{
List *rest;
HeapTuple tuple;
- Form_pg_attribute att;
-
- tuple = SearchSysCacheTuple(CLANAME,
- PointerGetDatum(funcIndex->class),
- 0, 0, 0);
-
- if (!HeapTupleIsValid(tuple))
- {
- elog(ERROR, "DefineIndex: %s class not found",
- funcIndex->class);
- }
- *opOidP = tuple->t_data->t_oid;
-
- MemSet(argTypes, 0, FUNC_MAX_ARGS * sizeof(Oid));
+ Oid retType;
+ int argn = 0;
/*
- * process the function arguments
+ * process the function arguments, which are a list of T_String
+ * (someday ought to allow more general expressions?)
*/
- for (rest = funcIndex->args; rest != NIL; rest = lnext(rest))
- {
- char *arg;
+ MemSet(funcInfo->arglist, 0, FUNC_MAX_ARGS * sizeof(Oid));
- arg = strVal(lfirst(rest));
+ foreach(rest, funcIndex->args)
+ {
+ char *arg = strVal(lfirst(rest));
+ Form_pg_attribute att;
tuple = SearchSysCacheTuple(ATTNAME,
ObjectIdGetDatum(relId),
PointerGetDatum(arg), 0, 0);
if (!HeapTupleIsValid(tuple))
- {
- elog(ERROR,
- "DefineIndex: attribute \"%s\" not found",
- arg);
- }
+ elog(ERROR, "DefineIndex: attribute \"%s\" not found", arg);
att = (Form_pg_attribute) GETSTRUCT(tuple);
*attNumP++ = att->attnum;
- *argTypes++ = att->atttypid;
+ funcInfo->arglist[argn++] = att->atttypid;
+ }
+
+ /* ----------------
+ * Lookup the function procedure to get its OID and result type.
+ * ----------------
+ */
+ tuple = SearchSysCacheTuple(PROCNAME,
+ PointerGetDatum(FIgetname(funcInfo)),
+ Int32GetDatum(FIgetnArgs(funcInfo)),
+ PointerGetDatum(FIgetArglist(funcInfo)),
+ 0);
+
+ if (!HeapTupleIsValid(tuple))
+ {
+ func_error("DefineIndex", FIgetname(funcInfo),
+ FIgetnArgs(funcInfo), FIgetArglist(funcInfo), NULL);
}
+
+ FIsetProcOid(funcInfo, tuple->t_data->t_oid);
+ retType = ((Form_pg_proc) GETSTRUCT(tuple))->prorettype;
+
+ /* Process type and opclass, using func return type as default */
+
+ ProcessAttrTypename(funcIndex, retType, -1);
+
+ *opOidP = GetAttrOpClass(funcIndex, retType);
}
static void
Oid relId)
{
List *rest;
- HeapTuple atttuple,
- tuple;
/*
* process attributeList
*/
-
- for (rest = attList; rest != NIL; rest = lnext(rest))
+ foreach(rest, attList)
{
- IndexElem *attribute;
+ IndexElem *attribute = lfirst(rest);
+ HeapTuple atttuple;
Form_pg_attribute attform;
- attribute = lfirst(rest);
-
if (attribute->name == NULL)
elog(ERROR, "missing attribute for define index");
atttuple = SearchSysCacheTupleCopy(ATTNAME,
ObjectIdGetDatum(relId),
- PointerGetDatum(attribute->name),
+ PointerGetDatum(attribute->name),
0, 0);
if (!HeapTupleIsValid(atttuple))
- {
- elog(ERROR,
- "DefineIndex: attribute \"%s\" not found",
+ elog(ERROR, "DefineIndex: attribute \"%s\" not found",
attribute->name);
- }
-
attform = (Form_pg_attribute) GETSTRUCT(atttuple);
+
*attNumP++ = attform->attnum;
- /* we want the type so we can set the proper alignment, etc. */
- if (attribute->typename == NULL)
- {
- tuple = SearchSysCacheTuple(TYPEOID,
- ObjectIdGetDatum(attform->atttypid),
- 0, 0, 0);
- if (!HeapTupleIsValid(tuple))
- elog(ERROR, "create index: type for attribute '%s' undefined",
- attribute->name);
- /* we just set the type name because that is all we need */
- attribute->typename = makeNode(TypeName);
- attribute->typename->name = nameout(&((Form_pg_type) GETSTRUCT(tuple))->typname);
-
- /* we all need the typmod for the char and varchar types. */
- attribute->typename->typmod = attform->atttypmod;
- }
+ ProcessAttrTypename(attribute, attform->atttypid, attform->atttypmod);
- if (attribute->class == NULL)
- {
- /* no operator class specified, so find the default */
- attribute->class = GetDefaultOpClass(attform->atttypid);
- if (attribute->class == NULL)
- {
- elog(ERROR,
- "Can't find a default operator class for type %u.",
- attform->atttypid);
- }
- }
+ *classOidP++ = GetAttrOpClass(attribute, attform->atttypid);
- tuple = SearchSysCacheTuple(CLANAME,
- PointerGetDatum(attribute->class),
- 0, 0, 0);
+ heap_freetuple(atttuple);
+ }
+}
+static void
+ProcessAttrTypename(IndexElem *attribute,
+ Oid defType, int32 defTypmod)
+{
+ HeapTuple tuple;
+
+ /* build a type node so we can set the proper alignment, etc. */
+ if (attribute->typename == NULL)
+ {
+ tuple = SearchSysCacheTuple(TYPEOID,
+ ObjectIdGetDatum(defType),
+ 0, 0, 0);
if (!HeapTupleIsValid(tuple))
- {
- elog(ERROR, "DefineIndex: %s class not found",
- attribute->class);
- }
- *classOidP++ = tuple->t_data->t_oid;
- heap_freetuple(atttuple);
+ elog(ERROR, "DefineIndex: type for attribute '%s' undefined",
+ attribute->name);
+
+ attribute->typename = makeNode(TypeName);
+ attribute->typename->name = nameout(&((Form_pg_type) GETSTRUCT(tuple))->typname);
+ attribute->typename->typmod = defTypmod;
}
}
+static Oid
+GetAttrOpClass(IndexElem *attribute, Oid attrType)
+{
+ HeapTuple tuple;
+
+ if (attribute->class == NULL)
+ {
+ /* no operator class specified, so find the default */
+ attribute->class = GetDefaultOpClass(attrType);
+ if (attribute->class == NULL)
+ elog(ERROR, "Can't find a default operator class for type %u",
+ attrType);
+ }
+
+ tuple = SearchSysCacheTuple(CLANAME,
+ PointerGetDatum(attribute->class),
+ 0, 0, 0);
+
+ if (!HeapTupleIsValid(tuple))
+ elog(ERROR, "DefineIndex: %s opclass not found",
+ attribute->class);
+
+ return tuple->t_data->t_oid;
+}
+
static char *
GetDefaultOpClass(Oid atttypid)
{