I want to generate a PDF in plperlu, store it in the database and then add it to an email as an attachment.
I am using PDF::Report to generate the PDF. The code looks like this:-
CREATE OR REPLACE FUNCTION workflow.make_pdf(report_template json, report_json json)
RETURNS bytea AS
$BODY$
use strict;
use PDF::Report;
my $pdf = new PDF::ReportNG(PageSize => 'A4', PageOrientation => "Landscape");
...
lots of tricky stuff to make PDF
...
return $pdf->Finish();
$BODY$ LANGUAGE plperlu;
This errors with invalid input syntax for type bytea which I assume is something to do with the encoding of the PDF document created.
The document itself is fine as $pdf->saveAs('/tmp/test.pdf'); creates a document that is perfectly readable.
I tried base64 encoding the result before returning it as the attachment to email will need to be in base64.
return MIME::base64::encode($pdf->Finish());
This removed the error, I can then store it in a table with:-
INSERT INTO weekly_report_pdfs(report)
VALUES (make_pdf(report_template,report_json));
Which also works fine, and can be attached to an email, but the corruption problem persists after the base64 decode.
Exporting the file directly from the database and running base64 -d test.b64 gives an invalid input error after only one line.
This appears to be something to do with the way postgres chucks bytea, as the file looks like this:-
MDA0OTY1MSAwMDAwMCBuIAowMDAwMDQ5ODU0IDAwMDAwIG4gCjAwMDAwNTAxNjcgMDAwMDAgbiAK\\012dHJhaWxlcgo8PCAvUm9vdCAxIDAgUiAvU2l6ZSA0MCAvSW5mbyA0IDAgUiA+PgpzdGFydHhyZWYK\\012
With lots of \012 separators.
Any ideas, I've been at this for hours and am completely stumped.
Returning binary from plperl
When declared as returning bytea, a pl/perl function must actually return a postgresql text representation for bytea.
Consider this excerpt from PL/Perl Functions and Arguments in the doc (and more specifically the last sentence):
Anything in a function argument that is not a reference is a string,
which is in the standard PostgreSQL external text representation for
the relevant data type. In the case of ordinary numeric or text types,
Perl will just do the right thing and the programmer will normally not
have to worry about it. However, in other cases the argument will need
to be converted into a form that is more usable in Perl. For example,
the decode_bytea function can be used to convert an argument of type
bytea into unescaped binary.
Similarly, values passed back to PostgreSQL must be in the external
text representation format. For example, the encode_bytea function can
be used to escape binary data for a return value of type bytea.
According to this, you should do:
return encode_bytea($pdf->Finish());
and then the invalid input syntax for type bytea error would go away.
Returning base64
If returning base64, the function should normally be declared as RETURNS text and the report column should be text too. That would solve the problem of having these \012 sequences that look like a line feed (ASCII code=12 in octal) expressed in a bytea string literal with postgres escape format.
The line feeds are typically added by base64 encoders every 76 characters to avoid long lines in a MIME body (RFC-4648).
If the report column stays in bytea and the function produces base64 with RETURNS text, an implicit cast should happen on INSERT and it would probably be fine. Otherwise the conversion could be made explicitly with convert_to(bytea_plperl_func(), 'US-ASCII')
But storing base64 in a bytea column doesn't make much sense.
Related
I'm trying to insert a base64 image code as the default value for one of my columns. I've tried encapsulating my base64 with single quotes but in SSMS it doesn't show it as a string and am getting errors when trying to save the table.
-Error validating the default for column 'mycol'
-Error modyfing column properties, Unclosed quotation mark after the character string : then shows the entire base64 code.
I also tried the following way: (N'(base64here)') but that also throws the same error.
I did a search/replace in notepad for any other single quotes in my string but there are none.
Not sure whats wrong here? Could it be that the string is too long for an varchar(MAX) field? It's 223210 characters long. I'm using SSMS gui not TSQL to enter the defaul value.
(N'(data:image/jpeg;base64,/9j/4QA2RXhpZgAASUkqAAgAAAABAJiCAgARAAAAGgAAAAAAAABTZWFuIFBhdm9uZSAyMDE5AAAAAP/sABFEdWNreQABAAQAAAA8AAD/4QTcaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLwA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/PiA8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJBZG9iZSBYTVAgQ29yZSA1LjYtYzE0NSA3OS4xNjM0OTksIDIwMTgvMDgvMTMtMTY6NDA6MjIgICAgICAgICI+IDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+IDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiIHhtbG5zOnhtcFJpZ2h0cz0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3JpZ2h0cy8iIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIiB4bWxuczpzdFJlZj0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlUmVmIyIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iIHhtcFJpZ2h0czpNYXJrZWQ9IlRydWUiIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0iRjdFQzhDRkZFRkU5ODUyNzg2QkU2MkI1NUMyNzA0RkMiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NEI5MEY5MURFNkREMTFFQUI1MTRFMTBEREY3OEY4MDIiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NEI5MEY5MUNFNkREMTFFQUI1MTRFMTBEREY3OEY4MDIiIHhtcDpDcmVhdG9yVG9vbD0iTklLT04gRDgxMCBWZXIuMS4xMCAgICAgIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9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\=)')
The base64 string above is truncated because stackoverflow has character limit btw.
I was able to add it using TSQL
ALTER TABLE MYTBL
ADD CONSTRAINT MYCOL
DEFAULT 'base64here' FOR MYCOL;
I have a table that for some reason stores text as IMAGE. I can grab the data and read it using
SELECT CONVERT(NVARCHAR(MAX), CONVERT(VARBINARY(MAX), column,2)) FROM table
Now I need to insert data back in to the table. I've tried
SELECT CONVERT(IMAGE, CAST('TEST TEXT' AS VARBINARY(MAX)))
But when I test converting it back using
SELECT CONVERT(NVARCHAR(MAX), CONVERT(VARBINARY(MAX), CONVERT(IMAGE, CAST('TEST TEXT' AS VARBINARY(MAX))),2))
It returns 䕔呓吠塅 which is obviously not right as it should return "TEST TEXT"
What am I doing wrong here?
The text you're trying to store is encoded as binary ASCII characters. You're trying to convert it back into a Unicode text string, which isn't what it originally was, therefore you're getting back garbled text.
Change your source text string into a Unicode string by adding N in front of it:
SELECT CONVERT(NVARCHAR(MAX), CONVERT(VARBINARY(MAX), CONVERT(IMAGE, CAST(N'TEST TEXT' AS VARBINARY(MAX))),2))
It should return the correct text. Tested this on SQL Server 2008
You can use this one:
SELECT CONVERT(**VARCHAR(MAX)**, CONVERT(VARBINARY(MAX), **CAST('TEST TEXT' AS IMAGE)**,**0**))
Basically, you were not consistent with your character type conversions. In some parts you used NVarChar and some parts Varchar. Also, the number 2 at the end is affecting the result. In you Convert statements, when you don't specify the code, default value (0) is used. So if you are converting it back, you should use the same code.
I can't understand the reason why PostgreSQL store data in own format
The "hex" format encodes binary data as 2 hexadecimal digits per byte, most significant nibble first. The entire string is preceded by the sequence \x (to distinguish it from the escape format).
Does it's mean that it is not simple hex and it would not possible to simple convert this hex to byte type and I should write parser of PostgreSQL hex format?
The client driver usually takes care of bytea conversion for you, supplying you a native language data type like byte[] for Java. The representation of bytea on the wire shouldn't generally concern you. The only time it'll really matter is if you're using bytea literals in SQL text, rather than sending them as bind parameters.
Anyway, it is normal hex, it just has a \x prefix. So it's utterly trivial to "parse" if you do need to do so manually. E.g. in Python
r'\x736f6d65737472696e67'[2:].decode("hex")
The reason for the \x prefix is largely historical. PostgreSQL used to use an octal escape format for bytea data. When the format was changed to hex - to make it easier for clients to consume and work with and make it a bit more compact - it was necessary for the client to be able to tell what format the data was in. Since \x can never appear in octal ("escape") format literals, any string beginning with \x must be a hex bytea literal. This is even more important when receiving data from a client, which might be sending either hex or escape style literals, and the server must be able to tell which is which.
We could've just required that all clients use the format specified by the server. But that would break compatibility for all old clients that use bytea. Personally I think that's exactly what we should've done, and required that people using old clients set bytea_format = escape or something. That's not what happened, though. The setting bytea_output controls the format the server sends, but it still understands both formats as input. That makes interoperating with old clients and scripts easier. In theory.
In practice lots of old clients blindly interpreted hex literals sent by the server as if they were escape-format even though they were invalid; they'd ignore the backslash or treat it as a literal backslash. So they'd tend to corrupt bytea data when loading it then saving it again. Exactly what we wanted to avoid.
I have a badly behaved client application that is sending non UTF8 characters in a sql string to postgres. The string is in the form
"select call_function('paramvalue_1', paramvalue_2')"
the function looking like:
create or replace function(parameter_1 text, parameter_2 text)
returns...
Unfortunately the client occasionaly sends dodgy characters in the function parameters. It's going to be tricky to clean up the client app and I was wondering if there is any way for a function in a UTF-8 database to accept non-UTF8 characters and strip them from the param values before they get inserted anywhere.
I'm pretty convinced the answer is no but I thought it was worth asking here.
I'm using this:
COPY( select field1, field2, field3 from table ) TO 'C://Program
Files/PostgreSql//8.4//data//output.dat' WITH BINARY
To export some fields to a file, one of them is a ByteA field. Now, I need to read the file with a custom made program.
How can I parse this file?
The general format of a file generated by COPY...BINARY is explained in the documentation, and it's non-trivial.
bytea contents are the most easy to deal with, since they're not encoded.
Each other datatype has its own encoding rules, which are not described in the documentation but in the source code. From the doc:
To determine the appropriate binary format for the actual tuple data
you should consult the PostgreSQL source, in particular the *send and
*recv functions for each column's data type (typically these functions are found in the src/backend/utils/adt/ directory of the source
distribution).
It might be easier to use the text format rather than binary (so just remove the WITH BINARY). The text format has better documentation and is designed for better interoperability. The binary format is more intended for moving between postgres installations, and even there they have version incompatibilities.
Text format will write the bytea field as if it was text, and encode any non-printable characters with \nnn octal representation (except for a few special cases that it encodes with C style \x patterns, such as \n and \t etc.) These are listed in the COPY documentation.
The only caveat with this is you need to be absolutely sure that the character encoding you're using is the same when saving the file as when reading it. To make sure that the printable characters map to the same numbers. I'd stick to SQL_ASCII as it keeps thing simpler.