functional index arg matching patch
Attached is a patch to allow
functinal indecies to use functions that
are for 'binary-compatible' types.
eg
create function foobar(text) returns text as ....
create table vc ( a varchar );
create index on vc ( foobar(a) );
should now work.
--
Mark Hollomon
mhh@mindspring.com
Attachments:
index.patchtext/plain; charset=us-asciiDownload
*** 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; i<argn; i++)
! {
! bestArgTypes[i] = pgProcP->proargtypes[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 */
Tom Lane wrote:
Mark Hollomon <mhh@mindspring.com> writes:
Attached is a patch to allow
functinal indecies to use functions that
are for 'binary-compatible' types.Um, thanks for working on this, but I already fixed that...
regards, tom lane
When? A message you sent on 8-11 indicated it wasn't.
And I didn't see any code in CVS as of ~ 8-17
when I started. But I may have missed it.
I'll be interested in seeing how you
did it.
--
Mark Hollomon
mhh@nortelnetworks.com
"Mark Hollomon" <mhh@nortelnetworks.com> writes:
Tom Lane wrote:
Um, thanks for working on this, but I already fixed that...
When? A message you sent on 8-11 indicated it wasn't.
(Checks CVS) ... yesterday, actually.
I'll be interested in seeing how you did it.
I just called the ambiguous-function-name-resolution code in
parse_func.c and then checked to make sure it hadn't selected
something the executor wasn't prepared to cope with --- ie,
functions requiring runtime conversions of input data types.
It looked like you had copied out a bunch of the parse_func.c code,
which is OK in the short run but the duplicated code might be
a headache to keep in sync later on.
regards, tom lane
Tom Lane wrote:
"Mark Hollomon" <mhh@nortelnetworks.com> writes:
Tom Lane wrote:
Um, thanks for working on this, but I already fixed that...
When? A message you sent on 8-11 indicated it wasn't.
(Checks CVS) ... yesterday, actually.
Yea, I saw it when a refreshed last night.
I'll be interested in seeing how you did it.
I just called the ambiguous-function-name-resolution code in
parse_func.c and then checked to make sure it hadn't selected
something the executor wasn't prepared to cope with --- ie,
functions requiring runtime conversions of input data types.It looked like you had copied out a bunch of the parse_func.c code,
which is OK in the short run but the duplicated code might be
a headache to keep in sync later on.
I had thought about doing it the way you did, but didn't know the
consequences of some of the other coersions that parse_func.c
tried to do. My guess that it wasn't harmless was correct judging from
your code.
--
Mark Hollomon
mhh@nortelnetworks.com
ESN 451-9008 (302)454-9008