tcdi / plrust

A Rust procedural language handler for PostgreSQL
PostgreSQL License
1.1k stars 32 forks source link

Some examples appear to always ERROR #382

Open workingjubilee opened 1 year ago

workingjubilee commented 1 year ago

e.g.

CREATE OR REPLACE FUNCTION plrust.random_slogan() RETURNS TEXT
LANGUAGE plrust AS $$
[dependencies]
    faker_rand = "0.1"
    rand = "0.8"
[code]
    use faker_rand::en_us::company::Slogan;
    Ok(Some(rand::random::<Slogan>().to_string()))
$$;

SELECT plrust.random_slogan();

reportedly yields

CREATE FUNCTION
ERROR:  cannot sample empty range

which hits an assert here:

    fn gen_range<T, R>(&mut self, range: R) -> T
    where
        T: SampleUniform,
        R: SampleRange<T>
    {
        assert!(!range.is_empty(), "cannot sample empty range");
        range.sample_single(self).unwrap()
    }
gaslitbytech commented 1 year ago

I created a test in plrust-tests/src/dependencies.rs that I wanted to use to reproduce the issue.

Though I did get:

   0: `faker_rand` is not an allowed dependency

New Test:

    #[pg_test]
    #[cfg(not(feature = "sandboxed"))]
    #[search_path(@extschema@)]
    fn plrust_deps_docs() -> spi::Result<()> {
        let definition = r#"
        CREATE OR REPLACE FUNCTION plrust.random_company_name(locale TEXT)
            RETURNS TEXT
            LANGUAGE plrust STRICT
        AS $$
        [dependencies]
            faker_rand = "0.1"
            rand = "0.8"
        [code]
            match locale {
                "en_us" => {
                    use faker_rand::en_us::company::CompanyName;
                    Ok(Some(rand::random::<CompanyName>().to_string()))
                }
                "fr_fr" => {
                    use faker_rand::fr_fr::company::CompanyName;
                    Ok(Some(rand::random::<CompanyName>().to_string()))
                }
                _ => panic!("Unsupported locale. Use en_us or fr_fr")
            }
        $$;    
        "#;
        Spi::run(definition)?;

        let retval = Spi::get_one::<String>(
            r#"
            SELECT plrust.random_company_name('fr_fr') AS fr_fr;        
        "#
        );
        assert!(retval.is_ok());
        assert!(retval.unwrap().is_some());
        Ok(())
    }

Full Error:

Client Error:

   0: `faker_rand` is not an allowed dependency

Location:
   plrust/src/user_crate/mod.rs:351

  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ SPANTRACE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

   0: plrust::user_crate::parse_source_and_deps
      at plrust/src/user_crate/mod.rs:308
   1: plrust::user_crate::crating::try_from_fn_oid with db_oid=Oid(16384) fn_oid=Oid(16481)
      at plrust/src/user_crate/crating.rs:59
   2: plrust::user_crate::try_from_fn_oid
      at plrust/src/user_crate/mod.rs:103
   3: plrust::plrust::compile_function with fn_oid=Oid(16481)
      at plrust/src/plrust.rs:100
   4: plrust::plrust_validator with fn_oid=Oid(16481) fcinfo=0x7fffe3ab9cd0
      at plrust/src/lib.rs:225

Backtrace omitted. Run with RUST_BACKTRACE=1 environment variable to display it.
Run with RUST_BACKTRACE=full to include source snippets.
postgres location: lib.rs
rust location: SQL statement "
        CREATE OR REPLACE FUNCTION plrust.random_company_name(locale TEXT)
            RETURNS TEXT
            LANGUAGE plrust STRICT
        AS $$
        [dependencies]
            faker_rand = "0.1"
            rand = "0.8"
        [code]
            match locale {
                "en_us" => {
                    use faker_rand::en_us::company::CompanyName;
                    Ok(Some(rand::random::<CompanyName>().to_string()))
                }
                "fr_fr" => {
                    use faker_rand::fr_fr::company::CompanyName;
                    Ok(Some(rand::random::<CompanyName>().to_string()))
                }
                _ => panic!("Unsupported locale. Use en_us or fr_fr")
            }
        $$;    
        "

', /home/david/.cargo/registry/src/index.crates.io-6f17d22bba15001f/pgrx-tests-0.10.0/src/framework.rs:172:9

failures:
    dependencies::tests::pg_plrust_deps_docs

test result: FAILED. 48 passed; 1 failed; 1 ignored; 0 measured; 0 filtered out; finished in 268.83s

Is this related to trusted / untrusted mode?

workingjubilee commented 1 year ago

The tests are set up with an allowed dependencies file here: https://github.com/tcdi/plrust/blob/3725747a97e3119fbc846a6c49a7871e16970627/plrust-tests/src/lib.rs#L71-L77

gaslitbytech commented 1 year ago

Thanks. Interesting that the test still passes.

So I changed

        assert!(retval.is_ok());
        assert!(retval.unwrap().is_some());

To

        assert_eq!(retval, Ok(Some("Is this a random french company name.".to_string())));

And now I get:

 Client Error:
assertion failed: `(left == right)`
  left: `Ok(Some("Agathange EI"))`,
 right: `Ok(Some("Is this a random french company name."))`
postgres location: dependencies.rs

So this means that this example does work in the unit tests. Just not when I launch using Dockerfile.try

workingjubilee commented 1 year ago

That's weird.