From ae2c690d7bf54fde6fdf4547b62194a5a436d04c Mon Sep 17 00:00:00 2001
From: Eric Ridge <eebbrr@gmail.com>
Date: Wed, 1 Feb 2023 11:29:07 -0500
Subject: [PATCH] remove the  dependency on `cstr_core` (#1025)

---
 Cargo.lock                                    | 18 ---------------
 README.md                                     |  2 +-
 articles/postgresql-aggregates-with-rust.md   |  4 ++--
 pgx-examples/aggregate/src/lib.rs             |  2 +-
 pgx-examples/custom_types/README.md           |  2 +-
 pgx-examples/custom_types/src/fixed_size.rs   |  2 +-
 pgx-macros/src/lib.rs                         | 16 +++++++-------
 pgx-pg-sys/src/lib.rs                         |  8 +++----
 pgx-pg-sys/src/submodules/ffi.rs              |  2 +-
 pgx-pg-sys/src/submodules/panic.rs            |  2 +-
 pgx-pg-sys/src/submodules/utils.rs            |  2 +-
 pgx-sql-entity-graph/Cargo.toml               |  1 -
 .../src/metadata/sql_translatable.rs          | 22 ++-----------------
 pgx-tests/src/tests/fcinfo_tests.rs           |  4 ++--
 pgx-tests/src/tests/postgres_type_tests.rs    |  2 +-
 pgx-tests/src/tests/struct_type_tests.rs      |  4 ++--
 pgx/Cargo.toml                                |  1 -
 pgx/src/datum/date.rs                         |  2 +-
 pgx/src/datum/from.rs                         | 21 +++---------------
 pgx/src/datum/inet.rs                         |  4 ++--
 pgx/src/datum/into.rs                         | 15 ++-----------
 pgx/src/datum/json.rs                         |  4 ++--
 pgx/src/datum/numeric.rs                      |  2 +-
 .../numeric_support/convert_anynumeric.rs     |  2 +-
 .../datum/numeric_support/convert_numeric.rs  |  2 +-
 pgx/src/datum/time.rs                         |  2 +-
 pgx/src/datum/time_stamp.rs                   |  2 +-
 pgx/src/datum/time_stamp_with_timezone.rs     |  2 +-
 pgx/src/datum/time_with_timezone.rs           |  2 +-
 pgx/src/datum/varlena.rs                      |  2 +-
 pgx/src/enum_helper.rs                        |  4 ++--
 pgx/src/fcinfo.rs                             |  6 ++---
 pgx/src/guc.rs                                |  2 +-
 pgx/src/hooks.rs                              | 12 +++++-----
 pgx/src/inoutfuncs.rs                         |  6 ++---
 pgx/src/lib.rs                                |  2 --
 pgx/src/lwlock.rs                             |  2 +-
 pgx/src/memcxt.rs                             |  4 ++--
 pgx/src/nodes.rs                              |  2 +-
 pgx/src/rel.rs                                |  2 +-
 pgx/src/shmem.rs                              |  8 +++----
 pgx/src/stringinfo.rs                         | 18 ++-------------
 pgx/src/trigger_support/pg_trigger.rs         | 10 ++++-----
 pgx/src/wrappers.rs                           |  2 +-
 44 files changed, 78 insertions(+), 158 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index f4255eb13..f429e9476 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -588,22 +588,6 @@ dependencies = [
  "typenum",
 ]
 
-[[package]]
-name = "cstr_core"
-version = "0.2.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dd98742e4fdca832d40cab219dc2e3048de17d873248f83f17df47c1bea70956"
-dependencies = [
- "cty",
- "memchr",
-]
-
-[[package]]
-name = "cty"
-version = "0.2.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b365fabc795046672053e29c954733ec3b05e4be654ab130fe8f1f94d7051f35"
-
 [[package]]
 name = "custom_sql"
 version = "0.0.0"
@@ -1472,7 +1456,6 @@ dependencies = [
  "atomic-traits",
  "bitflags",
  "bitvec",
- "cstr_core",
  "heapless",
  "libc",
  "once_cell",
@@ -1543,7 +1526,6 @@ version = "0.7.0"
 dependencies = [
  "atty",
  "convert_case",
- "cstr_core",
  "eyre",
  "owo-colors",
  "petgraph",
diff --git a/README.md b/README.md
index 395056695..eb6915460 100644
--- a/README.md
+++ b/README.md
@@ -188,7 +188,7 @@ Postgres Type | Rust Type (as `Option<T>`)
 `box` | `pgx::pg_sys::BOX`
 `point` | `pgx::pgx_sys::Point`
 `tid` | `pgx::pg_sys::ItemPointerData`
-`cstring` | `&std::ffi::CStr`
+`cstring` | `&core::ffi::CStr`
 `inet` | `pgx::Inet(String)` -- TODO: needs better support
 `numeric` | `pgx::Numeric<P, S> or pgx::AnyNumeric`
 `void` | `()`
diff --git a/articles/postgresql-aggregates-with-rust.md b/articles/postgresql-aggregates-with-rust.md
index 068633696..c49701462 100644
--- a/articles/postgresql-aggregates-with-rust.md
+++ b/articles/postgresql-aggregates-with-rust.md
@@ -426,7 +426,7 @@ CREATE TYPE DemoSum;
 -- src/lib.rs:6
 -- exploring_aggregates::demosum_in
 CREATE OR REPLACE FUNCTION "demosum_in"(
-	"input" cstring /* &cstr_core::CStr */
+	"input" cstring /* &std::ffi::CStr */
 ) RETURNS DemoSum /* exploring_aggregates::DemoSum */
 IMMUTABLE PARALLEL SAFE STRICT
 LANGUAGE c /* Rust */
@@ -436,7 +436,7 @@ AS 'MODULE_PATHNAME', 'demosum_in_wrapper';
 -- exploring_aggregates::demosum_out
 CREATE OR REPLACE FUNCTION "demosum_out"(
 	"input" DemoSum /* exploring_aggregates::DemoSum */
-) RETURNS cstring /* &cstr_core::CStr */
+) RETURNS cstring /* &std::ffi::CStr */
 IMMUTABLE PARALLEL SAFE STRICT
 LANGUAGE c /* Rust */
 AS 'MODULE_PATHNAME', 'demosum_out_wrapper';
diff --git a/pgx-examples/aggregate/src/lib.rs b/pgx-examples/aggregate/src/lib.rs
index a9b521d62..2356e3bde 100644
--- a/pgx-examples/aggregate/src/lib.rs
+++ b/pgx-examples/aggregate/src/lib.rs
@@ -6,8 +6,8 @@ All rights reserved.
 
 Use of this source code is governed by the MIT license that can be found in the LICENSE file.
 */
+use core::ffi::CStr;
 use pgx::aggregate::*;
-use pgx::cstr_core::CStr;
 use pgx::prelude::*;
 use pgx::{pgx, PgVarlena, PgVarlenaInOutFuncs, StringInfo};
 use serde::{Deserialize, Serialize};
diff --git a/pgx-examples/custom_types/README.md b/pgx-examples/custom_types/README.md
index 6c41fddee..6a69dcf71 100644
--- a/pgx-examples/custom_types/README.md
+++ b/pgx-examples/custom_types/README.md
@@ -86,7 +86,7 @@ struct MyType {
 impl PgVarlenaInOutFuncs for MyType {
 
     // parse the provided CStr into a `PgVarlena<MyType>`
-    fn input(input: &std::ffi::CStr) -> PgVarlena<Self> {
+    fn input(input: &core::ffi::CStr) -> PgVarlena<Self> {
         let mut iter = input.to_str().unwrap().split(',');
         let (a, b, c) = (iter.next(), iter.next(), iter.next());
 
diff --git a/pgx-examples/custom_types/src/fixed_size.rs b/pgx-examples/custom_types/src/fixed_size.rs
index 70d62d5a1..ed8ae8d94 100644
--- a/pgx-examples/custom_types/src/fixed_size.rs
+++ b/pgx-examples/custom_types/src/fixed_size.rs
@@ -6,7 +6,7 @@ All rights reserved.
 
 Use of this source code is governed by the MIT license that can be found in the LICENSE file.
 */
-use pgx::cstr_core::CStr;
+use core::ffi::CStr;
 use pgx::prelude::*;
 use pgx::{opname, pg_operator, PgVarlena, PgVarlenaInOutFuncs, StringInfo};
 use std::str::FromStr;
diff --git a/pgx-macros/src/lib.rs b/pgx-macros/src/lib.rs
index 820302535..4d035929f 100644
--- a/pgx-macros/src/lib.rs
+++ b/pgx-macros/src/lib.rs
@@ -348,12 +348,12 @@ extension_sql!(r#"\
 );
 
 #[pg_extern(immutable)]
-fn complex_in(input: &pgx::cstr_core::CStr) -> PgBox<Complex> {
+fn complex_in(input: &core::ffi::CStr) -> PgBox<Complex> {
     todo!()
 }
 
 #[pg_extern(immutable)]
-fn complex_out(complex: PgBox<Complex>) -> &'static pgx::cstr_core::CStr {
+fn complex_out(complex: PgBox<Complex>) -> &'static core::ffi::CStr {
     todo!()
 }
 
@@ -769,7 +769,7 @@ fn impl_postgres_type(ast: DeriveInput) -> syn::Result<proc_macro2::TokenStream>
 
             #[doc(hidden)]
             #[::pgx::pgx_macros::pg_extern(immutable,parallel_safe)]
-            pub fn #funcname_in #generics(input: Option<&#lifetime ::pgx::cstr_core::CStr>) -> Option<#name #generics> {
+            pub fn #funcname_in #generics(input: Option<&#lifetime ::core::ffi::CStr>) -> Option<#name #generics> {
                 input.map_or_else(|| {
                     for m in <#name as ::pgx::inoutfuncs::JsonInOutFuncs>::NULL_ERROR_MESSAGE {
                         ::pgx::pg_sys::error!("{}", m);
@@ -780,7 +780,7 @@ fn impl_postgres_type(ast: DeriveInput) -> syn::Result<proc_macro2::TokenStream>
 
             #[doc(hidden)]
             #[::pgx::pgx_macros::pg_extern(immutable,parallel_safe)]
-            pub fn #funcname_out #generics(input: #name #generics) -> &#lifetime ::pgx::cstr_core::CStr {
+            pub fn #funcname_out #generics(input: #name #generics) -> &#lifetime ::core::ffi::CStr {
                 let mut buffer = ::pgx::stringinfo::StringInfo::new();
                 ::pgx::inoutfuncs::JsonInOutFuncs::output(&input, &mut buffer);
                 buffer.into()
@@ -792,7 +792,7 @@ fn impl_postgres_type(ast: DeriveInput) -> syn::Result<proc_macro2::TokenStream>
         stream.extend(quote! {
             #[doc(hidden)]
             #[::pgx::pgx_macros::pg_extern(immutable,parallel_safe)]
-            pub fn #funcname_in #generics(input: Option<&#lifetime ::pgx::cstr_core::CStr>) -> Option<#name #generics> {
+            pub fn #funcname_in #generics(input: Option<&#lifetime ::core::ffi::CStr>) -> Option<#name #generics> {
                 input.map_or_else(|| {
                     for m in <#name as ::pgx::inoutfuncs::InOutFuncs>::NULL_ERROR_MESSAGE {
                         ::pgx::pg_sys::error!("{}", m);
@@ -803,7 +803,7 @@ fn impl_postgres_type(ast: DeriveInput) -> syn::Result<proc_macro2::TokenStream>
 
             #[doc(hidden)]
             #[::pgx::pgx_macros::pg_extern(immutable,parallel_safe)]
-            pub fn #funcname_out #generics(input: #name #generics) -> &#lifetime ::pgx::cstr_core::CStr {
+            pub fn #funcname_out #generics(input: #name #generics) -> &#lifetime ::core::ffi::CStr {
                 let mut buffer = ::pgx::stringinfo::StringInfo::new();
                 ::pgx::inoutfuncs::InOutFuncs::output(&input, &mut buffer);
                 buffer.into()
@@ -814,7 +814,7 @@ fn impl_postgres_type(ast: DeriveInput) -> syn::Result<proc_macro2::TokenStream>
         stream.extend(quote! {
             #[doc(hidden)]
             #[::pgx::pgx_macros::pg_extern(immutable,parallel_safe)]
-            pub fn #funcname_in #generics(input: Option<&#lifetime ::pgx::cstr_core::CStr>) -> Option<::pgx::datum::PgVarlena<#name #generics>> {
+            pub fn #funcname_in #generics(input: Option<&#lifetime ::core::ffi::CStr>) -> Option<::pgx::datum::PgVarlena<#name #generics>> {
                 input.map_or_else(|| {
                     for m in <#name as ::pgx::inoutfuncs::PgVarlenaInOutFuncs>::NULL_ERROR_MESSAGE {
                         ::pgx::pg_sys::error!("{}", m);
@@ -825,7 +825,7 @@ fn impl_postgres_type(ast: DeriveInput) -> syn::Result<proc_macro2::TokenStream>
 
             #[doc(hidden)]
             #[::pgx::pgx_macros::pg_extern(immutable,parallel_safe)]
-            pub fn #funcname_out #generics(input: ::pgx::datum::PgVarlena<#name #generics>) -> &#lifetime ::pgx::cstr_core::CStr {
+            pub fn #funcname_out #generics(input: ::pgx::datum::PgVarlena<#name #generics>) -> &#lifetime ::core::ffi::CStr {
                 let mut buffer = ::pgx::stringinfo::StringInfo::new();
                 ::pgx::inoutfuncs::PgVarlenaInOutFuncs::output(&*input, &mut buffer);
                 buffer.into()
diff --git a/pgx-pg-sys/src/lib.rs b/pgx-pg-sys/src/lib.rs
index 68729f990..dfd16ae08 100644
--- a/pgx-pg-sys/src/lib.rs
+++ b/pgx-pg-sys/src/lib.rs
@@ -28,8 +28,8 @@ std::compile_error!("exactly one one feature must be provided (pg11, pg12, pg13,
 
 pub mod submodules;
 
+use core::ffi::CStr;
 use core::ptr::NonNull;
-use std::ffi::CStr;
 use std::os::raw::c_char;
 
 // for convenience we pull up everything submodules exposes
@@ -427,7 +427,7 @@ mod all_versions {
 
     #[inline]
     pub fn get_pg_major_version_string() -> &'static str {
-        let mver = std::ffi::CStr::from_bytes_with_nul(super::PG_MAJORVERSION).unwrap();
+        let mver = core::ffi::CStr::from_bytes_with_nul(super::PG_MAJORVERSION).unwrap();
         mver.to_str().unwrap()
     }
 
@@ -438,13 +438,13 @@ mod all_versions {
 
     #[inline]
     pub fn get_pg_version_string() -> &'static str {
-        let ver = std::ffi::CStr::from_bytes_with_nul(super::PG_VERSION_STR).unwrap();
+        let ver = core::ffi::CStr::from_bytes_with_nul(super::PG_VERSION_STR).unwrap();
         ver.to_str().unwrap()
     }
 
     #[inline]
     pub fn get_pg_major_minor_version_string() -> &'static str {
-        let mver = std::ffi::CStr::from_bytes_with_nul(super::PG_VERSION).unwrap();
+        let mver = core::ffi::CStr::from_bytes_with_nul(super::PG_VERSION).unwrap();
         mver.to_str().unwrap()
     }
 
diff --git a/pgx-pg-sys/src/submodules/ffi.rs b/pgx-pg-sys/src/submodules/ffi.rs
index 6ca41a302..e8224fd5a 100644
--- a/pgx-pg-sys/src/submodules/ffi.rs
+++ b/pgx-pg-sys/src/submodules/ffi.rs
@@ -90,7 +90,7 @@ unsafe fn pg_guard_ffi_boundary_impl<T, F: FnOnce() -> T>(f: F) -> T {
 
     // just use these here to avoid compilation warnings when #[cfg(feature = "postgrestd")] is on
     use crate::panic::{CaughtError, ErrorReport, ErrorReportLocation, ErrorReportWithLevel};
-    use std::ffi::CStr;
+    use core::ffi::CStr;
 
     // The next code is definitely thread-unsafe (it manipulates statics in an
     // unsynchronized manner), so we may as well check here.
diff --git a/pgx-pg-sys/src/submodules/panic.rs b/pgx-pg-sys/src/submodules/panic.rs
index a92709e9b..57a8f9683 100644
--- a/pgx-pg-sys/src/submodules/panic.rs
+++ b/pgx-pg-sys/src/submodules/panic.rs
@@ -9,9 +9,9 @@ Use of this source code is governed by the MIT license that can be found in the
 #![deny(unsafe_op_in_unsafe_fn)]
 #![allow(non_snake_case)]
 
+use core::ffi::CStr;
 use std::any::Any;
 use std::cell::Cell;
-use std::ffi::CStr;
 use std::fmt::{Display, Formatter};
 use std::hint::unreachable_unchecked;
 use std::panic::{
diff --git a/pgx-pg-sys/src/submodules/utils.rs b/pgx-pg-sys/src/submodules/utils.rs
index 917c61130..214a74dfe 100644
--- a/pgx-pg-sys/src/submodules/utils.rs
+++ b/pgx-pg-sys/src/submodules/utils.rs
@@ -16,5 +16,5 @@ use crate as pg_sys;
 /// of the provided `pg_sys::NameData`
 #[inline]
 pub fn name_data_to_str(name_data: &pg_sys::NameData) -> &str {
-    unsafe { std::ffi::CStr::from_ptr(name_data.data.as_ptr()) }.to_str().unwrap()
+    unsafe { core::ffi::CStr::from_ptr(name_data.data.as_ptr()) }.to_str().unwrap()
 }
diff --git a/pgx-sql-entity-graph/Cargo.toml b/pgx-sql-entity-graph/Cargo.toml
index 0edea0421..5ecbbbf17 100644
--- a/pgx-sql-entity-graph/Cargo.toml
+++ b/pgx-sql-entity-graph/Cargo.toml
@@ -16,7 +16,6 @@ no-schema-generation = []
 
 [dependencies]
 seq-macro = "0.3"
-cstr_core = "0.2"
 convert_case = "0.5.0"
 eyre = "0.6.8"
 petgraph = "0.6.2"
diff --git a/pgx-sql-entity-graph/src/metadata/sql_translatable.rs b/pgx-sql-entity-graph/src/metadata/sql_translatable.rs
index 8973827fe..92dde0fcc 100644
--- a/pgx-sql-entity-graph/src/metadata/sql_translatable.rs
+++ b/pgx-sql-entity-graph/src/metadata/sql_translatable.rs
@@ -342,7 +342,7 @@ unsafe impl SqlTranslatable for f64 {
     }
 }
 
-unsafe impl SqlTranslatable for std::ffi::CStr {
+unsafe impl SqlTranslatable for core::ffi::CStr {
     fn argument_sql() -> Result<SqlMapping, ArgumentError> {
         Ok(SqlMapping::literal("cstring"))
     }
@@ -351,25 +351,7 @@ unsafe impl SqlTranslatable for std::ffi::CStr {
     }
 }
 
-unsafe impl SqlTranslatable for &'static std::ffi::CStr {
-    fn argument_sql() -> Result<SqlMapping, ArgumentError> {
-        Ok(SqlMapping::literal("cstring"))
-    }
-    fn return_sql() -> Result<Returns, ReturnsError> {
-        Ok(Returns::One(SqlMapping::literal("cstring")))
-    }
-}
-
-unsafe impl SqlTranslatable for &'static cstr_core::CStr {
-    fn argument_sql() -> Result<SqlMapping, ArgumentError> {
-        Ok(SqlMapping::literal("cstring"))
-    }
-    fn return_sql() -> Result<Returns, ReturnsError> {
-        Ok(Returns::One(SqlMapping::literal("cstring")))
-    }
-}
-
-unsafe impl SqlTranslatable for cstr_core::CStr {
+unsafe impl SqlTranslatable for &'static core::ffi::CStr {
     fn argument_sql() -> Result<SqlMapping, ArgumentError> {
         Ok(SqlMapping::literal("cstring"))
     }
diff --git a/pgx-tests/src/tests/fcinfo_tests.rs b/pgx-tests/src/tests/fcinfo_tests.rs
index 2e171f594..d1ba810fe 100644
--- a/pgx-tests/src/tests/fcinfo_tests.rs
+++ b/pgx-tests/src/tests/fcinfo_tests.rs
@@ -133,7 +133,7 @@ fn fcinfo_not_named_no_arg(fcinfo: pg_sys::FunctionCallInfo) -> i32 {
 pub struct NullStrict {}
 
 impl InOutFuncs for NullStrict {
-    fn input(_input: &pgx::cstr_core::CStr) -> Self
+    fn input(_input: &core::ffi::CStr) -> Self
     where
         Self: Sized,
     {
@@ -149,7 +149,7 @@ impl InOutFuncs for NullStrict {
 pub struct NullError {}
 
 impl InOutFuncs for NullError {
-    fn input(_input: &pgx::cstr_core::CStr) -> Self
+    fn input(_input: &core::ffi::CStr) -> Self
     where
         Self: Sized,
     {
diff --git a/pgx-tests/src/tests/postgres_type_tests.rs b/pgx-tests/src/tests/postgres_type_tests.rs
index 6cde3047a..8f1a4ad5b 100644
--- a/pgx-tests/src/tests/postgres_type_tests.rs
+++ b/pgx-tests/src/tests/postgres_type_tests.rs
@@ -6,7 +6,7 @@ All rights reserved.
 
 Use of this source code is governed by the MIT license that can be found in the LICENSE file.
 */
-use pgx::cstr_core::CStr;
+use core::ffi::CStr;
 use pgx::prelude::*;
 use pgx::{InOutFuncs, PgVarlena, PgVarlenaInOutFuncs, StringInfo};
 use serde::{Deserialize, Serialize};
diff --git a/pgx-tests/src/tests/struct_type_tests.rs b/pgx-tests/src/tests/struct_type_tests.rs
index 3293e86fd..f61bf9e33 100644
--- a/pgx-tests/src/tests/struct_type_tests.rs
+++ b/pgx-tests/src/tests/struct_type_tests.rs
@@ -40,7 +40,7 @@ unsafe impl SqlTranslatable for Complex {
 }
 
 #[pg_extern(immutable)]
-fn complex_in(input: &std::ffi::CStr) -> PgBox<Complex, AllocatedByRust> {
+fn complex_in(input: &core::ffi::CStr) -> PgBox<Complex, AllocatedByRust> {
     let input_as_str = input.to_str().unwrap();
     let re = regex::Regex::new(
         r#"(?P<x>[-+]?([0-9]*\.[0-9]+|[0-9]+)),\s*(?P<y>[-+]?([0-9]*\.[0-9]+|[0-9]+))"#,
@@ -57,7 +57,7 @@ fn complex_in(input: &std::ffi::CStr) -> PgBox<Complex, AllocatedByRust> {
 }
 
 #[pg_extern(immutable)]
-fn complex_out(complex: PgBox<Complex>) -> &'static std::ffi::CStr {
+fn complex_out(complex: PgBox<Complex>) -> &'static core::ffi::CStr {
     let mut sb = StringInfo::new();
     sb.push_str(&format!("{}, {}", &complex.x, &complex.y));
     sb.into()
diff --git a/pgx/Cargo.toml b/pgx/Cargo.toml
index 491aab825..57286c4b0 100644
--- a/pgx/Cargo.toml
+++ b/pgx/Cargo.toml
@@ -53,7 +53,6 @@ tracing-error = "0.2.0"
 atomic-traits = "0.3.0" # PgAtomic and shmem init
 bitflags = "1.3.2" # BackgroundWorker
 bitvec = "1.0" # processing array nullbitmaps
-cstr_core = "0.2.6" # no std compat
 heapless = "0.7.16" # shmem and PgLwLock
 libc = "0.2.139" # FFI type compat
 seahash = "4.1.0" # derive(PostgresHash)
diff --git a/pgx/src/datum/date.rs b/pgx/src/datum/date.rs
index baaa06657..acfa8d63e 100644
--- a/pgx/src/datum/date.rs
+++ b/pgx/src/datum/date.rs
@@ -8,11 +8,11 @@ Use of this source code is governed by the MIT license that can be found in the
 */
 
 use crate::{pg_sys, FromDatum, IntoDatum};
+use core::ffi::CStr;
 use core::num::TryFromIntError;
 use pgx_sql_entity_graph::metadata::{
     ArgumentError, Returns, ReturnsError, SqlMapping, SqlTranslatable,
 };
-use std::ffi::CStr;
 
 pub const POSTGRES_EPOCH_JDATE: i32 = pg_sys::POSTGRES_EPOCH_JDATE as i32;
 pub const UNIX_EPOCH_JDATE: i32 = pg_sys::UNIX_EPOCH_JDATE as i32;
diff --git a/pgx/src/datum/from.rs b/pgx/src/datum/from.rs
index 6bfe0a1ed..dfb58033b 100644
--- a/pgx/src/datum/from.rs
+++ b/pgx/src/datum/from.rs
@@ -13,7 +13,7 @@ use crate::{
     pg_sys, text_to_rust_str_unchecked, varlena_to_byte_slice, AllocatedByPostgres, IntoDatum,
     PgBox, PgMemoryContexts,
 };
-use std::ffi::CStr;
+use core::ffi::CStr;
 use std::num::NonZeroUsize;
 
 /// If converting a Datum to a Rust type fails, this is the set of possible reasons why.
@@ -398,7 +398,7 @@ impl FromDatum for char {
 }
 
 /// for cstring
-impl<'a> FromDatum for &'a std::ffi::CStr {
+impl<'a> FromDatum for &'a core::ffi::CStr {
     #[inline]
     unsafe fn from_polymorphic_datum(
         datum: pg_sys::Datum,
@@ -408,22 +408,7 @@ impl<'a> FromDatum for &'a std::ffi::CStr {
         if is_null || datum.is_null() {
             None
         } else {
-            Some(std::ffi::CStr::from_ptr(datum.cast_mut_ptr()))
-        }
-    }
-}
-
-impl<'a> FromDatum for &'a crate::cstr_core::CStr {
-    #[inline]
-    unsafe fn from_polymorphic_datum(
-        datum: pg_sys::Datum,
-        is_null: bool,
-        _: pg_sys::Oid,
-    ) -> Option<&'a crate::cstr_core::CStr> {
-        if is_null || datum.is_null() {
-            None
-        } else {
-            Some(crate::cstr_core::CStr::from_ptr(datum.cast_mut_ptr()))
+            Some(core::ffi::CStr::from_ptr(datum.cast_mut_ptr()))
         }
     }
 }
diff --git a/pgx/src/datum/inet.rs b/pgx/src/datum/inet.rs
index 3800146b2..380b579e3 100644
--- a/pgx/src/datum/inet.rs
+++ b/pgx/src/datum/inet.rs
@@ -8,6 +8,7 @@ Use of this source code is governed by the MIT license that can be found in the
 */
 
 use crate::{direct_function_call, direct_function_call_as_datum, pg_sys, FromDatum, IntoDatum};
+use core::ffi::CStr;
 use pgx_pg_sys::errcodes::PgSqlErrorCode;
 use pgx_pg_sys::PgTryBuilder;
 use pgx_sql_entity_graph::metadata::{
@@ -15,7 +16,6 @@ use pgx_sql_entity_graph::metadata::{
 };
 use serde::de::{Error, Visitor};
 use serde::{Deserialize, Deserializer, Serialize, Serializer};
-use std::ffi::CStr;
 use std::fmt;
 use std::ops::Deref;
 
@@ -108,7 +108,7 @@ impl FromDatum for Inet {
 
 impl IntoDatum for Inet {
     fn into_datum(self) -> Option<pg_sys::Datum> {
-        let cstr = std::ffi::CString::new(self.0).expect("failed to convert inet into CString");
+        let cstr = alloc::ffi::CString::new(self.0).expect("failed to convert inet into CString");
         unsafe {
             direct_function_call_as_datum(pg_sys::inet_in, vec![cstr.as_c_str().into_datum()])
         }
diff --git a/pgx/src/datum/into.rs b/pgx/src/datum/into.rs
index 4ffcda0fe..eaff62128 100644
--- a/pgx/src/datum/into.rs
+++ b/pgx/src/datum/into.rs
@@ -335,7 +335,7 @@ impl IntoDatum for char {
 /// ## Safety
 ///
 /// The `&CStr` better be allocated by Postgres
-impl<'a> IntoDatum for &'a std::ffi::CStr {
+impl<'a> IntoDatum for &'a core::ffi::CStr {
     #[inline]
     fn into_datum(self) -> Option<pg_sys::Datum> {
         Some(self.as_ptr().into())
@@ -346,18 +346,7 @@ impl<'a> IntoDatum for &'a std::ffi::CStr {
     }
 }
 
-impl IntoDatum for std::ffi::CString {
-    #[inline]
-    fn into_datum(self) -> Option<pg_sys::Datum> {
-        Some(self.as_ptr().into())
-    }
-
-    fn type_oid() -> pg_sys::Oid {
-        pg_sys::CSTRINGOID
-    }
-}
-
-impl<'a> IntoDatum for &'a crate::cstr_core::CStr {
+impl IntoDatum for alloc::ffi::CString {
     #[inline]
     fn into_datum(self) -> Option<pg_sys::Datum> {
         Some(self.as_ptr().into())
diff --git a/pgx/src/datum/json.rs b/pgx/src/datum/json.rs
index 6481c42c7..0e9c95a1e 100644
--- a/pgx/src/datum/json.rs
+++ b/pgx/src/datum/json.rs
@@ -63,7 +63,7 @@ impl FromDatum for JsonB {
             let varlena = datum.cast_mut_ptr();
             let detoasted = pg_sys::pg_detoast_datum_packed(varlena);
 
-            let cstr = direct_function_call::<&std::ffi::CStr>(
+            let cstr = direct_function_call::<&core::ffi::CStr>(
                 pg_sys::jsonb_out,
                 vec![Some(detoasted.into())],
             )
@@ -136,7 +136,7 @@ impl IntoDatum for JsonB {
     fn into_datum(self) -> Option<pg_sys::Datum> {
         let string = serde_json::to_string(&self.0).expect("failed to serialize JsonB value");
         let cstring =
-            std::ffi::CString::new(string).expect("string version of jsonb is not valid UTF8");
+            alloc::ffi::CString::new(string).expect("string version of jsonb is not valid UTF8");
 
         unsafe {
             direct_function_call_as_datum(pg_sys::jsonb_in, vec![Some(cstring.as_ptr().into())])
diff --git a/pgx/src/datum/numeric.rs b/pgx/src/datum/numeric.rs
index 25c57ac11..40c50dd74 100644
--- a/pgx/src/datum/numeric.rs
+++ b/pgx/src/datum/numeric.rs
@@ -7,8 +7,8 @@ All rights reserved.
 Use of this source code is governed by the MIT license that can be found in the LICENSE file.
 */
 
+use core::ffi::CStr;
 use core::fmt::{Debug, Display, Formatter};
-use std::ffi::CStr;
 use std::fmt;
 
 use crate::numeric_support::convert::from_primitive_helper;
diff --git a/pgx/src/datum/numeric_support/convert_anynumeric.rs b/pgx/src/datum/numeric_support/convert_anynumeric.rs
index d1312147a..34851307b 100644
--- a/pgx/src/datum/numeric_support/convert_anynumeric.rs
+++ b/pgx/src/datum/numeric_support/convert_anynumeric.rs
@@ -1,6 +1,6 @@
 //! Conversion implementations for from a thing into [AnyNumeric]
+use core::ffi::CStr;
 use core::str::FromStr;
-use std::ffi::CStr;
 
 use pg_sys::AsPgCStr;
 
diff --git a/pgx/src/datum/numeric_support/convert_numeric.rs b/pgx/src/datum/numeric_support/convert_numeric.rs
index 2288f89a2..357709679 100644
--- a/pgx/src/datum/numeric_support/convert_numeric.rs
+++ b/pgx/src/datum/numeric_support/convert_numeric.rs
@@ -1,6 +1,6 @@
 //! Conversion implementations for converting from a thing into [`Numeric<P, S>`]
+use core::ffi::CStr;
 use core::str::FromStr;
-use std::ffi::CStr;
 
 use pgx_pg_sys::AsPgCStr;
 
diff --git a/pgx/src/datum/time.rs b/pgx/src/datum/time.rs
index 20a946dd9..b86ab6cbe 100644
--- a/pgx/src/datum/time.rs
+++ b/pgx/src/datum/time.rs
@@ -112,7 +112,7 @@ impl serde::Serialize for Time {
     where
         S: serde::Serializer,
     {
-        let cstr: Option<&cstr_core::CStr> = unsafe {
+        let cstr: Option<&core::ffi::CStr> = unsafe {
             crate::direct_function_call(pg_sys::time_out, vec![self.clone().into_datum()])
         };
         serializer.serialize_str(cstr.and_then(|c| c.to_str().ok()).unwrap())
diff --git a/pgx/src/datum/time_stamp.rs b/pgx/src/datum/time_stamp.rs
index e04a36dbb..a4da27c6e 100644
--- a/pgx/src/datum/time_stamp.rs
+++ b/pgx/src/datum/time_stamp.rs
@@ -8,11 +8,11 @@ Use of this source code is governed by the MIT license that can be found in the
 */
 
 use crate::{pg_sys, FromDatum, FromTimeError, IntoDatum, TimestampWithTimeZone};
+use core::ffi::CStr;
 use pgx_sql_entity_graph::metadata::{
     ArgumentError, Returns, ReturnsError, SqlMapping, SqlTranslatable,
 };
 use serde::Deserialize;
-use std::ffi::CStr;
 
 #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Deserialize)]
 #[repr(transparent)]
diff --git a/pgx/src/datum/time_stamp_with_timezone.rs b/pgx/src/datum/time_stamp_with_timezone.rs
index e8695a862..4f5b34d9a 100644
--- a/pgx/src/datum/time_stamp_with_timezone.rs
+++ b/pgx/src/datum/time_stamp_with_timezone.rs
@@ -8,12 +8,12 @@ Use of this source code is governed by the MIT license that can be found in the
 */
 
 use crate::{pg_sys, FromDatum, IntoDatum};
+use core::ffi::CStr;
 use pgx_sql_entity_graph::metadata::{
     ArgumentError, Returns, ReturnsError, SqlMapping, SqlTranslatable,
 };
 use serde::Deserialize;
 use std::convert::TryFrom;
-use std::ffi::CStr;
 
 #[allow(dead_code)] // such is cfg life
 pub(crate) const USECS_PER_SEC: i64 = 1_000_000;
diff --git a/pgx/src/datum/time_with_timezone.rs b/pgx/src/datum/time_with_timezone.rs
index 7ae23824c..2087a9baf 100644
--- a/pgx/src/datum/time_with_timezone.rs
+++ b/pgx/src/datum/time_with_timezone.rs
@@ -98,7 +98,7 @@ impl serde::Serialize for TimeWithTimeZone {
     where
         S: serde::Serializer,
     {
-        let cstr: Option<&cstr_core::CStr> = unsafe {
+        let cstr: Option<&core::ffi::CStr> = unsafe {
             crate::direct_function_call(
                 pg_sys::timetz_out,
                 vec![Some(pg_sys::Datum::from(self as *const Self))],
diff --git a/pgx/src/datum/varlena.rs b/pgx/src/datum/varlena.rs
index b8e6ef9d6..6f5549a77 100644
--- a/pgx/src/datum/varlena.rs
+++ b/pgx/src/datum/varlena.rs
@@ -68,7 +68,7 @@ impl Clone for PallocdVarlena {
 /// }
 ///
 /// impl PgVarlenaInOutFuncs for MyType {
-///     fn input(input: &pgx::cstr_core::CStr) -> PgVarlena<Self> {
+///     fn input(input: &core::ffi::CStr) -> PgVarlena<Self> {
 ///         let mut iter = input.to_str().unwrap().split(',');
 ///         let (a, b, c) = (iter.next(), iter.next(), iter.next());
 ///
diff --git a/pgx/src/enum_helper.rs b/pgx/src/enum_helper.rs
index 680adcb14..bac1b61d3 100644
--- a/pgx/src/enum_helper.rs
+++ b/pgx/src/enum_helper.rs
@@ -34,7 +34,7 @@ pub fn lookup_enum_by_oid(enumval: pg_sys::Oid) -> (String, pg_sys::Oid, f32) {
     let en = unsafe { en.as_ref() }.unwrap();
     let result = (
         unsafe {
-            std::ffi::CStr::from_ptr(en.enumlabel.data.as_ptr() as *const std::os::raw::c_char)
+            core::ffi::CStr::from_ptr(en.enumlabel.data.as_ptr() as *const std::os::raw::c_char)
         }
         .to_str()
         .unwrap()
@@ -59,7 +59,7 @@ pub fn lookup_enum_by_label(typname: &str, label: &str) -> pg_sys::Datum {
 
     let tup = unsafe {
         let label =
-            std::ffi::CString::new(label).expect("failed to convert enum typname to a CString");
+            alloc::ffi::CString::new(label).expect("failed to convert enum typname to a CString");
         pg_sys::SearchSysCache(
             pg_sys::SysCacheIdentifier_ENUMTYPOIDNAME as i32,
             pg_sys::Datum::from(enumtypoid),
diff --git a/pgx/src/fcinfo.rs b/pgx/src/fcinfo.rs
index b32984759..7ebe7f1b8 100644
--- a/pgx/src/fcinfo.rs
+++ b/pgx/src/fcinfo.rs
@@ -364,14 +364,14 @@ pub unsafe fn pg_getarg_type(fcinfo: pg_sys::FunctionCallInfo, num: usize) -> pg
 /// [`pg_sys::FunctionCallInfo`] pointer.  This is your responsibility.
 ///
 /// It is also your responsibility to ensure that the argument Datum is pointing to a valid
-/// [`std::ffi::CStr`].
+/// [`core::ffi::CStr`].
 #[inline]
 pub unsafe fn pg_getarg_cstr<'a>(
     fcinfo: pg_sys::FunctionCallInfo,
     num: usize,
-) -> Option<&'a std::ffi::CStr> {
+) -> Option<&'a core::ffi::CStr> {
     match pg_getarg_pointer(fcinfo, num) {
-        Some(ptr) => Some(unsafe { std::ffi::CStr::from_ptr(ptr) }),
+        Some(ptr) => Some(unsafe { core::ffi::CStr::from_ptr(ptr) }),
         None => None,
     }
 }
diff --git a/pgx/src/guc.rs b/pgx/src/guc.rs
index 6e6334fed..74769dfed 100644
--- a/pgx/src/guc.rs
+++ b/pgx/src/guc.rs
@@ -10,8 +10,8 @@ Use of this source code is governed by the MIT license that can be found in the
 //! Provides a safe interface into Postgres' Configuration System (GUC)
 use crate::{pg_sys, PgMemoryContexts};
 pub use ::pgx_macros::PostgresGucEnum;
+use core::ffi::CStr;
 use std::cell::Cell;
-use std::ffi::CStr;
 
 pub enum GucContext {
     /// cannot be set by the user at all, but only through
diff --git a/pgx/src/hooks.rs b/pgx/src/hooks.rs
index 3e141ba9e..d73dc9b3e 100644
--- a/pgx/src/hooks.rs
+++ b/pgx/src/hooks.rs
@@ -113,7 +113,7 @@ pub trait PgHooks {
     fn process_utility_hook(
         &mut self,
         pstmt: PgBox<pg_sys::PlannedStmt>,
-        query_string: &std::ffi::CStr,
+        query_string: &core::ffi::CStr,
         read_only_tree: Option<bool>,
         context: pg_sys::ProcessUtilityContext,
         params: PgBox<pg_sys::ParamListInfoData>,
@@ -122,7 +122,7 @@ pub trait PgHooks {
         completion_tag: *mut pg_sys::QueryCompletion,
         prev_hook: fn(
             pstmt: PgBox<pg_sys::PlannedStmt>,
-            query_string: &std::ffi::CStr,
+            query_string: &core::ffi::CStr,
             read_only_tree: Option<bool>,
             context: pg_sys::ProcessUtilityContext,
             params: PgBox<pg_sys::ParamListInfoData>,
@@ -344,7 +344,7 @@ unsafe extern "C" fn pgx_process_utility(
 ) {
     fn prev(
         pstmt: PgBox<pg_sys::PlannedStmt>,
-        query_string: &std::ffi::CStr,
+        query_string: &core::ffi::CStr,
         _read_only_tree: Option<bool>,
         context: pg_sys::ProcessUtilityContext,
         params: PgBox<pg_sys::ParamListInfoData>,
@@ -368,7 +368,7 @@ unsafe extern "C" fn pgx_process_utility(
     let hook = &mut HOOKS.as_mut().unwrap().current_hook;
     hook.process_utility_hook(
         PgBox::from_pg(pstmt),
-        std::ffi::CStr::from_ptr(query_string),
+        core::ffi::CStr::from_ptr(query_string),
         None,
         context,
         PgBox::from_pg(params),
@@ -393,7 +393,7 @@ unsafe extern "C" fn pgx_process_utility(
 ) {
     fn prev(
         pstmt: PgBox<pg_sys::PlannedStmt>,
-        query_string: &std::ffi::CStr,
+        query_string: &core::ffi::CStr,
         read_only_tree: Option<bool>,
         context: pg_sys::ProcessUtilityContext,
         params: PgBox<pg_sys::ParamListInfoData>,
@@ -418,7 +418,7 @@ unsafe extern "C" fn pgx_process_utility(
     let hook = &mut HOOKS.as_mut().unwrap().current_hook;
     hook.process_utility_hook(
         PgBox::from_pg(pstmt),
-        std::ffi::CStr::from_ptr(query_string),
+        core::ffi::CStr::from_ptr(query_string),
         Some(read_only_tree),
         context,
         PgBox::from_pg(params),
diff --git a/pgx/src/inoutfuncs.rs b/pgx/src/inoutfuncs.rs
index 8a5a560c9..e4d6aedf7 100644
--- a/pgx/src/inoutfuncs.rs
+++ b/pgx/src/inoutfuncs.rs
@@ -21,7 +21,7 @@ pub trait PgVarlenaInOutFuncs {
     /// Given a string representation of `Self`, parse it into a `PgVarlena<Self>`.
     ///
     /// It is expected that malformed input will raise an `error!()` or `panic!()`
-    fn input(input: &crate::cstr_core::CStr) -> PgVarlena<Self>
+    fn input(input: &core::ffi::CStr) -> PgVarlena<Self>
     where
         Self: Copy + Sized;
 
@@ -39,7 +39,7 @@ pub trait InOutFuncs {
     /// Given a string representation of `Self`, parse it into `Self`.
     ///
     /// It is expected that malformed input will raise an `error!()` or `panic!()`
-    fn input(input: &crate::cstr_core::CStr) -> Self
+    fn input(input: &core::ffi::CStr) -> Self
     where
         Self: Sized;
 
@@ -55,7 +55,7 @@ pub trait InOutFuncs {
 /// **not** also have the `#[inoutfuncs]` attribute macro
 pub trait JsonInOutFuncs<'de>: serde::de::Deserialize<'de> + serde::ser::Serialize {
     /// Uses `serde_json` to deserialize the input, which is assumed to be JSON
-    fn input(input: &'de crate::cstr_core::CStr) -> Self {
+    fn input(input: &'de core::ffi::CStr) -> Self {
         serde_json::from_str(input.to_str().expect("text input is not valid UTF8"))
             .expect("failed to deserialize json")
     }
diff --git a/pgx/src/lib.rs b/pgx/src/lib.rs
index d8e0f6ddc..632686be6 100644
--- a/pgx/src/lib.rs
+++ b/pgx/src/lib.rs
@@ -128,8 +128,6 @@ pub use pg_sys::{
 #[doc(hidden)]
 pub use pgx_sql_entity_graph;
 
-pub use cstr_core;
-
 /// A macro for marking a library compatible with [`pgx`][crate].
 ///
 /// <div class="example-wrap" style="display:inline-block">
diff --git a/pgx/src/lwlock.rs b/pgx/src/lwlock.rs
index 636e115ee..55d17c352 100644
--- a/pgx/src/lwlock.rs
+++ b/pgx/src/lwlock.rs
@@ -97,7 +97,7 @@ impl<T> fmt::Debug for PgLwLockInner<T> {
 impl<'a, T> PgLwLockInner<T> {
     fn new(name: &'static str, data: *mut T) -> Self {
         unsafe {
-            let lock = std::ffi::CString::new(name).expect("CString::new failed");
+            let lock = alloc::ffi::CString::new(name).expect("CString::new failed");
             PgLwLockInner {
                 lock_ptr: &mut (*pg_sys::GetNamedLWLockTranche(lock.as_ptr())).lock,
                 data,
diff --git a/pgx/src/memcxt.rs b/pgx/src/memcxt.rs
index a57d8c20d..2ccf5af5f 100644
--- a/pgx/src/memcxt.rs
+++ b/pgx/src/memcxt.rs
@@ -386,7 +386,7 @@ impl PgMemoryContexts {
                 max_block_size,
             } => {
                 let context: pg_sys::MemoryContext = unsafe {
-                    let name = std::ffi::CString::new(*name).unwrap();
+                    let name = alloc::ffi::CString::new(*name).unwrap();
                     pg_sys::AllocSetContextCreateExtended(
                         *parent,
                         name.into_raw(),
@@ -428,7 +428,7 @@ impl PgMemoryContexts {
     /// We also cannot ensure that the result of this function will stay allocated as long as Rust's
     /// borrow checker thinks it will.
     pub unsafe fn pstrdup(&self, s: &str) -> *mut std::os::raw::c_char {
-        let cstring = std::ffi::CString::new(s).unwrap();
+        let cstring = alloc::ffi::CString::new(s).unwrap();
         unsafe { pg_sys::MemoryContextStrdup(self.value(), cstring.as_ptr()) }
     }
 
diff --git a/pgx/src/nodes.rs b/pgx/src/nodes.rs
index 4b63b0e93..0fd6067fb 100644
--- a/pgx/src/nodes.rs
+++ b/pgx/src/nodes.rs
@@ -31,7 +31,7 @@ pub unsafe fn node_to_string<'a>(nodeptr: *mut pg_sys::Node) -> Option<&'a str>
             None
         } else {
             Some(
-                std::ffi::CStr::from_ptr(string)
+                core::ffi::CStr::from_ptr(string)
                     .to_str()
                     .expect("unable to convert Node into a &str"),
             )
diff --git a/pgx/src/rel.rs b/pgx/src/rel.rs
index 90f9f7d77..db98aca57 100644
--- a/pgx/src/rel.rs
+++ b/pgx/src/rel.rs
@@ -167,7 +167,7 @@ impl PgRelation {
 
     /// What is the name of the namespace in which this relation is located?
     pub fn namespace(&self) -> &str {
-        unsafe { std::ffi::CStr::from_ptr(pg_sys::get_namespace_name(self.namespace_oid())) }
+        unsafe { core::ffi::CStr::from_ptr(pg_sys::get_namespace_name(self.namespace_oid())) }
             .to_str()
             .expect("unable to convert namespace name to UTF8")
     }
diff --git a/pgx/src/shmem.rs b/pgx/src/shmem.rs
index caa4c169c..3ddc52ab0 100644
--- a/pgx/src/shmem.rs
+++ b/pgx/src/shmem.rs
@@ -153,7 +153,7 @@ impl PgSharedMem {
     /// Must be run from PG_init, use for types which are guarded by a LWLock
     pub fn pg_init_locked<T: Default + PGXSharedMemory>(lock: &PgLwLock<T>) {
         unsafe {
-            let lock = std::ffi::CString::new(lock.get_name()).expect("CString::new failed");
+            let lock = alloc::ffi::CString::new(lock.get_name()).expect("CString::new failed");
             pg_sys::RequestAddinShmemSpace(std::mem::size_of::<T>());
             pg_sys::RequestNamedLWLockTranche(lock.as_ptr(), 1);
         }
@@ -170,7 +170,7 @@ impl PgSharedMem {
     pub fn shmem_init_locked<T: Default + PGXSharedMemory>(lock: &PgLwLock<T>) {
         let mut found = false;
         unsafe {
-            let shm_name = std::ffi::CString::new(lock.get_name()).expect("CString::new failed");
+            let shm_name = alloc::ffi::CString::new(lock.get_name()).expect("CString::new failed");
             let addin_shmem_init_lock: *mut pg_sys::LWLock =
                 &mut (*pg_sys::MainLWLockArray.add(21)).lock;
             pg_sys::LWLockAcquire(addin_shmem_init_lock, pg_sys::LWLockMode_LW_EXCLUSIVE);
@@ -189,8 +189,8 @@ impl PgSharedMem {
     /// Must be run from the shared memory init hook, use for rust atomics behind `PgAtomic`
     pub fn shmem_init_atomic<T: atomic_traits::Atomic + Default>(atomic: &PgAtomic<T>) {
         unsafe {
-            let shm_name =
-                std::ffi::CString::new(Uuid::new_v4().to_string()).expect("CString::new() failed");
+            let shm_name = alloc::ffi::CString::new(Uuid::new_v4().to_string())
+                .expect("CString::new() failed");
 
             let addin_shmem_init_lock: *mut pg_sys::LWLock =
                 &mut (*pg_sys::MainLWLockArray.add(21)).lock;
diff --git a/pgx/src/stringinfo.rs b/pgx/src/stringinfo.rs
index 761ae8cff..193a96946 100644
--- a/pgx/src/stringinfo.rs
+++ b/pgx/src/stringinfo.rs
@@ -21,27 +21,13 @@ pub struct StringInfo<AllocatedBy: WhoAllocated = AllocatedByRust> {
     inner: PgBox<pg_sys::StringInfoData, AllocatedBy>,
 }
 
-impl<AllocatedBy: WhoAllocated> From<StringInfo<AllocatedBy>> for &'static std::ffi::CStr {
+impl<AllocatedBy: WhoAllocated> From<StringInfo<AllocatedBy>> for &'static core::ffi::CStr {
     fn from(val: StringInfo<AllocatedBy>) -> Self {
         let len = val.len();
         let ptr = val.into_char_ptr();
 
         unsafe {
-            std::ffi::CStr::from_bytes_with_nul_unchecked(std::slice::from_raw_parts(
-                ptr as *const u8,
-                (len + 1) as usize, // +1 to get the trailing null byte
-            ))
-        }
-    }
-}
-
-impl<AllocatedBy: WhoAllocated> From<StringInfo<AllocatedBy>> for &'static crate::cstr_core::CStr {
-    fn from(val: StringInfo<AllocatedBy>) -> Self {
-        let len = val.len();
-        let ptr = val.into_char_ptr();
-
-        unsafe {
-            crate::cstr_core::CStr::from_bytes_with_nul_unchecked(std::slice::from_raw_parts(
+            core::ffi::CStr::from_bytes_with_nul_unchecked(std::slice::from_raw_parts(
                 ptr as *const u8,
                 (len + 1) as usize, // +1 to get the trailing null byte
             ))
diff --git a/pgx/src/trigger_support/pg_trigger.rs b/pgx/src/trigger_support/pg_trigger.rs
index 4836b4640..3f41efc27 100644
--- a/pgx/src/trigger_support/pg_trigger.rs
+++ b/pgx/src/trigger_support/pg_trigger.rs
@@ -6,8 +6,8 @@ use crate::trigger_support::{
     called_as_trigger, PgTriggerError, PgTriggerLevel, PgTriggerOperation, PgTriggerSafe,
     PgTriggerWhen, TriggerEvent, TriggerTuple,
 };
-use cstr_core::c_char;
 use std::borrow::Borrow;
+use std::ffi::c_char;
 
 /**
 The datatype accepted by a trigger
@@ -96,7 +96,7 @@ impl PgTrigger {
         // containing a known good `TriggerData` which also contains a known good `Trigger`... and the user agreed to
         // our `unsafe` constructor safety rules, we choose to trust this is indeed a valid pointer offered to us by
         // PostgreSQL, and that it trusts it.
-        let name_cstr = unsafe { cstr_core::CStr::from_ptr(name_ptr) };
+        let name_cstr = unsafe { core::ffi::CStr::from_ptr(name_ptr) };
         let name_str = name_cstr.to_str()?;
         Ok(name_str)
     }
@@ -136,7 +136,7 @@ impl PgTrigger {
             // containing a known good `TriggerData` which also contains a known good `Trigger`... and the user agreed to
             // our `unsafe` constructor safety rules, we choose to trust this is indeed a valid pointer offered to us by
             // PostgreSQL, and that it trusts it.
-            let table_name_cstr = unsafe { cstr_core::CStr::from_ptr(tgoldtable) };
+            let table_name_cstr = unsafe { core::ffi::CStr::from_ptr(tgoldtable) };
             let table_name_str = table_name_cstr.to_str()?;
             Ok(Some(table_name_str))
         } else {
@@ -152,7 +152,7 @@ impl PgTrigger {
             // containing a known good `TriggerData` which also contains a known good `Trigger`... and the user agreed to
             // our `unsafe` constructor safety rules, we choose to trust this is indeed a valid pointer offered to us by
             // PostgreSQL, and that it trusts it.
-            let table_name_cstr = unsafe { cstr_core::CStr::from_ptr(tgnewtable) };
+            let table_name_cstr = unsafe { core::ffi::CStr::from_ptr(tgnewtable) };
             let table_name_str = table_name_cstr.to_str()?;
             Ok(Some(table_name_str))
         } else {
@@ -222,7 +222,7 @@ impl PgTrigger {
                 // containing a known good `TriggerData` which also contains a known good `Trigger`... and the user agreed to
                 // our `unsafe` constructor safety rules, we choose to trust this is indeed a valid pointer offered to us by
                 // PostgreSQL, and that it trusts it.
-                unsafe { cstr_core::CStr::from_ptr(*v) }.to_str().map(ToString::to_string)
+                unsafe { core::ffi::CStr::from_ptr(*v) }.to_str().map(ToString::to_string)
             })
             .collect::<Result<_, core::str::Utf8Error>>()?;
         Ok(args)
diff --git a/pgx/src/wrappers.rs b/pgx/src/wrappers.rs
index ec45a751c..aa917f023 100644
--- a/pgx/src/wrappers.rs
+++ b/pgx/src/wrappers.rs
@@ -14,7 +14,7 @@ use crate::{direct_function_call, pg_sys, IntoDatum};
 /// Returns the `oid` of the specified type name.  Will panic if Postgres can't find the type
 pub fn regtypein(type_name: &str) -> pg_sys::Oid {
     let cstr =
-        std::ffi::CString::new(type_name).expect("specified type_name has embedded NULL byte");
+        alloc::ffi::CString::new(type_name).expect("specified type_name has embedded NULL byte");
     unsafe {
         direct_function_call::<pg_sys::Oid>(pg_sys::regtypein, vec![cstr.as_c_str().into_datum()])
             .expect("type lookup returned NULL")