├── .cargo └── config.toml ├── .dockerignore ├── .envrc ├── .git-blame-ignore-revs ├── .github ├── FUNDING.yml ├── docker │ ├── Dockerfile.alpine │ ├── Dockerfile.amazon_2 │ ├── Dockerfile.debian_bullseye │ ├── Dockerfile.fedora │ └── run-docker.sh └── workflows │ ├── package-test.yaml │ ├── runas.yml │ ├── tests.yml │ └── will-it-blend-develop.yml ├── .gitignore ├── .licensure.yml ├── Cargo.lock ├── Cargo.toml ├── LICENSE ├── README.md ├── SAFETY.md ├── SECURITY.md ├── art ├── LICENSE ├── pgrx-logo-color-475x518.png ├── pgrx-logo-color-transparent-475x518.png ├── pgrx-logo-color.svg ├── pgrx-logo-outline-black.svg └── pgrx-logo-outline-navy.svg ├── articles ├── README.md ├── forging-sql-from-rust.md └── postgresql-aggregates-with-rust.md ├── cargo-pgrx ├── Cargo.toml ├── README.md ├── build.rs ├── src │ ├── command │ │ ├── connect.rs │ │ ├── cross │ │ │ ├── mod.rs │ │ │ └── pgrx_target.rs │ │ ├── get.rs │ │ ├── info.rs │ │ ├── init.rs │ │ ├── install.rs │ │ ├── mod.rs │ │ ├── new.rs │ │ ├── package.rs │ │ ├── pgrx.rs │ │ ├── regress.rs │ │ ├── run.rs │ │ ├── schema.rs │ │ ├── start.rs │ │ ├── status.rs │ │ ├── stop.rs │ │ ├── sudo_install.rs │ │ ├── test.rs │ │ ├── upgrade.rs │ │ └── version.rs │ ├── env.rs │ ├── main.rs │ ├── manifest.rs │ ├── metadata.rs │ ├── profile.rs │ └── templates │ │ ├── bgworker_lib_rs │ │ ├── cargo_config_toml │ │ ├── cargo_toml │ │ ├── control │ │ ├── gitignore │ │ ├── lib_rs │ │ ├── pgrx_embed_rs │ │ ├── setup_out │ │ └── setup_sql └── tests │ └── fixtures │ └── macos-universal-binary ├── deny.toml ├── docs ├── .gitignore ├── book.toml └── src │ ├── README.md │ ├── SUMMARY.md │ ├── articles.md │ ├── articles │ ├── forging-sql-from-rust.md │ └── postgresql-aggregates-with-rust.md │ ├── contributing.md │ ├── contributing │ ├── pgrx-internal.md │ └── release.md │ ├── design-decisions.md │ ├── extension.md │ ├── extension │ ├── build.md │ ├── build │ │ └── cross-compile.md │ ├── cargo-pgrx.md │ ├── install.md │ ├── schema.md │ ├── test.md │ ├── test │ │ └── memory-checking.md │ └── write.md │ ├── ffi-error-handling.md │ ├── pg-internal.md │ └── pg-internal │ ├── datum.md │ ├── memory-context.md │ ├── setjmp-longjmp.md │ └── varlena.md ├── pgrx-bindgen ├── Cargo.toml └── src │ ├── build.rs │ ├── build │ └── clang.rs │ └── lib.rs ├── pgrx-examples ├── README.md ├── aggregate │ ├── .gitignore │ ├── Cargo.toml │ ├── README.md │ ├── aggregate.control │ └── src │ │ ├── bin │ │ └── pgrx_embed.rs │ │ └── lib.rs ├── arrays │ ├── .gitignore │ ├── Cargo.toml │ ├── README.md │ ├── arrays.control │ └── src │ │ ├── bin │ │ └── pgrx_embed.rs │ │ └── lib.rs ├── bad_ideas │ ├── .gitignore │ ├── Cargo.toml │ ├── README.md │ ├── bad_ideas.control │ └── src │ │ ├── bin │ │ └── pgrx_embed.rs │ │ └── lib.rs ├── bgworker │ ├── .gitignore │ ├── Cargo.toml │ ├── README.md │ ├── bgworker.control │ └── src │ │ ├── bin │ │ └── pgrx_embed.rs │ │ └── lib.rs ├── bytea │ ├── .gitignore │ ├── Cargo.toml │ ├── README.md │ ├── bytea.control │ └── src │ │ ├── bin │ │ └── pgrx_embed.rs │ │ └── lib.rs ├── composite_type │ ├── .gitignore │ ├── Cargo.toml │ ├── README.md │ ├── composite_type.control │ └── src │ │ ├── bin │ │ └── pgrx_embed.rs │ │ └── lib.rs ├── custom_libname │ ├── .gitignore │ ├── Cargo.toml │ ├── other_name.control │ └── src │ │ ├── bin │ │ └── pgrx_embed.rs │ │ └── lib.rs ├── custom_sql │ ├── .gitignore │ ├── Cargo.toml │ ├── README.md │ ├── custom_sql.control │ ├── sql │ │ ├── finalizer.sql │ │ ├── multiple.sql │ │ └── single.sql │ └── src │ │ ├── bin │ │ └── pgrx_embed.rs │ │ └── lib.rs ├── custom_types │ ├── .gitignore │ ├── Cargo.toml │ ├── README.md │ ├── custom_types.control │ └── src │ │ ├── alignment.rs │ │ ├── bin │ │ └── pgrx_embed.rs │ │ ├── complex.rs │ │ ├── fixed_size.rs │ │ ├── generic_enum.rs │ │ ├── hexint.rs │ │ ├── hstore_clone.rs │ │ ├── lib.rs │ │ ├── ordered.rs │ │ └── rust_enum.rs ├── datetime │ ├── .gitignore │ ├── Cargo.toml │ ├── README.md │ ├── datetime.control │ └── src │ │ ├── bin │ │ └── pgrx_embed.rs │ │ └── lib.rs ├── errors │ ├── .gitignore │ ├── Cargo.toml │ ├── README.md │ ├── errors.control │ └── src │ │ ├── bin │ │ └── pgrx_embed.rs │ │ └── lib.rs ├── nostd │ ├── .gitignore │ ├── Cargo.toml │ ├── nostd.control │ └── src │ │ ├── bin │ │ └── pgrx_embed.rs │ │ └── lib.rs ├── numeric │ ├── .gitignore │ ├── Cargo.toml │ ├── README.md │ ├── numeric.control │ └── src │ │ ├── bin │ │ └── pgrx_embed.rs │ │ └── lib.rs ├── operators │ ├── .gitignore │ ├── Cargo.toml │ ├── README.md │ ├── operators.control │ └── src │ │ ├── bin │ │ └── pgrx_embed.rs │ │ ├── derived.rs │ │ ├── lib.rs │ │ └── pgvarlena.rs ├── pgtrybuilder │ ├── .gitignore │ ├── Cargo.toml │ ├── README.md │ ├── pgtrybuilder.control │ └── src │ │ ├── bin │ │ └── pgrx_embed.rs │ │ └── lib.rs ├── range │ ├── .gitignore │ ├── Cargo.toml │ ├── README.md │ ├── range.control │ ├── src │ │ ├── bin │ │ │ └── pgrx_embed.rs │ │ └── lib.rs │ └── tests │ │ └── pg_regress │ │ ├── expected │ │ ├── make_range.out │ │ ├── setup.out │ │ └── store_ranges.out │ │ └── sql │ │ ├── make_range.sql │ │ ├── setup.sql │ │ └── store_ranges.sql ├── schemas │ ├── .gitignore │ ├── Cargo.toml │ ├── README.md │ ├── schemas.control │ └── src │ │ ├── bin │ │ └── pgrx_embed.rs │ │ └── lib.rs ├── shmem │ ├── .gitignore │ ├── Cargo.toml │ ├── README.md │ ├── shmem.control │ └── src │ │ ├── bin │ │ └── pgrx_embed.rs │ │ └── lib.rs ├── spi │ ├── .gitignore │ ├── Cargo.toml │ ├── README.md │ ├── spi.control │ └── src │ │ ├── bin │ │ └── pgrx_embed.rs │ │ └── lib.rs ├── spi_srf │ ├── .gitignore │ ├── Cargo.toml │ ├── README.md │ ├── spi_srf.control │ └── src │ │ ├── bin │ │ └── pgrx_embed.rs │ │ └── lib.rs ├── srf │ ├── .gitignore │ ├── Cargo.toml │ ├── README.md │ ├── src │ │ ├── bin │ │ │ └── pgrx_embed.rs │ │ └── lib.rs │ └── srf.control ├── strings │ ├── .gitignore │ ├── Cargo.toml │ ├── README.md │ ├── src │ │ ├── bin │ │ │ └── pgrx_embed.rs │ │ └── lib.rs │ └── strings.control ├── triggers │ ├── .gitignore │ ├── Cargo.toml │ ├── src │ │ ├── bin │ │ │ └── pgrx_embed.rs │ │ └── lib.rs │ └── triggers.control ├── versioned_custom_libname_so │ ├── .gitignore │ ├── Cargo.toml │ ├── src │ │ ├── bin │ │ │ └── pgrx_embed.rs │ │ └── lib.rs │ └── versioned_othername.control ├── versioned_so │ ├── .gitignore │ ├── Cargo.toml │ ├── src │ │ ├── bin │ │ │ └── pgrx_embed.rs │ │ └── lib.rs │ └── versioned_so.control └── wal_decoder │ ├── .gitignore │ ├── Cargo.toml │ ├── README.md │ ├── src │ ├── bin │ │ └── pgrx_embed.rs │ └── lib.rs │ └── wal_decoder.control ├── pgrx-macros ├── Cargo.toml ├── README.md └── src │ ├── lib.rs │ ├── operators.rs │ └── rewriter.rs ├── pgrx-pg-config ├── Cargo.toml ├── README.md └── src │ ├── cargo.rs │ ├── lib.rs │ └── path_methods.rs ├── pgrx-pg-sys ├── Cargo.toml ├── README.md ├── bindgen.rs ├── include │ ├── pg13.h │ ├── pg14.h │ ├── pg15.h │ ├── pg16.h │ ├── pg17.h │ └── pg18.h ├── pgrx-cshim.c └── src │ ├── cshim.rs │ ├── cstr.rs │ ├── include.rs │ ├── include │ ├── pg13.rs │ ├── pg13_oids.rs │ ├── pg14.rs │ ├── pg14_oids.rs │ ├── pg15.rs │ ├── pg15_oids.rs │ ├── pg16.rs │ ├── pg16_oids.rs │ ├── pg17.rs │ ├── pg17_oids.rs │ ├── pg18.rs │ └── pg18_oids.rs │ ├── lib.rs │ ├── node.rs │ ├── port.rs │ └── submodules │ ├── cmp.rs │ ├── datum.rs │ ├── elog.rs │ ├── errcodes.rs │ ├── ffi.rs │ ├── htup.rs │ ├── mod.rs │ ├── oids.rs │ ├── panic.rs │ ├── pg_try.rs │ ├── sql_translatable.rs │ ├── thread_check.rs │ ├── transaction_id.rs │ ├── tupdesc.rs │ └── utils.rs ├── pgrx-sql-entity-graph ├── Cargo.toml ├── README.md ├── assets │ └── ansi.tmTheme └── src │ ├── aggregate │ ├── aggregate_type.rs │ ├── entity.rs │ ├── mod.rs │ └── options.rs │ ├── composite_type.rs │ ├── control_file.rs │ ├── enrich.rs │ ├── extension_sql │ ├── entity.rs │ └── mod.rs │ ├── extern_args.rs │ ├── finfo.rs │ ├── fmt.rs │ ├── lib.rs │ ├── lifetimes.rs │ ├── mapping.rs │ ├── metadata │ ├── entity.rs │ ├── function_metadata.rs │ ├── mod.rs │ ├── return_variant.rs │ └── sql_translatable.rs │ ├── pg_extern │ ├── argument.rs │ ├── attribute.rs │ ├── cast.rs │ ├── entity │ │ ├── argument.rs │ │ ├── cast.rs │ │ ├── mod.rs │ │ ├── operator.rs │ │ └── returning.rs │ ├── mod.rs │ ├── operator.rs │ ├── returning.rs │ └── search_path.rs │ ├── pg_trigger │ ├── attribute.rs │ ├── entity.rs │ └── mod.rs │ ├── pgrx_attribute.rs │ ├── pgrx_sql.rs │ ├── positioning_ref.rs │ ├── postgres_enum │ ├── entity.rs │ └── mod.rs │ ├── postgres_hash │ ├── entity.rs │ └── mod.rs │ ├── postgres_ord │ ├── entity.rs │ └── mod.rs │ ├── postgres_type │ ├── entity.rs │ └── mod.rs │ ├── schema │ ├── entity.rs │ └── mod.rs │ ├── to_sql │ ├── entity.rs │ └── mod.rs │ └── used_type.rs ├── pgrx-tests ├── .gitignore ├── Cargo.toml ├── README.md ├── pgrx_tests.control ├── src │ ├── bin │ │ └── pgrx_embed.rs │ ├── framework.rs │ ├── framework │ │ └── shutdown.rs │ ├── lib.rs │ ├── proptest.rs │ └── tests │ │ ├── aggregate_tests.rs │ │ ├── anyarray_tests.rs │ │ ├── anyelement_tests.rs │ │ ├── anynumeric_tests.rs │ │ ├── array_tests.rs │ │ ├── attributes_tests.rs │ │ ├── bgworker_tests.rs │ │ ├── bindings_of_inline_fn_tests.rs │ │ ├── borrow_datum.rs │ │ ├── bytea_tests.rs │ │ ├── cfg_tests.rs │ │ ├── complex.rs │ │ ├── composite_type_tests.rs │ │ ├── datetime_tests.rs │ │ ├── default_arg_value_tests.rs │ │ ├── derive_pgtype_lifetimes.rs │ │ ├── enum_type_tests.rs │ │ ├── fcinfo_tests.rs │ │ ├── fn_call_tests.rs │ │ ├── from_into_datum_tests.rs │ │ ├── geo_tests.rs │ │ ├── guc_tests.rs │ │ ├── heap_tuple.rs │ │ ├── hooks_tests.rs │ │ ├── inet_tests.rs │ │ ├── internal_tests.rs │ │ ├── issue1134.rs │ │ ├── json_tests.rs │ │ ├── lifetime_tests.rs │ │ ├── list_tests.rs │ │ ├── log_tests.rs │ │ ├── memcxt_tests.rs │ │ ├── mod.rs │ │ ├── name_tests.rs │ │ ├── numeric_tests.rs │ │ ├── oid_tests.rs │ │ ├── pg_cast_tests.rs │ │ ├── pg_extern_tests.rs │ │ ├── pg_guard_tests.rs │ │ ├── pg_operator_tests.rs │ │ ├── pg_try_tests.rs │ │ ├── pgbox_tests.rs │ │ ├── pgrx_module_qualification.rs │ │ ├── postgres_type_tests.rs │ │ ├── proptests.rs │ │ ├── range_tests.rs │ │ ├── rel_tests.rs │ │ ├── result_tests.rs │ │ ├── roundtrip_tests.rs │ │ ├── schema_tests.rs │ │ ├── shmem_tests.rs │ │ ├── spi_tests.rs │ │ ├── srf_tests.rs │ │ ├── struct_type_tests.rs │ │ ├── trigger_tests.rs │ │ ├── uuid_tests.rs │ │ ├── variadic_tests.rs │ │ ├── xact_callback_tests.rs │ │ ├── xid64_tests.rs │ │ └── zero_datum_edge_cases.rs └── tests │ ├── compile-fail │ ├── aggregate-functions-dont-run-forever.rs │ ├── aggregate-functions-dont-run-forever.stderr │ ├── arrays-dont-leak.rs │ ├── arrays-dont-leak.stderr │ ├── eq-for-postgres_hash.rs │ ├── eq-for-postgres_hash.stderr │ ├── escaping-spiclient-1209-cursor.rs │ ├── escaping-spiclient-1209-cursor.stderr │ ├── escaping-spiclient-1209-prep-stmt.rs │ ├── escaping-spiclient-1209-prep-stmt.stderr │ ├── heap-tuples-dont-leak.rs │ ├── heap-tuples-dont-leak.stderr │ ├── invalid_pgcast_options.rs │ ├── invalid_pgcast_options.stderr │ ├── postgres-strings-arent-immortal.rs │ ├── postgres-strings-arent-immortal.stderr │ ├── spi-prepare-prepared-statement.rs.ignored │ ├── spi-prepare-prepared-statement.stderr │ ├── table-iterators-arent-immortal.rs │ ├── table-iterators-arent-immortal.stderr │ ├── too_many_cast_options.rs │ ├── too_many_cast_options.stderr │ ├── total-eq-for-postgres_eq.rs │ ├── total-eq-for-postgres_eq.stderr │ ├── total-ord-for-postgres_ord.rs │ ├── total-ord-for-postgres_ord.stderr │ ├── variadic-is-dead.rs │ └── variadic-is-dead.stderr │ ├── nightly │ └── compile-fail │ │ ├── allocation-doesnt-outlive-memcx.rs │ │ └── allocation-doesnt-outlive-memcx.stderr │ ├── todo │ ├── busted-exotic-signature.rs │ ├── busted-exotic-signature.stderr │ ├── composite-types-broken-on-spi.rs │ ├── composite-types-broken-on-spi.stderr │ ├── for-dog-in-dogs.rs │ ├── for-dog-in-dogs.stderr │ ├── random-vec-strs-arent-okay.rs │ ├── random-vec-strs-arent-okay.stderr │ ├── roundtrip-tests.rs │ ├── roundtrip-tests.stderr │ ├── vec-option-composite_type-nesting-problems.rs │ └── vec-option-composite_type-nesting-problems.stderr │ └── ui.rs ├── pgrx ├── Cargo.toml ├── deny.toml └── src │ ├── aggregate.rs │ ├── array.rs │ ├── array │ └── port.rs │ ├── atomics.rs │ ├── bgworkers.rs │ ├── callbacks.rs │ ├── callconv.rs │ ├── datum │ ├── anyarray.rs │ ├── anyelement.rs │ ├── array.rs │ ├── borrow.rs │ ├── date.rs │ ├── datetime_support │ │ ├── ctor.rs │ │ ├── mod.rs │ │ └── ops.rs │ ├── from.rs │ ├── geo.rs │ ├── inet.rs │ ├── internal.rs │ ├── interval.rs │ ├── into.rs │ ├── json.rs │ ├── mod.rs │ ├── numeric.rs │ ├── numeric_support │ │ ├── cmp.rs │ │ ├── convert.rs │ │ ├── convert_anynumeric.rs │ │ ├── convert_numeric.rs │ │ ├── convert_primitive.rs │ │ ├── datum.rs │ │ ├── error.rs │ │ ├── hash.rs │ │ ├── mod.rs │ │ ├── ops.rs │ │ ├── serde.rs │ │ └── sql.rs │ ├── range.rs │ ├── time.rs │ ├── time_stamp.rs │ ├── time_stamp_with_timezone.rs │ ├── time_with_timezone.rs │ ├── tuples.rs │ ├── unbox.rs │ ├── uuid.rs │ ├── varlena.rs │ └── with_typeid.rs │ ├── enum_helper.rs │ ├── fcinfo.rs │ ├── ffi.rs │ ├── fn_call.rs │ ├── guc.rs │ ├── heap_tuple.rs │ ├── hooks.rs │ ├── htup.rs │ ├── inoutfuncs.rs │ ├── itemptr.rs │ ├── iter.rs │ ├── layout.rs │ ├── lib.rs │ ├── list.rs │ ├── list │ ├── flat_list.rs │ └── old_list.rs │ ├── lwlock.rs │ ├── memcx.rs │ ├── memcxt.rs │ ├── misc.rs │ ├── namespace.rs │ ├── nodes.rs │ ├── nullable.rs │ ├── pg_catalog │ ├── mod.rs │ └── pg_proc.rs │ ├── pg_sys.rs │ ├── pgbox.rs │ ├── prelude.rs │ ├── ptr.rs │ ├── rel.rs │ ├── shmem.rs │ ├── slice.rs │ ├── spi.rs │ ├── spi │ ├── client.rs │ ├── cursor.rs │ ├── query.rs │ └── tuple.rs │ ├── spinlock.rs │ ├── stringinfo.rs │ ├── toast.rs │ ├── trigger_support │ ├── mod.rs │ ├── pg_trigger.rs │ ├── pg_trigger_error.rs │ ├── pg_trigger_level.rs │ ├── pg_trigger_option.rs │ ├── pg_trigger_when.rs │ └── trigger_tuple.rs │ ├── tupdesc.rs │ ├── varlena.rs │ ├── wrappers.rs │ └── xid.rs ├── prepare-release.sh ├── publish.sh ├── run-example.sh ├── rustfmt.toml ├── tools ├── license-check.sh ├── rustup.sh └── version-updater │ ├── Cargo.lock │ ├── Cargo.toml │ └── src │ └── main.rs ├── update-versions.sh └── upgrade-deps.sh /.cargo/config.toml: -------------------------------------------------------------------------------- 1 | [alias] 2 | b = "build --features" 3 | c = "check --features" 4 | t = "test --features" 5 | r = "run --features" 6 | 7 | [target.'cfg(target_os="macos")'] 8 | # Postgres symbols won't be available until runtime 9 | rustflags = ["-Clink-arg=-Wl,-undefined,dynamic_lookup"] 10 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .idea/ 3 | target/ 4 | *.iml 5 | **/*.rs.bk 6 | *.o 7 | *.so 8 | *.a 9 | cmake*/ 10 | .direnv 11 | pgrx-examples/*/target 12 | -------------------------------------------------------------------------------- /.envrc: -------------------------------------------------------------------------------- 1 | # reload when these files change 2 | watch_file flake.nix 3 | watch_file flake.lock 4 | # load the flake devShell 5 | eval "$(nix print-dev-env)" 6 | -------------------------------------------------------------------------------- /.git-blame-ignore-revs: -------------------------------------------------------------------------------- 1 | # to make `git blame` ignore the following commits, run: 2 | # git config blame.ignoreRevsFile .git-blame-ignore-revs 3 | 4 | # adding a rustfmt.toml 5 | 1ded8553fbeff635fcca0cbc8f37034cc124d698 6 | 7 | # utils -> sql-entity-graph 8 | cf6fd6f1c4709491e86f5dc536d5a99adb1f18fc 9 | 10 | # the pgrx rename 11 | 8726d4fb5482910ec389b014efa6b999c2208bae 12 | 13 | # modularizing pgrx::spi 14 | d333053dc6f6afc6433e40f343c885a9c261562d 15 | 16 | # modularizing pgrx-pg-sys 17 | c83c203aa0ca3021bf8bafdd2109f74f940812e5 18 | 19 | # removing the PgGuardRewriter struct and impl 20 | ccf82259a01ccef132cbdc6f56ea60845d387b23 21 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: [eeeebbbbrrrr, workingjubilee] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | # patreon: # Replace with a single Patreon username 5 | # open_collective: # Replace with a single Open Collective username 6 | # ko_fi: # Replace with a single Ko-fi username 7 | # tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | # community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | # liberapay: # Replace with a single Liberapay username 10 | # issuehunt: # Replace with a single IssueHunt username 11 | # otechie: # Replace with a single Otechie username 12 | # custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 13 | -------------------------------------------------------------------------------- /.github/docker/run-docker.sh: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env bash 2 | 3 | # Environment variables: 4 | # PG_MAJOR_VER: The major version of Postgres in which to build/run. E.g. 13, 14, 15 5 | # DOCKERFILE_ID: The Dockerfile identifier to be built, included in this repo, 6 | # e.g. debian:bullseye or amazon:2 7 | # CARGO_LOCKED_OPTION: Set to '--locked' to use "cargo --locked", or set to 8 | # blank '' to use "cargo" without "--locked" 9 | 10 | # Examples of running this script in CI (currently Github Actions): 11 | # ./.github/docker/run-docker.sh 14 debian_bullseye 12 | # ./.github/docker/run-docker.sh 13 fedora 13 | 14 | set -x 15 | 16 | PG_MAJOR_VER=$1 17 | DOCKERFILE_ID=$2 18 | 19 | echo "Building docker container for PGRX using Postgres version $PG_MAJOR_VER in container $DOCKERFILE_ID" 20 | echo "Cargo lock flag set to: '$CARGO_LOCKED_OPTION'" 21 | 22 | docker build \ 23 | --build-arg PG_MAJOR_VER="$PG_MAJOR_VER" \ 24 | --build-arg CARGO_LOCKED_OPTION="$CARGO_LOCKED_OPTION" \ 25 | -t pgrx \ 26 | -f ".github/docker/Dockerfile.$DOCKERFILE_ID" \ 27 | . 28 | 29 | echo "Running PGRX test suite using Postgres version $PG_MAJOR_VER in container $DOCKERFILE_ID with 'cshim', 'proptest'" 30 | 31 | docker run pgrx \ 32 | cargo test \ 33 | --no-default-features \ 34 | --features "pg$PG_MAJOR_VER cshim proptest" \ 35 | "$CARGO_LOCKED_OPTION" 36 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .idea/ 3 | target/ 4 | *.iml 5 | **/*.rs.bk 6 | *.o 7 | *.so 8 | *.a 9 | cmake*/ 10 | .direnv 11 | pgrx-examples/*/target 12 | /bin 13 | rustup-init.sh -------------------------------------------------------------------------------- /.licensure.yml: -------------------------------------------------------------------------------- 1 | change_in_place: true 2 | excludes: 3 | - Cargo.lock 4 | - LICENSE 5 | - pgrx-sql-entity-graph/assets/ansi.tmTheme 6 | - ".envrc" 7 | - ".gitignore" 8 | - ".dockerignore" 9 | - "flake\\..*" 10 | - "logo.*" 11 | - "rustfmt.toml" 12 | - ".github/**/*" 13 | - ".cargo/config.toml" 14 | - "cargo-pgrx/src/templates/*" 15 | - "cargo-pgrx/tests/fixtures/macos-universal-binary" 16 | - ".*\\.control" 17 | - ".*\\.md" 18 | - ".*\\.nix" 19 | - ".*\\.yml" 20 | licenses: 21 | - files: any 22 | ident: MIT 23 | authors: 24 | - name: PgCentral Foundation, Inc. 25 | email: contact@pgcentral.org 26 | template: |- 27 | Portions Copyright 2019-2021 ZomboDB, LLC. 28 | 29 | Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 30 | 31 | Portions Copyright 2023-[year] [name of author] 32 | 33 | All rights reserved. 34 | 35 | Use of this source code is governed by the [ident] license that can be found in the LICENSE file. 36 | comments: 37 | - extensions: 38 | - rs 39 | - c 40 | - h 41 | trailing_lines: 0 42 | commenter: 43 | type: line 44 | comment_char: "//LICENSE" 45 | - extension: sql 46 | trailing_lines: 0 47 | commenter: 48 | type: line 49 | comment_char: "--LICENSE" 50 | - extension: any 51 | trailing_lines: 0 52 | commenter: 53 | type: line 54 | comment_char: "#LICENSE" 55 | 56 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Portions Copyright 2019-2021 ZomboDB, LLC. 4 | Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 5 | Portions Copyright 2023 PgCentral Foundation, Inc. 6 | 7 | All rights reserved. 8 | 9 | Permission is hereby granted, free of charge, to any person obtaining a copy 10 | of this software and associated documentation files (the "Software"), to deal 11 | in the Software without restriction, including without limitation the rights 12 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | copies of the Software, and to permit persons to whom the Software is 14 | furnished to do so, subject to the following conditions: 15 | 16 | The above copyright notice and this permission notice shall be included in all 17 | copies or substantial portions of the Software. 18 | 19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 25 | SOFTWARE. 26 | -------------------------------------------------------------------------------- /SAFETY.md: -------------------------------------------------------------------------------- 1 | # Safety of `pgrx` 2 | 3 | Documentation for invariants that `pgrx` relies on for the soundness of its Rust interface, 4 | or ways that `pgrx` compensates for assumed non-invariants, or just notes about 5 | the quirks of Postgres that have been discovered. 6 | 7 | Specific functions will have their safety conditions documented on them, 8 | so this document is only useful for describing higher-level concepts. 9 | 10 | ## Postgres 11 | 12 | Quirks specific to Postgres. 13 | 14 | ### Memory Allocation 15 | 16 | The `palloc*` family of functions may throw a Postgres error but will not return `nullptr`. 17 | 18 | ## Rust 19 | 20 | Quirks specific to Rust that specifically inform the design of this crate and not, say, 21 | "every single crate ever". 22 | 23 | ### Destructors Are Not Guaranteed And `sig{set,long}jmp` Is Weird 24 | 25 | Rust does not guarantee that a `Drop::drop` implementation, even if it is described, will actually 26 | be run, due to the ways control flow can be interrupted before the destructor starts or finishes. 27 | Indeed, Drop implementations can be precisely a source of such problems if they are "non-trivial". 28 | Rust control flow has to be independently safe from Postgres control flow to keep Postgres safe from Rust, 29 | and Rust safe from Postgres. 30 | 31 | Accordingly, it should be noted that Rust isn't really designed with `sigsetjmp` or `siglongjmp` in mind, 32 | even though they are used in this crate and work well enough at making Rust more manageable 33 | in the face of the various machinations that Postgres may get up to. 34 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security 2 | 3 | ## Reporting Security Issues 4 | 5 | **Please do not report security vulnerabilities through public GitHub issues.** 6 | 7 | Instead, please open a [security advisory][advisory] to notify the maintainers. You should receive a response within 3 working days. If for some reason you do not, please follow up via email to ensure we received your original message. 8 | 9 | Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue: 10 | 11 | * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) 12 | * Full paths of source file(s) related to the manifestation of the issue 13 | * The location of the affected source code (tag/branch/commit or direct URL) 14 | * Any special configuration required to reproduce the issue 15 | * Step-by-step instructions to reproduce the issue 16 | * Proof-of-concept or exploit code (if possible) 17 | * Impact of the issue, including how an attacker might exploit the issue 18 | 19 | This information will help us triage your report more quickly. 20 | 21 | If you find a vulnerability anywhere in this project, such as the source or scripts, 22 | then please let the maintainers know ASAP and we will fix it as a critical priority. 23 | 24 | [advisory]: https://github.com/pgcentralfoundation/pgrx/security/advisories/new 25 | -------------------------------------------------------------------------------- /art/LICENSE: -------------------------------------------------------------------------------- 1 | pgrx-logos (c) by PgCentral Foundation, Inc. 2 | 3 | pgrx-logos is licensed under a 4 | Creative Commons Attribution-ShareAlike 4.0 International License. 5 | 6 | You should have received a copy of the license along with this 7 | work. If not, see . 8 | -------------------------------------------------------------------------------- /art/pgrx-logo-color-475x518.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pgcentralfoundation/pgrx/ee771db6ea772e36fd86b6d0076efaaa126c915e/art/pgrx-logo-color-475x518.png -------------------------------------------------------------------------------- /art/pgrx-logo-color-transparent-475x518.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pgcentralfoundation/pgrx/ee771db6ea772e36fd86b6d0076efaaa126c915e/art/pgrx-logo-color-transparent-475x518.png -------------------------------------------------------------------------------- /cargo-pgrx/build.rs: -------------------------------------------------------------------------------- 1 | //LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 2 | //LICENSE 3 | //LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 4 | //LICENSE 5 | //LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 6 | //LICENSE 7 | //LICENSE All rights reserved. 8 | //LICENSE 9 | //LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 10 | fn main() { 11 | println!("cargo:rerun-if-changed=build.rs"); 12 | if let Some(cargo_version) = cargo_version() { 13 | println!("cargo:rustc-env=CARGO_VERSION_DURING_BUILD={cargo_version}"); 14 | } 15 | } 16 | 17 | /// Gets the current `cargo` version. 18 | /// 19 | /// Used to check our toolchain version. `cargo` sets the `CARGO` env var both 20 | /// when running the build script and when running `cargo-pgrx`, so it's easier 21 | /// to check `cargo` than to check `rustc` itself. Also `cargo` will 22 | /// always have the same version as the `rustc` it goes with, so checking the 23 | /// `cargo` version is sufficient. 24 | /// 25 | /// [Reference: Environment variables Cargo sets for build 26 | /// scripts](https://doc.rust-lang.org/cargo/reference/environment-variables.html#environment-variables-cargo-sets-for-build-scripts) 27 | fn cargo_version() -> Option { 28 | let cargo = std::env::var_os("CARGO").expect("`CARGO` env var wasn't set!"); 29 | let output = std::process::Command::new(cargo).arg("--version").output().ok()?; 30 | std::str::from_utf8(&output.stdout).map(|s| s.trim().to_string()).ok() 31 | } 32 | -------------------------------------------------------------------------------- /cargo-pgrx/src/command/cross/mod.rs: -------------------------------------------------------------------------------- 1 | //LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 2 | //LICENSE 3 | //LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 4 | //LICENSE 5 | //LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 6 | //LICENSE 7 | //LICENSE All rights reserved. 8 | //LICENSE 9 | //LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 10 | use crate::CommandExecute; 11 | pub(crate) mod pgrx_target; 12 | 13 | /// Commands having to do with cross-compilation. (Experimental) 14 | #[derive(clap::Args, Debug)] 15 | #[clap(author)] 16 | pub(crate) struct Cross { 17 | #[command(subcommand)] 18 | pub(crate) subcommand: CargoPgrxCrossSubCommands, 19 | } 20 | 21 | impl CommandExecute for Cross { 22 | fn execute(self) -> eyre::Result<()> { 23 | self.subcommand.execute() 24 | } 25 | } 26 | 27 | /// Subcommands relevant to cross-compilation. 28 | #[derive(clap::Subcommand, Debug)] 29 | pub(crate) enum CargoPgrxCrossSubCommands { 30 | PgrxTarget(pgrx_target::PgrxTarget), 31 | } 32 | 33 | impl CommandExecute for CargoPgrxCrossSubCommands { 34 | fn execute(self) -> eyre::Result<()> { 35 | use CargoPgrxCrossSubCommands::*; 36 | match self { 37 | PgrxTarget(target_info) => target_info.execute(), 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /cargo-pgrx/src/templates/cargo_config_toml: -------------------------------------------------------------------------------- 1 | [target.'cfg(target_os="macos")'] 2 | # Postgres symbols won't be available until runtime 3 | rustflags = ["-Clink-arg=-Wl,-undefined,dynamic_lookup"] 4 | -------------------------------------------------------------------------------- /cargo-pgrx/src/templates/cargo_toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "{name}" 3 | version = "0.0.0" 4 | edition = "2021" 5 | 6 | [lib] 7 | crate-type = ["cdylib", "lib"] 8 | 9 | [[bin]] 10 | name = "pgrx_embed_{name}" 11 | path = "./src/bin/pgrx_embed.rs" 12 | 13 | [features] 14 | default = ["pg13"] 15 | pg13 = ["pgrx/pg13", "pgrx-tests/pg13" ] 16 | pg14 = ["pgrx/pg14", "pgrx-tests/pg14" ] 17 | pg15 = ["pgrx/pg15", "pgrx-tests/pg15" ] 18 | pg16 = ["pgrx/pg16", "pgrx-tests/pg16" ] 19 | pg17 = ["pgrx/pg17", "pgrx-tests/pg17" ] 20 | pg18 = ["pgrx/pg18", "pgrx-tests/pg18" ] 21 | pg_test = [] 22 | 23 | [dependencies] 24 | pgrx = "=0.14.3" 25 | 26 | [dev-dependencies] 27 | pgrx-tests = "=0.14.3" 28 | 29 | [profile.dev] 30 | panic = "unwind" 31 | 32 | [profile.release] 33 | panic = "unwind" 34 | opt-level = 3 35 | lto = "fat" 36 | codegen-units = 1 37 | -------------------------------------------------------------------------------- /cargo-pgrx/src/templates/control: -------------------------------------------------------------------------------- 1 | comment = '{name}: Created by pgrx' 2 | default_version = '@CARGO_VERSION@' 3 | module_pathname = '{name}' 4 | relocatable = false 5 | superuser = true 6 | trusted = false 7 | -------------------------------------------------------------------------------- /cargo-pgrx/src/templates/gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .idea/ 3 | /target 4 | *.iml 5 | **/*.rs.bk 6 | Cargo.lock 7 | pg_regress/results 8 | pg_regress/regression.diffs 9 | pg_regress/regression.out 10 | -------------------------------------------------------------------------------- /cargo-pgrx/src/templates/lib_rs: -------------------------------------------------------------------------------- 1 | use pgrx::prelude::*; 2 | 3 | ::pgrx::pg_module_magic!(c"{name}", pgrx::pg_sys::PG_VERSION); 4 | 5 | #[pg_extern] 6 | fn hello_{name}() -> &'static str {{ 7 | "Hello, {name}" 8 | }} 9 | 10 | #[cfg(any(test, feature = "pg_test"))] 11 | #[pg_schema] 12 | mod tests {{ 13 | use pgrx::prelude::*; 14 | 15 | #[pg_test] 16 | fn test_hello_{name}() {{ 17 | assert_eq!("Hello, {name}", crate::hello_{name}()); 18 | }} 19 | 20 | }} 21 | 22 | /// This module is required by `cargo pgrx test` invocations. 23 | /// It must be visible at the root of your extension crate. 24 | #[cfg(test)] 25 | pub mod pg_test {{ 26 | pub fn setup(_options: Vec<&str>) {{ 27 | // perform one-off initialization when the pg_test framework starts 28 | }} 29 | 30 | #[must_use] 31 | pub fn postgresql_conf_options() -> Vec<&'static str> {{ 32 | // return any postgresql.conf settings that are required for your tests 33 | vec![] 34 | }} 35 | }} 36 | -------------------------------------------------------------------------------- /cargo-pgrx/src/templates/pgrx_embed_rs: -------------------------------------------------------------------------------- 1 | ::pgrx::pgrx_embed!(); -------------------------------------------------------------------------------- /cargo-pgrx/src/templates/setup_out: -------------------------------------------------------------------------------- 1 | -- this setup file is run immediately after the regression database is (re)created 2 | -- the file is optional but you likely want to create the extension 3 | CREATE EXTENSION {name}; 4 | -------------------------------------------------------------------------------- /cargo-pgrx/src/templates/setup_sql: -------------------------------------------------------------------------------- 1 | -- this setup file is run immediately after the regression database is (re)created 2 | -- the file is optional but you likely want to create the extension 3 | CREATE EXTENSION {name}; 4 | -------------------------------------------------------------------------------- /cargo-pgrx/tests/fixtures/macos-universal-binary: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pgcentralfoundation/pgrx/ee771db6ea772e36fd86b6d0076efaaa126c915e/cargo-pgrx/tests/fixtures/macos-universal-binary -------------------------------------------------------------------------------- /docs/.gitignore: -------------------------------------------------------------------------------- 1 | book 2 | -------------------------------------------------------------------------------- /docs/book.toml: -------------------------------------------------------------------------------- 1 | [book] 2 | authors = ["Jubilee Young"] 3 | language = "en" 4 | multilingual = false 5 | src = "src" 6 | title = "Postgres Extensions in Rust" 7 | -------------------------------------------------------------------------------- /docs/src/SUMMARY.md: -------------------------------------------------------------------------------- 1 | # The PGRX Book 2 | 3 | - [Introduction](./README.md) 4 | - [Working with PGRX](./extension.md) 5 | - [Hello, `cargo pgrx`!](./extension/cargo-pgrx.md) 6 | - [Building Extensions with PGRX](./extension/build.md) 7 | - [Cross Compiling](./extension/build/cross-compile.md) 8 | - [Writing Extensions with PGRX](./extension/write.md) 9 | - [Testing Extensions with PGRX](./extension/test.md) 10 | - [Memory Checking](./extension/test/memory-checking.md) 11 | - [Installing a PGRX Extension](./extension/install.md) 12 | - [Schema Configuration](./extension/schema.md) 13 | - [Basics of Postgres Internals](./pg-internal.md) 14 | - [Pass-By-Datum](./pg-internal/datum.md) 15 | - [Memory Contexts](./pg-internal/memory-context.md) 16 | - [Varlena Types](./pg-internal/varlena.md) 17 | - [`sigsetjmp` & `siglongjmp`](./pg-internal/setjmp-longjmp.md) 18 | - [FFI Error Handling](./ffi-error-handling.md) 19 | - [Contributing](./contributing.md) 20 | - [PGRX Internals](./contributing/pgrx-internal.md) 21 | - [Releases](./contributing/release.md) 22 | - [Articles](./articles.md) 23 | - [Forging SQL from Rust](./articles/forging-sql-from-rust.md) 24 | - [Postgres Aggregates from Rust](./articles/postgresql-aggregates-with-rust.md) 25 | - [Design Decisions](./design-decisions.md) 26 | -------------------------------------------------------------------------------- /docs/src/articles.md: -------------------------------------------------------------------------------- 1 | # Articles 2 | 3 | - [Forging SQL from Rust](./articles/forging-sql-from-rust.md) 4 | - [Postgres Aggregates from Rust](./articles/postgresql-aggregates-with-rust.md) 5 | -------------------------------------------------------------------------------- /docs/src/articles/forging-sql-from-rust.md: -------------------------------------------------------------------------------- 1 | {{#include ./../../../articles/forging-sql-from-rust.md}} 2 | -------------------------------------------------------------------------------- /docs/src/articles/postgresql-aggregates-with-rust.md: -------------------------------------------------------------------------------- 1 | {{#include ./../../../articles/postgresql-aggregates-with-rust.md}} 2 | -------------------------------------------------------------------------------- /docs/src/contributing/release.md: -------------------------------------------------------------------------------- 1 | ```shell 2 | PGRX_HOME=/tmp/pgrx-release ./prepare-release.sh NEW_VERSION_NUMBER 3 | ``` 4 | 5 | - go make a PR to `develop` on GitHub 6 | - start "draft new release" on GitHub to ask it to "Generate release notes". Make sure to choose the `develop` branch to get the full set of changes.: https://github.com/pgcentralfoundation/pgrx/releases/new 7 | - paste them into the PR you made above 8 | - edit them as best as you can while channeling @workingjubilee's spirit 9 | - request a review 10 | - do a squash merge into develop 11 | - create the actual release on GitHub, tagging the `develop` branch with "${NEW_VERSION}", using the release notes you made in your PR 12 | 13 | ```shell 14 | git switch develop 15 | git pull origin/develop 16 | ./publish.sh 17 | ``` 18 | -------------------------------------------------------------------------------- /docs/src/extension.md: -------------------------------------------------------------------------------- 1 | # Working with PGRX 2 | 3 | - [Hello, `cargo pgrx`!](./extension/cargo-pgrx.md) 4 | - [Building Extensions with PGRX](./extension/build.md) 5 | - [Cross Compiling](./extension/build/cross-compile.md) 6 | - [Writing Extensions with PGRX](./extension/write.md) 7 | - [Testing Extensions with PGRX](./extension/test.md) 8 | - [Memory Checking](./extension/test/memory-checking.md) 9 | - [Installing a PGRX Extension](./extension/install.md) 10 | - [Schema configuration](./extension/schema.md) 11 | -------------------------------------------------------------------------------- /docs/src/extension/build.md: -------------------------------------------------------------------------------- 1 | # Building Extensions with PGRX 2 | 3 | 4 | ## Guides 5 | 6 | - [Cross Compiling](./build/cross-compile.md) 7 | -------------------------------------------------------------------------------- /docs/src/extension/cargo-pgrx.md: -------------------------------------------------------------------------------- 1 | # Hello, `cargo pgrx`! 2 | 3 | 4 | 5 | {{#include ./../../../cargo-pgrx/README.md}} 6 | -------------------------------------------------------------------------------- /docs/src/extension/schema.md: -------------------------------------------------------------------------------- 1 | # Schema Configuration 2 | 3 | {{#include ./../../../pgrx-examples/schemas/README.md}} -------------------------------------------------------------------------------- /docs/src/extension/test.md: -------------------------------------------------------------------------------- 1 | # Testing Extensions with PGRX 2 | 3 | Both `cargo test` and `cargo pgrx test` can be used to run tests using the `pgrx-tests` framework. 4 | Tests annotated with `#[pg_test]` will be run inside a Postgres database. 5 | 6 | 7 | ## Guides 8 | 9 | - [Memory-Checking (Valgrind, etc.)](./test/memory-checking.md) 10 | -------------------------------------------------------------------------------- /docs/src/extension/test/memory-checking.md: -------------------------------------------------------------------------------- 1 | # Memory Checking 2 | 3 | For some background see the writeup in . 4 | 5 | ## Running with Memory Checking 6 | 7 | ### Valgrind 8 | 9 | 1. Install valgrind, headers, libs (on Fedora `sudo dnf install valgrind valgrind-devel valgrind-tools-devel` is enough). 10 | 11 | 2. Run `cargo pgrx init --valgrind`. The only major downside to using this as your primary pgrx installation is that its slow, but you can still run without valgrind. 12 | 13 | 3. Set `USE_VALGRIND` in the environment when running tests, for example `USE_VALGRIND=1 cargo test`. valgrind must be on the path for this to work. This is slow -- taking about 15 minutes on a very beefy cloud server, so manage your timing expectations accordingly. 14 | 15 | ### Sanitizers 16 | 17 | TODO 18 | 19 | ### Hardened Allocators 20 | 21 | For basic usage of electric fence or scudo, `LD_PRELOAD=libefence.so cargo test` or `LD_PRELOAD=libscudo.so cargo test`. More advanced usage (like GWP-ASAN) is still TODO. 22 | -------------------------------------------------------------------------------- /docs/src/extension/write.md: -------------------------------------------------------------------------------- 1 | # Writing Extensions with PGRX 2 | 3 | 4 | 5 | If you use `cargo pgrx new "${extension_name}"`, you get a new directory set up with that name, 6 | a Cargo.toml, a .control file, and some templated Rust for that extension. 7 | 8 |
About the Templated Code 9 | 10 | This templated code is pregenerated, so you don't need to worry about it. 11 | However, if you are curious as to why it has to look a specific way: 12 | 13 | Any pgrx extension will require you to add `pgrx` to your Cargo.toml and add this in the `lib.rs`: 14 | 15 | ```rust 16 | pgrx::pg_module_magic!(); 17 | ``` 18 | 19 | This generates a few functions that Postgres will call and use to identify your loaded extension. 20 | 21 |
22 | 23 | When you write a function that will be exposed to Postgres, there are two ABIs to worry about: 24 | the Postgres ABI and the C ABI. The Postgres ABI is built on top of the C ABI, so all Postgres 25 | ABI functions are also C ABI functions, but not all C ABI functions that Postgres will call 26 | use the Postgres ABI. The Postgres ABI is only for functions that will be called via the 27 | "function manager", and are thus exposed in some way to SQL. 28 | 29 | The Postgres ABI is handled by adding `#[pg_extern]` to a function. 30 | 31 | A C ABI function that may be called as a callback by Postgres requires `#[pg_guard]` attached. 32 | This is due to Postgres using [setjmp and longjmp](../pg-internal/setjmp-longjmp.md) for a 33 | form of "exception-handling". This interacts poorly with Rust panic-handling unless translated. 34 | -------------------------------------------------------------------------------- /docs/src/pg-internal.md: -------------------------------------------------------------------------------- 1 | # Basics of Postgres Internals 2 | 3 | - [Pass-By-Datum](./pg-internal/datum.md) 4 | - [Memory Contexts](./pg-internal/memory-context.md) 5 | - [Varlena Types](./pg-internal/varlena.md) 6 | - [`sigsetjmp` & `siglongjmp`](./pg-internal/setjmp-longjmp.md) 7 | -------------------------------------------------------------------------------- /docs/src/pg-internal/datum.md: -------------------------------------------------------------------------------- 1 | # Pass-By-Datum 2 | 3 | The primary way that Postgres passes values between Postgres functions that can hypothetically 4 | have any type is using the "Datum" type. The declaration is written thus in the source code: 5 | ```c 6 | typedef uintptr_t Datum; 7 | ``` 8 | 9 | The way Postgres uses Datum is more like a sort of union, which might be logically described as 10 | ```rust 11 | #[repr(magic)] // This is not actually ABI-conformant 12 | union Datum { 13 | bool, 14 | i8, 15 | i16, 16 | i32, 17 | i64, 18 | f32, 19 | f64, 20 | Oid, 21 | *mut varlena, 22 | *mut c_char, // null-terminated cstring 23 | *mut c_void, 24 | } 25 | ``` 26 | 27 | Thus, sometimes it is a raw pointer, and sometimes it is a value that can fit in a pointer. 28 | This causes it to incur several of the hazards of being a raw pointer, likely to a lifetime-bound 29 | allocation, yet be copied around with the gleeful abandon that one reserves for ordinary bytes. 30 | The only way to determine which variant is in actual usage is to have some other contextual data. 31 | 32 | -------------------------------------------------------------------------------- /docs/src/pg-internal/varlena.md: -------------------------------------------------------------------------------- 1 | # Varlena Types 2 | 3 | Conceptually, any "varlena" type is: 4 | ```rust 5 | #[repr(C, packed)] 6 | union varlena { 7 | packed: (u8, [u8]), 8 | full: (u32, [u8]), 9 | } 10 | ``` 11 | 12 | Unfortunately, Rust does not take kindly to `?Sized` unions, and it would be a bit dodgy in C, too. 13 | 14 | 15 | -------------------------------------------------------------------------------- /pgrx-bindgen/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "pgrx-bindgen" 3 | description = "additional bindgen support for pgrx" 4 | version = "0.14.3" 5 | edition = "2021" 6 | license = "MIT" 7 | homepage = "https://github.com/pgcentralfoundation/pgrx" 8 | repository = "https://github.com/pgcentralfoundation/pgrx" 9 | documentation = "https://docs.rs/pgrx-bindgen" 10 | 11 | [dependencies] 12 | pgrx-pg-config.workspace = true 13 | 14 | eyre.workspace = true 15 | proc-macro2.workspace = true 16 | regex.workspace = true 17 | syn.workspace = true 18 | walkdir.workspace = true 19 | 20 | bindgen = { version = "0.71.1", default-features = false, features = ["experimental", "runtime"] } 21 | clang-sys = { version = "1", features = ["clang_6_0", "runtime"] } 22 | quote = "1.0.40" 23 | shlex = "1.3" # shell lexing, also used by many of our deps 24 | cc = "1.2" 25 | -------------------------------------------------------------------------------- /pgrx-bindgen/src/lib.rs: -------------------------------------------------------------------------------- 1 | pub mod build; 2 | -------------------------------------------------------------------------------- /pgrx-examples/README.md: -------------------------------------------------------------------------------- 1 | # pgrx-examples 2 | 3 | This directory contains examples of how to work with various aspects of `pgrx`. 4 | 5 | - [arrays/](arrays/): Working with Arrays 6 | - [bad_ideas/](bad_ideas/): Some "bad ideas" to do in Postgres extensions 7 | - [bgworker/](bgworker/): A simple Background Worker example 8 | - [bytea/](bytea/): Working with Postgres' `bytea` type as `Vec` and `&[u8]` in Rust 9 | - [custom_types/](custom_types/): Create your own custom Postgres types backed by Rust structs/enums 10 | - [errors/](errors/): Error handling using Postgres or Rust errors/panics 11 | - [operators/](operators/): Creating operator functions and associated `CREATE OPERATOR/OPERATOR CLASS/OPERATOR FAMILY` DDL 12 | - [shmem/](shmem/): Postgres Shared Memory support 13 | - [schemas/](schemas/): How `pgrx` uses Postgres schemas 14 | - [srf/](srf/): Set-Returning-Functions 15 | - [spi/](spi/): Using Postgres' Server Programming Interface (SPI) 16 | - [strings/](strings/): Using Postgres `text`/`varlena` types as Rust `String`s and `&str`s -------------------------------------------------------------------------------- /pgrx-examples/aggregate/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .idea/ 3 | /target 4 | *.iml 5 | **/*.rs.bk 6 | Cargo.lock 7 | sql/aggregate-1.0.sql 8 | -------------------------------------------------------------------------------- /pgrx-examples/aggregate/Cargo.toml: -------------------------------------------------------------------------------- 1 | #LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 2 | #LICENSE 3 | #LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 4 | #LICENSE 5 | #LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 6 | #LICENSE 7 | #LICENSE All rights reserved. 8 | #LICENSE 9 | #LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 10 | 11 | [package] 12 | name = "aggregate" 13 | version = "0.0.0" 14 | edition = "2021" 15 | publish = false 16 | 17 | [lib] 18 | crate-type = ["cdylib", "lib"] 19 | 20 | [[bin]] 21 | name = "pgrx_embed_aggregate" 22 | path = "./src/bin/pgrx_embed.rs" 23 | 24 | [features] 25 | default = ["pg13"] 26 | pg13 = ["pgrx/pg13", "pgrx-tests/pg13"] 27 | pg14 = ["pgrx/pg14", "pgrx-tests/pg14"] 28 | pg15 = ["pgrx/pg15", "pgrx-tests/pg15"] 29 | pg16 = ["pgrx/pg16", "pgrx-tests/pg16"] 30 | pg17 = ["pgrx/pg17", "pgrx-tests/pg17"] 31 | pg18 = ["pgrx/pg18", "pgrx-tests/pg18"] 32 | pg_test = [] 33 | bob = [] 34 | 35 | [dependencies] 36 | pgrx = { path = "../../pgrx", default-features = false } 37 | serde = "1.0" 38 | 39 | [dev-dependencies] 40 | pgrx-tests = { path = "../../pgrx-tests" } 41 | 42 | # uncomment these if compiling outside of 'pgrx' 43 | # [profile.dev] 44 | # panic = "unwind" 45 | 46 | # [profile.release] 47 | # panic = "unwind" 48 | # opt-level = 3 49 | # lto = "fat" 50 | # codegen-units = 1 51 | -------------------------------------------------------------------------------- /pgrx-examples/aggregate/README.md: -------------------------------------------------------------------------------- 1 | An example of how to create an Aggregate with `pgrx`. 2 | 3 | Demonstrates how to create a `IntegerAvgState` aggregate. 4 | 5 | This example also demonstrates the use of `PgVarlena` and how to use `#[pgvarlena_inoutfuncs]` with `#[derive(PostgresType)]`. -------------------------------------------------------------------------------- /pgrx-examples/aggregate/aggregate.control: -------------------------------------------------------------------------------- 1 | comment = 'aggregate: Created by pgrx' 2 | default_version = '@CARGO_VERSION@' 3 | module_pathname = 'aggregate' 4 | relocatable = false 5 | superuser = false 6 | -------------------------------------------------------------------------------- /pgrx-examples/aggregate/src/bin/pgrx_embed.rs: -------------------------------------------------------------------------------- 1 | ::pgrx::pgrx_embed!(); 2 | -------------------------------------------------------------------------------- /pgrx-examples/arrays/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .idea/ 3 | /target 4 | *.iml 5 | **/*.rs.bk 6 | Cargo.lock 7 | sql/arrays-1.0.sql 8 | -------------------------------------------------------------------------------- /pgrx-examples/arrays/Cargo.toml: -------------------------------------------------------------------------------- 1 | #LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 2 | #LICENSE 3 | #LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 4 | #LICENSE 5 | #LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 6 | #LICENSE 7 | #LICENSE All rights reserved. 8 | #LICENSE 9 | #LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 10 | 11 | [package] 12 | name = "arrays" 13 | version = "0.0.0" 14 | edition = "2021" 15 | publish = false 16 | 17 | [lib] 18 | crate-type = ["cdylib", "lib"] 19 | 20 | [[bin]] 21 | name = "pgrx_embed_arrays" 22 | path = "./src/bin/pgrx_embed.rs" 23 | 24 | [features] 25 | default = ["pg13"] 26 | pg13 = ["pgrx/pg13", "pgrx-tests/pg13"] 27 | pg14 = ["pgrx/pg14", "pgrx-tests/pg14"] 28 | pg15 = ["pgrx/pg15", "pgrx-tests/pg15"] 29 | pg16 = ["pgrx/pg16", "pgrx-tests/pg16"] 30 | pg17 = ["pgrx/pg17", "pgrx-tests/pg17"] 31 | pg18 = ["pgrx/pg18", "pgrx-tests/pg18"] 32 | pg_test = [] 33 | 34 | [dependencies] 35 | pgrx = { path = "../../pgrx", default-features = false } 36 | serde = "1.0" 37 | rand = "*" 38 | 39 | [dev-dependencies] 40 | pgrx-tests = { path = "../../pgrx-tests" } 41 | 42 | # uncomment these if compiling outside of 'pgrx' 43 | # [profile.dev] 44 | # panic = "unwind" 45 | 46 | # [profile.release] 47 | # panic = "unwind" 48 | # opt-level = 3 49 | # lto = "fat" 50 | # codegen-units = 1 51 | -------------------------------------------------------------------------------- /pgrx-examples/arrays/README.md: -------------------------------------------------------------------------------- 1 | Examples for working with Postgres arrays. 2 | 3 | Here's a video that walks through this example (and others): 4 | https://www.twitch.tv/videos/670479038 -------------------------------------------------------------------------------- /pgrx-examples/arrays/arrays.control: -------------------------------------------------------------------------------- 1 | comment = 'arrays: Created by pgrx' 2 | default_version = '0.1.0' 3 | module_pathname = 'arrays' 4 | relocatable = false 5 | superuser = false 6 | schema = arrays -------------------------------------------------------------------------------- /pgrx-examples/arrays/src/bin/pgrx_embed.rs: -------------------------------------------------------------------------------- 1 | ::pgrx::pgrx_embed!(); 2 | -------------------------------------------------------------------------------- /pgrx-examples/bad_ideas/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .idea/ 3 | /target 4 | *.iml 5 | **/*.rs.bk 6 | Cargo.lock 7 | sql/bad_ideas-1.0.sql 8 | -------------------------------------------------------------------------------- /pgrx-examples/bad_ideas/Cargo.toml: -------------------------------------------------------------------------------- 1 | #LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 2 | #LICENSE 3 | #LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 4 | #LICENSE 5 | #LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 6 | #LICENSE 7 | #LICENSE All rights reserved. 8 | #LICENSE 9 | #LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 10 | 11 | [package] 12 | name = "bad_ideas" 13 | version = "0.0.0" 14 | edition = "2021" 15 | publish = false 16 | 17 | [lib] 18 | crate-type = ["cdylib", "lib"] 19 | 20 | [[bin]] 21 | name = "pgrx_embed_bad_ideas" 22 | path = "./src/bin/pgrx_embed.rs" 23 | 24 | [features] 25 | default = ["pg13"] 26 | pg13 = ["pgrx/pg13", "pgrx-tests/pg13"] 27 | pg14 = ["pgrx/pg14", "pgrx-tests/pg14"] 28 | pg15 = ["pgrx/pg15", "pgrx-tests/pg15"] 29 | pg16 = ["pgrx/pg16", "pgrx-tests/pg16"] 30 | pg17 = ["pgrx/pg17", "pgrx-tests/pg17"] 31 | pg18 = ["pgrx/pg18", "pgrx-tests/pg18"] 32 | pg_test = [] 33 | 34 | [dependencies] 35 | pgrx = { path = "../../pgrx", default-features = false } 36 | rand = "0.9.0" 37 | ureq = "3.0.10" 38 | 39 | [dev-dependencies] 40 | pgrx-tests = { path = "../../pgrx-tests" } 41 | 42 | # uncomment these if compiling outside of 'pgrx' 43 | # [profile.dev] 44 | # panic = "unwind" 45 | 46 | # [profile.release] 47 | # panic = "unwind" 48 | # opt-level = 3 49 | # lto = "fat" 50 | # codegen-units = 1 51 | -------------------------------------------------------------------------------- /pgrx-examples/bad_ideas/README.md: -------------------------------------------------------------------------------- 1 | Some simple functions that demonstrate what are probably bad ideas to do in an extension. 2 | 3 | This one really is meant to be followed along via the video: 4 | https://www.twitch.tv/videos/694514963 -------------------------------------------------------------------------------- /pgrx-examples/bad_ideas/bad_ideas.control: -------------------------------------------------------------------------------- 1 | comment = 'bad_ideas: Created by pgrx' 2 | default_version = '@CARGO_VERSION@' 3 | module_pathname = 'bad_ideas' 4 | relocatable = false 5 | superuser = false 6 | -------------------------------------------------------------------------------- /pgrx-examples/bad_ideas/src/bin/pgrx_embed.rs: -------------------------------------------------------------------------------- 1 | ::pgrx::pgrx_embed!(); 2 | -------------------------------------------------------------------------------- /pgrx-examples/bgworker/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .idea/ 3 | /target 4 | *.iml 5 | **/*.rs.bk 6 | Cargo.lock 7 | sql/bgworker-1.0.sql 8 | -------------------------------------------------------------------------------- /pgrx-examples/bgworker/Cargo.toml: -------------------------------------------------------------------------------- 1 | #LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 2 | #LICENSE 3 | #LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 4 | #LICENSE 5 | #LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 6 | #LICENSE 7 | #LICENSE All rights reserved. 8 | #LICENSE 9 | #LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 10 | 11 | [package] 12 | name = "bgworker" 13 | version = "0.0.0" 14 | edition = "2021" 15 | publish = false 16 | 17 | [lib] 18 | crate-type = ["cdylib", "lib"] 19 | 20 | [[bin]] 21 | name = "pgrx_embed_bgworker" 22 | path = "./src/bin/pgrx_embed.rs" 23 | 24 | [features] 25 | default = ["pg13"] 26 | pg13 = ["pgrx/pg13", "pgrx-tests/pg13"] 27 | pg14 = ["pgrx/pg14", "pgrx-tests/pg14"] 28 | pg15 = ["pgrx/pg15", "pgrx-tests/pg15"] 29 | pg16 = ["pgrx/pg16", "pgrx-tests/pg16"] 30 | pg17 = ["pgrx/pg17", "pgrx-tests/pg17"] 31 | pg18 = ["pgrx/pg18", "pgrx-tests/pg18"] 32 | pg_test = [] 33 | 34 | [dependencies] 35 | pgrx = { path = "../../pgrx", default-features = false } 36 | 37 | [dev-dependencies] 38 | pgrx-tests = { path = "../../pgrx-tests" } 39 | 40 | # uncomment these if compiling outside of 'pgrx' 41 | # [profile.dev] 42 | # panic = "unwind" 43 | 44 | # [profile.release] 45 | # panic = "unwind" 46 | # opt-level = 3 47 | # lto = "fat" 48 | # codegen-units = 1 49 | -------------------------------------------------------------------------------- /pgrx-examples/bgworker/README.md: -------------------------------------------------------------------------------- 1 | A simple Background Worker that uses SPI (connected to a local database named `postgres`) in a 2 | transaction. 3 | 4 | In order to use this bgworker with pgrx, you'll need to edit the proper `postgresql.conf` file in 5 | "${PGRX_HOME}/data-$PGVER/postgresql.conf" and add this line to the end: 6 | 7 | ``` 8 | shared_preload_libraries = 'bgworker.so' 9 | ``` 10 | 11 | Background workers **must** be initialized in the extension's `_PG_init()` function, and can **only** 12 | be started if loaded through the `shared_preload_libraries` configuration setting. -------------------------------------------------------------------------------- /pgrx-examples/bgworker/bgworker.control: -------------------------------------------------------------------------------- 1 | comment = 'bgworker: Created by pgrx' 2 | default_version = '@CARGO_VERSION@' 3 | module_pathname = 'bgworker' 4 | relocatable = false 5 | superuser = false 6 | -------------------------------------------------------------------------------- /pgrx-examples/bgworker/src/bin/pgrx_embed.rs: -------------------------------------------------------------------------------- 1 | ::pgrx::pgrx_embed!(); 2 | -------------------------------------------------------------------------------- /pgrx-examples/bytea/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .idea/ 3 | /target 4 | *.iml 5 | **/*.rs.bk 6 | Cargo.lock 7 | sql/bytea-1.0.sql 8 | -------------------------------------------------------------------------------- /pgrx-examples/bytea/Cargo.toml: -------------------------------------------------------------------------------- 1 | #LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 2 | #LICENSE 3 | #LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 4 | #LICENSE 5 | #LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 6 | #LICENSE 7 | #LICENSE All rights reserved. 8 | #LICENSE 9 | #LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 10 | 11 | [package] 12 | name = "bytea" 13 | version = "0.0.0" 14 | edition = "2021" 15 | publish = false 16 | 17 | [lib] 18 | crate-type = ["cdylib", "lib"] 19 | 20 | [[bin]] 21 | name = "pgrx_embed_bytea" 22 | path = "./src/bin/pgrx_embed.rs" 23 | 24 | [features] 25 | default = ["pg13"] 26 | pg13 = ["pgrx/pg13", "pgrx-tests/pg13"] 27 | pg14 = ["pgrx/pg14", "pgrx-tests/pg14"] 28 | pg15 = ["pgrx/pg15", "pgrx-tests/pg15"] 29 | pg16 = ["pgrx/pg16", "pgrx-tests/pg16"] 30 | pg17 = ["pgrx/pg17", "pgrx-tests/pg17"] 31 | pg18 = ["pgrx/pg18", "pgrx-tests/pg18"] 32 | pg_test = [] 33 | 34 | [dependencies] 35 | pgrx = { path = "../../pgrx", default-features = false } 36 | libflate = "2.1.0" 37 | 38 | [dev-dependencies] 39 | pgrx-tests = { path = "../../pgrx-tests" } 40 | 41 | # uncomment these if compiling outside of 'pgrx' 42 | # [profile.dev] 43 | # panic = "unwind" 44 | 45 | # [profile.release] 46 | # panic = "unwind" 47 | # opt-level = 3 48 | # lto = "fat" 49 | # codegen-units = 1 50 | -------------------------------------------------------------------------------- /pgrx-examples/bytea/README.md: -------------------------------------------------------------------------------- 1 | Examples for working with Postgres `bytea` type. 2 | 3 | Postgres' `bytea` type can be represented as a borrowed `&[u8]` or an owned `Vec` with Rust. 4 | 5 | This example demonstrates how to use [`libflate`](https://crates.io/crates/libflate) to gzip/gunzip `bytea` (and `text`) data directly from UDFs. -------------------------------------------------------------------------------- /pgrx-examples/bytea/bytea.control: -------------------------------------------------------------------------------- 1 | comment = 'bytea: Created by pgrx' 2 | default_version = '@CARGO_VERSION@' 3 | module_pathname = 'bytea' 4 | relocatable = false 5 | superuser = false 6 | -------------------------------------------------------------------------------- /pgrx-examples/bytea/src/bin/pgrx_embed.rs: -------------------------------------------------------------------------------- 1 | ::pgrx::pgrx_embed!(); 2 | -------------------------------------------------------------------------------- /pgrx-examples/composite_type/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .idea/ 3 | /target 4 | *.iml 5 | **/*.rs.bk 6 | Cargo.lock 7 | sql/aggregate-1.0.sql 8 | -------------------------------------------------------------------------------- /pgrx-examples/composite_type/Cargo.toml: -------------------------------------------------------------------------------- 1 | #LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 2 | #LICENSE 3 | #LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 4 | #LICENSE 5 | #LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 6 | #LICENSE 7 | #LICENSE All rights reserved. 8 | #LICENSE 9 | #LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 10 | 11 | [package] 12 | name = "composite_type" 13 | version = "0.0.0" 14 | edition = "2021" 15 | publish = false 16 | 17 | [lib] 18 | crate-type = ["cdylib", "lib"] 19 | 20 | [[bin]] 21 | name = "pgrx_embed_composite_type" 22 | path = "./src/bin/pgrx_embed.rs" 23 | 24 | [features] 25 | default = ["pg13"] 26 | pg13 = ["pgrx/pg13", "pgrx-tests/pg13"] 27 | pg14 = ["pgrx/pg14", "pgrx-tests/pg14"] 28 | pg15 = ["pgrx/pg15", "pgrx-tests/pg15"] 29 | pg16 = ["pgrx/pg16", "pgrx-tests/pg16"] 30 | pg17 = ["pgrx/pg17", "pgrx-tests/pg17"] 31 | pg18 = ["pgrx/pg18", "pgrx-tests/pg18"] 32 | pg_test = [] 33 | 34 | [dependencies] 35 | pgrx = { path = "../../pgrx", default-features = false } 36 | serde = "1.0" 37 | 38 | [dev-dependencies] 39 | pgrx-tests = { path = "../../pgrx-tests" } 40 | 41 | # uncomment these if compiling outside of 'pgrx' 42 | # [profile.dev] 43 | # panic = "unwind" 44 | 45 | # [profile.release] 46 | # panic = "unwind" 47 | # opt-level = 3 48 | # lto = "fat" 49 | # codegen-units = 1 50 | -------------------------------------------------------------------------------- /pgrx-examples/composite_type/README.md: -------------------------------------------------------------------------------- 1 | An example of how to use composite types with `pgrx`. 2 | 3 | Demonstrates how to use composite types using `composite_type!()` in function arguments and aggregate implementations. 4 | -------------------------------------------------------------------------------- /pgrx-examples/composite_type/composite_type.control: -------------------------------------------------------------------------------- 1 | comment = 'composite_type: Created by pgrx' 2 | default_version = '@CARGO_VERSION@' 3 | module_pathname = 'composite_type' 4 | relocatable = false 5 | superuser = false 6 | -------------------------------------------------------------------------------- /pgrx-examples/composite_type/src/bin/pgrx_embed.rs: -------------------------------------------------------------------------------- 1 | ::pgrx::pgrx_embed!(); 2 | -------------------------------------------------------------------------------- /pgrx-examples/custom_libname/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .idea/ 3 | /target 4 | *.iml 5 | **/*.rs.bk 6 | Cargo.lock 7 | -------------------------------------------------------------------------------- /pgrx-examples/custom_libname/Cargo.toml: -------------------------------------------------------------------------------- 1 | #LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 2 | #LICENSE 3 | #LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 4 | #LICENSE 5 | #LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 6 | #LICENSE 7 | #LICENSE All rights reserved. 8 | #LICENSE 9 | #LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 10 | 11 | [package] 12 | name = "custom_libname" 13 | version = "0.0.0" 14 | edition = "2021" 15 | publish = false 16 | 17 | [lib] 18 | crate-type = ["cdylib", "lib"] 19 | name = "other_name" 20 | 21 | [[bin]] 22 | name = "pgrx_embed_custom_libname" 23 | path = "./src/bin/pgrx_embed.rs" 24 | 25 | [features] 26 | default = ["pg13"] 27 | pg13 = ["pgrx/pg13", "pgrx-tests/pg13"] 28 | pg14 = ["pgrx/pg14", "pgrx-tests/pg14"] 29 | pg15 = ["pgrx/pg15", "pgrx-tests/pg15"] 30 | pg16 = ["pgrx/pg16", "pgrx-tests/pg16"] 31 | pg17 = ["pgrx/pg17", "pgrx-tests/pg17"] 32 | pg18 = ["pgrx/pg18", "pgrx-tests/pg18"] 33 | pg_test = [] 34 | 35 | [dependencies] 36 | pgrx = { path = "../../pgrx", default-features = false } 37 | 38 | [dev-dependencies] 39 | pgrx-tests = { path = "../../pgrx-tests" } 40 | 41 | # uncomment these if compiling outside of 'pgrx' 42 | #[profile.dev] 43 | #panic = "unwind" 44 | 45 | #[profile.release] 46 | #panic = "unwind" 47 | #opt-level = 3 48 | #lto = "fat" 49 | #codegen-units = 1 50 | -------------------------------------------------------------------------------- /pgrx-examples/custom_libname/other_name.control: -------------------------------------------------------------------------------- 1 | comment = 'custom_libname: Created by pgrx' 2 | default_version = '@CARGO_VERSION@' 3 | module_pathname = 'other_name' 4 | relocatable = false 5 | superuser = false 6 | -------------------------------------------------------------------------------- /pgrx-examples/custom_libname/src/bin/pgrx_embed.rs: -------------------------------------------------------------------------------- 1 | ::pgrx::pgrx_embed!(); 2 | -------------------------------------------------------------------------------- /pgrx-examples/custom_libname/src/lib.rs: -------------------------------------------------------------------------------- 1 | //LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 2 | //LICENSE 3 | //LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 4 | //LICENSE 5 | //LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 6 | //LICENSE 7 | //LICENSE All rights reserved. 8 | //LICENSE 9 | //LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 10 | use pgrx::prelude::*; 11 | 12 | pgrx::pg_module_magic!(c"custom_libname", pgrx::pg_sys::PG_VERSION); 13 | 14 | #[pg_extern] 15 | fn hello_custom_libname() -> &'static str { 16 | "Hello, custom_libname" 17 | } 18 | 19 | #[cfg(any(test, feature = "pg_test"))] 20 | #[pg_schema] 21 | mod tests { 22 | use pgrx::prelude::*; 23 | 24 | #[pg_test] 25 | fn test_hello_custom_libname() { 26 | assert_eq!("Hello, custom_libname", crate::hello_custom_libname()); 27 | } 28 | } 29 | 30 | #[cfg(test)] 31 | pub mod pg_test { 32 | pub fn setup(_options: Vec<&str>) { 33 | // perform one-off initialization when the pg_test framework starts 34 | } 35 | 36 | pub fn postgresql_conf_options() -> Vec<&'static str> { 37 | // return any postgresql.conf settings that are required for your tests 38 | vec![] 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /pgrx-examples/custom_sql/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .idea/ 3 | /target 4 | *.iml 5 | **/*.rs.bk 6 | Cargo.lock 7 | sql/custom_sql-1.0.sql 8 | -------------------------------------------------------------------------------- /pgrx-examples/custom_sql/Cargo.toml: -------------------------------------------------------------------------------- 1 | #LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 2 | #LICENSE 3 | #LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 4 | #LICENSE 5 | #LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 6 | #LICENSE 7 | #LICENSE All rights reserved. 8 | #LICENSE 9 | #LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 10 | 11 | [package] 12 | name = "custom_sql" 13 | version = "0.0.0" 14 | edition = "2021" 15 | publish = false 16 | 17 | [lib] 18 | crate-type = ["cdylib", "lib"] 19 | 20 | [[bin]] 21 | name = "pgrx_embed_custom_sql" 22 | path = "./src/bin/pgrx_embed.rs" 23 | 24 | [features] 25 | default = ["pg13"] 26 | pg13 = ["pgrx/pg13", "pgrx-tests/pg13"] 27 | pg14 = ["pgrx/pg14", "pgrx-tests/pg14"] 28 | pg15 = ["pgrx/pg15", "pgrx-tests/pg15"] 29 | pg16 = ["pgrx/pg16", "pgrx-tests/pg16"] 30 | pg17 = ["pgrx/pg17", "pgrx-tests/pg17"] 31 | pg18 = ["pgrx/pg18", "pgrx-tests/pg18"] 32 | pg_test = [] 33 | 34 | [dependencies] 35 | pgrx = { path = "../../pgrx", default-features = false } 36 | serde = "1.0" 37 | 38 | [dev-dependencies] 39 | pgrx-tests = { path = "../../pgrx-tests" } 40 | 41 | # uncomment these if compiling outside of 'pgrx' 42 | # [profile.dev] 43 | # panic = "unwind" 44 | 45 | # [profile.release] 46 | # panic = "unwind" 47 | # opt-level = 3 48 | # lto = "fat" 49 | # codegen-units = 1 50 | -------------------------------------------------------------------------------- /pgrx-examples/custom_sql/README.md: -------------------------------------------------------------------------------- 1 | Examples for working with Postgres `extension_sql` and `extension_sql_file` macros. 2 | 3 | Postgres' `bytea` type can be represented as a borrowed `&[u8]` or an owned `Vec` with Rust. 4 | 5 | This example demonstrates how to use [`libflate`](https://crates.io/crates/libflate) to gzip/gunzip `bytea` (and `text`) data directly from UDFs. -------------------------------------------------------------------------------- /pgrx-examples/custom_sql/custom_sql.control: -------------------------------------------------------------------------------- 1 | comment = 'custom_sql: Created by pgrx' 2 | default_version = '@CARGO_VERSION@' 3 | module_pathname = 'custom_sql' 4 | relocatable = false 5 | superuser = false 6 | -------------------------------------------------------------------------------- /pgrx-examples/custom_sql/sql/finalizer.sql: -------------------------------------------------------------------------------- 1 | --LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 2 | --LICENSE 3 | --LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 4 | --LICENSE 5 | --LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 6 | --LICENSE 7 | --LICENSE All rights reserved. 8 | --LICENSE 9 | --LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 10 | 11 | 12 | INSERT INTO extension_sql VALUES ('finalizer'); 13 | -------------------------------------------------------------------------------- /pgrx-examples/custom_sql/sql/multiple.sql: -------------------------------------------------------------------------------- 1 | --LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 2 | --LICENSE 3 | --LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 4 | --LICENSE 5 | --LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 6 | --LICENSE 7 | --LICENSE All rights reserved. 8 | --LICENSE 9 | --LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 10 | 11 | 12 | INSERT INTO extension_sql VALUES ('multiple'); 13 | -------------------------------------------------------------------------------- /pgrx-examples/custom_sql/sql/single.sql: -------------------------------------------------------------------------------- 1 | --LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 2 | --LICENSE 3 | --LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 4 | --LICENSE 5 | --LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 6 | --LICENSE 7 | --LICENSE All rights reserved. 8 | --LICENSE 9 | --LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 10 | 11 | 12 | INSERT INTO extension_sql VALUES ('single'); 13 | -------------------------------------------------------------------------------- /pgrx-examples/custom_sql/src/bin/pgrx_embed.rs: -------------------------------------------------------------------------------- 1 | ::pgrx::pgrx_embed!(); 2 | -------------------------------------------------------------------------------- /pgrx-examples/custom_types/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .idea/ 3 | /target 4 | *.iml 5 | **/*.rs.bk 6 | Cargo.lock 7 | sql/custom_types-1.0.sql 8 | -------------------------------------------------------------------------------- /pgrx-examples/custom_types/Cargo.toml: -------------------------------------------------------------------------------- 1 | #LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 2 | #LICENSE 3 | #LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 4 | #LICENSE 5 | #LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 6 | #LICENSE 7 | #LICENSE All rights reserved. 8 | #LICENSE 9 | #LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 10 | 11 | [package] 12 | name = "custom_types" 13 | version = "0.0.0" 14 | edition = "2021" 15 | publish = false 16 | 17 | [lib] 18 | crate-type = ["cdylib", "lib"] 19 | 20 | [[bin]] 21 | name = "pgrx_embed_custom_types" 22 | path = "./src/bin/pgrx_embed.rs" 23 | 24 | [features] 25 | default = ["pg13"] 26 | pg13 = ["pgrx/pg13", "pgrx-tests/pg13"] 27 | pg14 = ["pgrx/pg14", "pgrx-tests/pg14"] 28 | pg15 = ["pgrx/pg15", "pgrx-tests/pg15"] 29 | pg16 = ["pgrx/pg16", "pgrx-tests/pg16"] 30 | pg17 = ["pgrx/pg17", "pgrx-tests/pg17"] 31 | pg18 = ["pgrx/pg18", "pgrx-tests/pg18"] 32 | pg_test = [] 33 | no-schema-generation = ["pgrx/no-schema-generation", "pgrx-tests/no-schema-generation"] 34 | 35 | [dependencies] 36 | pgrx = { path = "../../pgrx", default-features = false } 37 | maplit = "1.0.2" 38 | serde = "1.0" 39 | 40 | [dev-dependencies] 41 | pgrx-tests = { path = "../../pgrx-tests" } 42 | 43 | # uncomment these if compiling outside of 'pgrx' 44 | # [profile.dev] 45 | # panic = "unwind" 46 | 47 | # [profile.release] 48 | # panic = "unwind" 49 | # opt-level = 3 50 | # lto = "fat" 51 | # codegen-units = 1 52 | -------------------------------------------------------------------------------- /pgrx-examples/custom_types/custom_types.control: -------------------------------------------------------------------------------- 1 | comment = 'custom_types: Created by pgrx' 2 | default_version = '@CARGO_VERSION@' 3 | module_pathname = 'custom_types' 4 | relocatable = false 5 | superuser = false 6 | trusted = false 7 | -------------------------------------------------------------------------------- /pgrx-examples/custom_types/src/bin/pgrx_embed.rs: -------------------------------------------------------------------------------- 1 | ::pgrx::pgrx_embed!(); 2 | -------------------------------------------------------------------------------- /pgrx-examples/custom_types/src/generic_enum.rs: -------------------------------------------------------------------------------- 1 | //LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 2 | //LICENSE 3 | //LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 4 | //LICENSE 5 | //LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 6 | //LICENSE 7 | //LICENSE All rights reserved. 8 | //LICENSE 9 | //LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 10 | use pgrx::prelude::*; 11 | use serde::*; 12 | use std::fmt::{Display, Formatter}; 13 | 14 | #[derive(PostgresEnum, Serialize)] 15 | pub enum SomeValue { 16 | One, 17 | Two, 18 | Three, 19 | Four, 20 | Five, 21 | } 22 | 23 | impl Display for SomeValue { 24 | fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> { 25 | match self { 26 | SomeValue::One => write!(f, "1: one"), 27 | SomeValue::Two => write!(f, "2: two"), 28 | SomeValue::Three => write!(f, "3: three"), 29 | SomeValue::Four => write!(f, "4: four"), 30 | SomeValue::Five => write!(f, "5: five"), 31 | } 32 | } 33 | } 34 | 35 | #[pg_extern] 36 | fn get_some_value_name(input: SomeValue) -> String { 37 | format!("{input}") 38 | } 39 | -------------------------------------------------------------------------------- /pgrx-examples/custom_types/src/lib.rs: -------------------------------------------------------------------------------- 1 | //LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 2 | //LICENSE 3 | //LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 4 | //LICENSE 5 | //LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 6 | //LICENSE 7 | //LICENSE All rights reserved. 8 | //LICENSE 9 | //LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 10 | mod alignment; 11 | mod complex; 12 | mod fixed_size; 13 | mod generic_enum; 14 | mod hexint; 15 | mod hstore_clone; 16 | mod ordered; 17 | mod rust_enum; 18 | 19 | pgrx::pg_module_magic!(c"custom_types", pgrx::pg_sys::PG_VERSION); 20 | 21 | #[cfg(test)] 22 | pub mod pg_test { 23 | 24 | pub fn setup(_options: Vec<&str>) { 25 | // perform one-off initialization when the pg_test framework starts 26 | } 27 | 28 | pub fn postgresql_conf_options() -> Vec<&'static str> { 29 | // return any postgresql.conf settings that are required for your tests 30 | vec![] 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /pgrx-examples/custom_types/src/rust_enum.rs: -------------------------------------------------------------------------------- 1 | //LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 2 | //LICENSE 3 | //LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 4 | //LICENSE 5 | //LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 6 | //LICENSE 7 | //LICENSE All rights reserved. 8 | //LICENSE 9 | //LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 10 | use pgrx::prelude::*; 11 | use serde::*; 12 | 13 | #[derive(PostgresType, Serialize, Deserialize)] 14 | #[serde(untagged)] 15 | pub enum SomeEnum { 16 | String(String), 17 | Struct { a: usize, s: String }, 18 | } 19 | 20 | #[cfg(any(test, feature = "pg_test"))] 21 | #[pg_schema] 22 | mod tests { 23 | use crate::rust_enum::SomeEnum; 24 | use pgrx::prelude::*; 25 | 26 | #[cfg(not(feature = "no-schema-generation"))] 27 | #[pg_test] 28 | fn test_some_enum() { 29 | let val = Spi::get_one::(r#"SELECT '"hello world"'::SomeEnum"#); 30 | 31 | assert!(matches!( 32 | val, 33 | Ok(Some(SomeEnum::String(s))) if s == "hello world" 34 | )); 35 | 36 | let val = Spi::get_one::(r#"SELECT '{"a": 1, "s": "hello world"}'::SomeEnum"#); 37 | 38 | assert!(matches!( 39 | val, 40 | Ok(Some(SomeEnum::Struct{a: 1, s })) if s == "hello world" 41 | )); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /pgrx-examples/datetime/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .idea/ 3 | /target 4 | *.iml 5 | **/*.rs.bk 6 | Cargo.lock 7 | sql/arrays-1.0.sql 8 | -------------------------------------------------------------------------------- /pgrx-examples/datetime/Cargo.toml: -------------------------------------------------------------------------------- 1 | #LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 2 | #LICENSE 3 | #LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 4 | #LICENSE 5 | #LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 6 | #LICENSE 7 | #LICENSE All rights reserved. 8 | #LICENSE 9 | #LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 10 | 11 | [package] 12 | name = "datetime" 13 | version = "0.0.0" 14 | edition = "2021" 15 | publish = false 16 | 17 | [lib] 18 | crate-type = ["cdylib", "lib"] 19 | 20 | [[bin]] 21 | name = "pgrx_embed_datetime" 22 | path = "./src/bin/pgrx_embed.rs" 23 | 24 | [features] 25 | default = ["pg13"] 26 | pg13 = ["pgrx/pg13", "pgrx-tests/pg13"] 27 | pg14 = ["pgrx/pg14", "pgrx-tests/pg14"] 28 | pg15 = ["pgrx/pg15", "pgrx-tests/pg15"] 29 | pg16 = ["pgrx/pg16", "pgrx-tests/pg16"] 30 | pg17 = ["pgrx/pg17", "pgrx-tests/pg17"] 31 | pg18 = ["pgrx/pg18", "pgrx-tests/pg18"] 32 | pg_test = [] 33 | 34 | [dependencies] 35 | pgrx = { path = "../../pgrx", default-features = false } 36 | rand = "0.9" 37 | 38 | [dev-dependencies] 39 | pgrx-tests = { path = "../../pgrx-tests" } 40 | 41 | # uncomment these if compiling outside of 'pgrx' 42 | # [profile.dev] 43 | # panic = "unwind" 44 | 45 | # [profile.release] 46 | # panic = "unwind" 47 | # opt-level = 3 48 | # lto = "fat" 49 | # codegen-units = 1 50 | -------------------------------------------------------------------------------- /pgrx-examples/datetime/README.md: -------------------------------------------------------------------------------- 1 | Examples for working with Dates and Times with pgrx. -------------------------------------------------------------------------------- /pgrx-examples/datetime/datetime.control: -------------------------------------------------------------------------------- 1 | comment = 'arrays: Created by pgrx' 2 | default_version = '0.1.0' 3 | module_pathname = 'datetime' 4 | relocatable = true 5 | superuser = false -------------------------------------------------------------------------------- /pgrx-examples/datetime/src/bin/pgrx_embed.rs: -------------------------------------------------------------------------------- 1 | ::pgrx::pgrx_embed!(); 2 | -------------------------------------------------------------------------------- /pgrx-examples/errors/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .idea/ 3 | /target 4 | *.iml 5 | **/*.rs.bk 6 | Cargo.lock 7 | sql/errors-1.0.sql 8 | -------------------------------------------------------------------------------- /pgrx-examples/errors/Cargo.toml: -------------------------------------------------------------------------------- 1 | #LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 2 | #LICENSE 3 | #LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 4 | #LICENSE 5 | #LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 6 | #LICENSE 7 | #LICENSE All rights reserved. 8 | #LICENSE 9 | #LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 10 | 11 | [package] 12 | name = "errors" 13 | version = "0.0.0" 14 | edition = "2021" 15 | publish = false 16 | 17 | [lib] 18 | crate-type = ["cdylib", "lib"] 19 | 20 | [[bin]] 21 | name = "pgrx_embed_errors" 22 | path = "./src/bin/pgrx_embed.rs" 23 | 24 | [features] 25 | default = ["pg13"] 26 | pg13 = ["pgrx/pg13", "pgrx-tests/pg13"] 27 | pg14 = ["pgrx/pg14", "pgrx-tests/pg14"] 28 | pg15 = ["pgrx/pg15", "pgrx-tests/pg15"] 29 | pg16 = ["pgrx/pg16", "pgrx-tests/pg16"] 30 | pg17 = ["pgrx/pg17", "pgrx-tests/pg17"] 31 | pg18 = ["pgrx/pg18", "pgrx-tests/pg18"] 32 | pg_test = [] 33 | 34 | [dependencies] 35 | pgrx = { path = "../../pgrx", default-features = false } 36 | 37 | [dev-dependencies] 38 | pgrx-tests = { path = "../../pgrx-tests" } 39 | 40 | # uncomment these if compiling outside of 'pgrx' 41 | # [profile.dev] 42 | # panic = "unwind" 43 | 44 | # [profile.release] 45 | # panic = "unwind" 46 | # opt-level = 3 47 | # lto = "fat" 48 | # codegen-units = 1 49 | -------------------------------------------------------------------------------- /pgrx-examples/errors/README.md: -------------------------------------------------------------------------------- 1 | Examples for working with Postgres and Rust errors and panics. 2 | 3 | Here's a video that walks through this example (and others): 4 | https://www.twitch.tv/videos/670479038 -------------------------------------------------------------------------------- /pgrx-examples/errors/errors.control: -------------------------------------------------------------------------------- 1 | comment = 'errors: Created by pgrx' 2 | default_version = '@CARGO_VERSION@' 3 | module_pathname = 'errors' 4 | relocatable = false 5 | superuser = false 6 | schema = errors -------------------------------------------------------------------------------- /pgrx-examples/errors/src/bin/pgrx_embed.rs: -------------------------------------------------------------------------------- 1 | ::pgrx::pgrx_embed!(); 2 | -------------------------------------------------------------------------------- /pgrx-examples/nostd/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .idea/ 3 | /target 4 | *.iml 5 | **/*.rs.bk 6 | Cargo.lock 7 | sql/nostd-1.0.sql 8 | -------------------------------------------------------------------------------- /pgrx-examples/nostd/Cargo.toml: -------------------------------------------------------------------------------- 1 | #LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 2 | #LICENSE 3 | #LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 4 | #LICENSE 5 | #LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 6 | #LICENSE 7 | #LICENSE All rights reserved. 8 | #LICENSE 9 | #LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 10 | 11 | [package] 12 | name = "nostd" 13 | version = "0.0.0" 14 | edition = "2021" 15 | publish = false 16 | 17 | [lib] 18 | crate-type = ["cdylib", "lib"] 19 | 20 | [[bin]] 21 | name = "pgrx_embed_nostd" 22 | path = "./src/bin/pgrx_embed.rs" 23 | 24 | [features] 25 | default = ["pg13"] 26 | pg13 = ["pgrx/pg13", "pgrx-tests/pg13"] 27 | pg14 = ["pgrx/pg14", "pgrx-tests/pg14"] 28 | pg15 = ["pgrx/pg15", "pgrx-tests/pg15"] 29 | pg16 = ["pgrx/pg16", "pgrx-tests/pg16"] 30 | pg17 = ["pgrx/pg17", "pgrx-tests/pg17"] 31 | pg18 = ["pgrx/pg18", "pgrx-tests/pg18"] 32 | pg_test = [] 33 | 34 | [dependencies] 35 | pgrx = { path = "../../pgrx", default-features = false } 36 | serde = "1.0" 37 | 38 | [dev-dependencies] 39 | pgrx-tests = { path = "../../pgrx-tests" } 40 | 41 | # uncomment these if compiling outside of 'pgrx' 42 | # [profile.dev] 43 | # panic = "unwind" 44 | 45 | # [profile.release] 46 | # panic = "unwind" 47 | # opt-level = 3 48 | # lto = "fat" 49 | # codegen-units = 1 50 | -------------------------------------------------------------------------------- /pgrx-examples/nostd/nostd.control: -------------------------------------------------------------------------------- 1 | comment = 'nostd: Created by pgrx' 2 | default_version = '1.0' 3 | module_pathname = 'nostd' 4 | relocatable = false 5 | superuser = false 6 | -------------------------------------------------------------------------------- /pgrx-examples/nostd/src/bin/pgrx_embed.rs: -------------------------------------------------------------------------------- 1 | ::pgrx::pgrx_embed!(); 2 | -------------------------------------------------------------------------------- /pgrx-examples/numeric/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .idea/ 3 | /target 4 | *.iml 5 | **/*.rs.bk 6 | Cargo.lock 7 | -------------------------------------------------------------------------------- /pgrx-examples/numeric/Cargo.toml: -------------------------------------------------------------------------------- 1 | #LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 2 | #LICENSE 3 | #LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 4 | #LICENSE 5 | #LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 6 | #LICENSE 7 | #LICENSE All rights reserved. 8 | #LICENSE 9 | #LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 10 | 11 | [package] 12 | name = "numeric" 13 | version = "0.0.0" 14 | edition = "2021" 15 | publish = false 16 | rust-version = "1.58" 17 | 18 | [lib] 19 | crate-type = ["cdylib", "lib"] 20 | 21 | [[bin]] 22 | name = "pgrx_embed_numeric" 23 | path = "./src/bin/pgrx_embed.rs" 24 | 25 | [features] 26 | default = ["pg13"] 27 | pg13 = ["pgrx/pg13", "pgrx-tests/pg13"] 28 | pg14 = ["pgrx/pg14", "pgrx-tests/pg14"] 29 | pg15 = ["pgrx/pg15", "pgrx-tests/pg15"] 30 | pg16 = ["pgrx/pg16", "pgrx-tests/pg16"] 31 | pg17 = ["pgrx/pg17", "pgrx-tests/pg17"] 32 | pg18 = ["pgrx/pg18", "pgrx-tests/pg18"] 33 | pg_test = [] 34 | 35 | [dependencies] 36 | pgrx = { path = "../../pgrx", default-features = false } 37 | rand = "0.8.5" 38 | 39 | [dev-dependencies] 40 | pgrx-tests = { path = "../../pgrx-tests" } 41 | 42 | #[profile.dev] 43 | #panic = "unwind" 44 | # 45 | #[profile.release] 46 | #panic = "unwind" 47 | #opt-level = 3 48 | #lto = "fat" 49 | #codegen-units = 1 50 | -------------------------------------------------------------------------------- /pgrx-examples/numeric/numeric.control: -------------------------------------------------------------------------------- 1 | comment = 'numeric: Created by pgrx' 2 | default_version = '@CARGO_VERSION@' 3 | module_pathname = 'numeric' 4 | relocatable = false 5 | superuser = false 6 | -------------------------------------------------------------------------------- /pgrx-examples/numeric/src/bin/pgrx_embed.rs: -------------------------------------------------------------------------------- 1 | ::pgrx::pgrx_embed!(); 2 | -------------------------------------------------------------------------------- /pgrx-examples/operators/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .idea/ 3 | /target 4 | *.iml 5 | **/*.rs.bk 6 | Cargo.lock 7 | sql/operators-1.0.sql 8 | -------------------------------------------------------------------------------- /pgrx-examples/operators/Cargo.toml: -------------------------------------------------------------------------------- 1 | #LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 2 | #LICENSE 3 | #LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 4 | #LICENSE 5 | #LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 6 | #LICENSE 7 | #LICENSE All rights reserved. 8 | #LICENSE 9 | #LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 10 | 11 | [package] 12 | name = "operators" 13 | version = "0.0.0" 14 | edition = "2021" 15 | publish = false 16 | 17 | [lib] 18 | crate-type = ["cdylib", "lib"] 19 | 20 | [[bin]] 21 | name = "pgrx_embed_operators" 22 | path = "./src/bin/pgrx_embed.rs" 23 | 24 | [features] 25 | default = ["pg13"] 26 | pg13 = ["pgrx/pg13", "pgrx-tests/pg13"] 27 | pg14 = ["pgrx/pg14", "pgrx-tests/pg14"] 28 | pg15 = ["pgrx/pg15", "pgrx-tests/pg15"] 29 | pg16 = ["pgrx/pg16", "pgrx-tests/pg16"] 30 | pg17 = ["pgrx/pg17", "pgrx-tests/pg17"] 31 | pg18 = ["pgrx/pg18", "pgrx-tests/pg18"] 32 | pg_test = [] 33 | 34 | [dependencies] 35 | pgrx = { path = "../../pgrx", default-features = false } 36 | serde = "1.0" 37 | 38 | [dev-dependencies] 39 | pgrx-tests = { path = "../../pgrx-tests" } 40 | 41 | # uncomment these if compiling outside of 'pgrx' 42 | # [profile.dev] 43 | # panic = "unwind" 44 | 45 | # [profile.release] 46 | # panic = "unwind" 47 | # opt-level = 3 48 | # lto = "fat" 49 | # codegen-units = 1 50 | -------------------------------------------------------------------------------- /pgrx-examples/operators/operators.control: -------------------------------------------------------------------------------- 1 | comment = 'operators: Created by pgrx' 2 | default_version = '@CARGO_VERSION@' 3 | module_pathname = 'operators' 4 | relocatable = false 5 | superuser = false 6 | -------------------------------------------------------------------------------- /pgrx-examples/operators/src/bin/pgrx_embed.rs: -------------------------------------------------------------------------------- 1 | ::pgrx::pgrx_embed!(); 2 | -------------------------------------------------------------------------------- /pgrx-examples/operators/src/derived.rs: -------------------------------------------------------------------------------- 1 | //LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 2 | //LICENSE 3 | //LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 4 | //LICENSE 5 | //LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 6 | //LICENSE 7 | //LICENSE All rights reserved. 8 | //LICENSE 9 | //LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 10 | use pgrx::prelude::*; 11 | use serde::{Deserialize, Serialize}; 12 | 13 | /// standard Rust equality/comparison derives 14 | #[derive(Eq, PartialEq, Ord, Hash, PartialOrd)] 15 | 16 | /// Support using this struct as a Postgres type, which the easy way requires Serde 17 | #[derive(PostgresType, Serialize, Deserialize)] 18 | 19 | /// automatically generate =, <> SQL operator functions 20 | #[derive(PostgresEq)] 21 | 22 | /// automatically generate <, >, <=, >=, and a "_cmp" SQL functions 23 | /// When "PostgresEq" is also derived, pgrx also creates an "opclass" (and family) 24 | /// so that the type can be used in indexes `USING btree` 25 | #[derive(PostgresOrd)] 26 | 27 | /// automatically generate a "_hash" function, and the necessary "opclass" (and family) 28 | /// so the type can also be used in indexes `USING hash` 29 | #[derive(PostgresHash)] 30 | pub struct Thing(String); 31 | 32 | // and there's no code to write! 33 | -------------------------------------------------------------------------------- /pgrx-examples/operators/src/lib.rs: -------------------------------------------------------------------------------- 1 | //LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 2 | //LICENSE 3 | //LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 4 | //LICENSE 5 | //LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 6 | //LICENSE 7 | //LICENSE All rights reserved. 8 | //LICENSE 9 | //LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 10 | use pgrx::prelude::*; 11 | use pgrx::{opname, pg_operator}; 12 | use serde::{Deserialize, Serialize}; 13 | mod derived; 14 | mod pgvarlena; 15 | 16 | pgrx::pg_module_magic!(c"operators", pgrx::pg_sys::PG_VERSION); 17 | 18 | #[derive(PostgresType, Serialize, Deserialize, Eq, PartialEq)] 19 | pub struct MyType { 20 | value: i32, 21 | } 22 | 23 | #[pg_operator] 24 | #[opname(=)] 25 | fn my_eq(left: MyType, right: MyType) -> bool { 26 | left == right 27 | } 28 | 29 | #[cfg(test)] 30 | pub mod pg_test { 31 | pub fn setup(_options: Vec<&str>) { 32 | // perform one-off initialization when the pg_test framework starts 33 | } 34 | 35 | pub fn postgresql_conf_options() -> Vec<&'static str> { 36 | // return any postgresql.conf settings that are required for your tests 37 | vec![] 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /pgrx-examples/pgtrybuilder/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .idea/ 3 | /target 4 | *.iml 5 | **/*.rs.bk 6 | Cargo.lock 7 | -------------------------------------------------------------------------------- /pgrx-examples/pgtrybuilder/Cargo.toml: -------------------------------------------------------------------------------- 1 | #LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 2 | #LICENSE 3 | #LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 4 | #LICENSE 5 | #LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 6 | #LICENSE 7 | #LICENSE All rights reserved. 8 | #LICENSE 9 | #LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 10 | 11 | [package] 12 | name = "pgtrybuilder" 13 | version = "0.0.0" 14 | edition = "2021" 15 | publish = false 16 | 17 | [lib] 18 | crate-type = ["cdylib", "lib"] 19 | 20 | [[bin]] 21 | name = "pgrx_embed_pgtrybuilder" 22 | path = "./src/bin/pgrx_embed.rs" 23 | 24 | [features] 25 | default = ["pg13"] 26 | pg13 = ["pgrx/pg13", "pgrx-tests/pg13"] 27 | pg14 = ["pgrx/pg14", "pgrx-tests/pg14"] 28 | pg15 = ["pgrx/pg15", "pgrx-tests/pg15"] 29 | pg16 = ["pgrx/pg16", "pgrx-tests/pg16"] 30 | pg17 = ["pgrx/pg17", "pgrx-tests/pg17"] 31 | pg18 = ["pgrx/pg18", "pgrx-tests/pg18"] 32 | pg_test = [] 33 | 34 | [dependencies] 35 | pgrx = { path = "../../pgrx", default-features = false } 36 | 37 | [dev-dependencies] 38 | pgrx-tests = { path = "../../pgrx-tests" } 39 | 40 | # uncomment these if compiling outside of 'pgrx' 41 | # [profile.dev] 42 | # panic = "unwind" 43 | 44 | # [profile.release] 45 | # panic = "unwind" 46 | # opt-level = 3 47 | # lto = "fat" 48 | # codegen-units = 1 49 | -------------------------------------------------------------------------------- /pgrx-examples/pgtrybuilder/README.md: -------------------------------------------------------------------------------- 1 | Examples for working with Postgres and Rust panics using `PgTryBuilder` 2 | -------------------------------------------------------------------------------- /pgrx-examples/pgtrybuilder/pgtrybuilder.control: -------------------------------------------------------------------------------- 1 | comment = 'pgtrybuilder: Created by pgrx' 2 | default_version = '@CARGO_VERSION@' 3 | module_pathname = 'pgtrybuilder' 4 | relocatable = false 5 | superuser = false 6 | schema = pgtrybuilder -------------------------------------------------------------------------------- /pgrx-examples/pgtrybuilder/src/bin/pgrx_embed.rs: -------------------------------------------------------------------------------- 1 | ::pgrx::pgrx_embed!(); 2 | -------------------------------------------------------------------------------- /pgrx-examples/range/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .idea/ 3 | /target 4 | *.iml 5 | **/*.rs.bk 6 | Cargo.lock 7 | sql/arrays-1.0.sql 8 | tests/pg_regress/results 9 | tests/pg_regress/regression.diffs 10 | tests/pg_regress/regression.out 11 | -------------------------------------------------------------------------------- /pgrx-examples/range/Cargo.toml: -------------------------------------------------------------------------------- 1 | #LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 2 | #LICENSE 3 | #LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 4 | #LICENSE 5 | #LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 6 | #LICENSE 7 | #LICENSE All rights reserved. 8 | #LICENSE 9 | #LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 10 | 11 | [package] 12 | name = "range" 13 | version = "0.0.0" 14 | edition = "2021" 15 | publish = false 16 | 17 | [lib] 18 | crate-type = ["cdylib", "lib"] 19 | 20 | [[bin]] 21 | name = "pgrx_embed_range" 22 | path = "./src/bin/pgrx_embed.rs" 23 | 24 | [features] 25 | default = ["pg13"] 26 | pg13 = ["pgrx/pg13", "pgrx-tests/pg13"] 27 | pg14 = ["pgrx/pg14", "pgrx-tests/pg14"] 28 | pg15 = ["pgrx/pg15", "pgrx-tests/pg15"] 29 | pg16 = ["pgrx/pg16", "pgrx-tests/pg16"] 30 | pg17 = ["pgrx/pg17", "pgrx-tests/pg17"] 31 | pg18 = ["pgrx/pg18", "pgrx-tests/pg18"] 32 | pg_test = [] 33 | 34 | [dependencies] 35 | pgrx = { path = "../../pgrx", default-features = false } 36 | 37 | [dev-dependencies] 38 | pgrx-tests = { path = "../../pgrx-tests" } 39 | 40 | # uncomment these if compiling outside of 'pgrx' 41 | # [profile.dev] 42 | # panic = "unwind" 43 | 44 | # [profile.release] 45 | # panic = "unwind" 46 | # opt-level = 3 47 | # lto = "fat" 48 | # codegen-units = 1 49 | -------------------------------------------------------------------------------- /pgrx-examples/range/README.md: -------------------------------------------------------------------------------- 1 | Examples for using pgrx' `Range` support. 2 | 3 | pgrx supports the Postgres `int4range`, `int8range`, `numrange`, `daterange`, `tsrange`, and `tstzrange` types, safely 4 | mapped to `pgrx::Range` where `T` is any of `i32`, `i64`, `Numeric`, `AnyNumeric`, `Date`, `Timestamp`, and `TimestampWithTimeZone`. -------------------------------------------------------------------------------- /pgrx-examples/range/range.control: -------------------------------------------------------------------------------- 1 | comment = 'range: Created by pgrx' 2 | default_version = '0.1.0' 3 | module_pathname = 'range' 4 | relocatable = false 5 | superuser = false 6 | schema = range -------------------------------------------------------------------------------- /pgrx-examples/range/src/bin/pgrx_embed.rs: -------------------------------------------------------------------------------- 1 | ::pgrx::pgrx_embed!(); 2 | -------------------------------------------------------------------------------- /pgrx-examples/range/src/lib.rs: -------------------------------------------------------------------------------- 1 | //LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 2 | //LICENSE 3 | //LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 4 | //LICENSE 5 | //LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 6 | //LICENSE 7 | //LICENSE All rights reserved. 8 | //LICENSE 9 | //LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 10 | use pgrx::prelude::*; 11 | 12 | pgrx::pg_module_magic!(c"range", pgrx::pg_sys::PG_VERSION); 13 | 14 | #[pg_extern] 15 | fn range(s: i32, e: i32) -> pgrx::Range { 16 | (s..e).into() 17 | } 18 | 19 | #[pg_extern] 20 | fn range_from(s: i32) -> pgrx::Range { 21 | (s..).into() 22 | } 23 | 24 | #[pg_extern] 25 | fn range_full() -> pgrx::Range { 26 | (..).into() 27 | } 28 | 29 | #[pg_extern] 30 | fn range_inclusive(s: i32, e: i32) -> pgrx::Range { 31 | (s..=e).into() 32 | } 33 | 34 | #[pg_extern] 35 | fn range_to(e: i32) -> pgrx::Range { 36 | (..e).into() 37 | } 38 | 39 | #[pg_extern] 40 | fn range_to_inclusive(e: i32) -> pgrx::Range { 41 | (..=e).into() 42 | } 43 | 44 | #[pg_extern] 45 | fn empty() -> pgrx::Range { 46 | pgrx::Range::empty() 47 | } 48 | 49 | #[pg_extern] 50 | fn infinite() -> pgrx::Range { 51 | pgrx::Range::infinite() 52 | } 53 | 54 | #[pg_extern] 55 | fn assert_range(r: pgrx::Range, s: i32, e: i32) -> bool { 56 | r == (s..e).into() 57 | } 58 | -------------------------------------------------------------------------------- /pgrx-examples/range/tests/pg_regress/expected/make_range.out: -------------------------------------------------------------------------------- 1 | SELECT range.range(10, 101); 2 | range 3 | ---------- 4 | [10,101) 5 | (1 row) 6 | 7 | -------------------------------------------------------------------------------- /pgrx-examples/range/tests/pg_regress/expected/setup.out: -------------------------------------------------------------------------------- 1 | -- this setup file is run immediately after the regression database is (re)created 2 | -- the file is optional but you likely want to create the extension 3 | CREATE EXTENSION range; 4 | -------------------------------------------------------------------------------- /pgrx-examples/range/tests/pg_regress/sql/make_range.sql: -------------------------------------------------------------------------------- 1 | SELECT range.range(10, 101); -------------------------------------------------------------------------------- /pgrx-examples/range/tests/pg_regress/sql/setup.sql: -------------------------------------------------------------------------------- 1 | -- this setup file is run immediately after the regression database is (re)created 2 | -- the file is optional but you likely want to create the extension 3 | CREATE EXTENSION range; 4 | -------------------------------------------------------------------------------- /pgrx-examples/range/tests/pg_regress/sql/store_ranges.sql: -------------------------------------------------------------------------------- 1 | DROP TABLE IF EXISTS store_ranges; 2 | CREATE TABLE store_ranges 3 | ( 4 | id serial8, 5 | r int4range 6 | ); 7 | 8 | INSERT INTO store_ranges (r) 9 | SELECT range.range(100, 100 + x) 10 | FROM generate_series(0, 100) x; 11 | SELECT * 12 | FROM store_ranges; -------------------------------------------------------------------------------- /pgrx-examples/schemas/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .idea/ 3 | /target 4 | *.iml 5 | **/*.rs.bk 6 | Cargo.lock 7 | sql/schemas-1.0.sql 8 | -------------------------------------------------------------------------------- /pgrx-examples/schemas/Cargo.toml: -------------------------------------------------------------------------------- 1 | #LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 2 | #LICENSE 3 | #LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 4 | #LICENSE 5 | #LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 6 | #LICENSE 7 | #LICENSE All rights reserved. 8 | #LICENSE 9 | #LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 10 | 11 | [package] 12 | name = "schemas" 13 | version = "0.0.0" 14 | edition = "2021" 15 | publish = false 16 | 17 | [lib] 18 | crate-type = ["cdylib", "lib"] 19 | 20 | [[bin]] 21 | name = "pgrx_embed_schemas" 22 | path = "./src/bin/pgrx_embed.rs" 23 | 24 | [features] 25 | default = ["pg13"] 26 | pg13 = ["pgrx/pg13", "pgrx-tests/pg13"] 27 | pg14 = ["pgrx/pg14", "pgrx-tests/pg14"] 28 | pg15 = ["pgrx/pg15", "pgrx-tests/pg15"] 29 | pg16 = ["pgrx/pg16", "pgrx-tests/pg16"] 30 | pg17 = ["pgrx/pg17", "pgrx-tests/pg17"] 31 | pg18 = ["pgrx/pg18", "pgrx-tests/pg18"] 32 | pg_test = [] 33 | 34 | [dependencies] 35 | pgrx = { path = "../../pgrx", default-features = false } 36 | serde = "1.0" 37 | 38 | [dev-dependencies] 39 | pgrx-tests = { path = "../../pgrx-tests" } 40 | 41 | # uncomment these if compiling outside of 'pgrx' 42 | # [profile.dev] 43 | # panic = "unwind" 44 | 45 | # [profile.release] 46 | # panic = "unwind" 47 | # opt-level = 3 48 | # lto = "fat" 49 | # codegen-units = 1 50 | -------------------------------------------------------------------------------- /pgrx-examples/schemas/schemas.control: -------------------------------------------------------------------------------- 1 | comment = 'schemas: Created by pgrx' 2 | default_version = '@CARGO_VERSION@' 3 | module_pathname = 'schemas' 4 | relocatable = false 5 | superuser = true # b/c this extension creates objects in "pg_catalog" 6 | -------------------------------------------------------------------------------- /pgrx-examples/schemas/src/bin/pgrx_embed.rs: -------------------------------------------------------------------------------- 1 | ::pgrx::pgrx_embed!(); 2 | -------------------------------------------------------------------------------- /pgrx-examples/shmem/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .idea/ 3 | /target 4 | *.iml 5 | **/*.rs.bk 6 | Cargo.lock 7 | sql/shmem-1.0.sql 8 | -------------------------------------------------------------------------------- /pgrx-examples/shmem/Cargo.toml: -------------------------------------------------------------------------------- 1 | #LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 2 | #LICENSE 3 | #LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 4 | #LICENSE 5 | #LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 6 | #LICENSE 7 | #LICENSE All rights reserved. 8 | #LICENSE 9 | #LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 10 | 11 | [package] 12 | name = "shmem" 13 | version = "0.0.0" 14 | edition = "2021" 15 | publish = false 16 | 17 | [lib] 18 | crate-type = ["cdylib", "lib"] 19 | 20 | [[bin]] 21 | name = "pgrx_embed_shmem" 22 | path = "./src/bin/pgrx_embed.rs" 23 | 24 | [features] 25 | default = ["pg13"] 26 | pg13 = ["pgrx/pg13", "pgrx-tests/pg13"] 27 | pg14 = ["pgrx/pg14", "pgrx-tests/pg14"] 28 | pg15 = ["pgrx/pg15", "pgrx-tests/pg15"] 29 | pg16 = ["pgrx/pg16", "pgrx-tests/pg16"] 30 | pg17 = ["pgrx/pg17", "pgrx-tests/pg17"] 31 | pg18 = ["pgrx/pg18", "pgrx-tests/pg18"] 32 | pg_test = [] 33 | 34 | [dependencies] 35 | heapless = "0.8" 36 | pgrx = { path = "../../pgrx", default-features = false } 37 | serde = { version = "1.0", features = ["derive"] } 38 | 39 | [dev-dependencies] 40 | pgrx-tests = { path = "../../pgrx-tests" } 41 | 42 | # uncomment these if compiling outside of 'pgrx' 43 | # [profile.dev] 44 | # panic = "unwind" 45 | 46 | # [profile.release] 47 | # panic = "unwind" 48 | # opt-level = 3 49 | # lto = "fat" 50 | # codegen-units = 1 51 | -------------------------------------------------------------------------------- /pgrx-examples/shmem/README.md: -------------------------------------------------------------------------------- 1 | ## Postgres Shared Memory and LWLock Support 2 | 3 | Important: 4 | > Extensions that use shared memory **must** be loaded via `postgresql.conf`'s 5 | >`shared_preload_libraries` configuration setting. 6 | 7 | For now, please check out the example in [src/lib.rs](src/lib.rs). It demonstrates how to 8 | safely use standard Rust types, Rust Atomics, and various data structures from 9 | [`heapless`](https://crates.io/crates/heapless) via Postgres' shared memory system. 10 | 11 | -------------------------------------------------------------------------------- /pgrx-examples/shmem/shmem.control: -------------------------------------------------------------------------------- 1 | comment = 'shmem: Created by pgrx' 2 | default_version = '@CARGO_VERSION@' 3 | module_pathname = 'shmem' 4 | relocatable = false 5 | superuser = false 6 | -------------------------------------------------------------------------------- /pgrx-examples/shmem/src/bin/pgrx_embed.rs: -------------------------------------------------------------------------------- 1 | ::pgrx::pgrx_embed!(); 2 | -------------------------------------------------------------------------------- /pgrx-examples/spi/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .idea/ 3 | /target 4 | *.iml 5 | **/*.rs.bk 6 | Cargo.lock 7 | sql/spi-1.0.sql 8 | -------------------------------------------------------------------------------- /pgrx-examples/spi/Cargo.toml: -------------------------------------------------------------------------------- 1 | #LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 2 | #LICENSE 3 | #LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 4 | #LICENSE 5 | #LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 6 | #LICENSE 7 | #LICENSE All rights reserved. 8 | #LICENSE 9 | #LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 10 | 11 | [package] 12 | name = "spi" 13 | version = "0.0.0" 14 | edition = "2021" 15 | publish = false 16 | 17 | [lib] 18 | crate-type = ["cdylib", "lib"] 19 | 20 | [[bin]] 21 | name = "pgrx_embed_spi" 22 | path = "./src/bin/pgrx_embed.rs" 23 | 24 | [features] 25 | default = ["pg13"] 26 | pg13 = ["pgrx/pg13", "pgrx-tests/pg13"] 27 | pg14 = ["pgrx/pg14", "pgrx-tests/pg14"] 28 | pg15 = ["pgrx/pg15", "pgrx-tests/pg15"] 29 | pg16 = ["pgrx/pg16", "pgrx-tests/pg16"] 30 | pg17 = ["pgrx/pg17", "pgrx-tests/pg17"] 31 | pg18 = ["pgrx/pg18", "pgrx-tests/pg18"] 32 | pg_test = [] 33 | 34 | [dependencies] 35 | pgrx = { path = "../../pgrx", default-features = false } 36 | 37 | [dev-dependencies] 38 | pgrx-tests = { path = "../../pgrx-tests" } 39 | 40 | # uncomment these if compiling outside of 'pgrx' 41 | # [profile.dev] 42 | # panic = "unwind" 43 | 44 | # [profile.release] 45 | # panic = "unwind" 46 | # opt-level = 3 47 | # lto = "fat" 48 | # codegen-units = 1 49 | -------------------------------------------------------------------------------- /pgrx-examples/spi/README.md: -------------------------------------------------------------------------------- 1 | Some examples of using SPI (Server Programming Interface) with pgrx. 2 | 3 | A video covering this topic is located here: https://www.twitch.tv/videos/693509390 -------------------------------------------------------------------------------- /pgrx-examples/spi/spi.control: -------------------------------------------------------------------------------- 1 | comment = 'spi: Created by pgrx' 2 | default_version = '@CARGO_VERSION@' 3 | module_pathname = 'spi' 4 | relocatable = false 5 | superuser = false 6 | schema = 'spi' 7 | -------------------------------------------------------------------------------- /pgrx-examples/spi/src/bin/pgrx_embed.rs: -------------------------------------------------------------------------------- 1 | ::pgrx::pgrx_embed!(); 2 | -------------------------------------------------------------------------------- /pgrx-examples/spi_srf/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .idea/ 3 | /target 4 | *.iml 5 | **/*.rs.bk 6 | Cargo.lock 7 | sql/spi-1.0.sql 8 | -------------------------------------------------------------------------------- /pgrx-examples/spi_srf/Cargo.toml: -------------------------------------------------------------------------------- 1 | #LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 2 | #LICENSE 3 | #LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 4 | #LICENSE 5 | #LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 6 | #LICENSE 7 | #LICENSE All rights reserved. 8 | #LICENSE 9 | #LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 10 | 11 | [package] 12 | name = "spi_srf" 13 | version = "0.0.0" 14 | edition = "2021" 15 | publish = false 16 | rust-version = "1.58" 17 | 18 | [lib] 19 | crate-type = ["cdylib", "lib"] 20 | 21 | [[bin]] 22 | name = "pgrx_embed_spi_srf" 23 | path = "./src/bin/pgrx_embed.rs" 24 | 25 | [features] 26 | default = ["pg13"] 27 | pg13 = ["pgrx/pg13", "pgrx-tests/pg13"] 28 | pg14 = ["pgrx/pg14", "pgrx-tests/pg14"] 29 | pg15 = ["pgrx/pg15", "pgrx-tests/pg15"] 30 | pg16 = ["pgrx/pg16", "pgrx-tests/pg16"] 31 | pg17 = ["pgrx/pg17", "pgrx-tests/pg17"] 32 | pg18 = ["pgrx/pg18", "pgrx-tests/pg18"] 33 | pg_test = [] 34 | 35 | [dependencies] 36 | pgrx = { path = "../../pgrx", default-features = false } 37 | 38 | [dev-dependencies] 39 | pgrx-tests = { path = "../../pgrx-tests" } 40 | 41 | # uncomment these if compiling outside of 'pgrx' 42 | # [profile.dev] 43 | # panic = "unwind" 44 | 45 | # [profile.release] 46 | # panic = "unwind" 47 | # opt-level = 3 48 | # lto = "fat" 49 | # codegen-units = 1 50 | -------------------------------------------------------------------------------- /pgrx-examples/spi_srf/README.md: -------------------------------------------------------------------------------- 1 | Some examples of using SPI (Server Programming Interface) and SRF with pgrx. -------------------------------------------------------------------------------- /pgrx-examples/spi_srf/spi_srf.control: -------------------------------------------------------------------------------- 1 | comment = 'spi_srf: Created by pgrx' 2 | default_version = '@CARGO_VERSION@' 3 | module_pathname = 'spi_srf' 4 | relocatable = false 5 | superuser = false 6 | schema = 'spi_srf' 7 | -------------------------------------------------------------------------------- /pgrx-examples/spi_srf/src/bin/pgrx_embed.rs: -------------------------------------------------------------------------------- 1 | ::pgrx::pgrx_embed!(); 2 | -------------------------------------------------------------------------------- /pgrx-examples/srf/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .idea/ 3 | /target 4 | *.iml 5 | **/*.rs.bk 6 | Cargo.lock 7 | sql/srf-1.0.sql 8 | -------------------------------------------------------------------------------- /pgrx-examples/srf/Cargo.toml: -------------------------------------------------------------------------------- 1 | #LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 2 | #LICENSE 3 | #LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 4 | #LICENSE 5 | #LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 6 | #LICENSE 7 | #LICENSE All rights reserved. 8 | #LICENSE 9 | #LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 10 | 11 | [package] 12 | name = "srf" 13 | version = "0.0.0" 14 | edition = "2021" 15 | publish = false 16 | 17 | [lib] 18 | crate-type = ["cdylib", "lib"] 19 | 20 | [[bin]] 21 | name = "pgrx_embed_srf" 22 | path = "./src/bin/pgrx_embed.rs" 23 | 24 | [features] 25 | default = ["pg13"] 26 | pg13 = ["pgrx/pg13", "pgrx-tests/pg13"] 27 | pg14 = ["pgrx/pg14", "pgrx-tests/pg14"] 28 | pg15 = ["pgrx/pg15", "pgrx-tests/pg15"] 29 | pg16 = ["pgrx/pg16", "pgrx-tests/pg16"] 30 | pg17 = ["pgrx/pg17", "pgrx-tests/pg17"] 31 | pg18 = ["pgrx/pg18", "pgrx-tests/pg18"] 32 | pg_test = [] 33 | 34 | [dependencies] 35 | pgrx = { path = "../../pgrx", default-features = false } 36 | rand = "0.9.0" 37 | 38 | [dev-dependencies] 39 | pgrx-tests = { path = "../../pgrx-tests" } 40 | 41 | # uncomment these if compiling outside of 'pgrx' 42 | # [profile.dev] 43 | # panic = "unwind" 44 | 45 | # [profile.release] 46 | # panic = "unwind" 47 | # opt-level = 3 48 | # lto = "fat" 49 | # codegen-units = 1 50 | -------------------------------------------------------------------------------- /pgrx-examples/srf/README.md: -------------------------------------------------------------------------------- 1 | Examples for working with Postgres Set Returning Functions. 2 | 3 | Here's a video that walks through this example (and others): 4 | https://www.twitch.tv/videos/670479038 -------------------------------------------------------------------------------- /pgrx-examples/srf/src/bin/pgrx_embed.rs: -------------------------------------------------------------------------------- 1 | ::pgrx::pgrx_embed!(); 2 | -------------------------------------------------------------------------------- /pgrx-examples/srf/srf.control: -------------------------------------------------------------------------------- 1 | comment = 'srf: Created by pgrx' 2 | default_version = '@CARGO_VERSION@' 3 | module_pathname = 'srf' 4 | relocatable = false 5 | superuser = false 6 | schema = srf 7 | -------------------------------------------------------------------------------- /pgrx-examples/strings/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .idea/ 3 | /target 4 | *.iml 5 | **/*.rs.bk 6 | Cargo.lock 7 | sql/strings-1.0.sql 8 | -------------------------------------------------------------------------------- /pgrx-examples/strings/Cargo.toml: -------------------------------------------------------------------------------- 1 | #LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 2 | #LICENSE 3 | #LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 4 | #LICENSE 5 | #LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 6 | #LICENSE 7 | #LICENSE All rights reserved. 8 | #LICENSE 9 | #LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 10 | 11 | [package] 12 | name = "strings" 13 | version = "0.0.0" 14 | edition = "2021" 15 | publish = false 16 | 17 | [lib] 18 | crate-type = ["cdylib", "lib"] 19 | 20 | [[bin]] 21 | name = "pgrx_embed_strings" 22 | path = "./src/bin/pgrx_embed.rs" 23 | 24 | [features] 25 | default = ["pg13"] 26 | pg13 = ["pgrx/pg13", "pgrx-tests/pg13"] 27 | pg14 = ["pgrx/pg14", "pgrx-tests/pg14"] 28 | pg15 = ["pgrx/pg15", "pgrx-tests/pg15"] 29 | pg16 = ["pgrx/pg16", "pgrx-tests/pg16"] 30 | pg17 = ["pgrx/pg17", "pgrx-tests/pg17"] 31 | pg18 = ["pgrx/pg18", "pgrx-tests/pg18"] 32 | pg_test = [] 33 | 34 | [dependencies] 35 | pgrx = { path = "../../pgrx", default-features = false } 36 | 37 | [dev-dependencies] 38 | pgrx-tests = { path = "../../pgrx-tests" } 39 | 40 | # uncomment these if compiling outside of 'pgrx' 41 | # [profile.dev] 42 | # panic = "unwind" 43 | 44 | # [profile.release] 45 | # panic = "unwind" 46 | # opt-level = 3 47 | # lto = "fat" 48 | # codegen-units = 1 49 | -------------------------------------------------------------------------------- /pgrx-examples/strings/README.md: -------------------------------------------------------------------------------- 1 | Examples for working with Rust strings and Postgres `text`/`varlena` types. 2 | 3 | Here's a video that walks through these examples: 4 | https://www.twitch.tv/videos/675826352 -------------------------------------------------------------------------------- /pgrx-examples/strings/src/bin/pgrx_embed.rs: -------------------------------------------------------------------------------- 1 | ::pgrx::pgrx_embed!(); 2 | -------------------------------------------------------------------------------- /pgrx-examples/strings/strings.control: -------------------------------------------------------------------------------- 1 | comment = 'strings: Created by pgrx' 2 | default_version = '@CARGO_VERSION@' 3 | module_pathname = 'strings' 4 | relocatable = false 5 | superuser = false 6 | schema = strings -------------------------------------------------------------------------------- /pgrx-examples/triggers/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .idea/ 3 | /target 4 | *.iml 5 | **/*.rs.bk 6 | Cargo.lock 7 | sql/triggers-1.0.sql 8 | -------------------------------------------------------------------------------- /pgrx-examples/triggers/Cargo.toml: -------------------------------------------------------------------------------- 1 | #LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 2 | #LICENSE 3 | #LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 4 | #LICENSE 5 | #LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 6 | #LICENSE 7 | #LICENSE All rights reserved. 8 | #LICENSE 9 | #LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 10 | 11 | [package] 12 | name = "triggers" 13 | version = "0.0.0" 14 | edition = "2021" 15 | publish = false 16 | 17 | [lib] 18 | crate-type = ["cdylib", "lib"] 19 | 20 | [[bin]] 21 | name = "pgrx_embed_triggers" 22 | path = "./src/bin/pgrx_embed.rs" 23 | 24 | [features] 25 | default = ["pg13"] 26 | pg13 = ["pgrx/pg13", "pgrx-tests/pg13"] 27 | pg14 = ["pgrx/pg14", "pgrx-tests/pg14"] 28 | pg15 = ["pgrx/pg15", "pgrx-tests/pg15"] 29 | pg16 = ["pgrx/pg16", "pgrx-tests/pg16"] 30 | pg17 = ["pgrx/pg17", "pgrx-tests/pg17"] 31 | pg18 = ["pgrx/pg18", "pgrx-tests/pg18"] 32 | pg_test = [] 33 | 34 | [dependencies] 35 | pgrx = { path = "../../pgrx", default-features = false } 36 | thiserror = "2.0" 37 | 38 | [dev-dependencies] 39 | pgrx-tests = { path = "../../pgrx-tests" } 40 | 41 | # uncomment these if compiling outside of 'pgrx' 42 | #[profile.dev] 43 | #panic = "unwind" 44 | 45 | #[profile.release] 46 | #panic = "unwind" 47 | #opt-level = 3 48 | #lto = "fat" 49 | #codegen-units = 1 50 | -------------------------------------------------------------------------------- /pgrx-examples/triggers/src/bin/pgrx_embed.rs: -------------------------------------------------------------------------------- 1 | ::pgrx::pgrx_embed!(); 2 | -------------------------------------------------------------------------------- /pgrx-examples/triggers/triggers.control: -------------------------------------------------------------------------------- 1 | comment = 'triggers: Created by pgrx' 2 | default_version = '@CARGO_VERSION@' 3 | module_pathname = 'triggers' 4 | relocatable = false 5 | superuser = false 6 | -------------------------------------------------------------------------------- /pgrx-examples/versioned_custom_libname_so/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .idea/ 3 | /target 4 | *.iml 5 | **/*.rs.bk 6 | Cargo.lock 7 | -------------------------------------------------------------------------------- /pgrx-examples/versioned_custom_libname_so/Cargo.toml: -------------------------------------------------------------------------------- 1 | #LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 2 | #LICENSE 3 | #LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 4 | #LICENSE 5 | #LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 6 | #LICENSE 7 | #LICENSE All rights reserved. 8 | #LICENSE 9 | #LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 10 | 11 | [package] 12 | name = "versioned_custom_libname_so" 13 | version = "0.0.0" 14 | edition = "2021" 15 | publish = false 16 | 17 | [lib] 18 | crate-type = ["cdylib", "lib"] 19 | name = "versioned_othername" 20 | 21 | [[bin]] 22 | name = "pgrx_embed_versioned_custom_libname_so" 23 | path = "./src/bin/pgrx_embed.rs" 24 | 25 | [features] 26 | default = ["pg13"] 27 | pg13 = ["pgrx/pg13", "pgrx-tests/pg13"] 28 | pg14 = ["pgrx/pg14", "pgrx-tests/pg14"] 29 | pg15 = ["pgrx/pg15", "pgrx-tests/pg15"] 30 | pg16 = ["pgrx/pg16", "pgrx-tests/pg16"] 31 | pg17 = ["pgrx/pg17", "pgrx-tests/pg17"] 32 | pg18 = ["pgrx/pg18", "pgrx-tests/pg18"] 33 | pg_test = [] 34 | 35 | [dependencies] 36 | pgrx = { path = "../../pgrx", default-features = false } 37 | 38 | [dev-dependencies] 39 | pgrx-tests = { path = "../../pgrx-tests" } 40 | 41 | # uncomment these if compiling outside of 'pgrx' 42 | #[profile.dev] 43 | #panic = "unwind" 44 | 45 | #[profile.release] 46 | #panic = "unwind" 47 | #opt-level = 3 48 | #lto = "fat" 49 | #codegen-units = 1 50 | -------------------------------------------------------------------------------- /pgrx-examples/versioned_custom_libname_so/src/bin/pgrx_embed.rs: -------------------------------------------------------------------------------- 1 | ::pgrx::pgrx_embed!(); 2 | -------------------------------------------------------------------------------- /pgrx-examples/versioned_custom_libname_so/src/lib.rs: -------------------------------------------------------------------------------- 1 | //LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 2 | //LICENSE 3 | //LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 4 | //LICENSE 5 | //LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 6 | //LICENSE 7 | //LICENSE All rights reserved. 8 | //LICENSE 9 | //LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 10 | use pgrx::prelude::*; 11 | 12 | pgrx::pg_module_magic!(c"versioned_custom_libname_so", pgrx::pg_sys::PG_VERSION); 13 | 14 | #[pg_extern] 15 | fn hello_versioned_custom_libname_so() -> &'static str { 16 | "Hello, versioned_custom_libname_so" 17 | } 18 | 19 | #[cfg(any(test, feature = "pg_test"))] 20 | #[pg_schema] 21 | mod tests { 22 | use pgrx::prelude::*; 23 | 24 | #[pg_test] 25 | fn test_hello_versioned_custom_libname_so() { 26 | assert_eq!( 27 | "Hello, versioned_custom_libname_so", 28 | crate::hello_versioned_custom_libname_so() 29 | ); 30 | } 31 | } 32 | 33 | #[cfg(test)] 34 | pub mod pg_test { 35 | pub fn setup(_options: Vec<&str>) { 36 | // perform one-off initialization when the pg_test framework starts 37 | } 38 | 39 | pub fn postgresql_conf_options() -> Vec<&'static str> { 40 | // return any postgresql.conf settings that are required for your tests 41 | vec![] 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /pgrx-examples/versioned_custom_libname_so/versioned_othername.control: -------------------------------------------------------------------------------- 1 | comment = 'versioned_custom_libname_so: Created by pgrx' 2 | default_version = '@CARGO_VERSION@' 3 | # commenting-out module_pathname results in this extension being built/run/tested in "versioned shared-object mode" 4 | # module_pathname = 'versioned_othername' 5 | relocatable = false 6 | superuser = false 7 | -------------------------------------------------------------------------------- /pgrx-examples/versioned_so/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .idea/ 3 | /target 4 | *.iml 5 | **/*.rs.bk 6 | Cargo.lock 7 | -------------------------------------------------------------------------------- /pgrx-examples/versioned_so/Cargo.toml: -------------------------------------------------------------------------------- 1 | #LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 2 | #LICENSE 3 | #LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 4 | #LICENSE 5 | #LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 6 | #LICENSE 7 | #LICENSE All rights reserved. 8 | #LICENSE 9 | #LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 10 | 11 | [package] 12 | name = "versioned_so" 13 | version = "0.0.0" 14 | edition = "2021" 15 | publish = false 16 | 17 | [lib] 18 | crate-type = ["cdylib", "lib"] 19 | 20 | [[bin]] 21 | name = "pgrx_embed_versioned_so" 22 | path = "./src/bin/pgrx_embed.rs" 23 | 24 | [features] 25 | default = ["pg13"] 26 | pg13 = ["pgrx/pg13", "pgrx-tests/pg13"] 27 | pg14 = ["pgrx/pg14", "pgrx-tests/pg14"] 28 | pg15 = ["pgrx/pg15", "pgrx-tests/pg15"] 29 | pg16 = ["pgrx/pg16", "pgrx-tests/pg16"] 30 | pg17 = ["pgrx/pg17", "pgrx-tests/pg17"] 31 | pg18 = ["pgrx/pg18", "pgrx-tests/pg18"] 32 | pg_test = [] 33 | 34 | [dependencies] 35 | pgrx = { path = "../../pgrx", default-features = false } 36 | 37 | [dev-dependencies] 38 | pgrx-tests = { path = "../../pgrx-tests" } 39 | 40 | # uncomment these if compiling outside of 'pgrx' 41 | #[profile.dev] 42 | #panic = "unwind" 43 | 44 | #[profile.release] 45 | #panic = "unwind" 46 | #opt-level = 3 47 | #lto = "fat" 48 | #codegen-units = 1 49 | -------------------------------------------------------------------------------- /pgrx-examples/versioned_so/src/bin/pgrx_embed.rs: -------------------------------------------------------------------------------- 1 | ::pgrx::pgrx_embed!(); 2 | -------------------------------------------------------------------------------- /pgrx-examples/versioned_so/src/lib.rs: -------------------------------------------------------------------------------- 1 | //LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 2 | //LICENSE 3 | //LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 4 | //LICENSE 5 | //LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 6 | //LICENSE 7 | //LICENSE All rights reserved. 8 | //LICENSE 9 | //LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 10 | use pgrx::prelude::*; 11 | 12 | pgrx::pg_module_magic!(c"versioned_so", pgrx::pg_sys::PG_VERSION); 13 | 14 | #[pg_extern] 15 | fn hello_versioned_so() -> &'static str { 16 | "Hello, versioned_so" 17 | } 18 | 19 | #[cfg(any(test, feature = "pg_test"))] 20 | #[pg_schema] 21 | mod tests { 22 | use pgrx::prelude::*; 23 | 24 | #[pg_test] 25 | fn test_hello_versioned_so() { 26 | assert_eq!("Hello, versioned_so", crate::hello_versioned_so()); 27 | } 28 | } 29 | 30 | #[cfg(test)] 31 | pub mod pg_test { 32 | pub fn setup(_options: Vec<&str>) { 33 | // perform one-off initialization when the pg_test framework starts 34 | } 35 | 36 | pub fn postgresql_conf_options() -> Vec<&'static str> { 37 | // return any postgresql.conf settings that are required for your tests 38 | vec![] 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /pgrx-examples/versioned_so/versioned_so.control: -------------------------------------------------------------------------------- 1 | comment = 'versioned_so: Created by pgrx' 2 | default_version = '@CARGO_VERSION@' 3 | # commenting-out module_pathname results in this extension being built/run/tested in "versioned shared-object mode" 4 | # module_pathname = 'versioned_so' 5 | relocatable = false 6 | superuser = false 7 | -------------------------------------------------------------------------------- /pgrx-examples/wal_decoder/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .idea/ 3 | /target 4 | *.iml 5 | **/*.rs.bk 6 | Cargo.lock 7 | -------------------------------------------------------------------------------- /pgrx-examples/wal_decoder/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "wal_decoder" 3 | version = "0.0.0" 4 | edition = "2021" 5 | 6 | [lib] 7 | crate-type = ["cdylib", "lib"] 8 | 9 | [[bin]] 10 | name = "pgrx_embed_wal_decoder" 11 | path = "./src/bin/pgrx_embed.rs" 12 | 13 | [features] 14 | default = ["pg13"] 15 | pg13 = ["pgrx/pg13", "pgrx-tests/pg13"] 16 | pg14 = ["pgrx/pg14", "pgrx-tests/pg14"] 17 | pg15 = ["pgrx/pg15", "pgrx-tests/pg15"] 18 | pg16 = ["pgrx/pg16", "pgrx-tests/pg16"] 19 | pg17 = ["pgrx/pg17", "pgrx-tests/pg17"] 20 | pg18 = ["pgrx/pg18", "pgrx-tests/pg18"] 21 | pg_test = [] 22 | 23 | [dependencies] 24 | pgrx = { path = "../../pgrx", default-features = false } 25 | serde = "1.0.219" 26 | serde_json = "1.0.140" 27 | 28 | [dev-dependencies] 29 | pgrx-tests = { path = "../../pgrx-tests" } 30 | 31 | [profile.dev] 32 | panic = "unwind" 33 | 34 | [profile.release] 35 | panic = "unwind" 36 | opt-level = 3 37 | lto = "fat" 38 | codegen-units = 1 39 | -------------------------------------------------------------------------------- /pgrx-examples/wal_decoder/src/bin/pgrx_embed.rs: -------------------------------------------------------------------------------- 1 | ::pgrx::pgrx_embed!(); 2 | -------------------------------------------------------------------------------- /pgrx-examples/wal_decoder/wal_decoder.control: -------------------------------------------------------------------------------- 1 | comment = 'wal_decoder: Created by pgrx' 2 | default_version = '@CARGO_VERSION@' 3 | module_pathname = 'wal_decoder' 4 | relocatable = false 5 | superuser = true 6 | trusted = false 7 | -------------------------------------------------------------------------------- /pgrx-macros/Cargo.toml: -------------------------------------------------------------------------------- 1 | #LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 2 | #LICENSE 3 | #LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 4 | #LICENSE 5 | #LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 6 | #LICENSE 7 | #LICENSE All rights reserved. 8 | #LICENSE 9 | #LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 10 | 11 | [package] 12 | name = "pgrx-macros" 13 | version = "0.14.3" 14 | authors = ["PgCentral Foundation, Inc. "] 15 | license = "MIT" 16 | description = "Proc Macros for 'pgrx'" 17 | homepage = "https://github.com/pgcentralfoundation/pgrx/" 18 | repository = "https://github.com/pgcentralfoundation/pgrx/" 19 | documentation = "https://docs.rs/pgrx-macros" 20 | readme = "README.md" 21 | edition = "2021" 22 | 23 | [lib] 24 | proc-macro = true 25 | 26 | [package.metadata.docs.rs] 27 | # Enable `#[cfg(docsrs)]` (https://docs.rs/about/builds#cross-compiling) 28 | rustc-args = ["--cfg", "docsrs"] 29 | 30 | [features] 31 | no-schema-generation = ["pgrx-sql-entity-graph/no-schema-generation"] 32 | 33 | 34 | [dependencies] 35 | pgrx-sql-entity-graph.workspace = true 36 | 37 | proc-macro2.workspace = true 38 | quote.workspace = true 39 | syn.workspace = true 40 | 41 | 42 | [dev-dependencies] 43 | serde.workspace = true # for Documentation examples 44 | -------------------------------------------------------------------------------- /pgrx-macros/README.md: -------------------------------------------------------------------------------- 1 | # pgrx-macros 2 | 3 | Procedural macros for [`pgrx`](https://crates.io/crates/pgrx/). 4 | 5 | Provides: 6 | 7 | - #[pg_extern] 8 | - #[pg_guard] 9 | - #[pg_test] 10 | - #[derive(PostgresType)] 11 | - #[derive(PostgresEnum)] 12 | - #[derive(PostgresGucEnum)] 13 | 14 | Using `pgrx` as a dependency necessitates that `pgrx-macros` also be a dependency -------------------------------------------------------------------------------- /pgrx-pg-config/Cargo.toml: -------------------------------------------------------------------------------- 1 | #LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 2 | #LICENSE 3 | #LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 4 | #LICENSE 5 | #LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 6 | #LICENSE 7 | #LICENSE All rights reserved. 8 | #LICENSE 9 | #LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 10 | 11 | [package] 12 | name = "pgrx-pg-config" 13 | version = "0.14.3" 14 | authors = ["PgCentral Foundation, Inc. "] 15 | license = "MIT" 16 | description = "A Postgres pg_config wrapper for 'pgrx'" 17 | homepage = "https://github.com/pgcentralfoundation/pgrx/" 18 | repository = "https://github.com/pgcentralfoundation/pgrx/" 19 | documentation = "https://docs.rs/pgrx-pg-config" 20 | readme = "README.md" 21 | edition = "2021" 22 | 23 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 24 | 25 | [dependencies] 26 | cargo_toml.workspace = true 27 | eyre.workspace = true 28 | owo-colors.workspace = true 29 | serde.workspace = true 30 | serde_json.workspace = true 31 | thiserror.workspace = true 32 | toml.workspace = true 33 | url.workspace = true 34 | 35 | home = "0.5.11" 36 | pathsearch = "0.2.0" 37 | -------------------------------------------------------------------------------- /pgrx-pg-config/README.md: -------------------------------------------------------------------------------- 1 | # pgrx-pg-config 2 | 3 | A crate containing an abstraction/wrapper over Postgres' `pg_config` to be used with [`pgrx`](https://crates.io/crates/pgrx/) 4 | -------------------------------------------------------------------------------- /pgrx-pg-sys/README.md: -------------------------------------------------------------------------------- 1 | # pgrx-pg-sys 2 | 3 | Bindgen-generated bindings for [`pgrx`](https://crates.io/crates/pgrx/). Not meant to be used on its own. 4 | -------------------------------------------------------------------------------- /pgrx-pg-sys/bindgen.rs: -------------------------------------------------------------------------------- 1 | // not a build.rs so that it doesn't inherit the git history of the build.rs 2 | 3 | // little-known Rust quirk: you can import main from wherever 4 | use pgrx_bindgen::build::main; 5 | -------------------------------------------------------------------------------- /pgrx-pg-sys/pgrx-cshim.c: -------------------------------------------------------------------------------- 1 | //LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 2 | //LICENSE 3 | //LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 4 | //LICENSE 5 | //LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 6 | //LICENSE 7 | //LICENSE All rights reserved. 8 | //LICENSE 9 | //LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 10 | 11 | #include "pgrx-cshim-static.c" 12 | 13 | void SpinLockInit__pgrx_cshim(volatile slock_t *lock) { 14 | SpinLockInit(lock); 15 | } 16 | 17 | void SpinLockAcquire__pgrx_cshim(volatile slock_t *lock) { 18 | SpinLockAcquire(lock); 19 | } 20 | 21 | void SpinLockRelease__pgrx_cshim(volatile slock_t *lock) { 22 | SpinLockRelease(lock); 23 | } 24 | 25 | bool SpinLockFree__pgrx_cshim(slock_t *lock) { 26 | return SpinLockFree(lock); 27 | } 28 | 29 | int call_closure_with_sigsetjmp(int savemask, void* closure_env_ptr, int (*closure_code)(sigjmp_buf jbuf, void *env_ptr)) { 30 | sigjmp_buf jbuf; 31 | int val; 32 | if (0 == (val = sigsetjmp(jbuf, savemask))) { 33 | return closure_code(jbuf, closure_env_ptr); 34 | } else { 35 | return val; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /pgrx-pg-sys/src/cshim.rs: -------------------------------------------------------------------------------- 1 | #![cfg(feature = "cshim")] 2 | #![allow(deprecated)] 3 | 4 | use crate as pg_sys; 5 | 6 | #[pgrx_macros::pg_guard] 7 | extern "C-unwind" { 8 | #[link_name = "SpinLockInit__pgrx_cshim"] 9 | pub fn SpinLockInit(lock: *mut pg_sys::slock_t); 10 | #[link_name = "SpinLockAcquire__pgrx_cshim"] 11 | pub fn SpinLockAcquire(lock: *mut pg_sys::slock_t); 12 | #[link_name = "SpinLockRelease__pgrx_cshim"] 13 | pub fn SpinLockRelease(lock: *mut pg_sys::slock_t); 14 | #[link_name = "SpinLockFree__pgrx_cshim"] 15 | pub fn SpinLockFree(lock: *mut pg_sys::slock_t) -> bool; 16 | } 17 | -------------------------------------------------------------------------------- /pgrx-pg-sys/src/lib.rs: -------------------------------------------------------------------------------- 1 | //LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 2 | //LICENSE 3 | //LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 4 | //LICENSE 5 | //LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 6 | //LICENSE 7 | //LICENSE All rights reserved. 8 | //LICENSE 9 | //LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 10 | #[cfg( 11 | // no features at all will cause problems 12 | not(any(feature = "pg13", feature = "pg14", feature = "pg15", feature = "pg16", feature = "pg17", feature = "pg18")) 13 | )] 14 | std::compile_error!("exactly one feature must be provided (pg13, pg14, pg15, pg16, pg17, pg18)"); 15 | 16 | mod cshim; 17 | mod cstr; 18 | mod include; 19 | mod node; 20 | mod port; 21 | pub mod submodules; 22 | 23 | #[cfg(feature = "cshim")] 24 | pub use cshim::*; 25 | 26 | pub use cstr::AsPgCStr; 27 | pub use include::*; 28 | pub use node::PgNode; 29 | pub use port::*; 30 | 31 | // For postgres 18+, some functions will reexport when enabling `cshim` feature 32 | #[allow(ambiguous_glob_reexports)] 33 | pub use submodules::*; 34 | 35 | mod seal { 36 | pub trait Sealed {} 37 | } 38 | 39 | // Hack to fix linker errors that we get under amazonlinux2 on some PG versions 40 | // due to our wrappers for various system library functions. Should be fairly 41 | // harmless, but ideally we would not wrap these functions 42 | // (https://github.com/pgcentralfoundation/pgrx/issues/730). 43 | #[cfg(target_os = "linux")] 44 | #[link(name = "resolv")] 45 | extern "C" {} 46 | -------------------------------------------------------------------------------- /pgrx-pg-sys/src/submodules/cmp.rs: -------------------------------------------------------------------------------- 1 | use crate::{Point, BOX}; 2 | 3 | impl PartialEq for Point { 4 | #[inline] 5 | fn eq(&self, other: &Self) -> bool { 6 | self.x == other.x && self.y == other.y 7 | } 8 | } 9 | impl Eq for Point {} 10 | 11 | impl PartialEq for BOX { 12 | #[inline] 13 | fn eq(&self, other: &Self) -> bool { 14 | self.high == other.high && self.low == other.low 15 | } 16 | } 17 | impl Eq for BOX {} 18 | -------------------------------------------------------------------------------- /pgrx-pg-sys/src/submodules/mod.rs: -------------------------------------------------------------------------------- 1 | //LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 2 | //LICENSE 3 | //LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 4 | //LICENSE 5 | //LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 6 | //LICENSE 7 | //LICENSE All rights reserved. 8 | //LICENSE 9 | //LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 10 | pub mod datum; 11 | pub mod transaction_id; 12 | #[macro_use] 13 | pub mod elog; 14 | pub mod cmp; 15 | pub mod errcodes; 16 | pub mod ffi; 17 | pub mod htup; 18 | pub mod oids; 19 | pub mod panic; 20 | pub mod pg_try; 21 | #[doc(hidden)] 22 | pub mod thread_check; 23 | pub mod tupdesc; 24 | 25 | pub mod utils; 26 | 27 | // Various SqlTranslatable mappings for SQL generation 28 | mod sql_translatable; 29 | 30 | pub use datum::Datum; 31 | pub use transaction_id::{MultiXactId, TransactionId}; 32 | 33 | pub use htup::*; 34 | pub use oids::*; 35 | pub use pg_try::*; 36 | pub use utils::*; 37 | -------------------------------------------------------------------------------- /pgrx-pg-sys/src/submodules/tupdesc.rs: -------------------------------------------------------------------------------- 1 | //LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 2 | //LICENSE 3 | //LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 4 | //LICENSE 5 | //LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 6 | //LICENSE 7 | //LICENSE All rights reserved. 8 | //LICENSE 9 | //LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 10 | //! Provides helper implementations for various `TupleDesc`-related structs 11 | 12 | use crate::oids::PgOid; 13 | use crate::utils::name_data_to_str; 14 | 15 | /// Helper implementation for `FormData_pg_attribute` 16 | impl crate::FormData_pg_attribute { 17 | pub fn name(&self) -> &str { 18 | name_data_to_str(&self.attname) 19 | } 20 | 21 | pub fn type_oid(&self) -> PgOid { 22 | PgOid::from(self.atttypid) 23 | } 24 | 25 | pub fn type_mod(&self) -> i32 { 26 | self.atttypmod 27 | } 28 | 29 | pub fn num(&self) -> i16 { 30 | self.attnum 31 | } 32 | 33 | pub fn is_dropped(&self) -> bool { 34 | self.attisdropped 35 | } 36 | 37 | pub fn rel_id(&self) -> crate::Oid { 38 | self.attrelid 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /pgrx-pg-sys/src/submodules/utils.rs: -------------------------------------------------------------------------------- 1 | //LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 2 | //LICENSE 3 | //LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 4 | //LICENSE 5 | //LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 6 | //LICENSE 7 | //LICENSE All rights reserved. 8 | //LICENSE 9 | //LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 10 | //! General utility functions 11 | use crate as pg_sys; 12 | 13 | /// Converts a `pg_sys::NameData` struct into a `&str`. 14 | /// 15 | /// This is a zero-copy operation and the returned `&str` is tied to the lifetime 16 | /// of the provided `pg_sys::NameData` 17 | #[inline] 18 | pub fn name_data_to_str(name_data: &pg_sys::NameData) -> &str { 19 | unsafe { core::ffi::CStr::from_ptr(name_data.data.as_ptr()) }.to_str().unwrap() 20 | } 21 | -------------------------------------------------------------------------------- /pgrx-sql-entity-graph/Cargo.toml: -------------------------------------------------------------------------------- 1 | #LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 2 | #LICENSE 3 | #LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 4 | #LICENSE 5 | #LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 6 | #LICENSE 7 | #LICENSE All rights reserved. 8 | #LICENSE 9 | #LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 10 | 11 | [package] 12 | name = "pgrx-sql-entity-graph" 13 | version = "0.14.3" 14 | authors = ["PgCentral Foundation, Inc. "] 15 | license = "MIT" 16 | description = "Sql Entity Graph for `pgrx`" 17 | homepage = "https://github.com/pgcentralfoundation/pgrx/" 18 | repository = "https://github.com/pgcentralfoundation/pgrx/" 19 | documentation = "https://docs.rs/pgrx-sql-entity-graph" 20 | readme = "README.md" 21 | edition = "2021" 22 | include = ["src/**/*", "README.md"] 23 | 24 | [features] 25 | syntax-highlighting = ["dep:syntect", "dep:owo-colors"] 26 | no-schema-generation = [] 27 | 28 | [dependencies] 29 | eyre.workspace = true 30 | proc-macro2.workspace = true 31 | quote.workspace = true 32 | syn.workspace = true 33 | thiserror.workspace = true 34 | 35 | convert_case = "0.8.0" 36 | petgraph = "0.8.1" 37 | unescape = "0.1.0" # for escaped-character-handling 38 | 39 | # colorized sql output 40 | owo-colors = { optional = true, workspace = true } 41 | syntect = { version = "5.2.0", default-features = false, features = ["default-fancy"], optional = true } 42 | 43 | [lints.clippy] 44 | assigning-clones = "allow" # wrong diagnosis and wrong suggestions 45 | too-many-arguments = "allow" # I argue with myself all the time 46 | -------------------------------------------------------------------------------- /pgrx-sql-entity-graph/README.md: -------------------------------------------------------------------------------- 1 | # pgrx-sql-entity-graph 2 | 3 | Sql Entity Graph generation for [`pgrx`](https://crates.io/crates/pgrx/). 4 | 5 | This crate is used internally by various `pgrx` crates -------------------------------------------------------------------------------- /pgrx-sql-entity-graph/src/composite_type.rs: -------------------------------------------------------------------------------- 1 | /// Innards of a `composite_type!` 2 | /// 3 | /// For SQL generation and further expansion. 4 | /// Use this so you don't drop the span on the floor. 5 | #[derive(Debug, Clone)] 6 | pub struct CompositeTypeMacro { 7 | pub(crate) lifetime: Option, 8 | pub(crate) expr: syn::Expr, 9 | pub(crate) span: proc_macro2::Span, 10 | } 11 | 12 | impl syn::parse::Parse for CompositeTypeMacro { 13 | fn parse(input: syn::parse::ParseStream) -> Result { 14 | let span = input.span(); 15 | let lifetime: Option = input.parse().ok(); 16 | let _comma: Option = input.parse().ok(); 17 | let expr = input.parse()?; 18 | Ok(Self { lifetime, expr, span }) 19 | } 20 | } 21 | 22 | /// Take a `composite_type!` from a macro 23 | pub fn handle_composite_type_macro(mac: &syn::Macro) -> syn::Result { 24 | let out: CompositeTypeMacro = mac.parse_body()?; 25 | Ok(out) 26 | } 27 | 28 | impl CompositeTypeMacro { 29 | /// Expands into the implementing type, explicitly eliding the lifetime 30 | /// if none is actually given. 31 | pub fn expand_with_lifetime(&self) -> syn::Type { 32 | let CompositeTypeMacro { lifetime, span, .. } = self.clone(); 33 | let lifetime = lifetime.unwrap_or_else(|| syn::Lifetime::new("'_", span)); 34 | syn::parse_quote! { 35 | ::pgrx::heap_tuple::PgHeapTuple<#lifetime, ::pgrx::pgbox::AllocatedByRust> 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /pgrx-sql-entity-graph/src/enrich.rs: -------------------------------------------------------------------------------- 1 | //LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 2 | //LICENSE 3 | //LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 4 | //LICENSE 5 | //LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 6 | //LICENSE 7 | //LICENSE All rights reserved. 8 | //LICENSE 9 | //LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 10 | use proc_macro2::TokenStream as TokenStream2; 11 | use quote::{quote, ToTokens, TokenStreamExt}; 12 | 13 | pub struct CodeEnrichment(pub T); 14 | 15 | /// Generates the rust code that pgrx requires for one of its SQL interfaces such as `#[pg_extern]` 16 | pub trait ToRustCodeTokens { 17 | fn to_rust_code_tokens(&self) -> TokenStream2 { 18 | quote! {} 19 | } 20 | } 21 | 22 | /// Generates the rust code to tie one of pgrx' supported SQL interfaces into pgrx' schema generator 23 | pub trait ToEntityGraphTokens { 24 | fn to_entity_graph_tokens(&self) -> TokenStream2; 25 | } 26 | 27 | impl ToTokens for CodeEnrichment 28 | where 29 | T: ToEntityGraphTokens + ToRustCodeTokens, 30 | { 31 | fn to_tokens(&self, tokens: &mut TokenStream2) { 32 | #[cfg(not(feature = "no-schema-generation"))] 33 | { 34 | // only emit entity graph tokens when we're generating a schema, which is our default mode 35 | tokens.append_all(self.0.to_entity_graph_tokens()); 36 | } 37 | 38 | tokens.append_all(self.0.to_rust_code_tokens()); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /pgrx-sql-entity-graph/src/finfo.rs: -------------------------------------------------------------------------------- 1 | use proc_macro2::{Ident, TokenStream}; 2 | use quote::{format_ident, quote, quote_spanned}; 3 | use syn::{self, spanned::Spanned, ItemFn}; 4 | 5 | /// Generate the Postgres fn info record 6 | /// 7 | /// Equivalent to PG_FUNCTION_INFO_V1, Postgres will sprintf the fn ident, then `dlsym(so, expected_name)`, 8 | /// so it is important to pass exactly the ident that you want to have the record associated with! 9 | pub fn finfo_v1_tokens(ident: proc_macro2::Ident) -> syn::Result { 10 | let finfo_name = format_ident!("pg_finfo_{ident}"); 11 | let tokens = quote! { 12 | #[no_mangle] 13 | #[doc(hidden)] 14 | pub extern "C" fn #finfo_name() -> &'static ::pgrx::pg_sys::Pg_finfo_record { 15 | const V1_API: ::pgrx::pg_sys::Pg_finfo_record = ::pgrx::pg_sys::Pg_finfo_record { api_version: 1 }; 16 | &V1_API 17 | } 18 | }; 19 | syn::parse2(tokens) 20 | } 21 | 22 | pub fn finfo_v1_extern_c( 23 | original: &syn::ItemFn, 24 | fcinfo: Ident, 25 | contents: TokenStream, 26 | ) -> syn::Result { 27 | let original_name = &original.sig.ident; 28 | let wrapper_symbol = format_ident!("{}_wrapper", original_name); 29 | 30 | let synthetic = proc_macro2::Span::mixed_site(); 31 | let synthetic = synthetic.located_at(original.sig.span()); 32 | 33 | let tokens = quote_spanned! { synthetic => 34 | #[no_mangle] 35 | #[doc(hidden)] 36 | pub unsafe extern "C-unwind" fn #wrapper_symbol(#fcinfo: ::pgrx::pg_sys::FunctionCallInfo) -> ::pgrx::pg_sys::Datum { 37 | #contents 38 | } 39 | }; 40 | 41 | syn::parse2(tokens) 42 | } 43 | -------------------------------------------------------------------------------- /pgrx-sql-entity-graph/src/fmt.rs: -------------------------------------------------------------------------------- 1 | /// Evaluate an expression that resolves to any `impl ToTokens`, then produce a closure 2 | /// for lazily combining errors only on the unhappy path of `syn::Result` 3 | macro_rules! lazy_err { 4 | ($span_expr:expr, $lit:literal $(, $tokens:tt),*) => { 5 | { 6 | let spanning = $span_expr; 7 | || ::syn::Error::new_spanned(spanning, format!($lit, $($tokens)*)) 8 | } 9 | } 10 | } 11 | 12 | pub fn with_array_brackets(s: String, brackets: bool) -> String { 13 | s + if brackets { "[]" } else { "" } 14 | } 15 | 16 | pub(crate) trait ErrHarder { 17 | fn more_error(self, closerr: impl FnOnce() -> syn::Error) -> Self; 18 | } 19 | 20 | impl ErrHarder for syn::Result { 21 | fn more_error(self, closerr: impl FnOnce() -> syn::Error) -> Self { 22 | self.map_err(|inner| { 23 | let mut e = inner.clone(); 24 | e.combine(closerr()); 25 | e 26 | }) 27 | } 28 | } 29 | 30 | impl ErrHarder for syn::Error { 31 | fn more_error(mut self, closerr: impl FnOnce() -> syn::Error) -> Self { 32 | self.combine(closerr()); 33 | self 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /pgrx-sql-entity-graph/src/metadata/entity.rs: -------------------------------------------------------------------------------- 1 | //LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 2 | //LICENSE 3 | //LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 4 | //LICENSE 5 | //LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 6 | //LICENSE 7 | //LICENSE All rights reserved. 8 | //LICENSE 9 | //LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 10 | /*! 11 | 12 | Function and type level metadata entities for Rust to SQL translation 13 | 14 | > Like all of the [`sql_entity_graph`][crate] APIs, this is considered **internal** 15 | > to the `pgrx` framework and very subject to change between versions. While you may use this, please do it with caution. 16 | 17 | 18 | */ 19 | use super::{ArgumentError, Returns, ReturnsError, SqlMapping}; 20 | 21 | #[derive(Clone, Debug, Hash, Eq, PartialEq, Ord, PartialOrd)] 22 | pub struct FunctionMetadataEntity { 23 | pub arguments: Vec, 24 | pub retval: FunctionMetadataTypeEntity, 25 | pub path: &'static str, 26 | } 27 | 28 | #[derive(Clone, Debug, Hash, Eq, PartialEq, Ord, PartialOrd)] 29 | pub struct FunctionMetadataTypeEntity { 30 | pub type_name: &'static str, 31 | pub argument_sql: Result, 32 | pub return_sql: Result, 33 | pub variadic: bool, 34 | pub optional: bool, 35 | } 36 | -------------------------------------------------------------------------------- /pgrx-sql-entity-graph/src/metadata/mod.rs: -------------------------------------------------------------------------------- 1 | //LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 2 | //LICENSE 3 | //LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 4 | //LICENSE 5 | //LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 6 | //LICENSE 7 | //LICENSE All rights reserved. 8 | //LICENSE 9 | //LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 10 | /*! 11 | 12 | Function and type level metadata for Rust to SQL translation 13 | 14 | > Like all of the [`sql_entity_graph`][crate] APIs, this is considered **internal** 15 | > to the `pgrx` framework and very subject to change between versions. While you may use this, please do it with caution. 16 | 17 | 18 | */ 19 | 20 | mod entity; 21 | mod function_metadata; 22 | mod return_variant; 23 | mod sql_translatable; 24 | 25 | pub use entity::{FunctionMetadataEntity, FunctionMetadataTypeEntity}; 26 | pub use function_metadata::FunctionMetadata; 27 | pub use return_variant::{Returns, ReturnsError}; 28 | pub use sql_translatable::{ArgumentError, SqlMapping, SqlTranslatable}; 29 | -------------------------------------------------------------------------------- /pgrx-sql-entity-graph/src/pg_extern/entity/argument.rs: -------------------------------------------------------------------------------- 1 | //LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 2 | //LICENSE 3 | //LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 4 | //LICENSE 5 | //LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 6 | //LICENSE 7 | //LICENSE All rights reserved. 8 | //LICENSE 9 | //LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 10 | /*! 11 | 12 | `#[pg_extern]` related argument entities for Rust to SQL translation 13 | 14 | > Like all of the [`sql_entity_graph`][crate] APIs, this is considered **internal** 15 | > to the `pgrx` framework and very subject to change between versions. While you may use this, please do it with caution. 16 | 17 | */ 18 | use crate::{SqlGraphIdentifier, UsedTypeEntity}; 19 | 20 | /// The output of a [`PgExternArgument`](crate::PgExternArgument) from `quote::ToTokens::to_tokens`. 21 | #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] 22 | pub struct PgExternArgumentEntity { 23 | pub pattern: &'static str, 24 | pub used_ty: UsedTypeEntity, 25 | } 26 | 27 | impl SqlGraphIdentifier for PgExternArgumentEntity { 28 | fn dot_identifier(&self) -> String { 29 | format!("arg {}", self.rust_identifier()) 30 | } 31 | fn rust_identifier(&self) -> String { 32 | self.used_ty.full_path.to_string() 33 | } 34 | 35 | fn file(&self) -> Option<&'static str> { 36 | None 37 | } 38 | 39 | fn line(&self) -> Option { 40 | None 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /pgrx-sql-entity-graph/src/pg_extern/entity/cast.rs: -------------------------------------------------------------------------------- 1 | //LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 2 | //LICENSE 3 | //LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 4 | //LICENSE 5 | //LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 6 | //LICENSE 7 | //LICENSE All rights reserved. 8 | //LICENSE 9 | //LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 10 | /*! 11 | 12 | `#[pg_extern]` related cast entities for Rust to SQL translation 13 | 14 | > Like all of the [`sql_entity_graph`][crate] APIs, this is considered **internal** 15 | > to the `pgrx` framework and very subject to change between versions. While you may use this, please do it with caution. 16 | 17 | */ 18 | 19 | /// The output of a [`PgCast`](crate::PgCast) from `quote::ToTokens::to_tokens`. 20 | #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] 21 | pub enum PgCastEntity { 22 | Default, 23 | Assignment, 24 | Implicit, 25 | } 26 | -------------------------------------------------------------------------------- /pgrx-sql-entity-graph/src/pg_extern/entity/operator.rs: -------------------------------------------------------------------------------- 1 | //LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 2 | //LICENSE 3 | //LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 4 | //LICENSE 5 | //LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 6 | //LICENSE 7 | //LICENSE All rights reserved. 8 | //LICENSE 9 | //LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 10 | /*! 11 | 12 | `#[pg_extern]` related operator entities for Rust to SQL translation 13 | 14 | > Like all of the [`sql_entity_graph`][crate] APIs, this is considered **internal** 15 | > to the `pgrx` framework and very subject to change between versions. While you may use this, please do it with caution. 16 | 17 | */ 18 | 19 | /// The output of a [`PgOperator`](crate::PgOperator) from `quote::ToTokens::to_tokens`. 20 | #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] 21 | pub struct PgOperatorEntity { 22 | pub opname: Option<&'static str>, 23 | pub commutator: Option<&'static str>, 24 | pub negator: Option<&'static str>, 25 | pub restrict: Option<&'static str>, 26 | pub join: Option<&'static str>, 27 | pub hashes: bool, 28 | pub merges: bool, 29 | } 30 | -------------------------------------------------------------------------------- /pgrx-sql-entity-graph/src/pg_extern/entity/returning.rs: -------------------------------------------------------------------------------- 1 | //LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 2 | //LICENSE 3 | //LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 4 | //LICENSE 5 | //LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 6 | //LICENSE 7 | //LICENSE All rights reserved. 8 | //LICENSE 9 | //LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 10 | /*! 11 | 12 | `#[pg_extern]` related return value entities for Rust to SQL translation 13 | 14 | > Like all of the [`sql_entity_graph`][crate] APIs, this is considered **internal** 15 | > to the `pgrx` framework and very subject to change between versions. While you may use this, please do it with caution. 16 | 17 | */ 18 | use crate::UsedTypeEntity; 19 | 20 | #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] 21 | pub enum PgExternReturnEntity { 22 | None, 23 | Type { ty: UsedTypeEntity }, 24 | SetOf { ty: UsedTypeEntity }, 25 | Iterated { tys: Vec }, 26 | Trigger, 27 | } 28 | 29 | #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] 30 | pub struct PgExternReturnEntityIteratedItem { 31 | pub ty: UsedTypeEntity, 32 | pub name: Option<&'static str>, 33 | } 34 | -------------------------------------------------------------------------------- /pgrx-tests/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .idea/ 3 | target/ 4 | *.iml 5 | **/*.rs.bk 6 | Cargo.lock 7 | sql/pgrx_tests-1.0.sql 8 | -------------------------------------------------------------------------------- /pgrx-tests/README.md: -------------------------------------------------------------------------------- 1 | # pgrx-tests 2 | 3 | Test framework for [`pgrx`](https://crates.io/crates/pgrx/). 4 | 5 | Meant to be used as one of your `[dev-dependencies]` when using `pgrx`. -------------------------------------------------------------------------------- /pgrx-tests/pgrx_tests.control: -------------------------------------------------------------------------------- 1 | comment = 'tests: Created by pgrx' 2 | default_version = '1.0' 3 | module_pathname = 'pgrx_tests' 4 | relocatable = false 5 | superuser = false 6 | -------------------------------------------------------------------------------- /pgrx-tests/src/bin/pgrx_embed.rs: -------------------------------------------------------------------------------- 1 | ::pgrx::pgrx_embed!(); 2 | -------------------------------------------------------------------------------- /pgrx-tests/src/lib.rs: -------------------------------------------------------------------------------- 1 | //LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 2 | //LICENSE 3 | //LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 4 | //LICENSE 5 | //LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 6 | //LICENSE 7 | //LICENSE All rights reserved. 8 | //LICENSE 9 | //LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 10 | 11 | #![cfg_attr(feature = "nightly", feature(allocator_api))] 12 | 13 | mod framework; 14 | #[cfg(any(test, feature = "pg_test"))] 15 | mod tests; 16 | 17 | pub use framework::*; 18 | #[cfg(feature = "proptest")] 19 | pub mod proptest; 20 | 21 | #[cfg(any(test, feature = "pg_test"))] 22 | pgrx::pg_module_magic!(); 23 | 24 | #[cfg(test)] 25 | pub mod pg_test { 26 | pub fn setup(_options: Vec<&str>) { 27 | // noop 28 | } 29 | 30 | pub fn postgresql_conf_options() -> Vec<&'static str> { 31 | vec!["shared_preload_libraries='pgrx_tests'"] 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /pgrx-tests/src/tests/anyelement_tests.rs: -------------------------------------------------------------------------------- 1 | use pgrx::{prelude::*, AnyElement}; 2 | 3 | #[pg_extern] 4 | fn anyelement_arg(element: AnyElement) -> AnyElement { 5 | element 6 | } 7 | 8 | #[cfg(any(test, feature = "pg_test"))] 9 | #[pgrx::pg_schema] 10 | mod tests { 11 | #[allow(unused_imports)] 12 | use crate as pgrx_tests; 13 | 14 | use pgrx::{datum::DatumWithOid, prelude::*, AnyElement}; 15 | 16 | #[pg_test] 17 | fn test_anyelement_arg() -> Result<(), pgrx::spi::Error> { 18 | let element = Spi::get_one_with_args::("SELECT anyelement_arg($1);", unsafe { 19 | &[DatumWithOid::new(123, AnyElement::type_oid())] 20 | })? 21 | .map(|e| e.datum()); 22 | 23 | assert_eq!(element, 123.into_datum()); 24 | 25 | Ok(()) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /pgrx-tests/src/tests/anynumeric_tests.rs: -------------------------------------------------------------------------------- 1 | use pgrx::{prelude::*, AnyNumeric}; 2 | 3 | #[pg_extern] 4 | fn anynumeric_arg(numeric: AnyNumeric) -> AnyNumeric { 5 | numeric 6 | } 7 | 8 | #[cfg(any(test, feature = "pg_test"))] 9 | #[pgrx::pg_schema] 10 | mod tests { 11 | #[allow(unused_imports)] 12 | use crate as pgrx_tests; 13 | 14 | use pgrx::{prelude::*, AnyNumeric}; 15 | 16 | #[pg_test] 17 | fn test_anynumeric_arg() -> Result<(), pgrx::spi::Error> { 18 | let numeric = 19 | Spi::get_one_with_args::("SELECT anynumeric_arg($1);", &[123.into()])? 20 | .map(|n| n.normalize().to_string()); 21 | 22 | assert_eq!(numeric, Some("123".to_string())); 23 | 24 | Ok(()) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /pgrx-tests/src/tests/attributes_tests.rs: -------------------------------------------------------------------------------- 1 | //LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 2 | //LICENSE 3 | //LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 4 | //LICENSE 5 | //LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 6 | //LICENSE 7 | //LICENSE All rights reserved. 8 | //LICENSE 9 | //LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 10 | #[cfg(any(test, feature = "pg_test"))] 11 | #[pgrx::pg_schema] 12 | mod tests { 13 | #[allow(unused_imports)] 14 | use crate as pgrx_tests; 15 | 16 | use pgrx::prelude::*; 17 | 18 | #[pg_test] 19 | #[ignore = "This test should be ignored."] 20 | fn test_for_ignore_attribute() { 21 | assert_eq!(true, false); 22 | } 23 | 24 | #[pg_test] 25 | #[should_panic(expected = "I should panic")] 26 | fn test_for_should_panic_attribute() { 27 | assert_eq!(1, 2, "I should panic"); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /pgrx-tests/src/tests/bindings_of_inline_fn_tests.rs: -------------------------------------------------------------------------------- 1 | //LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 2 | //LICENSE 3 | //LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 4 | //LICENSE 5 | //LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 6 | //LICENSE 7 | //LICENSE All rights reserved. 8 | //LICENSE 9 | //LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 10 | #[cfg(any(test, feature = "pg_test"))] 11 | #[pgrx::pg_schema] 12 | mod tests { 13 | #[allow(unused_imports)] 14 | use crate as pgrx_tests; 15 | 16 | use pgrx::prelude::*; 17 | 18 | #[pg_test] 19 | fn test_static_inline_fns() { 20 | unsafe { 21 | use pgrx::pg_sys::{itemptr_encode, BlockIdData, ItemPointerData}; 22 | assert_eq!( 23 | itemptr_encode(&mut ItemPointerData { 24 | ip_blkid: BlockIdData { bi_hi: 111, bi_lo: 222 }, 25 | ip_posid: 333 26 | }), 27 | 476755919181 28 | ); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /pgrx-tests/src/tests/cfg_tests.rs: -------------------------------------------------------------------------------- 1 | //LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 2 | //LICENSE 3 | //LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 4 | //LICENSE 5 | //LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 6 | //LICENSE 7 | //LICENSE All rights reserved. 8 | //LICENSE 9 | //LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 10 | #![allow(unexpected_cfgs)] 11 | use pgrx::prelude::*; 12 | 13 | #[cfg(any(test, feature = "pg_test"))] 14 | #[pg_extern] 15 | fn func_test_cfg() {} 16 | 17 | #[cfg(feature = "nonexistent")] 18 | #[pg_extern] 19 | fn func_non_existent_cfg(t: NonexistentType) {} 20 | 21 | #[cfg(any(test, feature = "pg_test"))] 22 | #[pgrx::pg_schema] 23 | mod tests { 24 | #[allow(unused_imports)] 25 | use crate as pgrx_tests; 26 | 27 | use pgrx::prelude::*; 28 | 29 | #[pg_test] 30 | fn test_cfg_exists() -> Result<(), spi::Error> { 31 | Spi::run("SELECT func_test_cfg();") 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /pgrx-tests/src/tests/composite_type_tests.rs: -------------------------------------------------------------------------------- 1 | use pgrx::prelude::*; 2 | 3 | extension_sql!( 4 | r#" 5 | CREATE TYPE entity AS (id INT, lang TEXT); 6 | CREATE TYPE result AS (score DOUBLE PRECISION, entities entity[]); 7 | "#, 8 | name = "issue1293" 9 | ); 10 | 11 | #[pg_extern(requires = ["issue1293"])] 12 | fn create_result() -> pgrx::composite_type!('static, "result") { 13 | let mut record = PgHeapTuple::new_composite_type("result").unwrap(); 14 | record.set_by_name("score", 0.707).unwrap(); 15 | let mut entity_records: Vec = Vec::new(); 16 | for i in 0..10 { 17 | let mut entity_record = PgHeapTuple::new_composite_type("entity").unwrap(); 18 | entity_record.set_by_name("id", i).unwrap(); 19 | entity_record.set_by_name("lang", "en".to_string()).unwrap(); 20 | entity_records.push(entity_record); 21 | } 22 | record.set_by_name("entities", entity_records).unwrap(); 23 | return record; 24 | } 25 | 26 | #[cfg(any(test, feature = "pg_test"))] 27 | #[pgrx::pg_schema] 28 | mod tests { 29 | use pgrx::prelude::*; 30 | 31 | #[allow(unused_imports)] 32 | use crate as pgrx_tests; 33 | 34 | #[pg_test] 35 | fn test_array_of_composite_type() { 36 | Spi::get_one::("SELECT create_result() is not null") 37 | .expect("SPI failed") 38 | .expect("failed to create `result` composite type'"); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /pgrx-tests/src/tests/derive_pgtype_lifetimes.rs: -------------------------------------------------------------------------------- 1 | //LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 2 | //LICENSE 3 | //LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 4 | //LICENSE 5 | //LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 6 | //LICENSE 7 | //LICENSE All rights reserved. 8 | //LICENSE 9 | //LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 10 | #![allow(dead_code)] 11 | /// the purpose of this test is to just make sure this code compiles! 12 | use pgrx::prelude::*; 13 | use serde::*; 14 | 15 | fn foo<'a>(_s: Vec>) { 16 | unimplemented!() 17 | } 18 | 19 | #[derive(Debug, Clone, PartialEq, PostgresType, Serialize, Deserialize)] 20 | pub struct ProximityPart<'input> { 21 | #[serde(borrow)] 22 | pub words: Vec>, 23 | pub distance: Option, 24 | } 25 | 26 | #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] 27 | pub struct ProximityDistance { 28 | pub distance: u32, 29 | pub in_order: bool, 30 | } 31 | 32 | #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] 33 | pub enum Term<'input> { 34 | Null, 35 | String(String, Option), 36 | Wildcard(String, Option), 37 | Fuzzy(&'input str, u8, Option), 38 | ParsedArray(Vec>, Option), 39 | UnparsedArray(&'input str, Option), 40 | ProximityChain(Vec>), 41 | } 42 | -------------------------------------------------------------------------------- /pgrx-tests/src/tests/enum_type_tests.rs: -------------------------------------------------------------------------------- 1 | //LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 2 | //LICENSE 3 | //LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 4 | //LICENSE 5 | //LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 6 | //LICENSE 7 | //LICENSE All rights reserved. 8 | //LICENSE 9 | //LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 10 | use pgrx::prelude::*; 11 | 12 | #[derive(PostgresEnum, PartialEq, Debug, Default)] 13 | pub enum Foo { 14 | #[default] 15 | One, 16 | Two, 17 | Three, 18 | } 19 | 20 | #[pg_extern] 21 | fn take_foo_enum(value: Foo) -> Foo { 22 | assert_eq!(value, Foo::One); 23 | 24 | Foo::Three 25 | } 26 | 27 | #[cfg(any(test, feature = "pg_test"))] 28 | #[pgrx::pg_schema] 29 | mod tests { 30 | #[allow(unused_imports)] 31 | use crate as pgrx_tests; 32 | 33 | use super::Foo; 34 | use pgrx::prelude::*; 35 | 36 | #[test] 37 | fn make_idea_happy() {} 38 | 39 | #[pg_test] 40 | fn test_foo_enum() { 41 | let result = Spi::get_one::("SELECT take_foo_enum('One');"); 42 | assert_eq!(Ok(Some(Foo::Three)), result); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /pgrx-tests/src/tests/geo_tests.rs: -------------------------------------------------------------------------------- 1 | //LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 2 | //LICENSE 3 | //LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 4 | //LICENSE 5 | //LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 6 | //LICENSE 7 | //LICENSE All rights reserved. 8 | //LICENSE 9 | //LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 10 | #[cfg(any(test, feature = "pg_test"))] 11 | #[pgrx::pg_schema] 12 | mod tests { 13 | #[allow(unused_imports)] 14 | use crate as pgrx_tests; 15 | 16 | use pgrx::prelude::*; 17 | 18 | #[pg_test] 19 | fn test_point_into_datum() -> spi::Result<()> { 20 | let p = 21 | Spi::get_one::("SELECT '42, 99'::point")?.expect("SPI result was null"); 22 | assert_eq!(p.x, 42.0); 23 | assert_eq!(p.y, 99.0); 24 | Ok(()) 25 | } 26 | 27 | #[pg_test] 28 | fn test_box_into_datum() -> spi::Result<()> { 29 | let b = Spi::get_one::("SELECT '1,2,3,4'::box")?.expect("SPI result was null"); 30 | assert_eq!(b.high.x, 3.0); 31 | assert_eq!(b.high.y, 4.0); 32 | assert_eq!(b.low.x, 1.0); 33 | assert_eq!(b.low.y, 2.0); 34 | Ok(()) 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /pgrx-tests/src/tests/inet_tests.rs: -------------------------------------------------------------------------------- 1 | //LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 2 | //LICENSE 3 | //LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 4 | //LICENSE 5 | //LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 6 | //LICENSE 7 | //LICENSE All rights reserved. 8 | //LICENSE 9 | //LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 10 | #[cfg(any(test, feature = "pg_test"))] 11 | #[pgrx::pg_schema] 12 | mod tests { 13 | #[allow(unused_imports)] 14 | use crate as pgrx_tests; 15 | 16 | use pgrx::prelude::*; 17 | use pgrx::Inet; 18 | 19 | #[pg_test] 20 | fn test_deserialize_inet() { 21 | let inet = 22 | serde_json::from_str::("\"192.168.0.1\"").expect("failed to deserialize inet"); 23 | assert_eq!("192.168.0.1", &inet.0) 24 | } 25 | 26 | #[pg_test] 27 | fn test_serialize_inet() { 28 | let json = serde_json::to_string(&Inet("192.168.0.1".to_owned())) 29 | .expect("failed to serialize inet"); 30 | assert_eq!("\"192.168.0.1\"", &json); 31 | } 32 | 33 | #[pg_extern] 34 | fn take_and_return_inet(inet: Inet) -> Inet { 35 | inet 36 | } 37 | 38 | #[pg_test] 39 | fn test_take_and_return_inet() { 40 | let rc = Spi::get_one::( 41 | "SELECT tests.take_and_return_inet('192.168.0.1') = '192.168.0.1'::inet;", 42 | ); 43 | assert_eq!(rc, Ok(Some(true))); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /pgrx-tests/src/tests/issue1134.rs: -------------------------------------------------------------------------------- 1 | //LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 2 | //LICENSE 3 | //LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 4 | //LICENSE 5 | //LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 6 | //LICENSE 7 | //LICENSE All rights reserved. 8 | //LICENSE 9 | //LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 10 | // If this code doesn't generate a syntax error in the generated SQL then PR #1134 is working as expected 11 | use pgrx::{prelude::*, Internal}; 12 | 13 | pub struct Foo; 14 | 15 | #[pg_aggregate] 16 | impl Aggregate for Foo { 17 | const NAME: &'static str = "foo"; 18 | const ORDERED_SET: bool = true; 19 | 20 | type OrderedSetArgs = (name!(a, f64), name!(b, f64)); 21 | 22 | type State = Internal; 23 | type Args = f64; 24 | type Finalize = f64; 25 | 26 | fn state( 27 | state: Self::State, 28 | _value: Self::Args, 29 | _fcinfo: pg_sys::FunctionCallInfo, 30 | ) -> Self::State { 31 | // FIXME create and maintain real state here 32 | state 33 | } 34 | 35 | fn finalize( 36 | _state: Self::State, 37 | _dontcare: Self::OrderedSetArgs, 38 | _fcinfo: pg_sys::FunctionCallInfo, 39 | ) -> Self::Finalize { 40 | 0.0 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /pgrx-tests/src/tests/lifetime_tests.rs: -------------------------------------------------------------------------------- 1 | //LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 2 | //LICENSE 3 | //LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 4 | //LICENSE 5 | //LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 6 | //LICENSE 7 | //LICENSE All rights reserved. 8 | //LICENSE 9 | //LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 10 | //! This file exists just to ensure the code within compiles 11 | use pgrx::prelude::*; 12 | use serde::{Deserialize, Serialize}; 13 | use std::marker::PhantomData; 14 | 15 | #[derive(PostgresType, Serialize, Deserialize)] 16 | pub struct CustomType<'s> { 17 | __marker: PhantomData<&'s ()>, 18 | } 19 | 20 | #[pg_extern] 21 | fn type_with_lifetime<'s>(_value: Option>) {} 22 | 23 | #[pg_extern] 24 | fn type_ref_with_lifetime<'a>(_value: &'a str) {} 25 | 26 | #[pg_extern] 27 | fn returns_lifetime() -> Option> { 28 | None 29 | } 30 | 31 | #[pg_extern] 32 | fn returns_ref_with_lifetime() -> &'static str { 33 | "" 34 | } 35 | 36 | #[pg_extern] 37 | fn returns_option_ref_with_lifetime() -> Option<&'static str> { 38 | None 39 | } 40 | 41 | #[pg_extern] 42 | fn returns_tuple_with_lifetime<'a>( 43 | value: &'a str, 44 | ) -> TableIterator<'a, (name!(a, &'a str), name!(b, Option<&'a str>))> { 45 | TableIterator::once((value, Some(value))) 46 | } 47 | 48 | #[pg_extern] 49 | fn returns_iterator_with_lifetime<'a>(value: &'a str) -> SetOfIterator<'a, &'a str> { 50 | SetOfIterator::new(value.split_whitespace().into_iter()) 51 | } 52 | -------------------------------------------------------------------------------- /pgrx-tests/src/tests/name_tests.rs: -------------------------------------------------------------------------------- 1 | //LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 2 | //LICENSE 3 | //LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 4 | //LICENSE 5 | //LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 6 | //LICENSE 7 | //LICENSE All rights reserved. 8 | //LICENSE 9 | //LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 10 | use pgrx::prelude::*; 11 | 12 | #[pg_extern(name = "renamed_func")] 13 | fn func_to_rename() {} 14 | 15 | #[cfg(any(test, feature = "pg_test"))] 16 | #[pgrx::pg_schema] 17 | mod tests { 18 | #[allow(unused_imports)] 19 | use crate as pgrx_tests; 20 | 21 | use pgrx::prelude::*; 22 | 23 | #[pg_test] 24 | fn renamed_func() { 25 | Spi::run("SELECT renamed_func();").expect("SPI failed"); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /pgrx-tests/src/tests/oid_tests.rs: -------------------------------------------------------------------------------- 1 | //LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 2 | //LICENSE 3 | //LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 4 | //LICENSE 5 | //LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 6 | //LICENSE 7 | //LICENSE All rights reserved. 8 | //LICENSE 9 | //LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 10 | #[cfg(any(test, feature = "pg_test"))] 11 | #[pgrx::pg_schema] 12 | mod tests { 13 | #[allow(unused_imports)] 14 | use crate as pgrx_tests; 15 | 16 | use pgrx::prelude::*; 17 | 18 | #[pg_extern] 19 | fn oid_roundtrip(oid: pg_sys::Oid) -> pg_sys::Oid { 20 | oid 21 | } 22 | 23 | #[pg_test] 24 | fn test_reasonable_oid() -> spi::Result<()> { 25 | let oid = Spi::get_one::("SELECT tests.oid_roundtrip(42)")? 26 | .expect("SPI result was null"); 27 | assert_eq!(oid.to_u32(), 42); 28 | Ok(()) 29 | } 30 | 31 | #[pg_test] 32 | fn test_completely_unreasonable_but_still_valid_oid() -> spi::Result<()> { 33 | // nb: this stupid value is greater than i32::MAX 34 | let oid = Spi::get_one::("SELECT tests.oid_roundtrip(2147483648)")? 35 | .expect("SPI result was null"); 36 | assert_eq!(oid.to_u32(), 2_147_483_648); 37 | Ok(()) 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /pgrx-tests/src/tests/pg_guard_tests.rs: -------------------------------------------------------------------------------- 1 | //LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 2 | //LICENSE 3 | //LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 4 | //LICENSE 5 | //LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 6 | //LICENSE 7 | //LICENSE All rights reserved. 8 | //LICENSE 9 | //LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 10 | use pgrx::prelude::*; 11 | 12 | #[pg_extern] 13 | fn extern_func() -> bool { 14 | extern_func_impl::() 15 | } 16 | 17 | // This ensures that parameterized function compiles when it has `pg_guard` attached to it 18 | #[pg_guard] 19 | // Uncommenting the line below will make it fail to compile 20 | // #[no_mangle] 21 | extern "C-unwind" fn extern_func_impl() -> bool { 22 | true 23 | } 24 | 25 | // This ensures that non-parameterized function compiles when it has `pg_guard` attached to it 26 | // and [no_mangle] 27 | #[pg_guard] 28 | #[no_mangle] 29 | extern "C-unwind" fn extern_func_impl_1() -> bool { 30 | true 31 | } 32 | 33 | // This ensures that lifetime-parameterized function compiles when it has `pg_guard` attached to it 34 | // and [no_mangle] 35 | #[pg_guard] 36 | #[no_mangle] 37 | #[allow(unused_lifetimes)] 38 | extern "C-unwind" fn extern_func_impl_2<'a>() -> bool { 39 | true 40 | } 41 | 42 | #[cfg(any(test, feature = "pg_test"))] 43 | #[pg_schema] 44 | mod tests { 45 | #[allow(unused_imports)] 46 | use crate as pgrx_tests; 47 | } 48 | -------------------------------------------------------------------------------- /pgrx-tests/src/tests/pg_operator_tests.rs: -------------------------------------------------------------------------------- 1 | //LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 2 | //LICENSE 3 | //LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 4 | //LICENSE 5 | //LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 6 | //LICENSE 7 | //LICENSE All rights reserved. 8 | //LICENSE 9 | //LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 10 | use pgrx::prelude::*; 11 | 12 | #[pg_schema] 13 | mod pg_catalog { 14 | use pgrx::{opname, pg_operator}; 15 | 16 | #[pg_operator] 17 | #[opname(==>)] 18 | fn concat_strings(left: String, right: String) -> String { 19 | left + &right 20 | } 21 | } 22 | 23 | #[cfg(any(test, feature = "pg_test"))] 24 | #[pg_schema] 25 | mod tests { 26 | #[allow(unused_imports)] 27 | use crate as pgrx_tests; 28 | use pgrx::prelude::*; 29 | 30 | #[pg_test] 31 | fn test_correct_schema() { 32 | let result = Spi::get_one::("SELECT 'hello, ' OPERATOR(pg_catalog.==>) 'world';"); 33 | assert_eq!(result, Ok(Some(String::from("hello, world")))); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /pgrx-tests/src/tests/pgbox_tests.rs: -------------------------------------------------------------------------------- 1 | //LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 2 | //LICENSE 3 | //LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 4 | //LICENSE 5 | //LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 6 | //LICENSE 7 | //LICENSE All rights reserved. 8 | //LICENSE 9 | //LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 10 | #[cfg(any(test, feature = "pg_test"))] 11 | #[pgrx::pg_schema] 12 | mod tests { 13 | #[allow(unused_imports)] 14 | use crate as pgrx_tests; 15 | use pgrx::prelude::*; 16 | use pgrx::AllocatedByRust; 17 | 18 | #[pg_test] 19 | fn pgbox_alloc() { 20 | let mut ptr: PgBox = unsafe { PgBox::::alloc() }; 21 | // ptr is uninitialized data!!! This is dangerous to read from!!! 22 | *ptr = 5; 23 | 24 | assert_eq!(*ptr, 5); 25 | } 26 | 27 | #[pg_test] 28 | fn pgbox_alloc0() { 29 | let mut ptr: PgBox = unsafe { PgBox::::alloc0() }; 30 | 31 | assert_eq!(*ptr, 0); 32 | 33 | *ptr = 5; 34 | 35 | assert_eq!(*ptr, 5); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /pgrx-tests/src/tests/rel_tests.rs: -------------------------------------------------------------------------------- 1 | //LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 2 | //LICENSE 3 | //LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 4 | //LICENSE 5 | //LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 6 | //LICENSE 7 | //LICENSE All rights reserved. 8 | //LICENSE 9 | //LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 10 | use pgrx::prelude::*; 11 | use pgrx::rel::PgRelation; 12 | #[pg_extern] 13 | fn accept_relation(rel: PgRelation) { 14 | _ = rel; 15 | } 16 | 17 | #[cfg(any(test, feature = "pg_test"))] 18 | #[pgrx::pg_schema] 19 | mod tests { 20 | #[allow(unused_imports)] 21 | use crate as pgrx_tests; 22 | use pgrx::prelude::*; 23 | 24 | #[pg_test] 25 | fn test_accept_relation() { 26 | Spi::run("CREATE TABLE relation_test(name TEXT);").unwrap(); 27 | Spi::run("CREATE INDEX relation_test_index ON relation_test(name);").unwrap(); 28 | Spi::run("SELECT accept_relation('relation_test_index');").unwrap(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /pgrx-tests/src/tests/variadic_tests.rs: -------------------------------------------------------------------------------- 1 | //LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 2 | //LICENSE 3 | //LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 4 | //LICENSE 5 | //LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 6 | //LICENSE 7 | //LICENSE All rights reserved. 8 | //LICENSE 9 | //LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 10 | #[pgrx::pg_schema] 11 | mod test { 12 | use pgrx::prelude::*; 13 | use pgrx::VariadicArray; 14 | 15 | #[pg_extern] 16 | fn func_with_variadic_array_args<'dat>( 17 | _field: &str, 18 | values: VariadicArray<'dat, &'dat str>, 19 | ) -> String { 20 | values.get(0).unwrap().unwrap().to_string() 21 | } 22 | } 23 | 24 | #[cfg(any(test, feature = "pg_test"))] 25 | #[pgrx::pg_schema] 26 | mod tests { 27 | #[allow(unused_imports)] 28 | use crate as pgrx_tests; 29 | 30 | use pgrx::prelude::*; 31 | 32 | #[pg_test] 33 | fn test_func_with_variadic_array_args() { 34 | let result = Spi::get_one::( 35 | "SELECT test.func_with_variadic_array_args('test', 'a', 'b', 'c');", 36 | ); 37 | assert_eq!(result, Ok(Some("a".into()))); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /pgrx-tests/src/tests/xact_callback_tests.rs: -------------------------------------------------------------------------------- 1 | //LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 2 | //LICENSE 3 | //LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 4 | //LICENSE 5 | //LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 6 | //LICENSE 7 | //LICENSE All rights reserved. 8 | //LICENSE 9 | //LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 10 | #[cfg(any(test, feature = "pg_test"))] 11 | #[pgrx::pg_schema] 12 | mod tests { 13 | #[allow(unused_imports)] 14 | use crate as pgrx_tests; 15 | 16 | use pgrx::prelude::*; 17 | use pgrx::{info, register_xact_callback, PgXactCallbackEvent}; 18 | 19 | #[test] 20 | fn make_idea_happy() {} 21 | 22 | #[pg_test] 23 | fn test_xact_callback() { 24 | register_xact_callback(PgXactCallbackEvent::Abort, || info!("TESTMSG: Called on abort")); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /pgrx-tests/src/tests/xid64_tests.rs: -------------------------------------------------------------------------------- 1 | //LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 2 | //LICENSE 3 | //LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 4 | //LICENSE 5 | //LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 6 | //LICENSE 7 | //LICENSE All rights reserved. 8 | //LICENSE 9 | //LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 10 | #[cfg(any(test, feature = "pg_test"))] 11 | #[pgrx::pg_schema] 12 | mod tests { 13 | #[allow(unused_imports)] 14 | use crate as pgrx_tests; 15 | 16 | use pgrx::prelude::*; 17 | use pgrx::xid_to_64bit; 18 | 19 | #[test] 20 | fn make_idea_happy() {} 21 | 22 | #[pg_test] 23 | fn test_convert_xid_to_u64() { 24 | let xid = xid_to_64bit(32768.into()); 25 | assert_eq!(xid, 32768) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /pgrx-tests/tests/compile-fail/arrays-dont-leak.rs: -------------------------------------------------------------------------------- 1 | use pgrx::prelude::*; 2 | 3 | fn main() {} 4 | 5 | #[pg_extern] 6 | fn array_echo_a<'a>(a: Array<'a, &'a str>) -> Vec> { 7 | let v = a.iter().collect(); 8 | drop(a); 9 | v 10 | } 11 | 12 | #[pg_extern] 13 | fn array_echo_aba<'a, 'b>(a: Array<'a, &'b str>) -> Vec> { 14 | let v = a.iter().collect(); 15 | drop(a); 16 | v 17 | } 18 | 19 | #[pg_extern] 20 | fn array_echo_baa<'a, 'b>(a: Array<'b, &'a str>) -> Vec> { 21 | let v = a.iter().collect(); 22 | drop(a); 23 | v 24 | } 25 | 26 | fn test_leak_after_drop() -> Result<(), Box> { 27 | Spi::run("create table test_leak_after_drop (a text[]);")?; 28 | Spi::run( 29 | "insert into test_leak_after_drop (a) select array_agg(x::text) from generate_series(1, 10000) x;", 30 | )?; 31 | let array = Spi::get_one::>("SELECT array_echo(a) FROM test_leak_after_drop")? 32 | .expect("datum was null"); 33 | let top_5 = array.iter().take(5).collect::>(); 34 | drop(array); 35 | 36 | // just check the top 5 values. Even the first will be wrong if the backing Array data is freed 37 | assert_eq!(top_5, &[Some("1"), Some("2"), Some("3"), Some("4"), Some("5")]); 38 | Ok(()) 39 | } 40 | -------------------------------------------------------------------------------- /pgrx-tests/tests/compile-fail/eq-for-postgres_hash.rs: -------------------------------------------------------------------------------- 1 | use pgrx::prelude::*; 2 | use serde::{Serialize, Deserialize}; 3 | 4 | #[derive(Serialize, Deserialize, PostgresType, PostgresHash)] 5 | pub struct BrokenType { 6 | int: i32, 7 | } 8 | 9 | fn main() {} 10 | -------------------------------------------------------------------------------- /pgrx-tests/tests/compile-fail/escaping-spiclient-1209-cursor.rs: -------------------------------------------------------------------------------- 1 | use pgrx::prelude::*; 2 | use std::error::Error; 3 | 4 | #[pg_test] 5 | #[allow(deprecated)] 6 | fn issue1209() -> Result, Box> { 7 | // create the cursor we actually care about 8 | let mut res = Spi::connect(|c| { 9 | c.open_cursor("select 'hello world' from generate_series(1, 1000)", &[]) 10 | .fetch(1000) 11 | .unwrap() 12 | }); 13 | 14 | // here we just perform some allocations to make sure that the previous cursor gets invalidated 15 | for _ in 0..100 { 16 | Spi::connect(|c| c.open_cursor("select 1", &[]).fetch(1).unwrap()); 17 | } 18 | 19 | // later elements are probably more likely to point to deallocated memory 20 | for _ in 0..100 { 21 | res.next(); 22 | } 23 | 24 | // segfault 25 | Ok(res.next().unwrap().get::(1)?) 26 | } 27 | 28 | fn main() {} 29 | -------------------------------------------------------------------------------- /pgrx-tests/tests/compile-fail/escaping-spiclient-1209-prep-stmt.rs: -------------------------------------------------------------------------------- 1 | use pgrx::prelude::*; 2 | use std::error::Error; 3 | 4 | #[pg_extern] 5 | fn issue1209_prepared_stmt(q: &str) -> Result, Box> { 6 | use pgrx::spi::Query; 7 | 8 | let prepared = { Spi::connect(|c| c.prepare(q, &[]))? }; 9 | 10 | Ok(Spi::connect(|c| prepared.execute(&c, Some(1), &[])?.first().get(1))?) 11 | } 12 | 13 | fn main() {} 14 | -------------------------------------------------------------------------------- /pgrx-tests/tests/compile-fail/escaping-spiclient-1209-prep-stmt.stderr: -------------------------------------------------------------------------------- 1 | error: lifetime may not live long enough 2 | --> tests/compile-fail/escaping-spiclient-1209-prep-stmt.rs:8:39 3 | | 4 | 8 | let prepared = { Spi::connect(|c| c.prepare(q, &[]))? }; 5 | | -- ^^^^^^^^^^^^^^^^^ returning this value requires that `'1` must outlive `'2` 6 | | || 7 | | |return type of closure is std::result::Result, pgrx::spi::SpiError> 8 | | has type `&SpiClient<'1>` 9 | -------------------------------------------------------------------------------- /pgrx-tests/tests/compile-fail/heap-tuples-dont-leak.rs: -------------------------------------------------------------------------------- 1 | use ::pgrx::prelude::*; 2 | 3 | fn main() {} 4 | 5 | #[pg_extern] 6 | fn gets_name_field(dog: Option) -> Option<&str> { 7 | // Gets resolved to: 8 | let dog: Option> = dog; 9 | 10 | dog?.get_by_name("name").ok()? 11 | } 12 | 13 | #[pg_extern] 14 | fn gets_name_field_default( 15 | dog: default!(pgrx::composite_type!("Dog"), "ROW('Nami', 0)::Dog"), 16 | ) -> &str { 17 | // Gets resolved to: 18 | let dog: PgHeapTuple = dog; 19 | 20 | dog.get_by_name("name").unwrap().unwrap() 21 | } 22 | 23 | #[pg_extern] 24 | fn gets_name_field_strict(dog: pgrx::composite_type!("Dog")) -> &str { 25 | // Gets resolved to: 26 | let dog: PgHeapTuple = dog; 27 | 28 | dog.get_by_name("name").unwrap().unwrap() 29 | } 30 | -------------------------------------------------------------------------------- /pgrx-tests/tests/compile-fail/heap-tuples-dont-leak.stderr: -------------------------------------------------------------------------------- 1 | error[E0515]: cannot return value referencing temporary value 2 | --> tests/compile-fail/heap-tuples-dont-leak.rs:10:5 3 | | 4 | 10 | dog?.get_by_name("name").ok()? 5 | | ----^^^^^^^^^^^^^^^^^^^^^^^^^^ 6 | | | 7 | | returns a value referencing data owned by the current function 8 | | temporary value created here 9 | 10 | error[E0515]: cannot return value referencing local variable `dog` 11 | --> tests/compile-fail/heap-tuples-dont-leak.rs:20:5 12 | | 13 | 20 | dog.get_by_name("name").unwrap().unwrap() 14 | | ---^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 15 | | | 16 | | returns a value referencing data owned by the current function 17 | | `dog` is borrowed here 18 | 19 | error[E0515]: cannot return value referencing local variable `dog` 20 | --> tests/compile-fail/heap-tuples-dont-leak.rs:28:5 21 | | 22 | 28 | dog.get_by_name("name").unwrap().unwrap() 23 | | ---^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 24 | | | 25 | | returns a value referencing data owned by the current function 26 | | `dog` is borrowed here 27 | -------------------------------------------------------------------------------- /pgrx-tests/tests/compile-fail/invalid_pgcast_options.rs: -------------------------------------------------------------------------------- 1 | use pgrx::prelude::*; 2 | 3 | #[pg_cast(invalid_opt)] 4 | pub fn cast_function(foo: i32) -> i32 { 5 | foo 6 | } 7 | 8 | fn main() {} 9 | -------------------------------------------------------------------------------- /pgrx-tests/tests/compile-fail/invalid_pgcast_options.stderr: -------------------------------------------------------------------------------- 1 | error: Invalid option `invalid_opt` inside `invalid_opt ` 2 | --> tests/compile-fail/invalid_pgcast_options.rs:3:11 3 | | 4 | 3 | #[pg_cast(invalid_opt)] 5 | | ^^^^^^^^^^^ 6 | 7 | error: failed parsing pg_extern arguments 8 | --> tests/compile-fail/invalid_pgcast_options.rs:3:11 9 | | 10 | 3 | #[pg_cast(invalid_opt)] 11 | | ^^^^^^^^^^^ 12 | -------------------------------------------------------------------------------- /pgrx-tests/tests/compile-fail/postgres-strings-arent-immortal.rs: -------------------------------------------------------------------------------- 1 | use pgrx::prelude::*; 2 | 3 | #[pg_extern] 4 | fn split(input: &'static str, pattern: &str) -> Vec<&'static str> { 5 | input.split_terminator(pattern).collect() 6 | } 7 | 8 | fn main() {} 9 | -------------------------------------------------------------------------------- /pgrx-tests/tests/compile-fail/postgres-strings-arent-immortal.stderr: -------------------------------------------------------------------------------- 1 | error[E0521]: borrowed data escapes outside of function 2 | --> tests/compile-fail/postgres-strings-arent-immortal.rs:4:67 3 | | 4 | 3 | #[pg_extern] 5 | | ------------ 6 | | | 7 | | lifetime `'fcx` defined here 8 | | in this procedural macro expansion 9 | 4 | fn split(input: &'static str, pattern: &str) -> Vec<&'static str> { 10 | | ___________________________________________________________________^ 11 | 5 | | input.split_terminator(pattern).collect() 12 | 6 | | } 13 | | | ^ 14 | | | | 15 | | | `fcinfo` is a reference that is only valid in the function body 16 | | |_`fcinfo` escapes the function body here 17 | | argument requires that `'fcx` must outlive `'static` 18 | | 19 | = note: this error originates in the attribute macro `pg_extern` (in Nightly builds, run with -Z macro-backtrace for more info) 20 | -------------------------------------------------------------------------------- /pgrx-tests/tests/compile-fail/spi-prepare-prepared-statement.rs.ignored: -------------------------------------------------------------------------------- 1 | use pgrx::prelude::*; 2 | 3 | fn main() {} 4 | 5 | #[pg_extern] 6 | pub fn cast_function() { 7 | Spi::connect(|client| { 8 | let stmt = client.prepare(c"SELECT 1", None)?; 9 | 10 | client.prepare(stmt, None); 11 | 12 | Ok(()) 13 | }); 14 | } 15 | -------------------------------------------------------------------------------- /pgrx-tests/tests/compile-fail/spi-prepare-prepared-statement.stderr: -------------------------------------------------------------------------------- 1 | error[E0277]: the trait bound `PreparedStatement<'_>: spi::query::PreparableQuery<'_>` is not satisfied 2 | --> tests/compile-fail/spi-prepare-prepared-statement.rs:10:24 3 | | 4 | 10 | client.prepare(stmt, None); 5 | | ------- ^^^^ the trait `spi::query::PreparableQuery<'_>` is not implemented for `PreparedStatement<'_>` 6 | | | 7 | | required by a bound introduced by this call 8 | | 9 | = help: the following other types implement trait `spi::query::PreparableQuery<'conn>`: 10 | &CStr 11 | &CString 12 | &std::string::String 13 | &str 14 | note: required by a bound in `SpiClient::<'conn>::prepare` 15 | --> $WORKSPACE/pgrx/src/spi/client.rs 16 | | 17 | | pub fn prepare>( 18 | | ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `SpiClient::<'conn>::prepare` 19 | -------------------------------------------------------------------------------- /pgrx-tests/tests/compile-fail/table-iterators-arent-immortal.rs: -------------------------------------------------------------------------------- 1 | use pgrx::prelude::*; 2 | 3 | #[pg_extern] 4 | fn returns_tuple_with_lifetime( 5 | value: &'static str, 6 | ) -> TableIterator<(name!(a, &'static str), name!(b, Option<&'static str>))> { 7 | TableIterator::once((value, Some(value))) 8 | } 9 | 10 | fn main() {} 11 | -------------------------------------------------------------------------------- /pgrx-tests/tests/compile-fail/table-iterators-arent-immortal.stderr: -------------------------------------------------------------------------------- 1 | warning: elided lifetime has a name 2 | --> tests/compile-fail/table-iterators-arent-immortal.rs:6:19 3 | | 4 | 6 | ) -> TableIterator<(name!(a, &'static str), name!(b, Option<&'static str>))> { 5 | | ^ this elided lifetime gets resolved as `'static` 6 | | 7 | = note: `#[warn(elided_named_lifetimes)]` on by default 8 | help: consider specifying it explicitly 9 | | 10 | 6 | ) -> TableIterator<'static, (name!(a, &'static str), name!(b, Option<&'static str>))> { 11 | | ++++++++ 12 | 13 | error[E0521]: borrowed data escapes outside of function 14 | --> tests/compile-fail/table-iterators-arent-immortal.rs:6:78 15 | | 16 | 3 | #[pg_extern] 17 | | ------------ 18 | | | 19 | | lifetime `'fcx` defined here 20 | | in this procedural macro expansion 21 | ... 22 | 6 | ) -> TableIterator<(name!(a, &'static str), name!(b, Option<&'static str>))> { 23 | | ______________________________________________________________________________^ 24 | 7 | | TableIterator::once((value, Some(value))) 25 | 8 | | } 26 | | | ^ 27 | | | | 28 | | | `fcinfo` is a reference that is only valid in the function body 29 | | |_`fcinfo` escapes the function body here 30 | | argument requires that `'fcx` must outlive `'static` 31 | | 32 | = note: this error originates in the attribute macro `pg_extern` (in Nightly builds, run with -Z macro-backtrace for more info) 33 | -------------------------------------------------------------------------------- /pgrx-tests/tests/compile-fail/too_many_cast_options.rs: -------------------------------------------------------------------------------- 1 | use pgrx::prelude::*; 2 | 3 | #[pg_cast(implicit, assignment)] 4 | pub fn cast_function(foo: i32) -> i32 { 5 | foo 6 | } 7 | 8 | fn main() {} 9 | -------------------------------------------------------------------------------- /pgrx-tests/tests/compile-fail/too_many_cast_options.stderr: -------------------------------------------------------------------------------- 1 | error: custom attribute panicked 2 | --> tests/compile-fail/too_many_cast_options.rs:3:1 3 | | 4 | 3 | #[pg_cast(implicit, assignment)] 5 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 6 | | 7 | = help: message: The cast type has already been set to `Implicit` 8 | -------------------------------------------------------------------------------- /pgrx-tests/tests/compile-fail/total-eq-for-postgres_eq.rs: -------------------------------------------------------------------------------- 1 | use pgrx::prelude::*; 2 | use serde::{Serialize, Deserialize}; 3 | 4 | #[derive(Serialize, Deserialize, PartialEq, PostgresType, PostgresEq)] 5 | pub struct BrokenType { 6 | int: i32, 7 | } 8 | 9 | fn main() {} 10 | -------------------------------------------------------------------------------- /pgrx-tests/tests/compile-fail/total-ord-for-postgres_ord.rs: -------------------------------------------------------------------------------- 1 | use pgrx::prelude::*; 2 | use serde::{Serialize, Deserialize}; 3 | 4 | #[derive(Serialize, Deserialize, PartialEq, PartialOrd, PostgresType, PostgresOrd)] 5 | pub struct BrokenType { 6 | int: i32, 7 | } 8 | 9 | impl BrokenType { 10 | fn cmp(self, _other: &Self) -> Anything { 11 | Anything::Whatever 12 | } 13 | } 14 | 15 | #[repr(u8)] 16 | enum Anything { 17 | Whatever = 0, 18 | } 19 | 20 | fn main() {} 21 | -------------------------------------------------------------------------------- /pgrx-tests/tests/compile-fail/total-ord-for-postgres_ord.stderr: -------------------------------------------------------------------------------- 1 | error[E0277]: the trait bound `BrokenType: std::cmp::Ord` is not satisfied 2 | --> tests/compile-fail/total-ord-for-postgres_ord.rs:4:71 3 | | 4 | 4 | #[derive(Serialize, Deserialize, PartialEq, PartialOrd, PostgresType, PostgresOrd)] 5 | | ^^^^^^^^^^^ the trait `std::cmp::Ord` is not implemented for `BrokenType` 6 | | 7 | = note: this error originates in the derive macro `PostgresOrd` (in Nightly builds, run with -Z macro-backtrace for more info) 8 | help: consider annotating `BrokenType` with `#[derive(Ord)]` 9 | | 10 | 5 + #[derive(Ord)] 11 | 6 | pub struct BrokenType { 12 | | 13 | -------------------------------------------------------------------------------- /pgrx-tests/tests/compile-fail/variadic-is-dead.rs: -------------------------------------------------------------------------------- 1 | use pgrx::prelude::*; 2 | 3 | fn main() {} 4 | #[pg_extern] 5 | fn whatever() -> variadic!(i32) { 6 | todo!() 7 | } 8 | -------------------------------------------------------------------------------- /pgrx-tests/tests/compile-fail/variadic-is-dead.stderr: -------------------------------------------------------------------------------- 1 | error: type macros other than `composite_type!` are not yet implemented 2 | --> tests/compile-fail/variadic-is-dead.rs:5:18 3 | | 4 | 5 | fn whatever() -> variadic!(i32) { 5 | | ^^^^^^^^ 6 | -------------------------------------------------------------------------------- /pgrx-tests/tests/nightly/compile-fail/allocation-doesnt-outlive-memcx.rs: -------------------------------------------------------------------------------- 1 | #![feature(allocator_api)] 2 | 3 | fn main() {} 4 | 5 | fn allocation_outlive_memcx() { 6 | use pgrx::memcx::MemCx; 7 | use std::sync::Arc; 8 | 9 | let mut vector_used = Arc::new(None); 10 | 11 | pgrx::memcx::current_context(|mcx: &MemCx| { 12 | let mut inner_vec = Vec::new_in(&mcx); 13 | inner_vec.push(451); 14 | inner_vec.push(242); 15 | *Arc::>::get_mut(&mut vector_used).unwrap() = Some(inner_vec); 16 | }); 17 | let _vector = Arc::<_>::get_mut(&mut vector_used).take().unwrap(); 18 | } 19 | -------------------------------------------------------------------------------- /pgrx-tests/tests/nightly/compile-fail/allocation-doesnt-outlive-memcx.stderr: -------------------------------------------------------------------------------- 1 | error[E0521]: borrowed data escapes outside of closure 2 | --> tests/nightly/compile-fail/allocation-doesnt-outlive-memcx.rs:15:9 3 | | 4 | 9 | let mut vector_used = Arc::new(None); 5 | | --------------- `vector_used` declared here, outside of the closure body 6 | 10 | 7 | 11 | pgrx::memcx::current_context(|mcx: &MemCx| { 8 | | --- `mcx` is a reference that is only valid in the closure body 9 | ... 10 | 15 | *Arc::>::get_mut(&mut vector_used).unwrap() = Some(inner_vec); 11 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `mcx` escapes the closure body here 12 | 13 | error[E0521]: borrowed data escapes outside of closure 14 | --> tests/nightly/compile-fail/allocation-doesnt-outlive-memcx.rs:15:9 15 | | 16 | 9 | let mut vector_used = Arc::new(None); 17 | | --------------- `vector_used` declared here, outside of the closure body 18 | ... 19 | 12 | let mut inner_vec = Vec::new_in(&mcx); 20 | | ---- borrow is only valid in the closure body 21 | ... 22 | 15 | *Arc::>::get_mut(&mut vector_used).unwrap() = Some(inner_vec); 23 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference to `mcx` escapes the closure body here 24 | -------------------------------------------------------------------------------- /pgrx-tests/tests/todo/busted-exotic-signature.rs: -------------------------------------------------------------------------------- 1 | use pgrx::prelude::*; 2 | 3 | fn main() {} 4 | 5 | // Just a compile test... 6 | // We don't run these, but we ensure we can build SQL for them 7 | mod sql_generator_tests { 8 | use super::*; 9 | 10 | #[pg_extern] 11 | fn exotic_signature( 12 | _cats: pgrx::default!( 13 | Option>>, 14 | "ARRAY[ROW('Sally', 0)]::Cat[]" 15 | ), 16 | _a_single_fish: pgrx::default!( 17 | Option<::pgrx::composite_type!('static, "Fish")>, 18 | "ROW('Bob', 0)::Fish" 19 | ), 20 | _dogs: pgrx::default!( 21 | Option<::pgrx::VariadicArray<::pgrx::composite_type!('static, "Dog")>>, 22 | "ARRAY[ROW('Nami', 0), ROW('Brandy', 0)]::Dog[]" 23 | ), 24 | ) -> TableIterator< 25 | 'static, 26 | ( 27 | name!(dog, Option<::pgrx::composite_type!('static, "Dog")>), 28 | name!(cat, Option<::pgrx::composite_type!('static, "Cat")>), 29 | name!(fish, Option<::pgrx::composite_type!('static, "Fish")>), 30 | name!( 31 | related_edges, 32 | Option> 33 | ), 34 | ), 35 | > { 36 | TableIterator::new(Vec::new().into_iter()) 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /pgrx-tests/tests/todo/busted-exotic-signature.stderr: -------------------------------------------------------------------------------- 1 | error[E0277]: the trait bound `Vec>>: ArgAbi<'_>` is not satisfied 2 | --> tests/todo/busted-exotic-signature.rs:12:9 3 | | 4 | 10 | #[pg_extern] 5 | | ------------ in this procedural macro expansion 6 | 11 | fn exotic_signature( 7 | 12 | _cats: pgrx::default!( 8 | | ^^^^^ the trait `ArgAbi<'_>` is not implemented for `Vec>>` 9 | | 10 | = help: the following other types implement trait `ArgAbi<'fcx>`: 11 | Vec> 12 | Vec 13 | Vec 14 | = note: required for `Option>>>` to implement `ArgAbi<'_>` 15 | note: required by a bound in `pgrx::callconv::Args::<'a, 'fcx>::next_arg_unchecked` 16 | --> $WORKSPACE/pgrx/src/callconv.rs 17 | | 18 | | pub unsafe fn next_arg_unchecked>(&mut self) -> Option { 19 | | ^^^^^^^^^^^^ required by this bound in `Args::<'a, 'fcx>::next_arg_unchecked` 20 | = note: this error originates in the attribute macro `pg_extern` (in Nightly builds, run with -Z macro-backtrace for more info) 21 | -------------------------------------------------------------------------------- /pgrx-tests/tests/todo/random-vec-strs-arent-okay.rs: -------------------------------------------------------------------------------- 1 | use pgrx::prelude::*; 2 | 3 | fn main() {} 4 | 5 | #[pg_extern] 6 | fn exec<'a>( 7 | command: &'a str, 8 | args: default!(Vec>, "ARRAY[]::text[]"), 9 | ) -> TableIterator<'static, (name!(status, Option), name!(stdout, String))> { 10 | let mut command = &mut std::process::Command::new(command); 11 | 12 | for arg in args { 13 | if let Some(arg) = arg { 14 | command = command.arg(arg); 15 | } 16 | } 17 | 18 | let output = command.output().expect("command failed"); 19 | 20 | if !output.stderr.is_empty() { 21 | panic!("{}", String::from_utf8(output.stderr).expect("stderr is not valid utf8")) 22 | } 23 | 24 | TableIterator::once(( 25 | output.status.code(), 26 | String::from_utf8(output.stdout).expect("stdout is not valid utf8"), 27 | )) 28 | } 29 | -------------------------------------------------------------------------------- /pgrx-tests/tests/todo/random-vec-strs-arent-okay.stderr: -------------------------------------------------------------------------------- 1 | error[E0277]: the trait bound `Vec>: ArgAbi<'_>` is not satisfied 2 | --> tests/todo/random-vec-strs-arent-okay.rs:8:5 3 | | 4 | 5 | #[pg_extern] 5 | | ------------ in this procedural macro expansion 6 | ... 7 | 8 | args: default!(Vec>, "ARRAY[]::text[]"), 8 | | ^^^^ the trait `ArgAbi<'_>` is not implemented for `Vec>` 9 | | 10 | = help: the following other types implement trait `ArgAbi<'fcx>`: 11 | Vec> 12 | Vec 13 | Vec 14 | note: required by a bound in `pgrx::callconv::Args::<'a, 'fcx>::next_arg_unchecked` 15 | --> $WORKSPACE/pgrx/src/callconv.rs 16 | | 17 | | pub unsafe fn next_arg_unchecked>(&mut self) -> Option { 18 | | ^^^^^^^^^^^^ required by this bound in `Args::<'a, 'fcx>::next_arg_unchecked` 19 | = note: this error originates in the attribute macro `pg_extern` (in Nightly builds, run with -Z macro-backtrace for more info) 20 | -------------------------------------------------------------------------------- /pgrx-tests/tests/ui.rs: -------------------------------------------------------------------------------- 1 | #![cfg(not(target_env = "musl"))] 2 | 3 | use trybuild::TestCases; 4 | 5 | /// These are tests which are intended to always fail. 6 | #[cfg(not(feature = "nightly"))] 7 | #[test] 8 | fn compile_fail() { 9 | let t = TestCases::new(); 10 | t.compile_fail("tests/compile-fail/*.rs"); 11 | } 12 | 13 | /// These are tests which currently fail, but should be fixed later. 14 | #[cfg(not(feature = "nightly"))] 15 | #[test] 16 | fn todo() { 17 | let t = TestCases::new(); 18 | t.compile_fail("tests/todo/*.rs"); 19 | } 20 | 21 | /// These are tests which are intended to always fail. 22 | #[cfg(feature = "nightly")] 23 | #[test] 24 | fn compile_fail() { 25 | let t = TestCases::new(); 26 | t.compile_fail("tests/nightly/compile-fail/*.rs"); 27 | } 28 | -------------------------------------------------------------------------------- /pgrx/src/atomics.rs: -------------------------------------------------------------------------------- 1 | //LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 2 | //LICENSE 3 | //LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 4 | //LICENSE 5 | //LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 6 | //LICENSE 7 | //LICENSE All rights reserved. 8 | //LICENSE 9 | //LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 10 | #![deny(unsafe_op_in_unsafe_fn)] 11 | use std::cell::UnsafeCell; 12 | use std::ffi::CStr; 13 | 14 | pub struct PgAtomic { 15 | name: &'static CStr, 16 | inner: UnsafeCell<*mut T>, 17 | } 18 | 19 | impl PgAtomic { 20 | pub const fn new(name: &'static CStr) -> Self { 21 | Self { name, inner: UnsafeCell::new(std::ptr::null_mut()) } 22 | } 23 | 24 | pub fn name(&self) -> &'static CStr { 25 | self.name 26 | } 27 | } 28 | 29 | impl PgAtomic 30 | where 31 | T: atomic_traits::Atomic + Default, 32 | { 33 | /// SAFETY: Must only be called from inside the Postgres shared memory init hook 34 | pub unsafe fn attach(&self, value: *mut T) { 35 | unsafe { 36 | *self.inner.get() = value; 37 | } 38 | } 39 | 40 | pub fn get(&self) -> &T { 41 | unsafe { 42 | let shared = self.inner.get().read().as_ref().expect("PgAtomic was not initialized"); 43 | shared 44 | } 45 | } 46 | } 47 | 48 | unsafe impl Send for PgAtomic where T: atomic_traits::Atomic + Default {} 49 | unsafe impl Sync for PgAtomic where T: atomic_traits::Atomic + Default {} 50 | -------------------------------------------------------------------------------- /pgrx/src/datum/numeric_support/error.rs: -------------------------------------------------------------------------------- 1 | //LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 2 | //LICENSE 3 | //LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 4 | //LICENSE 5 | //LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 6 | //LICENSE 7 | //LICENSE All rights reserved. 8 | //LICENSE 9 | //LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 10 | use thiserror::Error; 11 | 12 | /// Represents some kind of conversion error when working with Postgres numerics 13 | #[derive(Debug, Eq, PartialEq, Error)] 14 | #[non_exhaustive] 15 | pub enum Error { 16 | /// A conversion to Numeric would produce a value outside the precision and scale constraints 17 | /// of the target Numeric 18 | #[error("{0}")] 19 | OutOfRange(String), 20 | 21 | /// A provided value is not also a valid Numeric 22 | #[error("{0}")] 23 | Invalid(String), 24 | 25 | /// Postgres versions less than 14 do not support `Infinity` and `-Infinity` values 26 | #[error("{0}")] 27 | ConversionNotSupported(String), 28 | } 29 | -------------------------------------------------------------------------------- /pgrx/src/datum/numeric_support/hash.rs: -------------------------------------------------------------------------------- 1 | //LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 2 | //LICENSE 3 | //LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 4 | //LICENSE 5 | //LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 6 | //LICENSE 7 | //LICENSE All rights reserved. 8 | //LICENSE 9 | //LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 10 | use std::hash::{Hash, Hasher}; 11 | 12 | use crate::{direct_function_call, pg_sys, AnyNumeric, Numeric}; 13 | 14 | impl Hash for AnyNumeric { 15 | #[inline] 16 | fn hash(&self, state: &mut H) { 17 | unsafe { 18 | let hash = direct_function_call(pg_sys::hash_numeric, &[self.as_datum()]).unwrap(); 19 | state.write_i32(hash) 20 | } 21 | } 22 | } 23 | 24 | impl Hash for Numeric { 25 | #[inline] 26 | fn hash(&self, state: &mut H) { 27 | self.as_anynumeric().hash(state) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /pgrx/src/datum/numeric_support/mod.rs: -------------------------------------------------------------------------------- 1 | //LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 2 | //LICENSE 3 | //LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 4 | //LICENSE 5 | //LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 6 | //LICENSE 7 | //LICENSE All rights reserved. 8 | //LICENSE 9 | //LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 10 | use crate::{direct_function_call_as_datum, pg_sys, AnyNumeric, FromDatum}; 11 | 12 | pub mod cmp; 13 | pub mod convert; 14 | pub(super) mod convert_anynumeric; 15 | pub(super) mod convert_numeric; 16 | pub(super) mod convert_primitive; 17 | pub mod datum; 18 | pub mod error; 19 | pub mod hash; 20 | pub mod ops; 21 | pub mod serde; 22 | pub mod sql; 23 | 24 | #[inline] 25 | pub(super) fn call_numeric_func( 26 | func: unsafe fn(pg_sys::FunctionCallInfo) -> pg_sys::Datum, 27 | args: &[Option], 28 | ) -> AnyNumeric { 29 | unsafe { 30 | // SAFETY: this call to direct_function_call_as_datum will never return None 31 | let numeric_datum = direct_function_call_as_datum(func, args).unwrap_unchecked(); 32 | 33 | // we asked Postgres to create this numeric so it'll need to be freed after we copy it 34 | let anynumeric = AnyNumeric::from_datum(numeric_datum, false); 35 | pg_sys::pfree(numeric_datum.cast_mut_ptr()); 36 | 37 | anynumeric.unwrap() 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /pgrx/src/datum/numeric_support/sql.rs: -------------------------------------------------------------------------------- 1 | //LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 2 | //LICENSE 3 | //LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 4 | //LICENSE 5 | //LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 6 | //LICENSE 7 | //LICENSE All rights reserved. 8 | //LICENSE 9 | //LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 10 | use pgrx_sql_entity_graph::metadata::{ 11 | ArgumentError, Returns, ReturnsError, SqlMapping, SqlTranslatable, 12 | }; 13 | 14 | use crate::{AnyNumeric, Numeric}; 15 | 16 | unsafe impl SqlTranslatable for Numeric { 17 | fn argument_sql() -> Result { 18 | match (P, S) { 19 | (0, 0) => Ok(SqlMapping::literal("NUMERIC")), 20 | (p, 0) => Ok(SqlMapping::As(format!("NUMERIC({p})"))), 21 | (p, s) => Ok(SqlMapping::As(format!("NUMERIC({p}, {s})"))), 22 | } 23 | } 24 | 25 | fn return_sql() -> Result { 26 | match (P, S) { 27 | (0, 0) => Ok(Returns::One(SqlMapping::literal("NUMERIC"))), 28 | (p, 0) => Ok(Returns::One(SqlMapping::As(format!("NUMERIC({p})")))), 29 | (p, s) => Ok(Returns::One(SqlMapping::As(format!("NUMERIC({p}, {s})")))), 30 | } 31 | } 32 | } 33 | 34 | unsafe impl SqlTranslatable for AnyNumeric { 35 | fn argument_sql() -> Result { 36 | Ok(SqlMapping::literal("NUMERIC")) 37 | } 38 | 39 | fn return_sql() -> Result { 40 | Ok(Returns::One(SqlMapping::literal("NUMERIC"))) 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /pgrx/src/ffi.rs: -------------------------------------------------------------------------------- 1 | //LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 2 | //LICENSE 3 | //LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 4 | //LICENSE 5 | //LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 6 | //LICENSE 7 | //LICENSE All rights reserved. 8 | //LICENSE 9 | //LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 10 | //! Reexport FFI definitions here. 11 | pub use alloc::ffi::CString; 12 | pub use libc::c_char; 13 | -------------------------------------------------------------------------------- /pgrx/src/misc.rs: -------------------------------------------------------------------------------- 1 | //LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 2 | //LICENSE 3 | //LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 4 | //LICENSE 5 | //LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 6 | //LICENSE 7 | //LICENSE All rights reserved. 8 | //LICENSE 9 | //LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 10 | use std::hash::{Hash, Hasher}; 11 | 12 | /// wrapper around `SeaHasher` from [Seahash](https://crates.io/crates/seahash) 13 | /// 14 | /// Primarily used by `pgrx`'s `#[derive(PostgresHash)]` macro. 15 | pub fn pgrx_seahash(value: &T) -> u64 { 16 | // taken from sources of "SeaHasher, v4.0.1" [Seahash](https://crates.io/crates/seahash) 17 | // assuming the underlying implementation doesn't change, we 18 | // also want to ensure however we seed it doesn't change either 19 | // 20 | // these hash values might be stored on disk by Postgres, so we can't afford 21 | // to have them changing over time 22 | let mut hasher = seahash::SeaHasher::with_seeds( 23 | 0x16f11fe89b0d677c, 24 | 0xb480a793d8e6c86c, 25 | 0x6fe2e5aaf078ebc9, 26 | 0x14f994a4c5259381, 27 | ); 28 | value.hash(&mut hasher); 29 | hasher.finish() 30 | } 31 | -------------------------------------------------------------------------------- /pgrx/src/nodes.rs: -------------------------------------------------------------------------------- 1 | //LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 2 | //LICENSE 3 | //LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 4 | //LICENSE 5 | //LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 6 | //LICENSE 7 | //LICENSE All rights reserved. 8 | //LICENSE 9 | //LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 10 | //! Helper functions and such for Postgres' various query tree `Node`s 11 | 12 | use crate::pg_sys; 13 | 14 | /// #define IsA(nodeptr,_type_) (nodeTag(nodeptr) == T_##_type_) 15 | #[inline] 16 | pub unsafe fn is_a(nodeptr: *mut pg_sys::Node, tag: pg_sys::NodeTag) -> bool { 17 | !nodeptr.is_null() && nodeptr.as_ref().unwrap().type_ == tag 18 | } 19 | 20 | /// Convert a [pg_sys::Node] into its textual representation 21 | /// 22 | /// ### Safety 23 | /// 24 | /// We cannot guarantee the provided `nodeptr` is a valid pointer 25 | pub unsafe fn node_to_string<'a>(nodeptr: *mut pg_sys::Node) -> Option<&'a str> { 26 | if nodeptr.is_null() { 27 | None 28 | } else { 29 | let string = pg_sys::nodeToString(nodeptr as crate::void_ptr); 30 | if string.is_null() { 31 | None 32 | } else { 33 | Some( 34 | core::ffi::CStr::from_ptr(string) 35 | .to_str() 36 | .expect("unable to convert Node into a &str"), 37 | ) 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /pgrx/src/pg_catalog/mod.rs: -------------------------------------------------------------------------------- 1 | //LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 2 | //LICENSE 3 | //LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 4 | //LICENSE 5 | //LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 6 | //LICENSE 7 | //LICENSE All rights reserved. 8 | //LICENSE 9 | //LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 10 | 11 | pub mod pg_proc; 12 | -------------------------------------------------------------------------------- /pgrx/src/pg_sys.rs: -------------------------------------------------------------------------------- 1 | //! dirty hacks 2 | 3 | // Flatten out the contents into here. 4 | use crate::memcx; 5 | use crate::ptr::PointerExt; 6 | pub use pgrx_pg_sys::*; 7 | 8 | // Interposing here can allow extensions like ZomboDB to skip the cshim, 9 | // i.e. we are deliberately shadowing the upcoming names. 10 | 11 | /** 12 | ```c 13 | #define rt_fetch(rangetable_index, rangetable) \ 14 | ((RangeTblEntry *) list_nth(rangetable, (rangetable_index)-1)) 15 | ``` 16 | */ 17 | #[inline] 18 | pub unsafe fn rt_fetch(index: Index, range_table: *mut List) -> *mut RangeTblEntry { 19 | memcx::current_context(|cx| { 20 | crate::list::List::<*mut core::ffi::c_void>::downcast_ptr_in_memcx(range_table, cx) 21 | .expect("rt_fetch used on non-ptr List") 22 | .get((index - 1) as _) 23 | .expect("rt_fetch used out-of-bounds") 24 | .cast() 25 | }) 26 | } 27 | 28 | /** 29 | ```c 30 | /* 31 | * In places where it's known that simple_rte_array[] must have been prepared 32 | * already, we just index into it to fetch RTEs. In code that might be 33 | * executed before or after entering query_planner(), use this macro. 34 | */ 35 | #define planner_rt_fetch(rti, root) \ 36 | ((root)->simple_rte_array ? (root)->simple_rte_array[rti] : \ 37 | rt_fetch(rti, (root)->parse->rtable)) 38 | ``` 39 | */ 40 | #[inline] 41 | pub unsafe fn planner_rt_fetch(index: Index, root: *mut PlannerInfo) -> *mut RangeTblEntry { 42 | unsafe { 43 | if (*root).simple_rte_array.is_non_null() { 44 | *(*root).simple_rte_array.add(index as _) 45 | } else { 46 | rt_fetch(index, (*(*root).parse).rtable).cast() 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /pgrx/src/ptr.rs: -------------------------------------------------------------------------------- 1 | pub(crate) trait PointerExt { 2 | fn is_non_null(&self) -> bool; 3 | } 4 | 5 | impl PointerExt for *mut T { 6 | fn is_non_null(&self) -> bool { 7 | !self.is_null() 8 | } 9 | } 10 | 11 | impl PointerExt for *const T { 12 | fn is_non_null(&self) -> bool { 13 | !self.is_null() 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /pgrx/src/toast.rs: -------------------------------------------------------------------------------- 1 | //LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 2 | //LICENSE 3 | //LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 4 | //LICENSE 5 | //LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 6 | //LICENSE 7 | //LICENSE All rights reserved. 8 | //LICENSE 9 | //LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 10 | use core::ops::{Deref, DerefMut}; 11 | 12 | pub(crate) enum Toast 13 | where 14 | T: Toasty, 15 | { 16 | Stale(T), 17 | Fresh(T), 18 | } 19 | 20 | pub(crate) trait Toasty: Sized { 21 | /// Why does it always land butter-side down? 22 | unsafe fn drop_toast(&mut self); 23 | } 24 | 25 | impl Drop for Toast { 26 | fn drop(&mut self) { 27 | match self { 28 | Toast::Stale(_) => {} 29 | Toast::Fresh(t) => unsafe { t.drop_toast() }, 30 | } 31 | } 32 | } 33 | 34 | impl Deref for Toast { 35 | type Target = T; 36 | 37 | fn deref(&self) -> &Self::Target { 38 | match self { 39 | Toast::Stale(t) => t, 40 | Toast::Fresh(t) => t, 41 | } 42 | } 43 | } 44 | 45 | impl DerefMut for Toast { 46 | fn deref_mut(&mut self) -> &mut Self::Target { 47 | match self { 48 | Toast::Stale(ref mut t) => t, 49 | Toast::Fresh(ref mut t) => t, 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /pgrx/src/trigger_support/pg_trigger_error.rs: -------------------------------------------------------------------------------- 1 | //LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 2 | //LICENSE 3 | //LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 4 | //LICENSE 5 | //LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 6 | //LICENSE 7 | //LICENSE All rights reserved. 8 | //LICENSE 9 | //LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 10 | #[derive(thiserror::Error, Debug, Clone, Copy)] 11 | pub enum PgTriggerError { 12 | #[error("`PgTrigger`s can only be built from `FunctionCallInfo` instances which `pgrx::pg_sys::called_as_trigger(fcinfo)` returns `true`")] 13 | NotTrigger, 14 | #[error("`PgTrigger`s cannot be built from `NULL` `pgrx::pg_sys::FunctionCallInfo`s")] 15 | NullFunctionCallInfo, 16 | #[error( 17 | "`InvalidPgTriggerWhen` cannot be built from `event & TRIGGER_EVENT_TIMINGMASK` of `{0}" 18 | )] 19 | InvalidPgTriggerWhen(u32), 20 | #[error( 21 | "`InvalidPgTriggerOperation` cannot be built from `event & TRIGGER_EVENT_OPMASK` of `{0}" 22 | )] 23 | InvalidPgTriggerOperation(u32), 24 | #[error("core::str::Utf8Error: {0}")] 25 | CoreUtf8(#[from] core::str::Utf8Error), 26 | #[error("TryFromIntError: {0}")] 27 | TryFromInt(#[from] core::num::TryFromIntError), 28 | #[error("The `pgrx::pg_sys::TriggerData`'s `tg_trigger` field was a NULL pointer")] 29 | NullTrigger, 30 | #[error("The `pgrx::pg_sys::FunctionCallInfo`'s `context` field was a NULL pointer")] 31 | NullTriggerData, 32 | #[error("The `pgrx::pg_sys::TriggerData`'s `tg_relation` field was a NULL pointer")] 33 | NullRelation, 34 | } 35 | -------------------------------------------------------------------------------- /pgrx/src/trigger_support/pg_trigger_level.rs: -------------------------------------------------------------------------------- 1 | use core::fmt::{Display, Formatter}; 2 | use std::fmt; 3 | //LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 4 | //LICENSE 5 | //LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 6 | //LICENSE 7 | //LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 8 | //LICENSE 9 | //LICENSE All rights reserved. 10 | //LICENSE 11 | //LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 12 | use crate::pg_sys; 13 | use crate::trigger_support::TriggerEvent; 14 | 15 | /// The level of a trigger 16 | /// 17 | /// Maps from a `TEXT` of `ROW` or `STATEMENT`. 18 | /// 19 | /// Can be calculated from a `pgrx_pg_sys::TriggerEvent`. 20 | // Postgres constants: https://cs.github.com/postgres/postgres/blob/36d4efe779bfc7190ea1c1cf8deb0d945b726663/src/include/commands/trigger.h?q=TRIGGER_FIRED_BEFORE#L98 21 | // Postgres defines: https://cs.github.com/postgres/postgres/blob/36d4efe779bfc7190ea1c1cf8deb0d945b726663/src/include/commands/trigger.h?q=TRIGGER_FIRED_BEFORE#L122-L126 22 | pub enum PgTriggerLevel { 23 | /// `ROW` 24 | Row, 25 | /// `STATEMENT` 26 | Statement, 27 | } 28 | 29 | impl From for PgTriggerLevel { 30 | fn from(event: TriggerEvent) -> Self { 31 | match event.0 & pg_sys::TRIGGER_EVENT_ROW { 32 | 0 => PgTriggerLevel::Statement, 33 | _ => PgTriggerLevel::Row, 34 | } 35 | } 36 | } 37 | 38 | impl Display for PgTriggerLevel { 39 | fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { 40 | f.write_str(match self { 41 | PgTriggerLevel::Row => "ROW", 42 | PgTriggerLevel::Statement => "STATEMENT", 43 | }) 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /pgrx/src/trigger_support/trigger_tuple.rs: -------------------------------------------------------------------------------- 1 | //LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 2 | //LICENSE 3 | //LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 4 | //LICENSE 5 | //LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 6 | //LICENSE 7 | //LICENSE All rights reserved. 8 | //LICENSE 9 | //LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 10 | /// Indicates which trigger tuple to convert into a [`PgHeapTuple`]. 11 | /// 12 | /// [`PgHeapTuple`]: crate::heap_tuple::PgHeapTuple 13 | #[derive(Debug, Copy, Clone)] 14 | pub enum TriggerTuple { 15 | /// Represents the new database row for INSERT/UPDATE operations in row-level triggers. 16 | New, 17 | 18 | /// Represents the old database row for UPDATE/DELETE operations in row-level triggers. 19 | Old, 20 | } 21 | -------------------------------------------------------------------------------- /pgrx/src/xid.rs: -------------------------------------------------------------------------------- 1 | //LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 2 | //LICENSE 3 | //LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 4 | //LICENSE 5 | //LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 6 | //LICENSE 7 | //LICENSE All rights reserved. 8 | //LICENSE 9 | //LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 10 | use crate::pg_sys; 11 | 12 | #[inline] 13 | pub fn xid_to_64bit(xid: pg_sys::TransactionId) -> u64 { 14 | let full_xid = unsafe { pg_sys::ReadNextFullTransactionId() }; 15 | 16 | let last_xid = full_xid.value as u32; 17 | let epoch = (full_xid.value >> 32) as u32; 18 | 19 | convert_xid_common(xid, last_xid.into(), epoch) 20 | } 21 | 22 | #[inline] 23 | fn convert_xid_common( 24 | xid: pg_sys::TransactionId, 25 | last_xid: pgrx_pg_sys::TransactionId, 26 | epoch: u32, 27 | ) -> u64 { 28 | /* return special xid's as-is */ 29 | if !pg_sys::TransactionIdIsNormal(xid) { 30 | return xid.into_inner() as u64; 31 | } 32 | 33 | /* xid can be on either side when near wrap-around */ 34 | let mut epoch = epoch as u64; 35 | if xid > last_xid && unsafe { pg_sys::TransactionIdPrecedes(xid, last_xid) } { 36 | epoch -= 1; 37 | } else if xid < last_xid && unsafe { pg_sys::TransactionIdFollows(xid, last_xid) } { 38 | epoch += 1; 39 | } 40 | 41 | (epoch << 32) | xid.into_inner() as u64 42 | } 43 | -------------------------------------------------------------------------------- /prepare-release.sh: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env bash 2 | #LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 3 | #LICENSE 4 | #LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 5 | #LICENSE 6 | #LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 7 | #LICENSE 8 | #LICENSE All rights reserved. 9 | #LICENSE 10 | #LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 11 | 12 | 13 | NEW_VERSION=$1 14 | if [ -z "${NEW_VERSION}" ]; then 15 | echo "Usage: ./prepare-release.sh NEW_VERSION_NUMBER [base branch name]" 16 | exit 1 17 | fi 18 | BASE_BRANCH=$2 19 | if [ -z "${BASE_BRANCH}" ]; then 20 | echo "using develop as the base branch" 21 | BASE_BRANCH=develop 22 | fi 23 | 24 | git switch ${BASE_BRANCH} || exit $? 25 | git fetch origin || exit $? 26 | git diff origin/${BASE_BRANCH} | if [ "$0" = "" ]; then 27 | echo "git diff found local changes on ${BASE_BRANCH} branch, cannot cut release." 28 | elif [ "$NEW_VERSION" = "" ]; then 29 | echo "No version set. Are you just copying and pasting this without checking?" 30 | else 31 | git pull origin ${BASE_BRANCH} --ff-only || exit $? 32 | git switch -c "prepare-${NEW_VERSION}" || exit $? 33 | 34 | cargo install --path cargo-pgrx --locked || exit $? 35 | cargo pgrx init || exit $? 36 | 37 | # exit early if the script fails 38 | ./update-versions.sh "${NEW_VERSION}" || exit $? 39 | 40 | # sanity check the diffs, but not Cargo.lock files cuz ugh 41 | # git diff -- . ':(exclude)Cargo.lock' 42 | 43 | # send it all to github 44 | git commit -a -m "Update version to ${NEW_VERSION}" || exit $? 45 | git push --set-upstream origin "prepare-${NEW_VERSION}" || exit $? 46 | fi 47 | 48 | -------------------------------------------------------------------------------- /publish.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | #LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 3 | #LICENSE 4 | #LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 5 | #LICENSE 6 | #LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 7 | #LICENSE 8 | #LICENSE All rights reserved. 9 | #LICENSE 10 | #LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 11 | 12 | 13 | DIR=`pwd` 14 | set -x 15 | 16 | # dependency graph, from roots to facades 17 | # 18 | # pgrx-pg-config 19 | # ├── cargo-pgrx 20 | # ├── pgrx-bindgen 21 | # │ [build-dependencies] 22 | # │ └── pgrx-pg-sys 23 | # │ └── pgrx 24 | # │ └── pgrx-tests 25 | # └── pgrx-tests 26 | # 27 | # pgrx-sql-entity-graph 28 | # ├── cargo-pgrx 29 | # ├── pgrx 30 | # │ └── pgrx-tests 31 | # ├── pgrx-macros 32 | # │ ├── pgrx 33 | # │ ├── pgrx-pg-sys 34 | # │ │ └── pgrx 35 | # │ └── pgrx-tests 36 | # └── pgrx-pg-sys 37 | 38 | 39 | cd $DIR/pgrx-pg-config && cargo publish 40 | cd $DIR/pgrx-bindgen && cargo publish 41 | cd $DIR/pgrx-sql-entity-graph && cargo publish 42 | cd $DIR/pgrx-macros && cargo publish 43 | cd $DIR/pgrx-pg-sys && cargo publish --no-verify 44 | cd $DIR/pgrx && cargo publish --no-verify 45 | cd $DIR/pgrx-tests && cargo publish --no-verify 46 | cd $DIR/cargo-pgrx && cargo publish # cargo-pgrx last so the templates are correct 47 | -------------------------------------------------------------------------------- /run-example.sh: -------------------------------------------------------------------------------- 1 | function exec_example() { 2 | CARGO_TARGET_DIR="$(pwd)/target" cargo test --manifest-path="${1}"/Cargo.toml --features "pg${PG_VER:-14}" --no-default-features 3 | } 4 | if [ $1 = "all" ]; then 5 | for example in pgrx-examples/*; do 6 | if [ -d $example ]; then 7 | exec_example "$example" 8 | fi 9 | done 10 | else 11 | exec_example "pgrx-examples/$1" 12 | fi 13 | -------------------------------------------------------------------------------- /rustfmt.toml: -------------------------------------------------------------------------------- 1 | # Run rustfmt with this config (it should be picked up automatically). 2 | use_small_heuristics = "Max" 3 | merge_derives = false 4 | 5 | # run `cargo +nightly fmt` with these uncommented occasionally until it stabilizes 6 | # unstable_features = true 7 | # imports_granularity = "Module" 8 | -------------------------------------------------------------------------------- /tools/license-check.sh: -------------------------------------------------------------------------------- 1 | cargo deny check licenses 2 | cd pgrx && cargo deny check licenses 3 | -------------------------------------------------------------------------------- /tools/rustup.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | echo "---- setup rustc ----" 4 | if [[ $(type rustup) ]]; then 5 | echo "rustup already installed" 6 | else 7 | curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs --output rustup-init.sh 8 | chmod +x rustup-init.sh 9 | ./rustup-init.sh -y 10 | fi 11 | # we want nightly to be always-available for some tests, even if we don't default to it 12 | rustup update nightly 13 | rustup update "${RUST_TOOLCHAIN:-stable}" 14 | rustup default "${RUST_TOOLCHAIN:-stable}" 15 | # only needed for cross-compile tests but we want consistent rust configuration 16 | rustup target add aarch64-unknown-linux-gnu 17 | 18 | # output full rustc version data 19 | rustc --version --verbose 20 | # this determines what our cargo version is, so don't ask 21 | -------------------------------------------------------------------------------- /tools/version-updater/Cargo.toml: -------------------------------------------------------------------------------- 1 | #LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 2 | #LICENSE 3 | #LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 4 | #LICENSE 5 | #LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 6 | #LICENSE 7 | #LICENSE All rights reserved. 8 | #LICENSE 9 | #LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 10 | 11 | [package] 12 | name = "pgrx-version-updater" 13 | version = "0.1.1" 14 | edition = "2021" 15 | authors = ["PgCentral Foundation, Inc. "] 16 | license = "MIT" 17 | description = "Standalone tool to update PGRX Cargo.toml versions and dependencies in preparation for a release." 18 | publish = false 19 | 20 | [dependencies] 21 | cargo_toml = "0.20.4" 22 | clap = { version = "4.4.2", features = [ "env", "derive" ] } 23 | owo-colors = "4" 24 | rustc-hash = "2" 25 | toml = "0.8.19" 26 | toml_edit = { version = "0.22" } 27 | walkdir = "2" 28 | 29 | [workspace] 30 | -------------------------------------------------------------------------------- /upgrade-deps.sh: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env bash 2 | #LICENSE Portions Copyright 2019-2021 ZomboDB, LLC. 3 | #LICENSE 4 | #LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc. 5 | #LICENSE 6 | #LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. 7 | #LICENSE 8 | #LICENSE All rights reserved. 9 | #LICENSE 10 | #LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file. 11 | 12 | 13 | # requires: "cargo install cargo-edit" from https://github.com/killercup/cargo-edit 14 | EXCLUSIONS="--exclude syn --exclude cargo_metadata --exclude clap --exclude clap-cargo" 15 | cargo update 16 | cargo upgrade --incompatible $EXCLUSIONS 17 | cargo generate-lockfile 18 | 19 | # examples are their own independent crates, so we have to do them individually. 20 | for folder in pgrx-examples/*; do 21 | if [ -d "$folder" ]; then 22 | cd $folder 23 | cargo update 24 | cargo upgrade --incompatible $EXCLUSIONS 25 | cargo generate-lockfile 26 | cargo check || exit $? 27 | cd - 28 | fi 29 | done 30 | --------------------------------------------------------------------------------