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

Confusion around PG::InvalidChangeOfResultFields error #468

Closed
coffenbacher opened this issue Jun 21, 2022 · 4 comments
Closed

Confusion around PG::InvalidChangeOfResultFields error #468

coffenbacher opened this issue Jun 21, 2022 · 4 comments

Comments

@coffenbacher
Copy link

I seem to have stumbled across a rather unique error, so I'm having trouble finding information on Google about it.

For background, I'm using .stream_each to stream data out of a WAL slot so that I can process it:

def peek_sql
    sql = <<-SQL
    select data from pg_logical_slot_peek_changes(
      :slot_name, NULL, NULL,
      'format-version', '2',
      'include-timestamp', 'on',
      'include-transaction', 'true',
      'include-lsn','true',
      'include-pk', 'true',
      'write-in-chunks', 'true',
      'actions', 'insert,update,delete');
    SQL

    ApplicationRecord.sanitize_sql_for_assignment([sql, slot_name: slot_name])
end
    connection = ActiveRecord::Base.connection_pool.checkout
    connection.raw_connection.send_query(peek_sql)
    connection.raw_connection.set_single_row_mode
    connection.raw_connection.get_result.stream_each { |row| process_row(row) }

This is yielding this error:

/usr/src/app/app/commands/wal/archive.rb:28:in `stream_each': number of fields must not change in single row mode (PG::InvalidChangeOfResultFields)

I am struggling to gather more debug information because it is currently only happening in production, and it seems like the automatic retries we have configured allow the tricky data to succeed subsequently.

I am also not particularly sure what the semantic meaning of the error is: there is really only a single field (data) returned by the query so I'm confused how it's changing.

If it helps at all, I believe that this error was first seen soon after running a migration to add or remove a column.

Any information about what the error means or how to address it would be most welcome.

@larskanis
Copy link
Collaborator

The error InvalidChangeOfResultFields originates from here:

ruby-pg/ext/pg_result.c

Lines 1481 to 1482 in 766c175

if( nfields != PQnfields(pgresult) )
rb_raise( rb_eInvalidChangeOfResultFields, "number of fields must not change in single row mode");
This was meant as a precaution only, when I implemented the code, to get an early error, if this expectation fails.

The expectation that the number of columns shouldn't change originates from here: https://www.postgresql.org/docs/current/libpq-single-row-mode.html where it's stated:

All of these PGresult objects will contain the same row description data (column names, types, etc) that an ordinary PGresult object for the query would have.

If I remember correctly, I didn't find a way to trigger that error, so that there is no spec to it. So congrats on finding such a case! 😅

@larskanis
Copy link
Collaborator

It wasn't too difficult to find a test case. I'd like to add such a test case and extend the error message while being over it in #469.

Could it be that you have another query in process_row or somewhere else using the same connection object?

@larskanis
Copy link
Collaborator

@coffenbacher Did you find the root cause for InvalidChangeOfResultFields error? Can the ticket be closed?

@coffenbacher
Copy link
Author

Hi @larskanis, this ticket can be closed, thanks! Unfortunately I never found out much more about what was going on. I think restarting my server resolved it IIRC.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants