*** indexcmds.c.orig Fri Aug 18 21:38:34 2000 --- indexcmds.c Mon Aug 21 11:42:16 2000 *************** *** 21,26 **** --- 21,27 ---- #include "catalog/catname.h" #include "catalog/heap.h" #include "catalog/index.h" + #include "catalog/indexing.h" #include "catalog/pg_am.h" #include "catalog/pg_amop.h" #include "catalog/pg_database.h" *************** *** 414,425 **** 0); if (!HeapTupleIsValid(tuple)) { ! func_error("DefineIndex", funcIndex->name, ! indexInfo->ii_NumKeyAttrs, argTypes, NULL); } indexInfo->ii_FuncOid = tuple->t_data->t_oid; retType = ((Form_pg_proc) GETSTRUCT(tuple))->prorettype; /* Process opclass, using func return type as default type */ --- 415,527 ---- 0); if (!HeapTupleIsValid(tuple)) { ! Relation heapRelation; ! Relation idesc; ! ScanKeyData skey; ! HeapTupleData stuple; ! IndexScanDesc sd; ! RetrieveIndexResult indexRes; ! Form_pg_proc pgProcP; ! int best_arg_match; ! int match_count; ! Oid bestArgTypes[FUNC_MAX_ARGS]; ! ! MemSet(bestArgTypes, 0, sizeof(bestArgTypes)); ! ! heapRelation = heap_openr(ProcedureRelationName, AccessShareLock); ! ! ScanKeyEntryInitialize(&skey, ! (bits16) 0x0, ! (AttrNumber) Anum_pg_proc_proname, ! (RegProcedure) F_NAMEEQ, ! (Datum) funcIndex->name); ! ! idesc = index_openr(ProcedureNameIndex); ! ! sd = index_beginscan(idesc, false, 1, &skey); ! ! /* The number of exact arg matches for the best match so far */ ! best_arg_match = -1; ! /* the number of functions with best_arg_match matches seen. ! * If we end with this being more than one, there is an ambiguity ! */ ! match_count = 0; ! ! do ! { ! indexRes = index_getnext(sd, ForwardScanDirection); ! if (indexRes) ! { ! Buffer buffer; ! ! stuple.t_datamcxt = NULL; ! stuple.t_data = NULL; ! stuple.t_self = indexRes->heap_iptr; ! heap_fetch(heapRelation, SnapshotNow, &stuple, &buffer); ! pfree(indexRes); ! if (stuple.t_data != NULL) ! { ! pgProcP = (Form_pg_proc) GETSTRUCT(&stuple); ! if (pgProcP->pronargs == argn) ! { ! int current_match_count; ! int i; ! ! current_match_count = 0; ! for (i=0; i< argn; i++) ! { ! if (argTypes[i] == pgProcP->proargtypes[i]) { ! current_match_count += 1; ! } else if (! IS_BINARY_COMPATIBLE(argTypes[i], pgProcP->proargtypes[i])) ! { ! break; ! } ! } ! if (i == argn) ! { ! if (current_match_count > best_arg_match) ! { ! best_arg_match = current_match_count; ! match_count = 1; ! for (i=0; iproargtypes[i]; ! } ! } else if (current_match_count == best_arg_match) ! { ! match_count += 1; ! } ! } ! } ! ReleaseBuffer(buffer); ! } ! } ! }while (indexRes); ! ! index_endscan(sd); ! index_close(idesc); ! heap_close(heapRelation, AccessShareLock); ! ! if (match_count != 1) ! { ! func_error("DefineIndex", funcIndex->name, ! indexInfo->ii_NumKeyAttrs, argTypes, NULL); ! } ! tuple = SearchSysCacheTuple(PROCNAME, ! PointerGetDatum(funcIndex->name), ! Int32GetDatum(indexInfo->ii_NumKeyAttrs), ! PointerGetDatum(bestArgTypes), ! 0); ! if (! HeapTupleIsValid(tuple)) ! { ! elog(ERROR, "Gosh, why couldn't we find the function after matching its args"); ! } ! } indexInfo->ii_FuncOid = tuple->t_data->t_oid; retType = ((Form_pg_proc) GETSTRUCT(tuple))->prorettype; + /* Process opclass, using func return type as default type */