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

SUBSTRING: change type of startpos and FOR-length arguments to BIGINT [CORE4892] #5185

Open
firebird-automations opened this issue Jul 30, 2015 · 1 comment

Comments

@firebird-automations
Copy link
Collaborator

Submitted by: @pavel-zotov

Currently documentation ( http://www.firebirdsql.org/refdocs/langrefupd25-intfunc-substring.html ) issues that "this function fully supports binary and text BLOBs of ___any___ length and character set" (note on emphasized "any").

This is false in case when there is text blob of length more than 2 Gb.
I've created such blob by fill GTT tables with result of

RECREATE SEQUENCE G;
RECREATE GLOBAL TEMPORARY TABLE GTT(BLOB_FLD BLOB) ON COMMIT DELETE ROWS;
SELECT LIST( gen_id( g, 1 ) ) FROM RDB$TYPES,RDB$TYPES,RDB$TYPES,(SELECT 1 k FROM RDB$TYPES ROWS 15);

-- and after that blob_fld will have length 2'346'948'497 bytes.

Exception:

Statement failed, SQLSTATE = 22003
arithmetic exception, numeric overflow, or string truncation
-numeric value is out of range

-- raises when trying to do:

select substring( bob_field from 2147483649 for 1); // NOTE: exception does NOT appear when 2nd arg = 2147483648, i.e. exact power(2, 31) from gtt;
select substring( bob_field from 2147483647 for 2147483648) from gtt;

It will be nice if we'll have new implementation of substring (and all other functions for string handling) that will be able to operate with blobs which length more than 2Gb.

@firebird-automations
Copy link
Collaborator Author

Commented by: @pavel-zotov

PS. Strange result is issued by POSITION function for such extra-large blob:

SQL> select char_length(b) from gtt;

      CHAR\_LENGTH

=====================
2346948497

SQL> select left(b, 50) from gtt;

         LEFT

=================
0:23

LEFT:
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20

SQL> select position(',2,' in left(b, 50)) from gtt;

POSITION

============
2 ---------------- OK

SQL> select position(',2,' in b) from gtt;

POSITION

============
0 --------------------------- ?!

But for relatively small (medium ?) blob it is OK:

SQL> delete from gtt2;
SQL> alter sequence g2 restart with 0;
SQL> insert into gtt2 select list(gen_id(g2,1)) from rdb$types,rdb$types;
SQL> select char_length(b) from gtt2;

      CHAR\_LENGTH

=====================
375989

SQL> select position(',2,' in b) from gtt2;

POSITION

============
2

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant