@ -24,61 +24,87 @@
# include "utils/hsearch.h"
static HTAB * extensible_node_methods = NULL ;
static HTAB * custom_scan_methods = NULL ;
typedef struct
{
char extnodename [ EXTNODENAME_MAX_LEN ] ;
const ExtensibleNodeMethods * methods ;
const void * extnode methods;
} ExtensibleNodeEntry ;
/*
* Register a new type of extensible node .
* An internal function to register a new callback structure
*/
void
RegisterExtensibleNodeMethods ( const ExtensibleNodeMethods * methods )
static void
RegisterExtensibleNodeEntry ( HTAB * * p_htable , const char * htable_label ,
const char * extnodename ,
const void * extnodemethods )
{
ExtensibleNodeEntry * entry ;
bool found ;
if ( extensible_node_methods = = NULL )
if ( * p_htable = = NULL )
{
HASHCTL ctl ;
memset ( & ctl , 0 , sizeof ( HASHCTL ) ) ;
ctl . keysize = EXTNODENAME_MAX_LEN ;
ctl . entrysize = sizeof ( ExtensibleNodeEntry ) ;
extensible_node_methods = hash_create ( " Extensible Node Methods " ,
100 , & ctl , HASH_ELEM ) ;
* p_htable = hash_create ( htable_label , 100 , & ctl , HASH_ELEM ) ;
}
if ( strlen ( methods - > extnodename ) > = EXTNODENAME_MAX_LEN )
if ( strlen ( extnodename ) > = EXTNODENAME_MAX_LEN )
elog ( ERROR , " extensible node name is too long " ) ;
entry = ( ExtensibleNodeEntry * ) hash_search ( extensible_node_methods ,
methods - > extnodename ,
entry = ( ExtensibleNodeEntry * ) hash_search ( * p_htable ,
extnodename ,
HASH_ENTER , & found ) ;
if ( found )
ereport ( ERROR ,
( errcode ( ERRCODE_DUPLICATE_OBJECT ) ,
errmsg ( " extensible node type \" %s \" already exists " ,
methods - > extnodename ) ) ) ;
extnodename ) ) ) ;
entry - > methods = methods ;
entry - > extnode methods = extnode methods;
}
/*
* Get the methods for a given type of extensible node .
* Register a new type of extensible node .
*/
const ExtensibleNodeMethods *
GetExtensibleNodeMethods ( const char * extnodename , bool missing_ok )
void
RegisterExtensibleNodeMethods ( const ExtensibleNodeMethods * methods )
{
RegisterExtensibleNodeEntry ( & extensible_node_methods ,
" Extensible Node Methods " ,
methods - > extnodename ,
methods ) ;
}
/*
* Register a new type of custom scan node
*/
void
RegisterCustomScanMethods ( const CustomScanMethods * methods )
{
RegisterExtensibleNodeEntry ( & custom_scan_methods ,
" Custom Scan Methods " ,
methods - > CustomName ,
methods ) ;
}
/*
* An internal routine to get an ExtensibleNodeEntry by the given identifier
*/
static const void *
GetExtensibleNodeEntry ( HTAB * htable , const char * extnodename , bool missing_ok )
{
ExtensibleNodeEntry * entry = NULL ;
if ( extensible_node_methods ! = NULL )
entry = ( ExtensibleNodeEntry * ) hash_search ( extensible_node_methods ,
if ( htable ! = NULL )
entry = ( ExtensibleNodeEntry * ) hash_search ( htable ,
extnodename ,
HASH_FIND , NULL ) ;
if ( ! entry )
{
if ( missing_ok )
@ -89,5 +115,29 @@ GetExtensibleNodeMethods(const char *extnodename, bool missing_ok)
extnodename ) ) ) ;
}
return entry - > methods ;
return entry - > extnodemethods ;
}
/*
* Get the methods for a given type of extensible node .
*/
const ExtensibleNodeMethods *
GetExtensibleNodeMethods ( const char * extnodename , bool missing_ok )
{
return ( const ExtensibleNodeMethods * )
GetExtensibleNodeEntry ( extensible_node_methods ,
extnodename ,
missing_ok ) ;
}
/*
* Get the methods for a given name of CustomScanMethods
*/
const CustomScanMethods *
GetCustomScanMethods ( const char * CustomName , bool missing_ok )
{
return ( const CustomScanMethods * )
GetExtensibleNodeEntry ( custom_scan_methods ,
CustomName ,
missing_ok ) ;
}