YugabyteDB (2.13.0.0-b42, bfc6a6643e7399ac8a0e81d06a3ee6d6571b33ab)

Coverage Report

Created: 2022-03-09 17:30

/Users/deen/code/yugabyte-db/src/postgres/src/backend/access/index/amapi.c
Line
Count
Source (jump to first uncovered line)
1
/*-------------------------------------------------------------------------
2
 *
3
 * amapi.c
4
 *    Support routines for API for Postgres index access methods.
5
 *
6
 * Copyright (c) 2015-2018, PostgreSQL Global Development Group
7
 *
8
 *
9
 * IDENTIFICATION
10
 *    src/backend/access/index/amapi.c
11
 *
12
 *-------------------------------------------------------------------------
13
 */
14
#include "postgres.h"
15
16
#include "access/amapi.h"
17
#include "access/htup_details.h"
18
#include "catalog/pg_am.h"
19
#include "catalog/pg_opclass.h"
20
#include "utils/builtins.h"
21
#include "utils/syscache.h"
22
23
24
/*
25
 * GetIndexAmRoutine - call the specified access method handler routine to get
26
 * its IndexAmRoutine struct, which will be palloc'd in the caller's context.
27
 *
28
 * Note that if the amhandler function is built-in, this will not involve
29
 * any catalog access.  It's therefore safe to use this while bootstrapping
30
 * indexes for the system catalogs.  relcache.c relies on that.
31
 */
32
IndexAmRoutine *
33
GetIndexAmRoutine(Oid amhandler)
34
193k
{
35
193k
  Datum   datum;
36
193k
  IndexAmRoutine *routine;
37
38
193k
  datum = OidFunctionCall0(amhandler);
39
193k
  routine = (IndexAmRoutine *) DatumGetPointer(datum);
40
41
193k
  if (routine == NULL || !IsA(routine, IndexAmRoutine))
42
0
    elog(ERROR, "index access method handler function %u did not return an IndexAmRoutine struct",
43
193k
       amhandler);
44
45
193k
  return routine;
46
193k
}
47
48
/*
49
 * GetIndexAmRoutineByAmId - look up the handler of the index access method
50
 * with the given OID, and get its IndexAmRoutine struct.
51
 *
52
 * If the given OID isn't a valid index access method, returns NULL if
53
 * noerror is true, else throws error.
54
 */
55
IndexAmRoutine *
56
GetIndexAmRoutineByAmId(Oid amoid, bool noerror)
57
1.00k
{
58
1.00k
  HeapTuple tuple;
59
1.00k
  Form_pg_am  amform;
60
1.00k
  regproc   amhandler;
61
62
  /* Get handler function OID for the access method */
63
1.00k
  tuple = SearchSysCache1(AMOID, ObjectIdGetDatum(amoid));
64
1.00k
  if (!HeapTupleIsValid(tuple))
65
0
  {
66
0
    if (noerror)
67
0
      return NULL;
68
0
    elog(ERROR, "cache lookup failed for access method %u",
69
0
       amoid);
70
0
  }
71
1.00k
  amform = (Form_pg_am) GETSTRUCT(tuple);
72
73
  /* Check if it's an index access method as opposed to some other AM */
74
1.00k
  if (amform->amtype != AMTYPE_INDEX)
75
0
  {
76
0
    if (noerror)
77
0
    {
78
0
      ReleaseSysCache(tuple);
79
0
      return NULL;
80
0
    }
81
0
    ereport(ERROR,
82
0
        (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
83
0
         errmsg("access method \"%s\" is not of type %s",
84
0
            NameStr(amform->amname), "INDEX")));
85
0
  }
86
87
1.00k
  amhandler = amform->amhandler;
88
89
  /* Complain if handler OID is invalid */
90
1.00k
  if (!RegProcedureIsValid(amhandler))
91
0
  {
92
0
    if (noerror)
93
0
    {
94
0
      ReleaseSysCache(tuple);
95
0
      return NULL;
96
0
    }
97
0
    ereport(ERROR,
98
0
        (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
99
0
         errmsg("index access method \"%s\" does not have a handler",
100
0
            NameStr(amform->amname))));
101
0
  }
102
103
1.00k
  ReleaseSysCache(tuple);
104
105
  /* And finally, call the handler function to get the API struct. */
106
1.00k
  return GetIndexAmRoutine(amhandler);
107
1.00k
}
108
109
110
/*
111
 * Ask appropriate access method to validate the specified opclass.
112
 */
113
Datum
114
amvalidate(PG_FUNCTION_ARGS)
115
5
{
116
5
  Oid     opclassoid = PG_GETARG_OID(0);
117
5
  bool    result;
118
5
  HeapTuple classtup;
119
5
  Form_pg_opclass classform;
120
5
  Oid     amoid;
121
5
  IndexAmRoutine *amroutine;
122
123
5
  classtup = SearchSysCache1(CLAOID, ObjectIdGetDatum(opclassoid));
124
5
  if (!HeapTupleIsValid(classtup))
125
0
    elog(ERROR, "cache lookup failed for operator class %u", opclassoid);
126
5
  classform = (Form_pg_opclass) GETSTRUCT(classtup);
127
128
5
  amoid = classform->opcmethod;
129
130
5
  ReleaseSysCache(classtup);
131
132
5
  amroutine = GetIndexAmRoutineByAmId(amoid, false);
133
134
5
  if (amroutine->amvalidate == NULL)
135
0
    elog(ERROR, "function amvalidate is not defined for index access method %u",
136
5
       amoid);
137
138
5
  result = amroutine->amvalidate(opclassoid);
139
140
5
  pfree(amroutine);
141
142
5
  PG_RETURN_BOOL(result);
143
5
}