Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added test to catch #39 #41

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/validation-rust.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ jobs:
file: Dockerfile.examples
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache-new
context: .
- # Temp fix
# https://github.com/docker/build-push-action/issues/252
# https://github.com/moby/buildkit/issues/1896
Expand Down Expand Up @@ -157,6 +158,7 @@ jobs:
# Run only integration tests with `--test '*'`
run: cargo test -p udf-examples --test '*' --features backend
- name: Print docker logs
if: always()
run: |
docker logs mdb-example-container
# If any critical / debug options were printed, error out
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile.examples
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,6 @@ RUN --mount=type=cache,target=/usr/local/cargo/registry \
&& mkdir /output \
&& cp target/release/libudf_examples.so /output

FROM mariadb:10.9
FROM mariadb:10.10

COPY --from=build /output/* /usr/lib/mysql/plugin/
21 changes: 20 additions & 1 deletion udf-examples/tests/lookup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ mod backend;
use backend::get_db_connection;
use diesel::dsl::sql;
use diesel::prelude::*;
use diesel::sql_types::{Nullable, Text};
use diesel::sql_types::{Nullable, Text, Untyped};

const SETUP: [&str; 1] = ["create or replace function lookup6
returns string
Expand Down Expand Up @@ -43,3 +43,22 @@ fn test_nonexistant() {

assert!(res.0.is_none());
}

#[test]
fn test_sql_buffer_bug() {
// This is intended to catch a buffer problem in mysql/mariadb
// See link: https://github.com/pluots/sql-udf/issues/39

let conn = &mut get_db_connection(&SETUP);

sql::<(Untyped,)>("set @testval = (select lookup6('0.0.0.0'))")
.execute(conn)
.unwrap();

let res: (Option<String>,) =
sql::<(Nullable<Text>,)>("select regexp_replace(@testval,'[:.]','')")
.get_result(conn)
.expect("bad result");

assert_eq!(res.0.unwrap(), "ffff0000");
}
52 changes: 49 additions & 3 deletions udf/src/wrapper/debug.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#![cfg(feature = "logging-debug")]

use std::any::type_name;
use std::ffi::{c_char, c_uchar};
use std::ffi::{c_char, c_uchar, c_ulong};

use cfg_if::cfg_if;
use udf_sys::{UDF_ARGS, UDF_INIT};
Expand Down Expand Up @@ -74,7 +74,6 @@ pub unsafe fn pre_add_call<T>(
}
}

#[allow(dead_code)]
pub unsafe fn pre_clear_call<T>(initid: *const UDF_INIT, error: *const c_uchar) {
udf_log!(Debug: "entering clear for `{}`", type_name::<T>());

Expand All @@ -87,7 +86,6 @@ pub unsafe fn pre_clear_call<T>(initid: *const UDF_INIT, error: *const c_uchar)
}
}

#[allow(dead_code)]
pub unsafe fn pre_remove_call<T>(
initid: *const UDF_INIT,
args: *const UDF_ARGS,
Expand Down Expand Up @@ -142,3 +140,51 @@ pub unsafe fn post_process_call<T>(
}
}
}

pub unsafe fn pre_process_call_buf<T>(
initid: *const UDF_INIT,
args: *const UDF_ARGS,
result: *const c_char,
length: *const c_ulong,
is_null: *const c_uchar,
error: *const c_uchar,
) {
udf_log!(Debug: "entering process for `{}`", type_name::<T>());

cfg_if! {
if #[cfg(feature = "logging-debug-calls")] {
udf_log!(Debug: "Data receive state at process:");
dbg!(&*initid);
dbg!(&*args);
dbg!(result);
dbg!(&*length);
dbg!(&*is_null);
dbg!(&*error);
}
}
}

pub unsafe fn post_process_call_buf<T>(
initid: *const UDF_INIT,
args: *const UDF_ARGS,
result: *const c_char,
length: *const c_ulong,
is_null: *const c_uchar,
error: *const c_uchar,
ret: *const c_char,
) {
udf_log!(Debug: "exiting process for `{}`", type_name::<T>());

cfg_if! {
if #[cfg(feature = "logging-debug-calls")] {
udf_log!(Debug: "Data return state at process:");
dbg!(&*initid);
dbg!(&*args);
dbg!(result);
dbg!(&*length);
dbg!(&*is_null);
dbg!(&*error);
dbg!(ret);
}
}
}
10 changes: 6 additions & 4 deletions udf/src/wrapper/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ unsafe fn ret_callback<R>(
/// Apply the `process` function for any implementation returning a nonbuffer type
/// (`f64`, `i64`)
#[inline]
#[allow(clippy::let_and_return)]
pub unsafe fn wrap_process_basic<U, R>(
initid: *mut UDF_INIT,
args: *mut UDF_ARGS,
Expand Down Expand Up @@ -91,6 +92,7 @@ where
/// Apply the `process` function for any implementation returning an optional
/// nonbuffer type (`Option<f64>`, `Option<i64>`)
#[inline]
#[allow(clippy::let_and_return)]
pub unsafe fn wrap_process_basic_option<U, R>(
initid: *mut UDF_INIT,
args: *mut UDF_ARGS,
Expand Down Expand Up @@ -136,7 +138,7 @@ where
for<'a> <U as BasicUdf>::Returns<'a>: AsRef<[u8]>,
{
#[cfg(feature = "logging-debug")]
debug::pre_process_call::<U>(initid, args, is_null, error);
debug::pre_process_call_buf::<U>(initid, args, result, length, is_null, error);

let cfg = UdfCfg::from_raw_ptr(initid);
let arglist = ArgList::from_raw_ptr(args);
Expand All @@ -159,7 +161,7 @@ where
cfg.store_box(b);

#[cfg(feature = "logging-debug")]
debug::post_process_call::<U>(initid, args, is_null, error);
debug::post_process_call_buf::<U>(initid, args, result, length, is_null, error, ret);

ret
}
Expand All @@ -181,7 +183,7 @@ where
B: AsRef<[u8]>,
{
#[cfg(feature = "logging-debug")]
debug::pre_process_call::<U>(initid, args, is_null, error);
debug::pre_process_call_buf::<U>(initid, args, result, length, is_null, error);

let cfg = UdfCfg::from_raw_ptr(initid);
let arglist = ArgList::from_raw_ptr(args);
Expand All @@ -208,7 +210,7 @@ where
cfg.store_box(b);

#[cfg(feature = "logging-debug")]
debug::post_process_call::<U>(initid, args, is_null, error);
debug::post_process_call_buf::<U>(initid, args, result, length, is_null, error, ret);

ret
}
Expand Down