1
1
#include "postgres.h"
2
2
#include "fmgr.h"
3
- #include "nodes/nodes.h"
3
+
4
+ #include "funcapi.h"
4
5
#include "miscadmin.h"
5
6
#include "storage/ipc.h"
6
- #include "storage/shmem.h"
7
7
#include "storage/lwlock.h"
8
- #include "utils/builtins .h"
8
+ #include "storage/shmem .h"
9
9
10
10
/* Constants and Macros */
11
11
PG_MODULE_MAGIC ;
@@ -16,26 +16,31 @@ PG_MODULE_MAGIC;
16
16
#endif
17
17
18
18
/* 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. */
21
21
#define CMD_TYPE_COUNT CMD_NOTHING+1
22
22
23
- typedef struct pgswUserPerm {
23
+ typedef struct pgswHashKey /* Hash entry key. */
24
+ {
24
25
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.
26
34
* CmdType enum members are indexes for this array, i.e.
27
35
* denyCmd[CMD_DELETE] = true to prohibit SQL DELETE statements. */
28
36
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 ;
36
38
37
39
/* Function Prototypes */
38
40
void _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
+
39
44
static void pgsw_shmem_request (void );
40
45
static void pgsw_shmem_startup (void );
41
46
@@ -45,7 +50,7 @@ PG_FUNCTION_INFO_V1(my_function);
45
50
/* Global variables */
46
51
static shmem_request_hook_type prev_shmem_request_hook = NULL ;
47
52
static shmem_startup_hook_type prev_shmem_startup_hook = NULL ;
48
- pgswSharedState * pgsw_shmem = NULL ;
53
+ static HTAB * pgsw_hash = NULL ;
49
54
50
55
void
51
56
_PG_init (void )
@@ -66,26 +71,45 @@ pgsw_shmem_request(void)
66
71
if (prev_shmem_request_hook )
67
72
prev_shmem_request_hook ();
68
73
69
- RequestAddinShmemSpace (MAXALIGN (sizeof (pgswSharedState )));
74
+ RequestAddinShmemSpace (
75
+ hash_estimate_size (DENY_LIST_MAX_SIZE , sizeof (pgswHashEntry )) );
70
76
RequestNamedLWLockTranche ("pg_sqlwall" , 1 );
71
77
}
72
78
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
+
73
94
void
74
95
pgsw_shmem_startup (void )
75
96
{
76
- bool found ;
97
+ HASHCTL info ;
77
98
78
99
if (prev_shmem_startup_hook )
79
100
prev_shmem_startup_hook ();
80
101
81
102
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 );
89
113
LWLockRelease (AddinShmemInitLock );
90
114
}
91
115
0 commit comments