ydb-platform / ydb

YDB is an open source Distributed SQL Database that combines high availability and scalability with strong consistency and ACID transactions
https://ydb.tech
Apache License 2.0
4k stars 565 forks source link

[pg] Segfault by incorrect query to pg_tables #7287

Closed rekby closed 2 months ago

rekby commented 3 months ago

Reproduce:

  1. https://github.com/ydb-platform/ydb/wiki/Local-run-postgres-tests

  2. Create any table by separate query:

echo "drop table t; create table t(id serial primary key);" | psql postgres://root:1234@localhost:5432/local
  1. Execute right after that (in few seconds):
    echo "select tablename from pg_tables where hasindexes='pg_proc';" | psql postgres://root:1234@localhost:5432/local

It may be some race: the problem doesn't reproduce if starts ydb with exists table or when I wait few minutes before execute incorrect query.

rekby commented 3 months ago

may be like https://github.com/ydb-platform/ydb/issues/7286

qrort commented 3 months ago

Segfault has a corrupted backtrace, and the only frame of it i can see is longjmp. It hints that some exception, namely, { <main>: Error: ydb/library/yql/minikql/computation/mkql_value_builder.cpp:52: Terminate was called, reason(57): ERROR: invalid input syntax for type boolean: "pg_proc" } is not handled correctly.

pg_tables implementation gives out correct CellVec, and it is successfully passed to execution. Here it throws an exception after trying to convert "pg_proc" to boolean, and I am unable to go through the line with gdb as it hangs indefinetely.

I tried to replicate the pattern with something like this:

echo "drop table t; create table t(id boolean primary key, value boolean);" | psql postgres://root:1234@localhost:5432/local
echo "insert into t values (true, true)" | psql postgresql://root:1234@localhost:5432/local
echo "SELECT value from t where value='pg_proc';" | psql postgresql://root:1234@localhost:5432/local

if i spam only the last query, no segfault occurs. But if i do it like this:

echo "drop table t; create table t(id boolean primary key, value boolean);" | psql postgres://root:1234@localhost:5432/local
echo "insert into t values (true, true)" | psql postgresql://root:1234@localhost:5432/local
echo "select tablename from pg_tables where hasindexes='pg_proc';" | psql postgres://root:1234@localhost:5432/local
echo "SELECT value from t where value='pg_proc';" | psql postgresql://root:1234@localhost:5432/local

the last query fails. it is seen in the logs that pg_tables query terminates successfully, while the next causes an error.

I'm not sure what causes the behaviour. Maybe the fact that CellVec is created w\o TScopedAlloc (see here)plays a role, but I do not really know.