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)
4139routine = (TableAmRoutine * )DatumGetPointer (datum );
4240
4341if (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" ,
4543amhandler );
4644
4745/*
@@ -98,106 +96,30 @@ GetTableAmRoutine(Oid amhandler)
9896return 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 */
197120if (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