Skip to content

Commit

Permalink
Split the shim into a separate header, that we run bindgen on
Browse files Browse the repository at this point in the history
  • Loading branch information
thomcc committed Oct 24, 2022
1 parent b2267d4 commit ad351b3
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 118 deletions.
22 changes: 15 additions & 7 deletions pgx-pg-sys/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,11 +161,14 @@ fn generate_bindings(
is_for_release: bool,
) -> eyre::Result<()> {
let major_version = pg_config.major_version().wrap_err("could not determine major version")?;
let mut include_h = build_paths.manifest_dir.clone();
include_h.push("include");
include_h.push(format!("pg{}.h", major_version));

let bindgen_output = run_bindgen(&pg_config, &include_h)
let header_src = format!(
r#"
#include "cshim/pgx-cshim.h"
#include "include/pg{major_version}.h"
"#
);

let bindgen_output = run_bindgen(&pg_config, &build_paths.manifest_dir, &header_src)
.wrap_err_with(|| format!("bindgen failed for pg{}", major_version))?;

let oids = extract_oids(&bindgen_output);
Expand Down Expand Up @@ -543,13 +546,18 @@ struct StructDescriptor<'a> {

/// Given a specific postgres version, `run_bindgen` generates bindings for the given
/// postgres version and returns them as a token stream.
fn run_bindgen(pg_config: &PgConfig, include_h: &PathBuf) -> eyre::Result<syn::File> {
fn run_bindgen(
pg_config: &PgConfig,
manifest_path: &PathBuf,
header_src: &str,
) -> eyre::Result<syn::File> {
let major_version = pg_config.major_version()?;
eprintln!("Generating bindings for pg{}", major_version);
let includedir_server = pg_config.includedir_server()?;
let bindings = bindgen::Builder::default()
.header(include_h.display().to_string())
.header_contents("combined-header.h", header_src)
.clang_arg(&format!("-I{}", includedir_server.display()))
.clang_arg(&format!("-I{}", manifest_path.display()))
.clang_args(&extra_bindgen_clang_args(pg_config)?)
.parse_callbacks(Box::new(PgxOverrides::default()))
.blocklist_type("(Nullable)?Datum") // manually wrapping datum types for correctness
Expand Down
56 changes: 4 additions & 52 deletions pgx-pg-sys/cshim/pgx-cshim.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,159 +6,111 @@ All rights reserved.
Use of this source code is governed by the MIT license that can be found in the LICENSE file.
*/
#include "postgres.h"
#include "pgx-cshim.h"

#define IS_PG_10 (PG_VERSION_NUM >= 100000 && PG_VERSION_NUM < 110000)
#define IS_PG_11 (PG_VERSION_NUM >= 110000 && PG_VERSION_NUM < 120000)
#define IS_PG_12 (PG_VERSION_NUM >= 120000 && PG_VERSION_NUM < 130000)
#define IS_PG_13 (PG_VERSION_NUM >= 130000 && PG_VERSION_NUM < 140000)

#include "access/htup.h"
#include "access/htup_details.h"
#include "catalog/pg_type.h"
#if IS_PG_10 || IS_PG_11
#include "nodes/relation.h"
#else
#include "nodes/pathnodes.h"
#endif
#include "nodes/pg_list.h"
#include "parser/parsetree.h"
#include "utils/memutils.h"
#include "utils/builtins.h"
#include "utils/array.h"
#include "storage/spin.h"


PGDLLEXPORT MemoryContext pgx_GetMemoryContextChunk(void *ptr);
MemoryContext pgx_GetMemoryContextChunk(void *ptr) {
return GetMemoryChunkContext(ptr);
}

PGDLLEXPORT void pgx_elog(int32 level, char *message);
void pgx_elog(int32 level, char *message) {
void pgx_elog(int32 level, const char *message) {
elog(level, "%s", message);
}

PGDLLEXPORT void pgx_elog_error(char *message);
void pgx_elog_error(char *message) {
void pgx_elog_error(const char *message) {
elog(ERROR, "%s", message);
}

PGDLLEXPORT void pgx_ereport(int level, int code, char *message, char *file, int lineno, int colno);
void pgx_ereport(int level, int code, char *message, char *file, int lineno, int colno) {
void pgx_ereport(int level, int code, const char *message, const char *file, int lineno, int colno) {
ereport(level,
(errcode(code),
errmsg("%s", message), errcontext_msg("%s:%d:%d", file, lineno, colno)));
}

PGDLLEXPORT void pgx_SET_VARSIZE(struct varlena *ptr, int size);
void pgx_SET_VARSIZE(struct varlena *ptr, int size) {
SET_VARSIZE(ptr, size);
}

PGDLLEXPORT void pgx_SET_VARSIZE_SHORT(struct varlena *ptr, int size);
void pgx_SET_VARSIZE_SHORT(struct varlena *ptr, int size) {
SET_VARSIZE_SHORT(ptr, size);
}

PGDLLEXPORT Datum pgx_heap_getattr(HeapTupleData *tuple, int attnum, TupleDesc tupdesc, bool *isnull);
Datum pgx_heap_getattr(HeapTupleData *tuple, int attnum, TupleDesc tupdesc, bool *isnull) {
return heap_getattr(tuple, attnum, tupdesc, isnull);
}

PGDLLEXPORT TransactionId pgx_HeapTupleHeaderGetXmin(HeapTupleHeader htup_header);
TransactionId pgx_HeapTupleHeaderGetXmin(HeapTupleHeader htup_header) {
return HeapTupleHeaderGetXmin(htup_header);
}

PGDLLEXPORT CommandId pgx_HeapTupleHeaderGetRawCommandId(HeapTupleHeader htup_header);
CommandId pgx_HeapTupleHeaderGetRawCommandId(HeapTupleHeader htup_header) {
return HeapTupleHeaderGetRawCommandId(htup_header);
}

PGDLLEXPORT RangeTblEntry *pgx_planner_rt_fetch(Index index, PlannerInfo *plannerInfo);
RangeTblEntry *pgx_planner_rt_fetch(Index index, PlannerInfo *root) {
return planner_rt_fetch(index, root);
}

PGDLLEXPORT void *pgx_list_nth(List *list, int nth);
void *pgx_list_nth(List *list, int nth) {
return list_nth(list, nth);
}

PGDLLEXPORT int pgx_list_nth_int(List *list, int nth);
int pgx_list_nth_int(List *list, int nth) {
return list_nth_int(list, nth);
}

PGDLLEXPORT Oid pgx_list_nth_oid(List *list, int nth);
Oid pgx_list_nth_oid(List *list, int nth) {
return list_nth_oid(list, nth);
}

PGDLLEXPORT ListCell *pgx_list_nth_cell(List *list, int nth);
ListCell *pgx_list_nth_cell(List *list, int nth) {
return list_nth_cell(list, nth);
}

#if IS_PG_10 || IS_PG_11
PGDLLEXPORT Oid pgx_HeapTupleHeaderGetOid(HeapTupleHeader htup_header);
Oid pgx_HeapTupleHeaderGetOid(HeapTupleHeader htup_header) {
return HeapTupleHeaderGetOid(htup_header);
}
#endif

PGDLLEXPORT char *pgx_GETSTRUCT(HeapTuple tuple);
char *pgx_GETSTRUCT(HeapTuple tuple) {
return GETSTRUCT(tuple);
}

PGDLLEXPORT char *pgx_ARR_DATA_PTR(ArrayType *arr);
char *pgx_ARR_DATA_PTR(ArrayType *arr) {
return ARR_DATA_PTR(arr);
}

PGDLLEXPORT int pgx_ARR_NELEMS(ArrayType *arr);
int pgx_ARR_NELEMS(ArrayType *arr) {
return ArrayGetNItems(arr->ndim, ARR_DIMS(arr));
}

PGDLLEXPORT bits8 *pgx_ARR_NULLBITMAP(ArrayType *arr);
bits8 *pgx_ARR_NULLBITMAP(ArrayType *arr) {
return ARR_NULLBITMAP(arr);
}

PGDLLEXPORT int pgx_ARR_NDIM(ArrayType *arr);
int pgx_ARR_NDIM(ArrayType *arr) {
return ARR_NDIM(arr);
}

PGDLLEXPORT bool pgx_ARR_HASNULL(ArrayType *arr);
bool pgx_ARR_HASNULL(ArrayType *arr) {
return ARR_HASNULL(arr);
}

PGDLLEXPORT int *pgx_ARR_DIMS(ArrayType *arr);
int *pgx_ARR_DIMS(ArrayType *arr){
return ARR_DIMS(arr);
}

PGDLLEXPORT void pgx_SpinLockInit(volatile slock_t *lock);
void pgx_SpinLockInit(volatile slock_t *lock) {
SpinLockInit(lock);
}

PGDLLEXPORT void pgx_SpinLockAcquire(volatile slock_t *lock);
void pgx_SpinLockAcquire(volatile slock_t *lock) {
SpinLockAcquire(lock);
}

PGDLLEXPORT void pgx_SpinLockRelease(volatile slock_t *lock);
void pgx_SpinLockRelease(volatile slock_t *lock) {
SpinLockRelease(lock);
}

PGDLLEXPORT bool pgx_SpinLockFree(slock_t *lock);
bool pgx_SpinLockFree(slock_t *lock) {
return SpinLockFree(lock);
}
59 changes: 59 additions & 0 deletions pgx-pg-sys/cshim/pgx-cshim.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
Portions Copyright 2019-2021 ZomboDB, LLC.
Portions Copyright 2021-2022 Technology Concepts & Design, Inc. <[email protected]>
All rights reserved.
Use of this source code is governed by the MIT license that can be found in the LICENSE file.
*/
#pragma once
#include "postgres.h"

#define IS_PG_10 (PG_VERSION_NUM >= 100000 && PG_VERSION_NUM < 110000)
#define IS_PG_11 (PG_VERSION_NUM >= 110000 && PG_VERSION_NUM < 120000)
#define IS_PG_12 (PG_VERSION_NUM >= 120000 && PG_VERSION_NUM < 130000)
#define IS_PG_13 (PG_VERSION_NUM >= 130000 && PG_VERSION_NUM < 140000)

#include "access/htup.h"
#include "access/htup_details.h"
#include "catalog/pg_type.h"
#if IS_PG_10 || IS_PG_11
#include "nodes/relation.h"
#else
#include "nodes/pathnodes.h"
#endif
#include "nodes/pg_list.h"
#include "parser/parsetree.h"
#include "utils/memutils.h"
#include "utils/builtins.h"
#include "utils/array.h"
#include "storage/spin.h"

PGDLLEXPORT MemoryContext pgx_GetMemoryContextChunk(void *ptr);
PGDLLEXPORT void pgx_elog(int32 level, const char *message);
PGDLLEXPORT void pgx_elog_error(const char *message);
PGDLLEXPORT void pgx_ereport(int level, int code, const char *message, const char *file, int lineno, int colno);
PGDLLEXPORT void pgx_SET_VARSIZE(struct varlena *ptr, int size);
PGDLLEXPORT void pgx_SET_VARSIZE_SHORT(struct varlena *ptr, int size);
PGDLLEXPORT Datum pgx_heap_getattr(HeapTupleData *tuple, int attnum, TupleDesc tupdesc, bool *isnull);
PGDLLEXPORT TransactionId pgx_HeapTupleHeaderGetXmin(HeapTupleHeader htup_header);
PGDLLEXPORT CommandId pgx_HeapTupleHeaderGetRawCommandId(HeapTupleHeader htup_header);
PGDLLEXPORT RangeTblEntry *pgx_planner_rt_fetch(Index index, PlannerInfo *plannerInfo);
PGDLLEXPORT void *pgx_list_nth(List *list, int nth);
PGDLLEXPORT int pgx_list_nth_int(List *list, int nth);
PGDLLEXPORT Oid pgx_list_nth_oid(List *list, int nth);
PGDLLEXPORT ListCell *pgx_list_nth_cell(List *list, int nth);
#if IS_PG_10 || IS_PG_11
PGDLLEXPORT Oid pgx_HeapTupleHeaderGetOid(HeapTupleHeader htup_header);
#endif
PGDLLEXPORT char *pgx_GETSTRUCT(HeapTuple tuple);
PGDLLEXPORT char *pgx_ARR_DATA_PTR(ArrayType *arr);
PGDLLEXPORT int pgx_ARR_NELEMS(ArrayType *arr);
PGDLLEXPORT bits8 *pgx_ARR_NULLBITMAP(ArrayType *arr);
PGDLLEXPORT int pgx_ARR_NDIM(ArrayType *arr);
PGDLLEXPORT bool pgx_ARR_HASNULL(ArrayType *arr);
PGDLLEXPORT int *pgx_ARR_DIMS(ArrayType *arr);
PGDLLEXPORT void pgx_SpinLockInit(volatile slock_t *lock);
PGDLLEXPORT void pgx_SpinLockAcquire(volatile slock_t *lock);
PGDLLEXPORT void pgx_SpinLockRelease(volatile slock_t *lock);
PGDLLEXPORT bool pgx_SpinLockFree(slock_t *lock);
53 changes: 6 additions & 47 deletions pgx-pg-sys/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -222,8 +222,6 @@ impl AsPgCStr for String {
/// item declarations we want to add to all versions
mod all_versions {
use crate as pg_sys;
use pgx_macros::*;

use memoffset::*;
use std::str::FromStr;

Expand All @@ -243,15 +241,6 @@ mod all_versions {
pub const FirstNormalTransactionId: super::TransactionId = 3 as super::TransactionId;
pub const MaxTransactionId: super::TransactionId = 0xFFFF_FFFF as super::TransactionId;

#[pgx_macros::pg_guard]
extern "C" {
pub fn pgx_list_nth(list: *mut super::List, nth: i32) -> *mut std::os::raw::c_void;
pub fn pgx_list_nth_int(list: *mut super::List, nth: i32) -> i32;
pub fn pgx_list_nth_oid(list: *mut super::List, nth: i32) -> super::Oid;
pub fn pgx_list_nth_cell(list: *mut super::List, nth: i32) -> *mut super::ListCell;
pub fn pgx_GETSTRUCT(tuple: pg_sys::HeapTuple) -> *mut std::os::raw::c_char;
}

#[inline]
pub fn VARHDRSZ_EXTERNAL() -> usize {
offset_of!(super::varattrib_1b_e, va_data)
Expand Down Expand Up @@ -322,7 +311,7 @@ mod all_versions {
index: super::Index,
range_table: *mut super::List,
) -> *mut super::RangeTblEntry {
pgx_list_nth(range_table, index as i32 - 1) as *mut super::RangeTblEntry
pg_sys::pgx_list_nth(range_table, index as i32 - 1) as *mut super::RangeTblEntry
}

#[inline]
Expand Down Expand Up @@ -429,44 +418,14 @@ mod all_versions {
if htup.is_null() {
0 as *mut T
} else {
unsafe { pgx_GETSTRUCT(htup) as *mut T }
unsafe { pg_sys::pgx_GETSTRUCT(htup) as *mut T }
}
}

#[pg_guard]
extern "C" {
pub fn query_tree_walker(
query: *mut super::Query,
walker: ::std::option::Option<
unsafe extern "C" fn(*mut super::Node, *mut ::std::os::raw::c_void) -> bool,
>,
context: *mut ::std::os::raw::c_void,
flags: ::std::os::raw::c_int,
) -> bool;
}

#[pg_guard]
extern "C" {
pub fn expression_tree_walker(
node: *mut super::Node,
walker: ::std::option::Option<
unsafe extern "C" fn(*mut super::Node, *mut ::std::os::raw::c_void) -> bool,
>,
context: *mut ::std::os::raw::c_void,
) -> bool;
}

#[pgx_macros::pg_guard]
extern "C" {
#[link_name = "pgx_SpinLockInit"]
pub fn SpinLockInit(lock: *mut pg_sys::slock_t);
#[link_name = "pgx_SpinLockAcquire"]
pub fn SpinLockAcquire(lock: *mut pg_sys::slock_t);
#[link_name = "pgx_SpinLockRelease"]
pub fn SpinLockRelease(lock: *mut pg_sys::slock_t);
#[link_name = "pgx_SpinLockFree"]
pub fn SpinLockFree(lock: *mut pg_sys::slock_t) -> bool;
}
pub use crate::{
pgx_SpinLockAcquire as SpinLockAcquire, pgx_SpinLockFree as SpinLockFree,
pgx_SpinLockInit as SpinLockInit, pgx_SpinLockRelease as SpinLockRelease,
};
}

mod internal {
Expand Down
15 changes: 3 additions & 12 deletions pgx-pg-sys/src/submodules/guard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,6 @@ use std::panic::{catch_unwind, RefUnwindSafe, UnwindSafe};

extern "C" {
fn pg_re_throw();
fn pgx_ereport(
level: i32,
code: i32,
message: *const std::os::raw::c_char,
file: *const std::os::raw::c_char,
lineno: i32,
colno: i32,
);

}

#[derive(Clone, Debug)]
Expand Down Expand Up @@ -230,11 +221,11 @@ where
let c_file = std::ffi::CString::new(location.file).unwrap();

unsafe {
pgx_ereport(
crate::pgx_ereport(
crate::ERROR as i32,
2600, // ERRCODE_INTERNAL_ERROR
c_message.as_ptr(),
c_file.as_ptr(),
c_message.as_ptr().cast::<std::os::raw::c_char>(),
c_file.as_ptr().cast::<std::os::raw::c_char>(),
location.line as i32,
location.col as i32,
);
Expand Down

0 comments on commit ad351b3

Please sign in to comment.