diff --git a/Cargo.lock b/Cargo.lock index 53a40128..b28ce756 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -35,15 +35,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "ansi_term" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" -dependencies = [ - "winapi", -] - [[package]] name = "approx" version = "0.4.0" @@ -143,12 +134,6 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8fe8f5a8a398345e52358e18ff07cc17a568fbca5c6f73873d3a62056309603" -[[package]] -name = "base64" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7" - [[package]] name = "base64" version = "0.13.0" @@ -166,9 +151,9 @@ dependencies = [ [[package]] name = "bindgen" -version = "0.59.2" +version = "0.60.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bd2a9a458e8f4304c52c43ebb0cfbd520289f8379a52e329a38afda99bf8eb8" +checksum = "062dddbc1ba4aca46de6338e2bf87771414c335f7b2f2036e8f3e9befebf88e6" dependencies = [ "bitflags", "cexpr", @@ -217,21 +202,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] -name = "block-buffer" -version = "0.10.2" +name = "bitvec" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf7fe51849ea569fd452f37822f606a5cabb684dc918707a0193fd4664ff324" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" dependencies = [ - "generic-array", + "funty", + "radium", + "tap", + "wyz", ] [[package]] -name = "build-deps" -version = "0.1.4" +name = "block-buffer" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64f14468960818ce4f3e3553c32d524446687884f8e7af5d3e252331d8a87e43" +checksum = "0bf7fe51849ea569fd452f37822f606a5cabb684dc918707a0193fd4664ff324" dependencies = [ - "glob", + "generic-array", ] [[package]] @@ -260,7 +248,7 @@ checksum = "9ff11ddd2af3b5e80dd0297fee6e56ac038d9bdc549573cdb51bd6d2efe7f05e" dependencies = [ "num-complex", "num-traits", - "rand 0.8.5", + "rand", "serde", ] @@ -407,7 +395,7 @@ dependencies = [ name = "countminsketch" version = "0.1.0" dependencies = [ - "rand 0.8.5", + "rand", "serde", ] @@ -567,17 +555,6 @@ dependencies = [ "quickcheck_macros", ] -[[package]] -name = "enum-primitive-derive" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c375b9c5eadb68d0a6efee2999fef292f45854c3444c86f09d8ab086ba942b0e" -dependencies = [ - "num-traits", - "quote", - "syn", -] - [[package]] name = "env_logger" version = "0.8.4" @@ -588,16 +565,6 @@ dependencies = [ "regex", ] -[[package]] -name = "env_proxy" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a5019be18538406a43b5419a5501461f0c8b49ea7dfda0cfc32f4e51fc44be1" -dependencies = [ - "log", - "url", -] - [[package]] name = "eyre" version = "0.6.8" @@ -666,28 +633,18 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "form_urlencoded" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191" +checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8" dependencies = [ - "matches", "percent-encoding", ] [[package]] -name = "futures" -version = "0.3.23" +name = "funty" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab30e97ab6aacfe635fad58f22c2bb06c8b685f7421eb1e064a729e2a5f481fa" -dependencies = [ - "futures-channel", - "futures-core", - "futures-executor", - "futures-io", - "futures-sink", - "futures-task", - "futures-util", -] +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" [[package]] name = "futures-channel" @@ -705,23 +662,6 @@ version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2acedae88d38235936c3922476b10fced7b2b68136f5e3c03c2d5be348a1115" -[[package]] -name = "futures-executor" -version = "0.3.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d11aa21b5b587a64682c0094c2bdd4df0076c5324961a40cc3abd7f37930528" -dependencies = [ - "futures-core", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-io" -version = "0.3.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93a66fc6d035a26a3ae255a6d2bca35eda63ae4c5512bef54449113f7a1228e5" - [[package]] name = "futures-macro" version = "0.3.23" @@ -751,13 +691,10 @@ version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0828a5471e340229c11c77ca80017937ce3c58cb788a17e5f1c2d5c485a9577" dependencies = [ - "futures-channel", "futures-core", - "futures-io", "futures-macro", "futures-sink", "futures-task", - "memchr", "pin-project-lite", "pin-utils", "slab", @@ -782,17 +719,6 @@ dependencies = [ "unicode-width", ] -[[package]] -name = "getrandom" -version = "0.1.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" -dependencies = [ - "cfg-if", - "libc", - "wasi 0.9.0+wasi-snapshot-preview1", -] - [[package]] name = "getrandom" version = "0.2.7" @@ -801,7 +727,7 @@ checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6" dependencies = [ "cfg-if", "libc", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi", ] [[package]] @@ -868,12 +794,6 @@ dependencies = [ "digest", ] -[[package]] -name = "httpdate" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "494b4d60369511e7dea41cf646832512a94e542f68bb9c49e54518e0f468eb47" - [[package]] name = "hyperloglogplusplus" version = "0.1.0" @@ -887,11 +807,10 @@ dependencies = [ [[package]] name = "idna" -version = "0.2.3" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" +checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6" dependencies = [ - "matches", "unicode-bidi", "unicode-normalization", ] @@ -941,9 +860,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.131" +version = "0.2.134" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04c3b4822ccebfa39c02fc03d1534441b22ead323fa0f48bb7ddd8e6ba076a40" +checksum = "329c933548736bc49fd575ee68c89e8be4d260064184389a5b77517cddd99ffb" [[package]] name = "libloading" @@ -1004,12 +923,6 @@ dependencies = [ "regex-automata", ] -[[package]] -name = "matches" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" - [[package]] name = "matrixmultiply" version = "0.3.2" @@ -1043,22 +956,6 @@ dependencies = [ "autocfg", ] -[[package]] -name = "mime" -version = "0.3.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" - -[[package]] -name = "mime_guess" -version = "2.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef" -dependencies = [ - "mime", - "unicase", -] - [[package]] name = "minimal-lexical" version = "0.2.1" @@ -1082,7 +979,7 @@ checksum = "57ee1c23c7c63b0c9250c339ffdc69255f110b298b901b9f6c82547b7b87caaf" dependencies = [ "libc", "log", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi", "windows-sys", ] @@ -1098,7 +995,7 @@ dependencies = [ "num-complex", "num-rational", "num-traits", - "rand 0.8.5", + "rand", "rand_distr", "simba", "typenum", @@ -1140,6 +1037,16 @@ dependencies = [ "minimal-lexical", ] +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + [[package]] name = "num-complex" version = "0.4.2" @@ -1147,7 +1054,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ae39348c8bc5fbd7f40c727a9925f03517afd2ab27d46702108b6a7e5414c19" dependencies = [ "num-traits", - "rand 0.8.5", + "rand", "serde", ] @@ -1212,9 +1119,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.13.0" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18a6dbe30758c9f83eb00cbea4ac95966305f5a7772f3f42ebfc7fc7eddbd8e1" +checksum = "e82dad04139b71a90c080c8463fe0dc7902db5192d939bd0950f074d014339e1" [[package]] name = "ordered-float" @@ -1232,11 +1139,17 @@ version = "6.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ff7415e9ae3fff1225851df9e0d9e4e5479f947619774677a63572e55e80eff" +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + [[package]] name = "owo-colors" -version = "3.4.0" +version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "decf7381921fea4dcb2549c5667eda59b3ec297ab7e2b5fc33eac69d2e7da87b" +checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f" [[package]] name = "parking_lot" @@ -1275,9 +1188,9 @@ checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" [[package]] name = "percent-encoding" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" +checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" [[package]] name = "pest" @@ -1335,26 +1248,28 @@ dependencies = [ [[package]] name = "pgx" -version = "0.4.5" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00f3f571b70d230cba9ec46c530000469710ef2c1ea3eadf56d7bc8a62b3510c" +checksum = "7bfbe2a1b1b2c77fc04a8b72149590f193dc34e12b586e3efa737b899ea5b91d" dependencies = [ "atomic-traits", "bitflags", + "bitvec", "cstr_core", - "enum-primitive-derive", "eyre", "heapless", - "num-traits", + "libc", "once_cell", "pgx-macros", "pgx-pg-sys", "pgx-utils", "quote", "seahash", + "seq-macro", "serde", "serde_cbor", "serde_json", + "thiserror", "time", "tracing", "tracing-error", @@ -1363,9 +1278,9 @@ dependencies = [ [[package]] name = "pgx-macros" -version = "0.4.5" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b854e9b42fa8940b5fa393915df75db559384f14663c8966eb5161b554ff5842" +checksum = "68a3d26c61adb81663ffb5391126783dcb3f6512d55189915793a066d7219634" dependencies = [ "pgx-utils", "proc-macro2", @@ -1374,33 +1289,51 @@ dependencies = [ "unescape", ] +[[package]] +name = "pgx-pg-config" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "850a9f2e7a8b24c2c5a2d5b73b97b274a2d7cb8663f4b37d304ad12e8730286e" +dependencies = [ + "dirs", + "eyre", + "owo-colors", + "serde", + "serde_derive", + "serde_json", + "toml", + "tracing", + "url", +] + [[package]] name = "pgx-pg-sys" -version = "0.4.5" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57be652efd8d69525ba4ec04743b2aa2feb024ef7c5d39d35f9bf5638bf64d48" +checksum = "bbc0dc317c60943633f1b84d757bc8ecce578506682bae065d66815b732bfa24" dependencies = [ "bindgen", - "build-deps", "color-eyre", "eyre", "memoffset", - "num_cpus", "once_cell", - "owo-colors", "pgx-macros", + "pgx-pg-config", "pgx-utils", "proc-macro2", "quote", "rayon", + "rustversion", + "shlex", + "sptr", "syn", ] [[package]] name = "pgx-tests" -version = "0.4.5" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9012d509f69898cc15762c3feb78b6a61b3a66a533084351f6afe89c78b8e47" +checksum = "4d57c8354ed351e0bf62384cebd4e4ee1fd58513b8d419ca4d8dd0e140ca84ce" dependencies = [ "eyre", "libc", @@ -1408,61 +1341,58 @@ dependencies = [ "owo-colors", "pgx", "pgx-macros", + "pgx-pg-config", "pgx-utils", "postgres", "regex", "serde", "serde_json", "shutdown_hooks", + "thiserror", "time", ] [[package]] name = "pgx-utils" -version = "0.4.5" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce5d334b177a9cd741521d01ebea505417adddaef4d368753b34ac4a43052674" +checksum = "d1dfb18f7a5efd503087c909ca04baa316d730e2632eb32b625d831d34ad902a" dependencies = [ "atty", "convert_case", - "dirs", - "env_proxy", + "cstr_core", "eyre", "owo-colors", "petgraph", - "prettyplease", "proc-macro2", "quote", "regex", - "rttp_client", + "seq-macro", "serde", - "serde-xml-rs", "serde_derive", "serde_json", "syn", "syntect", - "toml", "tracing", "tracing-error", "tracing-subscriber", "unescape", - "url", ] [[package]] name = "phf" -version = "0.10.1" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fabbf1ead8a5bcbc20f5f8b939ee3f5b0f6f281b6ad3468b84656b658b455259" +checksum = "928c6535de93548188ef63bb7c4036bd415cd8f36ad25af44b9789b2ee72a48c" dependencies = [ "phf_shared", ] [[package]] name = "phf_shared" -version = "0.10.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096" +checksum = "e1fb5f6f826b772a8d4c0394209441e7d37cbbb967ae9c7e0e8134365c9ee676" dependencies = [ "siphasher", ] @@ -1485,7 +1415,7 @@ version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd39bc6cdc9355ad1dc5eeedefee696bb35c34caf21768741e81826c0bbd7225" dependencies = [ - "base64 0.13.0", + "base64", "indexmap", "line-wrap", "serde", @@ -1503,13 +1433,13 @@ dependencies = [ [[package]] name = "postgres" -version = "0.19.3" +version = "0.19.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8bbcd5f6deb39585a0d9f4ef34c4a41c25b7ad26d23c75d837d78c8e7adc85f" +checksum = "960c214283ef8f0027974c03e9014517ced5db12f021a9abb66185a5751fab0a" dependencies = [ "bytes", "fallible-iterator", - "futures", + "futures-util", "log", "tokio", "tokio-postgres", @@ -1521,23 +1451,23 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "878c6cbf956e03af9aa8204b407b9cbf47c072164800aa918c516cd4b056c50c" dependencies = [ - "base64 0.13.0", + "base64", "byteorder", "bytes", "fallible-iterator", "hmac", "md-5", "memchr", - "rand 0.8.5", + "rand", "sha2", "stringprep", ] [[package]] name = "postgres-types" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebd6e8b7189a73169290e89bd24c771071f1012d8fe6f738f5226531f0b03d89" +checksum = "73d946ec7d256b04dfadc4e6a3292324e6f417124750fc5c0950f981b703a0f1" dependencies = [ "bytes", "fallible-iterator", @@ -1554,21 +1484,11 @@ version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" -[[package]] -name = "prettyplease" -version = "0.1.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "697ae720ee02011f439e0701db107ffe2916d83f718342d65d7f8bf7b8a5fee9" -dependencies = [ - "proc-macro2", - "syn", -] - [[package]] name = "proc-macro2" -version = "1.0.43" +version = "1.0.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a2ca2c61bc9f3d74d2886294ab7b9853abd9c1ad903a3ac7815c58989bb7bab" +checksum = "94e2ef8dbfc347b10c094890f778ee2e36ca9bb4262e86dc99cd217e35f3470b" dependencies = [ "unicode-ident", ] @@ -1593,7 +1513,7 @@ checksum = "588f6378e4dd99458b60ec275b4477add41ce4fa9f64dcba6f15adccb19b50d6" dependencies = [ "env_logger", "log", - "rand 0.8.5", + "rand", ] [[package]] @@ -1617,17 +1537,10 @@ dependencies = [ ] [[package]] -name = "rand" -version = "0.7.3" +name = "radium" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" -dependencies = [ - "getrandom 0.1.16", - "libc", - "rand_chacha 0.2.2", - "rand_core 0.5.1", - "rand_hc", -] +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" [[package]] name = "rand" @@ -1636,18 +1549,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", - "rand_chacha 0.3.1", - "rand_core 0.6.3", -] - -[[package]] -name = "rand_chacha" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" -dependencies = [ - "ppv-lite86", - "rand_core 0.5.1", + "rand_chacha", + "rand_core", ] [[package]] @@ -1657,16 +1560,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core 0.6.3", -] - -[[package]] -name = "rand_core" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" -dependencies = [ - "getrandom 0.1.16", + "rand_core", ] [[package]] @@ -1675,7 +1569,7 @@ version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" dependencies = [ - "getrandom 0.2.7", + "getrandom", ] [[package]] @@ -1685,16 +1579,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32cb0b9bc82b0a0876c2dd994a7e7a2683d3e7390ca40e6886785ef0c7e3ee31" dependencies = [ "num-traits", - "rand 0.8.5", -] - -[[package]] -name = "rand_hc" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" -dependencies = [ - "rand_core 0.5.1", + "rand", ] [[package]] @@ -1742,7 +1627,7 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" dependencies = [ - "getrandom 0.2.7", + "getrandom", "redox_syscall", "thiserror", ] @@ -1800,28 +1685,11 @@ version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "86018df177b1beef6c7c8ef949969c4f7cb9a9344181b92486b23c79995bdaa4" dependencies = [ - "base64 0.13.0", + "base64", "bitflags", "serde", ] -[[package]] -name = "rttp_client" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1396558eebd03e50e6526071e0bdcec24e3d67f4fec14bcc8139f24ae941db72" -dependencies = [ - "base64 0.11.0", - "flate2", - "httpdate", - "mime", - "mime_guess", - "percent-encoding", - "rand 0.7.3", - "socks", - "url", -] - [[package]] name = "rustc-demangle" version = "0.1.21" @@ -1861,6 +1729,12 @@ dependencies = [ "semver 1.0.13", ] +[[package]] +name = "rustversion" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97477e48b4cf8603ad5f7aaf897467cf42ab4218a38ef76fb14c2d6773a6d6a8" + [[package]] name = "ryu" version = "1.0.11" @@ -1934,24 +1808,18 @@ dependencies = [ ] [[package]] -name = "serde" -version = "1.0.143" +name = "seq-macro" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53e8e5d5b70924f74ff5c6d64d9a5acd91422117c60f48c4e07855238a254553" -dependencies = [ - "serde_derive", -] +checksum = "0772c5c30e1a0d91f6834f8e545c69281c099dfa9a3ac58d96a9fd629c8d4898" [[package]] -name = "serde-xml-rs" -version = "0.5.1" +name = "serde" +version = "1.0.145" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65162e9059be2f6a3421ebbb4fef3e74b7d9e7c60c50a0e292c6239f19f1edfa" +checksum = "728eb6351430bccb993660dfffc5a72f91ccc1295abaa8ce19b27ebe4f75568b" dependencies = [ - "log", - "serde", - "thiserror", - "xml-rs", + "serde_derive", ] [[package]] @@ -1966,9 +1834,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.143" +version = "1.0.145" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3d8e8de557aee63c26b85b947f5e59b690d0454c753f3adeb5cd7835ab88391" +checksum = "81fa1584d3d1bcacd84c277a0dfe21f5b0f6accf4a23d04d4c6d61f1af522b4c" dependencies = [ "proc-macro2", "quote", @@ -1977,9 +1845,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.83" +version = "1.0.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38dd04e3c8279e75b31ef29dbdceebfe5ad89f4d0937213c53f7d49d01b3d5a7" +checksum = "e55a28e3aaef9d5ce0506d0a14dbba8054ddc7e499ef522dd8b26859ec9d4a44" dependencies = [ "itoa", "ryu", @@ -2072,17 +1940,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "socks" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0c3dbbd9ae980613c6dd8e28a9407b50509d3803b57624d5dfe8315218cd58b" -dependencies = [ - "byteorder", - "libc", - "winapi", -] - [[package]] name = "spfunc" version = "0.1.0" @@ -2103,6 +1960,12 @@ dependencies = [ "lock_api", ] +[[package]] +name = "sptr" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b9b39299b249ad65f3b7e96443bad61c02ca5cd3589f46cb6d610a0fd6c0d6a" + [[package]] name = "sql-doctester" version = "0.1.0" @@ -2133,7 +1996,7 @@ dependencies = [ "lazy_static", "nalgebra", "num-traits", - "rand 0.8.5", + "rand", ] [[package]] @@ -2170,9 +2033,9 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" [[package]] name = "syn" -version = "1.0.99" +version = "1.0.102" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58dbef6ec655055e20b86b15a8cc6d439cca19b667537ac6a1369572d151ab13" +checksum = "3fcd952facd492f9be3ef0d0b7032a6e442ee9b361d4acc2b1d0c4aaa5f613a1" dependencies = [ "proc-macro2", "quote", @@ -2202,6 +2065,12 @@ dependencies = [ "yaml-rust", ] +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + [[package]] name = "tdigest" version = "0.2.2" @@ -2283,9 +2152,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.13" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db76ff9fa4b1458b3c7f077f3ff9887394058460d21e634355b273aaf11eea45" +checksum = "d634a985c4d4238ec39cacaed2e7ae552fbd3c476b552c1deac3021b7d7eaf0c" dependencies = [ "itoa", "libc", @@ -2330,8 +2199,8 @@ dependencies = [ "pgx", "pgx-macros", "pgx-tests", - "rand 0.8.5", - "rand_chacha 0.3.1", + "rand", + "rand_chacha", "rand_distr", "ron", "serde", @@ -2378,15 +2247,16 @@ dependencies = [ [[package]] name = "tokio-postgres" -version = "0.7.6" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19c88a47a23c5d2dc9ecd28fb38fba5fc7e5ddc1fe64488ec145076b0c71c8ae" +checksum = "29a12c1b3e0704ae7dfc25562629798b29c72e6b1d0a681b6f29ab4ae5e7f7bf" dependencies = [ "async-trait", "byteorder", "bytes", "fallible-iterator", - "futures", + "futures-channel", + "futures-util", "log", "parking_lot", "percent-encoding", @@ -2435,9 +2305,9 @@ dependencies = [ [[package]] name = "tracing" -version = "0.1.36" +version = "0.1.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fce9567bd60a67d08a16488756721ba392f24f29006402881e43b19aac64307" +checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" dependencies = [ "cfg-if", "pin-project-lite", @@ -2447,9 +2317,9 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.22" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11c75893af559bc8e10716548bdef5cb2b983f8e637db9d0e15126b61b484ee2" +checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a" dependencies = [ "proc-macro2", "quote", @@ -2458,9 +2328,9 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.29" +version = "0.1.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aeea4303076558a00714b823f9ad67d58a3bbda1df83d8827d21193156e22f7" +checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" dependencies = [ "once_cell", "valuable", @@ -2489,12 +2359,12 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.15" +version = "0.3.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60db860322da191b40952ad9affe65ea23e7dd6a5c442c2c42865810c6ab8e6b" +checksum = "a6176eae26dd70d0c919749377897b54a9276bd7061339665dd68777926b5a70" dependencies = [ - "ansi_term", "matchers", + "nu-ansi-term", "once_cell", "regex", "sharded-slab", @@ -2533,7 +2403,7 @@ dependencies = [ "ordered-float", "quickcheck", "quickcheck_macros", - "rand 0.8.5", + "rand", "serde", ] @@ -2598,13 +2468,12 @@ dependencies = [ [[package]] name = "url" -version = "2.2.2" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c" +checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643" dependencies = [ "form_urlencoded", "idna", - "matches", "percent-encoding", ] @@ -2614,7 +2483,7 @@ version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" dependencies = [ - "getrandom 0.2.7", + "getrandom", ] [[package]] @@ -2623,7 +2492,7 @@ version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd6469f4314d5f1ffec476e05f17cc9a78bc7a27a6a857842170bdf8d6f98d2f" dependencies = [ - "getrandom 0.2.7", + "getrandom", ] [[package]] @@ -2670,12 +2539,6 @@ dependencies = [ "winapi-util", ] -[[package]] -name = "wasi" -version = "0.9.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" - [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -2756,6 +2619,15 @@ version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" +[[package]] +name = "wyz" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30b31594f29d27036c383b53b59ed3476874d518f0efb151b27a4c275141390e" +dependencies = [ + "tap", +] + [[package]] name = "xml-rs" version = "0.8.4" diff --git a/Readme.md b/Readme.md index 9ed5e907..5364ab5f 100644 --- a/Readme.md +++ b/Readme.md @@ -51,7 +51,7 @@ sudo apt-get install make gcc pkg-config clang postgresql-server-dev-14 libssl-d Next you need [cargo-pgx](https://github.com/tcdi/pgx), which can be installed with ```bash -cargo install --version '=0.4.5' --force cargo-pgx +cargo install --version '=0.5.0' --force cargo-pgx ``` You must reinstall cargo-pgx whenver you update your Rust compiler, since cargo-pgx needs to be built with the same compiler as Toolkit. diff --git a/extension/Cargo.toml b/extension/Cargo.toml index ebcd6d4a..1020a6af 100644 --- a/extension/Cargo.toml +++ b/extension/Cargo.toml @@ -19,8 +19,8 @@ pg_test = ["approx"] [dependencies] # Keep synchronized with `cargo install --version N.N.N cargo-pgx` in Readme.md and docker/ci/Dockerfile # Also `pgx-tests` down below in `dev-dependencies`. -pgx = "=0.4.5" -pgx-macros = "=0.4.5" +pgx = "=0.5.0" +pgx-macros = "=0.5.0" encodings = {path="../crates/encodings"} flat_serialize = {path="../crates/flat_serialize/flat_serialize"} flat_serialize_macro = {path="../crates/flat_serialize/flat_serialize_macro"} @@ -53,5 +53,5 @@ spfunc = "0.1.0" statrs = "0.15.0" [dev-dependencies] -pgx-tests = "=0.4.5" +pgx-tests = "=0.5.0" approx = "0.4.0" diff --git a/extension/src/accessors.rs b/extension/src/accessors.rs index d311df73..7f85673d 100644 --- a/extension/src/accessors.rs +++ b/extension/src/accessors.rs @@ -461,7 +461,7 @@ ron_inout_funcs!(AccessorWithBounds); #[pg_extern(immutable, parallel_safe, name = "with_bounds")] pub fn accessor_with_bounds(bounds: crate::raw::tstzrange) -> AccessorWithBounds<'static> { - let range = unsafe { crate::range::get_range(bounds.0 as *mut pg_sys::varlena) }; + let range = unsafe { crate::range::get_range(bounds.0.cast_mut_ptr()) }; let mut accessor = build! { AccessorWithBounds { lower: 0, diff --git a/extension/src/counter_agg.rs b/extension/src/counter_agg.rs index 57a68ce6..86d8684b 100644 --- a/extension/src/counter_agg.rs +++ b/extension/src/counter_agg.rs @@ -264,7 +264,7 @@ pub fn counter_agg_trans_inner( None => { let mut s = CounterSummaryTransState::new(); if let Some(r) = bounds { - s.bounds = get_range(r.0 as *mut pg_sys::varlena); + s.bounds = get_range(r.0.cast_mut_ptr()); } s.push_point(p); Some(s.into()) @@ -289,9 +289,9 @@ pub fn counter_agg_trans_no_bounds( } #[pg_extern(immutable, parallel_safe)] -pub fn counter_agg_summary_trans( +pub fn counter_agg_summary_trans<'a>( state: Internal, - value: Option, + value: Option>, fcinfo: pg_sys::FunctionCallInfo, ) -> Option { counter_agg_summary_trans_inner(unsafe { state.to_inner() }, value, fcinfo).internal() @@ -465,95 +465,107 @@ extension_sql!( #[pg_operator(immutable, parallel_safe)] #[opname(->)] -pub fn arrow_counter_agg_delta(sketch: CounterSummary, _accessor: AccessorDelta) -> f64 { +pub fn arrow_counter_agg_delta<'a>( + sketch: CounterSummary<'a>, + _accessor: AccessorDelta<'a>, +) -> f64 { counter_agg_delta(sketch) } #[pg_extern(name = "delta", strict, immutable, parallel_safe)] -fn counter_agg_delta(summary: CounterSummary) -> f64 { +fn counter_agg_delta<'a>(summary: CounterSummary<'a>) -> f64 { summary.to_internal_counter_summary().delta() } #[pg_operator(immutable, parallel_safe)] #[opname(->)] -pub fn arrow_counter_agg_rate(sketch: CounterSummary, _accessor: AccessorRate) -> Option { +pub fn arrow_counter_agg_rate<'a>( + sketch: CounterSummary<'a>, + _accessor: AccessorRate<'a>, +) -> Option { counter_agg_rate(sketch) } #[pg_extern(name = "rate", strict, immutable, parallel_safe)] -fn counter_agg_rate(summary: CounterSummary) -> Option { +fn counter_agg_rate<'a>(summary: CounterSummary<'a>) -> Option { summary.to_internal_counter_summary().rate() } #[pg_operator(immutable, parallel_safe)] #[opname(->)] -pub fn arrow_counter_agg_time_delta(sketch: CounterSummary, _accessor: AccessorTimeDelta) -> f64 { +pub fn arrow_counter_agg_time_delta<'a>( + sketch: CounterSummary<'a>, + _accessor: AccessorTimeDelta<'a>, +) -> f64 { counter_agg_time_delta(sketch) } #[pg_extern(name = "time_delta", strict, immutable, parallel_safe)] -fn counter_agg_time_delta(summary: CounterSummary) -> f64 { +fn counter_agg_time_delta<'a>(summary: CounterSummary<'a>) -> f64 { summary.to_internal_counter_summary().time_delta() } #[pg_operator(immutable, parallel_safe)] #[opname(->)] -pub fn arrow_counter_agg_irate_left( - sketch: CounterSummary, - _accessor: AccessorIrateLeft, +pub fn arrow_counter_agg_irate_left<'a>( + sketch: CounterSummary<'a>, + _accessor: AccessorIrateLeft<'a>, ) -> Option { counter_agg_irate_left(sketch) } #[pg_extern(name = "irate_left", strict, immutable, parallel_safe)] -fn counter_agg_irate_left(summary: CounterSummary) -> Option { +fn counter_agg_irate_left<'a>(summary: CounterSummary<'a>) -> Option { summary.to_internal_counter_summary().irate_left() } #[pg_operator(immutable, parallel_safe)] #[opname(->)] -pub fn arrow_counter_agg_irate_right( - sketch: CounterSummary, - _accessor: AccessorIrateRight, +pub fn arrow_counter_agg_irate_right<'a>( + sketch: CounterSummary<'a>, + _accessor: AccessorIrateRight<'a>, ) -> Option { counter_agg_irate_right(sketch) } #[pg_extern(name = "irate_right", strict, immutable, parallel_safe)] -fn counter_agg_irate_right(summary: CounterSummary) -> Option { +fn counter_agg_irate_right<'a>(summary: CounterSummary<'a>) -> Option { summary.to_internal_counter_summary().irate_right() } #[pg_operator(immutable, parallel_safe)] #[opname(->)] -pub fn arrow_counter_agg_idelta_left(sketch: CounterSummary, _accessor: AccessorIdeltaLeft) -> f64 { +pub fn arrow_counter_agg_idelta_left<'a>( + sketch: CounterSummary<'a>, + _accessor: AccessorIdeltaLeft<'a>, +) -> f64 { counter_agg_idelta_left(sketch) } #[pg_extern(name = "idelta_left", strict, immutable, parallel_safe)] -fn counter_agg_idelta_left(summary: CounterSummary) -> f64 { +fn counter_agg_idelta_left<'a>(summary: CounterSummary<'a>) -> f64 { summary.to_internal_counter_summary().idelta_left() } #[pg_operator(immutable, parallel_safe)] #[opname(->)] -pub fn arrow_counter_agg_idelta_right( - sketch: CounterSummary, - _accessor: AccessorIdeltaRight, +pub fn arrow_counter_agg_idelta_right<'a>( + sketch: CounterSummary<'a>, + _accessor: AccessorIdeltaRight<'a>, ) -> f64 { counter_agg_idelta_right(sketch) } #[pg_extern(name = "idelta_right", strict, immutable, parallel_safe)] -fn counter_agg_idelta_right(summary: CounterSummary) -> f64 { +fn counter_agg_idelta_right<'a>(summary: CounterSummary<'a>) -> f64 { summary.to_internal_counter_summary().idelta_right() } #[pg_operator(immutable, parallel_safe)] #[opname(->)] -pub fn arrow_counter_agg_with_bounds( - sketch: CounterSummary, - accessor: AccessorWithBounds, +pub fn arrow_counter_agg_with_bounds<'a>( + sketch: CounterSummary<'a>, + accessor: AccessorWithBounds<'a>, ) -> CounterSummary<'static> { let mut builder = CounterSummaryBuilder::from(sketch.to_internal_counter_summary()); builder.set_bounds(accessor.bounds()); @@ -561,10 +573,13 @@ pub fn arrow_counter_agg_with_bounds( } #[pg_extern(name = "with_bounds", strict, immutable, parallel_safe)] -fn counter_agg_with_bounds(summary: CounterSummary, bounds: tstzrange) -> CounterSummary { +fn counter_agg_with_bounds<'a>( + summary: CounterSummary<'a>, + bounds: tstzrange, +) -> CounterSummary<'static> { // TODO dedup with previous by using apply_bounds unsafe { - let ptr = bounds.0 as *mut pg_sys::varlena; + let ptr = bounds.0.cast_mut_ptr(); let mut builder = CounterSummaryBuilder::from(summary.to_internal_counter_summary()); builder.set_bounds(get_range(ptr)); CounterSummary::from_internal_counter_summary(builder.build()) @@ -584,16 +599,16 @@ fn counter_agg_with_bounds(summary: CounterSummary, bounds: tstzrange) -> Counte #[pg_operator(immutable, parallel_safe)] #[opname(->)] -pub fn arrow_counter_agg_extrapolated_delta( - sketch: CounterSummary, - accessor: AccessorExtrapolatedDelta, +pub fn arrow_counter_agg_extrapolated_delta<'a>( + sketch: CounterSummary<'a>, + accessor: AccessorExtrapolatedDelta<'a>, ) -> Option { let method = String::from_utf8_lossy(accessor.bytes.as_slice()); counter_agg_extrapolated_delta(sketch, &*method) } #[pg_extern(name = "extrapolated_delta", strict, immutable, parallel_safe)] -fn counter_agg_extrapolated_delta(summary: CounterSummary, method: &str) -> Option { +fn counter_agg_extrapolated_delta<'a>(summary: CounterSummary<'a>, method: &str) -> Option { match method_kind(method) { Prometheus => summary .to_internal_counter_summary() @@ -608,12 +623,12 @@ fn counter_agg_extrapolated_delta(summary: CounterSummary, method: &str) -> Opti parallel_safe, schema = "toolkit_experimental" )] -fn counter_agg_interpolated_delta( - summary: CounterSummary, +fn counter_agg_interpolated_delta<'a>( + summary: CounterSummary<'a>, start: crate::raw::TimestampTz, interval: crate::raw::Interval, - prev: Option, - next: Option, + prev: Option>, + next: Option>, ) -> f64 { let interval = crate::datum_utils::interval_to_ms(&start, &interval); summary @@ -624,16 +639,16 @@ fn counter_agg_interpolated_delta( #[pg_operator(immutable, parallel_safe)] #[opname(->)] -pub fn arrow_counter_agg_extrapolated_rate( - sketch: CounterSummary, - accessor: AccessorExtrapolatedRate, +pub fn arrow_counter_agg_extrapolated_rate<'a>( + sketch: CounterSummary<'a>, + accessor: AccessorExtrapolatedRate<'a>, ) -> Option { let method = String::from_utf8_lossy(accessor.bytes.as_slice()); counter_agg_extrapolated_rate(sketch, &*method) } #[pg_extern(name = "extrapolated_rate", strict, immutable, parallel_safe)] -fn counter_agg_extrapolated_rate(summary: CounterSummary, method: &str) -> Option { +fn counter_agg_extrapolated_rate<'a>(summary: CounterSummary<'a>, method: &str) -> Option { match method_kind(method) { Prometheus => summary .to_internal_counter_summary() @@ -648,12 +663,12 @@ fn counter_agg_extrapolated_rate(summary: CounterSummary, method: &str) -> Optio parallel_safe, schema = "toolkit_experimental" )] -fn counter_agg_interpolated_rate( - summary: CounterSummary, +fn counter_agg_interpolated_rate<'a>( + summary: CounterSummary<'a>, start: crate::raw::TimestampTz, interval: crate::raw::Interval, - prev: Option, - next: Option, + prev: Option>, + next: Option>, ) -> Option { let interval = crate::datum_utils::interval_to_ms(&start, &interval); summary @@ -664,137 +679,157 @@ fn counter_agg_interpolated_rate( #[pg_operator(immutable, parallel_safe)] #[opname(->)] -pub fn arrow_counter_agg_num_elements( - sketch: CounterSummary, - _accessor: AccessorNumElements, +pub fn arrow_counter_agg_num_elements<'a>( + sketch: CounterSummary<'a>, + _accessor: AccessorNumElements<'a>, ) -> i64 { counter_agg_num_elements(sketch) } #[pg_extern(name = "num_elements", strict, immutable, parallel_safe)] -fn counter_agg_num_elements(summary: CounterSummary) -> i64 { +fn counter_agg_num_elements<'a>(summary: CounterSummary<'a>) -> i64 { summary.to_internal_counter_summary().stats.n as i64 } #[pg_operator(immutable, parallel_safe)] #[opname(->)] -pub fn arrow_counter_agg_num_changes(sketch: CounterSummary, _accessor: AccessorNumChanges) -> i64 { +pub fn arrow_counter_agg_num_changes<'a>( + sketch: CounterSummary<'a>, + _accessor: AccessorNumChanges<'a>, +) -> i64 { counter_agg_num_changes(sketch) } #[pg_extern(name = "num_changes", strict, immutable, parallel_safe)] -fn counter_agg_num_changes(summary: CounterSummary) -> i64 { +fn counter_agg_num_changes<'a>(summary: CounterSummary<'a>) -> i64 { summary.to_internal_counter_summary().num_changes as i64 } #[pg_operator(immutable, parallel_safe)] #[opname(->)] -pub fn arrow_counter_agg_num_resets(sketch: CounterSummary, _accessor: AccessorNumResets) -> i64 { +pub fn arrow_counter_agg_num_resets<'a>( + sketch: CounterSummary<'a>, + _accessor: AccessorNumResets<'a>, +) -> i64 { counter_agg_num_resets(sketch) } #[pg_extern(name = "num_resets", strict, immutable, parallel_safe)] -fn counter_agg_num_resets(summary: CounterSummary) -> i64 { +fn counter_agg_num_resets<'a>(summary: CounterSummary<'a>) -> i64 { summary.to_internal_counter_summary().num_resets as i64 } #[pg_operator(immutable, parallel_safe)] #[opname(->)] -pub fn arrow_counter_agg_slope(sketch: CounterSummary, _accessor: AccessorSlope) -> Option { +pub fn arrow_counter_agg_slope<'a>( + sketch: CounterSummary<'a>, + _accessor: AccessorSlope<'a>, +) -> Option { counter_agg_slope(sketch) } #[pg_extern(name = "slope", strict, immutable, parallel_safe)] -fn counter_agg_slope(summary: CounterSummary) -> Option { +fn counter_agg_slope<'a>(summary: CounterSummary<'a>) -> Option { summary.to_internal_counter_summary().stats.slope() } #[pg_operator(immutable, parallel_safe)] #[opname(->)] -pub fn arrow_counter_agg_intercept( - sketch: CounterSummary, - _accessor: AccessorIntercept, +pub fn arrow_counter_agg_intercept<'a>( + sketch: CounterSummary<'a>, + _accessor: AccessorIntercept<'a>, ) -> Option { counter_agg_intercept(sketch) } #[pg_extern(name = "intercept", strict, immutable, parallel_safe)] -fn counter_agg_intercept(summary: CounterSummary) -> Option { +fn counter_agg_intercept<'a>(summary: CounterSummary<'a>) -> Option { summary.to_internal_counter_summary().stats.intercept() } #[pg_operator(immutable, parallel_safe)] #[opname(->)] -pub fn arrow_counter_agg_corr(sketch: CounterSummary, _accessor: AccessorCorr) -> Option { +pub fn arrow_counter_agg_corr<'a>( + sketch: CounterSummary<'a>, + _accessor: AccessorCorr<'a>, +) -> Option { counter_agg_corr(sketch) } #[pg_extern(name = "corr", strict, immutable, parallel_safe)] -fn counter_agg_corr(summary: CounterSummary) -> Option { +fn counter_agg_corr<'a>(summary: CounterSummary<'a>) -> Option { summary.to_internal_counter_summary().stats.corr() } #[pg_operator(immutable, parallel_safe)] #[opname(->)] -pub fn arrow_counter_agg_zero_time( - sketch: CounterSummary, - _accessor: AccessorCounterZeroTime, +pub fn arrow_counter_agg_zero_time<'a>( + sketch: CounterSummary<'a>, + _accessor: AccessorCounterZeroTime<'a>, ) -> Option { counter_agg_counter_zero_time(sketch) } #[pg_extern(name = "counter_zero_time", strict, immutable, parallel_safe)] -fn counter_agg_counter_zero_time(summary: CounterSummary) -> Option { +fn counter_agg_counter_zero_time<'a>( + summary: CounterSummary<'a>, +) -> Option { Some(((summary.to_internal_counter_summary().stats.x_intercept()? * 1_000_000.0) as i64).into()) } #[pg_operator(immutable, parallel_safe)] #[opname(->)] -pub fn arrow_counter_agg_first_val(sketch: CounterSummary, _accessor: AccessorFirstVal) -> f64 { +pub fn arrow_counter_agg_first_val<'a>( + sketch: CounterSummary<'a>, + _accessor: AccessorFirstVal<'a>, +) -> f64 { counter_agg_first_val(sketch) } #[pg_extern(name = "first_val", strict, immutable, parallel_safe)] -fn counter_agg_first_val(summary: CounterSummary) -> f64 { +fn counter_agg_first_val<'a>(summary: CounterSummary<'a>) -> f64 { summary.to_internal_counter_summary().first.val } #[pg_operator(immutable, parallel_safe)] #[opname(->)] -pub fn arrow_counter_agg_last_val(sketch: CounterSummary, _accessor: AccessorLastVal) -> f64 { +pub fn arrow_counter_agg_last_val<'a>( + sketch: CounterSummary<'a>, + _accessor: AccessorLastVal<'a>, +) -> f64 { counter_agg_last_val(sketch) } #[pg_extern(name = "last_val", strict, immutable, parallel_safe)] -fn counter_agg_last_val(summary: CounterSummary) -> f64 { +fn counter_agg_last_val<'a>(summary: CounterSummary<'a>) -> f64 { summary.to_internal_counter_summary().last.val } #[pg_operator(immutable, parallel_safe)] #[opname(->)] -pub fn arrow_counter_agg_first_time( - sketch: CounterSummary, - _accessor: AccessorFirstTime, +pub fn arrow_counter_agg_first_time<'a>( + sketch: CounterSummary<'a>, + _accessor: AccessorFirstTime<'a>, ) -> crate::raw::TimestampTz { counter_agg_first_time(sketch) } #[pg_extern(name = "first_time", strict, immutable, parallel_safe)] -fn counter_agg_first_time(summary: CounterSummary) -> crate::raw::TimestampTz { +fn counter_agg_first_time<'a>(summary: CounterSummary<'a>) -> crate::raw::TimestampTz { summary.to_internal_counter_summary().first.ts.into() } #[pg_operator(immutable, parallel_safe)] #[opname(->)] -pub fn arrow_counter_agg_last_time( - sketch: CounterSummary, - _accessor: AccessorLastTime, +pub fn arrow_counter_agg_last_time<'a>( + sketch: CounterSummary<'a>, + _accessor: AccessorLastTime<'a>, ) -> crate::raw::TimestampTz { counter_agg_last_time(sketch) } #[pg_extern(name = "last_time", strict, immutable, parallel_safe)] -fn counter_agg_last_time(summary: CounterSummary) -> crate::raw::TimestampTz { +fn counter_agg_last_time<'a>(summary: CounterSummary<'a>) -> crate::raw::TimestampTz { summary.to_internal_counter_summary().last.ts.into() } @@ -1104,7 +1139,7 @@ mod tests { let mut control = state.unwrap(); let buffer = counter_summary_trans_serialize(Inner::from(control.clone()).internal().unwrap()); - let buffer = pgx::varlena::varlena_to_byte_slice(buffer.0 as *mut pg_sys::varlena); + let buffer = pgx::varlena::varlena_to_byte_slice(buffer.0.cast_mut_ptr()); let expected = [ 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 96, 194, 134, 7, 62, 2, 0, 0, 0, 0, 0, 0, 0, 36, @@ -1119,9 +1154,8 @@ mod tests { assert_eq!(buffer, expected); let expected = pgx::varlena::rust_byte_slice_to_bytea(&expected); - let new_state = counter_summary_trans_deserialize_inner(bytea( - &*expected as *const pg_sys::varlena as _, - )); + let new_state = + counter_summary_trans_deserialize_inner(bytea(pgx::Datum::from(expected.as_ptr()))); control.combine_summaries(); // Serialized form is always combined assert_eq!(&*new_state, &*control); diff --git a/extension/src/countminsketch.rs b/extension/src/countminsketch.rs index e8027df3..6240fdf0 100644 --- a/extension/src/countminsketch.rs +++ b/extension/src/countminsketch.rs @@ -127,7 +127,7 @@ impl toolkit_experimental::count_min_sketch { } #[pg_extern(immutable, parallel_safe, schema = "toolkit_experimental")] -pub fn approx_count(item: String, aggregate: Option) -> Option { +pub fn approx_count<'a>(item: String, aggregate: Option>) -> Option { aggregate.map(|sketch| CountMinSketch::to_internal_countminsketch(&sketch).estimate(item)) } diff --git a/extension/src/datum_utils.rs b/extension/src/datum_utils.rs index a4fa3c14..f36d82f6 100644 --- a/extension/src/datum_utils.rs +++ b/extension/src/datum_utils.rs @@ -24,10 +24,10 @@ pub(crate) unsafe fn deep_copy_datum(datum: Datum, typoid: Oid) -> Datum { // only varlena's can be toasted, manually copy anything with len >0 let size = (*tentry).typlen as usize; let copy = pg_sys::palloc0(size); - std::ptr::copy(datum as *const u8, copy as *mut u8, size); - copy as Datum + std::ptr::copy(datum.cast_mut_ptr(), copy as *mut u8, size); + pgx::Datum::from(copy) } else { - pg_sys::pg_detoast_datum_copy(datum as _) as _ + pgx::Datum::from(pg_sys::pg_detoast_datum_copy(datum.cast_mut_ptr())) } } @@ -45,7 +45,7 @@ pub fn interval_to_ms(ref_time: &crate::raw::TimestampTz, interval: &crate::raw: interval.0, ) }; - bound as i64 - ref_time.0 as i64 + bound.value() as i64 - ref_time.0.value() as i64 } pub struct TextSerializableDatumWriter { @@ -189,14 +189,14 @@ impl Hasher for DatumHashBuilder { let value = unsafe { let value = (*(*self.info).flinfo).fn_addr.unwrap()(self.info); (*self.info).args.as_mut_slice(1)[0] = pg_sys::NullableDatum { - value: 0, + value: Datum::from(0_usize), isnull: true, }; (*self.info).isnull = false; //FIXME 32bit vs 64 bit get value from datum on 32b arch value }; - value as u64 + value.value() as u64 } fn write(&mut self, bytes: &[u8]) { @@ -212,7 +212,7 @@ impl Hasher for DatumHashBuilder { fn write_usize(&mut self, i: usize) { unsafe { (*self.info).args.as_mut_slice(1)[0] = pg_sys::NullableDatum { - value: i, + value: Datum::from(i), isnull: false, }; (*self.info).isnull = false; @@ -353,7 +353,7 @@ impl From<(Oid, Vec)> for DatumStore<'_> { let mut data: Vec = vec![]; for datum in datums { - data.extend_from_slice(&datum.to_ne_bytes()); + data.extend_from_slice(&datum.value().to_ne_bytes()); } DatumStore { @@ -369,7 +369,8 @@ impl From<(Oid, Vec)> for DatumStore<'_> { for datum in datums { unsafe { - let ptr = pg_sys::pg_detoast_datum_packed(datum as *mut pg_sys::varlena); + let ptr = + pg_sys::pg_detoast_datum_packed(datum.cast_mut_ptr::()); let va_len = varsize_any(ptr); ptrs.push(ptr); @@ -411,7 +412,7 @@ impl From<(Oid, Vec)> for DatumStore<'_> { for (i, datum) in datums.iter().enumerate() { unsafe { std::ptr::copy( - *datum as *const u8, + datum.cast_mut_ptr(), std::ptr::addr_of_mut!(buffer[i * len]), tlen as usize, ) @@ -453,10 +454,9 @@ impl<'a, 'b> Iterator for DatumStoreIterator<'a, 'b> { None } else { unsafe { - let va = store.data.slice().as_ptr().offset(*next_offset as _) - as *const pg_sys::varlena; - *next_offset += padded_va_len(va) as u32; - Some(va as pg_sys::Datum) + let va = store.data.slice().as_ptr().offset(*next_offset as _); + *next_offset += padded_va_len(va as *const _) as u32; + Some(pgx::Datum::from(va)) } } } @@ -470,7 +470,9 @@ impl<'a, 'b> Iterator for DatumStoreIterator<'a, 'b> { None } else { *next_index += 1; - Some(unsafe { store.data.slice().as_ptr().offset(idx as _) } as pg_sys::Datum) + Some(pgx::Datum::from(unsafe { + store.data.slice().as_ptr().offset(idx as _) + })) } } } @@ -560,10 +562,9 @@ impl<'a> Iterator for DatumStoreIntoIterator<'a> { None } else { unsafe { - let va = store.data.slice().as_ptr().offset(*next_offset as _) - as *const pg_sys::varlena; - *next_offset += padded_va_len(va) as u32; - Some(va as pg_sys::Datum) + let va = store.data.slice().as_ptr().offset(*next_offset as _); + *next_offset += padded_va_len(va as *const _) as u32; + Some(pgx::Datum::from(va)) } } } @@ -577,7 +578,9 @@ impl<'a> Iterator for DatumStoreIntoIterator<'a> { None } else { *next_index += 1; - Some(unsafe { store.data.slice().as_ptr().offset(idx as _) } as pg_sys::Datum) + Some(pgx::Datum::from(unsafe { + store.data.slice().as_ptr().offset(idx as _) + })) } } } diff --git a/extension/src/frequency.rs b/extension/src/frequency.rs index a06eb06a..5137f81a 100644 --- a/extension/src/frequency.rs +++ b/extension/src/frequency.rs @@ -2,7 +2,10 @@ use std::fmt; -use pgx::*; +use pgx::{ + iter::{SetOfIterator, TableIterator}, + *, +}; use pg_sys::{Datum, Oid}; @@ -435,7 +438,7 @@ pub mod toolkit_experimental { let mut overcounts = Vec::new(); for entry in &trans.entries { - values.push(entry.value as i64); + values.push(entry.value.value() as i64); counts.push(entry.count); overcounts.push(entry.overcount); } @@ -560,7 +563,7 @@ pub fn topn_agg_with_skew_bigint_trans( let value = match value { None => None, Some(val) => unsafe { - AnyElement::from_datum(val as pg_sys::Datum, false, pg_sys::INT8OID) + AnyElement::from_polymorphic_datum(pgx::Datum::from(val), false, pg_sys::INT8OID) }, }; @@ -583,11 +586,11 @@ pub fn topn_agg_with_skew_text_trans( value: Option, fcinfo: pg_sys::FunctionCallInfo, ) -> Option { - let txt = value.map(|v| unsafe { pg_sys::pg_detoast_datum_copy(v.0 as *mut pg_sys::varlena) }); + let txt = value.map(|v| unsafe { pg_sys::pg_detoast_datum_copy(v.0.cast_mut_ptr()) }); let value = match txt { None => None, Some(val) => unsafe { - AnyElement::from_datum(val as pg_sys::Datum, false, pg_sys::TEXTOID) + AnyElement::from_polymorphic_datum(pgx::Datum::from(val), false, pg_sys::TEXTOID) }, }; @@ -632,7 +635,7 @@ pub fn freq_agg_bigint_trans( let value = match value { None => None, Some(val) => unsafe { - AnyElement::from_datum(val as pg_sys::Datum, false, pg_sys::INT8OID) + AnyElement::from_polymorphic_datum(pgx::Datum::from(val), false, pg_sys::INT8OID) }, }; freq_agg_trans(state, freq, value, fcinfo) @@ -645,11 +648,11 @@ pub fn freq_agg_text_trans( value: Option, fcinfo: pg_sys::FunctionCallInfo, ) -> Option { - let txt = value.map(|v| unsafe { pg_sys::pg_detoast_datum_copy(v.0 as *mut pg_sys::varlena) }); + let txt = value.map(|v| unsafe { pg_sys::pg_detoast_datum_copy(v.0.cast_mut_ptr()) }); let value = match txt { None => None, Some(val) => unsafe { - AnyElement::from_datum(val as pg_sys::Datum, false, pg_sys::TEXTOID) + AnyElement::from_polymorphic_datum(pgx::Datum::from(val), false, pg_sys::TEXTOID) }, }; freq_agg_trans(state, freq, value, fcinfo) @@ -973,29 +976,37 @@ extension_sql!( name = "into_values", schema = "toolkit_experimental" )] -pub fn freq_iter( - agg: SpaceSavingAggregate<'_>, +pub fn freq_iter<'a, 'b>( + agg: SpaceSavingAggregate<'a>, ty: AnyElement, -) -> impl std::iter::Iterator< - Item = ( +) -> TableIterator< + 'b, + ( name!(value, AnyElement), name!(min_freq, f64), name!(max_freq, f64), ), -> + '_ { +> { unsafe { if ty.oid() != agg.type_oid { pgx::error!("mischatched types") } let counts = agg.counts.slice().iter().zip(agg.overcounts.slice().iter()); - agg.datums.clone().into_iter().zip(counts).map_while( - move |(value, (&count, &overcount))| { - let total = agg.values_seen as f64; - let value = AnyElement::from_datum(value, false, agg.type_oid).unwrap(); - let min_freq = (count - overcount) as f64 / total; - let max_freq = count as f64 / total; - Some((value, min_freq, max_freq)) - }, + TableIterator::new( + agg.datums + .clone() + .into_iter() + .zip(counts) + .map_while(move |(value, (&count, &overcount))| { + let total = agg.values_seen as f64; + let value = + AnyElement::from_polymorphic_datum(value, false, agg.type_oid).unwrap(); + let min_freq = (count - overcount) as f64 / total; + let max_freq = count as f64 / total; + Some((value, min_freq, max_freq)) + }) + .collect::>() + .into_iter(), ) } } @@ -1006,26 +1017,31 @@ pub fn freq_iter( name = "into_values", schema = "toolkit_experimental" )] -pub fn freq_bigint_iter( - agg: SpaceSavingBigIntAggregate<'_>, -) -> impl std::iter::Iterator< - Item = ( +pub fn freq_bigint_iter<'a, 'b>( + agg: SpaceSavingBigIntAggregate<'a>, +) -> TableIterator< + 'b, + ( name!(value, i64), name!(min_freq, f64), name!(max_freq, f64), ), -> + '_ { +> { let counts = agg.counts.slice().iter().zip(agg.overcounts.slice().iter()); - agg.datums - .clone() - .into_iter() - .zip(counts) - .map_while(move |(value, (&count, &overcount))| { - let total = agg.values_seen as f64; - let min_freq = (count - overcount) as f64 / total; - let max_freq = count as f64 / total; - Some((value, min_freq, max_freq)) - }) + TableIterator::new( + agg.datums + .clone() + .into_iter() + .zip(counts) + .map_while(move |(value, (&count, &overcount))| { + let total = agg.values_seen as f64; + let min_freq = (count - overcount) as f64 / total; + let max_freq = count as f64 / total; + Some((value, min_freq, max_freq)) + }) + .collect::>() + .into_iter(), + ) } #[pg_extern( @@ -1034,27 +1050,32 @@ pub fn freq_bigint_iter( name = "into_values", schema = "toolkit_experimental" )] -pub fn freq_text_iter( - agg: SpaceSavingTextAggregate<'_>, -) -> impl std::iter::Iterator< - Item = ( +pub fn freq_text_iter<'a, 'b>( + agg: SpaceSavingTextAggregate<'a>, +) -> TableIterator< + 'b, + ( name!(value, String), name!(min_freq, f64), name!(max_freq, f64), ), -> + '_ { +> { let counts = agg.counts.slice().iter().zip(agg.overcounts.slice().iter()); - agg.datums - .clone() - .into_iter() - .zip(counts) - .map_while(move |(value, (&count, &overcount))| { - let total = agg.values_seen as f64; - let data = unsafe { varlena_to_string(value as *const pg_sys::varlena) }; - let min_freq = (count - overcount) as f64 / total; - let max_freq = count as f64 / total; - Some((data, min_freq, max_freq)) - }) + TableIterator::new( + agg.datums + .clone() + .into_iter() + .zip(counts) + .map_while(move |(value, (&count, &overcount))| { + let total = agg.values_seen as f64; + let data = unsafe { varlena_to_string(value.cast_mut_ptr()) }; + let min_freq = (count - overcount) as f64 / total; + let max_freq = count as f64 / total; + Some((data, min_freq, max_freq)) + }) + .collect::>() + .into_iter(), + ) } fn validate_topn_for_topn_agg( @@ -1087,11 +1108,7 @@ fn validate_topn_for_topn_agg( } #[pg_extern(immutable, parallel_safe, schema = "toolkit_experimental")] -pub fn topn( - agg: SpaceSavingAggregate<'_>, - n: i32, - ty: AnyElement, -) -> impl std::iter::Iterator + '_ { +pub fn topn(agg: SpaceSavingAggregate<'_>, n: i32, ty: AnyElement) -> SetOfIterator { if ty.oid() != agg.type_oid { pgx::error!("mischatched types") } @@ -1106,15 +1123,21 @@ pub fn topn( let min_freq = if agg.topn == 0 { agg.freq_param } else { 0. }; let type_oid: u32 = agg.type_oid; - TopNIterator::new( - agg.datums.clone().into_iter(), - agg.counts.clone().into_vec(), - agg.values_seen as f64, - n, - min_freq, + SetOfIterator::new( + TopNIterator::new( + agg.datums.clone().into_iter(), + agg.counts.clone().into_vec(), + agg.values_seen as f64, + n, + min_freq, + ) + // TODO Shouldn't failure to convert to AnyElement cause error, not early stop? + .map_while(move |value| unsafe { + AnyElement::from_polymorphic_datum(value, false, type_oid) + }) + .collect::>() + .into_iter(), ) - // TODO Shouldn't failure to convert to AnyElement cause error, not early stop? - .map_while(move |value| unsafe { AnyElement::from_datum(value, false, type_oid) }) } #[pg_extern( @@ -1123,10 +1146,7 @@ pub fn topn( name = "topn", schema = "toolkit_experimental" )] -pub fn default_topn( - agg: SpaceSavingAggregate<'_>, - ty: AnyElement, -) -> impl std::iter::Iterator + '_ { +pub fn default_topn(agg: SpaceSavingAggregate<'_>, ty: AnyElement) -> SetOfIterator { if agg.topn == 0 { pgx::error!("frequency aggregates require a N parameter to topn") } @@ -1140,10 +1160,7 @@ pub fn default_topn( name = "topn", schema = "toolkit_experimental" )] -pub fn topn_bigint( - agg: SpaceSavingBigIntAggregate<'_>, - n: i32, -) -> impl std::iter::Iterator + '_ { +pub fn topn_bigint(agg: SpaceSavingBigIntAggregate<'_>, n: i32) -> SetOfIterator { validate_topn_for_topn_agg( n, agg.topn, @@ -1153,12 +1170,16 @@ pub fn topn_bigint( ); let min_freq = if agg.topn == 0 { agg.freq_param } else { 0. }; - TopNIterator::new( - agg.datums.clone().into_iter(), - agg.counts.clone().into_vec(), - agg.values_seen as f64, - n, - min_freq, + SetOfIterator::new( + TopNIterator::new( + agg.datums.clone().into_iter(), + agg.counts.clone().into_vec(), + agg.values_seen as f64, + n, + min_freq, + ) + .collect::>() + .into_iter(), ) } @@ -1168,9 +1189,7 @@ pub fn topn_bigint( name = "topn", schema = "toolkit_experimental" )] -pub fn default_topn_bigint( - agg: SpaceSavingBigIntAggregate<'_>, -) -> impl std::iter::Iterator + '_ { +pub fn default_topn_bigint(agg: SpaceSavingBigIntAggregate<'_>) -> SetOfIterator { if agg.topn == 0 { pgx::error!("frequency aggregates require a N parameter to topn") } @@ -1184,10 +1203,7 @@ pub fn default_topn_bigint( name = "topn", schema = "toolkit_experimental" )] -pub fn topn_text( - agg: SpaceSavingTextAggregate<'_>, - n: i32, -) -> impl std::iter::Iterator + '_ { +pub fn topn_text(agg: SpaceSavingTextAggregate<'_>, n: i32) -> SetOfIterator { validate_topn_for_topn_agg( n, agg.topn, @@ -1197,14 +1213,18 @@ pub fn topn_text( ); let min_freq = if agg.topn == 0 { agg.freq_param } else { 0. }; - TopNIterator::new( - agg.datums.clone().into_iter(), - agg.counts.clone().into_vec(), - agg.values_seen as f64, - n, - min_freq, + SetOfIterator::new( + TopNIterator::new( + agg.datums.clone().into_iter(), + agg.counts.clone().into_vec(), + agg.values_seen as f64, + n, + min_freq, + ) + .map(|value| unsafe { varlena_to_string(value.cast_mut_ptr()) }) + .collect::>() + .into_iter(), ) - .map(|value| unsafe { varlena_to_string(value as *const pg_sys::varlena) }) } #[pg_extern( @@ -1213,9 +1233,7 @@ pub fn topn_text( name = "topn", schema = "toolkit_experimental" )] -pub fn default_topn_text( - agg: SpaceSavingTextAggregate<'_>, -) -> impl std::iter::Iterator + '_ { +pub fn default_topn_text(agg: SpaceSavingTextAggregate<'_>) -> SetOfIterator { if agg.topn == 0 { pgx::error!("frequency aggregates require a N parameter to topn") } @@ -1461,8 +1479,9 @@ mod tests { for i in 11..=20 { for j in i..=20 { - let value = - unsafe { AnyElement::from_datum(j as pg_sys::Datum, false, pg_sys::INT4OID) }; + let value = unsafe { + AnyElement::from_polymorphic_datum(pgx::Datum::from(j), false, pg_sys::INT4OID) + }; state = super::freq_agg_trans(state, freq, value, fcinfo).unwrap(); } } @@ -1471,8 +1490,8 @@ mod tests { let bytes = unsafe { std::slice::from_raw_parts( - vardata_any(first.0 as *const pg_sys::varlena) as *const u8, - varsize_any_exhdr(first.0 as *const pg_sys::varlena), + vardata_any(first.0.cast_mut_ptr()) as *const u8, + varsize_any_exhdr(first.0.cast_mut_ptr()), ) }; let expected = [ @@ -1520,21 +1539,22 @@ mod tests { for i in (1..=10).rev() { // reverse here introduces less error in the aggregate for j in i..=20 { - let value = - unsafe { AnyElement::from_datum(j as pg_sys::Datum, false, pg_sys::INT4OID) }; + let value = unsafe { + AnyElement::from_polymorphic_datum(pgx::Datum::from(j), false, pg_sys::INT4OID) + }; state = super::freq_agg_trans(state, freq, value, fcinfo).unwrap(); } } let second = super::space_saving_serialize(state); - let bytes = unsafe { + let bytes: &[u8] = unsafe { std::slice::from_raw_parts( - vardata_any(second.0 as *const pg_sys::varlena) as *const u8, - varsize_any_exhdr(second.0 as *const pg_sys::varlena), + vardata_any(second.0.cast_mut_ptr()) as *const u8, + varsize_any_exhdr(second.0.cast_mut_ptr()), ) }; - let expected = [ + let expected: [u8; 513] = [ 1, 1, // versions 22, 0, 0, 0, 0, 0, 0, 0, // size hint for sequence 155, 0, 0, 0, 0, 0, 0, 0, // elements seen @@ -1598,11 +1618,11 @@ mod tests { let bytes = unsafe { std::slice::from_raw_parts( - vardata_any(combined.0 as *const pg_sys::varlena) as *const u8, - varsize_any_exhdr(combined.0 as *const pg_sys::varlena), + vardata_any(combined.0.cast_mut_ptr()) as *const u8, + varsize_any_exhdr(combined.0.cast_mut_ptr()), ) }; - let expected = [ + let expected: [u8; 513] = [ 1, 1, // versions 22, 0, 0, 0, 0, 0, 0, 0, // size hint for sequence 210, 0, 0, 0, 0, 0, 0, 0, // elements seen @@ -1854,14 +1874,16 @@ mod tests { for _ in 0..200 { let v = rand100.sample(&mut rng); - let value = - unsafe { AnyElement::from_datum(v as pg_sys::Datum, false, pg_sys::INT4OID) }; + let value = unsafe { + AnyElement::from_polymorphic_datum(pgx::Datum::from(v), false, pg_sys::INT4OID) + }; state = super::freq_agg_trans(state, freq, value, fcinfo).unwrap(); counts[v] += 1; } let state = space_saving_final(state, fcinfo).unwrap(); - let vals: std::collections::HashSet = state.datums.iter().collect(); + let vals: std::collections::HashSet = + state.datums.iter().map(|datum| datum.value()).collect(); for (val, &count) in counts.iter().enumerate() { if count >= 3 { @@ -1896,8 +1918,9 @@ mod tests { if v == usize::MAX { continue; // These tail values can start to add up at low skew values } - let value = - unsafe { AnyElement::from_datum(v as pg_sys::Datum, false, pg_sys::INT4OID) }; + let value = unsafe { + AnyElement::from_polymorphic_datum(pgx::Datum::from(v), false, pg_sys::INT4OID) + }; state = super::topn_agg_with_skew_trans(state, n as i32, skew, value, fcinfo).unwrap(); if v < 100 { // anything greater than 100 will not be in the top values @@ -1906,9 +1929,10 @@ mod tests { } let state = space_saving_final(state, fcinfo).unwrap(); - let value = unsafe { AnyElement::from_datum(0, false, pg_sys::INT4OID) }; + let value = + unsafe { AnyElement::from_polymorphic_datum(Datum::from(0), false, pg_sys::INT4OID) }; let t: Vec = default_topn(state, value.unwrap()).collect(); - let agg_topn: Vec = t.iter().map(|x| x.datum()).collect(); + let agg_topn: Vec = t.iter().map(|x| x.datum().value()).collect(); let mut temp: Vec<(usize, &usize)> = counts.iter().enumerate().collect(); temp.sort_by(|(_, cnt1), (_, cnt2)| cnt2.cmp(cnt1)); // descending order by count diff --git a/extension/src/gauge_agg.rs b/extension/src/gauge_agg.rs index e165b8b8..d89d7c0e 100644 --- a/extension/src/gauge_agg.rs +++ b/extension/src/gauge_agg.rs @@ -230,7 +230,7 @@ fn gauge_agg_trans_inner( None => { let mut s = GaugeSummaryTransState::new(); if let Some(r) = bounds { - s.bounds = get_range(r.0 as *mut pg_sys::varlena); + s.bounds = get_range(r.0.cast_mut_ptr()); } s.push_point(p); Some(s.into()) @@ -255,9 +255,9 @@ fn gauge_agg_trans_no_bounds( } #[pg_extern(immutable, parallel_safe, schema = "toolkit_experimental")] -fn gauge_agg_summary_trans( +fn gauge_agg_summary_trans<'a>( state: Internal, - value: Option, + value: Option>, fcinfo: pg_sys::FunctionCallInfo, ) -> Option { gauge_agg_summary_trans_inner(unsafe { state.to_inner() }, value, fcinfo).internal() @@ -429,94 +429,100 @@ extension_sql!( #[pg_operator(immutable, parallel_safe)] #[opname(->)] -fn arrow_delta(sketch: GaugeSummary, _accessor: AccessorDelta) -> f64 { +fn arrow_delta<'a>(sketch: GaugeSummary<'a>, _accessor: AccessorDelta<'a>) -> f64 { delta(sketch) } #[pg_extern(strict, immutable, parallel_safe, schema = "toolkit_experimental")] -fn delta(summary: GaugeSummary) -> f64 { +fn delta<'a>(summary: GaugeSummary<'a>) -> f64 { MetricSummary::from(summary).delta() } #[pg_operator(immutable, parallel_safe)] #[opname(->)] -fn arrow_gauge_agg_rate(sketch: GaugeSummary, _accessor: AccessorRate) -> Option { +fn arrow_gauge_agg_rate<'a>(sketch: GaugeSummary<'a>, _accessor: AccessorRate<'a>) -> Option { rate(sketch) } #[pg_extern(strict, immutable, parallel_safe, schema = "toolkit_experimental")] -fn rate(summary: GaugeSummary) -> Option { +fn rate<'a>(summary: GaugeSummary<'a>) -> Option { MetricSummary::from(summary).rate() } #[pg_operator(immutable, parallel_safe)] #[opname(->)] -fn arrow_time_delta(sketch: GaugeSummary, _accessor: AccessorTimeDelta) -> f64 { +fn arrow_time_delta<'a>(sketch: GaugeSummary<'a>, _accessor: AccessorTimeDelta<'a>) -> f64 { time_delta(sketch) } #[pg_extern(strict, immutable, parallel_safe, schema = "toolkit_experimental")] -fn time_delta(summary: GaugeSummary) -> f64 { +fn time_delta<'a>(summary: GaugeSummary<'a>) -> f64 { MetricSummary::from(summary).time_delta() } #[pg_operator(immutable, parallel_safe)] #[opname(->)] -fn arrow_irate_left(sketch: GaugeSummary, _accessor: AccessorIrateLeft) -> Option { +fn arrow_irate_left<'a>(sketch: GaugeSummary<'a>, _accessor: AccessorIrateLeft<'a>) -> Option { irate_left(sketch) } #[pg_extern(strict, immutable, parallel_safe, schema = "toolkit_experimental")] -fn irate_left(summary: GaugeSummary) -> Option { +fn irate_left<'a>(summary: GaugeSummary<'a>) -> Option { MetricSummary::from(summary).irate_left() } #[pg_operator(immutable, parallel_safe)] #[opname(->)] -fn arrow_irate_right(sketch: GaugeSummary, _accessor: AccessorIrateRight) -> Option { +fn arrow_irate_right<'a>( + sketch: GaugeSummary<'a>, + _accessor: AccessorIrateRight<'a>, +) -> Option { irate_right(sketch) } #[pg_extern(strict, immutable, parallel_safe, schema = "toolkit_experimental")] -fn irate_right(summary: GaugeSummary) -> Option { +fn irate_right<'a>(summary: GaugeSummary<'a>) -> Option { MetricSummary::from(summary).irate_right() } #[pg_operator(immutable, parallel_safe)] #[opname(->)] -fn arrow_idelta_left(sketch: GaugeSummary, _accessor: AccessorIdeltaLeft) -> f64 { +fn arrow_idelta_left<'a>(sketch: GaugeSummary<'a>, _accessor: AccessorIdeltaLeft<'a>) -> f64 { idelta_left(sketch) } #[pg_extern(strict, immutable, parallel_safe, schema = "toolkit_experimental")] -fn idelta_left(summary: GaugeSummary) -> f64 { +fn idelta_left<'a>(summary: GaugeSummary<'a>) -> f64 { MetricSummary::from(summary).idelta_left() } #[pg_operator(immutable, parallel_safe)] #[opname(->)] -fn arrow_idelta_right(sketch: GaugeSummary, _accessor: AccessorIdeltaRight) -> f64 { +fn arrow_idelta_right<'a>(sketch: GaugeSummary<'a>, _accessor: AccessorIdeltaRight<'a>) -> f64 { idelta_right(sketch) } #[pg_extern(strict, immutable, parallel_safe, schema = "toolkit_experimental")] -fn idelta_right(summary: GaugeSummary) -> f64 { +fn idelta_right<'a>(summary: GaugeSummary<'a>) -> f64 { MetricSummary::from(summary).idelta_right() } #[pg_operator(immutable, parallel_safe)] #[opname(->)] -fn arrow_with_bounds(sketch: GaugeSummary, accessor: AccessorWithBounds) -> GaugeSummary<'static> { +fn arrow_with_bounds<'a>( + sketch: GaugeSummary<'a>, + accessor: AccessorWithBounds<'a>, +) -> GaugeSummary<'static> { let mut builder = GaugeSummaryBuilder::from(MetricSummary::from(sketch)); builder.set_bounds(accessor.bounds()); builder.build().into() } #[pg_extern(strict, immutable, parallel_safe, schema = "toolkit_experimental")] -fn with_bounds(summary: GaugeSummary, bounds: tstzrange) -> GaugeSummary { +fn with_bounds<'a>(summary: GaugeSummary<'a>, bounds: tstzrange) -> GaugeSummary { // TODO dedup with previous by using apply_bounds unsafe { - let ptr = bounds.0 as *mut pg_sys::varlena; + let ptr = bounds.0.cast_mut_ptr(); let mut builder = GaugeSummaryBuilder::from(MetricSummary::from(summary)); builder.set_bounds(get_range(ptr)); builder.build().into() @@ -525,25 +531,25 @@ fn with_bounds(summary: GaugeSummary, bounds: tstzrange) -> GaugeSummary { #[pg_operator(immutable, parallel_safe)] #[opname(->)] -fn arrow_extrapolated_delta( - sketch: GaugeSummary, - _accessor: AccessorExtrapolatedDelta, +fn arrow_extrapolated_delta<'a>( + sketch: GaugeSummary<'a>, + _accessor: AccessorExtrapolatedDelta<'a>, ) -> Option { extrapolated_delta(sketch) } #[pg_extern(strict, immutable, parallel_safe, schema = "toolkit_experimental")] -fn extrapolated_delta(summary: GaugeSummary) -> Option { +fn extrapolated_delta<'a>(summary: GaugeSummary<'a>) -> Option { MetricSummary::from(summary).prometheus_delta().unwrap() } #[pg_extern(immutable, parallel_safe, schema = "toolkit_experimental")] -fn interpolated_delta( - summary: GaugeSummary, +fn interpolated_delta<'a>( + summary: GaugeSummary<'a>, start: crate::raw::TimestampTz, interval: crate::raw::Interval, - prev: Option, - next: Option, + prev: Option>, + next: Option>, ) -> f64 { let interval = crate::datum_utils::interval_to_ms(&start, &interval); MetricSummary::from(summary.interpolate(start.into(), interval, prev, next)).delta() @@ -551,25 +557,25 @@ fn interpolated_delta( #[pg_operator(immutable, parallel_safe)] #[opname(->)] -fn arrow_extrapolated_rate( - sketch: GaugeSummary, - _accessor: AccessorExtrapolatedRate, +fn arrow_extrapolated_rate<'a>( + sketch: GaugeSummary<'a>, + _accessor: AccessorExtrapolatedRate<'a>, ) -> Option { extrapolated_rate(sketch) } #[pg_extern(strict, immutable, parallel_safe, schema = "toolkit_experimental")] -fn extrapolated_rate(summary: GaugeSummary) -> Option { +fn extrapolated_rate<'a>(summary: GaugeSummary<'a>) -> Option { MetricSummary::from(summary).prometheus_rate().unwrap() } #[pg_extern(immutable, parallel_safe, schema = "toolkit_experimental")] -fn interpolated_rate( - summary: GaugeSummary, +fn interpolated_rate<'a>( + summary: GaugeSummary<'a>, start: crate::raw::TimestampTz, interval: crate::raw::Interval, - prev: Option, - next: Option, + prev: Option>, + next: Option>, ) -> Option { let interval = crate::datum_utils::interval_to_ms(&start, &interval); MetricSummary::from(summary.interpolate(start.into(), interval, prev, next)).rate() @@ -577,70 +583,70 @@ fn interpolated_rate( #[pg_operator(immutable, parallel_safe)] #[opname(->)] -fn arrow_num_elements(sketch: GaugeSummary, _accessor: AccessorNumElements) -> i64 { +fn arrow_num_elements<'a>(sketch: GaugeSummary<'a>, _accessor: AccessorNumElements<'a>) -> i64 { num_elements(sketch) } #[pg_extern(strict, immutable, parallel_safe, schema = "toolkit_experimental")] -fn num_elements(summary: GaugeSummary) -> i64 { +fn num_elements<'a>(summary: GaugeSummary<'a>) -> i64 { MetricSummary::from(summary).stats.n as i64 } #[pg_operator(immutable, parallel_safe)] #[opname(->)] -fn arrow_num_changes(sketch: GaugeSummary, _accessor: AccessorNumChanges) -> i64 { +fn arrow_num_changes<'a>(sketch: GaugeSummary<'a>, _accessor: AccessorNumChanges<'a>) -> i64 { num_changes(sketch) } #[pg_extern(strict, immutable, parallel_safe, schema = "toolkit_experimental")] -fn num_changes(summary: GaugeSummary) -> i64 { +fn num_changes<'a>(summary: GaugeSummary<'a>) -> i64 { MetricSummary::from(summary).num_changes as i64 } #[pg_operator(immutable, parallel_safe)] #[opname(->)] -fn arrow_slope(sketch: GaugeSummary, _accessor: AccessorSlope) -> Option { +fn arrow_slope<'a>(sketch: GaugeSummary<'a>, _accessor: AccessorSlope<'a>) -> Option { slope(sketch) } #[pg_extern(strict, immutable, parallel_safe, schema = "toolkit_experimental")] -fn slope(summary: GaugeSummary) -> Option { +fn slope<'a>(summary: GaugeSummary<'a>) -> Option { MetricSummary::from(summary).stats.slope() } #[pg_operator(immutable, parallel_safe)] #[opname(->)] -fn arrow_intercept(sketch: GaugeSummary, _accessor: AccessorIntercept) -> Option { +fn arrow_intercept<'a>(sketch: GaugeSummary<'a>, _accessor: AccessorIntercept<'a>) -> Option { intercept(sketch) } #[pg_extern(strict, immutable, parallel_safe, schema = "toolkit_experimental")] -fn intercept(summary: GaugeSummary) -> Option { +fn intercept<'a>(summary: GaugeSummary<'a>) -> Option { MetricSummary::from(summary).stats.intercept() } #[pg_operator(immutable, parallel_safe)] #[opname(->)] -fn arrow_corr(sketch: GaugeSummary, _accessor: AccessorCorr) -> Option { +fn arrow_corr<'a>(sketch: GaugeSummary<'a>, _accessor: AccessorCorr<'a>) -> Option { corr(sketch) } #[pg_extern(strict, immutable, parallel_safe, schema = "toolkit_experimental")] -fn corr(summary: GaugeSummary) -> Option { +fn corr<'a>(summary: GaugeSummary<'a>) -> Option { MetricSummary::from(summary).stats.corr() } #[pg_operator(immutable, parallel_safe)] #[opname(->)] -fn arrow_zero_time( - sketch: GaugeSummary, - __accessor: AccessorCounterZeroTime, +fn arrow_zero_time<'a>( + sketch: GaugeSummary<'a>, + __accessor: AccessorCounterZeroTime<'a>, ) -> Option { gauge_zero_time(sketch) } #[pg_extern(strict, immutable, parallel_safe, schema = "toolkit_experimental")] -fn gauge_zero_time(summary: GaugeSummary) -> Option { +fn gauge_zero_time<'a>(summary: GaugeSummary<'a>) -> Option { Some(((MetricSummary::from(summary).stats.x_intercept()? * 1_000_000.0) as i64).into()) } diff --git a/extension/src/hyperloglog.rs b/extension/src/hyperloglog.rs index 60065689..5101bf5a 100644 --- a/extension/src/hyperloglog.rs +++ b/extension/src/hyperloglog.rs @@ -1,6 +1,9 @@ #![allow(clippy::identity_op)] // clippy gets confused by flat_serialize! enums -use std::convert::TryInto; +use std::{ + convert::TryInto, + hash::{Hash, Hasher}, +}; use serde::{Deserialize, Serialize}; @@ -19,9 +22,20 @@ use crate::{ use hyperloglogplusplus::{HyperLogLog as HLL, HyperLogLogStorage}; +// pgx doesn't implement Eq/Hash but it's okay here since we treat Datums as raw bytes +#[derive(Debug, Copy, Clone, PartialEq)] +struct HashableDatum(Datum); +impl Eq for HashableDatum {} +#[allow(clippy::derive_hash_xor_eq)] // partialeq and hash implementations match +impl Hash for HashableDatum { + fn hash(&self, state: &mut H) { + self.0.value().hash(state) + } +} + #[derive(Serialize, Deserialize, Clone, PartialEq, Eq)] pub struct HyperLogLogTrans { - logger: HLL<'static, Datum, DatumHashBuilder>, + logger: HLL<'static, HashableDatum, DatumHashBuilder>, } use crate::raw::AnyElement; @@ -34,9 +48,9 @@ pub fn hyperloglog_trans( value: Option, fc: pg_sys::FunctionCallInfo, ) -> Option { - // let state: Internal = Internal::from_datum(); + // let state: Internal = Internal::from_polymorphic_datum(); hyperloglog_trans_inner(unsafe { state.to_inner() }, size, value, fc, unsafe { - pgx::get_getarg_type(fc, 2) + pgx::pg_getarg_type(fc, 2) }) .internal() } @@ -51,13 +65,13 @@ pub fn approx_count_distinct_trans( value: Option, fc: pg_sys::FunctionCallInfo, ) -> Option { - // let state: Internal = Internal::from_datum(); + // let state: Internal = Internal::from_polymorphic_datum(); hyperloglog_trans_inner( unsafe { state.to_inner() }, APPROX_COUNT_DISTINCT_DEFAULT_SIZE, value, fc, - unsafe { pgx::get_getarg_type(fc, 1) }, + unsafe { pgx::pg_getarg_type(fc, 1) }, ) .internal() } @@ -102,7 +116,7 @@ pub fn hyperloglog_trans_inner( } Some(state) => state, }; - state.logger.add(&value); + state.logger.add(&HashableDatum(value)); Some(state) }) } @@ -260,9 +274,9 @@ extension_sql!( ); #[pg_extern(immutable, parallel_safe)] -pub fn hyperloglog_union( +pub fn hyperloglog_union<'a>( state: Internal, - other: HyperLogLog, + other: HyperLogLog<'a>, fc: pg_sys::FunctionCallInfo, ) -> Option { hyperloglog_union_inner(unsafe { state.to_inner() }, other, fc).internal() @@ -319,12 +333,15 @@ extension_sql!( #[pg_operator(immutable, parallel_safe)] #[opname(->)] -pub fn arrow_hyperloglog_count(sketch: HyperLogLog, _accessor: AccessorDistinctCount) -> i64 { +pub fn arrow_hyperloglog_count<'a>( + sketch: HyperLogLog<'a>, + _accessor: AccessorDistinctCount<'a>, +) -> i64 { hyperloglog_count(sketch) } #[pg_extern(name = "distinct_count", immutable, parallel_safe)] -pub fn hyperloglog_count(hyperloglog: HyperLogLog) -> i64 { +pub fn hyperloglog_count<'a>(hyperloglog: HyperLogLog<'a>) -> i64 { // count does not depend on the type parameters let log = match &hyperloglog.log { Storage::Sparse { @@ -332,26 +349,32 @@ pub fn hyperloglog_count(hyperloglog: HyperLogLog) -> i64 { precision, compressed, .. - } => { - HLL::::from_sparse_parts(compressed.slice(), *num_compressed, *precision, ()) - } + } => HLL::::from_sparse_parts( + compressed.slice(), + *num_compressed, + *precision, + (), + ), Storage::Dense { precision, registers, .. - } => HLL::::from_dense_parts(registers.slice(), *precision, ()), + } => HLL::::from_dense_parts(registers.slice(), *precision, ()), }; log.immutable_estimate_count() as i64 } #[pg_operator(immutable, parallel_safe)] #[opname(->)] -pub fn arrow_hyperloglog_error(sketch: HyperLogLog, _accessor: AccessorStderror) -> f64 { +pub fn arrow_hyperloglog_error<'a>( + sketch: HyperLogLog<'a>, + _accessor: AccessorStderror<'a>, +) -> f64 { hyperloglog_error(sketch) } #[pg_extern(name = "stderror", immutable, parallel_safe)] -pub fn hyperloglog_error(hyperloglog: HyperLogLog) -> f64 { +pub fn hyperloglog_error<'a>(hyperloglog: HyperLogLog<'a>) -> f64 { let precision = match hyperloglog.log { Storage::Sparse { precision, .. } => precision, Storage::Dense { precision, .. } => precision, @@ -373,10 +396,10 @@ impl HyperLogLog<'_> { .unwrap() .trailing_zeros(); let hasher = DatumHashBuilder::from_type_id(type_id, collation); - let mut logger: HLL = HLL::new(b as u8, hasher); + let mut logger: HLL = HLL::new(b as u8, hasher); for datum in data { - logger.add(&datum); + logger.add(&HashableDatum(datum)); } flatten_log(&mut logger) @@ -384,7 +407,7 @@ impl HyperLogLog<'_> { } } -fn flatten_log(hyperloglog: &mut HLL) -> HyperLogLog<'static> { +fn flatten_log(hyperloglog: &mut HLL) -> HyperLogLog<'static> { let (element_type, collation) = { let hasher = &hyperloglog.buildhasher; (ShortTypeId(hasher.type_id), PgCollationId(hasher.collation)) @@ -421,7 +444,7 @@ fn flatten_log(hyperloglog: &mut HLL) -> HyperLogLog<'s flat } -fn unflatten_log(hyperloglog: HyperLogLog) -> HLL { +fn unflatten_log(hyperloglog: HyperLogLog) -> HLL { match &hyperloglog.log { Storage::Sparse { num_compressed, @@ -430,7 +453,7 @@ fn unflatten_log(hyperloglog: HyperLogLog) -> HLL { element_type, collation, compressed_bytes: _, - } => HLL::::from_sparse_parts( + } => HLL::::from_sparse_parts( compressed.slice(), *num_compressed, *precision, @@ -441,7 +464,7 @@ fn unflatten_log(hyperloglog: HyperLogLog) -> HLL { registers, element_type, collation, - } => HLL::::from_dense_parts( + } => HLL::::from_dense_parts( registers.slice(), *precision, unsafe { DatumHashBuilder::from_type_id(element_type.0, Some(collation.0)) }, @@ -598,24 +621,24 @@ mod tests { let mut control = HyperLogLogTrans { logger: HLL::new(6, hasher), }; - control - .logger - .add(&rust_str_to_text_p("first").into_datum().unwrap()); - control - .logger - .add(&rust_str_to_text_p("second").into_datum().unwrap()); - control - .logger - .add(&rust_str_to_text_p("first").into_datum().unwrap()); - control - .logger - .add(&rust_str_to_text_p("second").into_datum().unwrap()); - control - .logger - .add(&rust_str_to_text_p("third").into_datum().unwrap()); + control.logger.add(&HashableDatum( + rust_str_to_text_p("first").into_datum().unwrap(), + )); + control.logger.add(&HashableDatum( + rust_str_to_text_p("second").into_datum().unwrap(), + )); + control.logger.add(&HashableDatum( + rust_str_to_text_p("first").into_datum().unwrap(), + )); + control.logger.add(&HashableDatum( + rust_str_to_text_p("second").into_datum().unwrap(), + )); + control.logger.add(&HashableDatum( + rust_str_to_text_p("third").into_datum().unwrap(), + )); let buffer = hyperloglog_serialize(Inner::from(control.clone()).internal().unwrap()); - let buffer = pgx::varlena::varlena_to_byte_slice(buffer.0 as *mut pg_sys::varlena); + let buffer = pgx::varlena::varlena_to_byte_slice(buffer.0.cast_mut_ptr()); let mut expected = vec![ 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 136, 136, 9, 7, @@ -626,20 +649,20 @@ mod tests { let expected = pgx::varlena::rust_byte_slice_to_bytea(&expected); let new_state = - hyperloglog_deserialize_inner(bytea(&*expected as *const pg_sys::varlena as _)); + hyperloglog_deserialize_inner(bytea(pgx::Datum::from(expected.as_ptr()))); control.logger.merge_all(); // Sparse representation buffers always merged on serialization assert!(*new_state == control); // Now generate a dense represenataion and validate that for i in 0..500 { - control - .logger - .add(&rust_str_to_text_p(&i.to_string()).into_datum().unwrap()); + control.logger.add(&HashableDatum( + rust_str_to_text_p(&i.to_string()).into_datum().unwrap(), + )); } let buffer = hyperloglog_serialize(Inner::from(control.clone()).internal().unwrap()); - let buffer = pgx::varlena::varlena_to_byte_slice(buffer.0 as *mut pg_sys::varlena); + let buffer = pgx::varlena::varlena_to_byte_slice(buffer.0.cast_mut_ptr()); let mut expected = vec![ 1, 1, 1, 0, 0, 0, 49, 0, 0, 0, 0, 0, 0, 0, 20, 65, 2, 12, 48, 199, 20, 33, 4, 12, @@ -652,7 +675,7 @@ mod tests { let expected = pgx::varlena::rust_byte_slice_to_bytea(&expected); let new_state = - hyperloglog_deserialize_inner(bytea(&*expected as *const pg_sys::varlena as _)); + hyperloglog_deserialize_inner(bytea(pgx::Datum::from(expected.as_ptr()))); assert!(*new_state == control); } diff --git a/extension/src/lib.rs b/extension/src/lib.rs index b7b9678a..c2ee177a 100644 --- a/extension/src/lib.rs +++ b/extension/src/lib.rs @@ -4,6 +4,10 @@ #![allow(clippy::extra_unused_lifetimes)] // every function calling in_aggregate_context should be unsafe #![allow(clippy::not_unsafe_ptr_arg_deref)] +// since 0.5 pgx requires non-elided lifetimes on extern functions: https://github.com/tcdi/pgx/issues/721 +#![allow(clippy::needless_lifetimes)] +// triggered by pg_extern macros +#![allow(clippy::useless_conversion)] pub mod accessors; pub mod asap; diff --git a/extension/src/ohlc.rs b/extension/src/ohlc.rs index b2dea1a4..83d33a83 100644 --- a/extension/src/ohlc.rs +++ b/extension/src/ohlc.rs @@ -147,9 +147,9 @@ pub fn ohlc_transition_inner( } #[pg_extern(immutable, parallel_safe, schema = "toolkit_experimental")] -pub fn ohlc_rollup_trans( +pub fn ohlc_rollup_trans<'a>( state: Internal, - value: Option, + value: Option>, fcinfo: pg_sys::FunctionCallInfo, ) -> Option { ohlc_rollup_trans_inner(unsafe { state.to_inner() }, value, fcinfo).internal() @@ -283,49 +283,49 @@ extension_sql!( ); #[pg_extern(immutable, parallel_safe, schema = "toolkit_experimental")] -pub fn open(aggregate: Option) -> f64 { +pub fn open<'a>(aggregate: Option>) -> f64 { let ohlc = aggregate.unwrap(); ohlc.open() } #[pg_extern(immutable, parallel_safe, schema = "toolkit_experimental")] -pub fn high(aggregate: Option) -> f64 { +pub fn high<'a>(aggregate: Option>) -> f64 { let ohlc = aggregate.unwrap(); ohlc.high() } #[pg_extern(immutable, parallel_safe, schema = "toolkit_experimental")] -pub fn low(aggregate: Option) -> f64 { +pub fn low<'a>(aggregate: Option>) -> f64 { let ohlc = aggregate.unwrap(); ohlc.low() } #[pg_extern(immutable, parallel_safe, schema = "toolkit_experimental")] -pub fn close(aggregate: Option) -> f64 { +pub fn close<'a>(aggregate: Option>) -> f64 { let ohlc = aggregate.unwrap(); ohlc.close() } #[pg_extern(immutable, parallel_safe, schema = "toolkit_experimental")] -pub fn open_time(aggregate: Option) -> crate::raw::TimestampTz { +pub fn open_time<'a>(aggregate: Option>) -> crate::raw::TimestampTz { let ohlc = aggregate.unwrap(); ohlc.open_time().into() } #[pg_extern(immutable, parallel_safe, schema = "toolkit_experimental")] -pub fn high_time(aggregate: Option) -> crate::raw::TimestampTz { +pub fn high_time<'a>(aggregate: Option>) -> crate::raw::TimestampTz { let ohlc = aggregate.unwrap(); ohlc.high_time().into() } #[pg_extern(immutable, parallel_safe, schema = "toolkit_experimental")] -pub fn low_time(aggregate: Option) -> crate::raw::TimestampTz { +pub fn low_time<'a>(aggregate: Option>) -> crate::raw::TimestampTz { let ohlc = aggregate.unwrap(); ohlc.low_time().into() } #[pg_extern(immutable, parallel_safe, schema = "toolkit_experimental")] -pub fn close_time(aggregate: Option) -> crate::raw::TimestampTz { +pub fn close_time<'a>(aggregate: Option>) -> crate::raw::TimestampTz { let ohlc = aggregate.unwrap(); ohlc.close_time().into() } diff --git a/extension/src/palloc.rs b/extension/src/palloc.rs index f95a0908..5b572e21 100644 --- a/extension/src/palloc.rs +++ b/extension/src/palloc.rs @@ -40,7 +40,8 @@ unsafe impl InternalAsValue for Internal { // } unsafe fn to_inner(self) -> Option> { - self.unwrap().map(|p| Inner(NonNull::new(p as _).unwrap())) + self.unwrap() + .map(|p| Inner(NonNull::new(p.cast_mut_ptr()).unwrap())) } } @@ -71,13 +72,13 @@ impl DerefMut for Inner { unsafe impl ToInternal for Option> { fn internal(self) -> Option { - self.map(|p| Internal::from(Some(p.0.as_ptr() as pg_sys::Datum))) + self.map(|p| Internal::from(Some(pgx::Datum::from(p.0.as_ptr())))) } } unsafe impl ToInternal for Inner { fn internal(self) -> Option { - Some(Internal::from(Some(self.0.as_ptr() as pg_sys::Datum))) + Some(Internal::from(Some(pgx::Datum::from(self.0.as_ptr())))) } } @@ -90,13 +91,13 @@ impl From for Inner { // TODO these last two should probably be `unsafe` unsafe impl ToInternal for *mut T { fn internal(self) -> Option { - Some(Internal::from(Some(self as pg_sys::Datum))) + Some(Internal::from(Some(pgx::Datum::from(self)))) } } unsafe impl ToInternal for *const T { fn internal(self) -> Option { - Some(Internal::from(Some(self as pg_sys::Datum))) + Some(Internal::from(Some(pgx::Datum::from(self)))) } } diff --git a/extension/src/pg_any_element.rs b/extension/src/pg_any_element.rs index e794c2a8..3becdba6 100644 --- a/extension/src/pg_any_element.rs +++ b/extension/src/pg_any_element.rs @@ -65,7 +65,7 @@ impl PartialEq for PgAnyElement { value: other.datum, isnull: false, }; - (*(*info).flinfo).fn_addr.unwrap()(info) != 0 + (*(*info).flinfo).fn_addr.unwrap()(info) != Datum::from(0) } } } @@ -75,7 +75,7 @@ impl Eq for PgAnyElement {} impl Hash for PgAnyElement { fn hash(&self, state: &mut H) { - self.datum.hash(state); + self.datum.value().hash(state); } } diff --git a/extension/src/raw.rs b/extension/src/raw.rs index 123421d1..e8ca8e42 100644 --- a/extension/src/raw.rs +++ b/extension/src/raw.rs @@ -1,6 +1,11 @@ #![allow(non_camel_case_types)] -use pgx::*; +use pgx::{ + utils::sql_entity_graph::metadata::{ + ArgumentError, Returns, ReturnsError, SqlMapping, SqlTranslatable, + }, + *, +}; extension_sql!( "\n\ @@ -24,9 +29,7 @@ extension_sql!( macro_rules! raw_type { ($name:ident, $tyid: path, $arrayid: path) => { impl FromDatum for $name { - const NEEDS_TYPID: bool = false; - - unsafe fn from_datum( + unsafe fn from_polymorphic_datum( datum: pg_sys::Datum, is_null: bool, _typoid: pg_sys::Oid, @@ -64,6 +67,16 @@ macro_rules! raw_type { v.0 } } + + // SAFETY: all calls to raw_type! use type names that are valid SQL + unsafe impl SqlTranslatable for $name { + fn argument_sql() -> Result { + Ok(SqlMapping::literal(stringify!($name))) + } + fn return_sql() -> Result { + Ok(Returns::One(SqlMapping::literal(stringify!($name)))) + } + } }; } @@ -87,13 +100,13 @@ raw_type!( impl From for pg_sys::TimestampTz { fn from(tstz: TimestampTz) -> Self { - tstz.0 as _ + tstz.0.value() as _ } } impl From for TimestampTz { fn from(ts: pg_sys::TimestampTz) -> Self { - Self(ts as _) + Self(pgx::Datum::from(ts)) } } diff --git a/extension/src/serialization/collations.rs b/extension/src/serialization/collations.rs index 435bfefd..0e84c4cd 100644 --- a/extension/src/serialization/collations.rs +++ b/extension/src/serialization/collations.rs @@ -11,7 +11,7 @@ use serde::{Deserialize, Serialize}; use once_cell::sync::Lazy; -use pg_sys::{Datum, Oid}; +use pg_sys::Oid; use pgx::*; // TODO short collation serializer? @@ -79,7 +79,7 @@ type Form_pg_database = *mut FormData_pg_database; static DEFAULT_COLLATION_NAME: Lazy = Lazy::new(|| unsafe { let tuple = pg_sys::SearchSysCache1( pg_sys::SysCacheIdentifier_DATABASEOID as _, - pg_sys::MyDatabaseId as _, + pgx::Datum::from(pg_sys::MyDatabaseId), ); if tuple.is_null() { pgx::error!("no database info"); @@ -109,8 +109,10 @@ impl Serialize for PgCollationId { return layout.serialize(serializer); } - let tuple = - pg_sys::SearchSysCache1(pg_sys::SysCacheIdentifier_COLLOID as _, self.0 as _); + let tuple = pg_sys::SearchSysCache1( + pg_sys::SysCacheIdentifier_COLLOID as _, + pgx::Datum::from(self.0), + ); if tuple.is_null() { pgx::error!("no collation info for oid {}", self.0); } @@ -206,20 +208,20 @@ impl<'de> Deserialize<'de> for PgCollationId { let mut collation_id = pg_sys::GetSysCacheOid( pg_sys::SysCacheIdentifier_COLLNAMEENCNSP as _, Anum_pg_collation_oid as _, - name.as_ptr() as Datum, - pg_sys::GetDatabaseEncoding() as _, - namespace_id as Datum, - 0, //unused + pgx::Datum::from(name.as_ptr()), + pgx::Datum::from(pg_sys::GetDatabaseEncoding()), + pgx::Datum::from(namespace_id), + Datum::from(0), //unused ); if collation_id == pg_sys::InvalidOid { collation_id = pg_sys::GetSysCacheOid( pg_sys::SysCacheIdentifier_COLLNAMEENCNSP as _, Anum_pg_collation_oid as _, - name.as_ptr() as Datum, - (-1isize) as usize, - namespace_id as Datum, - 0, //unused + pgx::Datum::from(name.as_ptr()), + Datum::from((-1isize) as usize), + pgx::Datum::from(namespace_id), + Datum::from(0), //unused ); } diff --git a/extension/src/serialization/functions.rs b/extension/src/serialization/functions.rs index b41b1efd..db4803e7 100644 --- a/extension/src/serialization/functions.rs +++ b/extension/src/serialization/functions.rs @@ -60,10 +60,10 @@ impl<'de> Deserialize<'de> for PgProcId { pg_sys::DirectFunctionCall1Coll( Some(regprocedurein), pg_sys::InvalidOid, - qualified_name.as_ptr() as pg_sys::Datum, + pgx::Datum::from(qualified_name.as_ptr()), ) }; - Ok(Self(oid as _)) + Ok(Self(oid.value() as _)) } } diff --git a/extension/src/serialization/types.rs b/extension/src/serialization/types.rs index c8a571fb..8b003add 100644 --- a/extension/src/serialization/types.rs +++ b/extension/src/serialization/types.rs @@ -8,7 +8,7 @@ use flat_serialize::{impl_flat_serializable, FlatSerializable, WrapErr}; use serde::{Deserialize, Serialize}; -use pg_sys::{Datum, Oid}; +use pg_sys::Oid; use pgx::*; /// Possibly a premature optimization, `ShortTypId` provides the ability to @@ -213,8 +213,10 @@ impl Serialize for PgTypId { S: serde::Serializer, { unsafe { - let tuple = - pg_sys::SearchSysCache1(pg_sys::SysCacheIdentifier_TYPEOID as _, self.0 as _); + let tuple = pg_sys::SearchSysCache1( + pg_sys::SysCacheIdentifier_TYPEOID as _, + pgx::Datum::from(self.0), + ); if tuple.is_null() { pgx::error!("no type info for oid {}", self.0); } @@ -289,10 +291,10 @@ impl<'de> Deserialize<'de> for PgTypId { let type_id = pg_sys::GetSysCacheOid( pg_sys::SysCacheIdentifier_TYPENAMENSP as _, pg_sys::Anum_pg_type_oid as _, - name.as_ptr() as Datum, - namespace_id as Datum, - 0, //unused - 0, //unused + pgx::Datum::from(name.as_ptr()), + pgx::Datum::from(namespace_id), + Datum::from(0), //unused + Datum::from(0), //unused ); if type_id == pg_sys::InvalidOid { return Err(D::Error::custom(format!( diff --git a/extension/src/state_aggregate.rs b/extension/src/state_aggregate.rs index 1b1af505..3a357aae 100644 --- a/extension/src/state_aggregate.rs +++ b/extension/src/state_aggregate.rs @@ -6,7 +6,7 @@ #![allow(non_camel_case_types)] -use pgx::*; +use pgx::{iter::TableIterator, *}; use serde::{Deserialize, Serialize}; use aggregate_builder::aggregate; @@ -324,7 +324,7 @@ impl StateAggTransState { } #[pg_extern(immutable, parallel_safe, schema = "toolkit_experimental")] -pub fn duration_in(state: String, aggregate: Option) -> crate::raw::Interval { +pub fn duration_in<'a>(state: String, aggregate: Option>) -> crate::raw::Interval { let time: i64 = aggregate .and_then(|aggregate| aggregate.get(&state)) .unwrap_or(0); @@ -345,19 +345,19 @@ pub fn duration_in(state: String, aggregate: Option) -> crate::raw::In // result = DatumGetIntervalP(DirectFunctionCall1(interval_justify_hours, // IntervalPGetDatum(result))); // So if we want the same behavior, we need to call interval_justify_hours too: - let function_args = vec![Some(interval as pg_sys::Datum)]; + let function_args = vec![Some(pgx::Datum::from(interval))]; unsafe { pgx::direct_function_call(pg_sys::interval_justify_hours, function_args) } .expect("interval_justify_hours does not return None") } #[pg_extern(immutable, parallel_safe, schema = "toolkit_experimental")] -pub fn interpolated_duration_in( +pub fn interpolated_duration_in<'a>( state: String, - aggregate: Option, + aggregate: Option>, start: TimestampTz, interval: crate::raw::Interval, - prev: Option, - next: Option, + prev: Option>, + next: Option>, ) -> crate::raw::Interval { match aggregate { None => pgx::error!( @@ -374,15 +374,22 @@ pub fn interpolated_duration_in( } #[pg_extern(immutable, parallel_safe, schema = "toolkit_experimental")] -pub fn into_values( - agg: StateAgg<'_>, -) -> impl std::iter::Iterator + '_ { +pub fn into_values<'a, 'b>( + agg: StateAgg<'a>, +) -> TableIterator<'b, (pgx::name!(state, String), pgx::name!(duration, i64))> { let states: String = agg.states_as_str().to_owned(); - agg.durations.clone().into_iter().map(move |record| { - let beg = record.state_beg as usize; - let end = record.state_end as usize; - (states[beg..end].to_owned(), record.duration) - }) + TableIterator::new( + agg.durations + .clone() + .into_iter() + .map(move |record| { + let beg = record.state_beg as usize; + let end = record.state_end as usize; + (states[beg..end].to_owned(), record.duration) + }) + .collect::>() + .into_iter(), + ) } #[derive(Clone, Debug, Deserialize, Eq, FlatSerializable, PartialEq, Serialize)] diff --git a/extension/src/stats_agg.rs b/extension/src/stats_agg.rs index 8f3f99f1..c8995ceb 100644 --- a/extension/src/stats_agg.rs +++ b/extension/src/stats_agg.rs @@ -277,16 +277,16 @@ pub fn stats2d_inv_trans_inner( } #[pg_extern(immutable, parallel_safe)] -pub fn stats1d_summary_trans( +pub fn stats1d_summary_trans<'a>( state: Internal, - value: Option, + value: Option>, fcinfo: pg_sys::FunctionCallInfo, ) -> Option { stats1d_summary_trans_inner(unsafe { state.to_inner() }, value, fcinfo).internal() } pub fn stats1d_summary_trans_inner<'s>( state: Option>>, - value: Option, + value: Option>, fcinfo: pg_sys::FunctionCallInfo, ) -> Option>> { unsafe { @@ -305,16 +305,16 @@ pub fn stats1d_summary_trans_inner<'s>( } #[pg_extern(immutable, parallel_safe)] -pub fn stats2d_summary_trans( +pub fn stats2d_summary_trans<'a>( state: Internal, - value: Option, + value: Option>, fcinfo: pg_sys::FunctionCallInfo, ) -> Option { stats2d_summary_trans_inner(unsafe { state.to_inner() }, value, fcinfo).internal() } pub fn stats2d_summary_trans_inner<'s>( state: Option>>, - value: Option, + value: Option>, fcinfo: pg_sys::FunctionCallInfo, ) -> Option>> { unsafe { @@ -333,9 +333,9 @@ pub fn stats2d_summary_trans_inner<'s>( } #[pg_extern(immutable, parallel_safe)] -pub fn stats1d_summary_inv_trans( +pub fn stats1d_summary_inv_trans<'a>( state: Internal, - value: Option, + value: Option>, fcinfo: pg_sys::FunctionCallInfo, ) -> Option { stats1d_summary_inv_trans_inner(unsafe { state.to_inner() }, value, fcinfo).internal() @@ -360,9 +360,9 @@ pub fn stats1d_summary_inv_trans_inner<'s>( } #[pg_extern(immutable, parallel_safe)] -pub fn stats2d_summary_inv_trans( +pub fn stats2d_summary_inv_trans<'a>( state: Internal, - value: Option, + value: Option>, fcinfo: pg_sys::FunctionCallInfo, ) -> Option { stats2d_summary_inv_trans_inner(unsafe { state.to_inner() }, value, fcinfo).internal() @@ -694,39 +694,45 @@ extension_sql!( #[pg_operator(immutable, parallel_safe)] #[opname(->)] -pub fn arrow_stats1d_average(sketch: StatsSummary1D, _accessor: AccessorAverage) -> Option { +pub fn arrow_stats1d_average<'a>( + sketch: StatsSummary1D<'a>, + _accessor: AccessorAverage<'a>, +) -> Option { stats1d_average(sketch) } #[pg_extern(name = "average", strict, immutable, parallel_safe)] -pub(crate) fn stats1d_average(summary: StatsSummary1D) -> Option { +pub(crate) fn stats1d_average<'a>(summary: StatsSummary1D<'a>) -> Option { summary.to_internal().avg() } #[pg_operator(immutable, parallel_safe)] #[opname(->)] -pub fn arrow_stats1d_sum(sketch: StatsSummary1D, _accessor: AccessorSum) -> Option { +pub fn arrow_stats1d_sum<'a>( + sketch: StatsSummary1D<'a>, + _accessor: AccessorSum<'a>, +) -> Option { stats1d_sum(sketch) } #[pg_extern(name = "sum", strict, immutable, parallel_safe)] -pub(crate) fn stats1d_sum(summary: StatsSummary1D) -> Option { +pub(crate) fn stats1d_sum<'a>(summary: StatsSummary1D<'a>) -> Option { summary.to_internal().sum() } #[pg_operator(immutable, parallel_safe)] #[opname(->)] -pub fn arrow_stats1d_stddev( - sketch: Option, - accessor: AccessorStdDev, +pub fn arrow_stats1d_stddev<'a>( + sketch: Option>, + accessor: AccessorStdDev<'a>, ) -> Option { let method = String::from_utf8_lossy(accessor.bytes.as_slice()); stats1d_stddev(sketch, &*method) } #[pg_extern(name = "stddev", immutable, parallel_safe)] -fn stats1d_stddev( - summary: Option, +fn stats1d_stddev<'a>( + summary: Option>, method: default!(&str, "'sample'"), ) -> Option { match method_kind(method) { @@ -737,17 +743,17 @@ fn stats1d_stddev( #[pg_operator(immutable, parallel_safe)] #[opname(->)] -pub fn arrow_stats1d_variance( - sketch: Option, - accessor: AccessorVariance, +pub fn arrow_stats1d_variance<'a>( + sketch: Option>, + accessor: AccessorVariance<'a>, ) -> Option { let method = String::from_utf8_lossy(accessor.bytes.as_slice()); stats1d_variance(sketch, &*method) } #[pg_extern(name = "variance", immutable, parallel_safe)] -fn stats1d_variance( - summary: Option, +fn stats1d_variance<'a>( + summary: Option>, method: default!(&str, "'sample'"), ) -> Option { match method_kind(method) { @@ -758,13 +764,19 @@ fn stats1d_variance( #[pg_operator(immutable, parallel_safe)] #[opname(->)] -pub fn arrow_stats1d_skewness(sketch: StatsSummary1D, accessor: AccessorSkewness) -> Option { +pub fn arrow_stats1d_skewness<'a>( + sketch: StatsSummary1D<'a>, + accessor: AccessorSkewness<'a>, +) -> Option { let method = String::from_utf8_lossy(accessor.bytes.as_slice()); stats1d_skewness(sketch, &*method) } #[pg_extern(name = "skewness", immutable, parallel_safe)] -fn stats1d_skewness(summary: StatsSummary1D, method: default!(&str, "'sample'")) -> Option { +fn stats1d_skewness<'a>( + summary: StatsSummary1D<'a>, + method: default!(&str, "'sample'"), +) -> Option { match method_kind(method) { Population => summary.to_internal().skewness_pop(), Sample => summary.to_internal().skewness_samp(), @@ -773,13 +785,19 @@ fn stats1d_skewness(summary: StatsSummary1D, method: default!(&str, "'sample'")) #[pg_operator(immutable, parallel_safe)] #[opname(->)] -pub fn arrow_stats1d_kurtosis(sketch: StatsSummary1D, accessor: AccessorKurtosis) -> Option { +pub fn arrow_stats1d_kurtosis<'a>( + sketch: StatsSummary1D<'a>, + accessor: AccessorKurtosis<'a>, +) -> Option { let method = String::from_utf8_lossy(accessor.bytes.as_slice()); stats1d_kurtosis(sketch, &*method) } #[pg_extern(name = "kurtosis", immutable, parallel_safe)] -fn stats1d_kurtosis(summary: StatsSummary1D, method: default!(&str, "'sample'")) -> Option { +fn stats1d_kurtosis<'a>( + summary: StatsSummary1D<'a>, + method: default!(&str, "'sample'"), +) -> Option { match method_kind(method) { Population => summary.to_internal().kurtosis_pop(), Sample => summary.to_internal().kurtosis_samp(), @@ -788,72 +806,87 @@ fn stats1d_kurtosis(summary: StatsSummary1D, method: default!(&str, "'sample'")) #[pg_operator(immutable, parallel_safe)] #[opname(->)] -pub fn arrow_stats1d_num_vals(sketch: StatsSummary1D, _accessor: AccessorNumVals) -> i64 { +pub fn arrow_stats1d_num_vals<'a>( + sketch: StatsSummary1D<'a>, + _accessor: AccessorNumVals<'a>, +) -> i64 { stats1d_num_vals(sketch) } #[pg_extern(name = "num_vals", strict, immutable, parallel_safe)] -fn stats1d_num_vals(summary: StatsSummary1D) -> i64 { +fn stats1d_num_vals<'a>(summary: StatsSummary1D<'a>) -> i64 { summary.to_internal().count() } #[pg_operator(immutable, parallel_safe)] #[opname(->)] -pub fn arrow_stats2d_average_x(sketch: StatsSummary2D, _accessor: AccessorAverageX) -> Option { +pub fn arrow_stats2d_average_x<'a>( + sketch: StatsSummary2D<'a>, + _accessor: AccessorAverageX<'a>, +) -> Option { stats2d_average_x(sketch) } #[pg_extern(name = "average_x", strict, immutable, parallel_safe)] -fn stats2d_average_x(summary: StatsSummary2D) -> Option { +fn stats2d_average_x<'a>(summary: StatsSummary2D<'a>) -> Option { Some(summary.to_internal().avg()?.x) } #[pg_operator(immutable, parallel_safe)] #[opname(->)] -pub fn arrow_stats2d_average_y(sketch: StatsSummary2D, _accessor: AccessorAverageY) -> Option { +pub fn arrow_stats2d_average_y<'a>( + sketch: StatsSummary2D<'a>, + _accessor: AccessorAverageY<'a>, +) -> Option { stats2d_average_y(sketch) } #[pg_extern(name = "average_y", strict, immutable, parallel_safe)] -fn stats2d_average_y(summary: StatsSummary2D) -> Option { +fn stats2d_average_y<'a>(summary: StatsSummary2D<'a>) -> Option { Some(summary.to_internal().avg()?.y) } #[pg_operator(immutable, parallel_safe)] #[opname(->)] -pub fn arrow_stats2d_sum_x(sketch: StatsSummary2D, _accessor: AccessorSumX) -> Option { +pub fn arrow_stats2d_sum_x<'a>( + sketch: StatsSummary2D<'a>, + _accessor: AccessorSumX<'a>, +) -> Option { stats2d_sum_x(sketch) } #[pg_extern(name = "sum_x", strict, immutable, parallel_safe)] -fn stats2d_sum_x(summary: StatsSummary2D) -> Option { +fn stats2d_sum_x<'a>(summary: StatsSummary2D<'a>) -> Option { Some(summary.to_internal().sum()?.x) } #[pg_operator(immutable, parallel_safe)] #[opname(->)] -pub fn arrow_stats2d_sum_y(sketch: StatsSummary2D, _accessor: AccessorSumY) -> Option { +pub fn arrow_stats2d_sum_y<'a>( + sketch: StatsSummary2D<'a>, + _accessor: AccessorSumY<'a>, +) -> Option { stats2d_sum_y(sketch) } #[pg_extern(name = "sum_y", strict, immutable, parallel_safe)] -fn stats2d_sum_y(summary: StatsSummary2D) -> Option { +fn stats2d_sum_y<'a>(summary: StatsSummary2D<'a>) -> Option { Some(summary.to_internal().sum()?.y) } #[pg_operator(immutable, parallel_safe)] #[opname(->)] -pub fn arrow_stats2d_stdddev_x( - sketch: Option, - accessor: AccessorStdDevX, +pub fn arrow_stats2d_stdddev_x<'a>( + sketch: Option>, + accessor: AccessorStdDevX<'a>, ) -> Option { let method = String::from_utf8_lossy(accessor.bytes.as_slice()); stats2d_stddev_x(sketch, &*method) } #[pg_extern(name = "stddev_x", immutable, parallel_safe)] -fn stats2d_stddev_x( - summary: Option, +fn stats2d_stddev_x<'a>( + summary: Option>, method: default!(&str, "'sample'"), ) -> Option { match method_kind(method) { @@ -864,17 +897,17 @@ fn stats2d_stddev_x( #[pg_operator(immutable, parallel_safe)] #[opname(->)] -pub fn arrow_stats2d_stdddev_y( - sketch: Option, - accessor: AccessorStdDevY, +pub fn arrow_stats2d_stdddev_y<'a>( + sketch: Option>, + accessor: AccessorStdDevY<'a>, ) -> Option { let method = String::from_utf8_lossy(accessor.bytes.as_slice()); stats2d_stddev_y(sketch, &*method) } #[pg_extern(name = "stddev_y", immutable, parallel_safe)] -fn stats2d_stddev_y( - summary: Option, +fn stats2d_stddev_y<'a>( + summary: Option>, method: default!(&str, "'sample'"), ) -> Option { match method_kind(method) { @@ -885,17 +918,17 @@ fn stats2d_stddev_y( #[pg_operator(immutable, parallel_safe)] #[opname(->)] -pub fn arrow_stats2d_variance_x( - sketch: Option, - accessor: AccessorVarianceX, +pub fn arrow_stats2d_variance_x<'a>( + sketch: Option>, + accessor: AccessorVarianceX<'a>, ) -> Option { let method = String::from_utf8_lossy(accessor.bytes.as_slice()); stats2d_variance_x(sketch, &*method) } #[pg_extern(name = "variance_x", immutable, parallel_safe)] -fn stats2d_variance_x( - summary: Option, +fn stats2d_variance_x<'a>( + summary: Option>, method: default!(&str, "'sample'"), ) -> Option { match method_kind(method) { @@ -906,17 +939,17 @@ fn stats2d_variance_x( #[pg_operator(immutable, parallel_safe)] #[opname(->)] -pub fn arrow_stats2d_variance_y( - sketch: Option, - accessor: AccessorVarianceY, +pub fn arrow_stats2d_variance_y<'a>( + sketch: Option>, + accessor: AccessorVarianceY<'a>, ) -> Option { let method = String::from_utf8_lossy(accessor.bytes.as_slice()); stats2d_variance_y(sketch, &*method) } #[pg_extern(name = "variance_y", immutable, parallel_safe)] -fn stats2d_variance_y( - summary: Option, +fn stats2d_variance_y<'a>( + summary: Option>, method: default!(&str, "'sample'"), ) -> Option { match method_kind(method) { @@ -927,16 +960,19 @@ fn stats2d_variance_y( #[pg_operator(immutable, parallel_safe)] #[opname(->)] -pub fn arrow_stats2d_skewness_x( - sketch: StatsSummary2D, - accessor: AccessorSkewnessX, +pub fn arrow_stats2d_skewness_x<'a>( + sketch: StatsSummary2D<'a>, + accessor: AccessorSkewnessX<'a>, ) -> Option { let method = String::from_utf8_lossy(accessor.bytes.as_slice()); stats2d_skewness_x(sketch, &*method) } #[pg_extern(name = "skewness_x", strict, immutable, parallel_safe)] -fn stats2d_skewness_x(summary: StatsSummary2D, method: default!(&str, "'sample'")) -> Option { +fn stats2d_skewness_x<'a>( + summary: StatsSummary2D<'a>, + method: default!(&str, "'sample'"), +) -> Option { match method_kind(method) { Population => Some(summary.to_internal().skewness_pop()?.x), Sample => Some(summary.to_internal().skewness_samp()?.x), @@ -945,16 +981,19 @@ fn stats2d_skewness_x(summary: StatsSummary2D, method: default!(&str, "'sample'" #[pg_operator(immutable, parallel_safe)] #[opname(->)] -pub fn arrow_stats2d_skewness_y( - sketch: StatsSummary2D, - accessor: AccessorSkewnessY, +pub fn arrow_stats2d_skewness_y<'a>( + sketch: StatsSummary2D<'a>, + accessor: AccessorSkewnessY<'a>, ) -> Option { let method = String::from_utf8_lossy(accessor.bytes.as_slice()); stats2d_skewness_y(sketch, &*method) } #[pg_extern(name = "skewness_y", strict, immutable, parallel_safe)] -fn stats2d_skewness_y(summary: StatsSummary2D, method: default!(&str, "'sample'")) -> Option { +fn stats2d_skewness_y<'a>( + summary: StatsSummary2D<'a>, + method: default!(&str, "'sample'"), +) -> Option { match method_kind(method) { Population => Some(summary.to_internal().skewness_pop()?.y), Sample => Some(summary.to_internal().skewness_samp()?.y), @@ -963,16 +1002,19 @@ fn stats2d_skewness_y(summary: StatsSummary2D, method: default!(&str, "'sample'" #[pg_operator(immutable, parallel_safe)] #[opname(->)] -pub fn arrow_stats2d_kurtosis_x( - sketch: StatsSummary2D, - accessor: AccessorKurtosisX, +pub fn arrow_stats2d_kurtosis_x<'a>( + sketch: StatsSummary2D<'a>, + accessor: AccessorKurtosisX<'a>, ) -> Option { let method = String::from_utf8_lossy(accessor.bytes.as_slice()); stats2d_kurtosis_x(sketch, &*method) } #[pg_extern(name = "kurtosis_x", strict, immutable, parallel_safe)] -fn stats2d_kurtosis_x(summary: StatsSummary2D, method: default!(&str, "'sample'")) -> Option { +fn stats2d_kurtosis_x<'a>( + summary: StatsSummary2D<'a>, + method: default!(&str, "'sample'"), +) -> Option { match method_kind(method) { Population => Some(summary.to_internal().kurtosis_pop()?.x), Sample => Some(summary.to_internal().kurtosis_samp()?.x), @@ -981,16 +1023,19 @@ fn stats2d_kurtosis_x(summary: StatsSummary2D, method: default!(&str, "'sample'" #[pg_operator(immutable, parallel_safe)] #[opname(->)] -pub fn arrow_stats2d_kurtosis_y( - sketch: StatsSummary2D, - accessor: AccessorKurtosisY, +pub fn arrow_stats2d_kurtosis_y<'a>( + sketch: StatsSummary2D<'a>, + accessor: AccessorKurtosisY<'a>, ) -> Option { let method = String::from_utf8_lossy(accessor.bytes.as_slice()); stats2d_kurtosis_y(sketch, &*method) } #[pg_extern(name = "kurtosis_y", strict, immutable, parallel_safe)] -fn stats2d_kurtosis_y(summary: StatsSummary2D, method: default!(&str, "'sample'")) -> Option { +fn stats2d_kurtosis_y<'a>( + summary: StatsSummary2D<'a>, + method: default!(&str, "'sample'"), +) -> Option { match method_kind(method) { Population => Some(summary.to_internal().kurtosis_pop()?.y), Sample => Some(summary.to_internal().kurtosis_samp()?.y), @@ -999,89 +1044,101 @@ fn stats2d_kurtosis_y(summary: StatsSummary2D, method: default!(&str, "'sample'" #[pg_operator(immutable, parallel_safe)] #[opname(->)] -pub fn arrow_stats2d_num_vals(sketch: StatsSummary2D, _accessor: AccessorNumVals) -> i64 { +pub fn arrow_stats2d_num_vals<'a>( + sketch: StatsSummary2D<'a>, + _accessor: AccessorNumVals<'a>, +) -> i64 { stats2d_num_vals(sketch) } #[pg_extern(name = "num_vals", strict, immutable, parallel_safe)] -fn stats2d_num_vals(summary: StatsSummary2D) -> i64 { +fn stats2d_num_vals<'a>(summary: StatsSummary2D<'a>) -> i64 { summary.to_internal().count() } #[pg_operator(immutable, parallel_safe)] #[opname(->)] -pub fn arrow_stats2d_slope(sketch: StatsSummary2D, _accessor: AccessorSlope) -> Option { +pub fn arrow_stats2d_slope<'a>( + sketch: StatsSummary2D<'a>, + _accessor: AccessorSlope<'a>, +) -> Option { stats2d_slope(sketch) } #[pg_extern(name = "slope", strict, immutable, parallel_safe)] -fn stats2d_slope(summary: StatsSummary2D) -> Option { +fn stats2d_slope<'a>(summary: StatsSummary2D<'a>) -> Option { summary.to_internal().slope() } #[pg_operator(immutable, parallel_safe)] #[opname(->)] -pub fn arrow_stats2d_corr(sketch: StatsSummary2D, _accessor: AccessorCorr) -> Option { +pub fn arrow_stats2d_corr<'a>( + sketch: StatsSummary2D<'a>, + _accessor: AccessorCorr<'a>, +) -> Option { stats2d_corr(sketch) } #[pg_extern(name = "corr", strict, immutable, parallel_safe)] -fn stats2d_corr(summary: StatsSummary2D) -> Option { +fn stats2d_corr<'a>(summary: StatsSummary2D<'a>) -> Option { summary.to_internal().corr() } #[pg_operator(immutable, parallel_safe)] #[opname(->)] -pub fn arrow_stats2d_intercept( - sketch: StatsSummary2D, - _accessor: AccessorIntercept, +pub fn arrow_stats2d_intercept<'a>( + sketch: StatsSummary2D<'a>, + _accessor: AccessorIntercept<'a>, ) -> Option { stats2d_intercept(sketch) } #[pg_extern(name = "intercept", strict, immutable, parallel_safe)] -fn stats2d_intercept(summary: StatsSummary2D) -> Option { +fn stats2d_intercept<'a>(summary: StatsSummary2D<'a>) -> Option { summary.to_internal().intercept() } #[pg_operator(immutable, parallel_safe)] #[opname(->)] -pub fn arrow_stats2d_x_intercept( - sketch: StatsSummary2D, - _accessor: AccessorXIntercept, +pub fn arrow_stats2d_x_intercept<'a>( + sketch: StatsSummary2D<'a>, + _accessor: AccessorXIntercept<'a>, ) -> Option { stats2d_x_intercept(sketch) } #[pg_extern(name = "x_intercept", strict, immutable, parallel_safe)] -fn stats2d_x_intercept(summary: StatsSummary2D) -> Option { +fn stats2d_x_intercept<'a>(summary: StatsSummary2D<'a>) -> Option { summary.to_internal().x_intercept() } #[pg_operator(immutable, parallel_safe)] #[opname(->)] -pub fn arrow_stats2d_determination_coeff( - sketch: StatsSummary2D, - _accessor: AccessorDeterminationCoeff, +pub fn arrow_stats2d_determination_coeff<'a>( + sketch: StatsSummary2D<'a>, + _accessor: AccessorDeterminationCoeff<'a>, ) -> Option { stats2d_determination_coeff(sketch) } #[pg_extern(name = "determination_coeff", strict, immutable, parallel_safe)] -fn stats2d_determination_coeff(summary: StatsSummary2D) -> Option { +fn stats2d_determination_coeff<'a>(summary: StatsSummary2D<'a>) -> Option { summary.to_internal().determination_coeff() } #[pg_operator(immutable, parallel_safe)] #[opname(->)] -pub fn arrow_stats2d_covar(sketch: Option, accessor: AccessorCovar) -> Option { +pub fn arrow_stats2d_covar<'a>( + sketch: Option>, + accessor: AccessorCovar<'a>, +) -> Option { let method = String::from_utf8_lossy(accessor.bytes.as_slice()); stats2d_covar(sketch, &*method) } #[pg_extern(name = "covariance", immutable, parallel_safe)] -fn stats2d_covar( - summary: Option, +fn stats2d_covar<'a>( + summary: Option>, method: default!(&str, "'sample'"), ) -> Option { match method_kind(method) { @@ -1328,7 +1385,7 @@ mod tests { let control = state.unwrap(); let buffer = stats1d_trans_serialize(Inner::from(control.clone()).internal().unwrap()); - let buffer = pgx::varlena::varlena_to_byte_slice(buffer.0 as *mut pg_sys::varlena); + let buffer = pgx::varlena::varlena_to_byte_slice(buffer.0.cast_mut_ptr()); let expected = [ 1, 1, 1, 5, 0, 0, 0, 0, 0, 0, 0, 144, 194, 245, 40, 92, 143, 73, 64, 100, 180, 142, @@ -1339,7 +1396,7 @@ mod tests { let expected = pgx::varlena::rust_byte_slice_to_bytea(&expected); let new_state = - stats1d_trans_deserialize_inner(bytea(&*expected as *const pg_sys::varlena as _)); + stats1d_trans_deserialize_inner(bytea(pgx::Datum::from(expected.as_ptr()))); assert_eq!(&*new_state, &*control); } diff --git a/extension/src/tdigest.rs b/extension/src/tdigest.rs index 9083e81b..3a2aa375 100644 --- a/extension/src/tdigest.rs +++ b/extension/src/tdigest.rs @@ -355,25 +355,31 @@ extension_sql!( #[pg_operator(immutable, parallel_safe)] #[opname(->)] -pub fn arrow_tdigest_approx_percentile(sketch: TDigest, accessor: AccessorApproxPercentile) -> f64 { +pub fn arrow_tdigest_approx_percentile<'a>( + sketch: TDigest<'a>, + accessor: AccessorApproxPercentile<'a>, +) -> f64 { tdigest_quantile(accessor.percentile, sketch) } // Approximate the value at the given quantile (0.0-1.0) #[pg_extern(immutable, parallel_safe, name = "approx_percentile")] -pub fn tdigest_quantile(quantile: f64, digest: TDigest) -> f64 { +pub fn tdigest_quantile<'a>(quantile: f64, digest: TDigest<'a>) -> f64 { digest.to_internal_tdigest().estimate_quantile(quantile) } #[pg_operator(immutable, parallel_safe)] #[opname(->)] -pub fn arrow_tdigest_approx_rank(sketch: TDigest, accessor: AccessorApproxPercentileRank) -> f64 { +pub fn arrow_tdigest_approx_rank<'a>( + sketch: TDigest<'a>, + accessor: AccessorApproxPercentileRank<'a>, +) -> f64 { tdigest_quantile_at_value(accessor.value, sketch) } // Approximate the quantile at the given value #[pg_extern(immutable, parallel_safe, name = "approx_percentile_rank")] -pub fn tdigest_quantile_at_value(value: f64, digest: TDigest) -> f64 { +pub fn tdigest_quantile_at_value<'a>(value: f64, digest: TDigest<'a>) -> f64 { digest .to_internal_tdigest() .estimate_quantile_at_value(value) @@ -381,50 +387,50 @@ pub fn tdigest_quantile_at_value(value: f64, digest: TDigest) -> f64 { #[pg_operator(immutable, parallel_safe)] #[opname(->)] -pub fn arrow_tdigest_num_vals(sketch: TDigest, _accessor: AccessorNumVals) -> f64 { +pub fn arrow_tdigest_num_vals<'a>(sketch: TDigest<'a>, _accessor: AccessorNumVals<'a>) -> f64 { tdigest_count(sketch) } // Number of elements from which the digest was built. #[pg_extern(immutable, parallel_safe, name = "num_vals")] -pub fn tdigest_count(digest: TDigest) -> f64 { +pub fn tdigest_count<'a>(digest: TDigest<'a>) -> f64 { digest.count as f64 } #[pg_operator(immutable, parallel_safe)] #[opname(->)] -pub fn arrow_tdigest_min(sketch: TDigest, _accessor: AccessorMinVal) -> f64 { +pub fn arrow_tdigest_min<'a>(sketch: TDigest<'a>, _accessor: AccessorMinVal<'a>) -> f64 { tdigest_min(sketch) } // Minimum value entered in the digest. #[pg_extern(immutable, parallel_safe, name = "min_val")] -pub fn tdigest_min(digest: TDigest) -> f64 { +pub fn tdigest_min<'a>(digest: TDigest<'a>) -> f64 { digest.min } #[pg_operator(immutable, parallel_safe)] #[opname(->)] -pub fn arrow_tdigest_max(sketch: TDigest, _accessor: AccessorMaxVal) -> f64 { +pub fn arrow_tdigest_max<'a>(sketch: TDigest<'a>, _accessor: AccessorMaxVal<'a>) -> f64 { tdigest_max(sketch) } // Maximum value entered in the digest. #[pg_extern(immutable, parallel_safe, name = "max_val")] -pub fn tdigest_max(digest: TDigest) -> f64 { +pub fn tdigest_max<'a>(digest: TDigest<'a>) -> f64 { digest.max } #[pg_operator(immutable, parallel_safe)] #[opname(->)] -pub fn arrow_tdigest_mean(sketch: TDigest, _accessor: AccessorMean) -> f64 { +pub fn arrow_tdigest_mean<'a>(sketch: TDigest<'a>, _accessor: AccessorMean<'a>) -> f64 { tdigest_mean(sketch) } // Average of all the values entered in the digest. // Note that this is not an approximation, though there may be loss of precision. #[pg_extern(immutable, parallel_safe, name = "mean")] -pub fn tdigest_mean(digest: TDigest) -> f64 { +pub fn tdigest_mean<'a>(digest: TDigest<'a>) -> f64 { if digest.count > 0 { digest.sum / digest.count as f64 } else { @@ -636,7 +642,7 @@ mod tests { let mut control = state.unwrap(); let buffer = tdigest_serialize(Inner::from(control.clone()).internal().unwrap()); - let buffer = pgx::varlena::varlena_to_byte_slice(buffer.0 as *mut pg_sys::varlena); + let buffer = pgx::varlena::varlena_to_byte_slice(buffer.0.cast_mut_ptr()); let expected = [ 1, 1, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 69, 192, 1, 0, 0, 0, 0, 0, 0, 0, @@ -649,8 +655,7 @@ mod tests { assert_eq!(buffer, expected); let expected = pgx::varlena::rust_byte_slice_to_bytea(&expected); - let new_state = - tdigest_deserialize_inner(bytea(&*expected as *const pg_sys::varlena as _)); + let new_state = tdigest_deserialize_inner(bytea(pgx::Datum::from(expected.as_ptr()))); control.digest(); // Serialized form is always digested assert_eq!(&*new_state, &*control); diff --git a/extension/src/time_vector.rs b/extension/src/time_vector.rs index d88a42c4..b6c0ad60 100644 --- a/extension/src/time_vector.rs +++ b/extension/src/time_vector.rs @@ -1,9 +1,8 @@ #![allow(clippy::identity_op)] // clippy gets confused by pg_type! enums -use pgx::*; +use pgx::{iter::TableIterator, *}; use crate::{ - accessors::AccessorUnnest, aggregate_utils::in_aggregate_context, build, palloc::{Inner, Internal, InternalAsValue, ToInternal}, @@ -106,22 +105,24 @@ pub static TIMEVECTOR_OID: once_cell::sync::Lazy = once_cell::sync::Lazy::new(Timevector_TSTZ_F64::type_oid); #[pg_extern(immutable, parallel_safe)] -pub fn unnest( - series: Timevector_TSTZ_F64<'_>, -) -> impl std::iter::Iterator + '_ -{ - series - .into_iter() - .map(|points| (points.ts.into(), points.val)) +pub fn unnest<'a, 'b>( + series: Timevector_TSTZ_F64<'a>, +) -> TableIterator<'b, (name!(time, crate::raw::TimestampTz), name!(value, f64))> { + TableIterator::new( + series + .into_iter() + .map(|points| (points.ts.into(), points.val)) + .collect::>() + .into_iter(), + ) } #[pg_operator(immutable, parallel_safe)] #[opname(->)] pub fn arrow_timevector_unnest<'a>( series: Timevector_TSTZ_F64<'a>, - _accessor: AccessorUnnest, -) -> impl std::iter::Iterator + 'a -{ + _accessor: crate::accessors::AccessorUnnest<'a>, +) -> TableIterator<'a, (name!(time, crate::raw::TimestampTz), name!(value, f64))> { unnest(series) } @@ -199,9 +200,9 @@ pub fn timevector_trans_inner( } #[pg_extern(immutable, parallel_safe)] -pub fn timevector_tstz_f64_compound_trans( +pub fn timevector_tstz_f64_compound_trans<'a>( state: Internal, - series: Option, + series: Option>, fcinfo: pg_sys::FunctionCallInfo, ) -> Option { inner_compound_trans(unsafe { state.to_inner() }, series, fcinfo).internal() diff --git a/extension/src/time_vector/pipeline.rs b/extension/src/time_vector/pipeline.rs index 9b780d14..8848c1cc 100644 --- a/extension/src/time_vector/pipeline.rs +++ b/extension/src/time_vector/pipeline.rs @@ -112,9 +112,9 @@ pub mod toolkit_experimental { #[pg_operator(immutable, parallel_safe)] #[opname(->)] -pub fn arrow_run_pipeline( - timevector: Timevector_TSTZ_F64, - pipeline: toolkit_experimental::UnstableTimevectorPipeline, +pub fn arrow_run_pipeline<'a>( + timevector: Timevector_TSTZ_F64<'a>, + pipeline: toolkit_experimental::UnstableTimevectorPipeline<'a>, ) -> Timevector_TSTZ_F64<'static> { run_pipeline_elements(timevector, pipeline.elements.iter()).in_current_context() } @@ -166,7 +166,8 @@ pub fn arrow_add_unstable_element<'p>( )] pub unsafe fn pipeline_support(input: Internal) -> Internal { pipeline_support_helper(input, |old_pipeline, new_element| { - let new_element = UnstableTimevectorPipeline::from_datum(new_element, false, 0).unwrap(); + let new_element = + UnstableTimevectorPipeline::from_polymorphic_datum(new_element, false, 0).unwrap(); arrow_add_unstable_element(old_pipeline, new_element) .into_datum() .unwrap() @@ -180,7 +181,7 @@ pub(crate) unsafe fn pipeline_support_helper( use std::mem::{size_of, MaybeUninit}; let input = input.unwrap().unwrap(); - let input: *mut pg_sys::Node = input as _; + let input: *mut pg_sys::Node = input.cast_mut_ptr(); if !pgx::is_a(input, pg_sys::NodeTag_T_SupportRequestSimplify) { return no_change(); } @@ -252,7 +253,8 @@ pub(crate) unsafe fn pipeline_support_helper( let new_element_const: *mut pg_sys::Const = arg2.cast(); let old_pipeline = - UnstableTimevectorPipeline::from_datum((*old_const).constvalue, false, 0).unwrap(); + UnstableTimevectorPipeline::from_polymorphic_datum((*old_const).constvalue, false, 0) + .unwrap(); let new_pipeline = make_new_pipeline(old_pipeline, (*new_element_const).constvalue); let new_const = pg_sys::palloc(size_of::()).cast(); @@ -266,13 +268,13 @@ pub(crate) unsafe fn pipeline_support_helper( new_executor_args.push(new_const.cast()); (*new_executor).args = new_executor_args.into_pg(); - Internal::from(Some(new_executor as pg_sys::Datum)) + Internal::from(Some(pgx::Datum::from(new_executor))) } // support functions are spec'd as returning NULL pointer if no simplification // can be made fn no_change() -> pgx::Internal { - Internal::from(Some(std::ptr::null_mut::() as pg_sys::Datum)) + Internal::from(Some(pgx::Datum::from(std::ptr::null_mut::()))) } // using this instead of pg_operator since the latter doesn't support schemas yet diff --git a/extension/src/time_vector/pipeline/aggregation.rs b/extension/src/time_vector/pipeline/aggregation.rs index f6e239da..bf2a46fa 100644 --- a/extension/src/time_vector/pipeline/aggregation.rs +++ b/extension/src/time_vector/pipeline/aggregation.rs @@ -103,9 +103,9 @@ pub mod toolkit_experimental { #[pg_operator(immutable, parallel_safe)] #[opname(->)] -pub fn arrow_run_pipeline_then_stats_agg( - mut timevector: Timevector_TSTZ_F64, - pipeline: toolkit_experimental::PipelineThenStatsAgg, +pub fn arrow_run_pipeline_then_stats_agg<'a>( + mut timevector: Timevector_TSTZ_F64<'a>, + pipeline: toolkit_experimental::PipelineThenStatsAgg<'a>, ) -> StatsSummary1D<'static> { if timevector.has_nulls() { panic!("Unable to compute stats aggregate over timevector containing nulls"); @@ -163,7 +163,8 @@ pub fn pipeline_stats_agg() -> toolkit_experimental::PipelineThenStatsAgg<'stati #[pg_extern(immutable, parallel_safe, schema = "toolkit_experimental")] pub unsafe fn pipeline_stats_agg_support(input: Internal) -> Internal { pipeline_support_helper(input, |old_pipeline, new_element| { - let new_element = PipelineThenStatsAgg::from_datum(new_element, false, 0).unwrap(); + let new_element = + PipelineThenStatsAgg::from_polymorphic_datum(new_element, false, 0).unwrap(); finalize_with_stats_agg(old_pipeline, new_element) .into_datum() .unwrap() @@ -187,7 +188,9 @@ ALTER FUNCTION "arrow_run_pipeline_then_stats_agg" SUPPORT toolkit_experimental. name = "sum_cast", schema = "toolkit_experimental" )] -pub fn sum_pipeline_element(accessor: AccessorSum) -> toolkit_experimental::PipelineThenSum { +pub fn sum_pipeline_element<'a>( + accessor: AccessorSum<'a>, +) -> toolkit_experimental::PipelineThenSum { let _ = accessor; build! { PipelineThenSum { @@ -209,9 +212,9 @@ extension_sql!( #[pg_operator(immutable, parallel_safe)] #[opname(->)] -pub fn arrow_pipeline_then_sum( - timevector: Timevector_TSTZ_F64, - pipeline: toolkit_experimental::PipelineThenSum, +pub fn arrow_pipeline_then_sum<'a>( + timevector: Timevector_TSTZ_F64<'a>, + pipeline: toolkit_experimental::PipelineThenSum<'a>, ) -> Option { let pipeline = pipeline.0; let pipeline = build! { @@ -255,7 +258,7 @@ pub fn finalize_with_sum<'e>( #[pg_extern(immutable, parallel_safe, schema = "toolkit_experimental")] pub unsafe fn pipeline_sum_support(input: Internal) -> Internal { pipeline_support_helper(input, |old_pipeline, new_element| { - let new_element = PipelineThenSum::from_datum(new_element, false, 0).unwrap(); + let new_element = PipelineThenSum::from_polymorphic_datum(new_element, false, 0).unwrap(); finalize_with_sum(old_pipeline, new_element) .into_datum() .unwrap() @@ -271,8 +274,8 @@ ALTER FUNCTION "arrow_pipeline_then_sum" SUPPORT toolkit_experimental.pipeline_s ); #[pg_extern(immutable, parallel_safe, schema = "toolkit_experimental")] -pub fn average_pipeline_element( - accessor: AccessorAverage, +pub fn average_pipeline_element<'a>( + accessor: AccessorAverage<'a>, ) -> toolkit_experimental::PipelineThenAverage { let _ = accessor; build! { @@ -299,9 +302,9 @@ extension_sql!( #[pg_operator(immutable, parallel_safe)] #[opname(->)] -pub fn arrow_pipeline_then_average( - timevector: Timevector_TSTZ_F64, - pipeline: toolkit_experimental::PipelineThenAverage, +pub fn arrow_pipeline_then_average<'a>( + timevector: Timevector_TSTZ_F64<'a>, + pipeline: toolkit_experimental::PipelineThenAverage<'a>, ) -> Option { let pipeline = pipeline.0; let pipeline = build! { @@ -345,7 +348,8 @@ pub fn finalize_with_average<'e>( #[pg_extern(immutable, parallel_safe, schema = "toolkit_experimental")] pub unsafe fn pipeline_average_support(input: Internal) -> Internal { pipeline_support_helper(input, |old_pipeline, new_element| { - let new_element = PipelineThenAverage::from_datum(new_element, false, 0).unwrap(); + let new_element = + PipelineThenAverage::from_polymorphic_datum(new_element, false, 0).unwrap(); finalize_with_average(old_pipeline, new_element) .into_datum() .unwrap() @@ -366,8 +370,8 @@ ALTER FUNCTION "arrow_pipeline_then_average" SUPPORT toolkit_experimental.pipeli name = "num_vals_cast", schema = "toolkit_experimental" )] -pub fn num_vals_pipeline_element( - accessor: AccessorNumVals, +pub fn num_vals_pipeline_element<'a>( + accessor: AccessorNumVals<'a>, ) -> toolkit_experimental::PipelineThenNumVals { let _ = accessor; build! { @@ -394,9 +398,9 @@ extension_sql!( #[pg_operator(immutable, parallel_safe)] #[opname(->)] -pub fn arrow_pipeline_then_num_vals( - timevector: Timevector_TSTZ_F64, - pipeline: toolkit_experimental::PipelineThenNumVals, +pub fn arrow_pipeline_then_num_vals<'a>( + timevector: Timevector_TSTZ_F64<'a>, + pipeline: toolkit_experimental::PipelineThenNumVals<'a>, ) -> i64 { run_pipeline_elements(timevector, pipeline.elements.iter()).num_vals() as _ } @@ -432,7 +436,8 @@ pub fn finalize_with_num_vals<'e>( #[pg_extern(immutable, parallel_safe, schema = "toolkit_experimental")] pub unsafe fn pipeline_num_vals_support(input: Internal) -> Internal { pipeline_support_helper(input, |old_pipeline, new_element| { - let new_element = PipelineThenNumVals::from_datum(new_element, false, 0).unwrap(); + let new_element = + PipelineThenNumVals::from_polymorphic_datum(new_element, false, 0).unwrap(); finalize_with_num_vals(old_pipeline, new_element) .into_datum() .unwrap() @@ -450,9 +455,9 @@ ALTER FUNCTION "arrow_pipeline_then_num_vals" SUPPORT toolkit_experimental.pipel // TODO support gauge #[pg_operator(immutable, parallel_safe)] #[opname(->)] -pub fn arrow_run_pipeline_then_counter_agg( - mut timevector: Timevector_TSTZ_F64, - pipeline: toolkit_experimental::PipelineThenCounterAgg, +pub fn arrow_run_pipeline_then_counter_agg<'a>( + mut timevector: Timevector_TSTZ_F64<'a>, + pipeline: toolkit_experimental::PipelineThenCounterAgg<'a>, ) -> Option> { timevector = run_pipeline_elements(timevector, pipeline.elements.iter()); if timevector.num_points() == 0 { @@ -515,7 +520,8 @@ pub fn pipeline_counter_agg() -> toolkit_experimental::PipelineThenCounterAgg<'s #[pg_extern(immutable, parallel_safe, schema = "toolkit_experimental")] pub unsafe fn pipeline_counter_agg_support(input: Internal) -> Internal { pipeline_support_helper(input, |old_pipeline, new_element| { - let new_element = PipelineThenCounterAgg::from_datum(new_element, false, 0).unwrap(); + let new_element = + PipelineThenCounterAgg::from_polymorphic_datum(new_element, false, 0).unwrap(); finalize_with_counter_agg(old_pipeline, new_element) .into_datum() .unwrap() @@ -535,9 +541,9 @@ ALTER FUNCTION "arrow_run_pipeline_then_counter_agg" SUPPORT toolkit_experimenta #[pg_operator(immutable, parallel_safe)] #[opname(->)] -pub fn arrow_run_pipeline_then_hyperloglog( - mut timevector: Timevector_TSTZ_F64, - pipeline: toolkit_experimental::PipelineThenHyperLogLog, +pub fn arrow_run_pipeline_then_hyperloglog<'a>( + mut timevector: Timevector_TSTZ_F64<'a>, + pipeline: toolkit_experimental::PipelineThenHyperLogLog<'a>, ) -> HyperLogLog<'static> { timevector = run_pipeline_elements(timevector, pipeline.elements.iter()); HyperLogLog::build_from( @@ -598,7 +604,8 @@ pub fn pipeline_hyperloglog(size: i32) -> toolkit_experimental::PipelineThenHype #[pg_extern(immutable, parallel_safe, schema = "toolkit_experimental")] pub unsafe fn pipeline_hyperloglog_support(input: Internal) -> Internal { pipeline_support_helper(input, |old_pipeline, new_element| { - let new_element = PipelineThenHyperLogLog::from_datum(new_element, false, 0).unwrap(); + let new_element = + PipelineThenHyperLogLog::from_polymorphic_datum(new_element, false, 0).unwrap(); finalize_with_hyperloglog(old_pipeline, new_element) .into_datum() .unwrap() @@ -618,9 +625,9 @@ ALTER FUNCTION "arrow_run_pipeline_then_hyperloglog" SUPPORT toolkit_experimenta #[pg_operator(immutable, parallel_safe)] #[opname(->)] -pub fn arrow_run_pipeline_then_percentile_agg( - mut timevector: Timevector_TSTZ_F64, - pipeline: toolkit_experimental::PipelineThenPercentileAgg, +pub fn arrow_run_pipeline_then_percentile_agg<'a>( + mut timevector: Timevector_TSTZ_F64<'a>, + pipeline: toolkit_experimental::PipelineThenPercentileAgg<'a>, ) -> UddSketch<'static> { timevector = run_pipeline_elements(timevector, pipeline.elements.iter()); UddSketch::from_iter(timevector.into_iter().map(|p| p.val)) @@ -671,7 +678,8 @@ pub fn pipeline_percentile_agg() -> toolkit_experimental::PipelineThenPercentile #[pg_extern(immutable, parallel_safe, schema = "toolkit_experimental")] pub unsafe fn pipeline_percentile_agg_support(input: Internal) -> Internal { pipeline_support_helper(input, |old_pipeline, new_element| { - let new_element = PipelineThenPercentileAgg::from_datum(new_element, false, 0).unwrap(); + let new_element = + PipelineThenPercentileAgg::from_polymorphic_datum(new_element, false, 0).unwrap(); finalize_with_percentile_agg(old_pipeline, new_element) .into_datum() .unwrap() diff --git a/extension/src/time_vector/pipeline/expansion.rs b/extension/src/time_vector/pipeline/expansion.rs index 4752a20d..aaf7b34e 100644 --- a/extension/src/time_vector/pipeline/expansion.rs +++ b/extension/src/time_vector/pipeline/expansion.rs @@ -1,6 +1,6 @@ -use std::{iter::Iterator, mem::take}; +use std::mem::take; -use pgx::*; +use pgx::{iter::TableIterator, *}; use super::*; @@ -81,10 +81,10 @@ pub fn arrow_finalize_with_unnest<'p>( #[pg_operator(immutable, parallel_safe)] #[opname(->)] -pub fn arrow_run_pipeline_then_unnest( - timevector: Timevector_TSTZ_F64, - pipeline: toolkit_experimental::PipelineThenUnnest, -) -> impl Iterator { +pub fn arrow_run_pipeline_then_unnest<'a>( + timevector: Timevector_TSTZ_F64<'a>, + pipeline: toolkit_experimental::PipelineThenUnnest<'a>, +) -> TableIterator<'static, (name!(time, crate::raw::TimestampTz), name!(value, f64))> { let series = run_pipeline_elements(timevector, pipeline.elements.iter()) .0 .into_owned(); @@ -136,9 +136,9 @@ pub fn arrow_force_materialize<'e>( #[pg_operator(immutable, parallel_safe)] #[opname(->)] -pub fn arrow_run_pipeline_then_materialize( - timevector: Timevector_TSTZ_F64, - pipeline: toolkit_experimental::PipelineForceMaterialize, +pub fn arrow_run_pipeline_then_materialize<'a>( + timevector: Timevector_TSTZ_F64<'a>, + pipeline: toolkit_experimental::PipelineForceMaterialize<'a>, ) -> toolkit_experimental::Timevector_TSTZ_F64<'static> { run_pipeline_elements(timevector, pipeline.elements.iter()).in_current_context() } @@ -146,7 +146,8 @@ pub fn arrow_run_pipeline_then_materialize( #[pg_extern(immutable, parallel_safe, schema = "toolkit_experimental")] pub unsafe fn pipeline_materialize_support(input: pgx::Internal) -> pgx::Internal { pipeline_support_helper(input, |old_pipeline, new_element| { - let new_element = PipelineForceMaterialize::from_datum(new_element, false, 0).unwrap(); + let new_element = + PipelineForceMaterialize::from_polymorphic_datum(new_element, false, 0).unwrap(); arrow_force_materialize(old_pipeline, new_element) .into_datum() .unwrap() diff --git a/extension/src/time_vector/pipeline/fill_to.rs b/extension/src/time_vector/pipeline/fill_to.rs index 208f32bf..136aaa1e 100644 --- a/extension/src/time_vector/pipeline/fill_to.rs +++ b/extension/src/time_vector/pipeline/fill_to.rs @@ -60,7 +60,7 @@ pub fn fillto_pipeline_element<'e>( fill_method: String, ) -> toolkit_experimental::UnstableTimevectorPipeline<'e> { unsafe { - let interval = interval.0 as *const pg_sys::Interval; + let interval = interval.0.cast_mut_ptr::() as *const pg_sys::Interval; // TODO: store the postgres interval object and use postgres timestamp/interval functions let interval = ((*interval).month as i64 * 30 + (*interval).day as i64) * 24 * 60 * 60 * 1000000 diff --git a/extension/src/time_vector/pipeline/lambda.rs b/extension/src/time_vector/pipeline/lambda.rs index f099d850..9e43a6f5 100644 --- a/extension/src/time_vector/pipeline/lambda.rs +++ b/extension/src/time_vector/pipeline/lambda.rs @@ -1,6 +1,9 @@ use std::borrow::Cow; -use pgx::*; +use pgx::{ + iter::{SetOfIterator, TableIterator}, + *, +}; use super::*; @@ -70,8 +73,8 @@ impl<'a> LambdaData<'a> { // #[pg_extern(stable, parallel_safe, schema = "toolkit_experimental")] -pub fn bool_lambda( - lambda: toolkit_experimental::Lambda, +pub fn bool_lambda<'a>( + lambda: toolkit_experimental::Lambda<'a>, time: crate::raw::TimestampTz, value: f64, ) -> bool { @@ -87,8 +90,8 @@ pub fn bool_lambda( } #[pg_extern(stable, parallel_safe, schema = "toolkit_experimental")] -pub fn f64_lambda( - lambda: toolkit_experimental::Lambda, +pub fn f64_lambda<'a>( + lambda: toolkit_experimental::Lambda<'a>, time: crate::raw::TimestampTz, value: f64, ) -> f64 { @@ -101,8 +104,8 @@ pub fn f64_lambda( } #[pg_extern(stable, parallel_safe, schema = "toolkit_experimental")] -pub fn ttz_lambda( - lambda: toolkit_experimental::Lambda, +pub fn ttz_lambda<'a>( + lambda: toolkit_experimental::Lambda<'a>, time: crate::raw::TimestampTz, value: f64, ) -> crate::raw::TimestampTz { @@ -116,8 +119,8 @@ pub fn ttz_lambda( use crate::raw::Interval; #[pg_extern(stable, parallel_safe, schema = "toolkit_experimental")] -pub fn interval_lambda( - lambda: toolkit_experimental::Lambda, +pub fn interval_lambda<'a>( + lambda: toolkit_experimental::Lambda<'a>, time: crate::raw::TimestampTz, value: f64, ) -> Interval { @@ -126,15 +129,15 @@ pub fn interval_lambda( panic!("invalid return type, must return a INTERVAL") } let mut executor = ExpressionExecutor::new(&expression); - (executor.exec(value, time.into()).interval() as pg_sys::Datum).into() + pgx::Datum::from(executor.exec(value, time.into()).interval()).into() } #[pg_extern(stable, parallel_safe, schema = "toolkit_experimental")] -pub fn point_lambda( - lambda: toolkit_experimental::Lambda, +pub fn point_lambda<'a>( + lambda: toolkit_experimental::Lambda<'a>, time: crate::raw::TimestampTz, value: f64, -) -> impl std::iter::Iterator { +) -> TableIterator<'static, (name!(time, crate::raw::TimestampTz), name!(value, f64))> { let expression = lambda.parse(); if !expression.expr.ty_is_ts_point() { panic!("invalid return type, must return a (TimestampTZ, DOUBLE PRECISION)") @@ -145,15 +148,15 @@ pub fn point_lambda( Value::Tuple(columns) => columns, _ => unreachable!(), }; - Some((columns[0].time().into(), columns[1].float())).into_iter() + TableIterator::new(Some((columns[0].time().into(), columns[1].float())).into_iter()) } #[pg_extern(stable, parallel_safe, schema = "toolkit_experimental")] -pub fn trace_lambda( - lambda: toolkit_experimental::Lambda, +pub fn trace_lambda<'a>( + lambda: toolkit_experimental::Lambda<'a>, time: crate::raw::TimestampTz, value: f64, -) -> impl std::iter::Iterator { +) -> SetOfIterator<'static, String> { let expression = lambda.parse(); let mut trace: Vec<_> = vec![]; @@ -164,9 +167,13 @@ pub fn trace_lambda( let _ = executor.exec(value, time.into()); let col1_size = trace.iter().map(|(e, _)| e.len()).max().unwrap_or(0); - trace - .into_iter() - .map(move |(e, v)| format!("{:>width$}: {:?}", e, v, width = col1_size)) + SetOfIterator::new( + trace + .into_iter() + .map(move |(e, v)| format!("{:>width$}: {:?}", e, v, width = col1_size)) + .collect::>() + .into_iter(), + ) } // @@ -371,9 +378,10 @@ impl PartialOrd for Value { let res = pg_sys::DirectFunctionCall2Coll( Some(interval_cmp), pg_sys::InvalidOid, - *l0 as _, - *r0 as _, - ) as i32; + pgx::Datum::from(*l0), + pgx::Datum::from(*r0), + ) + .value() as i32; res.cmp(&0).into() }, (_, _) => None, @@ -401,10 +409,10 @@ impl PartialEq for Value { let res = pg_sys::DirectFunctionCall2Coll( Some(interval_eq), pg_sys::InvalidOid, - *l0 as _, - *r0 as _, + pgx::Datum::from(*l0), + pgx::Datum::from(*r0), ); - res != 0 + res.value() != 0 }, (_, _) => false, } diff --git a/extension/src/time_vector/pipeline/lambda/executor.rs b/extension/src/time_vector/pipeline/lambda/executor.rs index 990d4e71..9d1f523b 100644 --- a/extension/src/time_vector/pipeline/lambda/executor.rs +++ b/extension/src/time_vector/pipeline/lambda/executor.rs @@ -213,9 +213,10 @@ where pg_sys::DirectFunctionCall2Coll( Some($calc), pg_sys::InvalidOid, - left as _, - right as _, - ) as _ + pgx::Datum::from(left), + pgx::Datum::from(right), + ) + .cast_mut_ptr() }; assert!(!res.is_null()); Value::Interval(res) @@ -231,9 +232,10 @@ where pg_sys::DirectFunctionCall2Coll( Some($calc), pg_sys::InvalidOid, - left as _, + pgx::Datum::from(left), right.into_datum().unwrap(), - ) as _ + ) + .value() as _ }; assert!(!res.is_null()); Value::Interval(res) @@ -249,9 +251,10 @@ where pg_sys::DirectFunctionCall2Coll( Some($calc), pg_sys::InvalidOid, - left as _, - right as _, - ) as _ + pgx::Datum::from(left), + pgx::Datum::from(right), + ) + .value() as _ }; Value::Time(res) diff --git a/extension/src/time_vector/pipeline/lambda/parser.rs b/extension/src/time_vector/pipeline/lambda/parser.rs index 72112459..3ec34417 100644 --- a/extension/src/time_vector/pipeline/lambda/parser.rs +++ b/extension/src/time_vector/pipeline/lambda/parser.rs @@ -236,7 +236,7 @@ fn build_binary_op( add => { let result_type = return_ty!("+" (Double, Double) => Double, - (Time, Interval) => Time, + (Type::Time, Interval) => Type::Time, (Interval, Interval) => Interval, ); Binary(Plus, left.into(), right.into(), result_type) @@ -245,7 +245,7 @@ fn build_binary_op( subtract => { let result_type = return_ty!("-" (Double, Double) => Double, - (Time, Interval) => Time, + (Type::Time, Interval) => Type::Time, (Interval, Interval) => Interval, ); Binary(Minus, left.into(), right.into(), result_type) @@ -377,12 +377,12 @@ fn parse_timestamptz(val: &str) -> i64 { pg_sys::DirectFunctionCall3Coll( Some(timestamptz_in), pg_sys::InvalidOid as _, - cstr.as_ptr() as _, - pg_sys::InvalidOid as _, - (-1i32) as _, + pgx::Datum::from(cstr.as_ptr()), + pgx::Datum::from(pg_sys::InvalidOid), + pgx::Datum::from(-1i32), ) }; - parsed_time as _ + parsed_time.value() as _ } fn parse_interval(val: &str) -> *mut pg_sys::Interval { @@ -398,12 +398,12 @@ fn parse_interval(val: &str) -> *mut pg_sys::Interval { pg_sys::DirectFunctionCall3Coll( Some(interval_in), pg_sys::InvalidOid as _, - cstr.as_ptr() as _, - pg_sys::InvalidOid as _, - (-1i32) as _, + pgx::Datum::from(cstr.as_ptr()), + pgx::Datum::from(pg_sys::InvalidOid), + pgx::Datum::from(-1i32), ) }; - parsed_interval as _ + parsed_interval.cast_mut_ptr() } // This static determines the precedence of infix operators diff --git a/extension/src/time_vector/pipeline/map.rs b/extension/src/time_vector/pipeline/map.rs index b003fb95..0ca83eeb 100644 --- a/extension/src/time_vector/pipeline/map.rs +++ b/extension/src/time_vector/pipeline/map.rs @@ -89,11 +89,11 @@ pub fn map_lambda_over_series( pub fn map_series_pipeline_element<'e>( function: crate::raw::regproc, ) -> toolkit_experimental::UnstableTimevectorPipeline<'e> { - map_series_element(function.0.try_into().unwrap()).flatten() + map_series_element(crate::raw::regproc::from(function.0)).flatten() } pub fn map_series_element<'a>(function: crate::raw::regproc) -> Element<'a> { - let function: pg_sys::regproc = function.0.try_into().unwrap(); + let function: pg_sys::regproc = function.0.value().try_into().unwrap(); check_user_function_type(function); Element::MapSeries { function: PgProcId(function), @@ -137,7 +137,7 @@ pub fn apply_to_series( // and the sub-function will allocate the returned timevector series.cached_datum_or_flatten(), ); - Timevector_TSTZ_F64::from_datum(res, false, pg_sys::InvalidOid) + Timevector_TSTZ_F64::from_polymorphic_datum(res, false, pg_sys::InvalidOid) .expect("unexpected NULL in timevector mapping function") } } @@ -155,7 +155,11 @@ pub fn map_data_pipeline_element<'e>( let mut argtypes: *mut pg_sys::Oid = ptr::null_mut(); let mut nargs: ::std::os::raw::c_int = 0; let rettype = unsafe { - pg_sys::get_func_signature(function.0.try_into().unwrap(), &mut argtypes, &mut nargs) + pg_sys::get_func_signature( + function.0.value().try_into().unwrap(), + &mut argtypes, + &mut nargs, + ) }; if nargs != 1 { @@ -171,7 +175,7 @@ pub fn map_data_pipeline_element<'e>( } Element::MapData { - function: PgProcId(function.0.try_into().unwrap()), + function: PgProcId(function.0.value().try_into().unwrap()), } .flatten() } @@ -182,7 +186,7 @@ pub fn apply_to( ) -> Timevector_TSTZ_F64<'_> { let mut flinfo: pg_sys::FmgrInfo = unsafe { MaybeUninit::zeroed().assume_init() }; - let fn_addr: unsafe extern "C" fn(*mut pg_sys::FunctionCallInfoBaseData) -> usize; + let fn_addr: unsafe extern "C" fn(*mut pg_sys::FunctionCallInfoBaseData) -> Datum; let mut fc_info = unsafe { pg_sys::fmgr_info(func, &mut flinfo); fn_addr = flinfo.fn_addr.expect("null function in timevector map"); @@ -200,7 +204,7 @@ pub fn apply_to( fncollation: pg_sys::InvalidOid, isnull: false, nargs: 1, - args: Default::default(), + args: pg_sys::__IncompleteArrayField::new(), }), } }; @@ -211,7 +215,7 @@ pub fn apply_to( args[0].value = val.into_datum().unwrap(); args[0].isnull = false; let res = fn_addr(fc_info); - f64::from_datum(res, fc_info.isnull, pg_sys::InvalidOid) + f64::from_polymorphic_datum(res, fc_info.isnull, pg_sys::InvalidOid) .expect("unexpected NULL in timevector mapping function") }; diff --git a/extension/src/time_weighted_average.rs b/extension/src/time_weighted_average.rs index a10e703b..4a12e8df 100644 --- a/extension/src/time_weighted_average.rs +++ b/extension/src/time_weighted_average.rs @@ -210,9 +210,9 @@ pub fn time_weight_trans_inner( } #[pg_extern(immutable, parallel_safe)] -pub fn time_weight_summary_trans( +pub fn time_weight_summary_trans<'a>( state: Internal, - next: Option, + next: Option>, fcinfo: pg_sys::FunctionCallInfo, ) -> Option { time_weight_summary_trans_inner(unsafe { state.to_inner() }, next, fcinfo).internal() @@ -323,51 +323,57 @@ fn time_weight_final_inner( #[pg_operator(immutable, parallel_safe)] #[opname(->)] -pub fn arrow_time_weight_first_val(sketch: TimeWeightSummary, _accessor: AccessorFirstVal) -> f64 { +pub fn arrow_time_weight_first_val<'a>( + sketch: TimeWeightSummary<'a>, + _accessor: AccessorFirstVal<'a>, +) -> f64 { time_weight_first_val(sketch) } #[pg_extern(name = "first_val", strict, immutable, parallel_safe)] -fn time_weight_first_val(summary: TimeWeightSummary) -> f64 { +fn time_weight_first_val<'a>(summary: TimeWeightSummary<'a>) -> f64 { summary.first.val } #[pg_operator(immutable, parallel_safe)] #[opname(->)] -pub fn arrow_time_weight_last_val(sketch: TimeWeightSummary, _accessor: AccessorLastVal) -> f64 { +pub fn arrow_time_weight_last_val<'a>( + sketch: TimeWeightSummary<'a>, + _accessor: AccessorLastVal<'a>, +) -> f64 { time_weight_last_val(sketch) } #[pg_extern(name = "last_val", strict, immutable, parallel_safe)] -fn time_weight_last_val(summary: TimeWeightSummary) -> f64 { +fn time_weight_last_val<'a>(summary: TimeWeightSummary<'a>) -> f64 { summary.last.val } #[pg_operator(immutable, parallel_safe)] #[opname(->)] -pub fn arrow_time_weight_first_time( - sketch: TimeWeightSummary, - _accessor: AccessorFirstTime, +pub fn arrow_time_weight_first_time<'a>( + sketch: TimeWeightSummary<'a>, + _accessor: AccessorFirstTime<'a>, ) -> crate::raw::TimestampTz { time_weight_first_time(sketch) } #[pg_extern(name = "first_time", strict, immutable, parallel_safe)] -fn time_weight_first_time(summary: TimeWeightSummary) -> crate::raw::TimestampTz { +fn time_weight_first_time<'a>(summary: TimeWeightSummary<'a>) -> crate::raw::TimestampTz { summary.first.ts.into() } #[pg_operator(immutable, parallel_safe)] #[opname(->)] -pub fn arrow_time_weight_last_time( - sketch: TimeWeightSummary, - _accessor: AccessorLastTime, +pub fn arrow_time_weight_last_time<'a>( + sketch: TimeWeightSummary<'a>, + _accessor: AccessorLastTime<'a>, ) -> crate::raw::TimestampTz { time_weight_last_time(sketch) } #[pg_extern(name = "last_time", strict, immutable, parallel_safe)] -fn time_weight_last_time(summary: TimeWeightSummary) -> crate::raw::TimestampTz { +fn time_weight_last_time<'a>(summary: TimeWeightSummary<'a>) -> crate::raw::TimestampTz { summary.last.ts.into() } @@ -408,18 +414,18 @@ extension_sql!( #[pg_operator(immutable, parallel_safe)] #[opname(->)] -pub fn arrow_time_weighted_average_average( - sketch: Option, - _accessor: AccessorAverage, +pub fn arrow_time_weighted_average_average<'a>( + sketch: Option>, + _accessor: AccessorAverage<'a>, ) -> Option { time_weighted_average_average(sketch) } #[pg_operator(immutable, parallel_safe)] #[opname(->)] -pub fn arrow_time_weighted_average_integral( - tws: Option, - accessor: toolkit_experimental::AccessorIntegral, +pub fn arrow_time_weighted_average_integral<'a>( + tws: Option>, + accessor: toolkit_experimental::AccessorIntegral<'a>, ) -> Option { time_weighted_average_integral( tws, @@ -428,7 +434,7 @@ pub fn arrow_time_weighted_average_integral( } #[pg_extern(immutable, parallel_safe, name = "average")] -pub fn time_weighted_average_average(tws: Option) -> Option { +pub fn time_weighted_average_average<'a>(tws: Option>) -> Option { match tws { None => None, Some(tws) => match tws.internal().time_weighted_average() { @@ -451,8 +457,8 @@ pub fn time_weighted_average_average(tws: Option) -> Option, +pub fn time_weighted_average_integral<'a>( + tws: Option>, unit: default!(String, "'second'"), ) -> Option { let unit = match DurationUnit::from_str(&unit) { @@ -488,12 +494,12 @@ fn interpolate<'a>( name = "interpolated_average", schema = "toolkit_experimental" )] -pub fn time_weighted_average_interpolated_average( - tws: Option, +pub fn time_weighted_average_interpolated_average<'a>( + tws: Option>, start: crate::raw::TimestampTz, interval: crate::raw::Interval, - prev: Option, - next: Option, + prev: Option>, + next: Option>, ) -> Option { let target = interpolate(tws, start, interval, prev, next); time_weighted_average_average(target) @@ -505,12 +511,12 @@ pub fn time_weighted_average_interpolated_average( name = "interpolated_integral", schema = "toolkit_experimental" )] -pub fn time_weighted_average_interpolated_integral( - tws: Option, +pub fn time_weighted_average_interpolated_integral<'a>( + tws: Option>, start: crate::raw::TimestampTz, interval: crate::raw::Interval, - prev: Option, - next: Option, + prev: Option>, + next: Option>, unit: String, ) -> Option { let target = interpolate(tws, start, interval, prev, next); @@ -781,7 +787,7 @@ mod tests { let mut control = state.unwrap(); let buffer = time_weight_trans_serialize(Inner::from(control.clone()).internal().unwrap()); - let buffer = pgx::varlena::varlena_to_byte_slice(buffer.0 as *mut pg_sys::varlena); + let buffer = pgx::varlena::varlena_to_byte_slice(buffer.0.cast_mut_ptr()); let expected = [ 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 96, 194, 134, 7, 62, 2, 0, @@ -791,9 +797,8 @@ mod tests { assert_eq!(buffer, expected); let expected = pgx::varlena::rust_byte_slice_to_bytea(&expected); - let new_state = time_weight_trans_deserialize_inner(bytea( - &*expected as *const pg_sys::varlena as _, - )); + let new_state = + time_weight_trans_deserialize_inner(bytea(pgx::Datum::from(expected.as_ptr()))); control.combine_summaries(); // Serialized form is always combined assert_eq!(&*new_state, &*control); diff --git a/extension/src/type_builder.rs b/extension/src/type_builder.rs index bd31bf09..7236a449 100644 --- a/extension/src/type_builder.rs +++ b/extension/src/type_builder.rs @@ -128,7 +128,7 @@ macro_rules! pg_type_impl { *self = self.0.flatten(); self.cached_datum_or_flatten() }, - FromInput(bytes) | Flattened(bytes) => bytes.as_ptr() as _, + FromInput(bytes) | Flattened(bytes) => pgx::Datum::from(bytes.as_ptr()), } } } @@ -177,7 +177,7 @@ macro_rules! pg_type_impl { } impl<$lifetemplate> pgx::FromDatum for $name<$lifetemplate> { - unsafe fn from_datum(datum: pgx::pg_sys::Datum, is_null: bool, _: pg_sys::Oid) -> Option + unsafe fn from_polymorphic_datum(datum: pgx::pg_sys::Datum, is_null: bool, _: pg_sys::Oid) -> Option where Self: Sized, { @@ -186,7 +186,7 @@ macro_rules! pg_type_impl { return None; } - let mut ptr = pg_sys::pg_detoast_datum_packed(datum as *mut pg_sys::varlena); + let mut ptr = pg_sys::pg_detoast_datum_packed(datum.cast_mut_ptr()); //TODO is there a better way to do this? if pgx::varatt_is_1b(ptr) { ptr = pg_sys::pg_detoast_datum_copy(ptr); @@ -206,8 +206,8 @@ macro_rules! pg_type_impl { fn into_datum(self) -> Option { use $crate::type_builder::CachedDatum::*; let datum = match self.1 { - Flattened(bytes) => bytes.as_ptr() as pgx::pg_sys::Datum, - FromInput(..) | None => self.0.to_pg_bytes().as_ptr() as pgx::pg_sys::Datum, + Flattened(bytes) => pgx::Datum::from(bytes.as_ptr()), + FromInput(..) | None => pgx::Datum::from(self.0.to_pg_bytes().as_ptr()), }; Some(datum) } @@ -362,7 +362,7 @@ macro_rules! do_serialize { let len = writer.position().try_into().expect("serialized size too large"); ::pgx::set_varsize(writer.get_mut().as_mut_ptr() as *mut _, len); } - $crate::raw::bytea::from(writer.into_inner().as_mut_ptr() as pg_sys::Datum) + $crate::raw::bytea::from(pgx::Datum::from(writer.into_inner().as_mut_ptr())) } }; } @@ -374,7 +374,7 @@ macro_rules! do_deserialize { let state: $t = unsafe { let input: $crate::raw::bytea = $bytes; let input: pgx::pg_sys::Datum = input.into(); - let detoasted = pg_sys::pg_detoast_datum_packed(input as *mut _); + let detoasted = pg_sys::pg_detoast_datum_packed(input.cast_mut_ptr()); let len = pgx::varsize_any_exhdr(detoasted); let data = pgx::vardata_any(detoasted); let bytes = std::slice::from_raw_parts(data as *mut u8, len); diff --git a/extension/src/uddsketch.rs b/extension/src/uddsketch.rs index aaf7f1f1..fc368e32 100644 --- a/extension/src/uddsketch.rs +++ b/extension/src/uddsketch.rs @@ -507,9 +507,9 @@ extension_sql!( ); #[pg_extern(immutable, parallel_safe)] -pub fn uddsketch_compound_trans( +pub fn uddsketch_compound_trans<'a>( state: Internal, - value: Option, + value: Option>, fcinfo: pg_sys::FunctionCallInfo, ) -> Option { unsafe { uddsketch_compound_trans_inner(state.to_inner(), value, fcinfo).internal() } @@ -563,16 +563,16 @@ extension_sql!( #[pg_operator(immutable, parallel_safe)] #[opname(->)] -pub fn arrow_uddsketch_approx_percentile( - sketch: UddSketch, - accessor: AccessorApproxPercentile, +pub fn arrow_uddsketch_approx_percentile<'a>( + sketch: UddSketch<'a>, + accessor: AccessorApproxPercentile<'a>, ) -> f64 { uddsketch_approx_percentile(accessor.percentile, sketch) } // Approximate the value at the given approx_percentile (0.0-1.0) #[pg_extern(immutable, parallel_safe, name = "approx_percentile")] -pub fn uddsketch_approx_percentile(percentile: f64, sketch: UddSketch) -> f64 { +pub fn uddsketch_approx_percentile<'a>(percentile: f64, sketch: UddSketch<'a>) -> f64 { uddsketch::estimate_quantile( percentile, sketch.alpha, @@ -584,16 +584,16 @@ pub fn uddsketch_approx_percentile(percentile: f64, sketch: UddSketch) -> f64 { #[pg_operator(immutable, parallel_safe)] #[opname(->)] -pub fn arrow_uddsketch_approx_rank( - sketch: UddSketch, - accessor: AccessorApproxPercentileRank, +pub fn arrow_uddsketch_approx_rank<'a>( + sketch: UddSketch<'a>, + accessor: AccessorApproxPercentileRank<'a>, ) -> f64 { uddsketch_approx_percentile_rank(accessor.value, sketch) } // Approximate the approx_percentile at the given value #[pg_extern(immutable, parallel_safe, name = "approx_percentile_rank")] -pub fn uddsketch_approx_percentile_rank(value: f64, sketch: UddSketch) -> f64 { +pub fn uddsketch_approx_percentile_rank<'a>(value: f64, sketch: UddSketch<'a>) -> f64 { uddsketch::estimate_quantile_at_value( value, uddsketch::gamma(sketch.alpha), @@ -604,26 +604,26 @@ pub fn uddsketch_approx_percentile_rank(value: f64, sketch: UddSketch) -> f64 { #[pg_operator(immutable, parallel_safe)] #[opname(->)] -pub fn arrow_uddsketch_num_vals(sketch: UddSketch, _accessor: AccessorNumVals) -> f64 { +pub fn arrow_uddsketch_num_vals<'a>(sketch: UddSketch<'a>, _accessor: AccessorNumVals<'a>) -> f64 { uddsketch_num_vals(sketch) } // Number of elements from which the sketch was built. #[pg_extern(immutable, parallel_safe, name = "num_vals")] -pub fn uddsketch_num_vals(sketch: UddSketch) -> f64 { +pub fn uddsketch_num_vals<'a>(sketch: UddSketch<'a>) -> f64 { sketch.count as f64 } #[pg_operator(immutable, parallel_safe)] #[opname(->)] -pub fn arrow_uddsketch_mean(sketch: UddSketch, _accessor: AccessorMean) -> f64 { +pub fn arrow_uddsketch_mean<'a>(sketch: UddSketch<'a>, _accessor: AccessorMean<'a>) -> f64 { uddsketch_mean(sketch) } // Average of all the values entered in the sketch. // Note that this is not an approximation, though there may be loss of precision. #[pg_extern(immutable, parallel_safe, name = "mean")] -pub fn uddsketch_mean(sketch: UddSketch) -> f64 { +pub fn uddsketch_mean<'a>(sketch: UddSketch<'a>) -> f64 { if sketch.count > 0 { sketch.sum / sketch.count as f64 } else { @@ -633,13 +633,13 @@ pub fn uddsketch_mean(sketch: UddSketch) -> f64 { #[pg_operator(immutable, parallel_safe)] #[opname(->)] -pub fn arrow_uddsketch_error(sketch: UddSketch, _accessor: AccessorError) -> f64 { +pub fn arrow_uddsketch_error<'a>(sketch: UddSketch<'a>, _accessor: AccessorError<'a>) -> f64 { uddsketch_error(sketch) } // The maximum error (relative to the true value) for any approx_percentile estimate. #[pg_extern(immutable, parallel_safe, name = "error")] -pub fn uddsketch_error(sketch: UddSketch) -> f64 { +pub fn uddsketch_error<'a>(sketch: UddSketch<'a>) -> f64 { sketch.alpha } @@ -1009,7 +1009,7 @@ mod tests { let control = state.unwrap(); let buffer = uddsketch_serialize(Inner::from(control.clone()).internal().unwrap()); - let buffer = pgx::varlena::varlena_to_byte_slice(buffer.0 as *mut pg_sys::varlena); + let buffer = pgx::varlena::varlena_to_byte_slice(buffer.0.cast_mut_ptr()); let expected = [ 1, 1, 123, 20, 174, 71, 225, 122, 116, 63, 100, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 5, @@ -1020,8 +1020,7 @@ mod tests { assert_eq!(buffer, expected); let expected = pgx::varlena::rust_byte_slice_to_bytea(&expected); - let new_state = - uddsketch_deserialize_inner(bytea(&*expected as *const pg_sys::varlena as _)); + let new_state = uddsketch_deserialize_inner(bytea(pgx::Datum::from(expected.as_ptr()))); assert_eq!(&*new_state, &*control); } } diff --git a/extension/src/utilities.rs b/extension/src/utilities.rs index 072c04bb..499e04b0 100644 --- a/extension/src/utilities.rs +++ b/extension/src/utilities.rs @@ -1,5 +1,5 @@ use crate::raw::TimestampTz; -use pgx::*; +use pgx::prelude::*; #[pg_extern( name = "generate_periodic_normal_series", @@ -8,7 +8,7 @@ use pgx::*; pub fn default_generate_periodic_normal_series( series_start: crate::raw::TimestampTz, rng_seed: Option, -) -> impl std::iter::Iterator + 'static { +) -> TableIterator<'static, (name!(time, TimestampTz), name!(value, f64))> { generate_periodic_normal_series(series_start, None, None, None, None, None, None, rng_seed) } @@ -22,7 +22,7 @@ pub fn alternate_generate_periodic_normal_series( periodic_magnitude: f64, standard_deviation: f64, rng_seed: Option, -) -> impl std::iter::Iterator + 'static { +) -> TableIterator<'static, (name!(time, TimestampTz), name!(value, f64))> { generate_periodic_normal_series( series_start, Some(periods_per_series * points_per_period * seconds_between_points * 1000000), @@ -46,7 +46,7 @@ pub fn generate_periodic_normal_series( periodic_magnitude: Option, standard_deviation: Option, rng_seed: Option, -) -> impl std::iter::Iterator + 'static { +) -> TableIterator<'static, (name!(time, TimestampTz), name!(value, f64))> { // Convenience consts to make defaults more readable const SECOND: i64 = 1000000; const MIN: i64 = 60 * SECOND; @@ -73,16 +73,20 @@ pub fn generate_periodic_normal_series( let distribution = rand_distr::Normal::new(0.0, standard_deviation).unwrap(); let series_start: i64 = series_start.into(); - (0..series_len) - .step_by(sample_interval as usize) - .map(move |accum| { - let time = series_start + accum; - let base = base_value - + f64::sin(accum as f64 / (2.0 * std::f64::consts::PI * period as f64)) - * periodic_magnitude; - let error = distribution.sample(&mut rng); - (time.into(), base + error) - }) + TableIterator::new( + (0..series_len) + .step_by(sample_interval as usize) + .map(move |accum| { + let time = series_start + accum; + let base = base_value + + f64::sin(accum as f64 / (2.0 * std::f64::consts::PI * period as f64)) + * periodic_magnitude; + let error = distribution.sample(&mut rng); + (time.into(), base + error) + }) + .collect::>() + .into_iter(), + ) } // Returns days in month