From ad351b3dbdaa9bb46989b3dbdf1cb99d01a288b1 Mon Sep 17 00:00:00 2001 From: Thom Chiovoloni Date: Mon, 24 Oct 2022 12:14:20 -0700 Subject: [PATCH] Split the shim into a separate header, that we run bindgen on --- pgx-pg-sys/build.rs | 22 +++++++---- pgx-pg-sys/cshim/pgx-cshim.c | 56 ++-------------------------- pgx-pg-sys/cshim/pgx-cshim.h | 59 ++++++++++++++++++++++++++++++ pgx-pg-sys/src/lib.rs | 53 +++------------------------ pgx-pg-sys/src/submodules/guard.rs | 15 ++------ 5 files changed, 87 insertions(+), 118 deletions(-) create mode 100644 pgx-pg-sys/cshim/pgx-cshim.h diff --git a/pgx-pg-sys/build.rs b/pgx-pg-sys/build.rs index 614697b432..4e69d70418 100644 --- a/pgx-pg-sys/build.rs +++ b/pgx-pg-sys/build.rs @@ -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); @@ -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 { +fn run_bindgen( + pg_config: &PgConfig, + manifest_path: &PathBuf, + header_src: &str, +) -> eyre::Result { 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 diff --git a/pgx-pg-sys/cshim/pgx-cshim.c b/pgx-pg-sys/cshim/pgx-cshim.c index a3acce9b91..3a87795090 100644 --- a/pgx-pg-sys/cshim/pgx-cshim.c +++ b/pgx-pg-sys/cshim/pgx-cshim.c @@ -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); } diff --git a/pgx-pg-sys/cshim/pgx-cshim.h b/pgx-pg-sys/cshim/pgx-cshim.h new file mode 100644 index 0000000000..eedeb1283e --- /dev/null +++ b/pgx-pg-sys/cshim/pgx-cshim.h @@ -0,0 +1,59 @@ +/* +Portions Copyright 2019-2021 ZomboDB, LLC. +Portions Copyright 2021-2022 Technology Concepts & Design, Inc. + +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); diff --git a/pgx-pg-sys/src/lib.rs b/pgx-pg-sys/src/lib.rs index 98608c73b1..93cf3e71b0 100644 --- a/pgx-pg-sys/src/lib.rs +++ b/pgx-pg-sys/src/lib.rs @@ -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; @@ -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) @@ -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] @@ -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 { diff --git a/pgx-pg-sys/src/submodules/guard.rs b/pgx-pg-sys/src/submodules/guard.rs index b2c3312b44..5911854c46 100644 --- a/pgx-pg-sys/src/submodules/guard.rs +++ b/pgx-pg-sys/src/submodules/guard.rs @@ -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)] @@ -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::(), + c_file.as_ptr().cast::(), location.line as i32, location.col as i32, );