Issue Details (XML | Word | Printable)

Key: CORE-2300
Type: Bug Bug
Status: Closed Closed
Resolution: Fixed
Priority: Critical Critical
Assignee: Adriano dos Santos Fernandes
Reporter: Dmitry Yemanov
Votes: 0
Watchers: 1
Operations

If you were logged in you would be able to see more operations.
Firebird Core

Unexpected error "arithmetic exception, numeric overflow, or string truncation" while evaluating SUBSTRING the second time

Created: 30/Jan/09 08:40 AM   Updated: 31/May/11 11:53 AM
Component/s: Engine
Affects Version/s: 2.1.0, 2.5 Alpha 1, 2.1.1
Fix Version/s: 2.5 Beta 1

Time Tracking:
Not Specified

Issue Links:
Relate
 

Planning Status: Unspecified


 Description  « Hide
Test case:

create procedure p
  returns ( res varchar(10) )
as begin
  res = null;
  suspend;
  res = '0123456789';
  suspend;
end

commit;

select substring(res from 1 for 5) from p order by 1; -- success
select substring(res from 1 for 5) from p order by 1; -- error

Arithmetic overflow or division by zero has occurred.
arithmetic exception, numeric overflow, or string truncation.
string right truncation.

The problem seems to be caused by the fact that the DSC_null flag is analyzed at both prepare-time and runtime but descriptors can be persistent and thus keep the runtime value until the next time.

In this particular case, the first select call sets DSC_null for the procedure's output and the second select call checks this flag during prepare and describes the output as VARCHAR(1) instead of VARCHAR(10), then this short length is used to prepare the sort buffer and at runtime string truncation happens, because a CHAR(10) string cannot be assigned to a CHAR(1) buffer.

 All   Comments   Work Log   Change History   Version Control   Subversion Commits      Sort Order: Ascending order - Click to sort in descending order
Adriano dos Santos Fernandes added a comment - 30/Jan/09 12:00 PM
I had to comment a line present since v1.5. It was setting DSC_null on the shared procedure format.

I tested with TCS and it didn't fail.

Vlad Khorsun added a comment - 31/Jan/09 05:43 PM
The fix is correct, you may remove that commented line ;)

I think proc_assignment() declaration must be changed by

static void proc_assignment(thread_db*, const dsc* const, const dsc* const, UCHAR*, const dsc* const, SSHORT, Record*);

i.e. use "const dsc* const" instead of "const dsc*" to explicitly disable change of descriptors.

Adriano dos Santos Fernandes added a comment - 31/Jan/09 06:14 PM
Thanks for review.

About the const, I never understand the need for such usage. Not because I don't understand how it apply, but because I don't understand its benefit used in "some" places.

I mean, if we think the const apply in this place, there is no difference in think it apply for all the others parameters too:
    static void proc_assignment(thread_db* const, const dsc* const, const dsc* const, UCHAR* const, const dsc* const, SSHORT const, Record* const);

It compiles ok, and has the same meaning of don't allow a local variable to change. And then we're adding consts to every variable.

Pavel Cisar added a comment - 31/May/11 11:53 AM
QA test added.