Issue Details (XML | Word | Printable)

Key: CORE-2370
Type: Bug Bug
Status: Resolved Resolved
Resolution: Fixed
Priority: Minor Minor
Assignee: Claudio Valderrama C.
Reporter: Bill Oliver
Votes: 0
Watchers: 0

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

SQL Plan greater than 2048 characters is not printed at all in ISQL

Created: 12/Mar/09 02:12 PM   Updated: 24/Feb/11 09:02 AM
Component/s: ISQL
Affects Version/s: 2.0.0, 1.5.4, 2.0.1, 2.0.2, 2.0.3, 1.5.5, 2.1.0, 2.0.4, 2.5 Alpha 1, 2.1.1, 2.0.5
Fix Version/s: 2.5 Beta 2

Environment: tested on windows xp
Issue Links:

Sub-Tasks  All   Open   

 Description  « Hide
I have a query plan with unions that is greater than 2048 characters, it is 5764 characters. The result is that in ISQL, I only get a blank line for the plan!

The trivial fix is to bump up the size of the buffer in ISQL's process_plan(). I increased buffer size to 8096, and it worked fine.

Perhaps a better fix is to max out the buffer size in process_plan(), so we don't have to touch this area again. We know that the maximum possible length of the plan is MAX_SSHORT, see dsql.cpp's DSQL_get_plan_info(). Anything longer than this, and the plan will be returned, but it will end in ellipses. That's ok.

I've coded a patch for this issue. In testing, it seems to me that dsql.cpp's put_item() length check is off by one, but I'd like the committer to double-check this.

### Eclipse Workspace Patch 1.0
#P firebird2
Index: src/dsql/dsql.cpp
RCS file: /cvsroot/firebird/firebird2/src/dsql/dsql.cpp,v
retrieving revision 1.276
diff -u -r1.276 dsql.cpp
--- src/dsql/dsql.cpp 3 Mar 2009 14:55:53 -0000 1.276
+++ src/dsql/dsql.cpp 12 Mar 2009 17:59:18 -0000
@@ -2740,7 +2740,7 @@
  const UCHAR* const end)
- if (ptr + length + 3 >= end) {
+ if (ptr + length + 3 > end) {
  *ptr = isc_info_truncated;
  return NULL;
Index: src/isql/isql.epp
RCS file: /cvsroot/firebird/firebird2/src/isql/isql.epp,v
retrieving revision 1.268
diff -u -r1.268 isql.epp
--- src/isql/isql.epp 1 Mar 2009 15:42:18 -0000 1.268
+++ src/isql/isql.epp 12 Mar 2009 17:59:18 -0000
@@ -7943,11 +7943,11 @@
 // any result to the caller.
 static void process_plan()
- // Bug 7565: A plan larger than plan_buffer will not be displayed
- // Bug 7565: Note also that the plan must fit into Print_Buffer
  const SCHAR plan_info[] = { isc_info_sql_get_plan };
+ // max length of plan is MAX_SSHORT
+ // add 1 for SQL info item, and 2 for actual length of the plan
+ TEXT plan_buffer[MAX_SSHORT + 3];
  memset(plan_buffer, 0, sizeof(plan_buffer));
  if (isc_dsql_sql_info(isc_status, &global_Stmt, sizeof(plan_info), plan_info,
  sizeof(plan_buffer), plan_buffer))

 All   Comments   Change History   Subversion Commits      Sort Order: Ascending order - Click to sort in descending order
Claudio Valderrama C. added a comment - 09/Jun/09 06:54 AM
First, put_item() is correct, because it's reserving space for isc_info_end and isc_info_sql_describe_end. Look at the functions that use it. When you are going to finish the string, if you discover there's no room for a single byte, it's too late to put even isc_info_truncated.

Second, I have enlarged the internal interface to take plans of any length in practice (really, up to 2^31-1), but there are some public API calls that I cannot change, so these places appear as constraints with a maximum of 2^16 (USHORT).

Third, the amount of places where temporary buffers are used to retrieve plan information is really daunting, plus several possibilities of internal retries (with bigger buffers). The sole call stack is a mountain. I don't dare to touch that for now, but some day it should be streamlined.

Claudio Valderrama C. added a comment - 24/Jun/09 06:47 AM
Tried to be conservative for versions <= FB2.1 (less than 32K) and use the full plan length in FB2.5 (around 64K).