From 3df9533af39d984af204b53a3558dbd5f5690845 Mon Sep 17 00:00:00 2001 From: Kaitmazian Maksim <m.kaitmazian@picodata.io> Date: Thu, 11 Jul 2024 14:29:50 +0300 Subject: [PATCH] feat(pgproto): support sending any values --- src/pgproto/backend/describe.rs | 3 +-- src/pgproto/value.rs | 1 + test/pgproto/types_test.py | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/src/pgproto/backend/describe.rs b/src/pgproto/backend/describe.rs index 75b7feb354..7724a93ede 100644 --- a/src/pgproto/backend/describe.rs +++ b/src/pgproto/backend/describe.rs @@ -219,14 +219,13 @@ impl MetadataColumn { fn pg_type_from_sbroad(sbroad: &SbroadType) -> PgResult<Type> { match sbroad { SbroadType::Integer | SbroadType::Unsigned => Ok(Type::INT8), - SbroadType::Map | SbroadType::Array => Ok(Type::JSON), + SbroadType::Map | SbroadType::Array | SbroadType::Any => Ok(Type::JSON), SbroadType::String => Ok(Type::TEXT), SbroadType::Boolean => Ok(Type::BOOL), SbroadType::Double => Ok(Type::FLOAT8), SbroadType::Decimal => Ok(Type::NUMERIC), SbroadType::Uuid => Ok(Type::UUID), SbroadType::Datetime => Ok(Type::TIMESTAMPTZ), - SbroadType::Any => Ok(Type::ANY), // According to tarantool [documentation](https://www.tarantool.io/en/doc/latest/reference/reference_sql/sql_user_guide/#sql-data-type-conversion): // NUMBER values have the same range as DOUBLE values. But NUMBER values may also be integers. // diff --git a/src/pgproto/value.rs b/src/pgproto/value.rs index 999bc28ace..bd8cb3d0f0 100644 --- a/src/pgproto/value.rs +++ b/src/pgproto/value.rs @@ -389,6 +389,7 @@ impl PgValue { let datetime = deserialize_rmpv_ext(&value)?; Ok(PgValue::Timestamptz(datetime)) } + (_any, Type::JSON | Type::JSONB) => Ok(PgValue::Json(Json(value))), (value, ty) => Err(PgError::FeatureNotSupported(format!( "{value:?} cannot be represented as a value of type {ty:?}" diff --git a/test/pgproto/types_test.py b/test/pgproto/types_test.py index e8582677cc..c9bde12bf7 100644 --- a/test/pgproto/types_test.py +++ b/test/pgproto/types_test.py @@ -468,3 +468,35 @@ def test_datetime(postgres: Postgres): # test binary encoding cur = conn.execute(""" SELECT * FROM T; """, binary=True) assert sorted(cur.fetchall()) == [(d1,), (d2,)] + + +# Verify that we can read from all system tables without errors. +def test_select_from_system_tables(postgres: Postgres): + user = "postgres" + password = "Passw0rd" + host = postgres.host + port = postgres.port + + # create a postgres user using a postgres compatible password + postgres.instance.sql( + f"CREATE USER \"{user}\" WITH PASSWORD '{password}' USING md5" + ) + # grant read on tables + postgres.instance.sql(f'GRANT READ TABLE TO "{user}"', sudo=True) + + # connect to the server and enable autocommit as we + # don't support interactive transactions + conn = psycopg.connect( + f"postgres://{user}:{password}@{host}:{port}?sslmode=disable" + ) + conn.autocommit = True + + # at the beginning there should be only '_pico' tables + cursor = conn.execute(""" SELECT "name" from "_pico_table" """) + tables = [row[0] for row in cursor.fetchall()] + + # read from all tables + for table in tables: + sql = f""" SELECT * from "{table}" """ + cur = conn.execute(bytes(sql, "utf-8")) + cur.fetchall() -- GitLab