11#include "postgres.h"
22#include "fmgr.h"
3- #include "nodes/nodes.h"
3+
4+ #include "funcapi.h"
45#include "miscadmin.h"
56#include "storage/ipc.h"
6- #include "storage/shmem.h"
77#include "storage/lwlock.h"
8- #include "utils/builtins .h"
8+ #include "storage/shmem .h"
99
1010/* Constants and Macros */
1111PG_MODULE_MAGIC ;
@@ -16,26 +16,31 @@ PG_MODULE_MAGIC;
1616#endif
1717
1818/* Is there a better size candidate? */
19- #define DENY_LIST_SIZE 128
20- /* CMD_NOTHING tells us about enum size as it is the last enum member. */
19+ #define DENY_LIST_MAX_SIZE 128
20+ /* CMD_NOTHING tells us about the enum size as it is the last enum member. */
2121#define CMD_TYPE_COUNT CMD_NOTHING+1
2222
23- typedef struct pgswUserPerm {
23+ typedef struct pgswHashKey /* Hash entry key. */
24+ {
2425 Oid userId ;
25- /* Lists SQL command types the user is NOT allowed to run.
26+ } pgswHashKey ;
27+
28+ typedef struct pgswHashEntry
29+ {
30+ slock_t mutex ; /* Protects the entry. */
31+ Oid userId ; /* User OID. */
32+
33+ /* Lists SQL command types the user is not allowed to run.
2634 * CmdType enum members are indexes for this array, i.e.
2735 * denyCmd[CMD_DELETE] = true to prohibit SQL DELETE statements. */
2836 bool denyCmd [CMD_TYPE_COUNT ];
29- } pgswUserPerm ;
30-
31- typedef struct pgswSharedState {
32- LWLock * lock ;
33- pgswUserPerm denyList [DENY_LIST_SIZE ];
34- int denyListSize ;
35- } pgswSharedState ;
37+ } pgswHashEntry ;
3638
3739/* Function Prototypes */
3840void _PG_init (void );
41+ static uint32 gen_hash_key (const void * key , Size keysize );
42+ static int compare_hash_key (const void * key1 , const void * key2 , Size keysize );
43+
3944static void pgsw_shmem_request (void );
4045static void pgsw_shmem_startup (void );
4146
@@ -45,7 +50,7 @@ PG_FUNCTION_INFO_V1(my_function);
4550/* Global variables */
4651static shmem_request_hook_type prev_shmem_request_hook = NULL ;
4752static shmem_startup_hook_type prev_shmem_startup_hook = NULL ;
48- pgswSharedState * pgsw_shmem = NULL ;
53+ static HTAB * pgsw_hash = NULL ;
4954
5055void
5156_PG_init (void )
@@ -66,26 +71,45 @@ pgsw_shmem_request(void)
6671 if (prev_shmem_request_hook )
6772 prev_shmem_request_hook ();
6873
69- RequestAddinShmemSpace (MAXALIGN (sizeof (pgswSharedState )));
74+ RequestAddinShmemSpace (
75+ hash_estimate_size (DENY_LIST_MAX_SIZE , sizeof (pgswHashEntry )) );
7076 RequestNamedLWLockTranche ("pg_sqlwall" , 1 );
7177}
7278
79+ int
80+ compare_hash_key (const void * key1 , const void * key2 , Size keysize )
81+ {
82+ const pgswHashKey * k1 = (const pgswHashKey * ) key1 ;
83+ const pgswHashKey * k2 = (const pgswHashKey * ) key2 ;
84+ return (k1 -> userId == k2 -> userId ) ? 0 : 1 ;
85+ }
86+
87+ uint32
88+ gen_hash_key (const void * key , Size keysize )
89+ {
90+ const pgswHashKey * k = (const pgswHashKey * ) key ;
91+ return (uint32 ) k -> userId ;
92+ }
93+
7394void
7495pgsw_shmem_startup (void )
7596{
76- bool found ;
97+ HASHCTL info ;
7798
7899 if (prev_shmem_startup_hook )
79100 prev_shmem_startup_hook ();
80101
81102 LWLockAcquire (AddinShmemInitLock , LW_EXCLUSIVE );
82-
83- pgsw_shmem = ShmemInitStruct ("pg_sqlwall" , sizeof (pgswSharedState ), & found );
84- if (!found ) {
85- pgsw_shmem -> denyListSize = 0 ;
86- pgsw_shmem -> lock = & (GetNamedLWLockTranche ("pg_sqlwall" ))-> lock ;
87- }
88-
103+ memset (& info , 0 , sizeof (info ));
104+ info .keysize = sizeof (pgswHashKey );
105+ info .entrysize = sizeof (pgswHashKey );
106+ info .hash = gen_hash_key ;
107+ info .match = compare_hash_key ;
108+ pgsw_hash = ShmemInitHash ("pg_sqlwall hash" ,
109+ MaxConnections ,
110+ MaxConnections ,
111+ & info ,
112+ HASH_ELEM |HASH_FUNCTION |HASH_COMPARE );
89113 LWLockRelease (AddinShmemInitLock );
90114}
91115
0 commit comments