Search code examples
delphifirebirddelphi-7firebird-3.0

TIB_Script run large script


I encountered a problem that IB_Script returned an error while running a longer script:

SQL Error Code = -104 Unexpected end of command - line 18, column 52

As long as the number of characters in the script did not exceed 65,536 characters (current is 66.186), there was no such error message.

I upload IB_Script with the following code:

with dm.DDLScript do
    begin
        try
            SQL.Clear;
            SQL.Add('SET TERM ^;');
            SQL.Add(Format('CREATE OR ALTER PACKAGE %s', [ObjectName]));
            SQL.Add('AS');             
            SQL.AddStrings(hdr.Lines); // hdr > TSynEdit

            Execute;
            SQL.Clear;
            
            SQL.Add('SET TERM ^;');
            SQL.Add(Format('RECREATE PACKAGE BODY %s', [ObjectName]));
            SQL.Add('AS');
            SQL.AddStrings(bdy.Lines); // bdy > TSynEdit
            SQL.Add('^');
            Execute;

            ObjectMod := false;
        except
            on e:exception do
            begin
                messageDlg(e.Message, mtError,[mbOk], 0);
                abort;
            end;
        end;
    end; 

Has anyone encountered a similar problem? It is not possible to run the script in a smaller number of characters because it would be a PACKAGE BODY as shown.


Solution

  • Firebird 2.5 and earlier only supported statements of 64KB (65535 bytes), and this limitation is also reflected in the fbclient.dll API where the size is a 16-bit unsigned integer. Firebird 3.0 increased the limitation to 10MB, but this requires the Firebird 3.0 or higher fbclient, and either using the new object-oriented API, or passing the statement with a length of zero, and the statement text as a NUL-terminated string.

    Likely, the library you're using is explicitly passing the size and this size overflows, resulting in Firebird only receiving a small part of the statement being sent (or at least, I guess that line 18 column 52 is a lot less characters than 65535). As Firebird receives an incomplete statement, it then produces the error "Unexpected end of command".

    I don't program Delphi myself, but the solution would need a modification in the library to pass statements to isc_dsql_prepare with size 0 and as a NUL-terminated string.