|
1 |
| -#include "pg_prelude.h" |
2 | 1 | #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 |
| -} |
160 | 2 |
|
161 | 3 | bool all_extensions_are_privileged(List *objects, const char *privileged_extensions){
|
162 | 4 | ListCell *lc;
|
|
0 commit comments