-
Notifications
You must be signed in to change notification settings - Fork 695
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
BUG: can't call parameterized distributed procedures outside an explicit transaction in Citus 12.1.3 (but not 12.1.0?) #7597
Comments
I have tried to reproduce this using the below python code. However on both 12.1.0 and 12.1.3, procedure f is called, it throws division by 0 exception and nothing is inserted to the table t. Is anything missing in this code?
|
I am not familiar with the python client, but I think there are two problems with that code.
|
Any luck reproducing this? |
I was able to replicate the issue with Npgsql on both Citus versions 12.1.3 and 12.1.0. Here is the code I executed:
Additionally, I attempted to simulate the same behavior using another library:
In this case, the behavior was as expected. My experience with Npgsql is somewhat limited, but here’s my take on the issue. It seems like the INSERT works and gets committed right away because of autocommit mode. However, the CALL fails on the client side due to a parameter binding problem in Npgsql. This error happens before the distributed transaction can complete on the worker nodes, so Citus doesn’t roll back the INSERT. |
I don't know what
does exactly, e.g. whether it's going to use actual SQL-level parameters for the values 1, 2, 2. The documentation is not clear on this point, either. It looks like it may well be passing literals and not using SQL-level parameters. Anyway, if it was due to a client-side problem in Npgsql, that would raise the question of why the problem doesn't occur if you don't call |
You're correct; when the function isn't distributed, it runs like a regular PostgreSQL function, resulting in a typical PostgreSQL error (22012: division by zero).
To help identify whether this is a bug in Citus or a client-side issue, tried executing the function directly using psql without involving the client driver (Npgsql or psycopg2).
It points more towards a client-side issue. Tried to simplify the query in the client code to ensure the parameters are passed in a basic form and check if the same issue occurs.
It could indicate that the issue arises when binding parameters dynamically rather than being an inherent issue with Citus. I encountered the same error when I tried both of these.
It seems likely that this error happens because of a mismatch between how the client sends parameters and how the server expects them, particularly with prepared statements. Since the function works fine when run directly on the server, the issue might be related to how the client interacts with the distributed Citus setup. The way positional parameter binding works in Npgsql may differ from how PostgreSQL handles those placeholders, so that could be part of the problem. |
I don't agree that it's a client-side problem, but it only happens when specifying parameters at the SQL (prepared statement) level. Clients that transform parameters into literals will not reproduce the problem. Running the function without parameters will not reproduce the problem. Parameter binding works in Npgsql for this function but only if you didn't previously call According to my original comments:
There was a similar bug reported previously - #7242 - which was also related to parameterized distributed functions called outside explicit transactions. It may be related, and it was a server-side problem. |
Do you already have logs set with My end I received these logs. Do you have similar one?
|
In Citus 12.1.3, when calling a distributed procedure in a batch of SQL statements, the CALL statement appears to execute in a different transaction from the rest of the statements in the batch. Also, it is generally impossible to call distributed procedures with batch parameters as arguments to the procedure. This behavior is not observed in Citus 12.1.0.
Repro steps
First, perform this setup:
Second, call the procedure in a parameterized batch of SQL statements:
In this batch, I used parameters
@0
= 1 and@1
= 2, but the specific values don't matter. The batch was sent with the Npgsql library, but any library that allows sending parameterized batches should be able to reproduce this bug. (Don't try putting the statements into a SQL procedure and calling it. That's not likely to reproduce the problem. Use a client library to send the parameterized batch.) Example Npgsql code:Expected behavior:
f(1, 2)
should be called, and fail with a division by zero error.Actual behavior:
f
is not called. Instead, an error occurs: "42P02: there is no parameter $1"Additional Comments
CALL f(1, @0);
it will fail.create_distributed_function
, the problem does not occur.BEGIN; INSERT ...; CALL ...; COMMIT;
CALL f(1, 2);
f
is supposed to succeed or fail. It never gets called in the first place.The text was updated successfully, but these errors were encountered: