Page 1 of 1

ERangeError in Delphi 2006

Posted: 27.11.2006, 17:58
by droetker
Hello.

I always et an ERangeError when opening a simple Query:
(Delphi 2006 -> MySQL 5.0.22)

Code: Select all

Connection.connected:=true;
Query.SQL.Text:='SELECT * FROM foo;';
Query.Open; //<-------------ERangeError
Debugging the code:
The Exception is in ZPlainMySQLDriver.pas, Line 3405:

Code: Select all

function TZMySQL5PlainDriver.GetFieldFlags(Field: PZMySQLField): Integer;
begin
  Result := ZPlainMySql5.PMYSQL_FIELD(Field)^.flags; //<---- HERE
end;
Is there anything I / you can do?
I need this working, urgently...
Or did I do something wrong?

Posted: 27.11.2006, 18:40
by droetker
more debug info:

when opening the query, there is called a method named 'TZMySQLResultSet.Open' (in ZDbcMySqlResultSet.pas). It's not too long so i can copy it here:

Code: Select all

procedure TZMySQLResultSet.Open;
var
  I: Integer;
  ColumnInfo: TZColumnInfo;
  FieldHandle: PZMySQLField;
  FieldFlags: Integer;
begin
  if ResultSetConcurrency = rcUpdatable then
    raise EZSQLException.Create(SLiveResultSetsAreNotSupported);

  if FUseResult then
  begin
    FQueryHandle := FPlainDriver.UseResult(FHandle);
    LastRowNo := 0;
  end
  else
  begin
    FQueryHandle := FPlainDriver.StoreResult(FHandle);
    if Assigned(FQueryHandle) then
      LastRowNo := FPlainDriver.GetRowCount(FQueryHandle)
    else LastRowNo := 0;
  end;

  if not Assigned(FQueryHandle) then
    raise EZSQLException.Create(SCanNotRetrieveResultSetData);

  { Fills the column info. }
  ColumnsInfo.Clear;
  for I := 0 to FPlainDriver.GetFieldCount(FQueryHandle) - 1 do
  begin
    FPlainDriver.SeekField(FQueryHandle, I);
    FieldHandle := FPlainDriver.FetchField(FQueryHandle);
    if FieldHandle = nil then
      Break;

    ColumnInfo := TZColumnInfo.Create;
    with ColumnInfo do
    begin
      FieldFlags := FPlainDriver.GetFieldFlags(FieldHandle); // <--ERROR

      ColumnLabel := FPlainDriver.GetFieldName(FieldHandle);
      TableName := FPlainDriver.GetFieldTable(FieldHandle);
      ReadOnly := (FPlainDriver.GetFieldTable(FieldHandle) = '');
      ColumnType := ConvertMySQLHandleToSQLType(FPlainDriver,
        FieldHandle, FieldFlags);
      ColumnDisplaySize := FPlainDriver.GetFieldLength(FieldHandle);
      Precision := Max(FPlainDriver.GetFieldMaxLength(FieldHandle),
        FPlainDriver.GetFieldLength(FieldHandle));
      Scale := FPlainDriver.GetFieldDecimals(FieldHandle);
      if (AUTO_INCREMENT_FLAG and FieldFlags <> 0)
        or (TIMESTAMP_FLAG and FieldFlags <> 0) then
        AutoIncrement := True;
      if UNSIGNED_FLAG and FieldFlags <> 0 then
        Signed := False
      else Signed := True;
      if NOT_NULL_FLAG and FieldFlags <> 0 then
        Nullable := ntNoNulls
      else Nullable := ntNullable;
    end;

    ColumnsInfo.Add(ColumnInfo);
  end;

  inherited Open;
end;
my table has 2 fields so the FOR-loop is done twice. The first loop is ok; in the second loop the GetFieldFlags call does the Error.
Maybe it helps you.

Posted: 27.11.2006, 19:03
by droetker
further DEBUG:
in the first FOR loop the

Code: Select all

ZPlainMySql5.PMYSQL_FIELD(Field)^.flags
is a 7, in the second loop it is 3120579657;
PMYSQL_FIELD.flags is cardinal type, look below; but the GetfieldFlags function returns an Integer - there is the ERangeError...?

This is from ZPlainMySql5.pas:

Code: Select all

  PMYSQL_FIELD = ^MYSQL_FIELD;
  MYSQL_FIELD = record
    name:             PChar;   // Name of column
    org_name:         PChar;   // Original column name, if an alias
    table:            PChar;   // Table of column if column was a field
    org_table:        PChar;   // Org table name if table was an alias
    db:               PChar;   // Database for table
    catalog:	      PChar;   // Catalog for table
    def:              PChar;   // Default value (set by mysql_list_fields)
    length:           LongInt; // Width of column
    max_length:       LongInt; // Max width of selected set
    name_length:      Cardinal;
    org_name_length:  Cardinal;
    table_length:     Cardinal;
    org_table_length: Cardinal;
    db_length:        Cardinal;
    catalog_length:   Cardinal;
    def_length:       Cardinal;
    flags:            Cardinal; // Div flags
    decimals:         Cardinal; // Number of decimals in field
    charsetnr:        Cardinal; // Character set
    _type:            Cardinal; // Type of field. Se mysql_com.h for types
  end;
BUT: 3120579657 ? Could that be? I don't know anything about the MySQL protocol - is that a possible value for the flags field?

And Why ERangeError? Cardinal and Integer are both 32bit, just signed/unsigned.

would it help to do an

Code: Select all

Result := Integer(ZPlainMySql5.PMYSQL_FIELD(Field)^.flags);