Skip to content

Commit ed1d642

Browse files
committed
Add support for custom git search path
This commit adds a way to configure, per table, the git search path that is sometimes required when running the FDW in very specific situations. Some logic got simplified in how get options too. This closes #10.
1 parent 442f2e0 commit ed1d642

File tree

7 files changed

+43
-17
lines changed

7 files changed

+43
-17
lines changed

Changelog

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
* Add support for lines added/deleted/files changed
1212
* Add support for bare repositories
1313
* Add support for libgit2 up to v0.27
14+
* Add support for a custom git search path
1415

1516
# Release 1.0.0
1617

README.md

+6-3
Original file line numberDiff line numberDiff line change
@@ -95,10 +95,13 @@ There are no options that can be passed to a git\_fdw server.
9595

9696
### Foreign Table
9797

98-
The possible options are:
98+
One must configure the foreign tables appropriately.
9999

100-
* `path`: The path of the git repository;
101-
* `branch`: The branch to be used.
100+
Here are the options:
101+
102+
* (Required) `path`: The path of the git repository;
103+
* (Required) `branch`: The branch to be used;
104+
* (Optional) `git_search_path`: Sometimes libgit2 has to be told where to find your configuration. See #10 for details.
102105

103106
## Note on Patches/Pull Requests
104107

execution_state.h

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ typedef struct GitFdwExecutionState
22
{
33
char *path;
44
char *branch;
5+
char *git_search_path;
56
List *options;
67
git_repository *repo;
78
int passes;

git_fdw.c

+31-13
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ Datum git_fdw_validator(PG_FUNCTION_ARGS) {
8282
Oid catalog = PG_GETARG_OID(1);
8383
char *path = NULL;
8484
char *branch = NULL;
85+
char *git_search_path = NULL;
8586
List *other_options = NIL;
8687
ListCell *cell;
8788

@@ -105,7 +106,7 @@ Datum git_fdw_validator(PG_FUNCTION_ARGS) {
105106
opt->optname);
106107
}
107108

108-
ereport(ERROR,
109+
ereport(WARNING,
109110
(errcode(ERRCODE_FDW_INVALID_OPTION_NAME),
110111
errmsg("invalid option \"%s\"", def->defname),
111112
buf.len > 0
@@ -130,6 +131,14 @@ Datum git_fdw_validator(PG_FUNCTION_ARGS) {
130131
errmsg("conflicting or redundant options")));
131132
branch = defGetString(def);
132133
}
134+
else if (strcmp(def->defname, "git_search_path") == 0)
135+
{
136+
if (git_search_path)
137+
ereport(ERROR,
138+
(errcode(ERRCODE_SYNTAX_ERROR),
139+
errmsg("conflicting or redundant options")));
140+
git_search_path = defGetString(def);
141+
}
133142
else
134143
other_options = lappend(other_options, def);
135144
}
@@ -145,6 +154,7 @@ Datum git_fdw_validator(PG_FUNCTION_ARGS) {
145154
// TODO: Find where this variable should go (Plan or Path?)
146155
char * repository_path;
147156
char * repository_branch;
157+
char * repository_git_search_path;
148158

149159
static bool is_valid_option(const char *option, Oid context) {
150160
const struct GitFdwOption *opt;
@@ -160,29 +170,27 @@ static bool is_valid_option(const char *option, Oid context) {
160170
static void gitGetOptions(Oid foreigntableid, GitFdwPlanState *state, List **other_options) {
161171
ForeignTable *table;
162172
List *options;
163-
ListCell *lc,
164-
*prev;
173+
ListCell *lc;
165174

166175
table = GetForeignTable(foreigntableid);
167176

168177
options = NIL;
169178
options = list_concat(options, table->options);
170179

171-
prev = NULL;
172180
foreach(lc, options) {
173181
DefElem *def = (DefElem *) lfirst(lc);
174182

175183
if (strcmp(def->defname, "path") == 0) {
176184
state->path = defGetString(def);
177-
options = list_delete_cell(options, lc, prev);
178185
}
179186

180187
if (strcmp(def->defname, "branch") == 0) {
181188
state->branch = defGetString(def);
182-
options = list_delete_cell(options, lc, prev);
183189
}
184190

185-
prev = lc;
191+
if (strcmp(def->defname, "git_search_path") == 0) {
192+
state->git_search_path = defGetString(def);
193+
}
186194
}
187195

188196
if (state->path == NULL) {
@@ -260,8 +268,9 @@ static ForeignScan * gitGetForeignPlan(PlannerInfo *root, RelOptInfo *baserel, O
260268
#endif
261269
); // Assuming outer_plan is null
262270

263-
repository_path = ((GitFdwPlanState*)scan->fdw_private)->path;
264-
repository_branch = ((GitFdwPlanState*)scan->fdw_private)->branch;
271+
repository_path = ((GitFdwPlanState*)scan->fdw_private)->path;
272+
repository_branch = ((GitFdwPlanState*)scan->fdw_private)->branch;
273+
repository_git_search_path = ((GitFdwPlanState*)scan->fdw_private)->git_search_path;
265274
return scan;
266275
}
267276

@@ -280,13 +289,22 @@ static void gitBeginForeignScan(ForeignScanState *node, int eflags) {
280289
git_libgit2_init();
281290

282291
festate = (GitFdwExecutionState *) palloc(sizeof(GitFdwExecutionState));
283-
festate->path = repository_path;
284-
festate->branch = repository_branch;
285-
festate->repo = NULL;
286-
festate->walker = NULL;
292+
festate->path = repository_path;
293+
festate->branch = repository_branch;
294+
festate->git_search_path = repository_git_search_path;
295+
festate->repo = NULL;
296+
festate->walker = NULL;
287297

288298
node->fdw_state = (void *) festate;
289299

300+
if(festate->git_search_path != NULL){
301+
git_libgit2_opts(
302+
GIT_OPT_SET_SEARCH_PATH,
303+
GIT_CONFIG_LEVEL_GLOBAL,
304+
festate->git_search_path
305+
);
306+
}
307+
290308
if(festate->repo == NULL) {
291309
int repo_opened = -1;
292310
if((repo_opened = git_repository_open(&festate->repo, festate->path)) != GIT_OK){

options.h

+1
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,6 @@ struct GitFdwOption {
77
static const struct GitFdwOption valid_options[] = {
88
{"path", ForeignTableRelationId},
99
{"branch", ForeignTableRelationId},
10+
{"git_search_path", ForeignTableRelationId},
1011
{NULL, InvalidOid}
1112
};

plan_state.h

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ typedef struct GitFdwPlanState
22
{
33
char *path;
44
char *branch;
5+
char *git_search_path;
56
List *options;
67
BlockNumber pages;
78
double ntuples;

tests/setup.sql

+2-1
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,6 @@ CREATE FOREIGN TABLE
1515
SERVER git_fdw_server
1616
OPTIONS (
1717
path '/git_fdw/repo.git',
18-
branch 'refs/heads/master'
18+
branch 'refs/heads/master',
19+
git_search_path '/optional/custom/search_path'
1920
);

0 commit comments

Comments
 (0)