Repository: candlecorp/wick (language: rust)

Issue:
Unable to parse date datatype in Azure
**Describe the bug**
When querying with a date as a string parameter, we get back an error saying unable to parse string to datetime.

**To Reproduce**
Query into an Azure db and pass in a date as a string


`wick invoke sqlcomponent.wick sales_comparison -- --from='2017-10-15 00:00:00'`

**Expected behavior**
Should be able to query with our parameter and get back the intended results

**Actual behavior**
We get this instead:

`ERROR error executing query error=Failed to fetch result of query: Token error: 'Conversion failed when converting character string to smalldatetime data type.' on server gwserver executing  on line 1 (code: 295, state: 3, class: 16)`

**Environment:**
Running on Mac M1, the latest Wick

**Additional context**
Add any other context about the problem here.



Discussion / hints:

Fix patch:
diff --git a/.github/workflows/mono_workflow.yaml b/.github/workflows/mono_workflow.yaml
index 87b5c9d67..b5f519b88 100644
--- a/.github/workflows/mono_workflow.yaml
+++ b/.github/workflows/mono_workflow.yaml
@@ -2,12 +2,9 @@ name: mono-workflow
 on:
   push:
     tags:
-      - "[0-9]+.[0-9]+.[0-9]+" # matches 0.1.0, 0.2.1, etc.
+      - '[0-9]+.[0-9]+.[0-9]+' # matches 0.1.0, 0.2.1, etc.
   schedule:
-    - cron: "0 1 * * *" # 1am UTC
-  pull_request:
-    branches:
-      - main
+    - cron: '0 1 * * *' # 1am UTC
   workflow_dispatch:
 permissions:
   contents: write
@@ -46,16 +43,16 @@ jobs:
     env:
       SCCACHE_AZURE_BLOB_CONTAINER: ${{ secrets.SCCACHE_AZURE_BLOB_CONTAINER }}
       SCCACHE_AZURE_CONNECTION_STRING: ${{ secrets.SCCACHE_AZURE_CONNECTION_STRING }}
-      SCCACHE_AZURE_KEY_PREFIX: "wick-github-actions-test"
-      RUSTC_WRAPPER: "sccache"
+      SCCACHE_AZURE_KEY_PREFIX: 'wick-github-actions-test'
+      RUSTC_WRAPPER: 'sccache'
     strategy:
       matrix:
         config:
           - {
-              os: "ubuntu-latest",
-              name: "linux",
-              arch: "amd64",
-              target: "x86_64-unknown-linux-gnu",
+              os: 'ubuntu-latest',
+              name: 'linux',
+              arch: 'amd64',
+              target: 'x86_64-unknown-linux-gnu',
             }
     steps:
       - name: make space
@@ -115,7 +112,7 @@ jobs:
         uses: dtolnay/rust-toolchain@stable
         with:
           target: ${{ matrix.config.target }}
-      - name: "rustup updates"
+      - name: 'rustup updates'
         run: |
           rustup target add wasm32-unknown-unknown wasm32-wasi
           cargo install cargo-deny just
@@ -131,43 +128,43 @@ jobs:
     env:
       SCCACHE_AZURE_BLOB_CONTAINER: ${{ secrets.SCCACHE_AZURE_BLOB_CONTAINER }}
       SCCACHE_AZURE_CONNECTION_STRING: ${{ secrets.SCCACHE_AZURE_CONNECTION_STRING }}
-      SCCACHE_AZURE_KEY_PREFIX: "wick-github-actions"
-      RUSTC_WRAPPER: "sccache"
-      CARGO_PROFILE_RELEASE_DEBUG: "0" # https://doc.rust-lang.org/cargo/reference/profiles.html#debug
-      CARGO_INCREMENTAL: "true" # https://doc.rust-lang.org/cargo/reference/profiles.html#incremental
-      CARGO_PROFILE_RELEASE_LTO: "true" # https://doc.rust-lang.org/cargo/reference/profiles.html#lto
-      CARGO_PROFILE_RELEASE_OPT_LEVEL: "3" # https://doc.rust-lang.org/cargo/reference/profiles.html#opt-level
-      CARGO_PROFILE_RELEASE_CODEGEN_UNITS: "1" # https://doc.rust-lang.org/cargo/reference/profiles.html#codegen-units
-      CARGO_PROFILE_RELEASE_STRIP: "true" # https://doc.rust-lang.org/cargo/reference/unstable.html#profile-strip-option
+      SCCACHE_AZURE_KEY_PREFIX: 'wick-github-actions'
+      RUSTC_WRAPPER: 'sccache'
+      CARGO_PROFILE_RELEASE_DEBUG: '0' # https://doc.rust-lang.org/cargo/reference/profiles.html#debug
+      CARGO_INCREMENTAL: 'true' # https://doc.rust-lang.org/cargo/reference/profiles.html#incremental
+      CARGO_PROFILE_RELEASE_LTO: 'true' # https://doc.rust-lang.org/cargo/reference/profiles.html#lto
+      CARGO_PROFILE_RELEASE_OPT_LEVEL: '3' # https://doc.rust-lang.org/cargo/reference/profiles.html#opt-level
+      CARGO_PROFILE_RELEASE_CODEGEN_UNITS: '1' # https://doc.rust-lang.org/cargo/reference/profiles.html#codegen-units
+      CARGO_PROFILE_RELEASE_STRIP: 'true' # https://doc.rust-lang.org/cargo/reference/unstable.html#profile-strip-option
     strategy:
       matrix:
         config:
           - {
-              os: "ubuntu-latest",
-              name: "linux",
-              arch: "amd64",
-              target: "x86_64-unknown-linux-gnu",
-              args: "",
+              os: 'ubuntu-latest',
+              name: 'linux',
+              arch: 'amd64',
+              target: 'x86_64-unknown-linux-gnu',
+              args: '',
             }
           - {
-              os: "ubuntu-latest",
-              name: "linux",
-              target: "aarch64-unknown-linux-gnu",
-              arch: "aarch64",
-              args: "--features cross",
+              os: 'ubuntu-latest',
+              name: 'linux',
+              target: 'aarch64-unknown-linux-gnu',
+              arch: 'aarch64',
+              args: '--features cross',
             }
           - {
-              os: "macos-latest",
-              name: "macos",
-              target: "x86_64-apple-darwin",
-              arch: "amd64",
+              os: 'macos-latest',
+              name: 'macos',
+              target: 'x86_64-apple-darwin',
+              arch: 'amd64',
             }
           - {
-              os: "macos-latest",
-              name: "macos",
-              target: "aarch64-apple-darwin",
-              arch: "aarch64",
-              args: "--features cross",
+              os: 'macos-latest',
+              name: 'macos',
+              target: 'aarch64-apple-darwin',
+              arch: 'aarch64',
+              args: '--features cross',
             }
           # - {
           #     os: "ubuntu-latest",
@@ -235,10 +232,10 @@ jobs:
         uses: dtolnay/rust-toolchain@stable
         with:
           target: ${{ matrix.config.target }}
-      - name: "rustup updates"
+      - name: 'rustup updates'
         run: |
           rustup target add wasm32-unknown-unknown wasm32-wasi
-      - name: "build binary"
+      - name: 'build binary'
         run: |
           cargo build --release -p wick-cli --target=${{ matrix.config.target }} ${{ matrix.config.args }}
       - name: package release assets
diff --git a/.gitignore b/.gitignore
index cf6457b42..167c50397 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,14 +1,22 @@
+# rust
 **/target
+crates/*/**/Cargo.lock
+
+# .env
 DEV.env
+.env.local
+
+# node/js
 node_modules
+
+# general wick/wasm
 /build
+.wick/
+crates/wick-rpc/src/generated/wick.rs
+
 /crates/integration/*/build
-.DS_Store
+
+# misc
 archive
-crates/wick-rpc/src/generated/wick.rs
-crates/*/**/Cargo.lock
-bundle.tar
-/codegen/dist
 .vscode/*.log
-wick_components/
-.wick/
\ No newline at end of file
+.DS_Store
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 135f6dbe4..65dcce48c 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -9,7 +9,11 @@
       "app.yaml"
     ]
   },
-  "rust-analyzer.cargo.features": ["wick-rpc/client"],
+  "rust-analyzer.cargo.features": [
+    "wick-rpc/client",
+    "wick-packet/datetime",
+    "wick-packet/invocation"
+  ],
   "rust-analyzer.rustfmt.overrideCommand": [
     "rustup",
     "run",
diff --git a/Cargo.lock b/Cargo.lock
index 46f2e8fef..863d9154e 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -6619,6 +6619,7 @@ dependencies = [
  "base64 0.21.0",
  "base64-serde",
  "bytes",
+ "chrono",
  "futures",
  "parking_lot 0.12.1",
  "pin-project-lite",
diff --git a/Justfile b/Justfile
index 20b97cdf7..b9f15b130 100644
--- a/Justfile
+++ b/Justfile
@@ -69,6 +69,11 @@ integration-tests: codegen-tests
 	  cargo test --workspace -- --skip slow_test --test-threads=6; \
 	fi
 	cargo test --manifest-path tests/template/Cargo.toml
+	just wick-db-tests
+
+wick-db-tests:
+  cargo run -p wick-cli -- test ./examples/db/flow-with-postgres.wick
+  cargo run -p wick-cli -- test ./examples/db/postgres-numeric.wick
 
 all-tests:
 	if {{nextest}} = "true"; then \
diff --git a/crates/components/wick-azure-sql/Cargo.toml b/crates/components/wick-azure-sql/Cargo.toml
index 6afe116b9..14a256c88 100644
--- a/crates/components/wick-azure-sql/Cargo.toml
+++ b/crates/components/wick-azure-sql/Cargo.toml
@@ -10,7 +10,7 @@ description = "Azure SQL Database component for the wick project."
 [features]
 
 [dependencies]
-wick-packet = { workspace = true, features = ["rt-tokio"] }
+wick-packet = { workspace = true, features = ["rt-tokio", "datetime"] }
 flow-component = { workspace = true }
 wick-config = { workspace = true }
 wick-rpc = { workspace = true }
diff --git a/crates/components/wick-azure-sql/src/component.rs b/crates/components/wick-azure-sql/src/component.rs
index e75363610..30fe70bcc 100644
--- a/crates/components/wick-azure-sql/src/component.rs
+++ b/crates/components/wick-azure-sql/src/component.rs
@@ -50,11 +50,19 @@ impl AzureSqlComponent {
   #[allow(clippy::needless_pass_by_value)]
   pub fn new(config: SqlComponentConfig, metadata: Metadata, resolver: &Resolver) -> Result<Self, ComponentError> {
     validate(&config, resolver)?;
-    let sig = component! {
+    let mut sig = component! {
       name: "wick/component/sql",
       version: metadata.version(),
       operations: config.operation_signatures(),
     };
+
+    // NOTE: remove this must change when db components support customized outputs.
+    sig.operations.iter_mut().for_each(|op| {
+      if !op.outputs.iter().any(|f| f.name == "output") {
+        op.outputs.push(Field::new("output", TypeSignature::Object));
+      }
+    });
+
     let addr = resolver(config.resource())
       .ok_or_else(|| ComponentError::message(&format!("Could not resolve resource ID {}", config.resource())))
       .and_then(|r| r.try_resource().map_err(ComponentError::new))?;
diff --git a/crates/components/wick-azure-sql/src/lib.rs b/crates/components/wick-azure-sql/src/lib.rs
index 3b11a5592..4ee50d9cb 100644
--- a/crates/components/wick-azure-sql/src/lib.rs
+++ b/crates/components/wick-azure-sql/src/lib.rs
@@ -85,7 +85,6 @@
 // Add exceptions here
 #![allow(missing_docs)]
 mod component;
-pub(crate) mod data;
 mod error;
 pub(crate) mod mssql;
 pub(crate) mod sql_wrapper;
diff --git a/crates/components/wick-azure-sql/src/sql_wrapper.rs b/crates/components/wick-azure-sql/src/sql_wrapper.rs
index cb3366f12..cf10b1d97 100644
--- a/crates/components/wick-azure-sql/src/sql_wrapper.rs
+++ b/crates/components/wick-azure-sql/src/sql_wrapper.rs
@@ -1,9 +1,7 @@
 use chrono::{NaiveDate, NaiveDateTime, NaiveTime};
 use serde_json::{Number, Value};
 use tiberius::{ColumnData, FromSql, IntoSql};
-use wick_packet::TypeWrapper;
-
-use crate::data::parse_date;
+use wick_packet::{parse_date, TypeWrapper};
 
 #[derive(Debug, Clone)]
 pub(crate) struct SqlWrapper(pub(crate) TypeWrapper);
@@ -11,6 +9,7 @@ pub(crate) struct SqlWrapper(pub(crate) TypeWrapper);
 impl<'a> IntoSql<'a> for SqlWrapper {
   fn into_sql(self) -> ColumnData<'a> {
     let v = self.0.inner();
+    println!("type sig is {:?}", self.0.type_signature());
     match self.0.type_signature() {
       wick_interface_types::TypeSignature::I8 => {
         let v = to_int::<i16>(v).unwrap();
diff --git a/crates/components/wick-sqlx/Cargo.toml b/crates/components/wick-sqlx/Cargo.toml
index 5536db85b..4bea24ccf 100644
--- a/crates/components/wick-sqlx/Cargo.toml
+++ b/crates/components/wick-sqlx/Cargo.toml
@@ -10,7 +10,7 @@ description = "SQL Database component for the wick project."
 [features]
 
 [dependencies]
-wick-packet = { workspace = true, features = ["rt-tokio"] }
+wick-packet = { workspace = true, features = ["rt-tokio", "datetime"] }
 flow-component = { workspace = true }
 wick-config = { workspace = true }
 wick-rpc = { workspace = true }
diff --git a/crates/components/wick-sqlx/src/component.rs b/crates/components/wick-sqlx/src/component.rs
index 7161615a9..043c66497 100644
--- a/crates/components/wick-sqlx/src/component.rs
+++ b/crates/components/wick-sqlx/src/component.rs
@@ -42,7 +42,7 @@ impl CtxPool {
 
         let b = a.map(|a| a.map(SerMapPgRow::from));
         let c = b.map(|a| {
-          a.map(|a| serde_json::to_value(a).unwrap())
+          a.map(|a| serde_json::to_value(a).unwrap_or(Value::Null))
             .map_err(|e| Error::Fetch(e.to_string()))
         });
         c.boxed()
@@ -56,7 +56,7 @@ impl CtxPool {
         let a = query.fetch(c);
         let b = a.map(|a| a.map(SerMapMssqlRow::from));
         let c = b.map(|a| {
-          a.map(|a| serde_json::to_value(a).unwrap())
+          a.map(|a| serde_json::to_value(a).unwrap_or(Value::Null))
             .map_err(|e| Error::Fetch(e.to_string()))
         });
         c.boxed()
@@ -96,11 +96,18 @@ impl SqlXComponent {
   #[allow(clippy::needless_pass_by_value)]
   pub fn new(config: SqlComponentConfig, metadata: Metadata, resolver: &Resolver) -> Result<Self, ComponentError> {
     validate(&config, resolver)?;
-    let sig = component! {
+    let mut sig = component! {
       name: "wick/component/sql",
       version: metadata.version(),
       operations: config.operation_signatures(),
     };
+    // NOTE: remove this must change when db components support customized outputs.
+    sig.operations.iter_mut().for_each(|op| {
+      if !op.outputs.iter().any(|f| f.name == "output") {
+        op.outputs.push(Field::new("output", TypeSignature::Object));
+      }
+    });
+
     let addr = resolver(config.resource())
       .ok_or_else(|| ComponentError::message(&format!("Could not resolve resource ID {}", config.resource())))
       .and_then(|r| r.try_resource().map_err(ComponentError::new))?;
@@ -229,6 +236,13 @@ fn validate(config: &SqlComponentConfig, _resolver: &Resolver) -> Result<(), Err
 }
 
 async fn init_client(config: SqlComponentConfig, addr: UrlResource) -> Result<CtxPool, Error> {
+  /*****************
+   *
+   * NOTE: This component was *supposed* to handle sql server (mssql) but sqlx was so buggy it
+   * wouldn't work. The mssql logic is still in this crate for now, but it's not used and may be
+   * removed in the future.
+   *
+   */
   let pool = match addr.scheme() {
     "mssql" => CtxPool::MsSql(mssql::connect(config, &addr).await?),
     "postgres" => CtxPool::Postgres(postgres::connect(config, &addr).await?),
diff --git a/crates/components/wick-sqlx/src/data.rs b/crates/components/wick-sqlx/src/data.rs
deleted file mode 100644
index 1ff485b0e..000000000
--- a/crates/components/wick-sqlx/src/data.rs
+++ /dev/null
@@ -1,43 +0,0 @@
-use chrono::NaiveDateTime;
-
-pub(crate) fn parse_date(v: &str) -> NaiveDateTime {
-  use chrono::DateTime;
-  let v: DateTime<chrono::Utc> = DateTime::parse_from_rfc3339(v)
-    .unwrap_or_else(|_| {
-      let datetime = NaiveDateTime::parse_from_str(v, "%Y-%m-%d %H:%M:%S")
-        .unwrap_or_else(|_| NaiveDateTime::parse_from_str(v, "%Y-%m-%d %H:%M:%S %z").unwrap());
-      DateTime::from_utc(
-        datetime,
-        chrono::TimeZone::offset_from_local_datetime(&chrono::Local, &datetime).unwrap(),
-      )
-    })
-    .into();
-  v.naive_utc()
-}
-
-#[cfg(test)]
-mod test {
-  use anyhow::Result;
-  use chrono::Datelike;
-
-  use super::*;
-
-  #[test]
-  fn test_datetime() -> Result<()> {
-    let date = parse_date("2023-04-25 00:00:00");
-
-    assert_eq!(date.year(), 2023);
-    assert_eq!(date.month(), 4);
-    let date = parse_date("2023-04-25 00:00:00 +02:00");
-
-    assert_eq!(date.year(), 2023);
-    assert_eq!(date.month(), 4);
-
-    let date_str = "2023-04-12T22:10:57+02:00";
-    let date = parse_date(date_str);
-    assert_eq!(date.year(), 2023);
-    assert_eq!(date.month(), 4);
-
-    Ok(())
-  }
-}
diff --git a/crates/components/wick-sqlx/src/lib.rs b/crates/components/wick-sqlx/src/lib.rs
index a42feecc7..339994423 100644
--- a/crates/components/wick-sqlx/src/lib.rs
+++ b/crates/components/wick-sqlx/src/lib.rs
@@ -85,7 +85,6 @@
 // Add exceptions here
 #![allow(missing_docs)]
 mod component;
-pub(crate) mod data;
 mod error;
 pub(crate) mod mssql;
 pub(crate) mod postgres;
diff --git a/crates/components/wick-sqlx/src/mssql/wrapper.rs b/crates/components/wick-sqlx/src/mssql/wrapper.rs
index 25044c2ec..4c468860c 100644
--- a/crates/components/wick-sqlx/src/mssql/wrapper.rs
+++ b/crates/components/wick-sqlx/src/mssql/wrapper.rs
@@ -8,9 +8,8 @@ use sqlx::encode::IsNull;
 use sqlx::mssql::MssqlTypeInfo;
 use sqlx::{Encode, Mssql, Type};
 use wick_interface_types::TypeSignature;
-use wick_packet::TypeWrapper;
+use wick_packet::{parse_date, TypeWrapper};
 
-use crate::data::parse_date;
 use crate::sql_wrapper::SqlWrapper;
 
 impl<'q> Encode<'q, Mssql> for SqlWrapper {
diff --git a/crates/components/wick-sqlx/src/postgres/wrapper.rs b/crates/components/wick-sqlx/src/postgres/wrapper.rs
index 6036e1d0a..6e727c5b8 100644
--- a/crates/components/wick-sqlx/src/postgres/wrapper.rs
+++ b/crates/components/wick-sqlx/src/postgres/wrapper.rs
@@ -4,23 +4,39 @@ use sqlx::encode::IsNull;
 use sqlx::postgres::PgTypeInfo;
 use sqlx::{Encode, Postgres};
 use wick_interface_types::TypeSignature;
+use wick_packet::parse_date;
 
-use crate::data::parse_date;
 use crate::sql_wrapper::SqlWrapper;
 
+macro_rules! convert_int {
+  ($ty:ty, $v:expr, $buf:expr) => {{
+    #[allow(trivial_numeric_casts)]
+    let v = $v.as_i64().unwrap() as $ty;
+    Encode::<Postgres>::encode(v, $buf)
+  }};
+}
+
+macro_rules! convert_uint {
+  ($ty:ty, $v:expr, $buf:expr) => {{
+    #[allow(trivial_numeric_casts)]
+    let v = $v.as_u64().unwrap() as $ty;
+    Encode::<Postgres>::encode(v, $buf)
+  }};
+}
+
 impl<'q> Encode<'q, Postgres> for SqlWrapper {
   fn encode_by_ref(&self, buf: &mut <Postgres as sqlx::database::HasArguments<'q>>::ArgumentBuffer) -> IsNull {
     let sig = self.0.type_signature();
     let v = self.0.inner();
     let res = match sig {
-      TypeSignature::I8 => convert_int::<i8>(v, buf).unwrap(),
-      TypeSignature::I16 => convert_int::<i16>(v, buf).unwrap(),
-      TypeSignature::I32 => convert_int::<i32>(v, buf).unwrap(),
-      TypeSignature::I64 => convert_int::<i64>(v, buf).unwrap(),
-      TypeSignature::U8 => convert_int::<i16>(v, buf).unwrap(),
-      TypeSignature::U16 => convert_int::<i32>(v, buf).unwrap(),
-      TypeSignature::U32 => convert_int::<i64>(v, buf).unwrap(),
-      TypeSignature::U64 => unimplemented!("u64 not yet handled"), //convert_int::<i64>(v, buf),
+      TypeSignature::I8 => convert_int!(i8, v, buf),
+      TypeSignature::I16 => convert_int!(i16, v, buf),
+      TypeSignature::I32 => convert_int!(i32, v, buf),
+      TypeSignature::I64 => convert_int!(i64, v, buf),
+      TypeSignature::U8 => convert_uint!(i8, v, buf),
+      TypeSignature::U16 => convert_uint!(i16, v, buf),
+      TypeSignature::U32 => convert_uint!(i32, v, buf),
+      TypeSignature::U64 => convert_uint!(i64, v, buf),
       TypeSignature::F32 => convert_float(v, buf),
       TypeSignature::F64 => convert_float(v, buf),
       TypeSignature::Bool => {
@@ -102,19 +118,6 @@ fn encode_array(
   unreachable!()
 }
 
-fn convert_int<'q, T>(
-  v: &Value,
-  buf: &mut <Postgres as sqlx::database::HasArguments<'_>>::ArgumentBuffer,
-) -> Result<IsNull, T::Error>
-where
-  T: TryFrom<i64>,
-  T::Error: std::fmt::Debug,
-  T: Encode<'q, Postgres>,
-{
-  let v: T = v.as_i64().unwrap().try_into()?;
-  Ok(v.encode_by_ref(buf))
-}
-
 fn convert_float(v: &Value, buf: &mut <Postgres as sqlx::database::HasArguments<'_>>::ArgumentBuffer) -> IsNull {
   let v: f32 = v.as_f64().unwrap() as f32;
   Encode::<Postgres>::encode(v, buf)
@@ -136,14 +139,13 @@ mod test {
   #[test]
   fn test_ints() -> Result<()> {
     let mut buf = <Postgres as sqlx::database::HasArguments<'_>>::ArgumentBuffer::default();
-    convert_int::<i32>(&json!(i32::MAX), &mut buf)?;
-    convert_int::<i64>(&json!(u32::MAX), &mut buf)?;
-    convert_int::<i64>(&json!(i64::MAX), &mut buf)?;
-    convert_int::<i16>(&json!(i16::MAX), &mut buf)?;
-    convert_int::<i32>(&json!(u16::MAX), &mut buf)?;
-    convert_int::<i8>(&json!(i8::MAX), &mut buf)?;
-    convert_int::<i16>(&json!(u8::MAX), &mut buf)?;
-
+    convert_int!(i32, &json!(i32::MAX), &mut buf);
+    convert_int!(i32, &json!(u32::MAX), &mut buf);
+    convert_int!(i64, &json!(i64::MAX), &mut buf);
+    convert_int!(i16, &json!(i16::MAX), &mut buf);
+    convert_int!(i16, &json!(u16::MAX), &mut buf);
+    convert_int!(i8, &json!(i8::MAX), &mut buf);
+    convert_int!(i8, &json!(u8::MAX), &mut buf);
     Ok(())
   }
 }
diff --git a/crates/wick/flow-expression-parser/src/ast.rs b/crates/wick/flow-expression-parser/src/ast.rs
index bedcbf7f6..0aae4dc3b 100644
--- a/crates/wick/flow-expression-parser/src/ast.rs
+++ b/crates/wick/flow-expression-parser/src/ast.rs
@@ -172,7 +172,7 @@ impl ConnectionExpression {
 /// A flow expression.
 pub enum FlowExpression {
   /// A [ConnectionExpression].
-  ConnectionExpression(ConnectionExpression),
+  ConnectionExpression(Box<ConnectionExpression>),
   /// A [BlockExpression].
   BlockExpression(BlockExpression),
 }
diff --git a/crates/wick/flow-expression-parser/src/parse/v1.rs b/crates/wick/flow-expression-parser/src/parse/v1.rs
index 2d5d3b856..328d5ccee 100644
--- a/crates/wick/flow-expression-parser/src/parse/v1.rs
+++ b/crates/wick/flow-expression-parser/src/parse/v1.rs
@@ -1,7 +1,7 @@
 use nom::branch::alt;
 use nom::bytes::complete::tag;
 use nom::character::complete::{alpha1, alphanumeric1, char, multispace0};
-use nom::combinator::{eof, map, recognize};
+use nom::combinator::{eof, recognize};
 use nom::error::ParseError;
 use nom::multi::{many0, many1};
 use nom::sequence::{delimited, pair, terminated};
@@ -137,11 +137,8 @@ fn connection_expression(input: &str) -> IResult<&str, ConnectionExpression> {
 }
 
 pub(crate) fn flow_expression(input: &str) -> IResult<&str, FlowExpression> {
-  let (i, expr) = terminated(
-    map(connection_expression, FlowExpression::ConnectionExpression),
-    alt((eof, ws(tag(";")))),
-  )(input)?;
-  Ok((i, expr))
+  let (i, expr) = terminated(connection_expression, alt((eof, ws(tag(";")))))(input)?;
+  Ok((i, FlowExpression::ConnectionExpression(Box::new(expr))))
 }
 
 fn _parse(input: &str) -> IResult<&str, FlowProgram> {
diff --git a/crates/wick/flow-graph-interpreter/src/interpreter/components.rs b/crates/wick/flow-graph-interpreter/src/interpreter/components.rs
index 5d6d404d5..9733835c8 100644
--- a/crates/wick/flow-graph-interpreter/src/interpreter/components.rs
+++ b/crates/wick/flow-graph-interpreter/src/interpreter/components.rs
@@ -90,7 +90,7 @@ pub(crate) fn dyn_component_id(name: &str, schematic: &str, instance: &str) -> S
   format!("{}<{}::{}>", name, schematic, instance)
 }
 
-pub(crate) fn get_id(ns: &str, name: &str, schematic: &str, instance: &str) -> String {
+pub(crate) fn reconcile_op_id(ns: &str, name: &str, schematic: &str, instance: &str) -> String {
   if ns == NS_CORE && name == CORE_ID_MERGE {
     dyn_component_id(name, schematic, instance)
   } else {
diff --git a/crates/wick/flow-graph-interpreter/src/interpreter/program.rs b/crates/wick/flow-graph-interpreter/src/interpreter/program.rs
index dcd8b50f2..8dcfc3120 100644
--- a/crates/wick/flow-graph-interpreter/src/interpreter/program.rs
+++ b/crates/wick/flow-graph-interpreter/src/interpreter/program.rs
@@ -9,7 +9,7 @@ use crate::error::ValidationError;
 use crate::graph::types::*;
 
 pub(crate) mod validator;
-use super::components::{get_id, ComponentMap};
+use super::components::{reconcile_op_id, ComponentMap};
 use super::error::Error;
 
 #[must_use]
@@ -165,33 +165,33 @@ fn get_schematic_signature(
 }
 
 fn get_signature(
-  schematic: &str,
-  p: &Port,
-  kind: PortDirection,
+  local_name: &str,
+  port: &Port,
+  direction: PortDirection,
   components: &ComponentMap,
 ) -> Result<Option<TypeSignature>, ValidationError> {
-  let name = p.name();
-  match p.node().kind() {
-    NodeKind::Input(_) => match kind {
+  let name = port.name();
+  match port.node().kind() {
+    NodeKind::Input(_) => match direction {
       PortDirection::In => Ok(None),
       PortDirection::Out => Ok(Some(TypeSignature::Object)),
     },
 
-    NodeKind::Output(_) => match kind {
+    NodeKind::Output(_) => match direction {
       PortDirection::Out => Ok(None),
       PortDirection::In => Ok(Some(TypeSignature::Object)),
     },
     NodeKind::External(ext) | NodeKind::Inherent(ext) => {
-      let ext_collection = components
+      let ext_component = components
         .get(ext.component_id())
         .ok_or_else(|| ValidationError::ComponentIdNotFound(ext.component_id().to_owned()))?;
 
-      let operation = p.node();
+      let op_node = port.node();
 
-      let id = get_id(ext.component_id(), ext.name(), schematic, operation.name());
+      let id = reconcile_op_id(ext.component_id(), ext.name(), local_name, op_node.name());
 
       let operation =
-        ext_collection
+        ext_component
           .operations
           .iter()
           .find(|op| op.name == id)
@@ -200,16 +200,30 @@ fn get_signature(
             name: id.clone(),
           })?;
 
-      let sig = match kind {
-        PortDirection::In => operation.inputs.iter().find(|p| p.name == name).map(|p| p.ty.clone()),
-        PortDirection::Out => operation.outputs.iter().find(|p| p.name == name).map(|p| p.ty.clone()),
+      let sig = match direction {
+        PortDirection::In => operation
+          .inputs
+          .iter()
+          .find(|p| p.name == name)
+          .map(|p| p.ty.clone())
+          .ok_or(ValidationError::UnknownInput {
+            operation: ext.name().to_owned(),
+            component: ext.component_id().to_owned(),
+            port: name.to_owned(),
+          })?,
+        PortDirection::Out => operation
+          .outputs
+          .iter()
+          .find(|p| p.name == name)
+          .map(|p| p.ty.clone())
+          .ok_or(ValidationError::UnknownOutput {
+            operation: ext.name().to_owned(),
+            component: ext.component_id().to_owned(),
+            port: name.to_owned(),
+          })?,
       };
 
-      Ok(Some(sig.ok_or(ValidationError::MissingConnection {
-        operation: ext.name().to_owned(),
-        component: ext.component_id().to_owned(),
-        port: name.to_owned(),
-      })?))
+      Ok(Some(sig))
     }
   }
 }
diff --git a/crates/wick/flow-graph-interpreter/src/interpreter/program/validator.rs b/crates/wick/flow-graph-interpreter/src/interpreter/program/validator.rs
index 714713e56..734827991 100644
--- a/crates/wick/flow-graph-interpreter/src/interpreter/program/validator.rs
+++ b/crates/wick/flow-graph-interpreter/src/interpreter/program/validator.rs
@@ -4,7 +4,7 @@ use self::error::{OperationInvalid, ValidationError};
 use super::Program;
 use crate::constants::CORE_ID_SENDER;
 use crate::graph::Reference;
-use crate::interpreter::components::get_id;
+use crate::interpreter::components::reconcile_op_id;
 
 pub(crate) mod error;
 
@@ -32,7 +32,7 @@ impl Validator {
           }
           let component = component.unwrap();
 
-          let id = get_id(
+          let id = reconcile_op_id(
             reference.component_id(),
             reference.name(),
             schematic.name(),
diff --git a/crates/wick/flow-graph-interpreter/src/interpreter/program/validator/error.rs b/crates/wick/flow-graph-interpreter/src/interpreter/program/validator/error.rs
index c6b858dff..531c899d5 100644
--- a/crates/wick/flow-graph-interpreter/src/interpreter/program/validator/error.rs
+++ b/crates/wick/flow-graph-interpreter/src/interpreter/program/validator/error.rs
@@ -29,6 +29,20 @@ pub enum ValidationError {
     operation: String,
   },
 
+  #[error("Input '{port}' on operation '{component}::{operation}' is connected but does not exist on operation.")]
+  UnknownInput {
+    port: String,
+    component: String,
+    operation: String,
+  },
+
+  #[error("Output '{port}' on operation '{component}::{operation}' is connected but does not exist on operation.")]
+  UnknownOutput {
+    port: String,
+    component: String,
+    operation: String,
+  },
+
   #[error("Unused output port '{port}' on component '{component}::{operation}'")]
   UnusedOutput {
     port: String,
diff --git a/crates/wick/wick-config/src/v0/conversions.rs b/crates/wick/wick-config/src/v0/conversions.rs
index c1e86e3fa..b66965113 100644
--- a/crates/wick/wick-config/src/v0/conversions.rs
+++ b/crates/wick/wick-config/src/v0/conversions.rs
@@ -110,7 +110,7 @@ impl TryFrom<crate::v0::SchematicManifest> for config::FlowOperation {
     let connections: Result<Vec<ast::FlowExpression>> = manifest
       .connections
       .into_iter()
-      .map(|def| Ok(ast::FlowExpression::ConnectionExpression(def.try_into()?)))
+      .map(|def| Ok(ast::FlowExpression::ConnectionExpression(Box::new(def.try_into()?))))
       .collect();
     Ok(Self {
       name: manifest.name.clone(),
diff --git a/crates/wick/wick-config/src/v1/conversions.rs b/crates/wick/wick-config/src/v1/conversions.rs
index 467d0d3bb..d73dbe235 100644
--- a/crates/wick/wick-config/src/v1/conversions.rs
+++ b/crates/wick/wick-config/src/v1/conversions.rs
@@ -752,7 +752,7 @@ impl TryFrom<v1::FlowExpression> for ast::FlowExpression {
 
   fn try_from(expr: v1::FlowExpression) -> Result<Self> {
     Ok(match expr {
-      v1::FlowExpression::ConnectionDefinition(v) => ast::FlowExpression::ConnectionExpression(v.try_into()?),
+      v1::FlowExpression::ConnectionDefinition(v) => ast::FlowExpression::ConnectionExpression(Box::new(v.try_into()?)),
       v1::FlowExpression::BlockExpression(v) => ast::FlowExpression::BlockExpression(v.try_into()?),
     })
   }
@@ -976,7 +976,7 @@ impl TryFrom<ast::FlowExpression> for v1::FlowExpression {
 
   fn try_from(value: ast::FlowExpression) -> std::result::Result<Self, Self::Error> {
     match value {
-      ast::FlowExpression::ConnectionExpression(c) => Ok(Self::ConnectionDefinition(c.try_into()?)),
+      ast::FlowExpression::ConnectionExpression(c) => Ok(Self::ConnectionDefinition((*c).try_into()?)),
       ast::FlowExpression::BlockExpression(c) => Ok(Self::BlockExpression(c.try_into()?)),
     }
   }
diff --git a/crates/wick/wick-package/src/package.rs b/crates/wick/wick-package/src/package.rs
index 762245d48..e44ab29ed 100644
--- a/crates/wick/wick-package/src/package.rs
+++ b/crates/wick/wick-package/src/package.rs
@@ -17,12 +17,14 @@ use crate::Error;
 
 type BoxFuture<'a, T> = std::pin::Pin<Box<dyn Future<Output = T> + Send + 'a>>;
 
+type ProcessResult = (HashSet<PathBuf>, Vec<PackageFile>);
+
 fn process_assets(
   mut seen_assets: HashSet<PathBuf>,
   assets: Assets<AssetReference>,
   root_parent_dir: PathBuf,
   parent_dir: PathBuf,
-) -> BoxFuture<Result<(HashSet<PathBuf>, Vec<PackageFile>), Error>> {
+) -> BoxFuture<Result<ProcessResult, Error>> {
   let task = async move {
     let mut wick_files: Vec<PackageFile> = Vec::new();
     for asset in assets.iter() {
diff --git a/crates/wick/wick-packet/Cargo.toml b/crates/wick/wick-packet/Cargo.toml
index b1794ff72..f672b751a 100644
--- a/crates/wick/wick-packet/Cargo.toml
+++ b/crates/wick/wick-packet/Cargo.toml
@@ -19,6 +19,7 @@ maintenance = { status = "actively-developed" }
 default = []
 invocation = ["uuid", "seeded-random"]
 rt-tokio = ["tokio/rt"]
+datetime = ["chrono"]
 
 [dependencies]
 wick-interface-types = { workspace = true, features = ["typeid"] }
@@ -41,6 +42,8 @@ seeded-random = { workspace = true, optional = true }
 pin-project-lite = "0.2"
 base64-serde = "0.7.0"
 base64 = { workspace = true, default-features = false, features = ["alloc"] }
+# datetime feature
+chrono = { workspace = true, optional = true, default-features = false }
 
 [target.'cfg(target_family = "wasm")'.dependencies]
 wasmrs-guest = { workspace = true }
diff --git a/crates/components/wick-azure-sql/src/data.rs b/crates/wick/wick-packet/src/datetime.rs
similarity index 85%
rename from crates/components/wick-azure-sql/src/data.rs
rename to crates/wick/wick-packet/src/datetime.rs
index 1ff485b0e..dd2cf8f9d 100644
--- a/crates/components/wick-azure-sql/src/data.rs
+++ b/crates/wick/wick-packet/src/datetime.rs
@@ -1,6 +1,8 @@
-use chrono::NaiveDateTime;
+pub use chrono::NaiveDateTime;
 
-pub(crate) fn parse_date(v: &str) -> NaiveDateTime {
+#[must_use]
+/// Parse a date from a string in RFC3339 format, or in the format `%Y-%m-%d %H:%M:%S`.
+pub fn parse_date(v: &str) -> NaiveDateTime {
   use chrono::DateTime;
   let v: DateTime<chrono::Utc> = DateTime::parse_from_rfc3339(v)
     .unwrap_or_else(|_| {
diff --git a/crates/wick/wick-packet/src/lib.rs b/crates/wick/wick-packet/src/lib.rs
index b9acf8614..cd224e82d 100644
--- a/crates/wick/wick-packet/src/lib.rs
+++ b/crates/wick/wick-packet/src/lib.rs
@@ -77,6 +77,8 @@
 mod b64_bytes;
 mod collection_link;
 mod context;
+#[cfg(feature = "datetime")]
+mod datetime;
 mod entity;
 mod error;
 mod inherent;
@@ -92,6 +94,8 @@ mod wrapped_type;
 
 pub use collection_link::ComponentReference;
 pub use context::{ContextTransport, OperationConfig};
+#[cfg(feature = "datetime")]
+pub use datetime::{parse_date, NaiveDateTime};
 pub use entity::Entity;
 pub use error::{Error, ParseError};
 pub use inherent::InherentData;
diff --git a/crates/wick/wick-runtime/src/triggers/http.rs b/crates/wick/wick-runtime/src/triggers/http.rs
index 12394f0ba..67ec773fc 100644
--- a/crates/wick/wick-runtime/src/triggers/http.rs
+++ b/crates/wick/wick-runtime/src/triggers/http.rs
@@ -502,9 +502,9 @@ mod test {
   #[test_logger::test(tokio::test)]
   async fn test_rest_router() -> Result<()> {
     let crate_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
-    let manifest_dir = crate_dir.join("../../../examples/");
+    let manifest_dir = crate_dir.join("../../../examples/http/");
 
-    let yaml = manifest_dir.join("http-restapi.wick");
+    let yaml = manifest_dir.join("rest-router.wick");
     let app_config = config::WickConfiguration::fetch(yaml.to_string_lossy(), Default::default())
       .await?
       .try_app_config()?;
diff --git a/etc/integration/mssql.sh b/etc/integration/mssql.sh
index 101cd43fa..31167791c 100755
--- a/etc/integration/mssql.sh
+++ b/etc/integration/mssql.sh
@@ -39,6 +39,8 @@ init() {
   docker exec -it $container_name /opt/mssql-tools/bin/sqlcmd -S localhost -U $username -P "$test_pw" -d $db -Q "CREATE TABLE users (id INT IDENTITY(1,1) PRIMARY KEY, name VARCHAR(255) NOT NULL, email VARCHAR(255) NOT NULL);"
   echo "Creating user 'Test User'"
   docker exec -it $container_name /opt/mssql-tools/bin/sqlcmd -S localhost -U $username -P "$test_pw" -d $db -Q "INSERT INTO users (name, email) VALUES ('Test User', 'test_user@example.com');"
+  echo "Creating table 'num_types'"
+  docker exec -it $container_name psql -U $username -h localhost -d $db -c "CREATE TABLE num_types (u8 tinyint, i16 smallint, i32 int, i64 bigint, db_decimal decimal, db_numeric numeric, f32 real, f64 float);"
 }
 
 handle "$@"
\ No newline at end of file
diff --git a/etc/integration/postgres.sh b/etc/integration/postgres.sh
index 99eb3eb5b..9af4d1fab 100755
--- a/etc/integration/postgres.sh
+++ b/etc/integration/postgres.sh
@@ -38,6 +38,8 @@ init() {
   docker exec -it $container_name psql -U $username -h localhost -d $db -c "CREATE TABLE users (id SERIAL PRIMARY KEY, name VARCHAR(255) NOT NULL, email VARCHAR(255) NOT NULL);"
   echo "Creating user 'Test User'"
   docker exec -it $container_name psql -U $username -h localhost -d $db -c "INSERT INTO users (name, email) VALUES ('Test User', 'test_users@example.com');"
+  echo "Creating table 'num_types'"
+  docker exec -it $container_name psql -U $username -h localhost -d $db -c "CREATE TABLE num_types (id SERIAL PRIMARY KEY, i16 smallint, i32 integer, i64 bigint, db_decimal decimal, db_numeric numeric, f32 real, f64 double precision);"
 }
 
 handle "$@"
\ No newline at end of file
diff --git a/examples/db/flow-with-postgres.wick b/examples/db/flow-with-postgres.wick
new file mode 100644
index 000000000..71a6217fa
--- /dev/null
+++ b/examples/db/flow-with-postgres.wick
@@ -0,0 +1,32 @@
+name: mycli
+kind: wick/component@v1
+import:
+  - name: MYDB
+    component:
+      kind: wick/component/manifest@v1
+      ref: ./postgres-component.wick
+component:
+  kind: wick/component/composite@v1
+  operations:
+    - name: get_user
+      flow:
+        - <>.id -> MYDB::get_user[a].id
+        - a.output -> <>
+tests:
+  - name: assert_test_user
+    operation: get_user
+    input:
+      - name: id
+        data: 1
+      - name: id
+        flags:
+          done: true
+    output:
+      - name: output
+        data:
+          email: test_users@example.com
+          id: 1
+          name: Test User
+      - name: output
+        flags:
+          done: true
diff --git a/examples/postgres-component.yaml b/examples/db/postgres-component.wick
similarity index 82%
rename from examples/postgres-component.yaml
rename to examples/db/postgres-component.wick
index 1ea201e7f..a2e37c2cf 100644
--- a/examples/postgres-component.yaml
+++ b/examples/db/postgres-component.wick
@@ -13,10 +13,7 @@ component:
     - name: get_user
       inputs:
         - name: id
-          type: u32
-      outputs:
-        - name: output
-          type: object
+          type: i32
       query: SELECT * FROM users WHERE id = $1
       arguments:
         - id
@@ -26,9 +23,6 @@ component:
           type: string
         - name: email
           type: string
-      outputs:
-        - name: output
-          type: object
       query: INSERT INTO users(name, email) VALUES ($1, $2)
       arguments:
         - name
diff --git a/examples/db/postgres-numeric.wick b/examples/db/postgres-numeric.wick
new file mode 100644
index 000000000..9b4580a4a
--- /dev/null
+++ b/examples/db/postgres-numeric.wick
@@ -0,0 +1,89 @@
+name: my_component
+kind: wick/component@v1
+resources:
+  - name: DBADDR
+    resource:
+      kind: wick/resource/url@v1
+      url: postgres://postgres:$TEST_PASSWORD@$TEST_HOST:$POSTGRES_PORT/wick_test
+component:
+  kind: wick/component/sql@v1
+  resource: DBADDR
+  tls: false
+  operations:
+    - name: native_types
+      inputs:
+        - name: i16
+          type: i16
+        - name: i32
+          type: i32
+        - name: i64
+          type: i64
+        - name: f32
+          type: f32
+      query: |
+        INSERT INTO num_types (i16, i32, i64, f32) VALUES ($1,$2,$3,$4) RETURNING i16,i32,i64,f32
+      arguments:
+        - i16
+        - i32
+        - i64
+        - f32
+    - name: coerced_types
+      inputs:
+        - name: u16
+          type: u16
+        - name: u32
+          type: u32
+        - name: u64
+          type: u64
+        - name: f64
+          type: f64
+      query: |
+        INSERT INTO num_types (i16, i32, i64, f32) VALUES ($1,$2,$3,$4) RETURNING i16,i32,i64,f32
+      arguments:
+        - u16
+        - u32
+        - u64
+        - f64
+tests:
+  - name: native_types
+    operation: native_types
+    input:
+      - name: i16
+        data: 32767
+      - name: i32
+        data: 2147483647
+      - name: i64
+        data: 9223372036854775807
+      - name: f32
+        data: 3.4028234663852886e+38
+    output:
+      - name: output
+        data:
+          i16: 32767
+          i32: 2147483647
+          i64: 9223372036854775807
+          f32: 3.4028234663852886e+38
+      - name: output
+        flags:
+          done: true
+  - name: coerced_types
+    operation: coerced_types
+    input:
+      - name: u16
+        data: 32767
+      - name: u32
+        data: 2147483647
+      - name: u64
+        data: 9223372036854775807
+      - name: f64
+        data: 3.4028234663852886e+38
+    output:
+      - name: output
+        data:
+          i16: 32767
+          i32: 2147483647
+          i64: 9223372036854775807
+          f32: 3.4028234663852886e+38
+      - name: output
+        flags:
+          done: true
diff --git a/examples/postgres.yaml b/examples/db/wasm-calling-postgres.wick
similarity index 82%
rename from examples/postgres.yaml
rename to examples/db/wasm-calling-postgres.wick
index 602ac940f..847476cc5 100644
--- a/examples/postgres.yaml
+++ b/examples/db/wasm-calling-postgres.wick
@@ -16,9 +16,6 @@ import:
           inputs:
             - name: id
               type: i32
-          outputs:
-            - name: output
-              type: object
           query: SELECT name FROM users WHERE id = $1
           arguments:
             - id
@@ -28,6 +25,6 @@ triggers:
       name: main
       component:
         kind: wick/component/manifest@v1
-        ref: ../crates/integration/test-cli-with-db/component.yaml
+        ref: ../../crates/integration/test-cli-with-db/component.yaml
         provide:
           db: MYDB
diff --git a/examples/proxy.wick b/examples/http/proxy-router.wick
similarity index 100%
rename from examples/proxy.wick
rename to examples/http/proxy-router.wick
diff --git a/examples/http_with_component/app.wick b/examples/http/raw-router.wick
similarity index 100%
rename from examples/http_with_component/app.wick
rename to examples/http/raw-router.wick
diff --git a/examples/http-restapi.wick b/examples/http/rest-router.wick
similarity index 95%
rename from examples/http-restapi.wick
rename to examples/http/rest-router.wick
index 2bfb50231..954016f2b 100644
--- a/examples/http-restapi.wick
+++ b/examples/http/rest-router.wick
@@ -20,7 +20,7 @@ import:
   - name: sample
     component:
       kind: wick/component/manifest@v1
-      ref: ./component.wick
+      ref: ./rest-router/component.wick
 triggers:
   - kind: wick/trigger/http@v1
     resource: http
diff --git a/examples/component.wick b/examples/http/rest-router/component.wick
similarity index 100%
rename from examples/component.wick
rename to examples/http/rest-router/component.wick
diff --git a/examples/static.wick b/examples/http/staticfile-router.wick
similarity index 100%
rename from examples/static.wick
rename to examples/http/staticfile-router.wick


Test patch:
diff --git a/crates/bins/wick/tests/integration/run/postgres.toml b/crates/bins/wick/tests/integration/run/postgres.toml
index 6c323075d..4aa00591f 100644
--- a/crates/bins/wick/tests/integration/run/postgres.toml
+++ b/crates/bins/wick/tests/integration/run/postgres.toml
@@ -1,6 +1,6 @@
 #:schema https://raw.githubusercontent.com/assert-rs/trycmd/main/schema.json
 bin.name = "wick"
-args = ["run", "../../../examples/postgres.yaml"]
+args = ["run", "../../../examples/db/wasm-calling-postgres.wick"]
 stdout = """
 
 cli:db: in WebAssembly CLI component
diff --git a/crates/wick/flow-graph-interpreter/tests/validation.rs b/crates/wick/flow-graph-interpreter/tests/validation.rs
index 61f2ddca5..83d9baa42 100644
--- a/crates/wick/flow-graph-interpreter/tests/validation.rs
+++ b/crates/wick/flow-graph-interpreter/tests/validation.rs
@@ -103,7 +103,7 @@ async fn test_invalid_port() -> Result<()> {
   if let Err(InterpreterError::EarlyError(e)) = result {
     assert_eq!(
       e,
-      ValidationError::MissingConnection {
+      ValidationError::UnknownInput {
         port: "input".to_owned(),
         operation: "echo".to_owned(),
         component: "test".to_owned(),
diff --git a/crates/wick/wick-config/tests/v0_load_from_file.rs b/crates/wick/wick-config/tests/v0_load_from_file.rs
index 296519f16..135bb61ea 100644
--- a/crates/wick/wick-config/tests/v0_load_from_file.rs
+++ b/crates/wick/wick-config/tests/v0_load_from_file.rs
@@ -74,10 +74,10 @@ async fn load_shortform_yaml() -> Result<(), ManifestError> {
 
   assert_eq!(
     expr,
-    &FlowExpression::ConnectionExpression(ConnectionExpression::new(
+    &FlowExpression::ConnectionExpression(Box::new(ConnectionExpression::new(
       ConnectionTargetExpression::new(InstanceTarget::Input, "input", Default::default()),
       ConnectionTargetExpression::new(InstanceTarget::named("logger"), "input", Default::default())
-    ))
+    )))
   );
 
   Ok(())
diff --git a/crates/wick/wick-runtime/tests/triggers.rs b/crates/wick/wick-runtime/tests/triggers.rs
index 8ecfb8e46..6bc449e83 100644
--- a/crates/wick/wick-runtime/tests/triggers.rs
+++ b/crates/wick/wick-runtime/tests/triggers.rs
@@ -56,8 +56,7 @@ mod integration_test {
   use super::*;
   #[test_logger::test(tokio::test)]
   async fn cli_with_db() -> Result<()> {
-    // let manifest = load_app_yaml("./manifests/v1/app_config/postgres.yaml").await?;
-    let manifest = load_app_yaml("../../../examples/postgres.yaml").await?;
+    let manifest = load_app_yaml("../../../examples/db/wasm-calling-postgres.wick").await?;
     let resources = Arc::new(init_resources(&manifest)?);
 
     let trigger_config = &manifest.triggers()[0];