firebird icon indicating copy to clipboard operation
firebird copied to clipboard

fb_interpret returns "Unknown ISC error"

Open P1cheneG opened this issue 8 months ago • 0 comments

Hello, I am writing a C++ program using the Firebird API and encountered an 'Unknown ISC error' message instead of the correct error message. The problem can be reproduced with the following code.

#include <iostream>
#include <string>
#include <vector>
#include "firebird/Interface.h"
#include "firebird/IdlFbInterfaces.h"

using namespace Firebird;

const char* USER = "SYSDBA";
const char* PASSWORD = "1234";
constexpr int MAX_DIAG_MSG_LEN = 300;

static IMaster* master = fb_get_master_interface();
static IProvider* prov = master->getDispatcher();
static IStatus* st = master->getStatus();

class PrintStatus : public BaseStatusWrapper<PrintStatus>
{
public:
    PrintStatus(IStatus* aStatus) : BaseStatusWrapper(aStatus) {}

    static void checkException(PrintStatus* status)
    {
        if (status && status->isDirty() && (status->getState() & IStatus::STATE_ERRORS))
        {
            status->hasError();
        }
    }

    bool hasError() const
    {
        const bool hasErr = isDirty() && (status->getState() & IStatus::STATE_ERRORS);
        if (hasErr)
        {
            auto statusPtr = status->getErrors();
            int code = statusPtr[1];
            std::cout << "SQL CODE = " << code << std::endl;

            char buffer[MAX_DIAG_MSG_LEN];
            while (fb_interpret(buffer, MAX_DIAG_MSG_LEN, &statusPtr))
            {
                std::cout << buffer << std::endl;
            }
        }
        return hasErr;
    }
};

int main()
{
    IAttachment* att = nullptr;
    PrintStatus status(st);

    IUtil* utl = master->getUtilInterface();
    IXpbBuilder* dpb = utl->getXpbBuilder(&status, IXpbBuilder::DPB, NULL, 0);
    dpb->insertString(&status, isc_dpb_user_name, USER);
    dpb->insertString(&status, isc_dpb_password, PASSWORD);

    std::string connectStr = "localhost:employee";
    att = prov->attachDatabase(
        &status,
        connectStr.c_str(),
        dpb->getBufferLength(&status),
        dpb->getBuffer(&status));

    if (status.hasError()) {
        dpb->dispose();
        return 1;
    }

    IXpbBuilder* tpb = utl->getXpbBuilder(&status, IXpbBuilder::TPB, NULL, 0);
    ITransaction* tra = att->startTransaction(
        &status,
        tpb->getBufferLength(&status),
        tpb->getBuffer(&status));

    att->execute(&status, tra, 0,
        "create function TEST_FUNC RETURNS float as BEGIN RETURN 1; END;",
        3, NULL, NULL, NULL, NULL);
    att->execute(&status, tra, 0,
        "create function TEST_FUNC RETURNS float as BEGIN RETURN 1; END;",
        3, NULL, NULL, NULL, NULL);

    if (tra) tra->commit(&status);
    if (tpb) tpb->dispose();
    if (dpb) dpb->dispose();
    if (att) att->detach(&status);
    st->dispose();
    prov->release();

    return 0;
}

P1cheneG avatar Apr 07 '25 17:04 P1cheneG