plrust icon indicating copy to clipboard operation
plrust copied to clipboard

Call a function from another function

Open dineshsivaji opened this issue 2 years ago • 6 comments

Hi,

I am just exploring on the feasibility of using multiple functions and calling from one another.

plrust=#     CREATE OR REPLACE FUNCTION plrust.strlen(val TEXT)
plrust-#     RETURNS BIGINT
plrust-#     LANGUAGE plrust STRICT
plrust-# AS $$
plrust$#     Ok(Some(val.len() as i64))
plrust$# $$;

CREATE FUNCTION
plrust=# 
plrust=# SELECT plrust.strlen('This is a random sentence');
 strlen 
--------
     25
(1 row)

plrust=# CREATE OR REPLACE FUNCTION plrust.strlen2(val TEXT)
plrust-#     RETURNS BIGINT
plrust-#     LANGUAGE plrust STRICT
plrust-# AS $$
plrust$#     Ok(Some(plrust.strlen(val)))
plrust$# $$;
ERROR:  
   0: `cargo build` failed

Location:
   /rustc/90c541806f23a127002de5b4038be731ba1458ca/library/core/src/convert/mod.rs:727

`cargo build` stderr:
       Updating crates.io index
      Compiling plrust_fn_oid_16384_16428_3272765079552 v0.0.0 (/Users/dsivaji/plrust-scratch/plrust_fn_oid_16384_16428_3272765079552)
   error[E0425]: cannot find value `plrust` in this scope
     --> src/lib.rs:13:17
      |
   13 |         Ok(Some(plrust.strlen(val)))
      |                 ^^^^^^ not found in this scope

   error[E0425]: cannot find value `plrust` in this scope
     --> src/lib.rs:48:17
      |
   48 |         Ok(Some(plrust.strlen(val)))
      |                 ^^^^^^ not found in this scope

   For more information about this error, try `rustc --explain E0425`.
   error: could not compile `plrust_fn_oid_16384_16428_3272765079552` (lib) due to 2 previous errors


Source Code:
   #![deny(unsafe_op_in_unsafe_fn)]
   pub mod opened {
       #[allow(unused_imports)]
       use pgrx::prelude::*;
       #[allow(unused_lifetimes)]
       #[pg_extern]
       fn plrust_fn_oid_16384_16428<'a>(
           val: &'a str,
       ) -> ::std::result::Result<
           Option<i64>,
           Box<dyn std::error::Error + Send + Sync + 'static>,
       > {
           Ok(Some(plrust.strlen(val)))
       }
   }
   #[deny(unknown_lints)]
   mod forbidden {
       #![forbid(deprecated)]
       #![forbid(implied_bounds_entailment)]
       #![forbid(plrust_async)]
       #![forbid(plrust_autotrait_impls)]
       #![forbid(plrust_closure_trait_impl)]
       #![forbid(plrust_env_macros)]
       #![forbid(plrust_extern_blocks)]
       #![forbid(plrust_external_mod)]
       #![forbid(plrust_filesystem_macros)]
       #![forbid(plrust_fn_pointers)]
       #![forbid(plrust_leaky)]
       #![forbid(plrust_lifetime_parameterized_traits)]
       #![forbid(plrust_print_macros)]
       #![forbid(plrust_static_impls)]
       #![forbid(plrust_stdio)]
       #![forbid(plrust_suspicious_trait_object)]
       #![forbid(plrust_tuple_struct_self_pattern)]
       #![forbid(soft_unstable)]
       #![forbid(suspicious_auto_trait_impls)]
       #![forbid(unsafe_code)]
       #![forbid(where_clauses_object_safety)]
       #[allow(unused_imports)]
       use pgrx::prelude::*;
       #[allow(unused_lifetimes)]
       fn plrust_fn_oid_16384_16428<'a>(
           val: &'a str,
       ) -> ::std::result::Result<
           Option<i64>,
           Box<dyn std::error::Error + Send + Sync + 'static>,
       > {
           Ok(Some(plrust.strlen(val)))
       }
   }


Backtrace omitted. Run with RUST_BACKTRACE=1 environment variable to display it.
Run with RUST_BACKTRACE=full to include source snippets.
plrust=# 

I read that CREATE FUNCTION is compiled to rust function internally in the documentation. In that case, how can we call another function from inside a function ? How to expose functions to one another ?

dineshsivaji avatar Aug 06 '23 11:08 dineshsivaji

Hi @dineshsivaji! PL/Rust doesn't support this yet. We have some loose plans around what this will look like, and intend to do it eventually. The implementation itself will largely be in pgrx. I'll leave this issue open as you're the first to publicly ask for it.

eeeebbbbrrrr avatar Aug 06 '23 19:08 eeeebbbbrrrr

I should add that you can use Spi to call another function. The major downside there is incurring the Spi overhead. Depending on what the other function does, maybe that won't be too terrible.

eeeebbbbrrrr avatar Aug 06 '23 19:08 eeeebbbbrrrr

Thanks, @eeeebbbbrrrr . I also thought of using SPI as an alternate. Hope this feature added in the near future.

dineshsivaji avatar Aug 07 '23 03:08 dineshsivaji

Was just about to suggest this and saw that the issue is already open. It would be really useful for us too.

decarbonise avatar Aug 30 '23 15:08 decarbonise

It's in-progress. Most of the work has to happen in pgrx, and I've got a proof-of-concept PR up already. Probably a couple more weeks of work.

eeeebbbbrrrr avatar Aug 30 '23 15:08 eeeebbbbrrrr

Brilliant, thanks @eeeebbbbrrrr

decarbonise avatar Aug 30 '23 15:08 decarbonise