use crate as pg_sys;
use crate::BLCKSZ;
use core::mem::offset_of;
use core::str::FromStr;
pub const InvalidOid: crate::Oid = crate::Oid::INVALID;
pub const InvalidOffsetNumber: super::OffsetNumber = 0;
pub const FirstOffsetNumber: super::OffsetNumber = 1;
pub const MaxOffsetNumber: super::OffsetNumber =
(super::BLCKSZ as usize / std::mem::size_of::<super::ItemIdData>()) as super::OffsetNumber;
pub const InvalidBlockNumber: u32 = 0xFFFF_FFFF as crate::BlockNumber;
pub const VARHDRSZ: usize = std::mem::size_of::<super::int32>();
pub const InvalidCommandId: super::CommandId = (!(0 as super::CommandId)) as super::CommandId;
pub const FirstCommandId: super::CommandId = 0 as super::CommandId;
pub const InvalidTransactionId: crate::TransactionId = crate::TransactionId::INVALID;
pub const BootstrapTransactionId: crate::TransactionId = crate::TransactionId::BOOTSTRAP;
pub const FrozenTransactionId: crate::TransactionId = crate::TransactionId::FROZEN;
pub const FirstNormalTransactionId: crate::TransactionId = crate::TransactionId::FIRST_NORMAL;
pub const MaxTransactionId: crate::TransactionId = crate::TransactionId::MAX;
#[inline(always)]
pub unsafe fn GETSTRUCT(tuple: crate::HeapTuple) -> *mut std::os::raw::c_char {
(*tuple).t_data.cast::<std::os::raw::c_char>().add((*(*tuple).t_data).t_hoff as _)
}
#[allow(non_snake_case)]
#[inline(always)]
pub const unsafe fn TYPEALIGN(alignval: usize, len: usize) -> usize {
((len) + ((alignval) - 1)) & !((alignval) - 1)
}
#[allow(non_snake_case)]
#[inline(always)]
pub const unsafe fn MAXALIGN(len: usize) -> usize {
TYPEALIGN(pg_sys::MAXIMUM_ALIGNOF as _, len)
}
#[allow(non_snake_case)]
pub unsafe fn GetMemoryChunkContext(pointer: *mut std::os::raw::c_void) -> pg_sys::MemoryContext {
#[cfg(any(feature = "pg13", feature = "pg14", feature = "pg15"))]
{
assert!(!pointer.is_null());
assert_eq!(pointer, MAXALIGN(pointer as usize) as *mut ::std::os::raw::c_void);
let context = unsafe {
*(pointer
.cast::<::std::os::raw::c_char>()
.sub(std::mem::size_of::<*mut ::std::os::raw::c_void>())
.cast())
};
assert!(MemoryContextIsValid(context));
context
}
#[cfg(any(feature = "pg16", feature = "pg17", feature = "pg18"))]
{
#[pgrx_macros::pg_guard]
unsafe extern "C-unwind" {
#[link_name = "GetMemoryChunkContext"]
pub fn extern_fn(pointer: *mut std::os::raw::c_void) -> pg_sys::MemoryContext;
}
extern_fn(pointer)
}
}
#[allow(non_snake_case)]
#[inline(always)]
pub unsafe fn MemoryContextIsValid(context: crate::MemoryContext) -> bool {
!context.is_null()
&& unsafe {
let tag = (*context.cast::<crate::Node>()).type_;
use crate::NodeTag::*;
matches!(tag, T_AllocSetContext | T_SlabContext | T_GenerationContext)
}
}
pub const VARHDRSZ_EXTERNAL: usize = offset_of!(super::varattrib_1b_e, va_data);
pub const VARHDRSZ_SHORT: usize = offset_of!(super::varattrib_1b, va_data);
#[inline]
pub fn get_pg_major_version_string() -> &'static str {
super::PG_MAJORVERSION.to_str().unwrap()
}
#[inline]
pub fn get_pg_major_version_num() -> u16 {
u16::from_str(super::get_pg_major_version_string()).unwrap()
}
#[cfg(any(not(target_env = "msvc"), feature = "pg17", feature = "pg18"))]
#[inline]
pub fn get_pg_version_string() -> &'static str {
super::PG_VERSION_STR.to_str().unwrap()
}
#[cfg(all(
target_env = "msvc",
any(feature = "pg13", feature = "pg14", feature = "pg15", feature = "pg16")
))]
#[inline]
pub fn get_pg_version_string() -> &'static str {
static PG_VERSION_STR: [u8; 256] = const {
let major = super::PG_MAJORVERSION_NUM;
let minor = super::PG_MINORVERSION_NUM;
#[cfg(target_pointer_width = "32")]
let pointer_width = 32_u32;
#[cfg(target_pointer_width = "64")]
let pointer_width = 64_u32;
let msc_ver = b"1700";
let mut buffer = [0u8; 256];
let mut pointer = 0;
{
let s = b"PostgreSQL ";
let mut i = 0;
while i < s.len() {
buffer[pointer + i] = s[i];
i += 1;
}
pointer += s.len();
}
{
buffer[pointer + 0] = b'0' + (major / 10) as u8;
buffer[pointer + 1] = b'0' + (major % 10) as u8;
pointer += 2;
}
{
let s = b".";
let mut i = 0;
while i < s.len() {
buffer[pointer + i] = s[i];
i += 1;
}
pointer += s.len();
}
if minor < 10 {
buffer[pointer + 0] = b'0' + (minor % 10) as u8;
pointer += 1;
} else {
buffer[pointer + 0] = b'0' + (minor / 10) as u8;
buffer[pointer + 1] = b'0' + (minor % 10) as u8;
pointer += 2;
}
{
let s = b", compiled by Visual C++ build ";
let mut i = 0;
while i < s.len() {
buffer[pointer + i] = s[i];
i += 1;
}
pointer += s.len();
}
{
let s = msc_ver;
let mut i = 0;
while i < s.len() {
buffer[pointer + i] = s[i];
i += 1;
}
pointer += s.len();
}
{
let s = b", ";
let mut i = 0;
while i < s.len() {
buffer[pointer + i] = s[i];
i += 1;
}
pointer += s.len();
}
{
buffer[pointer + 0] = b'0' + (pointer_width / 10) as u8;
buffer[pointer + 1] = b'0' + (pointer_width % 10) as u8;
pointer += 2;
}
{
let s = b"-bit";
let mut i = 0;
while i < s.len() {
buffer[pointer + i] = s[i];
i += 1;
}
pointer += s.len();
}
buffer[pointer] = 0;
buffer
};
unsafe { std::ffi::CStr::from_ptr(PG_VERSION_STR.as_ptr().cast()).to_str().unwrap() }
}
#[inline]
pub fn get_pg_major_minor_version_string() -> &'static str {
super::PG_VERSION.to_str().unwrap()
}
#[inline]
pub fn TransactionIdIsNormal(xid: super::TransactionId) -> bool {
xid >= FirstNormalTransactionId
}
#[inline]
pub unsafe fn type_is_array(typoid: super::Oid) -> bool {
super::get_element_type(typoid) != InvalidOid
}
#[inline]
pub unsafe fn BufferGetPage(buffer: crate::Buffer) -> crate::Page {
BufferGetBlock(buffer) as crate::Page
}
#[inline]
pub unsafe fn BufferGetBlock(buffer: crate::Buffer) -> crate::Block {
if BufferIsLocal(buffer) {
*crate::LocalBufferBlockPointers.offset(((-buffer) - 1) as isize)
} else {
crate::BufferBlocks.add(((buffer as crate::Size) - 1) * crate::BLCKSZ as usize)
as crate::Block
}
}
#[inline]
pub unsafe fn BufferIsLocal(buffer: crate::Buffer) -> bool {
buffer < 0
}
#[inline]
pub unsafe fn heap_tuple_get_struct<T>(htup: super::HeapTuple) -> *mut T {
if htup.is_null() {
std::ptr::null_mut()
} else {
unsafe {
GETSTRUCT(htup).cast()
}
}
}
#[cfg(any(feature = "pg13", feature = "pg14", feature = "pg15"))]
#[::pgrx_macros::pg_guard]
unsafe extern "C-unwind" {
pub fn planstate_tree_walker(
planstate: *mut super::PlanState,
walker: ::core::option::Option<
unsafe extern "C-unwind" fn(*mut super::PlanState, *mut ::core::ffi::c_void) -> bool,
>,
context: *mut ::core::ffi::c_void,
) -> bool;
pub fn query_tree_walker(
query: *mut super::Query,
walker: ::core::option::Option<
unsafe extern "C-unwind" fn(*mut super::Node, *mut ::core::ffi::c_void) -> bool,
>,
context: *mut ::core::ffi::c_void,
flags: ::core::ffi::c_int,
) -> bool;
pub fn query_or_expression_tree_walker(
node: *mut super::Node,
walker: ::core::option::Option<
unsafe extern "C-unwind" fn(*mut super::Node, *mut ::core::ffi::c_void) -> bool,
>,
context: *mut ::core::ffi::c_void,
flags: ::core::ffi::c_int,
) -> bool;
pub fn range_table_entry_walker(
rte: *mut super::RangeTblEntry,
walker: ::core::option::Option<
unsafe extern "C-unwind" fn(*mut super::Node, *mut ::core::ffi::c_void) -> bool,
>,
context: *mut ::core::ffi::c_void,
flags: ::core::ffi::c_int,
) -> bool;
pub fn range_table_walker(
rtable: *mut super::List,
walker: ::core::option::Option<
unsafe extern "C-unwind" fn(*mut super::Node, *mut ::core::ffi::c_void) -> bool,
>,
context: *mut ::core::ffi::c_void,
flags: ::core::ffi::c_int,
) -> bool;
pub fn expression_tree_walker(
node: *mut super::Node,
walker: ::core::option::Option<
unsafe extern "C-unwind" fn(*mut super::Node, *mut ::core::ffi::c_void) -> bool,
>,
context: *mut ::core::ffi::c_void,
) -> bool;
pub fn raw_expression_tree_walker(
node: *mut super::Node,
walker: ::core::option::Option<
unsafe extern "C-unwind" fn(*mut super::Node, *mut ::core::ffi::c_void) -> bool,
>,
context: *mut ::core::ffi::c_void,
) -> bool;
}
#[cfg(any(feature = "pg16", feature = "pg17", feature = "pg18"))]
pub unsafe fn planstate_tree_walker(
planstate: *mut super::PlanState,
walker: ::core::option::Option<
unsafe extern "C-unwind" fn(*mut super::PlanState, *mut ::core::ffi::c_void) -> bool,
>,
context: *mut ::core::ffi::c_void,
) -> bool {
crate::planstate_tree_walker_impl(planstate, walker, context)
}
#[cfg(any(feature = "pg16", feature = "pg17", feature = "pg18"))]
pub unsafe fn query_tree_walker(
query: *mut super::Query,
walker: ::core::option::Option<
unsafe extern "C-unwind" fn(*mut super::Node, *mut ::core::ffi::c_void) -> bool,
>,
context: *mut ::core::ffi::c_void,
flags: ::core::ffi::c_int,
) -> bool {
crate::query_tree_walker_impl(query, walker, context, flags)
}
#[cfg(any(feature = "pg16", feature = "pg17", feature = "pg18"))]
pub unsafe fn query_or_expression_tree_walker(
node: *mut super::Node,
walker: ::core::option::Option<
unsafe extern "C-unwind" fn(*mut super::Node, *mut ::core::ffi::c_void) -> bool,
>,
context: *mut ::core::ffi::c_void,
flags: ::core::ffi::c_int,
) -> bool {
crate::query_or_expression_tree_walker_impl(node, walker, context, flags)
}
#[cfg(any(feature = "pg16", feature = "pg17", feature = "pg18"))]
pub unsafe fn expression_tree_walker(
node: *mut crate::Node,
walker: Option<unsafe extern "C-unwind" fn(*mut crate::Node, *mut ::core::ffi::c_void) -> bool>,
context: *mut ::core::ffi::c_void,
) -> bool {
crate::expression_tree_walker_impl(node, walker, context)
}
#[cfg(any(feature = "pg16", feature = "pg17", feature = "pg18"))]
pub unsafe fn range_table_entry_walker(
rte: *mut super::RangeTblEntry,
walker: ::core::option::Option<
unsafe extern "C-unwind" fn(*mut super::Node, *mut ::core::ffi::c_void) -> bool,
>,
context: *mut ::core::ffi::c_void,
flags: ::core::ffi::c_int,
) -> bool {
crate::range_table_entry_walker_impl(rte, walker, context, flags)
}
#[cfg(any(feature = "pg16", feature = "pg17", feature = "pg18"))]
pub unsafe fn range_table_walker(
rtable: *mut super::List,
walker: ::core::option::Option<
unsafe extern "C-unwind" fn(*mut super::Node, *mut ::core::ffi::c_void) -> bool,
>,
context: *mut ::core::ffi::c_void,
flags: ::core::ffi::c_int,
) -> bool {
crate::range_table_walker_impl(rtable, walker, context, flags)
}
#[cfg(any(feature = "pg16", feature = "pg17", feature = "pg18"))]
pub unsafe fn raw_expression_tree_walker(
node: *mut crate::Node,
walker: Option<unsafe extern "C-unwind" fn(*mut crate::Node, *mut ::core::ffi::c_void) -> bool>,
context: *mut ::core::ffi::c_void,
) -> bool {
crate::raw_expression_tree_walker_impl(node, walker, context)
}
#[cfg(feature = "pg18")]
pub unsafe fn expression_tree_mutator(
node: *mut crate::Node,
mutator: crate::tree_mutator_callback,
context: *mut ::core::ffi::c_void,
) -> *mut crate::Node {
crate::expression_tree_mutator_impl(node, mutator, context)
}
#[inline(always)]
pub unsafe fn MemoryContextSwitchTo(context: crate::MemoryContext) -> crate::MemoryContext {
let old = crate::CurrentMemoryContext;
crate::CurrentMemoryContext = context;
old
}
#[allow(non_snake_case)]
#[inline(always)]
#[cfg(any(feature = "pg13", feature = "pg14", feature = "pg15"))]
pub unsafe fn BufferGetPageSize(buffer: pg_sys::Buffer) -> pg_sys::Size {
assert!(BufferIsValid(buffer));
pg_sys::BLCKSZ as pg_sys::Size
}
#[allow(non_snake_case)]
#[inline(always)]
#[cfg(any(feature = "pg13", feature = "pg14", feature = "pg15"))]
pub unsafe fn ItemIdGetOffset(item_id: pg_sys::ItemId) -> u32 {
(*item_id).lp_off()
}
#[allow(non_snake_case)]
#[inline(always)]
pub const unsafe fn PageIsValid(page: pg_sys::Page) -> bool {
!page.is_null()
}
#[allow(non_snake_case)]
#[inline(always)]
#[cfg(any(feature = "pg13", feature = "pg14", feature = "pg15"))]
pub unsafe fn PageIsEmpty(page: pg_sys::Page) -> bool {
const SizeOfPageHeaderData: pg_sys::Size =
core::mem::offset_of!(pg_sys::PageHeaderData, pd_linp);
let page_header = page as *mut pg_sys::PageHeaderData;
(*page_header).pd_lower <= SizeOfPageHeaderData as u16
}
#[allow(non_snake_case)]
#[inline(always)]
#[cfg(any(feature = "pg13", feature = "pg14", feature = "pg15"))]
pub unsafe fn PageIsNew(page: pg_sys::Page) -> bool {
let page_header = page as *mut pg_sys::PageHeaderData;
(*page_header).pd_upper == 0
}
#[allow(non_snake_case)]
#[inline(always)]
#[cfg(any(feature = "pg13", feature = "pg14", feature = "pg15"))]
pub unsafe fn PageGetItemId(page: pg_sys::Page, offset: pg_sys::OffsetNumber) -> pg_sys::ItemId {
let page_header = page as *mut pg_sys::PageHeaderData;
(*page_header).pd_linp.as_mut_ptr().add(offset as usize - 1)
}
#[allow(non_snake_case)]
#[inline(always)]
#[cfg(any(feature = "pg13", feature = "pg14", feature = "pg15"))]
pub unsafe fn PageGetContents(page: pg_sys::Page) -> *mut ::core::ffi::c_char {
const SizeOfPageHeaderData: pg_sys::Size =
core::mem::offset_of!(pg_sys::PageHeaderData, pd_linp);
page.add(pg_sys::MAXALIGN(SizeOfPageHeaderData)) as *mut ::core::ffi::c_char
}
#[allow(non_snake_case)]
#[inline(always)]
#[cfg(any(feature = "pg13", feature = "pg14", feature = "pg15"))]
pub fn PageSizeIsValid(page_size: usize) -> bool {
page_size == pg_sys::BLCKSZ as usize
}
#[allow(non_snake_case)]
#[inline(always)]
#[cfg(any(feature = "pg13", feature = "pg14", feature = "pg15"))]
pub unsafe fn PageGetPageSize(page: pg_sys::Page) -> usize {
let page_header = page as *mut pg_sys::PageHeaderData;
((*page_header).pd_pagesize_version & 0xFF00) as usize
}
#[allow(non_snake_case)]
#[inline(always)]
#[cfg(any(feature = "pg13", feature = "pg14", feature = "pg15"))]
pub unsafe fn PageGetPageLayoutVersion(page: pg_sys::Page) -> ::core::ffi::c_char {
let page_header = page as *mut pg_sys::PageHeaderData;
((*page_header).pd_pagesize_version & 0x00FF) as ::core::ffi::c_char
}
#[allow(non_snake_case)]
#[inline(always)]
#[cfg(any(feature = "pg13", feature = "pg14", feature = "pg15"))]
pub unsafe fn PageSetPageSizeAndVersion(page: pg_sys::Page, size: u16, version: u8) {
let page_header = page as *mut pg_sys::PageHeaderData;
(*page_header).pd_pagesize_version = size | (version as u16);
}
#[allow(non_snake_case)]
#[inline(always)]
#[cfg(any(feature = "pg13", feature = "pg14", feature = "pg15"))]
pub unsafe fn PageGetSpecialSize(page: pg_sys::Page) -> u16 {
let page_header = page as *mut pg_sys::PageHeaderData;
PageGetPageSize(page) as u16 - (*page_header).pd_special
}
pub const unsafe fn SizeOfPageHeaderData() -> usize {
offset_of!(pg_sys::PageHeaderData, pd_linp)
}
#[allow(non_snake_case)]
#[inline(always)]
pub const unsafe fn PageValidateSpecialPointer(page: pg_sys::Page) -> bool {
assert!(PageIsValid(page));
let page = page as *mut pg_sys::PageHeaderData;
assert!((*page).pd_special <= BLCKSZ as _);
assert!((*page).pd_special >= SizeOfPageHeaderData() as _);
true
}
#[allow(non_snake_case)]
#[inline(always)]
#[cfg(any(feature = "pg13", feature = "pg14", feature = "pg15", feature = "pg18"))]
pub unsafe fn PageGetSpecialPointer(page: pg_sys::Page) -> *mut ::core::ffi::c_char {
assert!(PageValidateSpecialPointer(page));
let page_header = page as *mut pg_sys::PageHeaderData;
page.add((*page_header).pd_special as usize) as *mut ::core::ffi::c_char
}
#[allow(non_snake_case)]
#[inline(always)]
#[cfg(any(feature = "pg13", feature = "pg14", feature = "pg15"))]
pub unsafe fn PageGetItem(page: pg_sys::Page, item_id: pg_sys::ItemId) -> *mut ::core::ffi::c_char {
page.add(ItemIdGetOffset(item_id) as usize)
}
#[allow(non_snake_case)]
#[inline(always)]
#[cfg(any(feature = "pg13", feature = "pg14", feature = "pg15"))]
pub unsafe fn PageGetMaxOffsetNumber(page: pg_sys::Page) -> pg_sys::OffsetNumber {
const SizeOfPageHeaderData: pg_sys::Size =
core::mem::offset_of!(pg_sys::PageHeaderData, pd_linp);
let page_header = page as *mut pg_sys::PageHeaderData;
if (*page_header).pd_lower <= SizeOfPageHeaderData as u16 {
0
} else {
((*page_header).pd_lower - SizeOfPageHeaderData as u16)
/ std::mem::size_of::<pg_sys::ItemIdData>() as u16
}
}
#[allow(non_snake_case)]
#[inline(always)]
#[cfg(any(feature = "pg13", feature = "pg14", feature = "pg15"))]
pub unsafe fn BufferIsValid(buffer: pg_sys::Buffer) -> bool {
assert!(buffer <= pg_sys::NBuffers);
assert!(buffer >= -pg_sys::NLocBuffer);
buffer != pg_sys::InvalidBuffer as pg_sys::Buffer
}