Home > database >  Laravel Firebird Error "invalid request BLR at offset"
Laravel Firebird Error "invalid request BLR at offset"

Time:07-19

I'm trying to connect to .fdb using package in my web-app

settings:

'firebird' => [
        'driver'   => 'firebird',
        'host'     => 'localhost',
        'port'     => '3050',
        'database' => storage_path('db.fdb'),
        'username' => 'SYSDBA',
        'password' => 'masterkey',
        'charset'  => 'UTF8',
        'version'  => '2.5', // 1.5 - same
        'role'     => null,
        'UdfAccess' => 'Full', // try like DBeaver connection
        'isc_dpb_no_db_triggers' => true, // try like DBeaver connection
],

controller:

$fb = DB::connection('firebird')->table('table')->count();

result:

SQLSTATE[HY000] [335544343] invalid request BLR at offset 132 (SQL: select count(*) as "aggregate" from "TABLE").

Full error is

invalid request BLR at offset 132 function POS is not defined module name or entrypoint could not be found

What is my problem? How to ignore UDF or turn it on?

Win 10, x64, have Firebird 2.5 and 3.

Have the same problem in C# app.

CodePudding user response:

The problem is that your database has a UDF definition (POS), but cannot find or load the UDF library (or the library doesn't contain the function entrypoint). This can happen if you moved your database to a different server, but forgot to move/install the accompanying UDF libraries, or if you're using a different version of the UDF library (one that doesn't contain the function entrypoint).

There are basically two ways to recover from this:

  1. Make sure your database server has the appropriate UDF library
  2. Remove any usage of the UDF from your database.

Option 1

Your POS UDF uses the DMM_UDF library (which doesn't sounds familiar to me, so it is likely a custom UDF library) with the ibPos entry point. On windows, this library would generally be called DMM_UDF.dll or dmm_udf.dll.

Find the right UDF DLL file (e.g. on the old database server), and make sure it has the same bitness as your Firebird server. If you only have a 32-bit version, replace your 64-bit Firebird server with a 32-bit Firebird server.

You need to add this DLL to the udf directory of your Firebird installation, and make sure the UDF directory is enabled in firebird.conf (setting UdfAccess, default is UdfAccess = Restrict UDF in Firebird 2.5 and 3.0 which will allow use of the udf directory, note that in Firebird 4.0 the default is UdfAccess = None, which disables loading of UDFs).

After doing this, restart Firebird, and Firebird should then be able to load the UDF.

Option 2

Hunt down and remove or replace all usages of the UDF.

A query to find the dependencies of UDF POS is (at least for top-level dependencies of the UDF, and table/view columns):

select 
  dependent_type.RDB$TYPE_NAME dependent_type, 
  rd.RDB$DEPENDENT_NAME, 
  rrf.RDB$RELATION_NAME dependent_table,
  rrf.RDB$FIELD_NAME dependent_column,
  rf.RDB$COMPUTED_SOURCE dependent_expression,
  depended_on_type.RDB$TYPE_NAME depended_on_type, 
  rd.RDB$DEPENDED_ON_NAME 
from RDB$DEPENDENCIES rd
inner join RDB$TYPES dependent_type
  on rd.RDB$DEPENDENT_TYPE = dependent_type.RDB$TYPE and dependent_type.RDB$FIELD_NAME = 'RDB$OBJECT_TYPE'
inner join RDB$TYPES depended_on_type
  on rd.RDB$DEPENDED_ON_TYPE = depended_on_type.RDB$TYPE and depended_on_type.RDB$FIELD_NAME = 'RDB$OBJECT_TYPE' 
left join RDB$RELATION_FIELDS rrf 
  on dependent_type.RDB$TYPE_NAME IN ('COMPUTED_FIELD', 'FIELD') and rrf.RDB$FIELD_SOURCE = rd.RDB$DEPENDENT_NAME 
left join RDB$FIELDS rf 
  on dependent_type.RDB$TYPE_NAME IN ('COMPUTED_FIELD', 'FIELD') and rf.RDB$FIELD_NAME = rd.RDB$DEPENDENT_NAME 
where rd.RDB$DEPENDED_ON_TYPE = 15
and rd.RDB$DEPENDED_ON_NAME = 'POS'

For example, if the UDF is used for a calculated column in table X, column CALCULATED_POS with expression POS(A, B), then you can drop it with

alter table X drop CALCULATED_POS

However, if this column has dependencies, or you still need it, this might not be so easy (or not a good idea).

You can also try to alter it to remove the dependencies, by replacing the expression for an equivalent using built-in functions, or just a dummy expression to get things to work. For example, say POS is equivalent to the built-in POSITION, then you could do something like:

alter table X alter CALCULATED_POS generated always as (POSITION(A, B))

You will need to make similar modifications if the dependencies is used in a view, check constraint (listed as a trigger), trigger or stored procedure.

  • Related