Skip to content

Commit

Permalink
support a pgx extension compiling with no_std (#385)
Browse files Browse the repository at this point in the history
* support a pgx extension compiling with no_std

* fix some compilation issues

* cleanups

* support a pgx extension compiling with no_std

* fix some compilation issues

* cleanups

* fix compilation problem
  • Loading branch information
eeeebbbbrrrr authored Feb 1, 2022
1 parent a0cf135 commit 10e133e
Show file tree
Hide file tree
Showing 28 changed files with 274 additions and 41 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/examples.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
matrix:
version: [10, 11, 12, 13, 14]
os: ["ubuntu-latest"]
examples: ["aggregate", "arrays", "bad_ideas", "bgworker", "bytea", "custom_types", "custom_sql", "errors", "operators", "schemas", "shmem", "spi", "srf", "strings", "triggers"]
examples: ["aggregate", "arrays", "bad_ideas", "bgworker", "bytea", "custom_types", "custom_sql", "errors", "nostd", "operators", "schemas", "shmem", "spi", "srf", "strings", "triggers"]

steps:
- uses: actions/checkout@v2
Expand Down
17 changes: 17 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ exclude = [
"pgx-examples/custom_types",
"pgx-examples/custom_sql",
"pgx-examples/errors",
"pgx-examples/nostd",
"pgx-examples/operators",
"pgx-examples/schemas",
"pgx-examples/shmem",
"pgx-examples/spi",
Expand Down
20 changes: 12 additions & 8 deletions pgx-examples/aggregate/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// use pgx::datum::sql_entity_graph::aggregate::{FinalizeModify, ParallelOption};
use pgx::cstr_core::CStr;
use pgx::*;
use serde::{Deserialize, Serialize};
use std::{ffi::CStr, str::FromStr};
use std::str::FromStr;

pg_module_magic!();

Expand All @@ -14,7 +14,10 @@ pub struct IntegerAvgState {

impl IntegerAvgState {
#[inline(always)]
fn state(mut current: <Self as Aggregate>::State, arg: <Self as Aggregate>::Args) -> <Self as Aggregate>::State {
fn state(
mut current: <Self as Aggregate>::State,
arg: <Self as Aggregate>::Args,
) -> <Self as Aggregate>::State {
current.sum += arg;
current.n += 1;
current
Expand Down Expand Up @@ -65,7 +68,11 @@ impl Aggregate for IntegerAvgState {
const INITIAL_CONDITION: Option<&'static str> = Some("0,0");

#[pgx(parallel_safe, immutable)]
fn state(current: Self::State, arg: Self::Args, _fcinfo: pg_sys::FunctionCallInfo) -> Self::State {
fn state(
current: Self::State,
arg: Self::Args,
_fcinfo: pg_sys::FunctionCallInfo,
) -> Self::State {
Self::state(current, arg)
}

Expand Down Expand Up @@ -130,10 +137,7 @@ mod tests {
let avg_state = IntegerAvgState::state(avg_state, 1);
let avg_state = IntegerAvgState::state(avg_state, 2);
let avg_state = IntegerAvgState::state(avg_state, 3);
assert_eq!(
2,
IntegerAvgState::finalize(avg_state),
);
assert_eq!(2, IntegerAvgState::finalize(avg_state),);
}

#[pg_test]
Expand Down
2 changes: 1 addition & 1 deletion pgx-examples/custom_types/src/fixed_size.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use pgx::cstr_core::CStr;
use pgx::*;
use std::ffi::CStr;
use std::str::FromStr;

#[derive(Copy, Clone, PostgresType)]
Expand Down
16 changes: 16 additions & 0 deletions pgx-examples/nostd/.cargo/config
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Auto-generated by pgx. You may edit this, or delete it to have a new one created.

[target.x86_64-unknown-linux-gnu]
linker = "./.cargo/pgx-linker-script.sh"

[target.aarch64-unknown-linux-gnu]
linker = "./.cargo/pgx-linker-script.sh"

[target.x86_64-apple-darwin]
linker = "./.cargo/pgx-linker-script.sh"

[target.aarch64-apple-darwin]
linker = "./.cargo/pgx-linker-script.sh"

[target.x86_64-unknown-freebsd]
linker = "./.cargo/pgx-linker-script.sh"
19 changes: 19 additions & 0 deletions pgx-examples/nostd/.cargo/pgx-linker-script.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#! /usr/bin/env bash
# Auto-generated by pgx. You may edit this, or delete it to have a new one created.

if [[ $CARGO_BIN_NAME == "sql-generator" ]]; then
UNAME=$(uname)
if [[ $UNAME == "Darwin" ]]; then
TEMP=$(mktemp pgx-XXX)
echo "*_pgx_internals_*" > ${TEMP}
gcc -exported_symbols_list ${TEMP} $@
rm -rf ${TEMP}
else
TEMP=$(mktemp pgx-XXX)
echo "{ __pgx_internals_*; };" > ${TEMP}
gcc -Wl,-dynamic-list=${TEMP} $@
rm -rf ${TEMP}
fi
else
gcc -Wl,-undefined,dynamic_lookup $@
fi
7 changes: 7 additions & 0 deletions pgx-examples/nostd/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.DS_Store
.idea/
/target
*.iml
**/*.rs.bk
Cargo.lock
sql/nostd-1.0.sql
37 changes: 37 additions & 0 deletions pgx-examples/nostd/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
[package]
name = "nostd"
version = "0.0.0"
edition = "2018"

[lib]
crate-type = ["cdylib", "rlib"]

# remove this empty 'workspace' declaration if compiling outside of 'pgx'
[workspace]

[features]
default = ["pg13"]
pg10 = ["pgx/pg10", "pgx-tests/pg10" ]
pg11 = ["pgx/pg11", "pgx-tests/pg11" ]
pg12 = ["pgx/pg12", "pgx-tests/pg12" ]
pg13 = ["pgx/pg13", "pgx-tests/pg13" ]
pg14 = ["pgx/pg14", "pgx-tests/pg14" ]
pg_test = []

[dependencies]
pgx = { path = "../../../pgx/pgx/", default-features = false }
serde = "1.0.114"

[dev-dependencies]
pgx-tests = { path = "../../../pgx/pgx-tests" }

# uncomment these if compiling outside of 'pgx'
# [profile.dev]
# panic = "unwind"
# lto = "thin"

# [profile.release]
# panic = "unwind"
# opt-level = 3
# lto = "fat"
# codegen-units = 1
5 changes: 5 additions & 0 deletions pgx-examples/nostd/nostd.control
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
comment = 'nostd: Created by pgx'
default_version = '1.0'
module_pathname = '$libdir/nostd'
relocatable = false
superuser = false
2 changes: 2 additions & 0 deletions pgx-examples/nostd/src/bin/sql-generator.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/* Auto-generated by pgx. You may edit this, or delete it to have a new one created. */
pgx::pg_binary_magic!(nostd);
51 changes: 51 additions & 0 deletions pgx-examples/nostd/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
//! This exists just to make sure we can compile various things under `#![no_std]`
#![no_std]
extern crate alloc;

use pgx::*;
use serde::{Deserialize, Serialize};

use alloc::string::String;

pg_module_magic!();

/// standard Rust equality/comparison derives
#[derive(Eq, PartialEq, Ord, Hash, PartialOrd)]

/// Support using this struct as a Postgres type, which the easy way requires Serde
#[derive(PostgresType, Serialize, Deserialize)]

/// automatically generate =, <> SQL operator functions
#[derive(PostgresEq)]

/// automatically generate <, >, <=, >=, and a "_cmp" SQL functions
/// When "PostgresEq" is also derived, pgx also creates an "opclass" (and family)
/// so that the type can be used in indexes `USING btree`
#[derive(PostgresOrd)]

/// automatically generate a "_hash" function, and the necessary "opclass" (and family)
/// so the type can also be used in indexes `USING hash`
#[derive(PostgresHash)]
pub struct Thing(String);

#[derive(PostgresType, Serialize, Deserialize, Eq, PartialEq)]
pub struct MyType {
value: i32,
}

#[pg_operator]
#[opname(=)]
fn my_eq(left: MyType, right: MyType) -> bool {
left == right
}

#[pg_extern]
fn hello_nostd() -> &'static str {
"Hello, nostd"
}

#[pg_extern]
fn echo(input: String) -> String {
input
}
16 changes: 8 additions & 8 deletions pgx-macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -294,12 +294,12 @@ extension_sql!(r#"\
);
#[pg_extern(immutable)]
fn complex_in(input: &std::ffi::CStr) -> PgBox<Complex> {
fn complex_in(input: &pgx::cstr_core::CStr) -> PgBox<Complex> {
todo!()
}
#[pg_extern(immutable)]
fn complex_out(complex: PgBox<Complex>) -> &'static std::ffi::CStr {
fn complex_out(complex: PgBox<Complex>) -> &'static pgx::cstr_core::CStr {
todo!()
}
Expand Down Expand Up @@ -735,12 +735,12 @@ fn impl_postgres_type(ast: DeriveInput) -> proc_macro2::TokenStream {
impl #generics JsonInOutFuncs #inout_generics for #name #generics {}

#[pg_extern(immutable,parallel_safe)]
pub fn #funcname_in #generics(input: &#lifetime std::ffi::CStr) -> #name #generics {
pub fn #funcname_in #generics(input: &#lifetime pgx::cstr_core::CStr) -> #name #generics {
#name::input(input)
}

#[pg_extern(immutable,parallel_safe)]
pub fn #funcname_out #generics(input: #name #generics) -> &#lifetime std::ffi::CStr {
pub fn #funcname_out #generics(input: #name #generics) -> &#lifetime pgx::cstr_core::CStr {
let mut buffer = StringInfo::new();
input.output(&mut buffer);
buffer.into()
Expand All @@ -751,12 +751,12 @@ fn impl_postgres_type(ast: DeriveInput) -> proc_macro2::TokenStream {
// otherwise if it's InOutFuncs our _in/_out functions use an owned type instance
stream.extend(quote! {
#[pg_extern(immutable,parallel_safe)]
pub fn #funcname_in #generics(input: &#lifetime std::ffi::CStr) -> #name #generics {
pub fn #funcname_in #generics(input: &#lifetime pgx::cstr_core::CStr) -> #name #generics {
#name::input(input)
}

#[pg_extern(immutable,parallel_safe)]
pub fn #funcname_out #generics(input: #name #generics) -> &#lifetime std::ffi::CStr {
pub fn #funcname_out #generics(input: #name #generics) -> &#lifetime pgx::cstr_core::CStr {
let mut buffer = StringInfo::new();
input.output(&mut buffer);
buffer.into()
Expand All @@ -766,12 +766,12 @@ fn impl_postgres_type(ast: DeriveInput) -> proc_macro2::TokenStream {
// otherwise if it's PgVarlenaInOutFuncs our _in/_out functions use a PgVarlena
stream.extend(quote! {
#[pg_extern(immutable,parallel_safe)]
pub fn #funcname_in #generics(input: &#lifetime std::ffi::CStr) -> pgx::PgVarlena<#name #generics> {
pub fn #funcname_in #generics(input: &#lifetime pgx::cstr_core::CStr) -> pgx::PgVarlena<#name #generics> {
#name::input(input)
}

#[pg_extern(immutable,parallel_safe)]
pub fn #funcname_out #generics(input: pgx::PgVarlena<#name #generics>) -> &#lifetime std::ffi::CStr {
pub fn #funcname_out #generics(input: pgx::PgVarlena<#name #generics>) -> &#lifetime pgx::cstr_core::CStr {
let mut buffer = StringInfo::new();
input.output(&mut buffer);
buffer.into()
Expand Down
2 changes: 1 addition & 1 deletion pgx-tests/src/tests/postgres_type_tests.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use pgx::cstr_core::CStr;
use pgx::*;
use serde::{Deserialize, Serialize};
use std::ffi::CStr;
use std::str::FromStr;

#[derive(Copy, Clone, PostgresType)]
Expand Down
6 changes: 6 additions & 0 deletions pgx-utils/src/sql_entity_graph/extension_sql.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,9 @@ impl ToTokens for ExtensionSqlFile {
let inv = quote! {
#[no_mangle]
pub extern "C" fn #sql_graph_entity_fn_name() -> pgx::datum::sql_entity_graph::SqlGraphEntity {
extern crate alloc;
use alloc::vec::Vec;
use alloc::vec;
let submission = pgx::datum::sql_entity_graph::ExtensionSqlEntity {
sql: include_str!(#path),
module_path: module_path!(),
Expand Down Expand Up @@ -194,6 +197,9 @@ impl ToTokens for ExtensionSql {
let inv = quote! {
#[no_mangle]
pub extern "C" fn #sql_graph_entity_fn_name() -> pgx::datum::sql_entity_graph::SqlGraphEntity {
extern crate alloc;
use alloc::vec::Vec;
use alloc::vec;
let submission = pgx::datum::sql_entity_graph::ExtensionSqlEntity {
sql: #sql,
module_path: module_path!(),
Expand Down
3 changes: 3 additions & 0 deletions pgx-utils/src/sql_entity_graph/pg_extern/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,9 @@ impl ToTokens for PgExtern {
#[no_mangle]
pub extern "C" fn #sql_graph_entity_fn_name() -> pgx::datum::sql_entity_graph::SqlGraphEntity {
use core::any::TypeId;
extern crate alloc;
use alloc::vec::Vec;
use alloc::vec;
let submission = pgx::datum::sql_entity_graph::PgExternEntity {
name: #name,
unaliased_name: stringify!(#ident),
Expand Down
5 changes: 4 additions & 1 deletion pgx-utils/src/sql_entity_graph/pg_schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,10 @@ impl ToTokens for Schema {
updated_content.push(syn::parse_quote! {
#[no_mangle]
pub extern "C" fn #sql_graph_entity_fn_name() -> pgx::datum::sql_entity_graph::SqlGraphEntity {
let submission = pgx::datum::sql_entity_graph::SchemaEntity {
extern crate alloc;
use alloc::vec::Vec;
use alloc::vec;
let submission = pgx::datum::sql_entity_graph::SchemaEntity {
module_path: module_path!(),
name: stringify!(#ident),
file: file!(),
Expand Down
3 changes: 3 additions & 0 deletions pgx-utils/src/sql_entity_graph/postgres_enum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,9 @@ impl ToTokens for PostgresEnum {
let inv = quote! {
#[no_mangle]
pub extern "C" fn #sql_graph_entity_fn_name() -> pgx::datum::sql_entity_graph::SqlGraphEntity {
extern crate alloc;
use alloc::vec::Vec;
use alloc::vec;
let mut mappings = Default::default();
<#name #ty_generics as pgx::datum::WithTypeIds>::register_with_refs(&mut mappings, stringify!(#name).to_string());
pgx::datum::WithSizedTypeIds::<#name #ty_generics>::register_sized_with_refs(&mut mappings, stringify!(#name).to_string());
Expand Down
3 changes: 3 additions & 0 deletions pgx-utils/src/sql_entity_graph/postgres_hash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,9 @@ impl ToTokens for PostgresHash {
#[no_mangle]
pub extern "C" fn #sql_graph_entity_fn_name() -> pgx::datum::sql_entity_graph::SqlGraphEntity {
use core::any::TypeId;
extern crate alloc;
use alloc::vec::Vec;
use alloc::vec;
let submission = pgx::datum::sql_entity_graph::PostgresHashEntity {
name: stringify!(#name),
file: file!(),
Expand Down
3 changes: 3 additions & 0 deletions pgx-utils/src/sql_entity_graph/postgres_ord.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,9 @@ impl ToTokens for PostgresOrd {
#[no_mangle]
pub extern "C" fn #sql_graph_entity_fn_name() -> pgx::datum::sql_entity_graph::SqlGraphEntity {
use core::any::TypeId;
extern crate alloc;
use alloc::vec::Vec;
use alloc::vec;
let submission = pgx::datum::sql_entity_graph::PostgresOrdEntity {
name: stringify!(#name),
file: file!(),
Expand Down
5 changes: 5 additions & 0 deletions pgx-utils/src/sql_entity_graph/postgres_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,11 @@ impl ToTokens for PostgresType {
let inv = quote! {
#[no_mangle]
pub extern "C" fn #sql_graph_entity_fn_name() -> pgx::datum::sql_entity_graph::SqlGraphEntity {
extern crate alloc;
use alloc::vec::Vec;
use alloc::vec;
use alloc::string::{String, ToString};

let mut mappings = Default::default();
<#name #ty_generics as pgx::datum::WithTypeIds>::register_with_refs(
&mut mappings,
Expand Down
Loading

0 comments on commit 10e133e

Please sign in to comment.