On 29.03.2011 15:17, Max Vlasov wrote:

> Thanks, this forced me to search more on the topic. I use Delphi and it
> appears that all Borland compilers has their own floating-point exception
> handling chain and it is on by default so if any division by zero or
> overflow appears inside sqlite3_step Delphi will handle this with its own
> exception handling.

When running SQLite from Delphi, you must disable FPU exceptions. Below
is a simple console project which uses the DISQLite3 Delphi port of
SQLite to demonstrate how this works.

Ralf

---

{ DISQLite3 example project to show how to disable FPU exceptions so
  that very large integer numbers are correctly converted to 'Inf' text.

  Exceptions should always be disabled before running any C library from
  Delphi. This is important because exceptions do not exist in C and C
  does not know how to handle them. Exceptions will therefore cause the
  entire C library stack to unwind undisturbed until the exception is
  finally handled by Delphi code. The result of this is undefined and
  might range from simple memory leaks to more severe and complicated
  problems.

  This applies to all C libraries, both internal (*.obj) and extenal
  (*.dll).

  Visit the DISQLite3 Internet site for latest information and updates:

    http://www.yunqa.de/delphi/

  Copyright (c) 2011 Ralf Junker, Delphi Inspiration <del...@yunqa.de>

--------------------------------------------------------------------- }

program DISQLite3_Very_Large_Integer;

{$APPTYPE CONSOLE}
{$I DI.inc}
{$I DISQLite3.inc}

uses
  {$IFDEF FastMM}FastMM4, {$ENDIF}DISystemCompat, SysUtils,
  DISQLite3Api;

var
  DB: sqlite3_ptr;

procedure ExecSql(const SQL: Utf8String);
var
  i: Integer;
  Stmt: sqlite3_stmt_ptr;
begin
  sqlite3_check(sqlite3_prepare_v2(DB,
    PUtf8Char(SQL), Length(SQL), @Stmt, nil), DB);
  try
    while sqlite3_check(sqlite3_step(Stmt), DB) = SQLITE_ROW do
      begin
        for i := 0 to sqlite3_column_count(Stmt) - 1 do
          begin
            if i > 0 then Write(', ');
            Write(sqlite3_column_str(Stmt, i));
          end;
        WriteLn;
      end;
  finally
    sqlite3_finalize(Stmt);
  end;
end;

const
  DB_FILE_NAME = 'test.db3';
begin
  { Disable FPU exceptions. No need to restore, setting is process
specific. }
  Set8087CW($133F);

  try
    sqlite3_initialize;
    DeleteFile(DB_FILE_NAME);
    sqlite3_check(sqlite3_open(DB_FILE_NAME, @DB));
    try
      ExecSql('CREATE TABLE t1(v TEXT);');
      ExecSql('INSERT INTO t1 VALUES(''' +
        '123456789012345678901234567890123456789012345678901234567890' +
        '123456789012345678901234567890123456789012345678901234567890' +
        '123456789012345678901234567890123456789012345678901234567890' +
        '123456789012345678901234567890123456789012345678901234567890' +
        '123456789012345678901234567890123456789012345678901234567890' +
        '1234567890'');');
      ExecSql('INSERT INTO t1 VALUES(''-' +
        '123456789012345678901234567890123456789012345678901234567890' +
        '123456789012345678901234567890123456789012345678901234567890' +
        '123456789012345678901234567890123456789012345678901234567890' +
        '123456789012345678901234567890123456789012345678901234567890' +
        '123456789012345678901234567890123456789012345678901234567890' +
        '1234567890'');');

      ExecSql('SELECT length(v), CAST(v AS float) FROM t1;');
    finally
      sqlite3_check(sqlite3_close(DB), DB);
      sqlite3_shutdown;
    end;

  except
    on e: Exception do
      WriteLn(e.Message);
  end;

  WriteLn;
  WriteLn('Done - Press ENTER to Exit');
  ReadLn;
end.

_______________________________________________
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users

Reply via email to