As attachements don't work, a short one:
Source is here:
https://github.com/FirebirdSQL/firebird/blob/master/src/burp/OdsDetection.epp

results in:

/*********** Preprocessed module -- do not edit ***************/
/*********** Preprocessed module -- do not edit ***************/
/*********** Preprocessed module -- do not edit ***************/
/*********** Preprocessed module -- do not edit ***************/
/*********** Preprocessed module -- do not edit ***************/
/***************** gpre version LI-T4.0.0.1436-dev Firebird 4.0 Beta 1 
**********************/
/*
  *     PROGRAM:        JRD Backup and Restore Program
  *     MODULE:         OdsDetection.cpp
  *     DESCRIPTION:    Detecting the backup (source) or restore (target) ODS
  *
  * The contents of this file are subject to the Interbase Public
  * License Version 1.0 (the "License"); you may not use this file
  * except in compliance with the License. You may obtain a copy
  * of the License at http://www.Inprise.com/IPL.html
  *
  * Software distributed under the License is distributed on an
  * "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express
  * or implied. See the License for the specific language governing
  * rights and limitations under the License.
  *
  * The Original Code was created by Inprise Corporation
  * and its predecessors. Portions created by Inprise Corporation are
  * Copyright (C) Inprise Corporation.
  *
  * All Rights Reserved.
  * Contributor(s): ______________________________________.
  *
  */

#include "firebird.h"
#include "../burp/burp.h"
#include "../burp/burp_proto.h"
#include "../burp/OdsDetection.h"


namespace
{
        // table used to determine capabilities, checking for specific
        // fields in system relations
        struct rel_field_t
        {
                const char* relation;
                const char* field;
                int ods_version;
        };

        const rel_field_t relations[] =
        {
                {"RDB$PROCEDURES",      0,      DB_VERSION_DDL8},       // IB4
                {"RDB$ROLES",           0,      DB_VERSION_DDL9},       // IB5
                {"RDB$PACKAGES",        0,      DB_VERSION_DDL12},      // FB3
                {0, 0, 0}
        };

        const rel_field_t rel_fields[] =
        {
                {"RDB$FIELDS",                                  
"RDB$FIELD_PRECISION",  DB_VERSION_DDL10},              // FB1, 
FB1.5
                {"RDB$ROLES",                                   
"RDB$DESCRIPTION",              DB_VERSION_DDL11},              // FB2
                {"RDB$RELATIONS",                               
"RDB$RELATION_TYPE",    DB_VERSION_DDL11_1},    // FB2.1
                {"RDB$PROCEDURE_PARAMETERS",    "RDB$FIELD_NAME",               
DB_VERSION_DDL11_2}, 
// FB2.5
                {"RDB$PROCEDURES",                              
"RDB$ENGINE_NAME",              DB_VERSION_DDL12},              // FB3.0
                {0, 0, 0}
        };

        void general_on_error();
}


/*DATABASE DB = STATIC FILENAME "yachts.lnk";*/
/**** GDS Preprocessor Definitions ****/
#ifndef JRD_IBASE_H
#include <ibase.h>
#endif
#include <firebird/Interface.h>
#define CAST_CONST_MSG(A) (reinterpret_cast<const unsigned char*>(A))
#define CAST_MSG(A) (reinterpret_cast<unsigned char*>(A))

static const ISC_QUAD
    fbBlobNull = {0, 0};        /* initializer for blobs */
static Firebird::IAttachment*
    DB = 0;             /* database handle */

static Firebird::ITransaction*
    fbTrans = 0;                /* default transaction handle */
static Firebird::IMaster* fbMaster = 
Firebird::fb_get_master_interface();            /* master interface */
static Firebird::IProvider* fbProvider = fbMaster->getDispatcher();             
/* 
provider interface */
static Firebird::CheckStatusWrapper fbStatusObj(fbMaster->getStatus()); 
/* status vector */
static Firebird::CheckStatusWrapper fbStatus2Obj(fbMaster->getStatus()); 
/* status vector */
static Firebird::CheckStatusWrapper* fbStatus = &fbStatusObj;   /* status 
vector */
static Firebird::CheckStatusWrapper* fbStatus2 = &fbStatus2Obj; /* 
status vector */
static int fbIStatus;   /* last completion code */
static const unsigned
    fb_0l = 164;
static const unsigned char
    fb_0 [] = {
       blr_version4,
       blr_begin,
         blr_message, 1, 1,0,
            blr_short, 0,
         blr_message, 0, 2,0,
            blr_cstring, 241,3,
            blr_cstring, 241,3,
         blr_receive, 0,
            blr_begin,
               blr_for,
                  blr_rse, 1,
                     blr_relation, 19, 
'R','D','B','$','R','E','L','A','T','I','O','N','_','F','I','E','L','D','S', 
0,
                     blr_first,
                        blr_literal, blr_long, 0, 1,0,0,0,
                     blr_boolean,
                        blr_and,
                           blr_eql,
                              blr_field, 0, 17, 
'R','D','B','$','R','E','L','A','T','I','O','N','_','N','A','M','E',
                              blr_parameter, 0, 0,0,
                           blr_and,
                              blr_eql,
                                 blr_field, 0, 14, 
'R','D','B','$','F','I','E','L','D','_','N','A','M','E',
                                 blr_parameter, 0, 1,0,
                              blr_eql,
                                 blr_field, 0, 15, 
'R','D','B','$','S','Y','S','T','E','M','_','F','L','A','G',
                                 blr_literal, blr_long, 0, 1,0,0,0,
                     blr_end,
                  blr_send, 1,
                     blr_begin,
                        blr_assignment,
                           blr_literal, blr_long, 0, 1,0,0,0,
                           blr_parameter, 1, 0,0,
                        blr_end,
               blr_send, 1,
                  blr_assignment,
                     blr_literal, blr_long, 0, 0,0,0,0,
                     blr_parameter, 1, 0,0,
               blr_end,
         blr_end,
       blr_eoc
    };  /* end of blr string for request fb_0 */

static const unsigned
    fb_6l = 132;
static const unsigned char
    fb_6 [] = {
       blr_version4,
       blr_begin,
         blr_message, 1, 1,0,
            blr_short, 0,
         blr_message, 0, 1,0,
            blr_cstring, 241,3,
         blr_receive, 0,
            blr_begin,
               blr_for,
                  blr_rse, 1,
                     blr_relation, 13, 
'R','D','B','$','R','E','L','A','T','I','O','N','S', 0,
                     blr_first,
                        blr_literal, blr_long, 0, 1,0,0,0,
                     blr_boolean,
                        blr_and,
                           blr_eql,
                              blr_field, 0, 17, 
'R','D','B','$','R','E','L','A','T','I','O','N','_','N','A','M','E',
                              blr_parameter, 0, 0,0,
                           blr_eql,
                              blr_field, 0, 15, 
'R','D','B','$','S','Y','S','T','E','M','_','F','L','A','G',
                              blr_literal, blr_long, 0, 1,0,0,0,
                     blr_end,
                  blr_send, 1,
                     blr_begin,
                        blr_assignment,
                           blr_literal, blr_long, 0, 1,0,0,0,
                           blr_parameter, 1, 0,0,
                        blr_end,
               blr_send, 1,
                  blr_assignment,
                     blr_literal, blr_long, 0, 0,0,0,0,
                     blr_parameter, 1, 0,0,
               blr_end,
         blr_end,
       blr_eoc
    };  /* end of blr string for request fb_6 */

static const unsigned
    fb_11l = 190;
static const unsigned char
    fb_11 [] = {
       blr_version4,
       blr_begin,
         blr_message, 0, 1,0,
            blr_short, 0,
         blr_begin,
            blr_for,
               blr_rse, 1,
                  blr_relation, 19, 
'R','D','B','$','R','E','L','A','T','I','O','N','_','F','I','E','L','D','S', 
0,
                  blr_boolean,
                     blr_and,
                        blr_or,
                           blr_eql,
                              blr_field, 0, 17, 
'R','D','B','$','R','E','L','A','T','I','O','N','_','N','A','M','E',
                              blr_literal, blr_text, 13,0, 
'R','D','B','$','R','E','L','A','T','I','O','N','S',
                           blr_eql,
                              blr_field, 0, 17, 
'R','D','B','$','R','E','L','A','T','I','O','N','_','N','A','M','E',
                              blr_literal, blr_text, 19,0, 
'R','D','B','$','R','E','L','A','T','I','O','N','_','F','I','E','L','D','S',
                        blr_eql,
                           blr_field, 0, 14, 
'R','D','B','$','F','I','E','L','D','_','N','A','M','E',
                           blr_literal, blr_text, 15,0, 
'R','D','B','$','S','Y','S','T','E','M','_','F','L','A','G',
                  blr_end,
               blr_send, 0,
                  blr_begin,
                     blr_assignment,
                        blr_literal, blr_long, 0, 1,0,0,0,
                        blr_parameter, 0, 0,0,
                     blr_end,
            blr_send, 0,
               blr_assignment,
                  blr_literal, blr_long, 0, 0,0,0,0,
                  blr_parameter, 0, 0,0,
            blr_end,
         blr_end,
       blr_eoc
    };  /* end of blr string for request fb_11 */




#define DB                      tdgbl->db_handle
#define fbTrans         tdgbl->tr_handle
#define gds_trans       tdgbl->tr_handle
#define fbStatus        (&tdgbl->status_vector)
#define isc_status      (&tdgbl->status_vector)
#define gds_status      (&tdgbl->status_vector)


void detectRuntimeODS()
{
    struct fb_4_struct {
           short fb_5;  /* fbUtility */
    } fb_4;
    struct fb_1_struct {
           char  fb_2 [1009];   /* RDB$RELATION_NAME */
           char  fb_3 [1009];   /* RDB$FIELD_NAME */
    } fb_1;
    struct fb_9_struct {
           short fb_10; /* fbUtility */
    } fb_9;
    struct fb_7_struct {
           char  fb_8 [1009];   /* RDB$RELATION_NAME */
    } fb_7;
    struct fb_12_struct {
           short fb_13; /* fbUtility */
    } fb_12;
/**************************************
  *
  *     d e t e c t R u n t i m e O D S
  *
  **************************************
  *
  * Functional description
  *     Find the ODS version number of the database.
  *     Use system_flag to avoid any possibility of ambiguity (someone using 
the rdb$ prefix).
  *
  **************************************/

        BurpGlobals* tdgbl = BurpGlobals::getSpecific();
        tdgbl->runtimeODS = 0;

        // Detect very old server before IB4 just in case to exit gracefully.
        // select count(*) from rdb$relation_fields
        // where rdb$relation_name in ('RDB$RELATIONS', 'RDB$RELATION_FIELDS')
        // and rdb$field_name = 'RDB$SYSTEM_FLAG';

        int count = 0;
        Firebird::IRequest* req_handle = nullptr;
        /*FOR (REQUEST_HANDLE req_handle)
                RFR IN RDB$RELATION_FIELDS
                WITH (RFR.RDB$RELATION_NAME = 'RDB$RELATIONS' OR 
RFR.RDB$RELATION_NAME 
= 'RDB$RELATION_FIELDS')
                AND RFR.RDB$FIELD_NAME = 'RDB$SYSTEM_FLAG'*/
        {
        for (int retries = 0; retries < 2; ++retries)
           {
            if (!req_handle && DB)
               req_handle = DB->compileRequest(fbStatus, sizeof(fb_11), 
fb_11);
           if (req_handle)
               req_handle->start(fbStatus, fbTrans, 0);
            if (fbStatus->getErrors()[1] == isc_bad_req_handle) { 
req_handle->release(); req_handle = NULL; }
           else break;
           }
        if (!(fbStatus->getState() & Firebird::IStatus::STATE_ERRORS)) {
        while (1)
           {
            req_handle->receive (fbStatus, 0, 0, 2, CAST_MSG(&fb_12));
           if (!fb_12.fb_13 || (fbStatus->getState() & 
Firebird::IStatus::STATE_ERRORS)) break;
                ++count;
        /*END_FOR;*/
           }
           };
        /*ON_ERROR*/
        if (fbStatus->getState() & Firebird::IStatus::STATE_ERRORS)
           {
                general_on_error();
        /*END_ERROR;*/
           }
        }
        MISC_release_request_silent(req_handle);

        if (count != 2)
                return;

        Firebird::IRequest* req_handle2 = nullptr;
        for (const rel_field_t* rel = relations; rel->relation; ++rel)
        {
                /*FOR (REQUEST_HANDLE req_handle2)
                        FIRST 1 X IN RDB$RELATIONS
                        WITH X.RDB$RELATION_NAME = rel->relation
                        AND X.RDB$SYSTEM_FLAG = 1*/
                {
                for (int retries = 0; retries < 2; ++retries)
                   {
                    if (!req_handle2 && DB)
                       req_handle2 = DB->compileRequest(fbStatus, 
sizeof(fb_6), fb_6);
                   isc_vtov ((const char*) rel->relation, (char*) fb_7.fb_8, 
1009);
                   if (req_handle2)
                       req_handle2->startAndSend(fbStatus, fbTrans, 0, 
0, 1009, CAST_CONST_MSG(&fb_7));
                    if (fbStatus->getErrors()[1] == isc_bad_req_handle) 
{ req_handle2->release(); req_handle2 = NULL; }
                   else break;
                   }
                if (!(fbStatus->getState() & Firebird::IStatus::STATE_ERRORS)) {
                while (1)
                   {
                    req_handle2->receive (fbStatus, 0, 1, 2, 
CAST_MSG(&fb_9));
                   if (!fb_9.fb_10 || (fbStatus->getState() & 
Firebird::IStatus::STATE_ERRORS)) break;
                        if (tdgbl->runtimeODS < rel->ods_version)
                                tdgbl->runtimeODS = rel->ods_version;
                /*END_FOR;*/
                   }
                   };
                /*ON_ERROR*/
                if (fbStatus->getState() & Firebird::IStatus::STATE_ERRORS)
                   {
                        general_on_error();
                /*END_ERROR;*/
                   }
                }
        }
        MISC_release_request_silent(req_handle2);

        if (tdgbl->runtimeODS < DB_VERSION_DDL8)
                return;

        Firebird::IRequest* req_handle3 = nullptr;
        for (const rel_field_t* rf = rel_fields; rf->relation; ++rf)
        {
                /*FOR (REQUEST_HANDLE req_handle3)
                        FIRST 1 X2 IN RDB$RELATION_FIELDS
                        WITH X2.RDB$RELATION_NAME = rf->relation
                        AND X2.RDB$FIELD_NAME = rf->field
                        AND X2.RDB$SYSTEM_FLAG = 1*/
                {
                for (int retries = 0; retries < 2; ++retries)
                   {
                    if (!req_handle3 && DB)
                       req_handle3 = DB->compileRequest(fbStatus, 
sizeof(fb_0), fb_0);
                   isc_vtov ((const char*) rf->relation, (char*) fb_1.fb_2, 
1009);
                   isc_vtov ((const char*) rf->field, (char*) fb_1.fb_3, 1009);
                   if (req_handle3)
                       req_handle3->startAndSend(fbStatus, fbTrans, 0, 
0, 2018, CAST_CONST_MSG(&fb_1));
                    if (fbStatus->getErrors()[1] == isc_bad_req_handle) 
{ req_handle3->release(); req_handle3 = NULL; }
                   else break;
                   }
                if (!(fbStatus->getState() & Firebird::IStatus::STATE_ERRORS)) {
                while (1)
                   {
                    req_handle3->receive (fbStatus, 0, 1, 2, 
CAST_MSG(&fb_4));
                   if (!fb_4.fb_5 || (fbStatus->getState() & 
Firebird::IStatus::STATE_ERRORS)) break;
                        if (tdgbl->runtimeODS < rf->ods_version)
                                tdgbl->runtimeODS = rf->ods_version;
                /*END_FOR;*/
                   }
                   };
                /*ON_ERROR*/
                if (fbStatus->getState() & Firebird::IStatus::STATE_ERRORS)
                   {
                        general_on_error();
                /*END_ERROR;*/
                   }
                }
        }
        MISC_release_request_silent(req_handle3);
}

namespace
{
        // copy/paste from backup.epp
        void general_on_error()
        {
        /**************************************
         *
         *      g e n e r a l _ o n _ e r r o r
         *
         **************************************
         *
         * Functional description
         *      Handle any general ON_ERROR clause during ODS level detection.
         *
         **************************************/
                BurpGlobals* tdgbl = BurpGlobals::getSpecific();

                BURP_print_status(true, isc_status);
                BURP_abort();
        }
}



On 13.02.19 17:39, Robert Tulloch [email protected] [firebird-support] 
wrote:
> 
> 
> Anyone have an example of embedded SQL code and the GPRE result?
> 
> Thanks
> 
> Best regards
> 
> 
> 

mit freundlichen Grüßen
Frank Schlottmann-Gödde

-- 
Oldenburger Str. 34, 23743 Grömitz, Tel.: 04562/266984

Reply via email to