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

Fetching Binary Data #3

Closed
kjurka opened this issue Jul 18, 2014 · 4 comments
Closed

Fetching Binary Data #3

kjurka opened this issue Jul 18, 2014 · 4 comments

Comments

@kjurka
Copy link

kjurka commented Jul 18, 2014

The fact that http_get returns varchar prevents this from being used to return binary data. I was specifically trying to fetch some images from a webserver.

@pramsey
Copy link
Owner

pramsey commented Jul 19, 2014

Hm, the data should be copied into the memory segment without alteration. Is it possible to cast it into a bytea and use it?

@kjurka
Copy link
Author

kjurka commented Jul 19, 2014

The problem is with bytes with a value of zero. There is no length field for varchar, it's null terminated. So your data will be truncated at the first zero.

@pramsey
Copy link
Owner

pramsey commented Dec 18, 2014

I've updated the documentation, and ensured the core code treats all data in a "binary clean" way, so you just need to use the right magic function to convert the varchar content into a bytea: use the textsend(text) function.

    WITH 
      http AS ( 
        SELECT * FROM http_get('http://localhost/PoweredByMacOSXLarge.gif') 
      ), 
      headers AS (
        SELECT (unnest(headers)).* FROM http
      ) 
    SELECT 
      http.content_type,
      length(textsend(http.content)) AS length_binary, 
      headers.value AS length_headers 
    FROM http, headers 
    WHERE field = 'Content-Length';

And for my example, I get this.

     content_type | length_binary | length_headers 
    --------------+---------------+----------------
     image/gif    |         31958 | 31958

You can see the underlying data is still there, and the length retrieved (as noted in the headers) is the same as the length in the underlying object (as measured after casting to bytea with textsend(text)

@mclei-asw
Copy link

This recommendation does not work, when client charset is different from database charset. For example, when my database charset is UTF-8 and client charset is WINDOWS-1250, then I get error about conversion:
ERROR: invalid byte sequence for encoding "UTF8": 0xe2 0xe3 0xcf

I have solved it be force defining SET client_encoding = 'UTF8' for the function, which calls the http_post:

create or replace function test (
  in URL text,
  in RequestData text,
  in ContentType text
)  returns test_rs
language plpgsql SET client_encoding = 'UTF8' as $$
declare
  l_Result                 test_rs;
begin
  select status, content_type, textsend(content) into l_Result.STATUS, l_Result.CONTENTTYPE, l_Result.CONTENT
    from public.http_post(URL, RequestData, ContentType);
  return l_Result;
end; $$;

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

3 participants