1#![allow(non_camel_case_types)]
15#![allow(non_snake_case)]
16#![allow(dead_code)]
17#![allow(non_upper_case_globals)]
18#![allow(improper_ctypes)]
19#![allow(clippy::unneeded_field_pattern)]
20#![cfg_attr(nightly, feature(strict_provenance))]
21
22#[cfg(
23 any(
24 not(any(feature = "pg11", feature = "pg12", feature = "pg13", feature = "pg14", feature = "pg15")),
26 ))]
27std::compile_error!("exactly one one feature must be provided (pg11, pg12, pg13, pg14, pg15)");
28
29pub mod submodules;
30
31use core::ffi::CStr;
32use core::ptr::NonNull;
33use std::os::raw::c_char;
34
35pub use submodules::*;
37
38#[cfg(all(feature = "pg11", not(docsrs)))]
44mod pg11 {
45 include!(concat!(env!("OUT_DIR"), "/pg11.rs"));
46}
47#[cfg(all(feature = "pg11", docsrs))]
48mod pg11;
49
50#[cfg(all(feature = "pg12", not(docsrs)))]
51mod pg12 {
52 include!(concat!(env!("OUT_DIR"), "/pg12.rs"));
53}
54#[cfg(all(feature = "pg12", docsrs))]
55mod pg12;
56
57#[cfg(all(feature = "pg13", not(docsrs)))]
58mod pg13 {
59 include!(concat!(env!("OUT_DIR"), "/pg13.rs"));
60}
61#[cfg(all(feature = "pg13", docsrs))]
62mod pg13;
63
64#[cfg(all(feature = "pg14", not(docsrs)))]
65mod pg14 {
66 include!(concat!(env!("OUT_DIR"), "/pg14.rs"));
67}
68#[cfg(all(feature = "pg14", docsrs))]
69mod pg14;
70
71#[cfg(all(feature = "pg15", not(docsrs)))]
72mod pg15 {
73 include!(concat!(env!("OUT_DIR"), "/pg15.rs"));
74}
75#[cfg(all(feature = "pg15", docsrs))]
76mod pg15;
77
78#[cfg(feature = "pg11")]
80pub use pg11::*;
81#[cfg(feature = "pg12")]
82pub use pg12::*;
83#[cfg(feature = "pg13")]
84pub use pg13::*;
85#[cfg(feature = "pg14")]
86pub use pg14::*;
87#[cfg(feature = "pg15")]
88pub use pg15::*;
89
90#[cfg(all(feature = "pg11", not(docsrs)))]
92mod pg11_oids {
93 include!(concat!(env!("OUT_DIR"), "/pg11_oids.rs"));
94}
95#[cfg(all(feature = "pg11", docsrs))]
96mod pg11;
97
98#[cfg(all(feature = "pg12", not(docsrs)))]
99mod pg12_oids {
100 include!(concat!(env!("OUT_DIR"), "/pg12_oids.rs"));
101}
102#[cfg(all(feature = "pg12", docsrs))]
103mod pg12_oids;
104
105#[cfg(all(feature = "pg13", not(docsrs)))]
106mod pg13_oids {
107 include!(concat!(env!("OUT_DIR"), "/pg13_oids.rs"));
108}
109#[cfg(all(feature = "pg13", docsrs))]
110mod pg13_oids;
111
112#[cfg(all(feature = "pg14", not(docsrs)))]
113mod pg14_oids {
114 include!(concat!(env!("OUT_DIR"), "/pg14_oids.rs"));
115}
116#[cfg(all(feature = "pg14", docsrs))]
117mod pg14_oids;
118
119#[cfg(all(feature = "pg15", not(docsrs)))]
120mod pg15_oids {
121 include!(concat!(env!("OUT_DIR"), "/pg15_oids.rs"));
122}
123#[cfg(all(feature = "pg15", docsrs))]
124mod pg15_oids;
125
126#[cfg(feature = "pg11")]
128pub use pg11_oids::*;
129#[cfg(feature = "pg12")]
130pub use pg12_oids::*;
131#[cfg(feature = "pg13")]
132pub use pg13_oids::*;
133#[cfg(feature = "pg14")]
134pub use pg14_oids::*;
135#[cfg(feature = "pg15")]
136pub use pg15_oids::*;
137
138pub use all_versions::*;
140
141#[cfg(feature = "pg11")]
143pub use internal::pg11::IndexBuildHeapScan;
144#[cfg(feature = "pg11")]
145pub use internal::pg11::*;
146
147#[cfg(feature = "pg12")]
148pub use internal::pg12::*;
149
150#[cfg(feature = "pg13")]
151pub use internal::pg13::*;
152
153#[cfg(feature = "pg14")]
154pub use internal::pg14::*;
155
156#[cfg(feature = "pg15")]
157pub use internal::pg15::*;
158
159pub trait PgNode: seal::Sealed {
161 #[inline]
173 fn display_node(&self) -> std::string::String {
174 unsafe { display_node_impl(NonNull::from(self).cast()) }
177 }
178}
179
180mod seal {
181 pub trait Sealed {}
182}
183
184#[warn(unsafe_op_in_unsafe_fn)]
189pub(crate) unsafe fn display_node_impl(node: NonNull<crate::Node>) -> std::string::String {
190 unsafe {
195 let node_cstr = crate::nodeToString(node.as_ptr().cast());
196
197 let result = match CStr::from_ptr(node_cstr).to_str() {
198 Ok(cstr) => cstr.to_string(),
199 Err(e) => format!("<ffi error: {:?}>", e),
200 };
201
202 crate::pfree(node_cstr.cast());
203
204 result
205 }
206}
207
208pub trait AsPgCStr {
210 fn as_pg_cstr(self) -> *mut std::os::raw::c_char;
212}
213
214impl<'a> AsPgCStr for &'a str {
215 fn as_pg_cstr(self) -> *mut std::os::raw::c_char {
216 let self_bytes = self.as_bytes();
217 let pg_cstr = unsafe { crate::palloc0(self_bytes.len() + 1) as *mut std::os::raw::c_uchar };
218 let slice = unsafe { std::slice::from_raw_parts_mut(pg_cstr, self_bytes.len()) };
219 slice.copy_from_slice(self_bytes);
220 pg_cstr as *mut std::os::raw::c_char
221 }
222}
223
224impl<'a> AsPgCStr for Option<&'a str> {
225 fn as_pg_cstr(self) -> *mut c_char {
226 match self {
227 Some(s) => s.as_pg_cstr(),
228 None => std::ptr::null_mut(),
229 }
230 }
231}
232
233impl AsPgCStr for std::string::String {
234 fn as_pg_cstr(self) -> *mut std::os::raw::c_char {
235 self.as_str().as_pg_cstr()
236 }
237}
238
239impl AsPgCStr for &std::string::String {
240 fn as_pg_cstr(self) -> *mut std::os::raw::c_char {
241 self.as_str().as_pg_cstr()
242 }
243}
244
245impl AsPgCStr for Option<std::string::String> {
246 fn as_pg_cstr(self) -> *mut c_char {
247 match self {
248 Some(s) => s.as_pg_cstr(),
249 None => std::ptr::null_mut(),
250 }
251 }
252}
253
254impl AsPgCStr for Option<&std::string::String> {
255 fn as_pg_cstr(self) -> *mut c_char {
256 match self {
257 Some(s) => s.as_pg_cstr(),
258 None => std::ptr::null_mut(),
259 }
260 }
261}
262
263impl AsPgCStr for &Option<std::string::String> {
264 fn as_pg_cstr(self) -> *mut c_char {
265 match self {
266 Some(s) => s.as_pg_cstr(),
267 None => std::ptr::null_mut(),
268 }
269 }
270}
271
272mod all_versions {
274 use crate as pg_sys;
275 use pgx_macros::*;
276
277 use memoffset::*;
278 use std::str::FromStr;
279
280 pub use crate::submodules::htup::*;
281
282 pub const InvalidOid: crate::Oid = crate::Oid::INVALID;
284 pub const InvalidOffsetNumber: super::OffsetNumber = 0;
285 pub const FirstOffsetNumber: super::OffsetNumber = 1;
286 pub const MaxOffsetNumber: super::OffsetNumber =
287 (super::BLCKSZ as usize / std::mem::size_of::<super::ItemIdData>()) as super::OffsetNumber;
288 pub const InvalidBlockNumber: u32 = 0xFFFF_FFFF as crate::BlockNumber;
289 pub const VARHDRSZ: usize = std::mem::size_of::<super::int32>();
290 pub const InvalidTransactionId: super::TransactionId = 0 as super::TransactionId;
291 pub const InvalidCommandId: super::CommandId = (!(0 as super::CommandId)) as super::CommandId;
292 pub const FirstCommandId: super::CommandId = 0 as super::CommandId;
293 pub const BootstrapTransactionId: super::TransactionId = 1 as super::TransactionId;
294 pub const FrozenTransactionId: super::TransactionId = 2 as super::TransactionId;
295 pub const FirstNormalTransactionId: super::TransactionId = 3 as super::TransactionId;
296 pub const MaxTransactionId: super::TransactionId = 0xFFFF_FFFF as super::TransactionId;
297
298 #[cfg(feature = "cshim")]
299 #[pgx_macros::pg_guard]
300 extern "C" {
301 pub fn pgx_list_nth(list: *mut super::List, nth: i32) -> *mut std::os::raw::c_void;
302 pub fn pgx_list_nth_int(list: *mut super::List, nth: i32) -> i32;
303 pub fn pgx_list_nth_oid(list: *mut super::List, nth: i32) -> super::Oid;
304 pub fn pgx_list_nth_cell(list: *mut super::List, nth: i32) -> *mut super::ListCell;
305 }
306
307 #[inline(always)]
313 pub unsafe fn GETSTRUCT(tuple: crate::HeapTuple) -> *mut std::os::raw::c_char {
314 (*tuple).t_data.cast::<std::os::raw::c_char>().add((*(*tuple).t_data).t_hoff as _)
319 }
320
321 #[allow(non_snake_case)]
327 #[inline(always)]
328 pub const unsafe fn TYPEALIGN(alignval: usize, len: usize) -> usize {
329 ((len) + ((alignval) - 1)) & !((alignval) - 1)
332 }
333
334 #[allow(non_snake_case)]
335 #[inline(always)]
336 pub const unsafe fn MAXALIGN(len: usize) -> usize {
337 TYPEALIGN(pg_sys::MAXIMUM_ALIGNOF as _, len)
339 }
340
341 #[allow(non_snake_case)]
360 pub unsafe fn GetMemoryContextChunk(
361 pointer: *mut std::os::raw::c_void,
362 ) -> pg_sys::MemoryContext {
363 assert!(!pointer.is_null());
369 assert_eq!(pointer, MAXALIGN(pointer as usize) as *mut ::std::os::raw::c_void);
370
371 let context = unsafe {
376 *(pointer
379 .cast::<::std::os::raw::c_char>()
380 .sub(std::mem::size_of::<*mut ::std::os::raw::c_void>())
381 .cast())
382 };
383
384 assert!(MemoryContextIsValid(context));
385
386 context
387 }
388
389 #[allow(non_snake_case)]
400 #[inline(always)]
401 pub unsafe fn MemoryContextIsValid(context: *mut crate::MemoryContextData) -> bool {
402 !context.is_null()
409 && unsafe {
410 (*context).type_ == crate::NodeTag_T_AllocSetContext
413 || (*context).type_ == crate::NodeTag_T_SlabContext
414 || (*context).type_ == crate::NodeTag_T_GenerationContext
415 }
416 }
417
418 #[inline]
419 pub fn VARHDRSZ_EXTERNAL() -> usize {
420 offset_of!(super::varattrib_1b_e, va_data)
421 }
422
423 #[inline]
424 pub fn VARHDRSZ_SHORT() -> usize {
425 offset_of!(super::varattrib_1b, va_data)
426 }
427
428 #[inline]
429 pub fn get_pg_major_version_string() -> &'static str {
430 let mver = core::ffi::CStr::from_bytes_with_nul(super::PG_MAJORVERSION).unwrap();
431 mver.to_str().unwrap()
432 }
433
434 #[inline]
435 pub fn get_pg_major_version_num() -> u16 {
436 u16::from_str(super::get_pg_major_version_string()).unwrap()
437 }
438
439 #[inline]
440 pub fn get_pg_version_string() -> &'static str {
441 let ver = core::ffi::CStr::from_bytes_with_nul(super::PG_VERSION_STR).unwrap();
442 ver.to_str().unwrap()
443 }
444
445 #[inline]
446 pub fn get_pg_major_minor_version_string() -> &'static str {
447 let mver = core::ffi::CStr::from_bytes_with_nul(super::PG_VERSION).unwrap();
448 mver.to_str().unwrap()
449 }
450
451 #[inline]
452 pub fn TransactionIdIsNormal(xid: super::TransactionId) -> bool {
453 xid >= FirstNormalTransactionId
454 }
455
456 #[inline]
460 pub unsafe fn type_is_array(typoid: super::Oid) -> bool {
461 super::get_element_type(typoid) != InvalidOid
462 }
463
464 #[cfg(feature = "cshim")]
465 #[pg_guard]
466 extern "C" {
467 #[link_name = "pgx_planner_rt_fetch"]
468 pub fn planner_rt_fetch(
469 index: super::Index,
470 root: *mut super::PlannerInfo,
471 ) -> *mut super::RangeTblEntry;
472 }
473
474 #[cfg(feature = "cshim")]
479 #[inline]
480 pub unsafe fn rt_fetch(
481 index: super::Index,
482 range_table: *mut super::List,
483 ) -> *mut super::RangeTblEntry {
484 pgx_list_nth(range_table, index as i32 - 1) as *mut super::RangeTblEntry
485 }
486
487 #[inline]
489 pub unsafe fn BufferGetPage(buffer: crate::Buffer) -> crate::Page {
490 BufferGetBlock(buffer) as crate::Page
491 }
492
493 #[inline]
502 pub unsafe fn BufferGetBlock(buffer: crate::Buffer) -> crate::Block {
503 if BufferIsLocal(buffer) {
504 *crate::LocalBufferBlockPointers.offset(((-buffer) - 1) as isize)
505 } else {
506 crate::BufferBlocks
507 .offset((((buffer as crate::Size) - 1) * crate::BLCKSZ as usize) as isize)
508 as crate::Block
509 }
510 }
511
512 #[inline]
514 pub unsafe fn BufferIsLocal(buffer: crate::Buffer) -> bool {
515 buffer < 0
516 }
517
518 #[inline]
531 pub unsafe fn heap_tuple_get_struct<T>(htup: super::HeapTuple) -> *mut T {
532 if htup.is_null() {
533 std::ptr::null_mut()
534 } else {
535 unsafe {
536 GETSTRUCT(htup).cast()
538 }
539 }
540 }
541
542 #[pg_guard]
543 extern "C" {
544 pub fn query_tree_walker(
545 query: *mut super::Query,
546 walker: ::std::option::Option<
547 unsafe extern "C" fn(*mut super::Node, *mut ::std::os::raw::c_void) -> bool,
548 >,
549 context: *mut ::std::os::raw::c_void,
550 flags: ::std::os::raw::c_int,
551 ) -> bool;
552 }
553
554 #[pg_guard]
555 extern "C" {
556 pub fn expression_tree_walker(
557 node: *mut super::Node,
558 walker: ::std::option::Option<
559 unsafe extern "C" fn(*mut super::Node, *mut ::std::os::raw::c_void) -> bool,
560 >,
561 context: *mut ::std::os::raw::c_void,
562 ) -> bool;
563 }
564
565 #[cfg(feature = "cshim")]
566 #[pgx_macros::pg_guard]
567 extern "C" {
568 #[link_name = "pgx_SpinLockInit"]
569 pub fn SpinLockInit(lock: *mut pg_sys::slock_t);
570 #[link_name = "pgx_SpinLockAcquire"]
571 pub fn SpinLockAcquire(lock: *mut pg_sys::slock_t);
572 #[link_name = "pgx_SpinLockRelease"]
573 pub fn SpinLockRelease(lock: *mut pg_sys::slock_t);
574 #[link_name = "pgx_SpinLockFree"]
575 pub fn SpinLockFree(lock: *mut pg_sys::slock_t) -> bool;
576 }
577
578 #[inline(always)]
579 pub unsafe fn MemoryContextSwitchTo(context: crate::MemoryContext) -> crate::MemoryContext {
580 let old = crate::CurrentMemoryContext;
581
582 crate::CurrentMemoryContext = context;
583 old
584 }
585}
586
587mod internal {
588 #[cfg(feature = "pg11")]
592 pub(crate) mod pg11 {
593 pub use crate::pg11::tupleDesc as TupleDescData;
594 pub type QueryCompletion = std::os::raw::c_char;
595
596 pub unsafe fn IndexBuildHeapScan<T>(
601 heap_relation: crate::Relation,
602 index_relation: crate::Relation,
603 index_info: *mut crate::pg11::IndexInfo,
604 build_callback: crate::IndexBuildCallback,
605 build_callback_state: *mut T,
606 ) {
607 crate::pg11::IndexBuildHeapScan(
608 heap_relation,
609 index_relation,
610 index_info,
611 true,
612 build_callback,
613 build_callback_state as *mut std::os::raw::c_void,
614 std::ptr::null_mut(),
615 );
616 }
617 }
618
619 #[cfg(feature = "pg12")]
620 pub(crate) mod pg12 {
621 pub use crate::pg12::AllocSetContextCreateInternal as AllocSetContextCreateExtended;
622 pub type QueryCompletion = std::os::raw::c_char;
623
624 pub const QTW_EXAMINE_RTES: u32 = crate::pg12::QTW_EXAMINE_RTES_BEFORE;
625
626 pub unsafe fn IndexBuildHeapScan<T>(
631 heap_relation: crate::Relation,
632 index_relation: crate::Relation,
633 index_info: *mut crate::pg12::IndexInfo,
634 build_callback: crate::IndexBuildCallback,
635 build_callback_state: *mut T,
636 ) {
637 let heap_relation_ref = heap_relation.as_ref().unwrap();
638 let table_am = heap_relation_ref.rd_tableam.as_ref().unwrap();
639
640 table_am.index_build_range_scan.unwrap()(
641 heap_relation,
642 index_relation,
643 index_info,
644 true,
645 false,
646 true,
647 0,
648 crate::InvalidBlockNumber,
649 build_callback,
650 build_callback_state as *mut std::os::raw::c_void,
651 std::ptr::null_mut(),
652 );
653 }
654 }
655
656 #[cfg(feature = "pg13")]
657 pub(crate) mod pg13 {
658 pub use crate::pg13::AllocSetContextCreateInternal as AllocSetContextCreateExtended;
659
660 pub const QTW_EXAMINE_RTES: u32 = crate::pg13::QTW_EXAMINE_RTES_BEFORE;
661
662 pub unsafe fn IndexBuildHeapScan<T>(
667 heap_relation: crate::Relation,
668 index_relation: crate::Relation,
669 index_info: *mut crate::IndexInfo,
670 build_callback: crate::IndexBuildCallback,
671 build_callback_state: *mut T,
672 ) {
673 let heap_relation_ref = heap_relation.as_ref().unwrap();
674 let table_am = heap_relation_ref.rd_tableam.as_ref().unwrap();
675
676 table_am.index_build_range_scan.unwrap()(
677 heap_relation,
678 index_relation,
679 index_info,
680 true,
681 false,
682 true,
683 0,
684 crate::InvalidBlockNumber,
685 build_callback,
686 build_callback_state as *mut std::os::raw::c_void,
687 std::ptr::null_mut(),
688 );
689 }
690 }
691
692 #[cfg(feature = "pg14")]
693 pub(crate) mod pg14 {
694 pub use crate::pg14::AllocSetContextCreateInternal as AllocSetContextCreateExtended;
695
696 pub const QTW_EXAMINE_RTES: u32 = crate::pg14::QTW_EXAMINE_RTES_BEFORE;
697
698 pub unsafe fn IndexBuildHeapScan<T>(
703 heap_relation: crate::Relation,
704 index_relation: crate::Relation,
705 index_info: *mut crate::IndexInfo,
706 build_callback: crate::IndexBuildCallback,
707 build_callback_state: *mut T,
708 ) {
709 let heap_relation_ref = heap_relation.as_ref().unwrap();
710 let table_am = heap_relation_ref.rd_tableam.as_ref().unwrap();
711
712 table_am.index_build_range_scan.unwrap()(
713 heap_relation,
714 index_relation,
715 index_info,
716 true,
717 false,
718 true,
719 0,
720 crate::InvalidBlockNumber,
721 build_callback,
722 build_callback_state as *mut std::os::raw::c_void,
723 std::ptr::null_mut(),
724 );
725 }
726 }
727
728 #[cfg(feature = "pg15")]
729 pub(crate) mod pg15 {
730 pub use crate::pg15::AllocSetContextCreateInternal as AllocSetContextCreateExtended;
731
732 pub const QTW_EXAMINE_RTES: u32 = crate::pg15::QTW_EXAMINE_RTES_BEFORE;
733
734 pub unsafe fn IndexBuildHeapScan<T>(
739 heap_relation: crate::Relation,
740 index_relation: crate::Relation,
741 index_info: *mut crate::IndexInfo,
742 build_callback: crate::IndexBuildCallback,
743 build_callback_state: *mut T,
744 ) {
745 let heap_relation_ref = heap_relation.as_ref().unwrap();
746 let table_am = heap_relation_ref.rd_tableam.as_ref().unwrap();
747
748 table_am.index_build_range_scan.unwrap()(
749 heap_relation,
750 index_relation,
751 index_info,
752 true,
753 false,
754 true,
755 0,
756 crate::InvalidBlockNumber,
757 build_callback,
758 build_callback_state as *mut std::os::raw::c_void,
759 std::ptr::null_mut(),
760 );
761 }
762 }
763}
764
765#[cfg(target_os = "linux")]
770#[link(name = "resolv")]
771extern "C" {}