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
