firebird icon indicating copy to clipboard operation
firebird copied to clipboard

ASCII_CHAR(13) being first character of EOL is ignored by ascii_val(), char_length() and comparison operator "="

Open pavel-zotov opened this issue 6 months ago • 5 comments

Consider two .sql scripts from attached .zip file. sql-check-EOL-handling_-_linux-vs-windows.zip

File "check-linux-line-EOL.sql" was created in Linux text editor (one that built-in in mc) and, of couse, has appropriate EOL characters = ascii_char(10): Image

File "check-windows-line-EOL.sql" was created in Windows and has EOL = concatenated ascii_char(13) and ascii_char(10): Image

Now run this scriprs in corresponding OS. On Linux output will be expected:

select ascii_val( '
' )
from rdb$database;
       10
-------------------------------------------------------
select char_length( '
' )
from rdb$database;
           1
-------------------------------------------------------
select ascii_char(10) = '
'
from rdb$database;
<true>
-------------------------------------------------------
select '
' = ascii_char(10)
from rdb$database;
<true>
-------------------------------------------------------
select trim('
') = trim(ascii_char(10))
from rdb$database;
<true>

On Windows output shows that ASCII_CHAR() ignores first character of EOL that is used on that OS, i.e. chr(13). And we get wrong results for all statements of this script:

select ascii_val( '
' )
from rdb$database;
       10 ---------------- ?? why not 13 ??
-------------------------------------------------------
select char_length( '
' )
from rdb$database;
           1 --------------------- ?? why not 2 ??
-------------------------------------------------------
select ascii_char(13) || ascii_char(10) = '
'
from rdb$database;
<false>
-------------------------------------------------------
select '
' = ascii_char(13) || ascii_char(10)
from rdb$database;
<false>

PS. Checked on 6.0.0.765

pavel-zotov avatar Jun 03 '25 18:06 pavel-zotov

What happens if you use ascii_char (i.e. ascii_char(13) || ascii_char(10) instead of a literal? (My tests show that works as expected.) I rather guess this is some normalization done on the script input by ISQL.

To be honest I wouldn't consider this something that needs or should be fixed.

mrotteveel avatar Jun 04 '25 06:06 mrotteveel

@mrotteveel

Did you mean this:

select
    ascii_char(13) || ascii_char(10) = ascii_char(13) || ascii_char(10)
   ,ascii_char(13) || ascii_char(10) = ascii_char(10)
   ,ascii_char(13) || ascii_char(10) = ascii_char(13)
from rdb$database;

-- ?

Ouput will be:

======= ======= =======
<true>  <false> <false>

guess this is some normalization done on the script input by ISQL.

Why this normalization affects on EOL ?

pavel-zotov avatar Jun 05 '25 10:06 pavel-zotov

Why this normalization affects on EOL ?

SQL script should produce the same results being run on Windows and Linux.

aafemt avatar Jun 05 '25 10:06 aafemt

Why this normalization affects on EOL ?

Probably it performs line oriented reading (which generally removes the line ending), and then normalizes on \n (0x10) as the new line.

And to be clear, this is my guess, and if my guess is correct, I see no point in changing the behaviour. I find relying on non-printable characters in string literals rather questionable, even if the standard and Firebird allows it.

And in tests it's even worse if you consider that line-endings can depend on your Git configuration (if not controlled with .gitattributes), potentially making your tests unstable.

mrotteveel avatar Jun 05 '25 16:06 mrotteveel

And to be clear, this is my guess, and if my guess is correct,

99.99% it is correct

I see no point in changing the behaviour. I find relying on non-printable characters in string literals rather questionable, even if the standard and Firebird allows it.

+1

AlexPeshkoff avatar Jun 05 '25 16:06 AlexPeshkoff