Skip to content

Commit 1c56d66

Browse files
committed
refactor: move custom scripts logic to its own file
1 parent 5ce2b2b commit 1c56d66

File tree

5 files changed

+179
-166
lines changed

5 files changed

+179
-166
lines changed

src/extension_custom_scripts.c

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
#include "extension_custom_scripts.h"
2+
3+
// Prevent recursively running custom scripts
4+
static bool running_custom_script = false;
5+
6+
// This produces a char surrounded by a triple single quote like '''x'''
7+
// This is so when it gets interpreted by SQL it converts to a single quote surround: 'x'
8+
// To see an example, do `select 'x';` vs `select '''x''';` on psql.
9+
static char *sql_literal(const char *str){
10+
return str == NULL?
11+
"'null'": // also handle the NULL cstr case
12+
quote_literal_cstr(quote_literal_cstr(str));
13+
}
14+
15+
static void run_custom_script(const char *filename, const char *extname,
16+
const char *extschema, const char *extversion,
17+
bool extcascade) {
18+
if (running_custom_script) {
19+
return;
20+
}
21+
running_custom_script = true;
22+
23+
static const char sql_replace_template[] = "\
24+
do $_$\
25+
begin\
26+
execute replace(replace(replace(replace(\
27+
pg_read_file(%s)\
28+
, '@extname@', %s)\
29+
, '@extschema@', %s)\
30+
, '@extversion@', %s)\
31+
, '@extcascade@', %s);\
32+
exception\
33+
when undefined_file then\
34+
null;\
35+
end; $_$";
36+
37+
static const size_t max_sql_len
38+
= sizeof (sql_replace_template)
39+
+ MAXPGPATH // max size of a file path
40+
+ 3 * (NAMEDATALEN + 6) // 3 *(identifier + 6 single quotes of the SQL literal, see sql_literal)
41+
+ sizeof ("false") // max size of a bool string value
42+
;
43+
44+
char sql[max_sql_len];
45+
46+
snprintf(sql,
47+
max_sql_len,
48+
sql_replace_template,
49+
quote_literal_cstr(filename),
50+
sql_literal(extname),
51+
sql_literal(extschema),
52+
sql_literal(extversion),
53+
extcascade?"'true'":"'false'");
54+
55+
PushActiveSnapshot(GetTransactionSnapshot());
56+
SPI_connect();
57+
58+
int rc = SPI_execute(sql, false, 0);
59+
if (rc != SPI_OK_UTILITY) {
60+
elog(ERROR, "SPI_execute failed with error code %d", rc);
61+
}
62+
SPI_finish();
63+
PopActiveSnapshot();
64+
running_custom_script = false;
65+
}
66+
67+
void run_global_before_create_script(char *extname, List *options, const char *privileged_extensions_custom_scripts_path){
68+
DefElem *d_schema = NULL, *d_new_version = NULL, *d_cascade = NULL;
69+
char *extschema = NULL, *extversion = NULL;
70+
bool extcascade = false;
71+
char filename[MAXPGPATH];
72+
73+
ListCell *option_cell = NULL;
74+
75+
foreach (option_cell, options) {
76+
DefElem *defel = (DefElem *)lfirst(option_cell);
77+
78+
if (strcmp(defel->defname, "schema") == 0) {
79+
d_schema = defel;
80+
extschema = defGetString(d_schema);
81+
} else if (strcmp(defel->defname, "new_version") == 0) {
82+
d_new_version = defel;
83+
extversion = defGetString(d_new_version);
84+
} else if (strcmp(defel->defname, "cascade") == 0) {
85+
d_cascade = defel;
86+
extcascade = defGetBoolean(d_cascade);
87+
}
88+
}
89+
90+
snprintf(filename, MAXPGPATH, "%s/before-create.sql",
91+
privileged_extensions_custom_scripts_path);
92+
run_custom_script(filename, extname, extschema, extversion,
93+
extcascade);
94+
}
95+
96+
void run_ext_before_create_script(char *extname, List *options, const char *privileged_extensions_custom_scripts_path){
97+
DefElem *d_schema = NULL;
98+
DefElem *d_new_version = NULL;
99+
DefElem *d_cascade = NULL;
100+
char *extschema = NULL;
101+
char *extversion = NULL;
102+
bool extcascade = false;
103+
ListCell *option_cell = NULL;
104+
char filename[MAXPGPATH];
105+
106+
foreach (option_cell, options) {
107+
DefElem *defel = (DefElem *)lfirst(option_cell);
108+
109+
if (strcmp(defel->defname, "schema") == 0) {
110+
d_schema = defel;
111+
extschema = defGetString(d_schema);
112+
} else if (strcmp(defel->defname, "new_version") == 0) {
113+
d_new_version = defel;
114+
extversion = defGetString(d_new_version);
115+
} else if (strcmp(defel->defname, "cascade") == 0) {
116+
d_cascade = defel;
117+
extcascade = defGetBoolean(d_cascade);
118+
}
119+
}
120+
121+
122+
snprintf(filename, MAXPGPATH, "%s/%s/before-create.sql",
123+
privileged_extensions_custom_scripts_path, extname);
124+
run_custom_script(filename, extname, extschema, extversion,
125+
extcascade);
126+
}
127+
128+
void run_ext_after_create_script(char *extname, List *options, const char *privileged_extensions_custom_scripts_path){
129+
DefElem *d_schema = NULL;
130+
DefElem *d_new_version = NULL;
131+
DefElem *d_cascade = NULL;
132+
char *extschema = NULL;
133+
char *extversion = NULL;
134+
bool extcascade = false;
135+
ListCell *option_cell = NULL;
136+
char filename[MAXPGPATH];
137+
138+
foreach (option_cell, options) {
139+
DefElem *defel = (DefElem *)lfirst(option_cell);
140+
141+
if (strcmp(defel->defname, "schema") == 0) {
142+
d_schema = defel;
143+
extschema = defGetString(d_schema);
144+
} else if (strcmp(defel->defname, "new_version") == 0) {
145+
d_new_version = defel;
146+
extversion = defGetString(d_new_version);
147+
} else if (strcmp(defel->defname, "cascade") == 0) {
148+
d_cascade = defel;
149+
extcascade = defGetBoolean(d_cascade);
150+
}
151+
}
152+
153+
snprintf(filename, MAXPGPATH, "%s/%s/after-create.sql",
154+
privileged_extensions_custom_scripts_path, extname);
155+
run_custom_script(filename, extname, extschema, extversion,
156+
extcascade);
157+
}

src/extension_custom_scripts.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#ifndef EXTENSION_CUSTOM_SCRIPTS_H
2+
#define EXTENSION_CUSTOM_SCRIPTS_H
3+
4+
#include "pg_prelude.h"
5+
6+
extern void run_global_before_create_script(
7+
char *extname, List *options,
8+
const char *privileged_extensions_custom_scripts_path);
9+
10+
extern void run_ext_before_create_script(
11+
char *extname, List *options,
12+
const char *privileged_extensions_custom_scripts_path);
13+
14+
extern void run_ext_after_create_script(
15+
char *extname, List *options,
16+
const char *privileged_extensions_custom_scripts_path);
17+
18+
#endif

src/privileged_extensions.c

Lines changed: 0 additions & 158 deletions
Original file line numberDiff line numberDiff line change
@@ -1,162 +1,4 @@
1-
#include "pg_prelude.h"
21
#include "privileged_extensions.h"
3-
#include "utils.h"
4-
5-
// Prevent recursively running custom scripts
6-
static bool running_custom_script = false;
7-
8-
// This produces a char surrounded by a triple single quote like '''x'''
9-
// This is so when it gets interpreted by SQL it converts to a single quote surround: 'x'
10-
// To see an example, do `select 'x';` vs `select '''x''';` on psql.
11-
static char *sql_literal(const char *str){
12-
return str == NULL?
13-
"'null'": // also handle the NULL cstr case
14-
quote_literal_cstr(quote_literal_cstr(str));
15-
}
16-
17-
static void run_custom_script(const char *filename, const char *extname,
18-
const char *extschema, const char *extversion,
19-
bool extcascade) {
20-
if (running_custom_script) {
21-
return;
22-
}
23-
running_custom_script = true;
24-
25-
static const char sql_replace_template[] = "\
26-
do $_$\
27-
begin\
28-
execute replace(replace(replace(replace(\
29-
pg_read_file(%s)\
30-
, '@extname@', %s)\
31-
, '@extschema@', %s)\
32-
, '@extversion@', %s)\
33-
, '@extcascade@', %s);\
34-
exception\
35-
when undefined_file then\
36-
null;\
37-
end; $_$";
38-
39-
static const size_t max_sql_len
40-
= sizeof (sql_replace_template)
41-
+ MAXPGPATH // max size of a file path
42-
+ 3 * (NAMEDATALEN + 6) // 3 *(identifier + 6 single quotes of the SQL literal, see sql_literal)
43-
+ sizeof ("false") // max size of a bool string value
44-
;
45-
46-
char sql[max_sql_len];
47-
48-
snprintf(sql,
49-
max_sql_len,
50-
sql_replace_template,
51-
quote_literal_cstr(filename),
52-
sql_literal(extname),
53-
sql_literal(extschema),
54-
sql_literal(extversion),
55-
extcascade?"'true'":"'false'");
56-
57-
PushActiveSnapshot(GetTransactionSnapshot());
58-
SPI_connect();
59-
60-
int rc = SPI_execute(sql, false, 0);
61-
if (rc != SPI_OK_UTILITY) {
62-
elog(ERROR, "SPI_execute failed with error code %d", rc);
63-
}
64-
SPI_finish();
65-
PopActiveSnapshot();
66-
running_custom_script = false;
67-
}
68-
69-
void run_global_before_create_script(char *extname, List *options, const char *privileged_extensions_custom_scripts_path){
70-
DefElem *d_schema = NULL, *d_new_version = NULL, *d_cascade = NULL;
71-
char *extschema = NULL, *extversion = NULL;
72-
bool extcascade = false;
73-
char filename[MAXPGPATH];
74-
75-
ListCell *option_cell = NULL;
76-
77-
foreach (option_cell, options) {
78-
DefElem *defel = (DefElem *)lfirst(option_cell);
79-
80-
if (strcmp(defel->defname, "schema") == 0) {
81-
d_schema = defel;
82-
extschema = defGetString(d_schema);
83-
} else if (strcmp(defel->defname, "new_version") == 0) {
84-
d_new_version = defel;
85-
extversion = defGetString(d_new_version);
86-
} else if (strcmp(defel->defname, "cascade") == 0) {
87-
d_cascade = defel;
88-
extcascade = defGetBoolean(d_cascade);
89-
}
90-
}
91-
92-
snprintf(filename, MAXPGPATH, "%s/before-create.sql",
93-
privileged_extensions_custom_scripts_path);
94-
run_custom_script(filename, extname, extschema, extversion,
95-
extcascade);
96-
}
97-
98-
void run_ext_before_create_script(char *extname, List *options, const char *privileged_extensions_custom_scripts_path){
99-
DefElem *d_schema = NULL;
100-
DefElem *d_new_version = NULL;
101-
DefElem *d_cascade = NULL;
102-
char *extschema = NULL;
103-
char *extversion = NULL;
104-
bool extcascade = false;
105-
ListCell *option_cell = NULL;
106-
char filename[MAXPGPATH];
107-
108-
foreach (option_cell, options) {
109-
DefElem *defel = (DefElem *)lfirst(option_cell);
110-
111-
if (strcmp(defel->defname, "schema") == 0) {
112-
d_schema = defel;
113-
extschema = defGetString(d_schema);
114-
} else if (strcmp(defel->defname, "new_version") == 0) {
115-
d_new_version = defel;
116-
extversion = defGetString(d_new_version);
117-
} else if (strcmp(defel->defname, "cascade") == 0) {
118-
d_cascade = defel;
119-
extcascade = defGetBoolean(d_cascade);
120-
}
121-
}
122-
123-
124-
snprintf(filename, MAXPGPATH, "%s/%s/before-create.sql",
125-
privileged_extensions_custom_scripts_path, extname);
126-
run_custom_script(filename, extname, extschema, extversion,
127-
extcascade);
128-
}
129-
130-
void run_ext_after_create_script(char *extname, List *options, const char *privileged_extensions_custom_scripts_path){
131-
DefElem *d_schema = NULL;
132-
DefElem *d_new_version = NULL;
133-
DefElem *d_cascade = NULL;
134-
char *extschema = NULL;
135-
char *extversion = NULL;
136-
bool extcascade = false;
137-
ListCell *option_cell = NULL;
138-
char filename[MAXPGPATH];
139-
140-
foreach (option_cell, options) {
141-
DefElem *defel = (DefElem *)lfirst(option_cell);
142-
143-
if (strcmp(defel->defname, "schema") == 0) {
144-
d_schema = defel;
145-
extschema = defGetString(d_schema);
146-
} else if (strcmp(defel->defname, "new_version") == 0) {
147-
d_new_version = defel;
148-
extversion = defGetString(d_new_version);
149-
} else if (strcmp(defel->defname, "cascade") == 0) {
150-
d_cascade = defel;
151-
extcascade = defGetBoolean(d_cascade);
152-
}
153-
}
154-
155-
snprintf(filename, MAXPGPATH, "%s/%s/after-create.sql",
156-
privileged_extensions_custom_scripts_path, extname);
157-
run_custom_script(filename, extname, extschema, extversion,
158-
extcascade);
159-
}
1602

1613
bool all_extensions_are_privileged(List *objects, const char *privileged_extensions){
1624
ListCell *lc;

src/privileged_extensions.h

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,11 @@
11
#ifndef PRIVILEGED_EXTENSIONS_H
22
#define PRIVILEGED_EXTENSIONS_H
33

4+
#include "pg_prelude.h"
45
#include "utils.h"
56

6-
bool all_extensions_are_privileged(List *objects, const char *privileged_extensions);
7+
extern bool all_extensions_are_privileged(List *objects, const char *privileged_extensions);
78

8-
bool is_extension_privileged(const char *extname, const char *privileged_extensions);
9-
10-
void run_global_before_create_script(char *extname, List *options, const char *privileged_extensions_custom_scripts_path);
11-
12-
void run_ext_before_create_script(char *extname, List *options, const char *privileged_extensions_custom_scripts_path);
13-
14-
void run_ext_after_create_script(char *extname, List *options, const char *privileged_extensions_custom_scripts_path);
9+
extern bool is_extension_privileged(const char *extname, const char *privileged_extensions);
1510

1611
#endif

src/supautils.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include "pg_prelude.h"
22
#include "constrained_extensions.h"
33
#include "drop_trigger_grants.h"
4+
#include "extension_custom_scripts.h"
45
#include "extensions_parameter_overrides.h"
56
#include "policy_grants.h"
67
#include "privileged_extensions.h"

0 commit comments

Comments
 (0)