crystal-pg icon indicating copy to clipboard operation
crystal-pg copied to clipboard

Strange exception

Open horrendo opened this issue 6 years ago • 6 comments

Hi,

Am I doing something wrong here ?

Thanks,

Steve

horrendo avatar Jun 25 '18 21:06 horrendo

Can you share the code for your add_db postgres UDF? Or a simplified version that gives the same crystal error?

will avatar Jun 25 '18 21:06 will

I've done a bit more digging, and it seems that the exception is due to the notices raised during function execution. I created two small test functions:

log=# create function foo() returns text as $$ begin raise notice 'hello'; return 'abcde'; end; $$ language plpgsql;
CREATE FUNCTION
log=# select foo();
NOTICE:  hello
  foo  
-------
 abcde
(1 row)

log=# create or replace function foo2() returns text as $$ begin return 'abcde'; end; $$ language plpgsql;
CREATE FUNCTION

In a crystal program, 'select foo()' causes the exception whereas 'select foo2()' does not.

horrendo avatar Jun 25 '18 21:06 horrendo

I added:

SET client_min_messages=WARNING;

to my function and problem solved.

Happy now !!!

horrendo avatar Jun 25 '18 21:06 horrendo

Oh interesting. This is defiantly an edge case I didn't come across when implementing the pg protocol, that should be addressed.

will avatar Jun 25 '18 21:06 will

Thanks Will. While you have the hood open, another edge case (due to my stupidity):

require "db"
require "pg"

def blah
  uri = URI.new
  uri.scheme = "postgres"
  uri.user = ENV["PGUSER"]
  uri.password = ENV["PGPASSWORD"]?
  uri.host = ENV["PGHOST"]?
  uri.port = ENV["PGPORT"]?.try &.to_i
  uri.path = "/" + ENV["PGDATABASE"]
  DB.open uri do |db|
    puts "Connected to DB"
    db.transaction do |trx|
      puts "Transaction started"
      trx.connection.query "SELECT 'abc'" do |rset|
        trx.commit
      end
    end
  end
end

blah()

It is caused by the commit inside the query block:

[~/git/pg_csvlog]$ crystal t.cr
Connected to DB
Transaction started
Unhandled exception: Expected PQ::Frame::ParseComplete but got PQ::Frame::Unknown(@type='D', @bytes=Bytes[0, 1, 0, 0, 0, 3, 97, 98, 99]) (Exception)
  from lib/pg/src/pq/connection.cr:296:7 in 'expect_frame'
  from lib/pg/src/pq/connection.cr:294:5 in 'expect_frame'
  from lib/pg/src/pg/statement.cr:18:5 in 'perform_query'
  from lib/pg/src/pg/statement.cr:35:14 in 'perform_exec'
  from lib/db/src/db/statement.cr:97:14 in 'perform_exec_and_release'
  from lib/db/src/db/statement.cr:67:7 in 'exec'
  from lib/db/src/db/query_methods.cr:263:7 in 'exec'
  from lib/db/src/db/connection.cr:98:7 in 'perform_commit_transaction'
  from lib/db/src/db/transaction.cr:50:7 in 'commit'
  from t.cr:17:9 in 'blah'
  from t.cr:23:1 in '__crystal_main'
  from /usr/local/Cellar/crystal-lang/0.25.0/src/crystal/main.cr:104:5 in 'main_user_code'
  from /usr/local/Cellar/crystal-lang/0.25.0/src/crystal/main.cr:93:7 in 'main'
  from /usr/local/Cellar/crystal-lang/0.25.0/src/crystal/main.cr:133:3 in 'main'

horrendo avatar Jun 25 '18 22:06 horrendo

that D frame is your data row (1 column, length 3, then ascii 97 for 'a' and so on) but coming at an unexpected time with the block there. This one is probably because the stdlib interface was added a little later.

I'm not 100% sure what is expected to work or not work inside a query block, but it shouldn't be an unexpected frame error, either way.

will avatar Jun 25 '18 23:06 will