8
8
*
9
9
*
10
10
* IDENTIFICATION
11
- * $Header: /cvsroot/pgsql/src/backend/commands/indexcmds.c,v 1.21 2000/02/18 09:29:37 inoue Exp $
11
+ * $Header: /cvsroot/pgsql/src/backend/commands/indexcmds.c,v 1.22 2000/02/25 02:58:48 tgl Exp $
12
12
*
13
13
*-------------------------------------------------------------------------
14
14
*/
31
31
#include "optimizer/planmain.h"
32
32
#include "optimizer/prep.h"
33
33
#include "parser/parsetree.h"
34
+ #include "parser/parse_func.h"
34
35
#include "utils/builtins.h"
35
36
#include "utils/syscache.h"
36
37
#include "miscadmin.h" /* ReindexDatabase() */
37
38
#include "utils/portal.h" /* ReindexDatabase() */
38
39
#include "catalog/catalog.h" /* ReindexDatabase() */
39
40
40
- #define IsFuncIndex (ATTR_LIST ) (((IndexElem*)lfirst(ATTR_LIST))->args!=NULL )
41
+ #define IsFuncIndex (ATTR_LIST ) (((IndexElem*)lfirst(ATTR_LIST))->args != NIL )
41
42
42
43
/* non-export function prototypes */
43
44
static void CheckPredicate (List * predList , List * rangeTable , Oid baseRelOid );
44
- static void CheckPredExpr (Node * predicate , List * rangeTable ,
45
- Oid baseRelOid );
46
- static void
47
- CheckPredClause (Expr * predicate , List * rangeTable , Oid baseRelOid );
48
- static void FuncIndexArgs (IndexElem * funcIndex , AttrNumber * attNumP ,
49
- Oid * argTypes , Oid * opOidP , Oid relId );
45
+ static void CheckPredExpr (Node * predicate , List * rangeTable , Oid baseRelOid );
46
+ static void CheckPredClause (Expr * predicate , List * rangeTable , Oid baseRelOid );
47
+ static void FuncIndexArgs (IndexElem * funcIndex , FuncIndexInfo * funcInfo ,
48
+ AttrNumber * attNumP , Oid * opOidP , Oid relId );
50
49
static void NormIndexAttrs (List * attList , AttrNumber * attNumP ,
51
- Oid * opOidP , Oid relId );
50
+ Oid * opOidP , Oid relId );
51
+ static void ProcessAttrTypename (IndexElem * attribute ,
52
+ Oid defType , int32 defTypmod );
53
+ static Oid GetAttrOpClass (IndexElem * attribute , Oid attrType );
52
54
static char * GetDefaultOpClass (Oid atttypid );
53
55
54
56
/*
@@ -169,40 +171,42 @@ DefineIndex(char *heapRelationName,
169
171
170
172
FIsetnArgs (& fInfo , nargs );
171
173
172
- strcpy (FIgetname (& fInfo ), funcIndex -> name );
173
-
174
- attributeNumberA = (AttrNumber * ) palloc (nargs * sizeof attributeNumberA [0 ]);
174
+ namestrcpy (& fInfo .funcName , funcIndex -> name );
175
175
176
- classObjectId = (Oid * ) palloc (sizeof classObjectId [0 ]);
176
+ attributeNumberA = (AttrNumber * ) palloc (nargs *
177
+ sizeof attributeNumberA [0 ]);
177
178
179
+ classObjectId = (Oid * ) palloc (sizeof (Oid ));
178
180
179
- FuncIndexArgs (funcIndex , attributeNumberA ,
180
- & (FIgetArg (& fInfo , 0 )),
181
+ FuncIndexArgs (funcIndex , & fInfo , attributeNumberA ,
181
182
classObjectId , relationId );
182
183
183
184
index_create (heapRelationName ,
184
185
indexRelationName ,
185
186
& fInfo , NULL , accessMethodId ,
186
187
numberOfAttributes , attributeNumberA ,
187
- classObjectId , parameterCount , parameterA , (Node * ) cnfPred ,
188
+ classObjectId , parameterCount , parameterA ,
189
+ (Node * ) cnfPred ,
188
190
lossy , unique , primary );
189
191
}
190
192
else
191
193
{
192
194
attributeNumberA = (AttrNumber * ) palloc (numberOfAttributes *
193
- sizeof attributeNumberA [0 ]);
195
+ sizeof attributeNumberA [0 ]);
194
196
195
- classObjectId = (Oid * ) palloc (numberOfAttributes * sizeof classObjectId [ 0 ] );
197
+ classObjectId = (Oid * ) palloc (numberOfAttributes * sizeof ( Oid ) );
196
198
197
199
NormIndexAttrs (attributeList , attributeNumberA ,
198
200
classObjectId , relationId );
199
201
200
202
index_create (heapRelationName , indexRelationName , NULL ,
201
203
attributeList ,
202
204
accessMethodId , numberOfAttributes , attributeNumberA ,
203
- classObjectId , parameterCount , parameterA , (Node * ) cnfPred ,
205
+ classObjectId , parameterCount , parameterA ,
206
+ (Node * ) cnfPred ,
204
207
lossy , unique , primary );
205
208
}
209
+
206
210
setRelhasindexInplace (relationId , true, false);
207
211
}
208
212
@@ -320,7 +324,6 @@ ExtendIndex(char *indexRelationName, Expr *predicate, List *rangetable)
320
324
if (indproc != InvalidOid )
321
325
{
322
326
funcInfo = & fInfo ;
323
- /* FIgetnArgs(funcInfo) = numberOfAttributes; */
324
327
FIsetnArgs (funcInfo , numberOfAttributes );
325
328
326
329
tuple = SearchSysCacheTuple (PROCOID ,
@@ -407,51 +410,62 @@ CheckPredClause(Expr *predicate, List *rangeTable, Oid baseRelOid)
407
410
408
411
static void
409
412
FuncIndexArgs (IndexElem * funcIndex ,
413
+ FuncIndexInfo * funcInfo ,
410
414
AttrNumber * attNumP ,
411
- Oid * argTypes ,
412
415
Oid * opOidP ,
413
416
Oid relId )
414
417
{
415
418
List * rest ;
416
419
HeapTuple tuple ;
417
- Form_pg_attribute att ;
418
-
419
- tuple = SearchSysCacheTuple (CLANAME ,
420
- PointerGetDatum (funcIndex -> class ),
421
- 0 , 0 , 0 );
422
-
423
- if (!HeapTupleIsValid (tuple ))
424
- {
425
- elog (ERROR , "DefineIndex: %s class not found" ,
426
- funcIndex -> class );
427
- }
428
- * opOidP = tuple -> t_data -> t_oid ;
429
-
430
- MemSet (argTypes , 0 , FUNC_MAX_ARGS * sizeof (Oid ));
420
+ Oid retType ;
421
+ int argn = 0 ;
431
422
432
423
/*
433
- * process the function arguments
424
+ * process the function arguments, which are a list of T_String
425
+ * (someday ought to allow more general expressions?)
434
426
*/
435
- for (rest = funcIndex -> args ; rest != NIL ; rest = lnext (rest ))
436
- {
437
- char * arg ;
427
+ MemSet (funcInfo -> arglist , 0 , FUNC_MAX_ARGS * sizeof (Oid ));
438
428
439
- arg = strVal (lfirst (rest ));
429
+ foreach (rest , funcIndex -> args )
430
+ {
431
+ char * arg = strVal (lfirst (rest ));
432
+ Form_pg_attribute att ;
440
433
441
434
tuple = SearchSysCacheTuple (ATTNAME ,
442
435
ObjectIdGetDatum (relId ),
443
436
PointerGetDatum (arg ), 0 , 0 );
444
437
445
438
if (!HeapTupleIsValid (tuple ))
446
- {
447
- elog (ERROR ,
448
- "DefineIndex: attribute \"%s\" not found" ,
449
- arg );
450
- }
439
+ elog (ERROR , "DefineIndex: attribute \"%s\" not found" , arg );
451
440
att = (Form_pg_attribute ) GETSTRUCT (tuple );
452
441
* attNumP ++ = att -> attnum ;
453
- * argTypes ++ = att -> atttypid ;
442
+ funcInfo -> arglist [argn ++ ] = att -> atttypid ;
443
+ }
444
+
445
+ /* ----------------
446
+ * Lookup the function procedure to get its OID and result type.
447
+ * ----------------
448
+ */
449
+ tuple = SearchSysCacheTuple (PROCNAME ,
450
+ PointerGetDatum (FIgetname (funcInfo )),
451
+ Int32GetDatum (FIgetnArgs (funcInfo )),
452
+ PointerGetDatum (FIgetArglist (funcInfo )),
453
+ 0 );
454
+
455
+ if (!HeapTupleIsValid (tuple ))
456
+ {
457
+ func_error ("DefineIndex" , FIgetname (funcInfo ),
458
+ FIgetnArgs (funcInfo ), FIgetArglist (funcInfo ), NULL );
454
459
}
460
+
461
+ FIsetProcOid (funcInfo , tuple -> t_data -> t_oid );
462
+ retType = ((Form_pg_proc ) GETSTRUCT (tuple ))-> prorettype ;
463
+
464
+ /* Process type and opclass, using func return type as default */
465
+
466
+ ProcessAttrTypename (funcIndex , retType , -1 );
467
+
468
+ * opOidP = GetAttrOpClass (funcIndex , retType );
455
469
}
456
470
457
471
static void
@@ -461,80 +475,85 @@ NormIndexAttrs(List *attList, /* list of IndexElem's */
461
475
Oid relId )
462
476
{
463
477
List * rest ;
464
- HeapTuple atttuple ,
465
- tuple ;
466
478
467
479
/*
468
480
* process attributeList
469
481
*/
470
-
471
- for (rest = attList ; rest != NIL ; rest = lnext (rest ))
482
+ foreach (rest , attList )
472
483
{
473
- IndexElem * attribute ;
484
+ IndexElem * attribute = lfirst (rest );
485
+ HeapTuple atttuple ;
474
486
Form_pg_attribute attform ;
475
487
476
- attribute = lfirst (rest );
477
-
478
488
if (attribute -> name == NULL )
479
489
elog (ERROR , "missing attribute for define index" );
480
490
481
491
atttuple = SearchSysCacheTupleCopy (ATTNAME ,
482
492
ObjectIdGetDatum (relId ),
483
- PointerGetDatum (attribute -> name ),
493
+ PointerGetDatum (attribute -> name ),
484
494
0 , 0 );
485
495
if (!HeapTupleIsValid (atttuple ))
486
- {
487
- elog (ERROR ,
488
- "DefineIndex: attribute \"%s\" not found" ,
496
+ elog (ERROR , "DefineIndex: attribute \"%s\" not found" ,
489
497
attribute -> name );
490
- }
491
-
492
498
attform = (Form_pg_attribute ) GETSTRUCT (atttuple );
499
+
493
500
* attNumP ++ = attform -> attnum ;
494
501
495
- /* we want the type so we can set the proper alignment, etc. */
496
- if (attribute -> typename == NULL )
497
- {
498
- tuple = SearchSysCacheTuple (TYPEOID ,
499
- ObjectIdGetDatum (attform -> atttypid ),
500
- 0 , 0 , 0 );
501
- if (!HeapTupleIsValid (tuple ))
502
- elog (ERROR , "create index: type for attribute '%s' undefined" ,
503
- attribute -> name );
504
- /* we just set the type name because that is all we need */
505
- attribute -> typename = makeNode (TypeName );
506
- attribute -> typename -> name = nameout (& ((Form_pg_type ) GETSTRUCT (tuple ))-> typname );
507
-
508
- /* we all need the typmod for the char and varchar types. */
509
- attribute -> typename -> typmod = attform -> atttypmod ;
510
- }
502
+ ProcessAttrTypename (attribute , attform -> atttypid , attform -> atttypmod );
511
503
512
- if (attribute -> class == NULL )
513
- {
514
- /* no operator class specified, so find the default */
515
- attribute -> class = GetDefaultOpClass (attform -> atttypid );
516
- if (attribute -> class == NULL )
517
- {
518
- elog (ERROR ,
519
- "Can't find a default operator class for type %u." ,
520
- attform -> atttypid );
521
- }
522
- }
504
+ * classOidP ++ = GetAttrOpClass (attribute , attform -> atttypid );
523
505
524
- tuple = SearchSysCacheTuple ( CLANAME ,
525
- PointerGetDatum ( attribute -> class ),
526
- 0 , 0 , 0 );
506
+ heap_freetuple ( atttuple );
507
+ }
508
+ }
527
509
510
+ static void
511
+ ProcessAttrTypename (IndexElem * attribute ,
512
+ Oid defType , int32 defTypmod )
513
+ {
514
+ HeapTuple tuple ;
515
+
516
+ /* build a type node so we can set the proper alignment, etc. */
517
+ if (attribute -> typename == NULL )
518
+ {
519
+ tuple = SearchSysCacheTuple (TYPEOID ,
520
+ ObjectIdGetDatum (defType ),
521
+ 0 , 0 , 0 );
528
522
if (!HeapTupleIsValid (tuple ))
529
- {
530
- elog ( ERROR , "DefineIndex: %s class not found" ,
531
- attribute -> class );
532
- }
533
- * classOidP ++ = tuple -> t_data -> t_oid ;
534
- heap_freetuple ( atttuple ) ;
523
+ elog ( ERROR , "DefineIndex: type for attribute '%s' undefined" ,
524
+ attribute -> name );
525
+
526
+ attribute -> typename = makeNode ( TypeName );
527
+ attribute -> typename -> name = nameout ( & (( Form_pg_type ) GETSTRUCT ( tuple )) -> typname ) ;
528
+ attribute -> typename -> typmod = defTypmod ;
535
529
}
536
530
}
537
531
532
+ static Oid
533
+ GetAttrOpClass (IndexElem * attribute , Oid attrType )
534
+ {
535
+ HeapTuple tuple ;
536
+
537
+ if (attribute -> class == NULL )
538
+ {
539
+ /* no operator class specified, so find the default */
540
+ attribute -> class = GetDefaultOpClass (attrType );
541
+ if (attribute -> class == NULL )
542
+ elog (ERROR , "Can't find a default operator class for type %u" ,
543
+ attrType );
544
+ }
545
+
546
+ tuple = SearchSysCacheTuple (CLANAME ,
547
+ PointerGetDatum (attribute -> class ),
548
+ 0 , 0 , 0 );
549
+
550
+ if (!HeapTupleIsValid (tuple ))
551
+ elog (ERROR , "DefineIndex: %s opclass not found" ,
552
+ attribute -> class );
553
+
554
+ return tuple -> t_data -> t_oid ;
555
+ }
556
+
538
557
static char *
539
558
GetDefaultOpClass (Oid atttypid )
540
559
{
0 commit comments