From b482a2c99e9a296408c18940bfdebc0505bdf155 Mon Sep 17 00:00:00 2001 From: Yevhenii Melnyk Date: Wed, 1 Feb 2023 17:29:54 +0100 Subject: [PATCH 1/3] [sqllogictest] Support `pg_typeof` --- datafusion/core/Cargo.toml | 1 + .../sqllogictests/src/engines/postgres/mod.rs | 4 + .../src/engines/postgres/types.rs | 27 +++ .../pg_compat/pg_compat_type_coercion.slt | 177 ++++++++++++++++++ 4 files changed, 209 insertions(+) create mode 100644 datafusion/core/tests/sqllogictests/src/engines/postgres/types.rs create mode 100644 datafusion/core/tests/sqllogictests/test_files/pg_compat/pg_compat_type_coercion.slt diff --git a/datafusion/core/Cargo.toml b/datafusion/core/Cargo.toml index 6b59e48ccfbb6..6cde4aa8e4fe0 100644 --- a/datafusion/core/Cargo.toml +++ b/datafusion/core/Cargo.toml @@ -113,6 +113,7 @@ doc-comment = "0.3" env_logger = "0.10" half = "2.2.1" parquet-test-utils = { path = "../../parquet-test-utils" } +postgres-protocol = "0.6.4" postgres-types = { version = "0.2.4", features = ["derive", "with-chrono-0_4"] } rstest = "0.16.0" rust_decimal = { version = "1.27.0", features = ["tokio-pg"] } diff --git a/datafusion/core/tests/sqllogictests/src/engines/postgres/mod.rs b/datafusion/core/tests/sqllogictests/src/engines/postgres/mod.rs index 2d7f02b408489..84adde90d94db 100644 --- a/datafusion/core/tests/sqllogictests/src/engines/postgres/mod.rs +++ b/datafusion/core/tests/sqllogictests/src/engines/postgres/mod.rs @@ -30,6 +30,9 @@ use chrono::{NaiveDate, NaiveDateTime, NaiveTime}; use postgres_types::Type; use rust_decimal::Decimal; use tokio_postgres::{Column, Row}; +use types::PgRegtype; + +mod types; // default connect string, can be overridden by the `PG_URL` environment variable const PG_URI: &str = "postgresql://postgres@127.0.0.1/test"; @@ -245,6 +248,7 @@ fn cell_to_string(row: &Row, column: &Column, idx: usize) -> String { } Type::FLOAT4 => make_string!(row, idx, f32, f32_to_str), Type::FLOAT8 => make_string!(row, idx, f64, f64_to_str), + Type::REGTYPE => make_string!(row, idx, PgRegtype), _ => unimplemented!("Unsupported type: {}", column.type_().name()), } } diff --git a/datafusion/core/tests/sqllogictests/src/engines/postgres/types.rs b/datafusion/core/tests/sqllogictests/src/engines/postgres/types.rs new file mode 100644 index 0000000000000..67f6f583f6a58 --- /dev/null +++ b/datafusion/core/tests/sqllogictests/src/engines/postgres/types.rs @@ -0,0 +1,27 @@ +use postgres_types::Type; +use tokio_postgres::types::FromSql; + +pub struct PgRegtype { + value: String, +} + +impl<'a> FromSql<'a> for PgRegtype { + fn from_sql( + _: &Type, + buf: &'a [u8], + ) -> Result> { + let oid = postgres_protocol::types::oid_from_sql(buf)?; + let value = Type::from_oid(oid).ok_or("bad type")?.to_string(); + Ok(PgRegtype { value }) + } + + fn accepts(ty: &Type) -> bool { + matches!(*ty, Type::REGTYPE) + } +} + +impl ToString for PgRegtype { + fn to_string(&self) -> String { + self.value.clone() + } +} diff --git a/datafusion/core/tests/sqllogictests/test_files/pg_compat/pg_compat_type_coercion.slt b/datafusion/core/tests/sqllogictests/test_files/pg_compat/pg_compat_type_coercion.slt new file mode 100644 index 0000000000000..75b46f7ec743d --- /dev/null +++ b/datafusion/core/tests/sqllogictests/test_files/pg_compat/pg_compat_type_coercion.slt @@ -0,0 +1,177 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at + +# http://www.apache.org/licenses/LICENSE-2.0 + +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +query ?? +select true and true, false and false; +---- +true false + + +onlyif DataFusion +query ?? +select arrow_typeof(true and true), arrow_typeof(false and false); +---- +Boolean Boolean + + +onlyif postgres +query ?? +select pg_typeof(true and true), pg_typeof(false and false); +---- +bool bool + +query ?? +select true or true, false or false; +---- +true false + + +onlyif DataFusion +query ?? +select arrow_typeof(true or true), arrow_typeof(false or false); +---- +Boolean Boolean + + +onlyif postgres +query ?? +select pg_typeof(true or true), pg_typeof(false or false); +---- +bool bool + + +query ?? +select false and true, true and false; +---- +false false + + +onlyif DataFusion +query ?? +select arrow_typeof(false and true), arrow_typeof(true and false); +---- +Boolean Boolean + + +onlyif postgres +query ?? +select pg_typeof(false and true), pg_typeof(true and false); +---- +bool bool + + +query ?? +select false or true, true or false; +---- +true true + + +onlyif DataFusion +query ?? +select arrow_typeof(false or true), arrow_typeof(true or false); +---- +Boolean Boolean + + +onlyif postgres +query ?? +select pg_typeof(false or true), pg_typeof(true or false); +---- +bool bool + + +# TODO: run for DataFusion as well after #4335 +onlyif postgres +query ?? +select null and null, null or null; +---- +NULL NULL + + +# TODO: uncomment after #4335 +#onlyif DataFusion +#query ?? +#select arrow_typeof(null and null), arrow_typeof(null or null); +#---- +#Boolean Boolean + + +onlyif postgres +query ?? +select pg_typeof(null and null), pg_typeof(null or null); +---- +bool bool + + +onlyif postgres +query ???? +select true and null, + false and null, + null and true, + null and false; +---- +NULL false NULL false + + +onlyif DataFusion +query ???? +select arrow_typeof(true and null), + arrow_typeof(false and null), + arrow_typeof(null and true), + arrow_typeof(null and false); +---- +Boolean Boolean Boolean Boolean + + +onlyif postgres +query ???? +select pg_typeof(true and null), + pg_typeof(false and null), + pg_typeof(null and true), + pg_typeof(null and false); +---- +bool bool bool bool + + +onlyif postgres +query ???? +select true or null, + false or null, + null or true, + null or false; +---- +true NULL true NULL + + +onlyif DataFusion +query ???? +select arrow_typeof(true or null), + arrow_typeof(false or null), + arrow_typeof(null or true), + arrow_typeof(null or false); +---- +Boolean Boolean Boolean Boolean + + +onlyif postgres +query ???? +select pg_typeof(true or null), + pg_typeof(false or null), + pg_typeof(null or true), + pg_typeof(null or false); +---- +bool bool bool bool From 378f3043de0967eb0fcd63b191cc29d836727696 Mon Sep 17 00:00:00 2001 From: Yevhenii Melnyk Date: Wed, 1 Feb 2023 17:32:27 +0100 Subject: [PATCH 2/3] add newline --- .../test_files/pg_compat/pg_compat_type_coercion.slt | 1 + 1 file changed, 1 insertion(+) diff --git a/datafusion/core/tests/sqllogictests/test_files/pg_compat/pg_compat_type_coercion.slt b/datafusion/core/tests/sqllogictests/test_files/pg_compat/pg_compat_type_coercion.slt index 75b46f7ec743d..aee35e08f59f1 100644 --- a/datafusion/core/tests/sqllogictests/test_files/pg_compat/pg_compat_type_coercion.slt +++ b/datafusion/core/tests/sqllogictests/test_files/pg_compat/pg_compat_type_coercion.slt @@ -34,6 +34,7 @@ select pg_typeof(true and true), pg_typeof(false and false); ---- bool bool + query ?? select true or true, false or false; ---- From 69d9371bbf72164f7c9378565610215734a07681 Mon Sep 17 00:00:00 2001 From: Yevhenii Melnyk Date: Wed, 1 Feb 2023 17:37:17 +0100 Subject: [PATCH 3/3] Add a license header --- .../sqllogictests/src/engines/postgres/types.rs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/datafusion/core/tests/sqllogictests/src/engines/postgres/types.rs b/datafusion/core/tests/sqllogictests/src/engines/postgres/types.rs index 67f6f583f6a58..0c66150d1bb4e 100644 --- a/datafusion/core/tests/sqllogictests/src/engines/postgres/types.rs +++ b/datafusion/core/tests/sqllogictests/src/engines/postgres/types.rs @@ -1,3 +1,20 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + use postgres_types::Type; use tokio_postgres::types::FromSql;