FirebirdSQL / firebird

Firebird server, client and tools
https://www.firebirdsql.org/
1.26k stars 216 forks source link

Transliteration error if connection charset is narrower that storage and requested charsets #8082

Open aafemt opened 6 months ago

aafemt commented 6 months ago

Also a temporary BLOB is created unnecessarily.

Test application is attached. ctest.zip

asfernandes commented 6 months ago

This is by design. When prepare is called, there is no additional information about charsets, then output message is generated using the connection charset.

For external routines, they can override client charset. I remember many (all) were against it, fortunately I insisted and maintained it allowing external routines to not be broken by client options.

aafemt commented 6 months ago

Problem is not with output message generated during prepare, it is informational only. Problem is with output message received during openCursor() which has to be used for data delivery.

asfernandes commented 6 months ago

You are wrong.

isql ctest -ch utf8
SQL> set exec_path_display blr;
SQL> select * from a;

Execution path (BLR):

    0 blr_version5,
    1 blr_begin,
    2    blr_message, 1, 11,0,
    6       blr_short, 0,
    8       blr_short, 0,
   10       blr_blob2, 1,0, 4,0,
   15       blr_short, 0,
   17       blr_blob2, 1,0, 4,0,
   22       blr_short, 0,
   24       blr_varying2, 4,0, 40,0,
   29       blr_short, 0,
   31       blr_varying2, 4,0, 40,0,
   36       blr_short, 0,
   38       blr_long, 0,
   40    blr_for,
   41       blr_stall,
   42       blr_rse, 1,
   44          blr_rid, 128,0, 0,
   48          blr_end,
   49    blr_send, 1,
   51       blr_begin,
   52          blr_assignment,
   53             blr_literal, blr_short, 0, 1,0,
   58             blr_parameter, 1, 0,0,
   62          blr_assignment,
   63             blr_fid, 0, 4,0,
   67             blr_parameter2, 1, 2,0, 1,0,
   73          blr_assignment,
   74             blr_fid, 0, 3,0,
   78             blr_parameter2, 1, 4,0, 3,0,
   84          blr_assignment,
   85             blr_fid, 0, 2,0,
   89             blr_parameter2, 1, 6,0, 5,0,
   95          blr_assignment,
   96             blr_fid, 0, 1,0,
  100             blr_parameter2, 1, 8,0, 7,0,
  106          blr_assignment,
  107             blr_fid, 0, 0,0,
  111             blr_parameter2, 1, 10,0, 9,0,
  117          blr_end,
  118    blr_send, 1,
  120       blr_assignment,
  121          blr_literal, blr_short, 0, 0,0,
  126          blr_parameter, 1, 0,0,
  130    blr_end,
  131 blr_eoc
aafemt commented 6 months ago

If you didn't notice: in contrast to isql my test application uses MessageMetadata for openCursor() different from one received after prepare(). If Firebird engine ignores it - this is the bug in the engine that must be fixed.

asfernandes commented 6 months ago

And you are not understanding that the things you pass to openCursor was not passed to prepare, and the things ISQL are displaying are things generated at prepare. openCursor does not recompile statement and regenerate its BLR/nodes.

I'm not saying it's good. I'm saying it's by design.

asfernandes commented 6 months ago

We may check if generate messages using same charset of the original data may work without others problems.

aafemt commented 6 months ago

openCursor does not recompile statement and regenerate its BLR/nodes.

And it does not need to. The BLR you showed contain message definition and action definition. EXE nodes are generated from second part and they don't (need to) care about first part as long as parameter numbers match so the sole problem is that there is unnecessary data conversion Record -> DSC from prepare() -> DSC from openCursor(). The former conversion must be completely eliminated, not just checked.

aafemt commented 6 months ago

blr_stall,

BTW, what does blr_stall do here? Its syntax and purpose is not documented anywhere.

aafemt commented 4 months ago

A funny fact: temporary BLOB created for necessary transliteration is created as a binary one.