diff --git a/Cargo.lock b/Cargo.lock index d503c87b4..34375018e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -34,9 +34,9 @@ dependencies = [ [[package]] name = "ahash" -version = "0.8.6" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" +checksum = "77c3a9648d43b9cd48db467b3f87fdd6e146bcc88ab0180006cef2179fe11d01" dependencies = [ "cfg-if", "once_cell", @@ -119,9 +119,9 @@ dependencies = [ [[package]] name = "async-trait" -version = "0.1.74" +version = "0.1.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9" +checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9" dependencies = [ "proc-macro2", "quote", @@ -177,9 +177,9 @@ checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" [[package]] name = "basic-toml" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f2139706359229bfa8f19142ac1155b4b80beafb7a60471ac5dd109d4a19778" +checksum = "2db21524cad41c5591204d22d75e1970a2d1f71060214ca931dc7d5afe2c14e5" dependencies = [ "serde", ] @@ -340,7 +340,6 @@ dependencies = [ "eyre", "flate2", "jobslot", - "libloading", "nix", "object", "once_cell", @@ -565,9 +564,9 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.11" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0" +checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" dependencies = [ "libc", ] @@ -583,35 +582,28 @@ dependencies = [ [[package]] name = "crossbeam-deque" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fca89a0e215bab21874660c67903c5f143333cab1da83d041c7ded6053774751" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" dependencies = [ - "cfg-if", "crossbeam-epoch", "crossbeam-utils", ] [[package]] name = "crossbeam-epoch" -version = "0.9.16" +version = "0.9.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d2fe95351b870527a5d09bf563ed3c97c0cffb87cf1c78a591bf48bb218d9aa" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" dependencies = [ - "autocfg", - "cfg-if", "crossbeam-utils", - "memoffset", ] [[package]] name = "crossbeam-utils" -version = "0.8.17" +version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d96137f14f244c37f989d9fff8f95e6c18b918e71f36638f8c49112e4c78f" -dependencies = [ - "cfg-if", -] +checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" [[package]] name = "crypto-common" @@ -866,9 +858,9 @@ checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" [[package]] name = "futures-channel" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff4dd66668b557604244583e3e1e1eada8c5c2e96a6d0d6653ede395b78bbacb" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" dependencies = [ "futures-core", "futures-sink", @@ -876,15 +868,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb1d22c66e66d9d72e1758f0bd7d4fd0bee04cad842ee34587d68c07e45d088c" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" [[package]] name = "futures-macro" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddb" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", @@ -893,21 +885,21 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e36d3378ee38c2a36ad710c5d30c2911d752cb941c00c72dbabfb786a7970817" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" [[package]] name = "futures-task" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efd193069b0ddadc69c46389b740bbccdd97203899b48d09c5f7969591d6bae2" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" [[package]] name = "futures-util" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a19526d624e703a3179b3d322efec918b6246ea0fa51d41124525f00f1cc8104" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" dependencies = [ "futures-core", "futures-macro", @@ -1062,9 +1054,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.66" +version = "0.3.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cee9c64da59eae3b50095c18d3e74f8b73c0b86d2792824ff01bbce68ba229ca" +checksum = "9a1d36f1235bc969acba30b7f5990b864423a6068a10f7c90ae8f0112e3a59d1" dependencies = [ "wasm-bindgen", ] @@ -1817,9 +1809,9 @@ dependencies = [ [[package]] name = "rayon" -version = "1.8.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c27db03db7734835b3f53954b534c91069375ce6ccaa2e065441e07d9b6cdb1" +checksum = "fa7237101a77a10773db45d62004a272517633fbcc3df19d96455ede1122e051" dependencies = [ "either", "rayon-core", @@ -1827,9 +1819,9 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.12.0" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" dependencies = [ "crossbeam-deque", "crossbeam-utils", @@ -1852,7 +1844,7 @@ checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.4.4", + "regex-automata 0.4.5", "regex-syntax 0.8.2", ] @@ -1867,9 +1859,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b7fa1134405e2ec9353fd416b17f8dacd46c473d7d3fd1cf202706a14eb792a" +checksum = "5bb987efffd3c6d0d8f5f89510bb458559eab11e4f869acb20bf845e016259cd" dependencies = [ "aho-corasick", "memchr", @@ -2133,9 +2125,9 @@ checksum = "a3f0bf26fd526d2a95683cd0f87bf103b8539e2ca1ef48ce002d67aad59aa0b4" [[package]] name = "serde" -version = "1.0.195" +version = "1.0.196" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63261df402c67811e9ac6def069e4786148c4563f4b50fd4bf30aa370d626b02" +checksum = "870026e60fa08c69f064aa766c10f10b1d62db9ccd4d0abb206472bee0ce3b32" dependencies = [ "serde_derive", ] @@ -2164,9 +2156,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.195" +version = "1.0.196" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46fe8f8603d81ba86327b23a2e9cdf49e1255fb94a4c5f297f6ee0547178ea2c" +checksum = "33c85360c95e7d137454dc81d9a4ed2b8efd8fbe19cee57357b32b9771fccb67" dependencies = [ "proc-macro2", "quote", @@ -2175,9 +2167,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.111" +version = "1.0.112" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "176e46fa42316f18edd598015a5166857fc835ec732f5215eac6b7bdbf0a84f4" +checksum = "4d1bd37ce2324cf3bf85e5a25f96eb4baf0d5aa6eba43e7ae8958870c4ec48ed" dependencies = [ "itoa", "ryu", @@ -2430,9 +2422,9 @@ dependencies = [ [[package]] name = "termcolor" -version = "1.4.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff1bc3d3f05aff0403e8ac0d92ced918ec05b666a43f83297ccef5bea8a3d449" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" dependencies = [ "winapi-util", ] @@ -2523,9 +2515,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.35.0" +version = "1.35.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "841d45b238a16291a4e1584e61820b8ae57d696cc5015c459c229ccc6990cc1c" +checksum = "c89b4efa943be685f629b149f53829423f8f5531ea21249408e8e2f8671ec104" dependencies = [ "backtrace", "bytes", @@ -2692,9 +2684,9 @@ dependencies = [ [[package]] name = "trybuild" -version = "1.0.85" +version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "196a58260a906cedb9bf6d8034b6379d0c11f552416960452f267402ceeddff1" +checksum = "9a9d3ba662913483d6722303f619e75ea10b7855b0f8e0d72799cf8621bb488f" dependencies = [ "basic-toml", "glob", @@ -2877,9 +2869,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.89" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ed0d4f68a3015cc185aff4db9506a015f4b96f95303897bfa23f846db54064e" +checksum = "b1223296a201415c7fad14792dbefaace9bd52b62d33453ade1c5b5f07555406" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -2887,9 +2879,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.89" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b56f625e64f3a1084ded111c4d5f477df9f8c92df113852fa5a374dbda78826" +checksum = "fcdc935b63408d58a32f8cc9738a0bffd8f05cc7c002086c6ef20b7312ad9dcd" dependencies = [ "bumpalo", "log", @@ -2902,9 +2894,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.89" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0162dbf37223cd2afce98f3d0785506dcb8d266223983e4b5b525859e6e182b2" +checksum = "3e4c238561b2d428924c49815533a8b9121c664599558a5d9ec51f8a1740a999" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -2912,9 +2904,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.89" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283" +checksum = "bae1abb6806dc1ad9e560ed242107c0f6c84335f1749dd4e8ddb012ebd5e25a7" dependencies = [ "proc-macro2", "quote", @@ -2925,15 +2917,15 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.89" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ab9b36309365056cd639da3134bf87fa8f3d86008abf99e612384a6eecd459f" +checksum = "4d91413b1c31d7539ba5ef2451af3f0b833a005eb27a631cec32bc0635a8602b" [[package]] name = "web-sys" -version = "0.3.66" +version = "0.3.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50c24a44ec86bb68fbecd1b3efed7e85ea5621b39b35ef2766b66cd984f8010f" +checksum = "58cd2333b6e0be7a39605f0e255892fd7418a682d8da8fe042fe25128794d2ed" dependencies = [ "js-sys", "wasm-bindgen", @@ -3120,9 +3112,9 @@ checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" [[package]] name = "winnow" -version = "0.5.34" +version = "0.5.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7cf47b659b318dccbd69cc4797a39ae128f533dce7902a1096044d1967b9c16" +checksum = "1931d78a9c73861da0134f453bb1f790ce49b2e30eba8410b4b79bac72b46a2d" dependencies = [ "memchr", ] @@ -3164,18 +3156,18 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.7.31" +version = "0.7.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c4061bedbb353041c12f413700357bec76df2c7e2ca8e4df8bac24c6bf68e3d" +checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.31" +version = "0.7.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3c129550b3e6de3fd0ba67ba5c81818f9805e58b8d7fee80a3a59d2c9fc601a" +checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" dependencies = [ "proc-macro2", "quote", diff --git a/README.md b/README.md index f6db6a836..1f9455f22 100644 --- a/README.md +++ b/README.md @@ -184,13 +184,6 @@ For more details on how to manage pgrx extensions see [Managing pgrx extensions] ## Upgrading -You can upgrade your current `cargo-pgrx` installation by passing the `--force` flag -to `cargo install`: - -```bash -cargo install --force --locked cargo-pgrx -``` - As new Postgres versions are supported by `pgrx`, you can re-run the `pgrx init` process to download and compile them: ```bash diff --git a/cargo-pgrx/Cargo.toml b/cargo-pgrx/Cargo.toml index 66206af42..27b2a8827 100644 --- a/cargo-pgrx/Cargo.toml +++ b/cargo-pgrx/Cargo.toml @@ -47,7 +47,6 @@ serde = { version = "1.0", features = [ "derive" ] } serde_derive = "1.0" serde-xml-rs = "0.6.0" syn = { version = "2.0.18", features = [ "extra-traits", "full", "fold", "parsing" ] } -libloading = "0.8.1" object = "0.32.1" once_cell = "1.18.0" color-eyre = "0.6.2" diff --git a/cargo-pgrx/README.md b/cargo-pgrx/README.md index db8692771..f2316ead2 100644 --- a/cargo-pgrx/README.md +++ b/cargo-pgrx/README.md @@ -14,7 +14,7 @@ Install via crates.io: $ cargo install --locked cargo-pgrx ``` -As new versions of `pgrx` are released, you'll want to make sure you run this command again to update it. You should also reinstall `cargo-pgrx` whenever you update `rustc` so that the same compiler is used to build `cargo-pgrx` and your Postgres extensions. You can force `cargo` to reinstall an existing crate by passing `--force`. +As new versions of `pgrx` are released, you'll want to make sure you run this command again to update it. Note that some of the features of PGRX involve compiling C code, including `cargo pgrx init`, and as such you will also need a toolchain for doing so and potentially must provide various libraries. @@ -717,30 +717,3 @@ Postgres, so loading two versions of the shared library will cause trouble. These scenarios are: - when using shared memory - when using query planner hooks - -## Compiler Version Dependence - -The version of the Rust compiler and toolchain used to build `cargo-pgrx` must be -the same as the version used to build your extension. - -Several subcommands (including `cargo pgrx schema`, `cargo pgrx test`, `cargo pgrx -install`, ...) will produce an error message if these do not match. - -Although this may be relaxed in the future, currently schema generation involves -`dlopen`ing the extension and calling `extern "Rust"` functions on -`#[repr(Rust)]` types. Generally, the appropriate way to fix this is reinstall -`cargo-pgrx`, using a command like the following - -```console -$ cargo install --force --locked cargo-pgrx -``` - -Possibly with a explicit `--version`, if needed. - -If you are certain that in this case, it is fine, you may set -`PGRX_IGNORE_RUST_VERSIONS` in the environment (to any value other than `"0"`), -and the check will be bypassed. However, note that while the check is not -fool-proof, it tries to be fairly liberal in what it allows. - -See and -for further information. diff --git a/cargo-pgrx/src/command/new.rs b/cargo-pgrx/src/command/new.rs index 8debf36db..4aa5d5cf2 100644 --- a/cargo-pgrx/src/command/new.rs +++ b/cargo-pgrx/src/command/new.rs @@ -57,6 +57,7 @@ pub(crate) fn create_crate_template( create_dotcargo_config_toml(&path, name)?; create_lib_rs(&path, name, is_bgworker)?; create_git_ignore(&path, name)?; + create_pgrx_embed_rs(&path)?; Ok(()) } @@ -67,13 +68,21 @@ fn create_directory_structure(path: &PathBuf) -> Result<(), std::io::Error> { src_dir.push("src"); std::fs::create_dir_all(&src_dir)?; + src_dir.push("bin"); + std::fs::create_dir_all(&src_dir)?; + src_dir.pop(); + src_dir.pop(); + src_dir.push(".cargo"); std::fs::create_dir_all(&src_dir)?; - src_dir.pop(); + src_dir.push("sql"); - std::fs::create_dir_all(&src_dir) + std::fs::create_dir_all(&src_dir)?; + src_dir.pop(); + + Ok(()) } fn create_control_file(path: &PathBuf, name: &str) -> Result<(), std::io::Error> { @@ -138,3 +147,13 @@ fn create_git_ignore(path: &PathBuf, _name: &str) -> Result<(), std::io::Error> Ok(()) } + +fn create_pgrx_embed_rs(path: &PathBuf) -> Result<(), std::io::Error> { + let mut filename = path.clone(); + filename.push("src"); + filename.push("bin"); + filename.push(format!("pgrx_embed.rs")); + let mut file = std::fs::File::create(filename)?; + file.write_all(include_bytes!("../templates/pgrx_embed_rs"))?; + Ok(()) +} diff --git a/cargo-pgrx/src/command/schema.rs b/cargo-pgrx/src/command/schema.rs index 198e10812..896ec3fe0 100644 --- a/cargo-pgrx/src/command/schema.rs +++ b/cargo-pgrx/src/command/schema.rs @@ -8,34 +8,20 @@ //LICENSE //LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. use crate::command::get::{find_control_file, get_property}; -use crate::command::install::format_display_path; -use crate::pgrx_pg_sys_stub::PgrxPgSysStub; use crate::profile::CargoProfile; use crate::CommandExecute; use cargo_toml::Manifest; use eyre::{eyre, WrapErr}; -use object::read::macho::{FatArch, FatHeader}; -use object::{Architecture, FileKind, Object}; -use once_cell::sync::OnceCell; use owo_colors::OwoColorize; -use pgrx_pg_config::{cargo::PgrxManifestExt, get_target_dir, PgConfig, Pgrx}; -use std::collections::HashSet; -use std::hash::{Hash, Hasher}; +use pgrx_pg_config::cargo::PgrxManifestExt; +use pgrx_pg_config::{get_target_dir, PgConfig, Pgrx}; +use std::io::Write; use std::path::{Path, PathBuf}; use std::process::Stdio; // Since we support extensions with `#[no_std]` extern crate alloc; use crate::manifest::{get_package_manifest, pg_config_and_version}; use alloc::vec::Vec; -use std::env; - -// An apparent bug in `glibc` 2.17 prevents us from safely dropping this -// otherwise users find issues such as https://github.com/pgcentralfoundation/pgrx/issues/572 -static POSTMASTER_LIBRARY: OnceCell = OnceCell::new(); - -// An apparent bug in `glibc` 2.17 prevents us from safely dropping this -// otherwise users find issues such as https://github.com/pgcentralfoundation/pgrx/issues/572 -static EXTENSION_LIBRARY: OnceCell = OnceCell::new(); /// Generate extension schema files #[derive(clap::Args, Debug)] @@ -126,50 +112,6 @@ impl CommandExecute for Schema { } } -/// Gets the current `cargo` version. -/// -/// This is a copy of the function in `build.rs`. -/// -/// [Environment variables Cargo sets for 3rd party subcommands](https://doc.rust-lang.org/cargo/reference/environment-variables.html#environment-variables-cargo-sets-for-3rd-party-subcommands) -fn cargo_version() -> Option { - let cargo = std::env::var_os("CARGO").expect("`CARGO` env var wasn't set!"); - let output = std::process::Command::new(cargo).arg("--version").output().ok()?; - std::str::from_utf8(&output.stdout).map(|s| s.trim().to_string()).ok() -} - -/// Returns an error if the rust toolchain version used to build `cargo-pgrx` -/// doesn't match the active toolchain's version. -/// -/// This is an error because we `dlopen` rust code that we build, and call -/// `extern "Rust"` functions on `#[repr(Rust)]` types. This may be relaxed in -/// the future, but for now is a requirement. -/// -/// To waive this, you may set `PGRX_IGNORE_RUST_VERSIONS` in the environment -/// (to any value other than `"0"`). Also, note that this check is best-effort -/// only, and is expected to error only if there is a definite mismatch. -/// -/// It also cannot detect versions of `cargo-pgrx` and `pgrx` differing, which -/// could cause similar issues (in the future this may be detected). -fn check_rust_version() -> eyre::Result<()> { - const CARGO_VERSION_DURING_BUILD: &str = env!("CARGO_VERSION_DURING_BUILD"); - if matches!(std::env::var("PGRX_IGNORE_RUST_VERSIONS"), Ok(s) if s != "0") { - return Ok(()); - } - if let (Some(during_build), Some(during_run)) = - (Some(CARGO_VERSION_DURING_BUILD), cargo_version()) - { - if during_build != during_run { - eyre::bail!( - "Mismatched toolchain versions: \ - `cargo-pgrx` was built with `{during_build}`, \ - but `{during_run}` is currently in use. \ - Set `PGRX_IGNORE_RUST_VERSIONS=1` to override this safety check.", - ); - } - } - Ok(()) -} - #[tracing::instrument(level = "error", skip_all, fields( pg_version = %pg_config.version()?, profile = ?profile, @@ -192,7 +134,6 @@ pub(crate) fn generate_schema( skip_build: bool, output_tracking: &mut Vec, ) -> eyre::Result<()> { - check_rust_version()?; let manifest = Manifest::from_path(&package_manifest_path)?; let (control_file, _extname) = find_control_file(&package_manifest_path)?; @@ -203,103 +144,89 @@ pub(crate) fn generate_schema( )); } - let versioned_so = get_property(&package_manifest_path, "module_pathname")?.is_none(); - let flags = std::env::var("PGRX_BUILD_FLAGS").unwrap_or_default(); - let mut target_dir_with_profile = get_target_dir()?; - target_dir_with_profile.push(profile.target_subdir()); - - // First, build the SQL generator so we can get a look at the symbol table - if !skip_build { - let mut command = crate::env::cargo(); - command.stderr(Stdio::inherit()); - command.stdout(Stdio::inherit()); - if is_test { - command.arg("test"); - command.arg("--no-run"); - } else { - command.arg("build"); - } + let features_arg = features.features.join(" "); - if let Some(user_package) = user_package { - command.arg("--package"); - command.arg(user_package); - } + let package_name = if let Some(user_package) = user_package { + user_package.clone() + } else { + manifest.package_name()? + }; + let lib_name = manifest.lib_name()?; + let lib_filename = manifest.lib_filename()?; - if let Some(user_manifest_path) = user_manifest_path { - command.arg("--manifest-path"); - command.arg(user_manifest_path.as_ref()); - } + if !skip_build { + first_build( + user_manifest_path.as_ref(), + profile, + features, + log_level.clone(), + is_test, + &features_arg, + &flags, + &package_name, + )?; + }; - command.args(profile.cargo_args()); + let symbols = compute_symbols(profile, &lib_filename)?; - if let Some(log_level) = &log_level { - command.env("RUST_LOG", log_level); - } + let mut out_path = None; + if let Some(path) = path.as_ref() { + let x = path.as_ref().to_str().expect("`path` is not a valid UTF8 string."); + out_path = Some(x.to_string()); + } - let features_arg = features.features.join(" "); - if !features_arg.trim().is_empty() { - command.arg("--features"); - command.arg(&features_arg); - } + let mut out_dot = None; + if let Some(dot) = dot.as_ref() { + let x = dot.as_ref().to_str().expect("`dot` is not a valid UTF8 string."); + out_dot = Some(x.to_string()); + }; - if features.no_default_features { - command.arg("--no-default-features"); - } + let codegen = compute_codegen(package_manifest_path, &symbols, &lib_name, out_path, out_dot)?; - if features.all_features { - command.arg("--all-features"); - } + let embed = { + let mut embed = tempfile::NamedTempFile::new()?; + embed.write_all(codegen.as_bytes())?; + embed.flush()?; + embed + }; - for arg in flags.split_ascii_whitespace() { - command.arg(arg); + if let Some(out_path) = path.as_ref() { + if let Some(parent) = out_path.as_ref().parent() { + std::fs::create_dir_all(parent).wrap_err("Could not create parent directory")?; } + output_tracking.push(out_path.as_ref().to_path_buf()); + } - let command = command.stderr(Stdio::inherit()); - let command_str = format!("{command:?}"); - eprintln!( - "{} for SQL generation with features `{}`", - " Building".bold().green(), - features_arg, - ); - - tracing::debug!(command = %command_str, "Running"); - let cargo_output = - command.output().wrap_err_with(|| format!("failed to spawn cargo: {command_str}"))?; - tracing::trace!(status_code = %cargo_output.status, command = %command_str, "Finished"); - - if !cargo_output.status.success() { - // We explicitly do not want to return a spantraced error here. - std::process::exit(1) - } - }; + if let Some(dot_path) = dot.as_ref() { + tracing::info!(dot = %dot_path.as_ref().display(), "Writing Graphviz DOT"); + } - // Create stubbed `pgrx_pg_sys` bindings for the generator to link with. - let mut postmaster_stub_dir = - Pgrx::postmaster_stub_dir().wrap_err("couldn't get postmaster stub dir env")?; - - postmaster_stub_dir.push( - pg_config - .postmaster_path() - .wrap_err("couldn't get postmaster path")? - .strip_prefix("/") - .wrap_err("couldn't make postmaster path relative")? - .parent() - .ok_or(eyre!("couldn't get postmaster parent dir"))?, - ); + second_build( + user_manifest_path.as_ref(), + profile, + features, + log_level.clone(), + &features_arg, + &flags, + embed.path(), + &package_name, + )?; - let postmaster_path = pg_config.postmaster_path().wrap_err("could not get postmaster path")?; + compute_sql(profile, &package_name)?; - // The next action may take a few seconds, we'd like the user to know we're thinking. - eprintln!("{} SQL entities", " Discovering".bold().green()); + Ok(()) +} - let postmaster_stub_built = create_stub(postmaster_path, &postmaster_stub_dir)?; +fn compute_symbols(profile: &CargoProfile, lib_filename: &str) -> eyre::Result> { + use object::Object; + use std::collections::HashSet; // Inspect the symbol table for a list of `__pgrx_internals` we should have the generator call - let mut lib_so = target_dir_with_profile.clone(); - - lib_so.push(manifest.lib_filename()?); + let mut lib_so = get_target_dir()?; + lib_so.push(profile.target_subdir()); + lib_so.push(lib_filename); let lib_so_data = std::fs::read(&lib_so).wrap_err("couldn't read extension shared object")?; let lib_so_obj_file = @@ -376,195 +303,270 @@ pub(crate) fn generate_schema( ); tracing::debug!("Collecting {} SQL entities", fns_to_call.len()); - let mut entities = Vec::default(); - - #[rustfmt::skip] // explicit extern "Rust" is more clear here - unsafe { - // SAFETY: Calls foreign functions with the correct type signatures. - // Assumes that repr(Rust) enums are represented the same in this crate as in the external - // binary, which is the case in practice when the same compiler is used to compile the - // external crate. - - POSTMASTER_LIBRARY - .get_or_try_init(|| { - libloading::os::unix::Library::open( - Some(&postmaster_stub_built), - libloading::os::unix::RTLD_NOW | libloading::os::unix::RTLD_GLOBAL, - ) - }) - .wrap_err_with(|| format!("Couldn't libload {}", postmaster_stub_built.display()))?; - let lib = EXTENSION_LIBRARY - .get_or_try_init(|| { - libloading::os::unix::Library::open(Some(&lib_so), libloading::os::unix::RTLD_LAZY) - }) - .wrap_err_with(|| format!("Couldn't libload {}", lib_so.display()))?; - - let symbol: libloading::os::unix::Symbol< - unsafe extern "Rust" fn(_: ()) -> pgrx_sql_entity_graph::ControlFile, - > = lib - .get("__pgrx_marker".as_bytes()) - .expect("Couldn't call __pgrx_marker"); - let control_file_entity = pgrx_sql_entity_graph::SqlGraphEntity::ExtensionRoot( - symbol(()), - ); - entities.push(control_file_entity); - - for symbol_to_call in fns_to_call { - let symbol: libloading::os::unix::Symbol pgrx_sql_entity_graph::SqlGraphEntity> = - lib.get(symbol_to_call.as_bytes()).unwrap_or_else(|_| - panic!("Couldn't call {symbol_to_call:#?}")); - let entity = symbol(); - entities.push(entity); - } - }; + Ok(fns_to_call.into_iter().collect()) +} - let pgrx_sql = pgrx_sql_entity_graph::PgrxSql::build( - entities.into_iter(), - manifest.lib_name()?, - versioned_so, - ) - .wrap_err("SQL generation error")?; +fn first_build( + user_manifest_path: Option<&impl AsRef>, + profile: &CargoProfile, + features: &clap_cargo::Features, + log_level: Option, + is_test: bool, + features_arg: &str, + flags: &str, + package_name: &str, +) -> eyre::Result<()> { + let mut command = crate::env::cargo(); + command.stdin(Stdio::null()); + command.stdout(Stdio::null()); + command.stderr(Stdio::inherit()); + + if is_test { + command.arg("test"); + command.arg("--no-run"); + } else { + command.arg("build"); + } - if let Some(out_path) = path { - let out_path = out_path.as_ref(); + command.arg("--package"); + command.arg(format!("{package_name}")); - eprintln!( - "{} SQL entities to {}", - " Writing".bold().green(), - format_display_path(out_path)?.cyan() - ); + if let Some(user_manifest_path) = user_manifest_path.as_ref() { + command.arg("--manifest-path"); + command.arg(user_manifest_path.as_ref()); + } - if let Some(parent) = out_path.parent() { - std::fs::create_dir_all(parent).wrap_err("Could not create parent directory")? - } - pgrx_sql - .to_file(out_path) - .wrap_err_with(|| eyre!("Could not write SQL to {}", out_path.display()))?; - output_tracking.push(out_path.to_path_buf()); - } else { - eprintln!("{} SQL entities to {}", " Writing".bold().green(), "/dev/stdout".cyan()); - pgrx_sql - .write(&mut std::io::stdout()) - .wrap_err_with(|| eyre!("Could not write SQL to stdout"))?; + command.args(profile.cargo_args()); + + if let Some(log_level) = &log_level { + command.env("RUST_LOG", log_level); } - if let Some(dot_path) = dot { - let dot_path = dot_path.as_ref(); - tracing::info!(dot = %dot_path.display(), "Writing Graphviz DOT"); - pgrx_sql.to_dot(dot_path)?; + if !features_arg.trim().is_empty() { + command.arg("--features"); + command.arg(&features_arg); } - Ok(()) -} -#[tracing::instrument(level = "error", skip_all, fields( - postmaster_path = %format_display_path(postmaster_path.as_ref())?, - postmaster_stub_dir = %format_display_path(postmaster_stub_dir.as_ref())?, -))] -fn create_stub( - postmaster_path: impl AsRef, - postmaster_stub_dir: impl AsRef, -) -> eyre::Result { - let postmaster_path = postmaster_path.as_ref(); - let postmaster_stub_dir = postmaster_stub_dir.as_ref(); + if features.no_default_features { + command.arg("--no-default-features"); + } - let mut postmaster_stub_file = postmaster_stub_dir.to_path_buf(); - postmaster_stub_file.push("postmaster_stub.rs"); + if features.all_features { + command.arg("--all-features"); + } - let mut postmaster_hash_file = postmaster_stub_dir.to_path_buf(); - postmaster_hash_file.push("postmaster.hash"); + for arg in flags.split_ascii_whitespace() { + command.arg(arg); + } - let mut postmaster_stub_built = postmaster_stub_dir.to_path_buf(); - postmaster_stub_built.push("postmaster_stub.so"); + let command_str = format!("{:?}", command); + eprintln!( + "{} for SQL generation with features `{}`", + " Building".bold().green(), + features_arg, + ); - let postmaster_bin_data = - std::fs::read(postmaster_path).wrap_err("couldn't read postmaster")?; + tracing::debug!(command = %command_str, "Running"); + let cargo_output = + command.output().wrap_err_with(|| format!("failed to spawn cargo: {}", command_str))?; + tracing::trace!(status_code = %cargo_output.status, command = %command_str, "Finished"); - let mut hasher = std::collections::hash_map::DefaultHasher::new(); - postmaster_bin_data.hash(&mut hasher); - let postmaster_bin_hash = hasher.finish().to_string().into_bytes(); + if !cargo_output.status.success() { + // We explicitly do not want to return a spantraced error here. + std::process::exit(1) + } - let postmaster_hash_data = std::fs::read(&postmaster_hash_file).ok(); + Ok(()) +} - // Determine if we already built this stub. - if let Some(postmaster_hash_data) = postmaster_hash_data { - if postmaster_hash_data == postmaster_bin_hash && postmaster_stub_built.exists() { - // We already built this and it's up to date. - tracing::debug!(stub = %postmaster_stub_built.display(), "Existing stub for postmaster"); - return Ok(postmaster_stub_built); +fn compute_codegen( + package_manifest_path: impl AsRef, + symbols: &[String], + lib_name: &str, + path: Option, + dot: Option, +) -> eyre::Result { + use proc_macro2::{Ident, Span, TokenStream}; + let lib_name_ident = Ident::new(&lib_name, Span::call_site()); + + let inputs = { + let mut out = quote::quote! { + let mut entities = Vec::new(); + let control_file_entity = ::pgrx::pgrx_sql_entity_graph::SqlGraphEntity::ExtensionRoot(::#lib_name_ident::__pgrx_marker()); + entities.push(control_file_entity); + }; + for name in symbols.iter() { + let name_ident = Ident::new(name, Span::call_site()); + out.extend(quote::quote! { + extern "Rust" { + fn #name_ident() -> ::pgrx::pgrx_sql_entity_graph::SqlGraphEntity; + } + let entity = unsafe { #name_ident() }; + entities.push(entity); + }); + } + out + }; + let build = { + let versioned_so = get_property(&package_manifest_path, "module_pathname")?.is_none(); + quote::quote! { + let pgrx_sql = ::pgrx::pgrx_sql_entity_graph::PgrxSql::build( + entities.into_iter(), + #lib_name.to_string(), + #versioned_so, + ) + .expect("SQL generation error"); + } + }; + let outputs = { + let mut out = TokenStream::new(); + if let Some(path) = path { + let writing = " Writing".bold().green().to_string(); + out.extend(quote::quote! { + eprintln!("{} SQL entities to {}", #writing, #path); + pgrx_sql + .to_file(#path) + .expect(&format!("Could not write SQL to {}", #path)); + }); + } else { + let writing = " Writing".bold().green().to_string(); + out.extend(quote::quote! { + eprintln!("{} SQL entities to {}", #writing, "/dev/stdout",); + pgrx_sql + .write(&mut std::io::stdout()) + .expect("Could not write SQL to stdout"); + }); + } + if let Some(dot) = dot { + out.extend(quote::quote! { + pgrx_sql + .to_dot(#dot) + .expect("Could not write Graphviz DOT"); + }); + } + out + }; + Ok(quote::quote! { + fn main() { + #inputs + #build + #outputs } } + .to_string()) +} - let postmaster_obj_file = - parse_object(&postmaster_bin_data).wrap_err("couldn't parse postmaster")?; - let postmaster_exports = postmaster_obj_file - .exports() - .wrap_err("couldn't get exports from extension shared object")?; +fn second_build( + user_manifest_path: Option<&impl AsRef>, + profile: &CargoProfile, + features: &clap_cargo::Features, + log_level: Option, + features_arg: &str, + flags: &str, + embed_path: impl AsRef, + package_name: &str, +) -> eyre::Result<()> { + let mut command = crate::env::cargo(); + command.stdin(Stdio::null()); + command.stdout(Stdio::null()); + command.stderr(Stdio::inherit()); + + // We do pass cfg to the binary and do not pass cfg to dependencies to avoid recompilation + // The only cargo command respecting our need is `cargo rustc` + command.arg("rustc"); + command.arg("--bin"); + command.arg(format!("pgrx_embed_{package_name}")); + + command.arg("--package"); + command.arg(format!("{package_name}")); + + if let Some(user_manifest_path) = user_manifest_path.as_ref() { + command.arg("--manifest-path"); + command.arg(user_manifest_path.as_ref()); + } - let mut symbols_to_stub = HashSet::new(); - for export in postmaster_exports { - let name = std::str::from_utf8(export.name())?.to_string(); - #[cfg(target_os = "macos")] - let name = { - // Mac will prefix symbols with `_` automatically, so we remove it to avoid getting - // two. - let mut name = name; - let rename = name.split_off(1); - assert_eq!(name, "_"); - rename - }; - symbols_to_stub.insert(name); + command.args(profile.cargo_args()); + + if let Some(log_level) = &log_level { + command.env("RUST_LOG", log_level); } - tracing::debug!("Creating stub of appropriate PostgreSQL symbols"); - PgrxPgSysStub::from_symbols(&symbols_to_stub)?.write_to_file(&postmaster_stub_file)?; + if !features_arg.trim().is_empty() { + command.arg("--features"); + command.arg(&features_arg); + } - let mut so_rustc_invocation = crate::env::rustc(); - so_rustc_invocation.stderr(Stdio::inherit()); + if features.no_default_features { + command.arg("--no-default-features"); + } - if let Ok(rustc_flags_str) = std::env::var("RUSTFLAGS") { - let rustc_flags = rustc_flags_str.split_whitespace().collect::>(); - if !rustc_flags.is_empty() { - so_rustc_invocation.args(rustc_flags); - } + if features.all_features { + command.arg("--all-features"); } - so_rustc_invocation.args([ - "--crate-type", - "cdylib", - "-o", - postmaster_stub_built - .to_str() - .ok_or(eyre!("could not call postmaster_stub_built.to_str()"))?, - postmaster_stub_file - .to_str() - .ok_or(eyre!("could not call postmaster_stub_file.to_str()"))?, - ]); - - let so_rustc_invocation_str = format!("{so_rustc_invocation:?}"); - tracing::debug!(command = %so_rustc_invocation_str, "Running"); - let output = so_rustc_invocation.output().wrap_err_with(|| { - eyre!("could not invoke `rustc` on {}", postmaster_stub_file.display()) - })?; - - let code = output.status.code().ok_or(eyre!("could not get status code of build"))?; - tracing::trace!(status_code = %code, command = %so_rustc_invocation_str, "Finished"); - if code != 0 { - return Err(eyre!("rustc exited with code {code}")); + for arg in flags.split_ascii_whitespace() { + command.arg(arg); } - std::fs::write(&postmaster_hash_file, postmaster_bin_hash) - .wrap_err("could not write postmaster stub hash")?; + command.arg("--"); + + command.args(["--cfg", "pgrx_embed"]); - Ok(postmaster_stub_built) + command.env("PGRX_EMBED", embed_path.as_ref()); + + let command_str = format!("{:?}", command); + eprintln!( + "{} for SQL generation with features `{}`", + " Rebuilding".bold().green(), + features_arg, + ); + + tracing::debug!(command = %command_str, "Running"); + let cargo_output = + command.output().wrap_err_with(|| format!("failed to spawn cargo: {}", command_str))?; + tracing::trace!(status_code = %cargo_output.status, command = %command_str, "Finished"); + + if !cargo_output.status.success() { + // We explicitly do not want to return a spantraced error here. + std::process::exit(1) + } + + Ok(()) +} + +fn compute_sql(profile: &CargoProfile, package_name: &str) -> eyre::Result<()> { + let mut bin = get_target_dir()?; + bin.push(profile.target_subdir()); + bin.push(format!("pgrx_embed_{package_name}")); + + let mut command = std::process::Command::new(bin); + command.stdin(Stdio::inherit()); + command.stdout(Stdio::inherit()); + command.stderr(Stdio::inherit()); + + let command_str = format!("{:?}", command); + tracing::debug!(command = %command_str, "Running"); + let embed_output = command + .output() + .wrap_err_with(|| format!("failed to spawn pgrx_embed: {}", command_str))?; + tracing::trace!(status_code = %embed_output.status, command = %command_str, "Finished"); + + if !embed_output.status.success() { + // We do not want to return a spantraced error here, to + // (speculative:) reduce the likelihood of emitting errors twice + std::process::exit(1) + } + + Ok(()) } fn parse_object(data: &[u8]) -> object::Result { let kind = object::FileKind::parse(data)?; match kind { - FileKind::MachOFat32 => { - let arch = env::consts::ARCH; + object::FileKind::MachOFat32 => { + let arch = std::env::consts::ARCH; match slice_arch32(data, arch) { Some(slice) => parse_object(slice), @@ -578,6 +580,9 @@ fn parse_object(data: &[u8]) -> object::Result { } fn slice_arch32<'a>(data: &'a [u8], arch: &str) -> Option<&'a [u8]> { + use object::macho::FatHeader; + use object::read::macho::FatArch; + use object::Architecture; let target = match arch { "x86" => Architecture::I386, "x86_64" => Architecture::X86_64, diff --git a/cargo-pgrx/src/env.rs b/cargo-pgrx/src/env.rs index ea08b1f5a..ae03d7b69 100644 --- a/cargo-pgrx/src/env.rs +++ b/cargo-pgrx/src/env.rs @@ -12,11 +12,6 @@ pub(crate) fn cargo() -> std::process::Command { std::process::Command::new(cargo) } -pub(crate) fn rustc() -> std::process::Command { - let rustc = std::env::var_os("RUSTC").unwrap_or_else(|| "rustc".into()); - std::process::Command::new(rustc) -} - /// Set some environment variables for use downstream (in `pgrx-test` for /// example). Does nothing if already set. pub(crate) fn initialize() { diff --git a/cargo-pgrx/src/main.rs b/cargo-pgrx/src/main.rs index 6147cc27e..338f3df14 100644 --- a/cargo-pgrx/src/main.rs +++ b/cargo-pgrx/src/main.rs @@ -13,7 +13,6 @@ mod command; mod manifest; mod metadata; -mod pgrx_pg_sys_stub; pub(crate) mod env; pub(crate) mod profile; diff --git a/cargo-pgrx/src/pgrx_pg_sys_stub.rs b/cargo-pgrx/src/pgrx_pg_sys_stub.rs deleted file mode 100644 index e841c5ae6..000000000 --- a/cargo-pgrx/src/pgrx_pg_sys_stub.rs +++ /dev/null @@ -1,68 +0,0 @@ -//LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. -//LICENSE -//LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. -//LICENSE -//LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. -//LICENSE -//LICENSE All rights reserved. -//LICENSE -//LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. -use std::collections::HashSet; -use std::fs::File; -use std::io::Write; -use std::path::Path; -use syn::{parse_quote, Ident, Item}; - -/// A utility structure which can generate 'stubs' of the bindings generated by `pgrx-pg-sys`'s build script. -/// -/// These stubs can be built. -/// -/// For example, this is used by `cargo-pgrx` and then `dlopen`'d before the extension for SQL generation. -pub struct PgrxPgSysStub { - stub_file: syn::File, -} - -const SYMBOL_SKIP_LIST: [&str; 2] = ["_fini", "_init"]; - -impl PgrxPgSysStub { - #[tracing::instrument(level = "error", skip_all, fields(symbols = %symbols.len()))] - pub fn from_symbols(symbols: &HashSet) -> eyre::Result { - let mut items = Vec::with_capacity(symbols.len()); - for symbol in symbols.iter().filter(|v| !SYMBOL_SKIP_LIST.contains(&v.as_ref())) { - match stub_for_symbol(symbol) { - Ok(stub) => items.push(stub), - Err(_e) => tracing::trace!(%symbol, "Skipping, not a valid Rust ident"), - } - } - - let stub_file = syn::File { shebang: None, attrs: Default::default(), items }; - - Ok(Self { stub_file }) - } - - #[tracing::instrument(level = "error", skip_all, fields(pgrx_pg_sys_stub = %pgrx_pg_sys_stub.as_ref().display()))] - pub fn write_to_file(&self, pgrx_pg_sys_stub: impl AsRef) -> eyre::Result<()> { - let pgrx_pg_sys_stub = pgrx_pg_sys_stub.as_ref(); - if let Some(parent) = pgrx_pg_sys_stub.parent() { - std::fs::create_dir_all(parent)?; - } - let mut output_file = File::create(pgrx_pg_sys_stub)?; - let content = prettyplease::unparse(&self.stub_file); - output_file.write_all(content.as_bytes())?; - Ok(()) - } -} - -#[tracing::instrument] -fn stub_for_symbol(name: &str) -> eyre::Result { - let ident = syn::parse_str::(name)?; - let item_fn: syn::ItemFn = parse_quote! { - #[allow(dead_code)] - #[allow(non_snake_case)] - #[no_mangle] - extern "C" fn #ident() { - unimplemented!(concat!(stringify!(#name), " is stubbed and cannot be used right now.")); - } - }; - Ok(Item::Fn(item_fn)) -} diff --git a/cargo-pgrx/src/templates/cargo_toml b/cargo-pgrx/src/templates/cargo_toml index 7e4b053d8..efd14967d 100644 --- a/cargo-pgrx/src/templates/cargo_toml +++ b/cargo-pgrx/src/templates/cargo_toml @@ -4,7 +4,11 @@ version = "0.0.0" edition = "2021" [lib] -crate-type = ["cdylib"] +crate-type = ["cdylib", "lib"] + +[[bin]] +name = "pgrx_embed_{name}" +path = "./src/bin/pgrx_embed.rs" [features] default = ["pg13"] diff --git a/cargo-pgrx/src/templates/pgrx_embed_rs b/cargo-pgrx/src/templates/pgrx_embed_rs new file mode 100644 index 000000000..57483f108 --- /dev/null +++ b/cargo-pgrx/src/templates/pgrx_embed_rs @@ -0,0 +1 @@ +::pgrx::pgrx_embed!(); \ No newline at end of file diff --git a/pgrx-examples/aggregate/Cargo.toml b/pgrx-examples/aggregate/Cargo.toml index 2e9f72122..f91c2f172 100644 --- a/pgrx-examples/aggregate/Cargo.toml +++ b/pgrx-examples/aggregate/Cargo.toml @@ -15,7 +15,11 @@ edition = "2021" publish = false [lib] -crate-type = ["cdylib"] +crate-type = ["cdylib", "lib"] + +[[bin]] +name = "pgrx_embed_aggregate" +path = "./src/bin/pgrx_embed.rs" [features] default = ["pg13"] diff --git a/pgrx-examples/aggregate/src/bin/pgrx_embed.rs b/pgrx-examples/aggregate/src/bin/pgrx_embed.rs new file mode 100644 index 000000000..5f5c4d858 --- /dev/null +++ b/pgrx-examples/aggregate/src/bin/pgrx_embed.rs @@ -0,0 +1 @@ +::pgrx::pgrx_embed!(); diff --git a/pgrx-examples/arrays/Cargo.toml b/pgrx-examples/arrays/Cargo.toml index 03c2c4c1e..04f9e9b63 100644 --- a/pgrx-examples/arrays/Cargo.toml +++ b/pgrx-examples/arrays/Cargo.toml @@ -15,7 +15,11 @@ edition = "2021" publish = false [lib] -crate-type = ["cdylib"] +crate-type = ["cdylib", "lib"] + +[[bin]] +name = "pgrx_embed_arrays" +path = "./src/bin/pgrx_embed.rs" [features] default = ["pg13"] diff --git a/pgrx-examples/arrays/src/bin/pgrx_embed.rs b/pgrx-examples/arrays/src/bin/pgrx_embed.rs new file mode 100644 index 000000000..5f5c4d858 --- /dev/null +++ b/pgrx-examples/arrays/src/bin/pgrx_embed.rs @@ -0,0 +1 @@ +::pgrx::pgrx_embed!(); diff --git a/pgrx-examples/bad_ideas/Cargo.toml b/pgrx-examples/bad_ideas/Cargo.toml index 6d862ae8f..7eda5b911 100644 --- a/pgrx-examples/bad_ideas/Cargo.toml +++ b/pgrx-examples/bad_ideas/Cargo.toml @@ -15,7 +15,11 @@ edition = "2021" publish = false [lib] -crate-type = ["cdylib"] +crate-type = ["cdylib", "lib"] + +[[bin]] +name = "pgrx_embed_bad_ideas" +path = "./src/bin/pgrx_embed.rs" [features] default = ["pg13"] diff --git a/pgrx-examples/bad_ideas/src/bin/pgrx_embed.rs b/pgrx-examples/bad_ideas/src/bin/pgrx_embed.rs new file mode 100644 index 000000000..5f5c4d858 --- /dev/null +++ b/pgrx-examples/bad_ideas/src/bin/pgrx_embed.rs @@ -0,0 +1 @@ +::pgrx::pgrx_embed!(); diff --git a/pgrx-examples/bgworker/Cargo.toml b/pgrx-examples/bgworker/Cargo.toml index 4bd4f6eb7..0b0dc4b94 100644 --- a/pgrx-examples/bgworker/Cargo.toml +++ b/pgrx-examples/bgworker/Cargo.toml @@ -15,7 +15,11 @@ edition = "2021" publish = false [lib] -crate-type = ["cdylib"] +crate-type = ["cdylib", "lib"] + +[[bin]] +name = "pgrx_embed_bgworker" +path = "./src/bin/pgrx_embed.rs" [features] default = ["pg13"] diff --git a/pgrx-examples/bgworker/src/bin/pgrx_embed.rs b/pgrx-examples/bgworker/src/bin/pgrx_embed.rs new file mode 100644 index 000000000..5f5c4d858 --- /dev/null +++ b/pgrx-examples/bgworker/src/bin/pgrx_embed.rs @@ -0,0 +1 @@ +::pgrx::pgrx_embed!(); diff --git a/pgrx-examples/bytea/Cargo.toml b/pgrx-examples/bytea/Cargo.toml index f50c33888..4a6806212 100644 --- a/pgrx-examples/bytea/Cargo.toml +++ b/pgrx-examples/bytea/Cargo.toml @@ -15,7 +15,11 @@ edition = "2021" publish = false [lib] -crate-type = ["cdylib"] +crate-type = ["cdylib", "lib"] + +[[bin]] +name = "pgrx_embed_bytea" +path = "./src/bin/pgrx_embed.rs" [features] default = ["pg13"] diff --git a/pgrx-examples/bytea/src/bin/pgrx_embed.rs b/pgrx-examples/bytea/src/bin/pgrx_embed.rs new file mode 100644 index 000000000..5f5c4d858 --- /dev/null +++ b/pgrx-examples/bytea/src/bin/pgrx_embed.rs @@ -0,0 +1 @@ +::pgrx::pgrx_embed!(); diff --git a/pgrx-examples/composite_type/Cargo.toml b/pgrx-examples/composite_type/Cargo.toml index 6d322a9b9..5e9e7c79c 100644 --- a/pgrx-examples/composite_type/Cargo.toml +++ b/pgrx-examples/composite_type/Cargo.toml @@ -15,7 +15,11 @@ edition = "2021" publish = false [lib] -crate-type = ["cdylib"] +crate-type = ["cdylib", "lib"] + +[[bin]] +name = "pgrx_embed_composite_type" +path = "./src/bin/pgrx_embed.rs" [features] default = ["pg13"] diff --git a/pgrx-examples/composite_type/src/bin/pgrx_embed.rs b/pgrx-examples/composite_type/src/bin/pgrx_embed.rs new file mode 100644 index 000000000..5f5c4d858 --- /dev/null +++ b/pgrx-examples/composite_type/src/bin/pgrx_embed.rs @@ -0,0 +1 @@ +::pgrx::pgrx_embed!(); diff --git a/pgrx-examples/custom_libname/Cargo.toml b/pgrx-examples/custom_libname/Cargo.toml index 0eb504f3d..b24057d7d 100644 --- a/pgrx-examples/custom_libname/Cargo.toml +++ b/pgrx-examples/custom_libname/Cargo.toml @@ -15,9 +15,13 @@ edition = "2021" publish = false [lib] -crate-type = ["cdylib"] +crate-type = ["cdylib", "lib"] name = "other_name" +[[bin]] +name = "pgrx_embed_custom_libname" +path = "./src/bin/pgrx_embed.rs" + [features] default = ["pg13"] pg12 = ["pgrx/pg12", "pgrx-tests/pg12" ] diff --git a/pgrx-examples/custom_libname/src/bin/pgrx_embed.rs b/pgrx-examples/custom_libname/src/bin/pgrx_embed.rs new file mode 100644 index 000000000..5f5c4d858 --- /dev/null +++ b/pgrx-examples/custom_libname/src/bin/pgrx_embed.rs @@ -0,0 +1 @@ +::pgrx::pgrx_embed!(); diff --git a/pgrx-examples/custom_sql/Cargo.toml b/pgrx-examples/custom_sql/Cargo.toml index 173cdcaec..5636cba9c 100644 --- a/pgrx-examples/custom_sql/Cargo.toml +++ b/pgrx-examples/custom_sql/Cargo.toml @@ -15,7 +15,11 @@ edition = "2021" publish = false [lib] -crate-type = ["cdylib"] +crate-type = ["cdylib", "lib"] + +[[bin]] +name = "pgrx_embed_custom_sql" +path = "./src/bin/pgrx_embed.rs" [features] default = ["pg13"] diff --git a/pgrx-examples/custom_sql/src/bin/pgrx_embed.rs b/pgrx-examples/custom_sql/src/bin/pgrx_embed.rs new file mode 100644 index 000000000..5f5c4d858 --- /dev/null +++ b/pgrx-examples/custom_sql/src/bin/pgrx_embed.rs @@ -0,0 +1 @@ +::pgrx::pgrx_embed!(); diff --git a/pgrx-examples/custom_types/Cargo.toml b/pgrx-examples/custom_types/Cargo.toml index a1e9aa44f..5dbac2927 100644 --- a/pgrx-examples/custom_types/Cargo.toml +++ b/pgrx-examples/custom_types/Cargo.toml @@ -15,7 +15,11 @@ edition = "2021" publish = false [lib] -crate-type = ["cdylib"] +crate-type = ["cdylib", "lib"] + +[[bin]] +name = "pgrx_embed_custom_types" +path = "./src/bin/pgrx_embed.rs" [features] default = ["pg13"] diff --git a/pgrx-examples/custom_types/src/bin/pgrx_embed.rs b/pgrx-examples/custom_types/src/bin/pgrx_embed.rs new file mode 100644 index 000000000..5f5c4d858 --- /dev/null +++ b/pgrx-examples/custom_types/src/bin/pgrx_embed.rs @@ -0,0 +1 @@ +::pgrx::pgrx_embed!(); diff --git a/pgrx-examples/datetime/Cargo.toml b/pgrx-examples/datetime/Cargo.toml index 4ae82bd39..85eea0867 100644 --- a/pgrx-examples/datetime/Cargo.toml +++ b/pgrx-examples/datetime/Cargo.toml @@ -15,7 +15,11 @@ edition = "2021" publish = false [lib] -crate-type = ["cdylib"] +crate-type = ["cdylib", "lib"] + +[[bin]] +name = "pgrx_embed_datetime" +path = "./src/bin/pgrx_embed.rs" [features] default = ["pg13"] diff --git a/pgrx-examples/datetime/src/bin/pgrx_embed.rs b/pgrx-examples/datetime/src/bin/pgrx_embed.rs new file mode 100644 index 000000000..5f5c4d858 --- /dev/null +++ b/pgrx-examples/datetime/src/bin/pgrx_embed.rs @@ -0,0 +1 @@ +::pgrx::pgrx_embed!(); diff --git a/pgrx-examples/errors/Cargo.toml b/pgrx-examples/errors/Cargo.toml index 024859f39..0fe9ddc93 100644 --- a/pgrx-examples/errors/Cargo.toml +++ b/pgrx-examples/errors/Cargo.toml @@ -15,7 +15,11 @@ edition = "2021" publish = false [lib] -crate-type = ["cdylib"] +crate-type = ["cdylib", "lib"] + +[[bin]] +name = "pgrx_embed_errors" +path = "./src/bin/pgrx_embed.rs" [features] default = ["pg13"] diff --git a/pgrx-examples/errors/src/bin/pgrx_embed.rs b/pgrx-examples/errors/src/bin/pgrx_embed.rs new file mode 100644 index 000000000..5f5c4d858 --- /dev/null +++ b/pgrx-examples/errors/src/bin/pgrx_embed.rs @@ -0,0 +1 @@ +::pgrx::pgrx_embed!(); diff --git a/pgrx-examples/nostd/Cargo.toml b/pgrx-examples/nostd/Cargo.toml index ecfb6d5e4..d051829ad 100644 --- a/pgrx-examples/nostd/Cargo.toml +++ b/pgrx-examples/nostd/Cargo.toml @@ -15,7 +15,11 @@ edition = "2021" publish = false [lib] -crate-type = ["cdylib"] +crate-type = ["cdylib", "lib"] + +[[bin]] +name = "pgrx_embed_nostd" +path = "./src/bin/pgrx_embed.rs" [features] default = ["pg13"] diff --git a/pgrx-examples/nostd/src/bin/pgrx_embed.rs b/pgrx-examples/nostd/src/bin/pgrx_embed.rs new file mode 100644 index 000000000..5f5c4d858 --- /dev/null +++ b/pgrx-examples/nostd/src/bin/pgrx_embed.rs @@ -0,0 +1 @@ +::pgrx::pgrx_embed!(); diff --git a/pgrx-examples/numeric/Cargo.toml b/pgrx-examples/numeric/Cargo.toml index df425bb14..e282d0f2f 100644 --- a/pgrx-examples/numeric/Cargo.toml +++ b/pgrx-examples/numeric/Cargo.toml @@ -16,7 +16,11 @@ publish = false rust-version = "1.58" [lib] -crate-type = ["cdylib"] +crate-type = ["cdylib", "lib"] + +[[bin]] +name = "pgrx_embed_numeric" +path = "./src/bin/pgrx_embed.rs" [features] default = ["pg13"] diff --git a/pgrx-examples/numeric/src/bin/pgrx_embed.rs b/pgrx-examples/numeric/src/bin/pgrx_embed.rs new file mode 100644 index 000000000..5f5c4d858 --- /dev/null +++ b/pgrx-examples/numeric/src/bin/pgrx_embed.rs @@ -0,0 +1 @@ +::pgrx::pgrx_embed!(); diff --git a/pgrx-examples/operators/Cargo.toml b/pgrx-examples/operators/Cargo.toml index 9937a261a..364d5dd97 100644 --- a/pgrx-examples/operators/Cargo.toml +++ b/pgrx-examples/operators/Cargo.toml @@ -15,7 +15,11 @@ edition = "2021" publish = false [lib] -crate-type = ["cdylib"] +crate-type = ["cdylib", "lib"] + +[[bin]] +name = "pgrx_embed_operators" +path = "./src/bin/pgrx_embed.rs" [features] default = ["pg13"] diff --git a/pgrx-examples/operators/src/bin/pgrx_embed.rs b/pgrx-examples/operators/src/bin/pgrx_embed.rs new file mode 100644 index 000000000..5f5c4d858 --- /dev/null +++ b/pgrx-examples/operators/src/bin/pgrx_embed.rs @@ -0,0 +1 @@ +::pgrx::pgrx_embed!(); diff --git a/pgrx-examples/pgtrybuilder/Cargo.toml b/pgrx-examples/pgtrybuilder/Cargo.toml index 610a126f2..67cbde562 100644 --- a/pgrx-examples/pgtrybuilder/Cargo.toml +++ b/pgrx-examples/pgtrybuilder/Cargo.toml @@ -15,7 +15,11 @@ edition = "2021" publish = false [lib] -crate-type = ["cdylib"] +crate-type = ["cdylib", "lib"] + +[[bin]] +name = "pgrx_embed_pgtrybuilder" +path = "./src/bin/pgrx_embed.rs" [features] default = ["pg13"] diff --git a/pgrx-examples/pgtrybuilder/src/bin/pgrx_embed.rs b/pgrx-examples/pgtrybuilder/src/bin/pgrx_embed.rs new file mode 100644 index 000000000..5f5c4d858 --- /dev/null +++ b/pgrx-examples/pgtrybuilder/src/bin/pgrx_embed.rs @@ -0,0 +1 @@ +::pgrx::pgrx_embed!(); diff --git a/pgrx-examples/range/Cargo.toml b/pgrx-examples/range/Cargo.toml index 4741cfb58..13f156471 100644 --- a/pgrx-examples/range/Cargo.toml +++ b/pgrx-examples/range/Cargo.toml @@ -15,7 +15,11 @@ edition = "2021" publish = false [lib] -crate-type = ["cdylib"] +crate-type = ["cdylib", "lib"] + +[[bin]] +name = "pgrx_embed_range" +path = "./src/bin/pgrx_embed.rs" [features] default = ["pg13"] diff --git a/pgrx-examples/range/src/bin/pgrx_embed.rs b/pgrx-examples/range/src/bin/pgrx_embed.rs new file mode 100644 index 000000000..5f5c4d858 --- /dev/null +++ b/pgrx-examples/range/src/bin/pgrx_embed.rs @@ -0,0 +1 @@ +::pgrx::pgrx_embed!(); diff --git a/pgrx-examples/schemas/Cargo.toml b/pgrx-examples/schemas/Cargo.toml index c412672c0..e32af0412 100644 --- a/pgrx-examples/schemas/Cargo.toml +++ b/pgrx-examples/schemas/Cargo.toml @@ -15,7 +15,11 @@ edition = "2021" publish = false [lib] -crate-type = ["cdylib"] +crate-type = ["cdylib", "lib"] + +[[bin]] +name = "pgrx_embed_schemas" +path = "./src/bin/pgrx_embed.rs" [features] default = ["pg13"] diff --git a/pgrx-examples/schemas/src/bin/pgrx_embed.rs b/pgrx-examples/schemas/src/bin/pgrx_embed.rs new file mode 100644 index 000000000..5f5c4d858 --- /dev/null +++ b/pgrx-examples/schemas/src/bin/pgrx_embed.rs @@ -0,0 +1 @@ +::pgrx::pgrx_embed!(); diff --git a/pgrx-examples/shmem/Cargo.toml b/pgrx-examples/shmem/Cargo.toml index 6fab6fa61..827408c8c 100644 --- a/pgrx-examples/shmem/Cargo.toml +++ b/pgrx-examples/shmem/Cargo.toml @@ -15,7 +15,11 @@ edition = "2021" publish = false [lib] -crate-type = ["cdylib"] +crate-type = ["cdylib", "lib"] + +[[bin]] +name = "pgrx_embed_shmem" +path = "./src/bin/pgrx_embed.rs" [features] default = ["pg13"] diff --git a/pgrx-examples/shmem/src/bin/pgrx_embed.rs b/pgrx-examples/shmem/src/bin/pgrx_embed.rs new file mode 100644 index 000000000..5f5c4d858 --- /dev/null +++ b/pgrx-examples/shmem/src/bin/pgrx_embed.rs @@ -0,0 +1 @@ +::pgrx::pgrx_embed!(); diff --git a/pgrx-examples/spi/Cargo.toml b/pgrx-examples/spi/Cargo.toml index f87d378e6..350a97bf0 100644 --- a/pgrx-examples/spi/Cargo.toml +++ b/pgrx-examples/spi/Cargo.toml @@ -15,7 +15,11 @@ edition = "2021" publish = false [lib] -crate-type = ["cdylib"] +crate-type = ["cdylib", "lib"] + +[[bin]] +name = "pgrx_embed_spi" +path = "./src/bin/pgrx_embed.rs" [features] default = ["pg13"] diff --git a/pgrx-examples/spi/src/bin/pgrx_embed.rs b/pgrx-examples/spi/src/bin/pgrx_embed.rs new file mode 100644 index 000000000..5f5c4d858 --- /dev/null +++ b/pgrx-examples/spi/src/bin/pgrx_embed.rs @@ -0,0 +1 @@ +::pgrx::pgrx_embed!(); diff --git a/pgrx-examples/spi_srf/Cargo.toml b/pgrx-examples/spi_srf/Cargo.toml index 5972a0e18..a53a628fd 100644 --- a/pgrx-examples/spi_srf/Cargo.toml +++ b/pgrx-examples/spi_srf/Cargo.toml @@ -16,7 +16,11 @@ publish = false rust-version = "1.58" [lib] -crate-type = ["cdylib"] +crate-type = ["cdylib", "lib"] + +[[bin]] +name = "pgrx_embed_spi_srf" +path = "./src/bin/pgrx_embed.rs" [features] default = ["pg13"] diff --git a/pgrx-examples/spi_srf/src/bin/pgrx_embed.rs b/pgrx-examples/spi_srf/src/bin/pgrx_embed.rs new file mode 100644 index 000000000..5f5c4d858 --- /dev/null +++ b/pgrx-examples/spi_srf/src/bin/pgrx_embed.rs @@ -0,0 +1 @@ +::pgrx::pgrx_embed!(); diff --git a/pgrx-examples/srf/Cargo.toml b/pgrx-examples/srf/Cargo.toml index 899ae3c9c..bcb7cffb2 100644 --- a/pgrx-examples/srf/Cargo.toml +++ b/pgrx-examples/srf/Cargo.toml @@ -15,7 +15,11 @@ edition = "2021" publish = false [lib] -crate-type = ["cdylib"] +crate-type = ["cdylib", "lib"] + +[[bin]] +name = "pgrx_embed_srf" +path = "./src/bin/pgrx_embed.rs" [features] default = ["pg13"] diff --git a/pgrx-examples/srf/src/bin/pgrx_embed.rs b/pgrx-examples/srf/src/bin/pgrx_embed.rs new file mode 100644 index 000000000..5f5c4d858 --- /dev/null +++ b/pgrx-examples/srf/src/bin/pgrx_embed.rs @@ -0,0 +1 @@ +::pgrx::pgrx_embed!(); diff --git a/pgrx-examples/strings/Cargo.toml b/pgrx-examples/strings/Cargo.toml index e69921719..6ff957b8b 100644 --- a/pgrx-examples/strings/Cargo.toml +++ b/pgrx-examples/strings/Cargo.toml @@ -15,7 +15,11 @@ edition = "2021" publish = false [lib] -crate-type = ["cdylib"] +crate-type = ["cdylib", "lib"] + +[[bin]] +name = "pgrx_embed_strings" +path = "./src/bin/pgrx_embed.rs" [features] default = ["pg13"] diff --git a/pgrx-examples/strings/src/bin/pgrx_embed.rs b/pgrx-examples/strings/src/bin/pgrx_embed.rs new file mode 100644 index 000000000..5f5c4d858 --- /dev/null +++ b/pgrx-examples/strings/src/bin/pgrx_embed.rs @@ -0,0 +1 @@ +::pgrx::pgrx_embed!(); diff --git a/pgrx-examples/triggers/Cargo.toml b/pgrx-examples/triggers/Cargo.toml index 873b2ed0a..906ac269e 100644 --- a/pgrx-examples/triggers/Cargo.toml +++ b/pgrx-examples/triggers/Cargo.toml @@ -15,7 +15,11 @@ edition = "2021" publish = false [lib] -crate-type = ["cdylib"] +crate-type = ["cdylib", "lib"] + +[[bin]] +name = "pgrx_embed_triggers" +path = "./src/bin/pgrx_embed.rs" [features] default = ["pg13"] diff --git a/pgrx-examples/triggers/src/bin/pgrx_embed.rs b/pgrx-examples/triggers/src/bin/pgrx_embed.rs new file mode 100644 index 000000000..5f5c4d858 --- /dev/null +++ b/pgrx-examples/triggers/src/bin/pgrx_embed.rs @@ -0,0 +1 @@ +::pgrx::pgrx_embed!(); diff --git a/pgrx-examples/versioned_custom_libname_so/Cargo.toml b/pgrx-examples/versioned_custom_libname_so/Cargo.toml index e50800132..2054735ac 100644 --- a/pgrx-examples/versioned_custom_libname_so/Cargo.toml +++ b/pgrx-examples/versioned_custom_libname_so/Cargo.toml @@ -15,9 +15,13 @@ edition = "2021" publish = false [lib] -crate-type = ["cdylib"] +crate-type = ["cdylib", "lib"] name = "versioned_othername" +[[bin]] +name = "pgrx_embed_versioned_custom_libname_so" +path = "./src/bin/pgrx_embed.rs" + [features] default = ["pg13"] pg12 = ["pgrx/pg12", "pgrx-tests/pg12" ] diff --git a/pgrx-examples/versioned_custom_libname_so/src/bin/pgrx_embed.rs b/pgrx-examples/versioned_custom_libname_so/src/bin/pgrx_embed.rs new file mode 100644 index 000000000..5f5c4d858 --- /dev/null +++ b/pgrx-examples/versioned_custom_libname_so/src/bin/pgrx_embed.rs @@ -0,0 +1 @@ +::pgrx::pgrx_embed!(); diff --git a/pgrx-examples/versioned_so/Cargo.toml b/pgrx-examples/versioned_so/Cargo.toml index 6ed466e5c..367f7f6ce 100644 --- a/pgrx-examples/versioned_so/Cargo.toml +++ b/pgrx-examples/versioned_so/Cargo.toml @@ -15,7 +15,11 @@ edition = "2021" publish = false [lib] -crate-type = ["cdylib"] +crate-type = ["cdylib", "lib"] + +[[bin]] +name = "pgrx_embed_versioned_so" +path = "./src/bin/pgrx_embed.rs" [features] default = ["pg13"] diff --git a/pgrx-examples/versioned_so/src/bin/pgrx_embed.rs b/pgrx-examples/versioned_so/src/bin/pgrx_embed.rs new file mode 100644 index 000000000..5f5c4d858 --- /dev/null +++ b/pgrx-examples/versioned_so/src/bin/pgrx_embed.rs @@ -0,0 +1 @@ +::pgrx::pgrx_embed!(); diff --git a/pgrx-sql-entity-graph/src/extension_sql/mod.rs b/pgrx-sql-entity-graph/src/extension_sql/mod.rs index 372a08e1e..aec432112 100644 --- a/pgrx-sql-entity-graph/src/extension_sql/mod.rs +++ b/pgrx-sql-entity-graph/src/extension_sql/mod.rs @@ -196,6 +196,7 @@ impl ToEntityGraphTokens for ExtensionSql { syn::Ident::new(&format!("__pgrx_internals_sql_{}", name.value()), Span::call_site()); quote! { #[no_mangle] + #[doc(hidden)] #[allow(unknown_lints, clippy::no_mangle_with_rust_abi)] pub extern "Rust" fn #sql_graph_entity_fn_name() -> ::pgrx::pgrx_sql_entity_graph::SqlGraphEntity { extern crate alloc; diff --git a/pgrx-sql-entity-graph/src/metadata/function_metadata.rs b/pgrx-sql-entity-graph/src/metadata/function_metadata.rs index 49e78051c..d5b072469 100644 --- a/pgrx-sql-entity-graph/src/metadata/function_metadata.rs +++ b/pgrx-sql-entity-graph/src/metadata/function_metadata.rs @@ -16,8 +16,7 @@ to the `pgrx` framework and very subject to change between versions. While you m */ -use super::{FunctionMetadataEntity, PhantomDataExt, SqlTranslatable}; -use core::marker::PhantomData; +use super::{FunctionMetadataEntity, SqlTranslatable}; /** Provide SQL generation related information on functions @@ -27,8 +26,7 @@ use pgrx_sql_entity_graph::metadata::{FunctionMetadata, Returns, SqlMapping}; fn floof(i: i32) -> String { todo!() } type FunctionPointer = fn(i32) -> String; -let marker: FunctionPointer = floof; -let metadata = pgrx_sql_entity_graph::metadata::FunctionMetadata::entity(&marker); +let metadata = FunctionPointer::entity(); assert_eq!( metadata.retval.return_sql, Ok(Returns::One(SqlMapping::As("TEXT".to_string()))), @@ -36,10 +34,10 @@ assert_eq!( ``` */ pub trait FunctionMetadata { - fn path(&self) -> &'static str { + fn path() -> &'static str { core::any::type_name::() } - fn entity(&self) -> FunctionMetadataEntity; + fn entity() -> FunctionMetadataEntity; } macro_rules! impl_fn { @@ -50,11 +48,11 @@ macro_rules! impl_fn { R: SqlTranslatable, F: FnMut($($A,)*) -> R, { - fn entity(&self) -> FunctionMetadataEntity { + fn entity() -> FunctionMetadataEntity { FunctionMetadataEntity { - arguments: vec![$(PhantomData::<$A>.entity()),*], - retval: PhantomData::.entity(), - path: self.path(), + arguments: vec![$(<$A>::entity()),*], + retval: R::entity(), + path: core::any::type_name::(), } } } @@ -63,11 +61,11 @@ macro_rules! impl_fn { $($A: SqlTranslatable,)* R: SqlTranslatable, { - fn entity(&self) -> FunctionMetadataEntity { + fn entity() -> FunctionMetadataEntity { FunctionMetadataEntity { - arguments: vec![$(PhantomData::<$A>.entity()),*], - retval: PhantomData::.entity(), - path: self.path(), + arguments: vec![$(<$A>::entity()),*], + retval: R::entity(), + path: core::any::type_name::(), } } } diff --git a/pgrx-sql-entity-graph/src/metadata/mod.rs b/pgrx-sql-entity-graph/src/metadata/mod.rs index e19946941..b1b422072 100644 --- a/pgrx-sql-entity-graph/src/metadata/mod.rs +++ b/pgrx-sql-entity-graph/src/metadata/mod.rs @@ -19,12 +19,10 @@ to the `pgrx` framework and very subject to change between versions. While you m mod entity; mod function_metadata; -mod phantomdata_ext; mod return_variant; mod sql_translatable; pub use entity::{FunctionMetadataEntity, FunctionMetadataTypeEntity}; pub use function_metadata::FunctionMetadata; -pub use phantomdata_ext::PhantomDataExt; pub use return_variant::{Returns, ReturnsError}; pub use sql_translatable::{ArgumentError, SqlMapping, SqlTranslatable}; diff --git a/pgrx-sql-entity-graph/src/metadata/phantomdata_ext.rs b/pgrx-sql-entity-graph/src/metadata/phantomdata_ext.rs deleted file mode 100644 index 7e8112bdf..000000000 --- a/pgrx-sql-entity-graph/src/metadata/phantomdata_ext.rs +++ /dev/null @@ -1,59 +0,0 @@ -//LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. -//LICENSE -//LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. -//LICENSE -//LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. -//LICENSE -//LICENSE All rights reserved. -//LICENSE -//LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. -/*! - -Zero sized type marker metadata for Rust to SQL translation - -> Like all of the [`sql_entity_graph`][crate] APIs, this is considered **internal** -to the `pgrx` framework and very subject to change between versions. While you may use this, please do it with caution. - -*/ -use core::marker::PhantomData; - -use super::return_variant::ReturnsError; -use super::{ArgumentError, FunctionMetadataTypeEntity, Returns, SqlMapping, SqlTranslatable}; - -/** -An extension trait for [`PhantomData`] offering SQL generation related info - -Since we don't actually want to construct values during SQL generation, we use a [`PhantomData`]. - */ -pub trait PhantomDataExt { - fn type_name(&self) -> &'static str; - fn argument_sql(&self) -> Result; - fn return_sql(&self) -> Result; - fn variadic(&self) -> bool; - fn optional(&self) -> bool; - fn entity(&self) -> FunctionMetadataTypeEntity; -} - -impl PhantomDataExt for PhantomData -where - T: SqlTranslatable, -{ - fn type_name(&self) -> &'static str { - T::type_name() - } - fn argument_sql(&self) -> Result { - T::argument_sql() - } - fn return_sql(&self) -> Result { - T::return_sql() - } - fn variadic(&self) -> bool { - T::variadic() - } - fn optional(&self) -> bool { - T::optional() - } - fn entity(&self) -> FunctionMetadataTypeEntity { - T::entity() - } -} diff --git a/pgrx-sql-entity-graph/src/pg_extern/mod.rs b/pgrx-sql-entity-graph/src/pg_extern/mod.rs index b40be182c..aad789dc6 100644 --- a/pgrx-sql-entity-graph/src/pg_extern/mod.rs +++ b/pgrx-sql-entity-graph/src/pg_extern/mod.rs @@ -320,14 +320,13 @@ impl PgExtern { extern crate alloc; #[allow(unused_imports)] use alloc::{vec, vec::Vec}; - type FunctionPointer = #hrtb #unsafety fn (#( #input_types ),*) #return_type; - let metadata: FunctionPointer = #ident; + type FunctionPointer = #hrtb #unsafety fn(#( #input_types ),*) #return_type; let submission = ::pgrx::pgrx_sql_entity_graph::PgExternEntity { name: #name, unaliased_name: stringify!(#ident), module_path: core::module_path!(), full_path: concat!(core::module_path!(), "::", stringify!(#ident)), - metadata: ::pgrx::pgrx_sql_entity_graph::metadata::FunctionMetadata::entity(&metadata), + metadata: >::entity(), fn_args: vec![#(#inputs_iter),*], fn_return: #returns, #[allow(clippy::or_fun_call)] diff --git a/pgrx-sql-entity-graph/src/used_type.rs b/pgrx-sql-entity-graph/src/used_type.rs index 925714f24..35796fa0e 100644 --- a/pgrx-sql-entity-graph/src/used_type.rs +++ b/pgrx-sql-entity-graph/src/used_type.rs @@ -342,9 +342,8 @@ impl UsedType { /// Set via the type being an `Option`. optional: #optional, metadata: { - use ::pgrx::pgrx_sql_entity_graph::metadata::PhantomDataExt; - let marker: core::marker::PhantomData<#resolved_ty> = core::marker::PhantomData; - marker.entity() + use ::pgrx::pgrx_sql_entity_graph::metadata::SqlTranslatable; + <#resolved_ty>::entity() }, } } diff --git a/pgrx-tests/Cargo.toml b/pgrx-tests/Cargo.toml index 9f84b7a37..2816e3457 100644 --- a/pgrx-tests/Cargo.toml +++ b/pgrx-tests/Cargo.toml @@ -23,6 +23,10 @@ edition = "2021" [lib] crate-type = [ "cdylib", "lib" ] +[[bin]] +name = "pgrx_embed_pgrx-tests" +path = "./src/bin/pgrx_embed.rs" + [features] default = [ "proptest" ] pg12 = [ "pgrx/pg12" ] diff --git a/pgrx-tests/src/bin/pgrx_embed.rs b/pgrx-tests/src/bin/pgrx_embed.rs new file mode 100644 index 000000000..5f5c4d858 --- /dev/null +++ b/pgrx-tests/src/bin/pgrx_embed.rs @@ -0,0 +1 @@ +::pgrx::pgrx_embed!(); diff --git a/pgrx/src/lib.rs b/pgrx/src/lib.rs index 6c3c78e3a..0c5e3ad25 100644 --- a/pgrx/src/lib.rs +++ b/pgrx/src/lib.rs @@ -275,12 +275,8 @@ macro_rules! pg_magic_func { macro_rules! pg_sql_graph_magic { () => { // A marker which must exist in the root of the extension. -#[no_mangle] #[doc(hidden)] - #[rustfmt::skip] // explicit extern "Rust" is more clear here - pub extern "Rust" fn __pgrx_marker( - _: (), - ) -> $crate::pgrx_sql_entity_graph::ControlFile { + pub fn __pgrx_marker() -> $crate::pgrx_sql_entity_graph::ControlFile { use ::core::convert::TryFrom; let package_version = env!("CARGO_PKG_VERSION"); let context = include_str!(concat!( @@ -328,3 +324,19 @@ pub(crate) enum Utf8Compat { /// An "extended ASCII" encoding, so we're fine if we only touch ASCII Ascii, } + +/// Entry point for cargo-pgrx's schema generation so that PGRX's framework can +/// generate SQL for its types and functions and topographically sort them into +/// an order Postgres will accept. Typically written by the `cargo pgrx new` +/// template, so you probably don't need to worry about this. +#[macro_export] +macro_rules! pgrx_embed { + () => { + #[cfg(not(pgrx_embed))] + fn main() { + panic!("PGRX_EMBED was not set."); + } + #[cfg(pgrx_embed)] + include!(env!("PGRX_EMBED")); + }; +}