-
-
Save Laeeth/c46a48fea8bb6e125c21a28c7d684020 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/+ | |
use with postgres 10 | |
d++ git_fdw.dpp --include-path /usr/include/postgresql/server | |
pg_config | grep LIBS | |
-lpgcommon -lpgport -lpthread -lxml2 -lpam -lssl -lcrypto -lgssapi_krb5 -lz -lreadline -lrt -lcrypt -ldl -lm | |
-lgit2 | |
+/ | |
module symmetry.integration.fdw.api; | |
import std.exception: Exception; | |
import std.experimental.logger; | |
#include "postgres.h" | |
#include <sys/stat.h> | |
#include <unistd.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <git2.h> | |
#include "access/htup_details.h" | |
#include "access/reloptions.h" | |
#include "access/sysattr.h" | |
#include "catalog/pg_foreign_table.h" | |
#include "commands/defrem.h" | |
#include "commands/explain.h" | |
#include "commands/vacuum.h" | |
#include "foreign/fdwapi.h" | |
#include "foreign/foreign.h" | |
#include "miscadmin.h" | |
#include "nodes/makefuncs.h" | |
#include "optimizer/cost.h" | |
#include "optimizer/pathnode.h" | |
#include "optimizer/planmain.h" | |
#include "optimizer/restrictinfo.h" | |
#include "optimizer/var.h" | |
#include "utils/memutils.h" | |
#include "utils/rel.h" | |
#include "utils/builtins.h" | |
#include "utils/timestamp.h" | |
extern(C) | |
{ | |
FdwRoutine* gitFdwHandler() | |
{ | |
auto ret = make!FdwRoutine(pallocator); | |
with(ret) | |
{ | |
.GetForeignRelSize = git_get_foreign_rel_size; | |
.GetForeignPaths = git_get_foreign_paths; | |
.GetForeignPlan = git_get_foreign_plan; | |
.BeginForeignScan = git_begin_foreign_scan; | |
.IterateForeignScan = git_iterate_foreign_scan; | |
.EndForeignScan = git_end_foreign_scan; | |
.ExplainForeignScan = git_explain_foreign_scan; | |
.ReScanForeignScan = git_rescan_foreign_scan; | |
.AnalyzeForeignTable = git_analyze_foreign_table; | |
.ImportForeignSchema = git_import_foreign_schema; | |
} | |
return ret; | |
} | |
} | |
Datum git_fdw_handler(PG_FUNCTION_ARGS) | |
{ | |
return PG_RETURN_POINTER(gitFdwHandler()); | |
} | |
Datum git_fdw_validator(PG_FUNCTION_ARGS) | |
{ | |
auto optionsList = untransformRelOptions(getPostgresArgument!Datum(0)).ListRange; | |
auto catalog = getPostgresArgument!Oid(1); | |
gitFdwValidator(optionsList,catalog); | |
PG_RETURN_VOID(); | |
} | |
string[] gitImportForeignSchema(ImportForeignSchemaStmt* stmt, Oid serverOid) | |
ForeignScan* make_foreign_scan(List* tlist, List* scanClauses, Index scanRelid, List* a1, ForeignPath* bestPath, Plan* outerPlan) | |
{ | |
ForeignScan* makeForeignScan(List* tlist, List* scanClauses, Index scanRelid, List* a1, ForeignPath* bestPath, Plan* outerPlan) | |
} | |
ForeignScan* git_get_foreign_plan(PlannerInfo *root, RelOptInfo *baserel, Oid foreigntableid, ForeignPath *best_path, List* tlist, List* scanClauses, Plan *outerPlan) | |
List* git_import_foreign_schema(ImportForeignSchemaStmt* stmt, Oid serverOid) | |
{ | |
return PList(gitImportForeignSchema).data; | |
} | |
void estimate_costs(PlannerInfo *root, RelOptInfo *baserel, GitFdwPlanState *planState, Cost *startupCost, Cost *totalCost) | |
{ | |
auto result = estimateCosts(root,baserel,planState); | |
*startupCost = result.startupCost; | |
*totalCost = result.totalCost; | |
} | |
bool git_analyze_foreign_table(Relation relation) | |
{ | |
auto result = gitAnalyzeForeignTable(relation); | |
*func = result[0]; | |
*totalPages = result[1]; | |
return true; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module symmetry.integration.fdw.pallocator; | |
import std.experimental.allocator.common; | |
struct DppOffsetSize{int offset; int size; } | |
#include "postgres.h" | |
#include "utils/palloc.h" | |
/** | |
The Postgresql heap allocator. palloc always returns word-aligned memory | |
Heavily based off std.experimental.allocator.mallocator; | |
*/ | |
struct Pallocator | |
{ | |
@system unittest { testAllocator!(() => Pallocator.instance); } | |
/** | |
Postgresql allocator methods per the semantics defined above. The | |
`deallocate` and `reallocate` methods are `@system` because they | |
may move memory around, leaving dangling pointers in user code. Somewhat | |
paradoxically, `palloc` is `@safe` but that's only useful to safe | |
programs that can afford to leak memory allocated. | |
*/ | |
@trusted @nogc nothrow | |
void[] allocate(size_t bytes) shared | |
{ | |
if (!bytes) return null; | |
auto p = palloc(bytes); | |
return p ? p[0 .. bytes] : null; | |
} | |
/// Ditto | |
@system @nogc nothrow | |
bool deallocate(void[] b) shared | |
{ | |
pfree(b.ptr); | |
return true; | |
} | |
/// Ditto | |
@system @nogc nothrow | |
bool reallocate(ref void[] b, size_t s) shared | |
{ | |
if (!s) | |
{ | |
deallocate(b); | |
b = null; | |
return true; | |
} | |
auto p = cast(ubyte*) repalloc(b.ptr, s); | |
if (!p) return false; | |
b = p[0 .. s]; | |
return true; | |
} | |
@trusted @nogc nothrow | |
void[] allocateZeroed()(size_t bytes) shared | |
{ | |
if (!bytes) return null; | |
auto p = palloc0(bytes); | |
return p ? p[0 .. bytes] : null; | |
} | |
/** | |
Returns the global instance of this allocator type. The C heap allocator is | |
thread-safe, therefore all of its methods and `it` itself are | |
`shared`. | |
*/ | |
static shared Pallocator instance; | |
} | |
/// | |
@nogc @system nothrow unittest | |
{ | |
auto buffer = Pallocator.instance.allocate(1024 * 1024 * 4); | |
scope(exit) Pallocator.instance.deallocate(buffer); | |
//... | |
} | |
@nogc @system nothrow unittest | |
{ | |
@nogc nothrow | |
static void test(A)() | |
{ | |
int* p = null; | |
p = cast(int*) A.instance.allocate(int.sizeof); | |
scope(exit) () nothrow @nogc { A.instance.deallocate(p[0 .. int.sizeof]); }(); | |
*p = 42; | |
assert(*p == 42); | |
} | |
test!Pallocator(); | |
} | |
@nogc @system nothrow unittest | |
{ | |
static void test(A)() | |
{ | |
import std.experimental.allocator : make; | |
Object p = null; | |
p = A.instance.make!Object(); | |
assert(p !is null); | |
} | |
test!Pallocator(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment