1717#include "access/xact.h"
1818#include "catalog/pg_am.h"
1919#include "catalog/pg_proc.h"
20+ #include "commands/defrem.h"
2021#include "utils/fmgroids.h"
2122#include "utils/memutils.h"
2223#include "utils/syscache.h"
2324
2425
25- static Oid get_table_am_oid (const char * tableamname , bool missing_ok );
26-
27-
2826/*
2927 * GetTableAmRoutine
3028 * Call the specified access method handler routine to get its
@@ -41,7 +39,7 @@ GetTableAmRoutine(Oid amhandler)
4139 routine = (TableAmRoutine * ) DatumGetPointer (datum );
4240
4341 if (routine == NULL || !IsA (routine , TableAmRoutine ))
44- elog (ERROR , "Table access method handler %u did not return a TableAmRoutine struct" ,
42+ elog (ERROR , "table access method handler %u did not return a TableAmRoutine struct" ,
4543 amhandler );
4644
4745 /*
@@ -98,106 +96,30 @@ GetTableAmRoutine(Oid amhandler)
9896 return routine ;
9997}
10098
101- /*
102- * GetTableAmRoutineByAmId - look up the handler of the table access
103- * method with the given OID, and get its TableAmRoutine struct.
104- */
105- const TableAmRoutine *
106- GetTableAmRoutineByAmId (Oid amoid )
107- {
108- regproc amhandler ;
109- HeapTuple tuple ;
110- Form_pg_am amform ;
111-
112- /* Get handler function OID for the access method */
113- tuple = SearchSysCache1 (AMOID , ObjectIdGetDatum (amoid ));
114- if (!HeapTupleIsValid (tuple ))
115- elog (ERROR , "cache lookup failed for access method %u" ,
116- amoid );
117- amform = (Form_pg_am ) GETSTRUCT (tuple );
118-
119- /* Check that it is a table access method */
120- if (amform -> amtype != AMTYPE_TABLE )
121- ereport (ERROR ,
122- (errcode (ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE ),
123- errmsg ("access method \"%s\" is not of type %s" ,
124- NameStr (amform -> amname ), "TABLE" )));
125-
126- amhandler = amform -> amhandler ;
127-
128- /* Complain if handler OID is invalid */
129- if (!RegProcedureIsValid (amhandler ))
130- ereport (ERROR ,
131- (errcode (ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE ),
132- errmsg ("table access method \"%s\" does not have a handler" ,
133- NameStr (amform -> amname ))));
134-
135- ReleaseSysCache (tuple );
136-
137- /* And finally, call the handler function to get the API struct. */
138- return GetTableAmRoutine (amhandler );
139- }
140-
141- /*
142- * get_table_am_oid - given a table access method name, look up the OID
143- *
144- * If missing_ok is false, throw an error if table access method name not
145- * found. If true, just return InvalidOid.
146- */
147- static Oid
148- get_table_am_oid (const char * tableamname , bool missing_ok )
149- {
150- Oid result ;
151- Relation rel ;
152- TableScanDesc scandesc ;
153- HeapTuple tuple ;
154- ScanKeyData entry [1 ];
155-
156- /*
157- * Search pg_am. We use a heapscan here even though there is an index on
158- * name, on the theory that pg_am will usually have just a few entries and
159- * so an indexed lookup is a waste of effort.
160- */
161- rel = heap_open (AccessMethodRelationId , AccessShareLock );
162-
163- ScanKeyInit (& entry [0 ],
164- Anum_pg_am_amname ,
165- BTEqualStrategyNumber , F_NAMEEQ ,
166- CStringGetDatum (tableamname ));
167- scandesc = table_beginscan_catalog (rel , 1 , entry );
168- tuple = heap_getnext (scandesc , ForwardScanDirection );
169-
170- /* We assume that there can be at most one matching tuple */
171- if (HeapTupleIsValid (tuple ) &&
172- ((Form_pg_am ) GETSTRUCT (tuple ))-> amtype == AMTYPE_TABLE )
173- result = ((Form_pg_am ) GETSTRUCT (tuple ))-> oid ;
174- else
175- result = InvalidOid ;
176-
177- table_endscan (scandesc );
178- heap_close (rel , AccessShareLock );
179-
180- if (!OidIsValid (result ) && !missing_ok )
181- ereport (ERROR ,
182- (errcode (ERRCODE_UNDEFINED_OBJECT ),
183- errmsg ("table access method \"%s\" does not exist" ,
184- tableamname )));
185-
186- return result ;
187- }
188-
18999/* check_hook: validate new default_table_access_method */
190100bool
191101check_default_table_access_method (char * * newval , void * * extra , GucSource source )
192102{
103+ if (* * newval == '\0' )
104+ {
105+ GUC_check_errdetail ("default_table_access_method may not be empty." );
106+ return false;
107+ }
108+
109+ if (strlen (* newval ) >= NAMEDATALEN )
110+ {
111+ GUC_check_errdetail ("default_table_access_method is too long (maximum %d characters)." ,
112+ NAMEDATALEN - 1 );
113+ return false;
114+ }
115+
193116 /*
194117 * If we aren't inside a transaction, we cannot do database access so
195118 * cannot verify the name. Must accept the value on faith.
196119 */
197120 if (IsTransactionState ())
198121 {
199- if (* * newval != '\0' &&
200- !OidIsValid (get_table_am_oid (* newval , true)))
122+ if (!OidIsValid (get_table_am_oid (* newval , true)))
201123 {
202124 /*
203125 * When source == PGC_S_TEST, don't throw a hard error for a
0 commit comments