Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

invalid BLOB type for operation (x86_64) [CORE2377] #2799

Closed
firebird-automations opened this issue Mar 16, 2009 · 13 comments
Closed

invalid BLOB type for operation (x86_64) [CORE2377] #2799

firebird-automations opened this issue Mar 16, 2009 · 13 comments

Comments

@firebird-automations
Copy link
Collaborator

Submitted by: Alexander (coopht)

I recieve this error only x86_64 architecture,
on the same firebird version, but on X86 Gentoo linux everithing is fine.

I have following UDF function:
void my_func (BLOB b, BLOB out))
{
char *buf = NULL;
short length = 0;
short actual_length = 0;

if (!b->blob_handle)
return;

length = (short) (b->blob_max_segment);

buf = malloc (length + 1L);

(*b->blob_get_segment) (b->blob_handle, buf, length, &actual_length);
buf [actual_length] = 0;

  if \(out\-\>blob\_handle\)
\(\*out\-\>blob\_put\_segment\) \(out\-\>blob\_handle, buf, actual\_length\);    

if (buf)
free (buf);
}

declare query:

DECLARE EXTERNAL FUNCTION BSTR
BLOB, BLOB
RETURNS PARAMETER 2
ENTRY_POINT 'my_func' MODULE_NAME 'my_udf.so'

Creating table for input blob:
CREATE TABLE test_table (B BLOB (80,1))

Insert blob into table:
INSERT INTO test_table VALUES (?)
I insert blob into test table from my program, and it is a TEXT BLOB, and it is correct,
because i can view it's content with flamerobin.

And when i execute select:
SELECT BSTR (B) FROM test_table

i got such error:

*** IBPP::SQLException ***
Context: Statement::Fetch
Message: isc_dsql_fetch failed.

SQL Message : -685
invalid ARRAY or BLOB operation

Engine Code : 335544465
Engine Message :
invalid BLOB type for operation

@firebird-automations
Copy link
Collaborator Author

Commented by: @AlexPeshkoff

How is defined BLOB in your UDF? Where from is BLOB definition taken?

@firebird-automations
Copy link
Collaborator Author

Commented by: Alexander (coopht)

BLOB is defined as followed in my UDF
typedef struct blob {
short (*blob_get_segment)();
int *blob_handle;
long blob_number_segments;
long blob_max_segment;
long blob_total_length;
void (*blob_put_segment)();
long (*blob_seek)();
} *BLOB;

@firebird-automations
Copy link
Collaborator Author

Commented by: @AlexPeshkoff

X64 played rather typical joke with you. You have declared a few entities as long:
long blob_number_segments;
and this is 64-bit on X64, but must be - 32-bit. The safest way is to use BLOBCALLBACK (declared in ibase.h) in all your UDFs instead of your BLOB.

Please confirm - did it fix your problem or not.

@firebird-automations
Copy link
Collaborator Author

Commented by: Alexander (coopht)

I defined BLOB type as followed, and fixed the problem .

typedef struct blob {
short (*blob_get_segment)();
void *blob_handle;
int blob_number_segments;
int blob_max_segment;
int blob_total_length;
void (*blob_put_segment)();
int (*blob_seek)();
} *BLOB;

Thank you for your help.

P.S. There no any information about ISC_BLOB_CALLBACK structure in Developers guide, that is why i did not use it.

@firebird-automations
Copy link
Collaborator Author

Modified by: @dyemanov

status: Open [ 1 ] => Resolved [ 5 ]

resolution: Won't Fix [ 2 ]

@firebird-automations
Copy link
Collaborator Author

Modified by: @pcisar

status: Resolved [ 5 ] => Closed [ 6 ]

@firebird-automations
Copy link
Collaborator Author

Commented by: SITA VINCENZO (sita)

Hello,

I tried to do the same with lazarus for firebird64 but il doesn't work.
In win32 it works but in vista64 it doesn't.
I did something wrong.
Perhaps you have some idea for help.

Thank you

New declaration
TISC_BlobGetSegment = function(BlobHandle: PInt; Buffer: PChar; BufferSize: Int; var ResultLength: Int): Short; cdecl;
Old declaration
TISC_BlobGetSegment = function(BlobHandle: PInt; Buffer: PChar; BufferSize: Long; var ResultLength: Long): Short; cdecl;

New declaration
TISC_BlobPutSegment = procedure(BlobHandle: PInt; Buffer: PChar; BufferLength: Short); cdecl;
Old declaration
TISC_BlobPutSegment = procedure(BlobHandle: PInt; Buffer: PChar; BufferLength: Short); cdecl;

New declaration
TISC_BlobSeekSegment = procedure(BlobHandle:PInt; Mode:Short; Offset:Int); cdecl;

New declaration
TBlob = record
GetSegment : TISC_BlobGetSegment;
BlobHandle : PInt;
SegmentCount : Int;
MaxSegmentLength : Int;
TotalSize : Int;
PutSegment : TISC_BlobPutSegment;
SeekSegment : TISC_BlobSeekSegment;
end;
PBlob = ^TBlob;

Old declaration
TBlob = record
GetSegment :TISC_BlobGetSegment;
BlobHandle : PInt;
SegmentCount : Long;
MaxSegmentLength : Long;
TotalSize : Long;
PutSegment : TISC_BlobPutSegment;
end;
PBlob = ^TBlob;

//Example of IB_EXTERNALS.PAS how it was before

(*
* ib_externals.pas
* copyright (c) 1998 by
* Gregory Deatz
* mailto:gdeatz@hlmdd.com
*)
unit ib_externals;

{$IFDEF FPC}
{$PACKRECORDS 1}
{$ENDIF}

{ Some structures, declarations that we need for the IB stuff to work, but
that aren't really part of the ib header file. }
interface

{$IFDEF FPC}
{$IFDEF MSWINDOWS}
uses
Windows,
StdFuncs;
{$ENDIF}
{$ELSE}
uses
Windows,
StdFuncs;
{$ENDIF}

type
Int = LongInt; // 32 bit signed
UInt = DWord; // 32 bit unsigned
Long = LongInt; // 32 bit signed
ULong = DWord; // 32 bit unsigned
Short = SmallInt;// 16 bit signed
UShort = Word; // 16 bit unsigned
Float = Single; // 32 bit
UChar = Byte; // 8 bit unsigned
ISC_LONG = Long; // 32 bit signed
UISC_LONG = ULong; // 32 bit unsigned
ISC_STATUS = Long; // 32 bit signed
UISC_STATUS = ULong; // 32 bit unsigned
Void = Pointer;
// Delphi "Pointer types"
PPChar = ^PChar;
PSmallInt = ^SmallInt;
PInt = ^Int;
PInteger = ^Integer;
PShort = ^Short;
PUShort = ^UShort;
PLong = ^Long;
PULong = ^ULong;
PFloat = ^Float;
PUChar = ^UChar;
PVoid = ^Pointer;
PDouble = ^Double;
PISC_LONG = ^ISC_LONG;
PUISC_LONG = ^UISC_LONG;
PISC_STATUS = ^ISC_STATUS;
PPISC_STATUS = ^PISC_STATUS;
PUISC_STATUS = ^UISC_STATUS;

{ C Date/Time Structure }
{$IFDEF FPC}
TCTimeStructure = packed record
tm_sec : longint; // Seconds
tm_min : longint; // Minutes
tm_hour : longint; // Hour (0--23)
tm_mday : longint; // Day of month (1--31)
tm_mon : longint; // Month (0--11)
tm_year : longint; // Year (calendar year minus 1900)
tm_wday : longint; // Weekday (0--6) Sunday = 0)
tm_yday : longint; // Day of year (0--365)
tm_isdst : longint; // 0 if daylight savings time is not in effect)
__tm_gmtoof: longint;
__tm_zone: PChar;
end;
{$ELSE}
TCTimeStructure = record
tm_sec : integer; // Seconds
tm_min : integer; // Minutes
tm_hour : integer; // Hour (0--23)
tm_mday : integer; // Day of month (1--31)
tm_mon : integer; // Month (0--11)
tm_year : integer; // Year (calendar year minus 1900)
tm_wday : integer; // Weekday (0--6) Sunday = 0)
tm_yday : integer; // Day of year (0--365)
tm_isdst : integer; // 0 if daylight savings time is not in effect)
end;
{$ENDIF}

PCTimeStructure = ^TCTimeStructure;
TM = TCTimeStructure;
PTM = ^TM;

TISC_VARYING = record
strlen: Short;
str: array[0..0] of Char;
end;

{***************************}
{* Some blob ctl structs *}
{* from IB help files for *}
{* implementing UDFs . *}
{* -- Taken from docs, not *}
{* in original ibase.h *}
{***************************}
TISC_BlobGetSegment = function(BlobHandle: PInt; Buffer: PChar; BufferSize: Long; var ResultLength: Long): Short; cdecl;

TISC_BlobPutSegment = procedure(BlobHandle: PInt; Buffer: PChar; BufferLength: Short); cdecl;

TBlob = record
GetSegment :TISC_BlobGetSegment;
BlobHandle : PInt;
SegmentCount : Long;
MaxSegmentLength : Long;
TotalSize : Long;
PutSegment : TISC_BlobPutSegment;
end;
PBlob = ^TBlob;

const
// Delphi consts
// Days of week
dSun = 1; dMon = 2; dTue = 3; dWed = 4; dThu = 5; dFri = 6; dSat = 7;
// Months of year
dJan = 1; dFeb = 2; dMar = 3; dApr = 4; dMay = 5; dJun = 6;
dJul = 7; dAug = 8; dSep = 9; dOct = 10; dNov = 11; dDec = 12;
// C Consts
cYearOffset = 1900;
// Days of week
cSun = 0; cMon = 1; cTue = 2; cWed = 3; cThu = 4; cFri = 5; cSat = 6;
// Months of year
cJan = 0; cFeb = 1; cMar = 2; cApr = 3; cMay = 4; cJun = 5;
cJul = 6; cAug = 7; cSep = 8; cOct = 9; cNov = 10; cDec = 11;

procedure InitializeTCTimeStructure(var tm_record: TCTimeStructure);

implementation

procedure InitializeTCTimeStructure(var tm_record: TCTimeStructure);
begin
with tm_record do
begin
tm_sec := 0;
tm_min := 0;
tm_hour := 0;
tm_mday := 0;
tm_mon := 0;
tm_year := 0;
tm_wday := 0;
tm_yday := 0;
tm_isdst := 0;
end;
end;

end.

@firebird-automations
Copy link
Collaborator Author

Commented by: @asfernandes

Are you sure that "Int = LongInt; // 32 bit signed" really defines it as 32 bit integer?

@firebird-automations
Copy link
Collaborator Author

Commented by: SITA VINCENZO (sita)

No but I'don't know which type i shut use in free-pascal.

@firebird-automations
Copy link
Collaborator Author

Commented by: @asfernandes

Integer?

@firebird-automations
Copy link
Collaborator Author

Commented by: SITA VINCENZO (sita)

I've tried but without sucess.

@firebird-automations
Copy link
Collaborator Author

Commented by: SITA VINCENZO (sita)

Hello

I ask me if you have an idea why --> Getsegment works

                          TISC\_BlobGetSegment = function\(BlobHandle: PInt; Buffer: PChar; BufferSize: Long; var ResultLength: Long\): Short; cdecl; 
                          Exemple

with Blob^ do
begin
SetString(S, nil, TotalSize);
total_bytes_read := 0;
bytes_left := TotalSize;
if (bytes_left = 0) then exit;
repeat
GetSegment(BlobHandle, @s[total_bytes_read + 1], bytes_left, bytes_read);
Inc(total_bytes_read, bytes_read);
Dec(bytes_left, bytes_read);
until bytes_left <= 0;
end;

and PutSegment don't works

                          TISC\_BlobPutSegment = procedure\(BlobHandle: PInt; const Buffer: PChar; BufferLength: UShort\); cdecl;

thank you

@firebird-automations
Copy link
Collaborator Author

Commented by: @asfernandes

Blob handle is not pointer, it's 32 bit value.

You shall better move your questions to the support list.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant