mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-22 18:03:03 +01:00
read only databases are supported unconditionally in fb2
This commit is contained in:
parent
9587c717b3
commit
baa3485651
@ -1,30 +1,34 @@
|
||||
//____________________________________________________________
|
||||
//
|
||||
//
|
||||
// PROGRAM: Alice (All Else) Utility
|
||||
// MODULE: alice.cpp
|
||||
// DESCRIPTION: Neo-Debe (does everything but eat)
|
||||
//
|
||||
//
|
||||
// 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): ______________________________________.
|
||||
//
|
||||
//
|
||||
//
|
||||
//____________________________________________________________
|
||||
//
|
||||
// $Id: alice.cpp,v 1.1.1.1 2001-05-23 13:25:33 tamlin Exp $
|
||||
// $Id: alice.cpp,v 1.2 2001-07-10 17:35:12 awharrison Exp $
|
||||
//
|
||||
// 2001.07.06 Sean Leyne - Code Cleanup, removed "#ifdef READONLY_DATABASE"
|
||||
// conditionals, as the engine now fully supports
|
||||
// readonly databases.
|
||||
//
|
||||
|
||||
#include <stdlib.h>
|
||||
@ -105,9 +109,9 @@ static void alice_output(CONST SCHAR *, ...);
|
||||
#ifdef SUPERSERVER
|
||||
|
||||
//____________________________________________________________
|
||||
//
|
||||
//
|
||||
// Entry point for GFIX in case of service manager.
|
||||
//
|
||||
//
|
||||
|
||||
int main_gfix(SVC service)
|
||||
{
|
||||
@ -120,8 +124,8 @@ int main_gfix(SVC service)
|
||||
if (service->svc_service->in_use != NULL)
|
||||
*(service->svc_service->in_use) = FALSE;
|
||||
|
||||
// Mark service thread as finished.
|
||||
// If service is detached, cleanup memory being used by service.
|
||||
// Mark service thread as finished.
|
||||
// If service is detached, cleanup memory being used by service.
|
||||
SVC_finish(service, SVC_finished);
|
||||
|
||||
return exit_code;
|
||||
@ -129,9 +133,9 @@ int main_gfix(SVC service)
|
||||
|
||||
|
||||
//____________________________________________________________
|
||||
//
|
||||
//
|
||||
// Routine which is passed to GFIX for calling back when there is output.
|
||||
//
|
||||
//
|
||||
|
||||
static int output_thread(SLONG output_data, UCHAR * output_buf)
|
||||
{
|
||||
@ -145,9 +149,9 @@ static int output_thread(SLONG output_data, UCHAR * output_buf)
|
||||
#ifndef GUI_TOOLS
|
||||
|
||||
//____________________________________________________________
|
||||
//
|
||||
//
|
||||
// Call the 'real' main.
|
||||
//
|
||||
//
|
||||
|
||||
int CLIB_ROUTINE main(int argc, char *argv[])
|
||||
{
|
||||
@ -160,9 +164,9 @@ int CLIB_ROUTINE main(int argc, char *argv[])
|
||||
|
||||
|
||||
//____________________________________________________________
|
||||
//
|
||||
//
|
||||
// Routine which is passed to GFIX for calling back when there is output.
|
||||
//
|
||||
//
|
||||
|
||||
static int output_main(SLONG output_data, UCHAR * output_buf)
|
||||
{
|
||||
@ -173,10 +177,10 @@ static int output_main(SLONG output_data, UCHAR * output_buf)
|
||||
#endif
|
||||
|
||||
//____________________________________________________________
|
||||
//
|
||||
//
|
||||
// Routine which is passed to GFIX for calling back when there is output
|
||||
// if gfix is run as a service
|
||||
//
|
||||
//
|
||||
|
||||
static int output_svc(SLONG output_data, UCHAR * output_buf)
|
||||
{
|
||||
@ -186,10 +190,10 @@ static int output_svc(SLONG output_data, UCHAR * output_buf)
|
||||
|
||||
|
||||
//____________________________________________________________
|
||||
//
|
||||
//
|
||||
// Routine called by command line utility, and server manager
|
||||
// Parse switches and do work
|
||||
//
|
||||
//
|
||||
|
||||
int DLL_EXPORT ALICE_gfix(
|
||||
int argc,
|
||||
@ -208,7 +212,7 @@ int DLL_EXPORT ALICE_gfix(
|
||||
#endif
|
||||
|
||||
VOLATILE tgbl *tdgbl = (struct tgbl *) gds__alloc(sizeof(*tdgbl));
|
||||
// NOMEM: return error, FREE: during function exit in the SETJMP
|
||||
// NOMEM: return error, FREE: during function exit in the SETJMP
|
||||
if (tdgbl == NULL)
|
||||
return FINI_ERROR;
|
||||
// TMN
|
||||
@ -219,8 +223,8 @@ int DLL_EXPORT ALICE_gfix(
|
||||
#endif
|
||||
SVC_PUTSPECIFIC_DATA;
|
||||
memset((void *) tdgbl, 0, sizeof(*tdgbl));
|
||||
// TMN: I can't for my life understand why the jmp_buf is defined
|
||||
// as a UCHAR* in ' struct tgbl', but it forces this cast.
|
||||
// TMN: I can't for my life understand why the jmp_buf is defined
|
||||
// as a UCHAR* in ' struct tgbl', but it forces this cast.
|
||||
tdgbl->alice_env = (UCHAR * volatile) env;
|
||||
tdgbl->output_proc = output_proc;
|
||||
tdgbl->output_data = output_data;
|
||||
@ -265,7 +269,7 @@ int DLL_EXPORT ALICE_gfix(
|
||||
|
||||
// Perform some special handling when run as an Interbase service. The
|
||||
// first switch can be "-svc" (lower case!) or it can be "-svc_re" followed
|
||||
// by 3 file descriptors to use in re-directing ib_stdin, ib_stdout, and ib_stderr.
|
||||
// by 3 file descriptors to use in re-directing ib_stdin, ib_stdout, and ib_stderr.
|
||||
|
||||
tdgbl->sw_service = FALSE;
|
||||
tdgbl->sw_service_thd = FALSE;
|
||||
@ -319,7 +323,7 @@ int DLL_EXPORT ALICE_gfix(
|
||||
tdgbl->ALICE_data.ua_user = NULL;
|
||||
tdgbl->ALICE_data.ua_password = NULL;
|
||||
|
||||
// Start by parsing switches
|
||||
// Start by parsing switches
|
||||
|
||||
error = 0;
|
||||
switches = 0;
|
||||
@ -340,7 +344,7 @@ int DLL_EXPORT ALICE_gfix(
|
||||
// name in the correct character set.
|
||||
// if (GetConsoleCP != GetACP())
|
||||
// OemToAnsi(database, database);
|
||||
//
|
||||
//
|
||||
#else
|
||||
#endif
|
||||
continue;
|
||||
@ -414,7 +418,7 @@ int DLL_EXPORT ALICE_gfix(
|
||||
ALICE_error(7, 0, 0, 0, 0, 0); /* msg 7: numeric value required */
|
||||
|
||||
if (tdgbl->ALICE_data.ua_db_SQL_dialect < 0)
|
||||
ALICE_error(8, 0, 0, 0, 0, 0); /* msg 8: positive numeric value
|
||||
ALICE_error(8, 0, 0, 0, 0, 0); /* msg 8: positive numeric value
|
||||
required */
|
||||
}
|
||||
|
||||
@ -489,7 +493,6 @@ int DLL_EXPORT ALICE_gfix(
|
||||
ALICE_error(18, 0, 0, 0, 0, 0); /* msg 18: numeric value between 0 and 32767 inclusive required */
|
||||
}
|
||||
|
||||
#ifdef READONLY_DATABASE
|
||||
if (table->in_sw_value & sw_mode) {
|
||||
if (--argc <= 0)
|
||||
ALICE_error(110, 0, 0, 0, 0, 0); /* msg 110: "read_only" or "read_write" required */
|
||||
@ -501,18 +504,17 @@ int DLL_EXPORT ALICE_gfix(
|
||||
else
|
||||
ALICE_error(110, 0, 0, 0, 0, 0); /* msg 110: "read_only" or "read_write" required */
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
// put this here since to put it above overly complicates the parsing
|
||||
// can't use tbl_requires since it only looks backwards on command line
|
||||
// put this here since to put it above overly complicates the parsing
|
||||
// can't use tbl_requires since it only looks backwards on command line
|
||||
if ((switches & sw_shut)
|
||||
&& !(switches & ((sw_attach | sw_force | sw_tran | sw_cache))))
|
||||
ALICE_error(19, 0, 0, 0, 0, 0); /* msg 19: must specify type of shutdown */
|
||||
|
||||
// catch the case where -z is only command line option
|
||||
// switches is unset since sw_z == 0
|
||||
// catch the case where -z is only command line option
|
||||
// switches is unset since sw_z == 0
|
||||
if (!switches && !error && table->in_sw_value == sw_z)
|
||||
EXIT(FINI_OK);
|
||||
|
||||
@ -542,7 +544,7 @@ int DLL_EXPORT ALICE_gfix(
|
||||
ALICE_error(23, 0, 0, 0, 0, 0); /* msg 23: please retry, giving a database name */
|
||||
|
||||
// generate the database parameter block for the attach,
|
||||
// based on the various switches
|
||||
// based on the various switches
|
||||
|
||||
if (switches & (sw_list | sw_commit | sw_rollback | sw_two_phase))
|
||||
ret = EXE_two_phase(database, switches);
|
||||
@ -578,9 +580,9 @@ int DLL_EXPORT ALICE_gfix(
|
||||
|
||||
|
||||
//____________________________________________________________
|
||||
//
|
||||
//
|
||||
// Copy a string, down casing as we go.
|
||||
//
|
||||
//
|
||||
|
||||
void ALICE_down_case(TEXT * in, TEXT * out)
|
||||
{
|
||||
@ -594,9 +596,9 @@ void ALICE_down_case(TEXT * in, TEXT * out)
|
||||
|
||||
|
||||
//____________________________________________________________
|
||||
//
|
||||
//
|
||||
// Display a formatted error message
|
||||
//
|
||||
//
|
||||
|
||||
void ALICE_print(USHORT number,
|
||||
TEXT * arg1,
|
||||
@ -612,10 +614,10 @@ void ALICE_print(USHORT number,
|
||||
|
||||
|
||||
//____________________________________________________________
|
||||
//
|
||||
//
|
||||
// Print error message. Use isc_interprete
|
||||
// to allow redirecting output.
|
||||
//
|
||||
//
|
||||
|
||||
void ALICE_print_status(STATUS * status_vector)
|
||||
{
|
||||
@ -654,9 +656,9 @@ void ALICE_print_status(STATUS * status_vector)
|
||||
|
||||
|
||||
//____________________________________________________________
|
||||
//
|
||||
//
|
||||
// Format and print an error message, then punt.
|
||||
//
|
||||
//
|
||||
|
||||
void ALICE_error(USHORT number,
|
||||
TEXT * arg1,
|
||||
@ -689,9 +691,9 @@ void ALICE_error(USHORT number,
|
||||
|
||||
|
||||
//____________________________________________________________
|
||||
//
|
||||
//
|
||||
// Platform independent output routine.
|
||||
//
|
||||
//
|
||||
|
||||
static void alice_output(CONST SCHAR * format, ...)
|
||||
{
|
||||
@ -729,10 +731,10 @@ static void alice_output(CONST SCHAR * format, ...)
|
||||
|
||||
|
||||
//____________________________________________________________
|
||||
//
|
||||
//
|
||||
// Fully expand a file name. If the file doesn't exist, do something
|
||||
// intelligent.
|
||||
//
|
||||
//
|
||||
|
||||
static void expand_filename(TEXT * filename, TEXT * expanded_name)
|
||||
{
|
||||
@ -740,4 +742,4 @@ static void expand_filename(TEXT * filename, TEXT * expanded_name)
|
||||
}
|
||||
|
||||
|
||||
} // extern "C"
|
||||
} // extern "C"
|
@ -15,6 +15,9 @@
|
||||
*
|
||||
* All Rights Reserved.
|
||||
* Contributor(s): ______________________________________.
|
||||
* 2001.07.06 Sean Leyne - Code Cleanup, removed "#ifdef READONLY_DATABASE"
|
||||
* conditionals, as the engine now fully supports
|
||||
* readonly databases.
|
||||
*/
|
||||
#ifndef ALICE_ALICESWI_H
|
||||
#define ALICE_ALICESWI_H
|
||||
@ -160,11 +163,9 @@ static struct in_sw_tab_t alice_in_sw_table[] =
|
||||
IN_SW_ALICE_MEND, isc_spb_rpr_mend_db, "mend", SW_MEND,
|
||||
0, ~sw_no_update, FALSE, 38, 0, NULL,
|
||||
/* msg 38: \t-mend\t\tprepare corrupt database for backup */
|
||||
#ifdef READONLY_DATABASE
|
||||
IN_SW_ALICE_MODE, 0, "mode", sw_mode,
|
||||
0, ~sw_mode, FALSE, 109, 0, NULL,
|
||||
/* msg 109: \t-mode\t\tread_only or read_write */
|
||||
#endif /* READONLY_DATABASE */
|
||||
IN_SW_ALICE_NO_UPDATE, isc_spb_rpr_check_db, "no_update", sw_no_update,
|
||||
sw_validate, 0, FALSE, 39, 0, NULL,
|
||||
/* msg 39: \t-no_update\tread-only validation (-v) */
|
||||
@ -250,15 +251,13 @@ static struct in_sw_tab_t alice_in_sw_table[] =
|
||||
0, 0, 0, FALSE, 0, 0, NULL,
|
||||
IN_SW_ALICE_HIDDEN_ATTACH, isc_spb_prp_deny_new_attachments,
|
||||
"shut -attach", 0, 0, 0, FALSE, 0, 0, NULL,
|
||||
#ifdef READONLY_DATABASE
|
||||
IN_SW_ALICE_HIDDEN_RDONLY, isc_spb_prp_am_readonly, "mode read_only", 0,
|
||||
0, 0, FALSE, 0, 0, NULL,
|
||||
IN_SW_ALICE_HIDDEN_RDWRITE, isc_spb_prp_am_readwrite, "mode read_write",
|
||||
0, 0, 0, FALSE, 0, 0, NULL,
|
||||
#endif /* READONLY_DATABASE */
|
||||
/************************************************************************/
|
||||
IN_SW_ALICE_0, 0, NULL, 0,
|
||||
0, 0, FALSE, 0, 0, NULL
|
||||
};
|
||||
|
||||
#endif /* ALICE_ALICESWI_H */
|
||||
#endif /* ALICE_ALICESWI_H */
|
@ -1,30 +1,34 @@
|
||||
//____________________________________________________________
|
||||
//
|
||||
//
|
||||
// PROGRAM: Alice (All Else) Utility
|
||||
// MODULE: exe.cpp
|
||||
// DESCRIPTION: Does the database calls
|
||||
//
|
||||
//
|
||||
// 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): ______________________________________.
|
||||
//
|
||||
//
|
||||
//
|
||||
//____________________________________________________________
|
||||
//
|
||||
// $Id: exe.cpp,v 1.1.1.1 2001-05-23 13:25:33 tamlin Exp $
|
||||
// $Id: exe.cpp,v 1.2 2001-07-10 17:35:12 awharrison Exp $
|
||||
//
|
||||
// 2001.07.06 Sean Leyne - Code Cleanup, removed "#ifdef READONLY_DATABASE"
|
||||
// conditionals, as the engine now fully supports
|
||||
// readonly databases.
|
||||
//
|
||||
|
||||
#include "../jrd/ib_stdio.h"
|
||||
@ -76,8 +80,8 @@ static TEXT val_errors[] =
|
||||
|
||||
|
||||
//____________________________________________________________
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
int EXE_action(TEXT * database, ULONG switches)
|
||||
{
|
||||
@ -96,7 +100,7 @@ int EXE_action(TEXT * database, ULONG switches)
|
||||
tdgbl->ALICE_data.ua_val_errors[i] = 0;
|
||||
|
||||
// generate the database parameter block for the attach,
|
||||
// based on the various switches
|
||||
// based on the various switches
|
||||
|
||||
dpb_length = build_dpb(dpb, switches);
|
||||
|
||||
@ -144,8 +148,8 @@ int EXE_action(TEXT * database, ULONG switches)
|
||||
|
||||
#ifndef GUI_TOOLS
|
||||
//____________________________________________________________
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
int EXE_two_phase(TEXT * database, ULONG switches)
|
||||
{
|
||||
@ -163,7 +167,7 @@ int EXE_two_phase(TEXT * database, ULONG switches)
|
||||
tdgbl->ALICE_data.ua_val_errors[i] = 0;
|
||||
|
||||
// generate the database parameter block for the attach,
|
||||
// based on the various switches
|
||||
// based on the various switches
|
||||
|
||||
dpb_length = build_dpb(dpb, switches);
|
||||
|
||||
@ -201,11 +205,11 @@ int EXE_two_phase(TEXT * database, ULONG switches)
|
||||
|
||||
|
||||
//____________________________________________________________
|
||||
//
|
||||
//
|
||||
// generate the database parameter block for the attach,
|
||||
// based on the various switches
|
||||
//
|
||||
//
|
||||
//
|
||||
// generate the database parameter block for the attach,
|
||||
// based on the various switches
|
||||
//
|
||||
|
||||
static USHORT build_dpb(UCHAR * dpb, ULONG switches)
|
||||
{
|
||||
@ -289,13 +293,12 @@ static USHORT build_dpb(UCHAR * dpb, ULONG switches)
|
||||
*d++ = 1;
|
||||
*d++ = tdgbl->ALICE_data.ua_use;
|
||||
}
|
||||
#ifdef READONLY_DATABASE
|
||||
|
||||
else if (switches & sw_mode) {
|
||||
*d++ = isc_dpb_set_db_readonly;
|
||||
*d++ = 1;
|
||||
*d++ = tdgbl->ALICE_data.ua_read_only;
|
||||
}
|
||||
#endif /* READONLY_DATABASE */
|
||||
else if (switches & sw_shut) {
|
||||
*d++ = gds_dpb_shutdown;
|
||||
*d++ = 1;
|
||||
@ -366,9 +369,9 @@ static USHORT build_dpb(UCHAR * dpb, ULONG switches)
|
||||
|
||||
|
||||
//____________________________________________________________
|
||||
//
|
||||
//
|
||||
// Extract database info from string
|
||||
//
|
||||
//
|
||||
|
||||
static void extract_db_info(UCHAR * db_info_buffer)
|
||||
{
|
||||
@ -444,4 +447,4 @@ static void extract_db_info(UCHAR * db_info_buffer)
|
||||
}
|
||||
|
||||
|
||||
} // extern "C"
|
||||
} // extern "C"
|
File diff suppressed because it is too large
Load Diff
@ -19,6 +19,9 @@
|
||||
*
|
||||
* All Rights Reserved.
|
||||
* Contributor(s): ______________________________________.
|
||||
* 2001.07.06 Sean Leyne - Code Cleanup, removed "#ifdef READONLY_DATABASE"
|
||||
* conditionals, as the engine now fully supports
|
||||
* readonly databases.
|
||||
*/
|
||||
|
||||
#include "../jrd/ib_stdio.h"
|
||||
@ -371,7 +374,7 @@ int CLIB_ROUTINE main(int argc, char* argv[])
|
||||
*
|
||||
* If -USER and -PASSWORD switches are used by the user within
|
||||
* the gbak command line then we have to eliminate them from there. The
|
||||
* password will be encrypted and added along with the user name
|
||||
* password will be encrypted and added along with the user name
|
||||
* within SVC_start function later on. We shall also eliminate
|
||||
* the -SERVER switch because the switch has already been processed.
|
||||
*/
|
||||
@ -449,7 +452,7 @@ int DLL_EXPORT BURP_gbak(int argc,
|
||||
TEXT *file1, **end, *string, *p, *q, c, *device, *redirect;
|
||||
/* This function runs within thread for services API, so here should not be
|
||||
*any* static variables. I did not change an existing definition
|
||||
for AIX PowerPC because of the problem (see comments below). So
|
||||
for AIX PowerPC because of the problem (see comments below). So
|
||||
whoever will do a port on AIX, must reconsider a static definition */
|
||||
#ifdef AIX_PPC
|
||||
static TEXT *file2; /* SomeHow, making this VOLATILE does'nt give the
|
||||
@ -629,9 +632,7 @@ int DLL_EXPORT BURP_gbak(int argc,
|
||||
tdgbl->gbl_sw_ignore_limbo = FALSE;
|
||||
tdgbl->gbl_sw_blk_factor = 0;
|
||||
tdgbl->gbl_sw_no_reserve = FALSE;
|
||||
#ifdef READONLY_DATABASE
|
||||
tdgbl->gbl_sw_mode = FALSE;
|
||||
#endif /* READONLY_DATABASE */
|
||||
tdgbl->gbl_sw_skip_count = 0;
|
||||
tdgbl->gbl_sw_bug8183 = FALSE;
|
||||
tdgbl->action = NULL;
|
||||
@ -718,7 +719,6 @@ int DLL_EXPORT BURP_gbak(int argc,
|
||||
BURP_error(259, *argv, 0, 0, 0, 0); /* msg 259 expected page buffers, encountered "%s" */
|
||||
argv++;
|
||||
}
|
||||
#ifdef READONLY_DATABASE
|
||||
else if (in_sw_tab->in_sw == IN_SW_BURP_MODE) {
|
||||
if (argv >= end)
|
||||
BURP_error(279, 0, 0, 0, 0, 0); /* msg 279: "read_only" or "read_write" required */
|
||||
@ -731,7 +731,6 @@ int DLL_EXPORT BURP_gbak(int argc,
|
||||
BURP_error(279, 0, 0, 0, 0, 0); /* msg 279: "read_only" or "read_write" required */
|
||||
tdgbl->gbl_sw_mode = TRUE;
|
||||
}
|
||||
#endif /* READONLY_DATABASE */
|
||||
else if (in_sw_tab->in_sw == IN_SW_BURP_PASS) {
|
||||
if (argv >= end)
|
||||
BURP_error(189, 0, 0, 0, 0, 0); /* password parameter missing */
|
||||
@ -904,11 +903,9 @@ int DLL_EXPORT BURP_gbak(int argc,
|
||||
tdgbl->gbl_sw_meta = TRUE;
|
||||
break;
|
||||
|
||||
#ifdef READONLY_DATABASE
|
||||
case (IN_SW_BURP_MODE):
|
||||
tdgbl->gbl_sw_mode = TRUE;
|
||||
break;
|
||||
#endif /* READONLY_DATABASE */
|
||||
|
||||
case (IN_SW_BURP_N):
|
||||
tdgbl->gbl_sw_novalidity = TRUE;
|
||||
@ -1285,7 +1282,7 @@ void BURP_msg_partial( USHORT number,
|
||||
**************************************
|
||||
*
|
||||
* Functional description
|
||||
* Retrieve a message from the error file,
|
||||
* Retrieve a message from the error file,
|
||||
* format it, and print it without a newline.
|
||||
*
|
||||
**************************************/
|
||||
@ -1474,7 +1471,7 @@ static void close_out_transaction(VOLATILE SSHORT action,
|
||||
}
|
||||
}
|
||||
else
|
||||
/* A backup shouldn't touch any data - we ensure that
|
||||
/* A backup shouldn't touch any data - we ensure that
|
||||
* by never writing data during a backup, but let's double
|
||||
* ensure it by doing a rollback
|
||||
*/
|
||||
@ -1892,11 +1889,11 @@ static SSHORT open_files(TEXT * file1,
|
||||
if (sw_replace == IN_SW_BURP_R && status_vector[1] == isc_adm_task_denied) {
|
||||
/* if we got an error from attach database and we have replace switch set
|
||||
* then look for error from attach returned due to not owner, if we are
|
||||
* not owner then return the error status back up
|
||||
* not owner then return the error status back up
|
||||
*/
|
||||
BURP_error(274, 0, 0, 0, 0, 0);
|
||||
/* msg # 274 : Cannot restore over current database, must be sysdba
|
||||
* or owner of the existing database.
|
||||
* or owner of the existing database.
|
||||
*/
|
||||
}
|
||||
/* if we got here, then all is well, remove any error condition from the
|
||||
@ -2255,4 +2252,4 @@ static int api_gbak(int argc,
|
||||
#endif // !SUPERSERVER
|
||||
|
||||
|
||||
} // extern "C"
|
||||
} // extern "C"
|
@ -19,6 +19,9 @@
|
||||
*
|
||||
* All Rights Reserved.
|
||||
* Contributor(s): ______________________________________.
|
||||
* 2001.07.06 Sean Leyne - Code Cleanup, removed "#ifdef READONLY_DATABASE"
|
||||
* conditionals, as the engine now fully supports
|
||||
* readonly databases.
|
||||
*/
|
||||
|
||||
#ifndef _BURP_BURPSWI_H_
|
||||
@ -110,10 +113,8 @@ static struct in_sw_tab_t burp_in_sw_table [] =
|
||||
IN_SW_BURP_M, isc_spb_bkp_metadata_only, "METADATA", 0, 0, 0, FALSE, 0, 0, NULL,
|
||||
IN_SW_BURP_M, 0, "META_DATA", 0, 0, 0, FALSE, 63, 0, NULL,
|
||||
/* msg 63: %sMETA_DATA backup metadata only */
|
||||
#ifdef READONLY_DATABASE
|
||||
IN_SW_BURP_MODE, 0, "MODE", 0, 0, 0, FALSE, 278, 0, NULL,
|
||||
/* msg 278: %sMODE read_only or read_write access */
|
||||
#endif /* READONLY_DATABASE */
|
||||
IN_SW_BURP_N, isc_spb_res_no_validity, "NO_VALIDITY", 0, 0, 0, FALSE, 187, 0, NULL,
|
||||
/* msg 187: %sN(O_VALIDITY) do not restore database validity conditions */
|
||||
IN_SW_BURP_NT, isc_spb_bkp_non_transportable, "NT", 0, 0, 0, FALSE, 239, 0, NULL,
|
||||
@ -156,7 +157,6 @@ static struct in_sw_tab_t burp_in_sw_table [] =
|
||||
#endif
|
||||
/* next switch is a hidden option in case of bug_no 8183 */
|
||||
IN_SW_BURP_BUG8183, 0, "BUG_8183", 0, 0, 0, FALSE, 0, 0, NULL,
|
||||
#ifdef READONLY_DATABASE
|
||||
/**************************************************************************/
|
||||
/* The next two 'virtual' switches are hidden from user and are needed */
|
||||
/* for services API */
|
||||
@ -164,7 +164,6 @@ static struct in_sw_tab_t burp_in_sw_table [] =
|
||||
IN_SW_BURP_HIDDEN_RDONLY, isc_spb_res_am_readonly, "mode read_only", 0, 0, 0, FALSE, 0, 0, NULL,
|
||||
IN_SW_BURP_HIDDEN_RDWRITE, isc_spb_res_am_readwrite, "mode read_write", 0, 0, 0, FALSE, 0, 0, NULL,
|
||||
/**************************************************************************/
|
||||
#endif
|
||||
IN_SW_BURP_0, 0, NULL, 0, 0, 0, FALSE, 0, 0, NULL
|
||||
};
|
||||
|
||||
@ -182,4 +181,4 @@ static struct in_sw_tab_t spit_in_sw_table [] =
|
||||
IN_SW_SPIT_0, 0, NULL, 0, 0, 0, FALSE, 0, 0, NULL
|
||||
};
|
||||
|
||||
#endif /* _BURP_BURP_H_ */
|
||||
#endif /* _BURP_BURP_H_ */
|
File diff suppressed because it is too large
Load Diff
@ -20,9 +20,13 @@
|
||||
* All Rights Reserved.
|
||||
* Contributor(s): ______________________________________.
|
||||
*
|
||||
* $Id: ddl.cpp,v 1.1.1.1 2001-05-23 13:25:35 tamlin Exp $
|
||||
* $Id: ddl.cpp,v 1.2 2001-07-10 17:35:13 awharrison Exp $
|
||||
* 2001.5.20 Claudio Valderrama: Stop null pointer that leads to a crash,
|
||||
* caused by incomplete yacc syntax that allows ALTER DOMAIN dom SET;
|
||||
*
|
||||
* 2001.07.06 Sean Leyne - Code Cleanup, removed "#ifdef READONLY_DATABASE"
|
||||
* conditionals, as the engine now fully supports
|
||||
* readonly databases.
|
||||
*/
|
||||
|
||||
#include "../jrd/ib_stdio.h"
|
||||
@ -195,7 +199,7 @@ ASSERT_FILENAME void DDL_execute( REQ request)
|
||||
*
|
||||
* Functional description
|
||||
* Call access method layered service DYN
|
||||
* to interpret dyn string and perform
|
||||
* to interpret dyn string and perform
|
||||
* metadata updates.
|
||||
*
|
||||
**************************************/
|
||||
@ -271,12 +275,10 @@ void DDL_generate( REQ request, NOD node)
|
||||
*
|
||||
**************************************/
|
||||
|
||||
#ifdef READONLY_DATABASE
|
||||
if (request->req_dbb->dbb_flags & DBB_read_only) {
|
||||
ERRD_post(isc_read_only_database, 0);
|
||||
return;
|
||||
}
|
||||
#endif /* READONLY_DATABASE */
|
||||
|
||||
STUFF(gds_dyn_version_1);
|
||||
generate_dyn(request, node);
|
||||
@ -319,7 +321,7 @@ void DDL_put_field_dtype( REQ request, FLD field, USHORT use_subtype)
|
||||
{
|
||||
/**************************************
|
||||
*
|
||||
* D D L _ p u t _ f i e l d _ d t y p e
|
||||
* D D L _ p u t _ f i e l d _ d t y p e
|
||||
*
|
||||
**************************************
|
||||
*
|
||||
@ -575,7 +577,7 @@ static USHORT check_array_or_blob( NOD node)
|
||||
* Functional description
|
||||
* return TRUE if there is an array or blob in expression, else FALSE.
|
||||
* Array and blob expressions have limited usefullness in a computed
|
||||
* expression - so we detect it here to report a syntax error at
|
||||
* expression - so we detect it here to report a syntax error at
|
||||
* definition time, rather than a runtime error at execution.
|
||||
*
|
||||
**************************************/
|
||||
@ -737,7 +739,7 @@ static void create_view_triggers( REQ request, NOD element, NOD items)
|
||||
{ /* Fields in the VIEW actually */
|
||||
/* *************************************
|
||||
*
|
||||
* c r e a t e _ v i e w _ t r i g g e r s
|
||||
* c r e a t e _ v i e w _ t r i g g e r s
|
||||
*
|
||||
**************************************
|
||||
*
|
||||
@ -802,8 +804,8 @@ static void define_computed(
|
||||
**************************************
|
||||
*
|
||||
* Function
|
||||
* Create the ddl to define a computed field
|
||||
* or an expression index.
|
||||
* Create the ddl to define a computed field
|
||||
* or an expression index.
|
||||
*
|
||||
**************************************/
|
||||
NOD input, ddl_node;
|
||||
@ -1040,9 +1042,9 @@ static void define_database( REQ request)
|
||||
**************************************
|
||||
*
|
||||
* Function
|
||||
* Create a database. Assumes that
|
||||
* database is created elsewhere with
|
||||
* initial options. Modify the
|
||||
* Create a database. Assumes that
|
||||
* database is created elsewhere with
|
||||
* initial options. Modify the
|
||||
* database using DYN to add the remaining
|
||||
* options.
|
||||
*
|
||||
@ -1261,7 +1263,7 @@ TEXT * prim_rel_name, TEXT * for_rel_name, BOOLEAN on_upd_trg)
|
||||
*****************************************************
|
||||
*
|
||||
* Function
|
||||
* define "on delete|update set default" trigger (for
|
||||
* define "on delete|update set default" trigger (for
|
||||
* referential integrity) along with its blr
|
||||
*
|
||||
*****************************************************/
|
||||
@ -1349,7 +1351,7 @@ TEXT * prim_rel_name, TEXT * for_rel_name, BOOLEAN on_upd_trg)
|
||||
(2) The default-info for this column is not in memory (This is
|
||||
because this is an alter table ddl statement). The table
|
||||
already exists; therefore we get the column and/or domain
|
||||
default value from the system tables by calling:
|
||||
default value from the system tables by calling:
|
||||
METD_get_col_default(). */
|
||||
|
||||
found_default = FALSE;
|
||||
@ -1385,7 +1387,7 @@ TEXT * prim_rel_name, TEXT * for_rel_name, BOOLEAN on_upd_trg)
|
||||
reinterpret_cast <
|
||||
char *>(domain_name_str->str_data))) break;
|
||||
|
||||
/* case: (1-b): domain name is available. Column level default
|
||||
/* case: (1-b): domain name is available. Column level default
|
||||
is not declared. so get the domain default */
|
||||
METD_get_domain_default(request, domain_name, &found_default,
|
||||
reinterpret_cast <
|
||||
@ -1457,7 +1459,7 @@ static void define_dimensions( REQ request, FLD field)
|
||||
*****************************************
|
||||
*
|
||||
* Function
|
||||
* Define dimensions of an array
|
||||
* Define dimensions of an array
|
||||
*
|
||||
**************************************/
|
||||
NOD elements, element;
|
||||
@ -1510,7 +1512,7 @@ static void define_domain( REQ request)
|
||||
**************************************
|
||||
*
|
||||
* Function
|
||||
* Define a domain (global field)
|
||||
* Define a domain (global field)
|
||||
*
|
||||
**************************************/
|
||||
NOD node;
|
||||
@ -1927,7 +1929,7 @@ static void define_index( REQ request)
|
||||
put_cstring(request, gds_dyn_rel_name,
|
||||
reinterpret_cast<char*>(relation_name->str_data));
|
||||
|
||||
/* go through the fields list, making an index segment for each field,
|
||||
/* go through the fields list, making an index segment for each field,
|
||||
unless we have a computation, in which case generate an expression index */
|
||||
|
||||
if (field_list->nod_type == nod_list)
|
||||
@ -1963,9 +1965,9 @@ static NOD define_insert_action( REQ request)
|
||||
**************************************
|
||||
*
|
||||
* Function
|
||||
* Define an action statement which, given a view
|
||||
* Define an action statement which, given a view
|
||||
* definition, will store a record from
|
||||
* a view of a single relation into the
|
||||
* a view of a single relation into the
|
||||
* base relation.
|
||||
*
|
||||
**************************************/
|
||||
@ -1983,7 +1985,7 @@ static NOD define_insert_action( REQ request)
|
||||
|
||||
if (ddl_node->nod_type != nod_def_view ||
|
||||
!(select_node = ddl_node->nod_arg[e_view_select]) ||
|
||||
/*
|
||||
/*
|
||||
Handle VIEWS with UNION : nod_select now points to nod_list
|
||||
which in turn points to nod_select_expr
|
||||
*/
|
||||
@ -2006,7 +2008,7 @@ static NOD define_insert_action( REQ request)
|
||||
from_list->nod_arg[0]->nod_arg[e_rln_name];
|
||||
relation_node->nod_arg[e_rln_alias] = (NOD) MAKE_cstring(TEMP_CONTEXT);
|
||||
|
||||
/* get the list of values and fields to assign to -- if there is
|
||||
/* get the list of values and fields to assign to -- if there is
|
||||
no list of fields, get all fields in the base relation that
|
||||
are not computed */
|
||||
|
||||
@ -2277,7 +2279,7 @@ static void define_rel_constraint( REQ request, NOD element)
|
||||
{
|
||||
/**************************************
|
||||
*
|
||||
* d e f i n e _ r e l _ c o n s t r a i n t
|
||||
* d e f i n e _ r e l _ c o n s t r a i n t
|
||||
*
|
||||
**************************************
|
||||
*
|
||||
@ -2314,7 +2316,7 @@ static void define_relation( REQ request)
|
||||
*
|
||||
* Function
|
||||
* Create an SQL table, relying on DYN to generate
|
||||
* global fields for the local fields.
|
||||
* global fields for the local fields.
|
||||
*
|
||||
**************************************/
|
||||
NOD ddl_node, elements, element, *ptr, *end, relation_node;
|
||||
@ -2427,7 +2429,7 @@ TEXT * prim_rel_name, TEXT * for_rel_name, BOOLEAN on_upd_trg)
|
||||
/* the trigger blr */
|
||||
begin_blr(request, gds_dyn_trg_blr);
|
||||
|
||||
/* for ON UPDATE TRIGGER only: generate the trigger firing condition:
|
||||
/* for ON UPDATE TRIGGER only: generate the trigger firing condition:
|
||||
if prim_key.old_value != prim_key.new value.
|
||||
Note that the key could consist of multiple columns */
|
||||
|
||||
@ -2884,9 +2886,9 @@ static void define_update_action(
|
||||
**************************************
|
||||
*
|
||||
* Function
|
||||
* Define an action statement which, given a view
|
||||
* Define an action statement which, given a view
|
||||
* definition, will map a update to a record from
|
||||
* a view of a single relation into the
|
||||
* a view of a single relation into the
|
||||
* base relation.
|
||||
*
|
||||
**************************************/
|
||||
@ -2906,7 +2908,7 @@ static void define_update_action(
|
||||
|
||||
if (ddl_node->nod_type != nod_def_view ||
|
||||
!(select_node = ddl_node->nod_arg[e_view_select]) ||
|
||||
/*
|
||||
/*
|
||||
Handle VIEWS with UNION : nod_select now points to nod_list
|
||||
which in turn points to nod_select_expr
|
||||
*/
|
||||
@ -2923,7 +2925,7 @@ static void define_update_action(
|
||||
relation_node->nod_arg[e_rln_alias] = (NOD) MAKE_cstring(TEMP_CONTEXT);
|
||||
*base_relation = relation_node;
|
||||
|
||||
/* get the list of values and fields to compare to -- if there is
|
||||
/* get the list of values and fields to compare to -- if there is
|
||||
no list of fields, get all fields in the base relation that
|
||||
are not computed */
|
||||
|
||||
@ -3296,7 +3298,7 @@ static void define_view( REQ request)
|
||||
gds_arg_gds, gds__table_view_err,
|
||||
/* Only one table allowed for VIEW WITH CHECK OPTION */
|
||||
0);
|
||||
/*
|
||||
/*
|
||||
Handle VIEWS with UNION : nod_select now points to nod_list
|
||||
which in turn points to nod_select_expr
|
||||
*/
|
||||
@ -3307,7 +3309,7 @@ static void define_view( REQ request)
|
||||
/* Only one table allowed for VIEW WITH CHECK OPTION */
|
||||
0);
|
||||
|
||||
/*
|
||||
/*
|
||||
Handle VIEWS with UNION : nod_select now points to nod_list
|
||||
which in turn points to nod_select_expr
|
||||
*/
|
||||
@ -3335,8 +3337,8 @@ static void define_view( REQ request)
|
||||
|
||||
check->nod_arg[e_cnstr_source] = (NOD) source;
|
||||
|
||||
/* the condition for the trigger is the converse of the selection
|
||||
criteria for the view, suitably fixed up so that the fields in
|
||||
/* the condition for the trigger is the converse of the selection
|
||||
criteria for the view, suitably fixed up so that the fields in
|
||||
the view are referenced */
|
||||
|
||||
check->nod_arg[e_cnstr_condition] = select_expr->nod_arg[e_sel_where];
|
||||
@ -3377,7 +3379,7 @@ static void define_view_trigger( REQ request, NOD node, NOD rse, NOD items)
|
||||
ddl_node = request->req_ddl_node;
|
||||
|
||||
select = ddl_node->nod_arg[e_view_select];
|
||||
/*
|
||||
/*
|
||||
Handle VIEWS with UNION : nod_select now points to nod_list
|
||||
which in turn points to nod_select_expr
|
||||
*/
|
||||
@ -3884,8 +3886,8 @@ static void make_index(
|
||||
**************************************
|
||||
*
|
||||
* Function
|
||||
* Generate ddl to create an index for a unique
|
||||
* or primary key constraint.
|
||||
* Generate ddl to create an index for a unique
|
||||
* or primary key constraint.
|
||||
* This is not called for a foreign key constraint.
|
||||
* The func. make_index_trf_ref_int handles foreign key constraint
|
||||
*
|
||||
@ -3932,7 +3934,7 @@ static void make_index_trg_ref_int(
|
||||
*
|
||||
* Function
|
||||
* This is called only when the element->nod_type == nod_foreign_key
|
||||
*
|
||||
*
|
||||
* o Generate ddl to create an index for a unique
|
||||
* or primary key constraint.
|
||||
* o Also make an index for the foreign key constraint
|
||||
@ -4077,7 +4079,7 @@ static void modify_database( REQ request)
|
||||
**************************************
|
||||
*
|
||||
* Function
|
||||
* Modify a database.
|
||||
* Modify a database.
|
||||
*
|
||||
**************************************/
|
||||
NOD ddl_node, elements, element, *ptr, *end;
|
||||
@ -4222,7 +4224,7 @@ static void modify_domain( REQ request)
|
||||
{
|
||||
/**************************************
|
||||
*
|
||||
* m o d i f y _ d o m a i n
|
||||
* m o d i f y _ d o m a i n
|
||||
*
|
||||
**************************************
|
||||
*
|
||||
@ -4565,7 +4567,7 @@ static void modify_relation( REQ request)
|
||||
*
|
||||
* Function
|
||||
* Alter an SQL table, relying on DYN to generate
|
||||
* global fields for the local fields.
|
||||
* global fields for the local fields.
|
||||
*
|
||||
**************************************/
|
||||
NOD ddl_node, ops, element, *ptr, *end, relation_node, field_node;
|
||||
@ -4660,7 +4662,7 @@ static void modify_relation( REQ request)
|
||||
/* Fix for bug 8054:
|
||||
|
||||
[CASCADE | RESTRICT] syntax is available in IB4.5, but not
|
||||
required until v5.0.
|
||||
required until v5.0.
|
||||
|
||||
Option CASCADE causes an error :
|
||||
unsupported DSQL construct
|
||||
@ -4774,7 +4776,7 @@ static void put_dtype( REQ request, FLD field, USHORT use_subtype)
|
||||
{
|
||||
/**************************************
|
||||
*
|
||||
* p u t _ d t y p e
|
||||
* p u t _ d t y p e
|
||||
*
|
||||
**************************************
|
||||
*
|
||||
@ -4833,7 +4835,7 @@ static void put_field( REQ request, FLD field, BOOLEAN udf_flag)
|
||||
{
|
||||
/**************************************
|
||||
*
|
||||
* p u t _ f i e l d
|
||||
* p u t _ f i e l d
|
||||
*
|
||||
**************************************
|
||||
*
|
||||
@ -5163,7 +5165,7 @@ static void reset_context_stack( REQ request)
|
||||
**************************************
|
||||
*
|
||||
* Function
|
||||
* Get rid of any predefined contexts created
|
||||
* Get rid of any predefined contexts created
|
||||
* for a view or trigger definition.
|
||||
*
|
||||
**************************************/
|
||||
@ -5185,7 +5187,7 @@ static void save_field( REQ request, TEXT * field_name)
|
||||
* Function
|
||||
* Save the name of a field in the relation or view currently
|
||||
* being defined. This is done to support definition
|
||||
* of triggers which will depend on the metadata created
|
||||
* of triggers which will depend on the metadata created
|
||||
* in this request.
|
||||
*
|
||||
**************************************/
|
||||
@ -5216,7 +5218,7 @@ static void save_relation( REQ request, STR relation_name)
|
||||
* Function
|
||||
* Save the name of the relation or view currently
|
||||
* being defined. This is done to support definition
|
||||
* of triggers which will depend on the metadata created
|
||||
* of triggers which will depend on the metadata created
|
||||
* in this request.
|
||||
*
|
||||
**************************************/
|
||||
@ -5317,7 +5319,7 @@ static void stuff_matching_blr(
|
||||
* Function
|
||||
* Generate blr to express: foreign_key == primary_key
|
||||
* ie., for_key.column_1 = prim_key.column_1 and
|
||||
* for_key.column_2 = prim_key.column_2 and .... so on..
|
||||
* for_key.column_2 = prim_key.column_2 and .... so on..
|
||||
*
|
||||
**************************************/
|
||||
NOD *for_key_flds, *prim_key_flds;
|
||||
@ -5523,4 +5525,4 @@ static void set_nod_value_attributes( NOD node, FLD field)
|
||||
}
|
||||
|
||||
|
||||
} // extern "C"
|
||||
} // extern "C"
|
@ -19,9 +19,12 @@
|
||||
*
|
||||
* All Rights Reserved.
|
||||
* Contributor(s): ______________________________________.
|
||||
* 2001.07.06 Sean Leyne - Code Cleanup, removed "#ifdef READONLY_DATABASE"
|
||||
* conditionals, as the engine now fully supports
|
||||
* readonly databases.
|
||||
*/
|
||||
/*
|
||||
$Id: dsql.cpp,v 1.2 2001-05-24 14:54:25 tamlin Exp $
|
||||
$Id: dsql.cpp,v 1.3 2001-07-10 17:35:13 awharrison Exp $
|
||||
*/
|
||||
/**************************************************************
|
||||
V4 Multi-threading changes.
|
||||
@ -37,7 +40,7 @@ V4 Multi-threading changes.
|
||||
the following protocol will be used. Care should be taken if
|
||||
nested FOR loops are added.
|
||||
|
||||
THREAD_EXIT; // last statment before FOR loop
|
||||
THREAD_EXIT; // last statment before FOR loop
|
||||
|
||||
FOR ...............
|
||||
|
||||
@ -48,7 +51,7 @@ nested FOR loops are added.
|
||||
|
||||
END_FOR;
|
||||
|
||||
THREAD_ENTER; // First statment after FOR loop
|
||||
THREAD_ENTER; // First statment after FOR loop
|
||||
***************************************************************/
|
||||
|
||||
#define DSQL_MAIN
|
||||
@ -157,7 +160,7 @@ static CONST SCHAR db_hdr_info_items[] = {
|
||||
isc_info_db_sql_dialect,
|
||||
gds_info_ods_version,
|
||||
gds_info_base_level,
|
||||
#ifdef READONLY_DATABASE
|
||||
#ifde_DATABASE
|
||||
isc_info_db_read_only,
|
||||
#endif /* READONLY_DATABASE */
|
||||
frb_info_att_charset,
|
||||
@ -325,7 +328,7 @@ STATUS DLL_EXPORT GDS_DSQL_EXECUTE(STATUS * user_status,
|
||||
|
||||
/* If the output message length is zero on a REQ_SELECT then we must
|
||||
* be doing an OPEN cursor operation.
|
||||
* If we do have an output message length, then we're doing
|
||||
* If we do have an output message length, then we're doing
|
||||
* a singleton SELECT. In that event, we don't add the cursor
|
||||
* to the list of open cursors (it's not really open).
|
||||
*/
|
||||
@ -380,7 +383,7 @@ STATUS DLL_EXPORT GDS_DSQL_EXECUTE_IMMED(STATUS * user_status,
|
||||
{
|
||||
/**************************************
|
||||
*
|
||||
* d s q l _ e x e c u t e _ i m m e d i a t e
|
||||
* d s q l _ e x e c u t e _ i m m e d i a t e
|
||||
*
|
||||
**************************************
|
||||
*
|
||||
@ -439,7 +442,7 @@ STATUS DLL_EXPORT GDS_DSQL_EXECUTE_IMMED(STATUS * user_status,
|
||||
* parser = (combined) %10 == 1
|
||||
* dialect = (combined) / 19 == 1
|
||||
*
|
||||
* If the parser version is not part of the dialect, then assume that the
|
||||
* If the parser version is not part of the dialect, then assume that the
|
||||
* connection being made is a local classic connection.
|
||||
*/
|
||||
|
||||
@ -522,9 +525,9 @@ STATUS DLL_EXPORT GDS_DSQL_FETCH(STATUS * user_status,
|
||||
|
||||
#ifdef SCROLLABLE_CURSORS
|
||||
|
||||
/* check whether we need to send an asynchronous scrolling message
|
||||
to the engine; the engine will automatically advance one record
|
||||
in the same direction as before, so optimize out messages of that
|
||||
/* check whether we need to send an asynchronous scrolling message
|
||||
to the engine; the engine will automatically advance one record
|
||||
in the same direction as before, so optimize out messages of that
|
||||
type */
|
||||
|
||||
if (request->req_type == REQ_SELECT &&
|
||||
@ -885,7 +888,7 @@ STATUS DLL_EXPORT GDS_DSQL_PREPARE(STATUS * user_status,
|
||||
* parser = (combined) %10 == 1
|
||||
* dialect = (combined) / 19 == 1
|
||||
*
|
||||
* If the parser version is not part of the dialect, then assume that the
|
||||
* If the parser version is not part of the dialect, then assume that the
|
||||
* connection being made is a local classic connection.
|
||||
*/
|
||||
|
||||
@ -958,7 +961,7 @@ STATUS DLL_EXPORT GDS_DSQL_SET_CURSOR(STATUS * user_status,
|
||||
request = *req_handle;
|
||||
tdsql->tsql_default = request->req_pool;
|
||||
if (input_cursor[0] == '\"') {
|
||||
/** Quoted cursor names eh? Strip'em.
|
||||
/** Quoted cursor names eh? Strip'em.
|
||||
Note that "" will be replaced with ".
|
||||
**/
|
||||
int ij;
|
||||
@ -993,7 +996,7 @@ STATUS DLL_EXPORT GDS_DSQL_SET_CURSOR(STATUS * user_status,
|
||||
gds_arg_gds, gds_dsql_decl_err, 0);
|
||||
}
|
||||
|
||||
/* If there already is a cursor and its name isn't the same, ditto.
|
||||
/* If there already is a cursor and its name isn't the same, ditto.
|
||||
We already know there is no cursor by this name in the hash table */
|
||||
|
||||
if (!request->req_cursor)
|
||||
@ -1139,7 +1142,7 @@ STATUS DLL_EXPORT GDS_DSQL_SQL_INFO(STATUS * user_status,
|
||||
}
|
||||
}
|
||||
else if (item == gds_info_sql_get_plan) {
|
||||
/* be careful, get_plan_info() will reallocate the buffer to a
|
||||
/* be careful, get_plan_info() will reallocate the buffer to a
|
||||
larger size if it is not big enough */
|
||||
|
||||
buffer_ptr = buffer;
|
||||
@ -1751,7 +1754,7 @@ static void cleanup( void *arg)
|
||||
{
|
||||
/**************************************
|
||||
*
|
||||
* c l e a n u p
|
||||
* c l e a n u p
|
||||
*
|
||||
**************************************
|
||||
*
|
||||
@ -1779,7 +1782,7 @@ static void cleanup_database( SLONG ** db_handle, SLONG flag)
|
||||
**************************************
|
||||
*
|
||||
* Functional description
|
||||
* Clean up DSQL globals.
|
||||
* Clean up DSQL globals.
|
||||
*
|
||||
* N.B., the cleanup handlers (registered with gds__database_cleanup)
|
||||
* are called outside of the ISC thread mechanism...
|
||||
@ -1853,11 +1856,11 @@ static void cleanup_transaction( SLONG * tra_handle, SLONG arg)
|
||||
The close routine will have done that. */
|
||||
|
||||
THD_MUTEX_UNLOCK(&cursors_mutex);
|
||||
/*
|
||||
/*
|
||||
* we are expected to be within the subsystem when we do this
|
||||
* cleanup, for now do a thread_enter/thread_exit here.
|
||||
* cleanup, for now do a thread_enter/thread_exit here.
|
||||
* Note that the function GDS_DSQL_FREE() calls the local function.
|
||||
* Over the long run, it might be better to move the subsystem_exit()
|
||||
* Over the long run, it might be better to move the subsystem_exit()
|
||||
* call in why.c below the cleanup handlers. smistry 9-27-98
|
||||
*/
|
||||
THREAD_ENTER;
|
||||
@ -2437,7 +2440,7 @@ static BOOLEAN get_indices(
|
||||
**************************************
|
||||
*
|
||||
* Functional description
|
||||
* Retrieve the indices from the index tree in
|
||||
* Retrieve the indices from the index tree in
|
||||
* the request info buffer, and print them out
|
||||
* in the plan buffer.
|
||||
*
|
||||
@ -2728,7 +2731,7 @@ SCHAR ** plan_ptr, USHORT * parent_join_count, USHORT * level_ptr)
|
||||
|
||||
case gds_info_rsb_relation:
|
||||
|
||||
/* for the single relation case, initiate
|
||||
/* for the single relation case, initiate
|
||||
the relation with a parenthesis */
|
||||
|
||||
if (!*parent_join_count) {
|
||||
@ -2802,7 +2805,7 @@ SCHAR ** plan_ptr, USHORT * parent_join_count, USHORT * level_ptr)
|
||||
case gds_info_rsb_left_cross:
|
||||
case gds_info_rsb_merge:
|
||||
|
||||
/* if this join is itself part of a join list,
|
||||
/* if this join is itself part of a join list,
|
||||
but not the first item, then put out a comma */
|
||||
|
||||
if (*parent_join_count && plan[-1] != '(') {
|
||||
@ -2895,9 +2898,9 @@ SCHAR ** plan_ptr, USHORT * parent_join_count, USHORT * level_ptr)
|
||||
|
||||
case gds_info_rsb_sort:
|
||||
|
||||
/* if this sort is on behalf of a union, don't bother to
|
||||
print out the sort, because unions handle the sort on all
|
||||
substreams at once, and a plan maps to each substream
|
||||
/* if this sort is on behalf of a union, don't bother to
|
||||
print out the sort, because unions handle the sort on all
|
||||
substreams at once, and a plan maps to each substream
|
||||
in the union, so the sort doesn't really apply to a particular plan */
|
||||
|
||||
if (explain_length > 2 &&
|
||||
@ -2920,7 +2923,7 @@ SCHAR ** plan_ptr, USHORT * parent_join_count, USHORT * level_ptr)
|
||||
while (*p)
|
||||
*plan++ = *p++;
|
||||
|
||||
/* the rsb_sort should always be followed by a begin...end block,
|
||||
/* the rsb_sort should always be followed by a begin...end block,
|
||||
allowing us to include everything inside the sort in parentheses */
|
||||
|
||||
save_level = *level_ptr;
|
||||
@ -3061,19 +3064,19 @@ static DBB init( SLONG ** db_handle)
|
||||
database->dbb_flags &= ~DBB_v3;
|
||||
break;
|
||||
|
||||
/* This flag indicates the version level of the engine
|
||||
itself, so we can tell what capabilities the engine
|
||||
/* This flag indicates the version level of the engine
|
||||
itself, so we can tell what capabilities the engine
|
||||
code itself (as opposed to the on-disk structure).
|
||||
Apparently the base level up to now indicated the major
|
||||
version number, but for 4.1 the base level is being
|
||||
incremented, so the base level indicates an engine version
|
||||
Apparently the base level up to now indicated the major
|
||||
version number, but for 4.1 the base level is being
|
||||
incremented, so the base level indicates an engine version
|
||||
as follows:
|
||||
1 == v1.x
|
||||
2 == v2.x
|
||||
3 == v3.x
|
||||
4 == v4.0 only
|
||||
5 == v4.1
|
||||
Note: this info item is so old it apparently uses an
|
||||
Note: this info item is so old it apparently uses an
|
||||
archaic format, not a standard vax integer format.
|
||||
*/
|
||||
|
||||
@ -3081,14 +3084,12 @@ static DBB init( SLONG ** db_handle)
|
||||
database->dbb_base_level = (USHORT) data[1];
|
||||
break;
|
||||
|
||||
#ifdef READONLY_DATABASE
|
||||
case isc_info_db_read_only:
|
||||
if ((USHORT) data[0])
|
||||
database->dbb_flags |= DBB_read_only;
|
||||
else
|
||||
database->dbb_flags &= ~DBB_read_only;
|
||||
break;
|
||||
#endif /* READONLY_DATABASE */
|
||||
|
||||
case frb_info_att_charset:
|
||||
database->dbb_att_charset =
|
||||
@ -3473,7 +3474,7 @@ static REQ prepare(
|
||||
|
||||
#ifdef SCROLLABLE_CURSORS
|
||||
if (request->req_dbb->dbb_base_level >= 5) {
|
||||
/* allocate a message in which to send scrolling information
|
||||
/* allocate a message in which to send scrolling information
|
||||
outside of the normal send/receive protocol */
|
||||
|
||||
request->req_async = message = (MSG) ALLOCD(type_msg);
|
||||
@ -3484,7 +3485,7 @@ static REQ prepare(
|
||||
request->req_type = REQ_SELECT;
|
||||
request->req_flags &= ~(REQ_cursor_open | REQ_embedded_sql_cursor);
|
||||
|
||||
/*
|
||||
/*
|
||||
* No work is done during pass1 for set transaction - like
|
||||
* checking for valid table names. This is because that will
|
||||
* require a valid transaction handle.
|
||||
@ -3538,7 +3539,7 @@ static REQ prepare(
|
||||
request->req_blr_yellow =
|
||||
request->req_blr + request->req_blr_string->str_length;
|
||||
|
||||
/* Start transactions takes parameters via a parameter block.
|
||||
/* Start transactions takes parameters via a parameter block.
|
||||
The request blr string is used for that. */
|
||||
|
||||
if (request->req_type == REQ_START_TRANS) {
|
||||
@ -3958,4 +3959,4 @@ static SCHAR *var_info(
|
||||
}
|
||||
|
||||
|
||||
} // extern "C"
|
||||
} // extern "C"
|
@ -19,9 +19,12 @@
|
||||
*
|
||||
* All Rights Reserved.
|
||||
* Contributor(s): ______________________________________.
|
||||
* 2001.07.06 Sean Leyne - Code Cleanup, removed "#ifdef READONLY_DATABASE"
|
||||
* conditionals, as the engine now fully supports
|
||||
* readonly databases.
|
||||
*/
|
||||
/*
|
||||
$Id: blb.cpp,v 1.1.1.1 2001-05-23 13:26:22 tamlin Exp $
|
||||
$Id: blb.cpp,v 1.2 2001-07-10 17:35:13 awharrison Exp $
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
@ -118,7 +121,7 @@ void BLB_close(TDBB tdbb, BLB blob)
|
||||
**************************************
|
||||
*
|
||||
* Functional description
|
||||
* Close a blob. If the blob is open for retrieval, release the
|
||||
* Close a blob. If the blob is open for retrieval, release the
|
||||
* blob block. If it's a temporary blob, flush out the last page
|
||||
* (if necessary) in preparation for materialization.
|
||||
*
|
||||
@ -188,10 +191,8 @@ BLB BLB_create2(TDBB tdbb,
|
||||
dbb = tdbb->tdbb_database;
|
||||
CHECK_DBB(dbb);
|
||||
|
||||
#ifdef READONLY_DATABASE
|
||||
if (dbb->dbb_flags & DBB_read_only)
|
||||
ERR_post(isc_read_only_database, 0);
|
||||
#endif /* READONLY_DATABASE */
|
||||
|
||||
/* Create a blob large enough to hold a single data page */
|
||||
|
||||
@ -350,7 +351,7 @@ BLB BLB_get_array(TDBB tdbb, TRA transaction, BID blob_id, ADS desc)
|
||||
{
|
||||
/**************************************
|
||||
*
|
||||
* B L B _ g e t _ a r r a y
|
||||
* B L B _ g e t _ a r r a y
|
||||
*
|
||||
**************************************
|
||||
*
|
||||
@ -403,7 +404,7 @@ SLONG BLB_get_data(TDBB tdbb, BLB blob, UCHAR* buffer, SLONG length)
|
||||
|
||||
while (length > 0) {
|
||||
/* I have no idea why this limit is 32768 instead of 32767
|
||||
* 1994-August-12 David Schnepper
|
||||
* 1994-August-12 David Schnepper
|
||||
*/
|
||||
n = (USHORT) MIN(length, (SLONG) 32768);
|
||||
n = BLB_get_segment(tdbb, blob, p, n);
|
||||
@ -782,10 +783,10 @@ void DLL_EXPORT BLB_map_blobs(TDBB tdbb, BLB old_blob, BLB new_blob)
|
||||
*
|
||||
* Functional description
|
||||
* Form a mapping between two blobs.
|
||||
* Since the blobs have been newly created
|
||||
* Since the blobs have been newly created
|
||||
* in this session, only the second part of
|
||||
* the blob id is significant. At the moment
|
||||
* this is intended solely for REPLAY, when
|
||||
* the blob id is significant. At the moment
|
||||
* this is intended solely for REPLAY, when
|
||||
* replaying a log.
|
||||
*
|
||||
**************************************/
|
||||
@ -890,7 +891,7 @@ void BLB_move(TDBB tdbb, DSC * from_desc, DSC * to_desc, NOD field)
|
||||
get_replay_blob(tdbb, source);
|
||||
#endif
|
||||
|
||||
/* If the source is a permanent blob, then the blob must be copied.
|
||||
/* If the source is a permanent blob, then the blob must be copied.
|
||||
Otherwise find the temporary blob referenced. */
|
||||
|
||||
array = 0;
|
||||
@ -1098,7 +1099,7 @@ BLB BLB_open2(TDBB tdbb,
|
||||
}
|
||||
|
||||
/* Ordinarily, we would call MET_relation to get the relation id.
|
||||
However, since the blob id must be consider suspect, this is
|
||||
However, since the blob id must be consider suspect, this is
|
||||
not a good idea. On the other hand, if we don't already
|
||||
know about the relation, the blob id has got to be invalid
|
||||
anyway. */
|
||||
@ -1824,10 +1825,8 @@ static void delete_blob(TDBB tdbb, BLB blob, ULONG prior_page)
|
||||
dbb = tdbb->tdbb_database;
|
||||
CHECK_DBB(dbb);
|
||||
|
||||
#ifdef READONLY_DATABASE
|
||||
if (dbb->dbb_flags & DBB_read_only)
|
||||
ERR_post(isc_read_only_database, 0);
|
||||
#endif /* READONLY_DATABASE */
|
||||
|
||||
/* Level 0 blobs don't need cleanup */
|
||||
|
||||
@ -2311,7 +2310,7 @@ static void slice_callback(SLICE arg, ULONG count, DSC * descriptors)
|
||||
USHORT tmp_len;
|
||||
TDBB tdbb;
|
||||
|
||||
/* Note: cannot remove this GET_THREAD_DATA without api change
|
||||
/* Note: cannot remove this GET_THREAD_DATA without api change
|
||||
to slice callback routines */
|
||||
tdbb = GET_THREAD_DATA;
|
||||
|
||||
@ -2338,7 +2337,7 @@ static void slice_callback(SLICE arg, ULONG count, DSC * descriptors)
|
||||
/* FROM array_desc TO slice_desc */
|
||||
|
||||
/* If the element is under the high-water mark, fetch it,
|
||||
* otherwise just zero it
|
||||
* otherwise just zero it
|
||||
*/
|
||||
if ((BLOB_PTR *) array_desc->dsc_address <
|
||||
(BLOB_PTR *) arg->slice_high_water) {
|
||||
@ -2422,4 +2421,4 @@ static BLB store_array(TDBB tdbb, TRA transaction, BID blob_id)
|
||||
}
|
||||
|
||||
|
||||
} // extern "C"
|
||||
} // extern "C"
|
117
src/jrd/cch.cpp
117
src/jrd/cch.cpp
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* PROGRAM: JRD Access Method
|
||||
* MODULE: cch.c
|
||||
* DESCRIPTION: Disk cache manager
|
||||
* DESCRIPTION: Disk cache manager
|
||||
*
|
||||
* The contents of this file are subject to the Interbase Public
|
||||
* License Version 1.0 (the "License"); you may not use this file
|
||||
@ -19,6 +19,9 @@
|
||||
*
|
||||
* All Rights Reserved.
|
||||
* Contributor(s): ______________________________________.
|
||||
* 2001.07.06 Sean Leyne - Code Cleanup, removed "#ifdef READONLY_DATABASE"
|
||||
* conditionals, as the engine now fully supports
|
||||
* readonly databases.
|
||||
*/
|
||||
#include "../jrd/ibsetjmp.h"
|
||||
#include "../jrd/ib_stdio.h"
|
||||
@ -118,8 +121,8 @@ static void unmark(TDBB, WIN *);
|
||||
#endif
|
||||
|
||||
/* In the superserver mode, no page locks are acquired through the lock manager.
|
||||
Instead, a latching mechanism is used. So the calls to lock subsystem for
|
||||
database pages in the original code should not be made, lest they should cause
|
||||
Instead, a latching mechanism is used. So the calls to lock subsystem for
|
||||
database pages in the original code should not be made, lest they should cause
|
||||
any undesirable side-effects. The following defines help us achieve that. */
|
||||
|
||||
#ifdef SUPERSERVER
|
||||
@ -409,7 +412,7 @@ BOOLEAN CCH_exclusive(TDBB tdbb, USHORT level, SSHORT wait_flag)
|
||||
*
|
||||
* Functional description
|
||||
* Get exclusive access to a database. If we get it, return TRUE.
|
||||
* If the wait flag is FALSE, and we can't get it, give up and
|
||||
* If the wait flag is FALSE, and we can't get it, give up and
|
||||
* return FALSE. There are two levels of database exclusivity: LCK_PW
|
||||
* guarantees there are no normal users in the database while LCK_EX
|
||||
* additionally guarantes background database processes like the
|
||||
@ -470,7 +473,7 @@ BOOLEAN CCH_exclusive_attachment(TDBB tdbb, USHORT level, SSHORT wait_flag)
|
||||
*
|
||||
* Functional description
|
||||
* Get exclusive access to a database. If we get it, return TRUE.
|
||||
* If the wait flag is FALSE, and we can't get it, give up and
|
||||
* If the wait flag is FALSE, and we can't get it, give up and
|
||||
* return FALSE.
|
||||
*
|
||||
**************************************/
|
||||
@ -822,7 +825,7 @@ SSHORT CCH_fetch_lock(TDBB tdbb,
|
||||
if (lock_type >= LCK_write)
|
||||
bdb->bdb_flags |= BDB_writer;
|
||||
|
||||
/* the expanded index buffer is only good when the page is
|
||||
/* the expanded index buffer is only good when the page is
|
||||
fetched for read; if it is ever fetched for write, it must
|
||||
be discarded */
|
||||
|
||||
@ -883,22 +886,22 @@ void CCH_fetch_page(
|
||||
file = dbb->dbb_file;
|
||||
retryCount = 0;
|
||||
|
||||
/* We will read a page, and if there is an I/O error we will try to
|
||||
/* We will read a page, and if there is an I/O error we will try to
|
||||
use the shadow file, and try reading again, for a maximum of
|
||||
3 tries, before it gives up.
|
||||
|
||||
The read_shadow flag is set to false only in the call to
|
||||
FETCH_NO_SHADOW, which is only called from validate
|
||||
code.
|
||||
|
||||
code.
|
||||
|
||||
read_shadow = FALSE -> IF an I/O error occurs give up (exit
|
||||
the loop, clean up, and return). So the caller,
|
||||
validate in most cases, can know about it and attempt
|
||||
to remedy the situation.
|
||||
|
||||
validate in most cases, can know about it and attempt
|
||||
to remedy the situation.
|
||||
|
||||
read_shadow = TRUE -> IF an I/O error occurs attempt
|
||||
to rollover to the shadow file. If the I/O error is
|
||||
persistant (more than 3 times) error out of the routine by
|
||||
persistant (more than 3 times) error out of the routine by
|
||||
calling CCH_unwind, and eventually punting out. */
|
||||
|
||||
while (!PIO_read(file, bdb, page, status)) {
|
||||
@ -1099,7 +1102,7 @@ void CCH_flush(TDBB tdbb, USHORT flush_flag, SLONG tra_number)
|
||||
**************************************
|
||||
*
|
||||
* Functional description
|
||||
* Flush all buffers. If the release flag is set,
|
||||
* Flush all buffers. If the release flag is set,
|
||||
* release all locks.
|
||||
*
|
||||
**************************************/
|
||||
@ -1186,7 +1189,7 @@ void CCH_flush(TDBB tdbb, USHORT flush_flag, SLONG tra_number)
|
||||
/* PIO_flush (dbb->dbb_shadow->sdw_file); */
|
||||
|
||||
/* take the opportunity when we know there are no pages
|
||||
in cache to check that the shadow(s) have not been
|
||||
in cache to check that the shadow(s) have not been
|
||||
scheduled for shutdown or deletion */
|
||||
|
||||
SDW_check();
|
||||
@ -1216,10 +1219,8 @@ BOOLEAN CCH_free_page(TDBB tdbb)
|
||||
dbb = tdbb->tdbb_database;
|
||||
bcb = dbb->dbb_bcb;
|
||||
|
||||
#ifdef READONLY_DATABASE
|
||||
if (dbb->dbb_flags & DBB_read_only)
|
||||
return FALSE;
|
||||
#endif
|
||||
|
||||
if (bcb->bcb_flags & BCB_free_pending &&
|
||||
(bdb = get_buffer(tdbb, FREE_PAGE, LATCH_none, 1))) {
|
||||
@ -1451,9 +1452,7 @@ void CCH_init(TDBB tdbb, ULONG number)
|
||||
#endif
|
||||
|
||||
#ifdef CACHE_WRITER
|
||||
#ifdef READONLY_DATABASE
|
||||
if (!(dbb->dbb_flags & DBB_read_only))
|
||||
#endif
|
||||
{
|
||||
event = dbb->dbb_writer_event;
|
||||
ISC_event_init(event, 0, 0);
|
||||
@ -1574,7 +1573,7 @@ void CCH_journal_record(TDBB tdbb,
|
||||
if (latch_bdb(tdbb, LATCH_mark, journal, journal->bdb_page, 1) == -1)
|
||||
cache_bugcheck(302); /* msg 302 unexpected page change */
|
||||
|
||||
/* Now we can safely release this bdb to clear its bdb_io, bdb_exclusive and
|
||||
/* Now we can safely release this bdb to clear its bdb_io, bdb_exclusive and
|
||||
bdb_use_count fields. */
|
||||
release_bdb(tdbb, journal, FALSE, FALSE, FALSE);
|
||||
|
||||
@ -1891,7 +1890,7 @@ BOOLEAN CCH_prefetch_pages(TDBB tdbb)
|
||||
*
|
||||
* Functional description
|
||||
* Check the prefetch bitmap for a set
|
||||
* of pages and read them into the cache.
|
||||
* of pages and read them into the cache.
|
||||
*
|
||||
**************************************/
|
||||
|
||||
@ -1912,7 +1911,7 @@ void CCH_recover_shadow(TDBB tdbb, SBM sbm_rec)
|
||||
**************************************
|
||||
*
|
||||
* Functional description
|
||||
* Walk through the sparse bit map created during recovery and
|
||||
* Walk through the sparse bit map created during recovery and
|
||||
* write all changed pages to all the shadows.
|
||||
*
|
||||
**************************************/
|
||||
@ -1957,7 +1956,7 @@ void CCH_recover_shadow(TDBB tdbb, SBM sbm_rec)
|
||||
|
||||
if (result == FALSE)
|
||||
ERR_punt();
|
||||
/*
|
||||
/*
|
||||
* do 2 control points after a recovery to flush all the pages to the
|
||||
* database and shadow. Note that this has to be doen after the shadows
|
||||
* are updated.
|
||||
@ -2026,7 +2025,7 @@ void CCH_release(TDBB tdbb, WIN * window, BOOLEAN release_tail)
|
||||
bdb = window->win_bdb;
|
||||
BLKCHK(bdb, type_bdb);
|
||||
|
||||
/* if an expanded buffer has been created, retain it
|
||||
/* if an expanded buffer has been created, retain it
|
||||
for possible future use */
|
||||
|
||||
bdb->bdb_expanded_buffer = window->win_expanded_buffer;
|
||||
@ -2234,7 +2233,7 @@ BOOLEAN CCH_rollover_to_shadow(DBB dbb, FIL file, BOOLEAN inAst)
|
||||
**************************************
|
||||
*
|
||||
* Functional description
|
||||
* An I/O error has been detected on the
|
||||
* An I/O error has been detected on the
|
||||
* main database file. Roll over to use
|
||||
* the shadow file.
|
||||
*
|
||||
@ -2469,12 +2468,12 @@ BOOLEAN CCH_write_all_shadows(TDBB tdbb,
|
||||
|
||||
/* Fix for bug 7925. drop_gdb fails to remove secondary file if
|
||||
the shadow is conditional. Reason being the header page not
|
||||
being correctly initialized.
|
||||
being correctly initialized.
|
||||
|
||||
The following block was not being performed for a conditional
|
||||
shadow since SDW_INVALID expanded to include conditional shadow
|
||||
|
||||
-Sudesh 07/10/95
|
||||
-Sudesh 07/10/95
|
||||
old code --> if (sdw->sdw_flags & SDW_INVALID)
|
||||
*/
|
||||
|
||||
@ -2514,8 +2513,8 @@ BOOLEAN CCH_write_all_shadows(TDBB tdbb,
|
||||
if ((sdw->sdw_flags & SDW_conditional) &&
|
||||
(bdb->bdb_page != HEADER_PAGE)) continue;
|
||||
|
||||
/* if a write failure happens on an AUTO shadow, mark the
|
||||
shadow to be deleted at the next available opportunity when we
|
||||
/* if a write failure happens on an AUTO shadow, mark the
|
||||
shadow to be deleted at the next available opportunity when we
|
||||
know we don't have a page fetched */
|
||||
|
||||
if (!PIO_write(sdw->sdw_file, bdb, page, status))
|
||||
@ -2675,9 +2674,9 @@ static void btc_flush(
|
||||
*
|
||||
* Functional description
|
||||
* Walk the dirty page binary tree, flushing all buffers
|
||||
* that could have been modified by this transaction.
|
||||
* The pages are flushed in page order to roughly
|
||||
* emulate an elevator-type disk controller. Iteration
|
||||
* that could have been modified by this transaction.
|
||||
* The pages are flushed in page order to roughly
|
||||
* emulate an elevator-type disk controller. Iteration
|
||||
* is used to minimize call overhead.
|
||||
*
|
||||
**************************************/
|
||||
@ -2792,7 +2791,7 @@ static void btc_insert(DBB dbb, BDB bdb)
|
||||
**************************************
|
||||
*
|
||||
* Functional description
|
||||
* Insert a buffer into the dirty page
|
||||
* Insert a buffer into the dirty page
|
||||
* binary tree.
|
||||
*
|
||||
**************************************/
|
||||
@ -2801,7 +2800,7 @@ static void btc_insert(DBB dbb, BDB bdb)
|
||||
|
||||
/* if the page is already in the tree (as in when it is
|
||||
written out as a dependency while walking the tree),
|
||||
just leave well enough alone -- this won't check if
|
||||
just leave well enough alone -- this won't check if
|
||||
it's at the root but who cares then */
|
||||
|
||||
if (bdb->bdb_parent)
|
||||
@ -2861,10 +2860,10 @@ static void btc_remove(BDB bdb)
|
||||
*
|
||||
* Functional description
|
||||
* Remove a page from the dirty page binary tree.
|
||||
* The idea is to place the left child of this
|
||||
* page in this page's place, then make the
|
||||
* right child of this page a child of the left
|
||||
* child -- this removal mechanism won't promote
|
||||
* The idea is to place the left child of this
|
||||
* page in this page's place, then make the
|
||||
* right child of this page a child of the left
|
||||
* child -- this removal mechanism won't promote
|
||||
* a balanced tree but that isn't of primary
|
||||
* importance.
|
||||
*
|
||||
@ -2902,7 +2901,7 @@ static void btc_remove(BDB bdb)
|
||||
else
|
||||
new_child = bdb->bdb_right;
|
||||
|
||||
/* link the parent with the child node --
|
||||
/* link the parent with the child node --
|
||||
if no parent place it at the root */
|
||||
|
||||
if (!(bdb_parent = bdb->bdb_parent))
|
||||
@ -3788,7 +3787,7 @@ static BDB get_buffer(TDBB tdbb, SLONG page, LATCH latch, SSHORT latch_wait)
|
||||
* bdb pointer if successful.
|
||||
* NULL pointer if timeout occurred (only possible is latch_wait <> 1).
|
||||
* if cache manager doesn't have any pages to write anymore.
|
||||
*
|
||||
*
|
||||
**************************************/
|
||||
DBB dbb;
|
||||
QUE mod_que;
|
||||
@ -3896,7 +3895,7 @@ static BDB get_buffer(TDBB tdbb, SLONG page, LATCH latch, SSHORT latch_wait)
|
||||
QUE_INSERT(bcb->bcb_in_use, bdb->bdb_in_use);
|
||||
}
|
||||
|
||||
/* This correction for bdb_use_count below is needed to
|
||||
/* This correction for bdb_use_count below is needed to
|
||||
avoid a deadlock situation in latching code. It's not
|
||||
clear though how the bdb_use_count can get < 0 for a bdb
|
||||
in bcb_empty queue */
|
||||
@ -4190,11 +4189,11 @@ static SSHORT latch_bdb(
|
||||
ahead of all other latch requests (to avoid deadlocks and
|
||||
this does not cause starvation). Also, shared latches are granted
|
||||
immediately if a disk write is in progress.
|
||||
Note that asking for a higher mode latch when already holding a
|
||||
Note that asking for a higher mode latch when already holding a
|
||||
share latch results in deadlock. CCH_handoff routinely acquires a
|
||||
shared latch while owning already a shared latch on the page
|
||||
(the case of handing off to the same page). If the BDB_must_write
|
||||
flag is set, then an exclusive latch request will be followed by
|
||||
flag is set, then an exclusive latch request will be followed by
|
||||
an io latch request. */
|
||||
|
||||
switch (type) {
|
||||
@ -4250,7 +4249,7 @@ static SSHORT latch_bdb(
|
||||
case LATCH_exclusive:
|
||||
/* Exclusive latches wait for existing shared latches and
|
||||
(unfortunately) for existing io latches. This is not as
|
||||
bad as it sounds because an exclusive latch is typically followed
|
||||
bad as it sounds because an exclusive latch is typically followed
|
||||
by a mark latch, which then would wait behind the io latch. */
|
||||
/* Note that the ail-code latches the same buffer multiple times
|
||||
in shared and exclusive */
|
||||
@ -4372,7 +4371,7 @@ static SSHORT latch_bdb(
|
||||
* Functional description
|
||||
* Simple optimized latching for single-threaded
|
||||
* non-SUPERSERVER platforms.
|
||||
*
|
||||
*
|
||||
**************************************/
|
||||
|
||||
++bdb->bdb_use_count;
|
||||
@ -4417,7 +4416,7 @@ static SSHORT lock_buffer(
|
||||
* LCK_NO_WAIT = FALSE = 0 => If the lock can't be acquired immediately,
|
||||
* give up and return -1.
|
||||
* <negative number> => Lock timeout interval in seconds.
|
||||
*
|
||||
*
|
||||
* return: 0 => buffer locked, page is already in memroy.
|
||||
* 1 => buffer locked, page needs to be read from disk.
|
||||
* -1 => timeout on lock occurred, see input parameter 'wait'.
|
||||
@ -4440,8 +4439,8 @@ static SSHORT lock_buffer(
|
||||
|
||||
if (dbb->dbb_refresh_ranges && bdb->bdb_flags & BDB_writer &&
|
||||
(page_type == pag_data || page_type == pag_index)) {
|
||||
/* This gives refresh cache ranges the potential to work with page
|
||||
* latching by taking out a temporary page lock for notification
|
||||
/* This gives refresh cache ranges the potential to work with page
|
||||
* latching by taking out a temporary page lock for notification
|
||||
* purposes.
|
||||
* Fix cache ranges on NetWare due to latching (bug 7199)
|
||||
* Marion change # 18270, 13-Oct-1994
|
||||
@ -4512,7 +4511,7 @@ static SSHORT lock_buffer(
|
||||
lock->lck_object = (BLK) bdb;
|
||||
}
|
||||
|
||||
/* Case: a timeout was specified, or the caller didn't want to wait,
|
||||
/* Case: a timeout was specified, or the caller didn't want to wait,
|
||||
return the error. */
|
||||
|
||||
if ((wait == LCK_NO_WAIT)
|
||||
@ -4521,7 +4520,7 @@ static SSHORT lock_buffer(
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Case: lock manager detected a deadlock, probably caused by locking the
|
||||
/* Case: lock manager detected a deadlock, probably caused by locking the
|
||||
bdb's in an unfortunate order. Nothing we can do about it, return the
|
||||
error, and log it to interbase.log. */
|
||||
|
||||
@ -4557,7 +4556,7 @@ static SSHORT lock_buffer(
|
||||
if (PAGE_LOCK(lock, lock_type, wait))
|
||||
return 1;
|
||||
|
||||
/* Case: a timeout was specified, or the caller didn't want to wait,
|
||||
/* Case: a timeout was specified, or the caller didn't want to wait,
|
||||
return the error. */
|
||||
|
||||
if ((wait < 0) && (status[1] == gds__lock_timeout)) {
|
||||
@ -4565,7 +4564,7 @@ static SSHORT lock_buffer(
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Case: lock manager detected a deadlock, probably caused by locking the
|
||||
/* Case: lock manager detected a deadlock, probably caused by locking the
|
||||
bdb's in an unfortunate order. Nothing we can do about it, return the
|
||||
error, and log it to interbase.log. */
|
||||
|
||||
@ -4719,7 +4718,7 @@ static void prefetch_epilogue(PRF prefetch, STATUS * status_vector)
|
||||
*
|
||||
* Functional description
|
||||
* Stall on asynchronous I/O completion.
|
||||
* Move data from prefetch buffer to database
|
||||
* Move data from prefetch buffer to database
|
||||
* buffers, compute the checksum, and release
|
||||
* the latch.
|
||||
*
|
||||
@ -5247,21 +5246,21 @@ static int write_buffer(
|
||||
* Write a dirty buffer. This may recurse due to
|
||||
* precedence problems.
|
||||
*
|
||||
* input: write_this_page
|
||||
* input: write_this_page
|
||||
* = true if the input page needs to be written
|
||||
* before returning. (normal case)
|
||||
* = false if the input page is being written
|
||||
* = false if the input page is being written
|
||||
* because of precedence. Only write
|
||||
* one page and return so that the caller
|
||||
* can re-establish the need to write this
|
||||
* page.
|
||||
*
|
||||
*
|
||||
* return: 0 = Write failed.
|
||||
* 1 = Page is written. Page was written by this
|
||||
* call, or was written by someone else, or the
|
||||
* cache buffer is already reassigned.
|
||||
* 2 = Only possible if write_this_page is FALSE.
|
||||
* This input page is not written. One
|
||||
* This input page is not written. One
|
||||
* page higher in precedence is written
|
||||
* though. Probable action: re-establich the
|
||||
* need to write this page and retry write.
|
||||
@ -5441,7 +5440,7 @@ static BOOLEAN write_page(
|
||||
page->pag_offset = bdb->bdb_page;
|
||||
#endif
|
||||
|
||||
/* write out page to main database file, and to any
|
||||
/* write out page to main database file, and to any
|
||||
shadows, making a special case of the header page */
|
||||
|
||||
if (bdb->bdb_page >= 0) {
|
||||
@ -5549,4 +5548,4 @@ static void unmark(TDBB tdbb, WIN * window)
|
||||
}
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
} // extern "C"
|
@ -20,10 +20,14 @@
|
||||
* All Rights Reserved.
|
||||
* Contributor(s): ______________________________________.
|
||||
* Added TCP_NO_DELAY option for superserver on Linux
|
||||
* FSG 16.03.2001
|
||||
* FSG 16.03.2001
|
||||
*
|
||||
* 2001.07.06 Sean Leyne - Code Cleanup, removed "#ifdef READONLY_DATABASE"
|
||||
* conditionals, as the engine now fully supports
|
||||
* readonly databases.
|
||||
*/
|
||||
/*
|
||||
$Id: common.h,v 1.1.1.1 2001-05-23 13:26:08 tamlin Exp $
|
||||
$Id: common.h,v 1.2 2001-07-10 17:35:13 awharrison Exp $
|
||||
*/
|
||||
|
||||
#ifndef JRD_COMMON_H
|
||||
@ -33,7 +37,7 @@ $Id: common.h,v 1.1.1.1 2001-05-23 13:26:08 tamlin Exp $
|
||||
#include "../include/fb_macros.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
/*
|
||||
do not use links in source code to maintain platform neutraility
|
||||
*/
|
||||
|
||||
@ -163,7 +167,7 @@ $Id: common.h,v 1.1.1.1 2001-05-23 13:26:08 tamlin Exp $
|
||||
|
||||
/* Defined KILLER_SIGNALS for Sun - as we were getting lots of lockups
|
||||
* using pipe server.
|
||||
* 1995-February-24 David Schnepper
|
||||
* 1995-February-24 David Schnepper
|
||||
*/
|
||||
#define KILLER_SIGNALS
|
||||
|
||||
@ -218,7 +222,7 @@ $Id: common.h,v 1.1.1.1 2001-05-23 13:26:08 tamlin Exp $
|
||||
|
||||
For maximum portability, memmove should be used when the memory areas
|
||||
indicated by s1 and s2 may overlap, and memcpy used for faster copying
|
||||
between non-overlapping areas.
|
||||
between non-overlapping areas.
|
||||
|
||||
**********/
|
||||
|
||||
@ -407,7 +411,7 @@ $Id: common.h,v 1.1.1.1 2001-05-23 13:26:08 tamlin Exp $
|
||||
|
||||
|
||||
|
||||
/* DOS does not compare the high order word of far pointers,
|
||||
/* DOS does not compare the high order word of far pointers,
|
||||
so we must cast them to huge in comparions; also, for routines
|
||||
which return a double, they must be given a pascal type so that
|
||||
they will work in a multithreaded environment */
|
||||
@ -817,8 +821,8 @@ typedef unsigned long DWORD;
|
||||
#define INTL_BACKEND
|
||||
#define SYNC_WRITE_DEFAULT 1
|
||||
|
||||
/* turn on stack reduction methods for only those routines
|
||||
which are not commonly used; since this is a server, we
|
||||
/* turn on stack reduction methods for only those routines
|
||||
which are not commonly used; since this is a server, we
|
||||
want to allocate buffers on the stack for oft-used routines */
|
||||
|
||||
#define STACK_REDUCTION
|
||||
@ -1139,11 +1143,6 @@ typedef struct {
|
||||
} SQUAD;
|
||||
#endif
|
||||
|
||||
/* Enable support for READONLY databases in InterBase, IB 6.0 (Kinobi) project */
|
||||
#ifndef READONLY_DATABASE
|
||||
#define READONLY_DATABASE
|
||||
#endif
|
||||
|
||||
#ifndef ATOM_DEFINED /* 32 or 64 bit */
|
||||
typedef long SATOM;
|
||||
typedef unsigned long UATOM;
|
||||
@ -1337,7 +1336,7 @@ typedef USHORT FLD_LENGTH;
|
||||
|
||||
#ifdef DEV_BUILD
|
||||
|
||||
/* Define any debugging symbols and macros here. This
|
||||
/* Define any debugging symbols and macros here. This
|
||||
ifdef will be executed during development builds. */
|
||||
|
||||
#ifdef NETWARE_386
|
||||
@ -1437,4 +1436,4 @@ typedef struct in_sw_tab_t {
|
||||
|
||||
} *IN_SW_TAB;
|
||||
|
||||
#endif /* JRD_COMMON_H */
|
||||
#endif /* JRD_COMMON_H */
|
@ -29,6 +29,11 @@
|
||||
* Change: Corrected routine to use new variables from PAG_init.
|
||||
*/
|
||||
|
||||
/* 2001.07.06 Sean Leyne - Code Cleanup, removed "#ifdef READONLY_DATABASE"
|
||||
* conditionals, as the engine now fully supports
|
||||
* readonly databases.
|
||||
*/
|
||||
|
||||
#include "../jrd/ib_stdio.h"
|
||||
#include "../jrd/ibsetjmp.h"
|
||||
#include <string.h>
|
||||
@ -201,7 +206,7 @@ int DPM_chain( TDBB tdbb, RPB * org_rpb, RPB * new_rpb)
|
||||
**************************************
|
||||
*
|
||||
* Functional description
|
||||
* Start here with a plausible, but non-active RPB.
|
||||
* Start here with a plausible, but non-active RPB.
|
||||
*
|
||||
* We need to create a new version of a record. If the new version
|
||||
* fits on the same page as the old record, things are simple and
|
||||
@ -209,9 +214,9 @@ int DPM_chain( TDBB tdbb, RPB * org_rpb, RPB * new_rpb)
|
||||
*
|
||||
* Note that we also return FALSE if the record fetched doesn't
|
||||
* match the state of the input rpb, or if there is no record for
|
||||
* that record number. The caller has to check the results to
|
||||
* that record number. The caller has to check the results to
|
||||
* see what failed if FALSE is returned. At the moment, there is
|
||||
* only one caller, VIO_erase.
|
||||
* only one caller, VIO_erase.
|
||||
*
|
||||
**************************************/
|
||||
DBB dbb;
|
||||
@ -1101,8 +1106,8 @@ SINT64 DPM_gen_id(TDBB tdbb, SLONG generator, USHORT initialize, SINT64 val)
|
||||
*
|
||||
* Functional description
|
||||
* Generate relation specific value.
|
||||
* If initialize is set then value of generator is made
|
||||
* equal to val else generator is incremented by val.
|
||||
* If initialize is set then value of generator is made
|
||||
* equal to val else generator is incremented by val.
|
||||
* The resulting value is the result of the function.
|
||||
**************************************/
|
||||
DBB dbb;
|
||||
@ -1153,14 +1158,10 @@ SINT64 DPM_gen_id(TDBB tdbb, SLONG generator, USHORT initialize, SINT64 val)
|
||||
|
||||
window.win_page = vector->vcl_long[sequence];
|
||||
window.win_flags = 0;
|
||||
#ifdef READONLY_DATABASE
|
||||
if (dbb->dbb_flags & DBB_read_only)
|
||||
page = (GPG) CCH_FETCH(tdbb, &window, LCK_read, pag_ids);
|
||||
else
|
||||
page = (GPG) CCH_FETCH(tdbb, &window, LCK_write, pag_ids);
|
||||
#else
|
||||
page = (GPG) CCH_FETCH(tdbb, &window, LCK_write, pag_ids);
|
||||
#endif /* READONLY_DATABASE */
|
||||
|
||||
/* If we are in ODS >= 10, then we have a pointer to an int64 value in the
|
||||
* generator page: if earlier than 10, it's a pointer to a long value.
|
||||
@ -1175,11 +1176,10 @@ SINT64 DPM_gen_id(TDBB tdbb, SLONG generator, USHORT initialize, SINT64 val)
|
||||
lptr = ((SLONG *) (((PPG) page)->ppg_page)) + offset;
|
||||
|
||||
if (val || initialize) {
|
||||
#ifdef READONLY_DATABASE
|
||||
if (dbb->dbb_flags & DBB_read_only)
|
||||
ERR_post(isc_read_only_database, 0);
|
||||
#endif /* READONLY_DATABASE */
|
||||
CCH_MARK(tdbb, &window);
|
||||
|
||||
CCH_MARK(tdbb, &window);
|
||||
|
||||
/* Initialize or increment the quad value in an ODS 10 or later
|
||||
* generator page, or the long value in ODS <= 9.
|
||||
@ -1309,7 +1309,7 @@ ULONG DPM_get_blob(TDBB tdbb,
|
||||
*
|
||||
* Functional description
|
||||
* Given a blob block, find the associated blob. If blob is level 0,
|
||||
* get the data clump, otherwise get the vector of pointers.
|
||||
* get the data clump, otherwise get the vector of pointers.
|
||||
*
|
||||
* If the delete flag is set, delete the blob header after access
|
||||
* and return the page number. This is a kludge, but less code
|
||||
@ -1507,7 +1507,7 @@ BOOLEAN DPM_next(TDBB tdbb,
|
||||
rpb->rpb_number--;
|
||||
else if (rpb->rpb_number < 0) {
|
||||
/* if the stream was just opened, assume we want to start
|
||||
at the end of the stream, so compute the last theoretically
|
||||
at the end of the stream, so compute the last theoretically
|
||||
possible rpb_number and go down from there */
|
||||
/** for now, we must force a scan to make sure that we get
|
||||
the last pointer page: this should be changed to use
|
||||
@ -2301,7 +2301,7 @@ static void fragment(
|
||||
* messing with the head until we get back, and, if possible, we'd
|
||||
* like to keep as much space on the original page as we can get.
|
||||
* Making matters worse, we may be storing a new version of the
|
||||
* record or we may be backing out an old one and replacing it
|
||||
* record or we may be backing out an old one and replacing it
|
||||
* with one older still (replacing a dead rolled back record with
|
||||
* the preceding version).
|
||||
*
|
||||
@ -2319,7 +2319,7 @@ static void fragment(
|
||||
* id. Applying deltas to the expanded form of the same version of the
|
||||
* record is a no-op -- but it doesn't cost much and the case is rare.
|
||||
*
|
||||
* If we're backing out a rolled back version, we've got another
|
||||
* If we're backing out a rolled back version, we've got another
|
||||
* problem. The rpb we've got is for record version n - 1, not version
|
||||
* n + 1. (e.g. I'm transaction 32 removing the rolled back record
|
||||
* created by transaction 28 and reinstating the committed version
|
||||
@ -2501,7 +2501,7 @@ static void extend_relation( TDBB tdbb, REL relation, WIN * window)
|
||||
* Functional description
|
||||
* Extend a relation with a given page. The window points to an
|
||||
* already allocated, fetched, and marked data page to be inserted
|
||||
* into the pointer pages for a given relation.
|
||||
* into the pointer pages for a given relation.
|
||||
* This routine returns a window on the datapage locked for write
|
||||
*
|
||||
**************************************/
|
||||
@ -2671,7 +2671,7 @@ static UCHAR *find_space(TDBB tdbb,
|
||||
* data page, and return a pointer to the space.
|
||||
*
|
||||
* To maintain page precedence when objects point to objects, a stack
|
||||
* of pages of high precedence may be passed in.
|
||||
* of pages of high precedence may be passed in.
|
||||
*
|
||||
**************************************/
|
||||
DBB dbb;
|
||||
@ -2963,8 +2963,8 @@ static RHD locate_space(
|
||||
}
|
||||
|
||||
/* Sigh. No space. Extend relation. Try for a while
|
||||
in case someone grabs the page before we can get it
|
||||
locked, then give up on the assumption that things
|
||||
in case someone grabs the page before we can get it
|
||||
locked, then give up on the assumption that things
|
||||
are really screwed up. */
|
||||
|
||||
for (i = 0; i < 20; i++) {
|
||||
@ -3034,7 +3034,7 @@ static void mark_full( TDBB tdbb, register RPB * rpb)
|
||||
DECOMPOSE(sequence, dbb->dbb_dp_per_pp, pp_sequence, slot);
|
||||
|
||||
/* Fetch the pointer page, then the data page. Since this is a case of
|
||||
fetching a second page after having fetched the first page with an
|
||||
fetching a second page after having fetched the first page with an
|
||||
exclusive latch, care has to be taken to prevent a deadlock. This
|
||||
is accomplished by timing out the second latch request and retrying
|
||||
the whole thing. */
|
||||
@ -3293,4 +3293,4 @@ static void store_big_record(
|
||||
}
|
||||
else
|
||||
CCH_RELEASE(tdbb, &rpb->rpb_window);
|
||||
}
|
||||
}
|
@ -19,6 +19,9 @@
|
||||
*
|
||||
* All Rights Reserved.
|
||||
* Contributor(s): ______________________________________.
|
||||
* 2001.07.06 Sean Leyne - Code Cleanup, removed "#ifdef READONLY_DATABASE"
|
||||
* conditionals, as the engine now fully supports
|
||||
* readonly databases.
|
||||
*/
|
||||
|
||||
#include "../jrd/ib_stdio.h"
|
||||
@ -333,7 +336,7 @@ RSB EXT_optimize(register OPT opt, SSHORT stream, NOD * sort_ptr)
|
||||
register CSB csb;
|
||||
REL relation;
|
||||
RSB rsb;
|
||||
/* all these are un refrenced due to the code commented below
|
||||
/* all these are un refrenced due to the code commented below
|
||||
NOD node, inversion;
|
||||
register opt::opt_repeat *tail, *opt_end;
|
||||
SSHORT i, size;
|
||||
@ -365,14 +368,14 @@ if (opt->opt_count)
|
||||
for (tail = opt->opt_rpt; tail < opt_end; tail++)
|
||||
{
|
||||
node = tail->opt_conjunct;
|
||||
if (!(tail->opt_flags & opt_used) &&
|
||||
if (!(tail->opt_flags & opt_used) &&
|
||||
computable (csb, node, -1))
|
||||
match (opt, stream, node, idx);
|
||||
if (node->nod_type == nod_starts)
|
||||
compose (&inversion,
|
||||
compose (&inversion,
|
||||
make_starts (opt, node, stream, idx), nod_bit_and);
|
||||
}
|
||||
compose (&inversion, make_index (opt, relation, idx),
|
||||
compose (&inversion, make_index (opt, relation, idx),
|
||||
nod_bit_and);
|
||||
idx = idx->idx_rpt + idx->idx_count;
|
||||
}
|
||||
@ -437,10 +440,9 @@ void EXT_store(RPB * rpb, int *transaction)
|
||||
/* Loop thru fields setting missing fields to either blanks/zeros
|
||||
or the missing value */
|
||||
|
||||
/* check if file is read only if read only then
|
||||
/* check if file is read only if read only then
|
||||
post error we cannot write to this file */
|
||||
if (file->ext_flags & EXT_readonly) {
|
||||
#ifdef READONLY_DATABASE
|
||||
DBB dbb;
|
||||
|
||||
dbb = GET_DBB;
|
||||
@ -449,7 +451,6 @@ void EXT_store(RPB * rpb, int *transaction)
|
||||
if (dbb->dbb_flags & DBB_read_only)
|
||||
ERR_post(isc_read_only_database, 0);
|
||||
else
|
||||
#endif /* READONLY_DATABASE */
|
||||
ERR_post(isc_io_error,
|
||||
gds_arg_string, "insert",
|
||||
gds_arg_string, file->ext_filename,
|
||||
@ -554,4 +555,4 @@ void EXT_trans_start(TRA transaction)
|
||||
}
|
||||
|
||||
|
||||
} // extern "C"
|
||||
} // extern "C"
|
@ -19,6 +19,9 @@
|
||||
*
|
||||
* All Rights Reserved.
|
||||
* Contributor(s): ______________________________________.
|
||||
* 2001.07.06 Sean Leyne - Code Cleanup, removed "#ifdef READONLY_DATABASE"
|
||||
* conditionals, as the engine now fully supports
|
||||
* readonly databases.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
@ -61,7 +64,7 @@ extern "C" {
|
||||
* the change to Firebird this number could no longer be used.
|
||||
* The DBSERVER_BASE_LEVEL for firebird starts at 6 which is the base level
|
||||
* of InterBase(r) from which Firebird was derived.
|
||||
* It is expected that this value will increase as changes are added to
|
||||
* It is expected that this value will increase as changes are added to
|
||||
* Firebird
|
||||
*/
|
||||
|
||||
@ -468,7 +471,7 @@ int INF_database_info(
|
||||
case gds_info_base_level:
|
||||
/* info_base_level is used by the client to represent
|
||||
* what the server is capable of. It is equivalent to the
|
||||
* ods version of a database. For example,
|
||||
* ods version of a database. For example,
|
||||
* ods_version represents what the database 'knows'
|
||||
* base_level represents what the server 'knows'
|
||||
*/
|
||||
@ -666,14 +669,14 @@ int INF_database_info(
|
||||
**
|
||||
** there are 3 types of databases:
|
||||
**
|
||||
** 1. a DB that is created before V6.0. This DB only speak SQL
|
||||
** 1. a DB that is created before V6.0. This DB only speak SQL
|
||||
** dialect 1 and 2.
|
||||
**
|
||||
** 2. a non ODS 10 DB is backed up/restored in IB V6.0. Since
|
||||
** this DB contained some old SQL dialect, therefore it
|
||||
** speaks SQL dialect 1, 2, and 3
|
||||
**
|
||||
** 3. a DB that is created in V6.0. This DB speak SQL
|
||||
** 3. a DB that is created in V6.0. This DB speak SQL
|
||||
** dialect 1, 2 or 3 depending the DB was created
|
||||
** under which SQL dialect.
|
||||
**
|
||||
@ -681,12 +684,12 @@ int INF_database_info(
|
||||
if (ENCODE_ODS(dbb->dbb_ods_version, dbb->dbb_minor_original)
|
||||
>= ODS_10_0)
|
||||
if (dbb->dbb_flags & DBB_DB_SQL_dialect_3)
|
||||
/*
|
||||
** DB created in IB V6.0 by client SQL dialect 3
|
||||
/*
|
||||
** DB created in IB V6.0 by client SQL dialect 3
|
||||
*/
|
||||
*p++ = SQL_DIALECT_V6;
|
||||
else
|
||||
/*
|
||||
/*
|
||||
** old DB was gbaked in IB V6.0
|
||||
*/
|
||||
*p++ = SQL_DIALECT_V5;
|
||||
@ -696,13 +699,11 @@ int INF_database_info(
|
||||
length = p - buffer;
|
||||
break;
|
||||
|
||||
#ifdef READONLY_DATABASE
|
||||
case isc_info_db_read_only:
|
||||
*p++ = (dbb->dbb_flags & DBB_read_only) ? 1 : 0;
|
||||
length = p - buffer;
|
||||
|
||||
break;
|
||||
#endif /* READONLY_DATABASE */
|
||||
|
||||
case isc_info_db_size_in_pages:
|
||||
CCH_flush(tdbb, (USHORT) FLUSH_ALL, 0L);
|
||||
@ -970,9 +971,9 @@ int INF_request_info(
|
||||
|
||||
case gds_info_access_path:
|
||||
|
||||
/* the access path has the potential to be large, so if the default
|
||||
buffer is not big enough, allocate a really large one--don't
|
||||
continue to allocate larger and larger, because of the potential
|
||||
/* the access path has the potential to be large, so if the default
|
||||
buffer is not big enough, allocate a really large one--don't
|
||||
continue to allocate larger and larger, because of the potential
|
||||
for a bug which would bring the server to its knees */
|
||||
|
||||
if (!OPT_access_path
|
||||
@ -1133,4 +1134,4 @@ static USHORT get_counts(USHORT count_id, UCHAR * buffer, USHORT length)
|
||||
#endif
|
||||
|
||||
|
||||
} // extern "C"
|
||||
} // extern "C"
|
@ -19,6 +19,9 @@
|
||||
*
|
||||
* All Rights Reserved.
|
||||
* Contributor(s): ______________________________________.
|
||||
* 2001.07.06 Sean Leyne - Code Cleanup, removed "#ifdef READONLY_DATABASE"
|
||||
* conditionals, as the engine now fully supports
|
||||
* readonly databases.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
@ -715,10 +718,10 @@ void INI_update_database(void)
|
||||
**************************************
|
||||
*
|
||||
* Functional description
|
||||
* Perform changes to ODS that were required
|
||||
* Perform changes to ODS that were required
|
||||
* since ODS 8 and are dynamically updatable.
|
||||
*
|
||||
* %% Note %% Update the switch() statement to reflect new major ODS
|
||||
* %% Note %% Update the switch() statement to reflect new major ODS
|
||||
* addition
|
||||
**************************************/
|
||||
DBB dbb;
|
||||
@ -731,11 +734,9 @@ void INI_update_database(void)
|
||||
dbb = tdbb->tdbb_database;
|
||||
CHECK_DBB(dbb);
|
||||
|
||||
#ifdef READONLY_DATABASE
|
||||
/* If database is ReadOnly, return without upgrading ODS */
|
||||
if (dbb->dbb_flags & DBB_read_only)
|
||||
return;
|
||||
#endif
|
||||
|
||||
/* check out the update version to see if we have work to do */
|
||||
|
||||
@ -753,7 +754,7 @@ void INI_update_database(void)
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
** when new engine is attaching an older ODS database
|
||||
** when new engine is attaching an older ODS database
|
||||
** perform the necessary modifications
|
||||
********************************************************************/
|
||||
|
||||
@ -786,7 +787,7 @@ void INI_update_database(void)
|
||||
header = (HDR) CCH_FETCH(tdbb, &window, LCK_write, pag_header);
|
||||
CCH_MARK(tdbb, &window);
|
||||
|
||||
/* Only minor upgrades can occur within a major ODS, define which one
|
||||
/* Only minor upgrades can occur within a major ODS, define which one
|
||||
occured here. */
|
||||
switch (major_version)
|
||||
{
|
||||
@ -931,7 +932,7 @@ static void add_index_set(DBB dbb,
|
||||
(((USHORT) DECODE_ODS_MAJOR(index->ini_idx_version_flag)) !=
|
||||
major_version)))
|
||||
{
|
||||
/* The DECODE_ODS_MAJOR() is used (in this case) to instruct the server
|
||||
/* The DECODE_ODS_MAJOR() is used (in this case) to instruct the server
|
||||
to perform updates for minor ODS versions only within a major ODS */
|
||||
continue;
|
||||
}
|
||||
@ -990,9 +991,9 @@ static void add_new_triggers(USHORT major_version, USHORT minor_version)
|
||||
**************************************
|
||||
*
|
||||
* Functional description
|
||||
* Store all new ODS 8.x (x > 0) triggers.
|
||||
* Store all new ODS 8.x (x > 0) triggers.
|
||||
* The major and minor_version passed in are the ODS versions
|
||||
* before the ODS is upgraded.
|
||||
* before the ODS is upgraded.
|
||||
* This routine is used to upgrade ODS versions.
|
||||
*
|
||||
**************************************/
|
||||
@ -1116,7 +1117,7 @@ static void add_security_to_sys_rel(TDBB tdbb,
|
||||
*
|
||||
* Functional description
|
||||
*
|
||||
* Add security to system relations. Only the owner of the
|
||||
* Add security to system relations. Only the owner of the
|
||||
* database has SELECT/INSERT/UPDATE/DELETE privileges on
|
||||
* any system relations. Any other users only has SELECT
|
||||
* privilege.
|
||||
@ -1292,7 +1293,7 @@ static void modify_relation_field(TDBB tdbb,
|
||||
**************************************
|
||||
*
|
||||
* Functional description
|
||||
* Modify a local field according to the
|
||||
* Modify a local field according to the
|
||||
* passed information. Note that the field id and
|
||||
* field position do not change.
|
||||
*
|
||||
@ -1324,7 +1325,7 @@ static void store_generator(TDBB tdbb, CONST GEN* generator, BLK* handle)
|
||||
**************************************
|
||||
*
|
||||
* Functional description
|
||||
* Store the passed generator according to
|
||||
* Store the passed generator according to
|
||||
* the information in the generator block.
|
||||
*
|
||||
**************************************/
|
||||
@ -1350,7 +1351,7 @@ static void store_global_field(TDBB tdbb, GFLD* gfield, BLK* handle)
|
||||
**************************************
|
||||
*
|
||||
* Functional description
|
||||
* Store a global field according to the
|
||||
* Store a global field according to the
|
||||
* passed information.
|
||||
*
|
||||
**************************************/
|
||||
@ -1476,7 +1477,7 @@ static void store_intlnames(TDBB tdbb, DBB dbb)
|
||||
{
|
||||
/**************************************
|
||||
*
|
||||
* s t o r e _ i n t l n a m e s
|
||||
* s t o r e _ i n t l n a m e s
|
||||
*
|
||||
**************************************
|
||||
*
|
||||
@ -1562,7 +1563,7 @@ static void store_relation_field(TDBB tdbb,
|
||||
**************************************
|
||||
*
|
||||
* Functional description
|
||||
* Store a local field according to the
|
||||
* Store a local field according to the
|
||||
* passed information.
|
||||
*
|
||||
**************************************/
|
||||
@ -1595,7 +1596,7 @@ static void store_trigger(TDBB tdbb, CONST TRG* trigger, BLK* handle)
|
||||
**************************************
|
||||
*
|
||||
* Functional description
|
||||
* Store the trigger according to the
|
||||
* Store the trigger according to the
|
||||
* information in the trigger block.
|
||||
*
|
||||
**************************************/
|
||||
@ -1633,4 +1634,4 @@ static void store_trigger(TDBB tdbb, CONST TRG* trigger, BLK* handle)
|
||||
trigger->trg_length);
|
||||
BLB_close(tdbb, blob);
|
||||
END_STORE;
|
||||
}
|
||||
}
|
@ -19,6 +19,9 @@
|
||||
*
|
||||
* All Rights Reserved.
|
||||
* Contributor(s): ______________________________________.
|
||||
* 2001.07.06 Sean Leyne - Code Cleanup, removed "#ifdef READONLY_DATABASE"
|
||||
* conditionals, as the engine now fully supports
|
||||
* readonly databases.
|
||||
*/
|
||||
|
||||
#ifdef SHLIB_DEFS
|
||||
@ -786,7 +789,7 @@ STATUS DLL_EXPORT GDS_ATTACH_DATABASE(STATUS* user_status,
|
||||
PAG_init2(0);
|
||||
if (options.dpb_disable_wal)
|
||||
{
|
||||
/* Forcibly disable WAL before the next step.
|
||||
/* Forcibly disable WAL before the next step.
|
||||
We have an exclusive access to the database. */
|
||||
AIL_drop_log_force();
|
||||
options.dpb_disable_wal = FALSE; /* To avoid further processing below */
|
||||
@ -818,13 +821,7 @@ STATUS DLL_EXPORT GDS_ATTACH_DATABASE(STATUS* user_status,
|
||||
INI_update_database();
|
||||
}
|
||||
|
||||
#ifdef READONLY_DATABASE
|
||||
/* Attachments to a ReadOnly database need NOT do garbage collection */
|
||||
if (dbb->dbb_flags & DBB_read_only)
|
||||
attachment->att_flags |= ATT_no_cleanup;
|
||||
#endif /* READONLY_DATABASE */
|
||||
|
||||
if (options.dpb_disable_wal)
|
||||
if (options.dpb_disable_wal)
|
||||
{
|
||||
ERR_post(gds_lock_timeout, gds_arg_gds, gds_obj_in_use,
|
||||
gds_arg_string, ERR_string(file_name, fl), 0);
|
||||
@ -920,9 +917,9 @@ STATUS DLL_EXPORT GDS_ATTACH_DATABASE(STATUS* user_status,
|
||||
BOOLEAN delimited_done = FALSE;
|
||||
TEXT end_quote = *p1;
|
||||
*p1++;
|
||||
/*
|
||||
** remove the delimited quotes and escape quote
|
||||
** from ROLE name
|
||||
/*
|
||||
** remove the delimited quotes and escape quote
|
||||
** from ROLE name
|
||||
*/
|
||||
while (*p1 && !delimited_done
|
||||
&& cnt < BUFFER_LENGTH128 - 1)
|
||||
@ -1003,7 +1000,7 @@ STATUS DLL_EXPORT GDS_ATTACH_DATABASE(STATUS* user_status,
|
||||
if (options.dpb_shutdown || options.dpb_online) {
|
||||
/* By releasing the DBB_MUTX_init_fini mutex here, we would be allowing
|
||||
other threads to proceed with their detachments, so that shutdown does
|
||||
not timeout for exclusive access and other threads don't have to wait
|
||||
not timeout for exclusive access and other threads don't have to wait
|
||||
behind shutdown */
|
||||
|
||||
V4_JRD_MUTEX_UNLOCK(dbb->dbb_mutexes + DBB_MUTX_init_fini);
|
||||
@ -1025,9 +1022,9 @@ STATUS DLL_EXPORT GDS_ATTACH_DATABASE(STATUS* user_status,
|
||||
}
|
||||
|
||||
#ifdef SUPERSERVER
|
||||
/* Check if another attachment has or is requesting exclusive database access.
|
||||
/* Check if another attachment has or is requesting exclusive database access.
|
||||
If this is an implicit attachment for the security (password) database, don't
|
||||
try to get exclusive attachment to avoid a deadlock condition which happens
|
||||
try to get exclusive attachment to avoid a deadlock condition which happens
|
||||
when a client tries to connect to the security database itself. */
|
||||
|
||||
if (!options.dpb_sec_attach) {
|
||||
@ -1204,19 +1201,6 @@ STATUS DLL_EXPORT GDS_ATTACH_DATABASE(STATUS* user_status,
|
||||
PAG_set_page_buffers(options.dpb_page_buffers);
|
||||
}
|
||||
|
||||
#ifdef READONLY_DATABASE
|
||||
if (options.dpb_set_db_readonly)
|
||||
{
|
||||
if (!CCH_exclusive(tdbb, LCK_EX, WAIT_PERIOD))
|
||||
{
|
||||
ERR_post(gds_lock_timeout, gds_arg_gds, gds_obj_in_use,
|
||||
gds_arg_string, ERR_string(file_name, fl), 0);
|
||||
}
|
||||
|
||||
PAG_set_db_readonly(dbb, options.dpb_db_readonly);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef REPLAY_OSRI_API_CALLS_SUBSYSTEM
|
||||
/* don't record the attach until now in case the log is added during the attach */
|
||||
|
||||
@ -1920,7 +1904,7 @@ STATUS DLL_EXPORT GDS_CREATE_DATABASE(STATUS* user_status,
|
||||
if (options.dpb_shutdown || options.dpb_online) {
|
||||
/* By releasing the DBB_MUTX_init_fini mutex here, we would be allowing
|
||||
other threads to proceed with their detachments, so that shutdown does
|
||||
not timeout for exclusive access and other threads don't have to wait
|
||||
not timeout for exclusive access and other threads don't have to wait
|
||||
behind shutdown */
|
||||
|
||||
V4_JRD_MUTEX_UNLOCK(dbb->dbb_mutexes + DBB_MUTX_init_fini);
|
||||
@ -1959,7 +1943,16 @@ STATUS DLL_EXPORT GDS_CREATE_DATABASE(STATUS* user_status,
|
||||
VIO_init(tdbb);
|
||||
#endif
|
||||
|
||||
CCH_release_exclusive(tdbb);
|
||||
if (options.dpb_set_db_readonly)
|
||||
{
|
||||
if (!CCH_exclusive (tdbb, LCK_EX, WAIT_PERIOD))
|
||||
ERR_post (gds__lock_timeout, gds_arg_gds, gds__obj_in_use,
|
||||
gds_arg_string, ERR_string (file_name, fl), 0);
|
||||
|
||||
PAG_set_db_readonly (dbb, options.dpb_db_readonly);
|
||||
}
|
||||
|
||||
CCH_release_exclusive(tdbb);
|
||||
|
||||
/* Figure out what character set & collation this attachment prefers */
|
||||
|
||||
@ -2077,12 +2070,12 @@ STATUS DLL_EXPORT GDS_DDL(STATUS * user_status,
|
||||
DYN_ddl(attachment, transaction, ddl_length,
|
||||
reinterpret_cast < UCHAR * >(ddl));
|
||||
|
||||
/*
|
||||
/*
|
||||
* Perform an auto commit for autocommit transactions.
|
||||
* This is slightly tricky. If the commit retain works,
|
||||
* all is well. If TRA_commit () fails, we perform
|
||||
* a rollback_retain (). This will backout the
|
||||
* effects of the transaction, mark it dead and
|
||||
* effects of the transaction, mark it dead and
|
||||
* start a new transaction.
|
||||
|
||||
* For now only ExpressLink will use this feature. Later
|
||||
@ -3189,7 +3182,7 @@ STATUS DLL_EXPORT GDS_SERVICE_QUERY(STATUS* user_status,
|
||||
* NOTE: The parameter RESERVED must not be used
|
||||
* for any purpose as there are networking issues
|
||||
* involved (as with any handle that goes over the
|
||||
* network). This parameter will be implemented at
|
||||
* network). This parameter will be implemented at
|
||||
* a later date.
|
||||
*
|
||||
**************************************/
|
||||
@ -3212,7 +3205,7 @@ STATUS DLL_EXPORT GDS_SERVICE_QUERY(STATUS* user_status,
|
||||
SVC_query(service, send_item_length, send_items, recv_item_length,
|
||||
recv_items, buffer_length, buffer);
|
||||
else {
|
||||
/* For SVC_query2, we are going to completly dismantle user_status (since at this point it is
|
||||
/* For SVC_query2, we are going to completly dismantle user_status (since at this point it is
|
||||
* meaningless anyway). The status vector returned by this function can hold information about
|
||||
* the call to query the service manager and/or a service thread that may have been running.
|
||||
*/
|
||||
@ -3256,7 +3249,7 @@ STATUS DLL_EXPORT GDS_SERVICE_START(STATUS* user_status,
|
||||
* NOTE: The parameter RESERVED must not be used
|
||||
* for any purpose as there are networking issues
|
||||
* involved (as with any handle that goes over the
|
||||
* network). This parameter will be implemented at
|
||||
* network). This parameter will be implemented at
|
||||
* a later date.
|
||||
**************************************/
|
||||
SVC service;
|
||||
@ -3855,9 +3848,9 @@ USHORT JRD_getdir(TEXT * buf, USHORT len)
|
||||
*
|
||||
* Functional description
|
||||
* Current working directory is cached in the attachment
|
||||
* block. get it out. This function could be called before
|
||||
* block. get it out. This function could be called before
|
||||
* an attachment is created. In such a case thread specific
|
||||
* data (t_data) will hold the user name which will be used
|
||||
* data (t_data) will hold the user name which will be used
|
||||
* to get the users home directory.
|
||||
*
|
||||
**************************************/
|
||||
@ -3903,9 +3896,9 @@ USHORT JRD_getdir(TEXT * buf, USHORT len)
|
||||
else
|
||||
return 0;
|
||||
|
||||
/**
|
||||
/**
|
||||
An older version of client will not be sending isc_dpb_working directory
|
||||
so in all probabilities attachment->att_working_directory will be null.
|
||||
so in all probabilities attachment->att_working_directory will be null.
|
||||
return 0 so that ISC_expand_filename will create the file in ibserver's dir
|
||||
**/
|
||||
if (!attachment->att_working_directory ||
|
||||
@ -4006,7 +3999,7 @@ void JRD_print_procedure_info(TDBB tdbb, char *mesg)
|
||||
*****************************************************
|
||||
*
|
||||
* Functional description
|
||||
* print name , use_count of all procedures in
|
||||
* print name , use_count of all procedures in
|
||||
* cache
|
||||
*
|
||||
******************************************************/
|
||||
@ -4756,7 +4749,7 @@ static void get_options(UCHAR* dpb,
|
||||
|
||||
THD_getspecific_data((void **) &t_data);
|
||||
|
||||
/*
|
||||
/*
|
||||
Null value for working_directory implies remote database. So get
|
||||
the users HOME directory
|
||||
*/
|
||||
@ -5066,13 +5059,6 @@ static void get_options(UCHAR* dpb,
|
||||
options->dpb_set_db_sql_dialect = (USHORT) get_parameter(&p);
|
||||
break;
|
||||
|
||||
#ifdef READONLY_DATABASE
|
||||
case isc_dpb_set_db_readonly:
|
||||
options->dpb_set_db_readonly = TRUE;
|
||||
options->dpb_db_readonly = (SSHORT) get_parameter(&p);
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
l = *p++;
|
||||
p += l;
|
||||
@ -5279,7 +5265,7 @@ static DBB init(TDBB tdbb,
|
||||
THD_MUTEX_INIT_N(temp_mutx, DBB_MUTX_max);
|
||||
V4_RW_LOCK_INIT_N(temp_wlck, DBB_WLCK_max);
|
||||
|
||||
/* set up the temporary database block with fields that are
|
||||
/* set up the temporary database block with fields that are
|
||||
required for doing the ALL_init() */
|
||||
|
||||
temp.dbb_header.blk_type = type_dbb;
|
||||
@ -5504,8 +5490,8 @@ static void release_attachment(ATT attachment)
|
||||
LCK_release(tdbb, record_lock);
|
||||
}
|
||||
|
||||
/* bug #7781, need to null out the attachment pointer of all locks which
|
||||
were hung off this attachment block, to ensure that the attachment
|
||||
/* bug #7781, need to null out the attachment pointer of all locks which
|
||||
were hung off this attachment block, to ensure that the attachment
|
||||
block doesn't get dereferenced after it is released */
|
||||
|
||||
for (record_lock = attachment->att_long_locks; record_lock;
|
||||
@ -5561,8 +5547,8 @@ static STATUS return_success(TDBB tdbb)
|
||||
|
||||
p = user_status = tdbb->tdbb_status_vector;
|
||||
|
||||
/* If the status vector has not been initialized, then
|
||||
initilalize the status vector to indicate success.
|
||||
/* If the status vector has not been initialized, then
|
||||
initilalize the status vector to indicate success.
|
||||
Else pass the status vector along at it stands. */
|
||||
if (p[0] != gds_arg_gds ||
|
||||
p[1] != SUCCESS ||
|
||||
@ -6231,4 +6217,4 @@ static void purge_attachment(TDBB tdbb,
|
||||
}
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
} // extern "C"
|
107
src/jrd/met.e
107
src/jrd/met.e
@ -19,9 +19,12 @@
|
||||
*
|
||||
* All Rights Reserved.
|
||||
* Contributor(s): ______________________________________.
|
||||
* 2001.07.06 Sean Leyne - Code Cleanup, removed "#ifdef READONLY_DATABASE"
|
||||
* conditionals, as the engine now fully supports
|
||||
* readonly databases.
|
||||
*/
|
||||
/*
|
||||
$Id: met.e,v 1.1.1.1 2001-05-23 13:26:19 tamlin Exp $
|
||||
$Id: met.e,v 1.2 2001-07-10 17:35:13 awharrison Exp $
|
||||
*/
|
||||
|
||||
#ifdef SHLIB_DEFS
|
||||
@ -183,7 +186,7 @@ void MET_activate_shadow( TDBB tdbb)
|
||||
handle = NULL;
|
||||
FOR(REQUEST_HANDLE handle) X IN RDB$FILES
|
||||
WITH X.RDB$SHADOW_NUMBER NOT MISSING
|
||||
AND X.RDB$SHADOW_NUMBER EQ 0
|
||||
AND X.RDB$SHADOW_NUMBER EQ 0
|
||||
ERASE X;
|
||||
END_FOR;
|
||||
|
||||
@ -220,7 +223,7 @@ void MET_activate_shadow( TDBB tdbb)
|
||||
|
||||
/* Get rid of WAL after activation. For V4.0, we are not allowing
|
||||
WAL and Shadowing to be configured together. So the following
|
||||
(commented out) code should be re-visited when we do allow
|
||||
(commented out) code should be re-visited when we do allow
|
||||
such configuration. */
|
||||
|
||||
/***********************
|
||||
@ -344,7 +347,7 @@ void MET_delete_dependencies(TDBB tdbb,
|
||||
**************************************
|
||||
*
|
||||
* Functional description
|
||||
* Delete all dependencies for the specified
|
||||
* Delete all dependencies for the specified
|
||||
* object of given type.
|
||||
*
|
||||
**************************************/
|
||||
@ -382,7 +385,7 @@ void MET_delete_shadow( TDBB tdbb, USHORT shadow_number)
|
||||
*
|
||||
**************************************
|
||||
*
|
||||
* Functional description
|
||||
* Functional description
|
||||
* When any of the shadows in RDB$FILES for a particular
|
||||
* shadow are deleted, stop shadowing to that file and
|
||||
* remove all other files from the same shadow.
|
||||
@ -398,7 +401,7 @@ void MET_delete_shadow( TDBB tdbb, USHORT shadow_number)
|
||||
handle = NULL;
|
||||
|
||||
FOR(REQUEST_HANDLE handle)
|
||||
X IN RDB$FILES WITH X.RDB$SHADOW_NUMBER EQ shadow_number
|
||||
X IN RDB$FILES WITH X.RDB$SHADOW_NUMBER EQ shadow_number
|
||||
ERASE X;
|
||||
END_FOR;
|
||||
|
||||
@ -504,7 +507,7 @@ FMT MET_format(TDBB tdbb, register REL relation, USHORT number)
|
||||
|
||||
FOR(REQUEST_HANDLE request)
|
||||
X IN RDB$FORMATS WITH X.RDB$RELATION_ID EQ relation->rel_id AND
|
||||
X.RDB$FORMAT EQ number
|
||||
X.RDB$FORMAT EQ number
|
||||
|
||||
if (!REQUEST(irq_r_format))
|
||||
{
|
||||
@ -553,7 +556,7 @@ BOOLEAN MET_get_char_subtype(TDBB tdbb,
|
||||
{
|
||||
/**************************************
|
||||
*
|
||||
* M E T _ g e t _ c h a r _ s u b t y p e
|
||||
* M E T _ g e t _ c h a r _ s u b t y p e
|
||||
*
|
||||
**************************************
|
||||
*
|
||||
@ -634,7 +637,7 @@ NOD MET_get_dependencies(TDBB tdbb,
|
||||
**************************************
|
||||
*
|
||||
* Functional description
|
||||
* Get dependencies for an object by parsing
|
||||
* Get dependencies for an object by parsing
|
||||
* the blr used in its definition.
|
||||
*
|
||||
**************************************/
|
||||
@ -735,7 +738,7 @@ void MET_get_shadow_files( TDBB tdbb, USHORT delete)
|
||||
*
|
||||
* Functional description
|
||||
* Check the shadows found in the database against
|
||||
* our in-memory list: if any new shadow files have
|
||||
* our in-memory list: if any new shadow files have
|
||||
* been defined since the last time we looked, start
|
||||
* shadowing to them; if any have been deleted, stop
|
||||
* shadowing to them.
|
||||
@ -761,7 +764,7 @@ void MET_get_shadow_files( TDBB tdbb, USHORT delete)
|
||||
SDW_start(X.RDB$FILE_NAME, X.RDB$SHADOW_NUMBER, file_flags,
|
||||
delete);
|
||||
|
||||
/* if the shadow exists, mark the appropriate shadow
|
||||
/* if the shadow exists, mark the appropriate shadow
|
||||
block as found for the purposes of this routine;
|
||||
if the shadow was conditional and is no longer, note it */
|
||||
|
||||
@ -781,7 +784,7 @@ void MET_get_shadow_files( TDBB tdbb, USHORT delete)
|
||||
|
||||
CMP_release(tdbb, (REQ)handle);
|
||||
|
||||
/* if any current shadows were not defined in database, mark
|
||||
/* if any current shadows were not defined in database, mark
|
||||
them to be shutdown since they don't exist anymore */
|
||||
|
||||
for (shadow = dbb->dbb_shadow; shadow; shadow = shadow->sdw_next)
|
||||
@ -882,12 +885,10 @@ void MET_load_trigger(
|
||||
if (relation->rel_flags & REL_sys_trigs_being_loaded)
|
||||
return;
|
||||
|
||||
#ifdef READONLY_DATABASE
|
||||
/* No need to load triggers for ReadOnly databases,
|
||||
since INSERT/DELETE/UPDATE statements are not going to be allowed */
|
||||
if (dbb->dbb_flags & DBB_read_only)
|
||||
return;
|
||||
#endif /* READONLY_DATABASE */
|
||||
|
||||
/* Scan RDB$TRIGGERS next */
|
||||
|
||||
@ -982,7 +983,7 @@ void MET_lookup_cnstrt_for_trigger(
|
||||
{
|
||||
/**************************************
|
||||
*
|
||||
* M E T _ l o o k u p _ c n s t r t _ f o r _ t r i g g e r
|
||||
* M E T _ l o o k u p _ c n s t r t _ f o r _ t r i g g e r
|
||||
*
|
||||
**************************************
|
||||
*
|
||||
@ -1002,9 +1003,9 @@ void MET_lookup_cnstrt_for_trigger(
|
||||
request = (BLK) CMP_find_request(tdbb, irq_l_check, IRQ_REQUESTS);
|
||||
request2 = (BLK) CMP_find_request(tdbb, irq_l_check2, IRQ_REQUESTS);
|
||||
|
||||
/* utilize two requests rather than one so that we
|
||||
/* utilize two requests rather than one so that we
|
||||
guarantee we always return the name of the relation
|
||||
that the trigger is defined on, even if we don't
|
||||
that the trigger is defined on, even if we don't
|
||||
have a check constraint defined for that trigger */
|
||||
|
||||
FOR(REQUEST_HANDLE request)
|
||||
@ -1200,7 +1201,7 @@ int MET_lookup_field(TDBB tdbb, REL relation, CONST TEXT* name)
|
||||
FOR(REQUEST_HANDLE request)
|
||||
X IN RDB$RELATION_FIELDS WITH
|
||||
X.RDB$RELATION_NAME EQ relation->rel_name AND
|
||||
X.RDB$FIELD_NAME EQ name
|
||||
X.RDB$FIELD_NAME EQ name
|
||||
|
||||
if (!REQUEST(irq_l_field))
|
||||
{
|
||||
@ -1248,7 +1249,7 @@ BLF MET_lookup_filter(TDBB tdbb, SSHORT from, SSHORT to)
|
||||
|
||||
FOR(REQUEST_HANDLE request)
|
||||
X IN RDB$FILTERS WITH X.RDB$INPUT_SUB_TYPE EQ from AND
|
||||
X.RDB$OUTPUT_SUB_TYPE EQ to
|
||||
X.RDB$OUTPUT_SUB_TYPE EQ to
|
||||
|
||||
if (!REQUEST(irq_r_filters))
|
||||
REQUEST(irq_r_filters) = request;
|
||||
@ -1378,7 +1379,7 @@ void DLL_EXPORT MET_lookup_index(
|
||||
|
||||
FOR(REQUEST_HANDLE request)
|
||||
X IN RDB$INDICES WITH X.RDB$RELATION_NAME EQ relation_name
|
||||
AND X.RDB$INDEX_ID EQ number
|
||||
AND X.RDB$INDEX_ID EQ number
|
||||
|
||||
if (!REQUEST(irq_l_index))
|
||||
REQUEST(irq_l_index) = request;
|
||||
@ -1496,7 +1497,7 @@ int MET_lookup_partner(
|
||||
IDX.RDB$INDEX_NAME STARTING WITH "RDB$FOREIGN" AND
|
||||
IDX.RDB$RELATION_NAME EQ relation->rel_name AND
|
||||
IND.RDB$INDEX_NAME EQ IDX.RDB$FOREIGN_KEY AND
|
||||
IND.RDB$UNIQUE_FLAG NOT MISSING
|
||||
IND.RDB$UNIQUE_FLAG NOT MISSING
|
||||
|
||||
if (!REQUEST(irq_foreign1))
|
||||
{
|
||||
@ -1514,7 +1515,7 @@ int MET_lookup_partner(
|
||||
|
||||
references->frgn_reference_ids->vec_object[index_number] =
|
||||
(BLK) (IDX.RDB$INDEX_ID - 1);
|
||||
|
||||
|
||||
ALL_vector(dbb->dbb_permanent,
|
||||
&references->frgn_relations,
|
||||
(USHORT)index_number);
|
||||
@ -1750,7 +1751,7 @@ PRC MET_lookup_procedure(TDBB tdbb, SCHAR * name)
|
||||
FOR(REQUEST_HANDLE request)
|
||||
P IN RDB$PROCEDURES WITH P.RDB$PROCEDURE_NAME EQ name
|
||||
|
||||
if (!REQUEST(irq_l_procedure))
|
||||
if (!REQUEST(irq_l_procedure))
|
||||
REQUEST(irq_l_procedure) = request;
|
||||
|
||||
procedure = MET_procedure(tdbb, P.RDB$PROCEDURE_ID, 0);
|
||||
@ -1807,7 +1808,7 @@ PRC MET_lookup_procedure_id(TDBB tdbb,
|
||||
FOR(REQUEST_HANDLE request)
|
||||
P IN RDB$PROCEDURES WITH P.RDB$PROCEDURE_ID EQ id
|
||||
|
||||
if (!REQUEST(irq_l_proc_id))
|
||||
if (!REQUEST(irq_l_proc_id))
|
||||
REQUEST(irq_l_proc_id) = request;
|
||||
|
||||
procedure = MET_procedure(tdbb, P.RDB$PROCEDURE_ID, flags);
|
||||
@ -2101,7 +2102,6 @@ void MET_parse_sys_trigger(TDBB tdbb, REL relation)
|
||||
if (relation->rel_post_modify)
|
||||
MET_release_triggers(tdbb, &relation->rel_post_modify);
|
||||
|
||||
#ifdef READONLY_DATABASE
|
||||
/* No need to load triggers for ReadOnly databases, since
|
||||
INSERT/DELETE/UPDATE statements are not going to be allowed */
|
||||
|
||||
@ -2109,7 +2109,6 @@ void MET_parse_sys_trigger(TDBB tdbb, REL relation)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif /* READONLY_DATABASE */
|
||||
|
||||
relation->rel_flags |= REL_sys_trigs_being_loaded;
|
||||
|
||||
@ -2210,7 +2209,7 @@ void MET_prepare( TDBB tdbb, TRA transaction, USHORT length, UCHAR * msg)
|
||||
{
|
||||
/**************************************
|
||||
*
|
||||
* M E T _ p r e p a r e
|
||||
* M E T _ p r e p a r e
|
||||
*
|
||||
**************************************
|
||||
*
|
||||
@ -2292,13 +2291,13 @@ PRC MET_procedure(TDBB tdbb, int id, USHORT flags)
|
||||
dbb->dbb_flags |= DBB_sp_rec_mutex_init;
|
||||
}
|
||||
THREAD_EXIT;
|
||||
|
||||
|
||||
if (THD_rec_mutex_lock(&dbb->dbb_sp_rec_mutex))
|
||||
{
|
||||
THREAD_ENTER;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
THREAD_ENTER;
|
||||
|
||||
#endif /* SUPERSERVER */
|
||||
@ -2315,18 +2314,18 @@ PRC MET_procedure(TDBB tdbb, int id, USHORT flags)
|
||||
/* To avoid scanning recursive procedure's blr recursively let's
|
||||
make use of PRC_being_scanned bit. Because this bit is set
|
||||
later in the code, it is not set when we are here first time.
|
||||
If (in case of rec. procedure) we get here second time it is
|
||||
If (in case of rec. procedure) we get here second time it is
|
||||
already set and we return half baked procedure.
|
||||
In case of superserver this code is under the rec. mutex
|
||||
protection, thus the only guy (thread) who can get here and see
|
||||
PRC_being_scanned bit set is the guy which started procedure scan
|
||||
and currently holds the mutex.
|
||||
In case of classic, there is always only one guy and if it
|
||||
In case of classic, there is always only one guy and if it
|
||||
sees PRC_being_scanned bit set it is safe to assume it is here
|
||||
second time.
|
||||
|
||||
If procedure has already been scanned - return. This condition
|
||||
is for those threads that did not find procedure in cach and
|
||||
is for those threads that did not find procedure in cach and
|
||||
came here to get it from disk. But only one was able to lock
|
||||
the mutex and do the scanning, others were waiting. As soon as
|
||||
the first thread releases the mutex another thread gets in and
|
||||
@ -2563,7 +2562,7 @@ REL MET_relation(TDBB tdbb, USHORT id)
|
||||
major_version = (SSHORT) dbb->dbb_ods_version;
|
||||
minor_original = (SSHORT) dbb->dbb_minor_original;
|
||||
|
||||
/* From ODS 9 onwards, the first 128 relation IDS have been
|
||||
/* From ODS 9 onwards, the first 128 relation IDS have been
|
||||
reserved for system relations */
|
||||
if (ENCODE_ODS(major_version, minor_original) < ODS_9_0)
|
||||
max_sys_rel = (USHORT) USER_REL_INIT_ID_ODS8 - 1;
|
||||
@ -2647,7 +2646,7 @@ void MET_remove_procedure( TDBB tdbb, int id, PRC procedure)
|
||||
|
||||
/* Procedure that is being altered may have references
|
||||
to it by other procedures via pointer to current meta
|
||||
data structure, so don't loose the structure or the pointer.
|
||||
data structure, so don't loose the structure or the pointer.
|
||||
if (!(procedure->prc_flags & PRC_being_altered))
|
||||
vector->vec_object [id] = (BLK) NULL_PTR;
|
||||
*/
|
||||
@ -2742,7 +2741,7 @@ void MET_revoke(
|
||||
FIRST 1 P IN RDB$USER_PRIVILEGES WITH
|
||||
P.RDB$RELATION_NAME EQ relation AND
|
||||
P.RDB$PRIVILEGE EQ privilege AND
|
||||
P.RDB$USER EQ revokee
|
||||
P.RDB$USER EQ revokee
|
||||
|
||||
if (!REQUEST(irq_revoke1))
|
||||
REQUEST(irq_revoke1) = request;
|
||||
@ -2764,7 +2763,7 @@ void MET_revoke(
|
||||
P IN RDB$USER_PRIVILEGES WITH
|
||||
P.RDB$RELATION_NAME EQ relation AND
|
||||
P.RDB$PRIVILEGE EQ privilege AND
|
||||
P.RDB$GRANTOR EQ revokee
|
||||
P.RDB$GRANTOR EQ revokee
|
||||
|
||||
if (!REQUEST(irq_revoke2))
|
||||
REQUEST(irq_revoke2) = request;
|
||||
@ -3103,11 +3102,11 @@ void MET_scan_relation( TDBB tdbb, REL relation)
|
||||
ALL_release((FRB)csb);
|
||||
}
|
||||
|
||||
/* release any triggers in case of a rescan, but not if the rescan
|
||||
/* release any triggers in case of a rescan, but not if the rescan
|
||||
hapenned while system triggers were being loaded. */
|
||||
|
||||
if (!(relation->rel_flags & REL_sys_trigs_being_loaded)) {
|
||||
/* if we are scanning a system relation during loading the system
|
||||
/* if we are scanning a system relation during loading the system
|
||||
triggers, (during parsing its blr actually), we must not release the
|
||||
existing system triggers; because we have already set the
|
||||
relation->rel_flag to not have REL_sys_trig, so these
|
||||
@ -3115,7 +3114,7 @@ void MET_scan_relation( TDBB tdbb, REL relation)
|
||||
|
||||
/* We have just loaded the triggers onto the local vector triggers.
|
||||
Its now time to place them at their rightful place ie the relation
|
||||
block.
|
||||
block.
|
||||
*/
|
||||
tmp_vector = relation->rel_pre_store;
|
||||
relation->rel_pre_store = triggers[TRIGGER_PRE_STORE];
|
||||
@ -3177,7 +3176,7 @@ TEXT *MET_trigger_msg(TDBB tdbb, TEXT * name, USHORT number)
|
||||
FOR(REQUEST_HANDLE request)
|
||||
MSG IN RDB$TRIGGER_MESSAGES WITH
|
||||
MSG.RDB$TRIGGER_NAME EQ name AND
|
||||
MSG.RDB$MESSAGE_NUMBER EQ number
|
||||
MSG.RDB$MESSAGE_NUMBER EQ number
|
||||
|
||||
if (!REQUEST(irq_s_msgs))
|
||||
REQUEST(irq_s_msgs) = request;
|
||||
@ -3242,8 +3241,8 @@ void MET_update_transaction( TDBB tdbb, TRA transaction, USHORT flag)
|
||||
request = (BLK) CMP_find_request(tdbb, irq_m_trans, IRQ_REQUESTS);
|
||||
|
||||
FOR(REQUEST_HANDLE request)
|
||||
X IN RDB$TRANSACTIONS
|
||||
WITH X.RDB$TRANSACTION_ID EQ transaction->tra_number
|
||||
X IN RDB$TRANSACTIONS
|
||||
WITH X.RDB$TRANSACTION_ID EQ transaction->tra_number
|
||||
|
||||
if (!REQUEST(irq_m_trans))
|
||||
REQUEST(irq_m_trans) = request;
|
||||
@ -3445,7 +3444,7 @@ static BOOLEAN get_type( TDBB tdbb, SSHORT * id, UCHAR * name, UCHAR * field)
|
||||
FOR(REQUEST_HANDLE handle)
|
||||
FIRST 1 T IN RDB$TYPES WITH
|
||||
T.RDB$FIELD_NAME EQ field AND
|
||||
T.RDB$TYPE_NAME EQ buffer
|
||||
T.RDB$TYPE_NAME EQ buffer
|
||||
|
||||
found = TRUE;
|
||||
*id = T.RDB$TYPE;
|
||||
@ -3465,9 +3464,9 @@ static void lookup_view_contexts( TDBB tdbb, REL view)
|
||||
**************************************
|
||||
*
|
||||
* Functional description
|
||||
* Lookup view contexts and store in a linked
|
||||
* Lookup view contexts and store in a linked
|
||||
* list on the relation block.
|
||||
*
|
||||
*
|
||||
**************************************/
|
||||
DBB dbb;
|
||||
BLK request;
|
||||
@ -3484,7 +3483,7 @@ static void lookup_view_contexts( TDBB tdbb, REL view)
|
||||
FOR(REQUEST_HANDLE request)
|
||||
V IN RDB$VIEW_RELATIONS WITH
|
||||
V.RDB$VIEW_NAME EQ view->rel_name
|
||||
SORTED BY V.RDB$VIEW_CONTEXT
|
||||
SORTED BY V.RDB$VIEW_CONTEXT
|
||||
|
||||
if (!REQUEST(irq_view_context))
|
||||
REQUEST(irq_view_context) = request;
|
||||
@ -3755,7 +3754,7 @@ static BOOLEAN resolve_charset_and_collation(
|
||||
* NULL means use the default collation for (charset).
|
||||
*
|
||||
* Outputs:
|
||||
* (*id)
|
||||
* (*id)
|
||||
* Set to character set specified by this name.
|
||||
*
|
||||
* Return:
|
||||
@ -3794,7 +3793,7 @@ static BOOLEAN resolve_charset_and_collation(
|
||||
|
||||
FOR(REQUEST_HANDLE handle)
|
||||
FIRST 1 CS IN RDB$CHARACTER_SETS
|
||||
WITH CS.RDB$CHARACTER_SET_NAME EQ charset
|
||||
WITH CS.RDB$CHARACTER_SET_NAME EQ charset
|
||||
|
||||
found = TRUE;
|
||||
*id = CS.RDB$CHARACTER_SET_ID;
|
||||
@ -3808,7 +3807,7 @@ static BOOLEAN resolve_charset_and_collation(
|
||||
{
|
||||
FOR(REQUEST_HANDLE handle)
|
||||
FIRST 1 COL IN RDB$COLLATIONS
|
||||
WITH COL.RDB$COLLATION_NAME EQ collation
|
||||
WITH COL.RDB$COLLATION_NAME EQ collation
|
||||
|
||||
found = TRUE;
|
||||
*id = COL.RDB$CHARACTER_SET_ID;
|
||||
@ -3826,7 +3825,7 @@ static BOOLEAN resolve_charset_and_collation(
|
||||
WITH AL1.RDB$FIELD_NAME EQ "RDB$CHARACTER_SET_NAME"
|
||||
AND AL1.RDB$TYPE_NAME EQ charset
|
||||
AND COL.RDB$COLLATION_NAME EQ collation
|
||||
AND AL1.RDB$TYPE EQ CS.RDB$CHARACTER_SET_ID
|
||||
AND AL1.RDB$TYPE EQ CS.RDB$CHARACTER_SET_ID
|
||||
|
||||
found = TRUE;
|
||||
*id = CS.RDB$CHARACTER_SET_ID;
|
||||
@ -3909,7 +3908,7 @@ static void store_dependencies(TDBB tdbb,
|
||||
*
|
||||
* Functional description
|
||||
* Store records in RDB$DEPENDENCIES
|
||||
* corresponding to the objects found during
|
||||
* corresponding to the objects found during
|
||||
* compilation of blr for a trigger, view, etc.
|
||||
*
|
||||
**************************************/
|
||||
@ -4088,9 +4087,9 @@ static BOOLEAN verify_TRG_ignore_perm(TDBB tdbb, TEXT* trig_name)
|
||||
* Functional description
|
||||
* Return TRUE if this trigger can go through without any permission
|
||||
* checks. Currently, the only class of triggers that can go
|
||||
* through without permission checks are
|
||||
* through without permission checks are
|
||||
* (a) two system triggers (RDB$TRIGGERS_34 and RDB$TRIGGERS_35)
|
||||
* (b) those defined for referential integrity actions such as,
|
||||
* (b) those defined for referential integrity actions such as,
|
||||
* set null, set default, and cascade.
|
||||
*
|
||||
**************************************/
|
||||
@ -4144,4 +4143,4 @@ static BOOLEAN verify_TRG_ignore_perm(TDBB tdbb, TEXT* trig_name)
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
}
|
@ -15,6 +15,9 @@
|
||||
*
|
||||
* All Rights Reserved.
|
||||
* Contributor(s): ______________________________________.
|
||||
* 2001.07.06 Sean Leyne - Code Cleanup, removed "#ifdef READONLY_DATABASE"
|
||||
* conditionals, as the engine now fully supports
|
||||
* readonly databases.
|
||||
*/
|
||||
#include "../jrd/ib_stdio.h"
|
||||
#include <fcntl.h>
|
||||
@ -396,18 +399,15 @@ FIL PIO_open(dbb, string, length, trace_flag, connection, file_name,
|
||||
break;
|
||||
|
||||
if (desc == -1) {
|
||||
#ifdef READONLY_DATABASE
|
||||
/* Try opening the database file in ReadOnly mode. The database file could
|
||||
* be on a RO medium (CD-ROM etc.). If this fileopen fails, return error.
|
||||
*/
|
||||
if ((desc = NWDFS_open(ptr, O_RDONLY)) == -1) {
|
||||
#endif /* READONLY_DATABASE */
|
||||
ERR_post(isc_io_error,
|
||||
gds_arg_string, "open",
|
||||
gds_arg_cstring, file_length, ERR_string(file_name,
|
||||
file_length),
|
||||
isc_arg_gds, isc_io_open_err, gds_arg_netware, errno, 0);
|
||||
#ifdef READONLY_DATABASE
|
||||
}
|
||||
else {
|
||||
/* If this is the primary file, set DBB flag to indicate that it is
|
||||
@ -418,7 +418,6 @@ FIL PIO_open(dbb, string, length, trace_flag, connection, file_name,
|
||||
if (!dbb->dbb_file)
|
||||
dbb->dbb_flags |= DBB_being_opened_read_only;
|
||||
}
|
||||
#endif /* READONLY_DATABASE */
|
||||
}
|
||||
|
||||
return dfs_setup_file(dbb, string, length, desc);
|
||||
@ -739,7 +738,7 @@ static netware_error(string, file, operation, status_vector)
|
||||
int NWDFS_open(SCHAR * file_name, int access)
|
||||
/**************************************
|
||||
*
|
||||
* N W D F S _ o p e n
|
||||
* N W D F S _ o p e n
|
||||
*
|
||||
**************************************
|
||||
*
|
||||
@ -825,9 +824,9 @@ int NWDFS_write(FIL fil, int length, SCHAR * buffer)
|
||||
starting_sector = fil->dfs_position / BYTES_PER_SECTOR;
|
||||
offset_in_sector = fil->dfs_position % BYTES_PER_SECTOR;
|
||||
|
||||
/* if we are not at sector boundary :
|
||||
/* if we are not at sector boundary :
|
||||
1) read entire sector into temporary buffer
|
||||
2) copy as many bytes as we can from original buffer to temporary buf
|
||||
2) copy as many bytes as we can from original buffer to temporary buf
|
||||
3) re-write sector */
|
||||
|
||||
if (offset_in_sector != 0) {
|
||||
@ -883,7 +882,7 @@ int NWDFS_write(FIL fil, int length, SCHAR * buffer)
|
||||
length -= bytes_written;
|
||||
}
|
||||
|
||||
/* if last bit spills out of last sector
|
||||
/* if last bit spills out of last sector
|
||||
1) read sector into temp buffer
|
||||
2) copy last bit to temporary buffer
|
||||
2) re-write sector */
|
||||
@ -942,7 +941,7 @@ int NWDFS_read(FIL fil, int length, SCHAR * buffer)
|
||||
starting_sector = fil->dfs_position / BYTES_PER_SECTOR;
|
||||
offset_in_sector = fil->dfs_position % BYTES_PER_SECTOR;
|
||||
|
||||
/* if we are not at sector boundary :
|
||||
/* if we are not at sector boundary :
|
||||
1) read entire sector into temporary buffer
|
||||
2) copy bytes from current position to end of sector into buffer */
|
||||
|
||||
@ -967,7 +966,7 @@ int NWDFS_read(FIL fil, int length, SCHAR * buffer)
|
||||
starting_sector++;
|
||||
}
|
||||
|
||||
/* if more than one sector left to read, read all sectors up to last
|
||||
/* if more than one sector left to read, read all sectors up to last
|
||||
sector */
|
||||
|
||||
number_of_sectors = length / BYTES_PER_SECTOR;
|
||||
@ -1038,7 +1037,7 @@ int dfs_write(FIL fil, int starting_sector, int number_of_sectors,
|
||||
SCHAR * buffer)
|
||||
/**************************************
|
||||
*
|
||||
* d f s _ w r i t e
|
||||
* d f s _ w r i t e
|
||||
*
|
||||
**************************************
|
||||
*
|
||||
@ -1065,7 +1064,7 @@ int dfs_write(FIL fil, int starting_sector, int number_of_sectors,
|
||||
byte_offset_in_file = starting_sector * BYTES_PER_SECTOR;
|
||||
starting_block = byte_offset_in_file / fil->dfs_block_size;
|
||||
|
||||
/* if it is on a block boundary and it is not block zero
|
||||
/* if it is on a block boundary and it is not block zero
|
||||
start at previous block */
|
||||
if ((byte_offset_in_file % fil->dfs_block_size) == 0)
|
||||
if (byte_offset_in_file > 0)
|
||||
@ -1157,7 +1156,7 @@ void read_back_and_check(PAG page, BDB bdb, FIL file)
|
||||
written_checksum = page->pag_checksum;
|
||||
|
||||
if (read_checksum != written_checksum) {
|
||||
// ConsolePrintf("read = %d write = %d page = %d\n",
|
||||
// ConsolePrintf("read = %d write = %d page = %d\n",
|
||||
// read_checksum, written_checksum, page_no);
|
||||
Breakpoint(1);
|
||||
}
|
||||
@ -1257,4 +1256,4 @@ int expand_it(FIL fil, int blocks_to_expand, int starting_block)
|
||||
}
|
||||
|
||||
|
||||
} // extern "C"
|
||||
} // extern "C"
|
@ -30,6 +30,11 @@
|
||||
* for use in DPM_gen_id.
|
||||
*/
|
||||
|
||||
/* 2001.07.06 Sean Leyne - Code Cleanup, removed "#ifdef READONLY_DATABASE"
|
||||
* conditionals, as the engine now fully supports
|
||||
* readonly databases.
|
||||
*/
|
||||
|
||||
#include "../jrd/ib_stdio.h"
|
||||
#include <string.h>
|
||||
|
||||
@ -72,11 +77,7 @@ static void find_clump_space(SLONG, WIN *, PAG *, USHORT, SSHORT, UCHAR *,
|
||||
static BOOLEAN find_type(SLONG, WIN *, PAG *, USHORT, USHORT, UCHAR **,
|
||||
UCHAR **);
|
||||
|
||||
#ifdef READONLY_DATABASE
|
||||
#define ERR_POST_IF_DATABASE_IS_READONLY(dbb) {if (dbb->dbb_flags & DBB_read_only) ERR_post (isc_read_only_database, 0);}
|
||||
#else
|
||||
#define ERR_POST_IF_DATABASE_IS_READONLY
|
||||
#endif /* READONLY_DATABASE */
|
||||
|
||||
/* This macro enables the ability of the engine to connect to databases
|
||||
* from ODS 8 up to the latest. If this macro is undefined, the engine
|
||||
@ -108,7 +109,7 @@ static BOOLEAN find_type(SLONG, WIN *, PAG *, USHORT, USHORT, UCHAR **,
|
||||
20 LINUX on sparc systems
|
||||
21 FreeBSD/i386
|
||||
22 NetBSD/i386
|
||||
|
||||
|
||||
*/
|
||||
|
||||
// TMN: Left the APOLLO stuff commented out for historical reference. :-)
|
||||
@ -325,7 +326,7 @@ int PAG_add_clump(
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* delete the entry
|
||||
/* delete the entry
|
||||
|
||||
* Page is marked must write because of precedence problems. Later
|
||||
* on we may allocate a new page and set up a precedence relationship.
|
||||
@ -729,9 +730,7 @@ SLONG PAG_attachment_id(void)
|
||||
JRNDA_SIZE, 0, 0);
|
||||
}
|
||||
CCH_RELEASE(tdbb, &window);
|
||||
#ifdef READONLY_DATABASE
|
||||
}
|
||||
#endif /* READONLY_DATABASE */
|
||||
|
||||
/* Take out lock on attachment id */
|
||||
|
||||
@ -955,7 +954,7 @@ int PAG_get_clump(SLONG page_num, USHORT type, USHORT * len, UCHAR * entry)
|
||||
* TRUE - Found it
|
||||
* FALSE - Not present
|
||||
* RETURNS
|
||||
* value of clump in entry
|
||||
* value of clump in entry
|
||||
* length in len
|
||||
*
|
||||
**************************************/
|
||||
@ -1023,7 +1022,7 @@ void PAG_header(TEXT * file_name, USHORT file_length)
|
||||
and set up to release it in case of error; note
|
||||
that dbb_page_size has not been set yet, so we
|
||||
can't depend on this.
|
||||
|
||||
|
||||
Make sure that buffer is aligned on a page boundary
|
||||
and unit of transfer is a multiple of physical disk
|
||||
sector for raw disk access. */
|
||||
@ -1050,7 +1049,7 @@ void PAG_header(TEXT * file_name, USHORT file_length)
|
||||
file_length), 0);
|
||||
|
||||
#ifdef ODS_8_TO_CURRENT
|
||||
/* This Server understands ODS greater than 8 *ONLY* upto current major
|
||||
/* This Server understands ODS greater than 8 *ONLY* upto current major
|
||||
ODS_VERSION defined in ods.h, Refuse connections to older or newer ODS's */
|
||||
if ((header->hdr_ods_version < ODS_VERSION8)
|
||||
|| (header->hdr_ods_version > ODS_VERSION))
|
||||
@ -1063,20 +1062,20 @@ void PAG_header(TEXT * file_name, USHORT file_length)
|
||||
gds_arg_number, (SLONG) header->hdr_ods_version,
|
||||
gds_arg_number, (SLONG) ODS_VERSION, 0);
|
||||
|
||||
/****
|
||||
Note that if this check is turned on, it should be recoded in order that
|
||||
the Intel platforms can share databases. At present (Feb 95) it is possible
|
||||
to share databases between Windows and NT, but not with NetWare. Sharing
|
||||
databases with OS/2 is unknown and needs to be investigated. The CLASS was
|
||||
initially 8 for all Intel platforms, but was changed after 4.0 was released
|
||||
in order to allow differentiation between databases created on various
|
||||
platforms. This should allow us in future to identify where databases were
|
||||
created. Even when we get to the stage where databases created on PC platforms
|
||||
are sharable between all platforms, it would be useful to identify where they
|
||||
/****
|
||||
Note that if this check is turned on, it should be recoded in order that
|
||||
the Intel platforms can share databases. At present (Feb 95) it is possible
|
||||
to share databases between Windows and NT, but not with NetWare. Sharing
|
||||
databases with OS/2 is unknown and needs to be investigated. The CLASS was
|
||||
initially 8 for all Intel platforms, but was changed after 4.0 was released
|
||||
in order to allow differentiation between databases created on various
|
||||
platforms. This should allow us in future to identify where databases were
|
||||
created. Even when we get to the stage where databases created on PC platforms
|
||||
are sharable between all platforms, it would be useful to identify where they
|
||||
were created for debugging purposes. - Deej 2/6/95
|
||||
|
||||
if (header->hdr_implementation && header->hdr_implementation != CLASS)
|
||||
ERR_post (gds__bad_db_format,
|
||||
ERR_post (gds__bad_db_format,
|
||||
gds_arg_cstring, file_length, ERR_string(file_name, file_length), 0);
|
||||
****/
|
||||
|
||||
@ -1114,7 +1113,6 @@ if (header->hdr_implementation && header->hdr_implementation != CLASS)
|
||||
dbb->dbb_oldest_active = header->hdr_oldest_active;
|
||||
dbb->dbb_oldest_snapshot = header->hdr_oldest_snapshot;
|
||||
|
||||
#ifdef READONLY_DATABASE
|
||||
dbb->dbb_attachment_id = header->hdr_attachment_id;
|
||||
|
||||
if (header->hdr_flags & hdr_read_only) {
|
||||
@ -1136,13 +1134,10 @@ if (header->hdr_implementation && header->hdr_implementation != CLASS)
|
||||
gds_arg_cstring, file_length, ERR_string(file_name,
|
||||
file_length), 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (header->hdr_flags & hdr_force_write) {
|
||||
dbb->dbb_flags |= DBB_force_write;
|
||||
#ifdef READONLY_DATABASE
|
||||
if (!(header->hdr_flags & hdr_read_only))
|
||||
#endif /* READONLY_DATABASE */
|
||||
PIO_force_write(dbb->dbb_file, TRUE);
|
||||
}
|
||||
|
||||
@ -1287,10 +1282,10 @@ void PAG_init2(USHORT shadow_number)
|
||||
file_name = NULL;
|
||||
window.win_page = file->fil_min_page;
|
||||
do {
|
||||
/* note that we do not have to get a read lock on
|
||||
the header page (except for header page 0) because
|
||||
the only time it will be modified is when adding a file,
|
||||
which must be done with an exclusive lock on the database --
|
||||
/* note that we do not have to get a read lock on
|
||||
the header page (except for header page 0) because
|
||||
the only time it will be modified is when adding a file,
|
||||
which must be done with an exclusive lock on the database --
|
||||
if this changes, this policy will have to be reevaluated;
|
||||
at any rate there is a problem with getting a read lock
|
||||
because the corresponding page in the main database file
|
||||
@ -1323,9 +1318,7 @@ void PAG_init2(USHORT shadow_number)
|
||||
break;
|
||||
|
||||
case HDR_sweep_interval:
|
||||
#ifdef READONLY_DATABASE
|
||||
if (!(dbb->dbb_flags & DBB_read_only))
|
||||
#endif
|
||||
MOVE_FAST(p + 2, &dbb->dbb_sweep_interval,
|
||||
sizeof(SLONG));
|
||||
break;
|
||||
@ -1515,7 +1508,7 @@ void PAG_release_page(SLONG number, SLONG prior_page)
|
||||
pip_window.win_flags = 0;
|
||||
|
||||
/* if shared cache is being used, the page which is being freed up
|
||||
* may have a journal buffer which in no longer valid after the
|
||||
* may have a journal buffer which in no longer valid after the
|
||||
* page has been freed up. Zero out the journal buffer.
|
||||
* It is possible that the shared cache manager will write out the
|
||||
* record as part of a scan.
|
||||
@ -1675,7 +1668,7 @@ void PAG_set_db_readonly(DBB dbb, SSHORT flag)
|
||||
header = (HDR) CCH_FETCH(tdbb, &window, LCK_write, pag_header);
|
||||
|
||||
if (!flag) {
|
||||
/* If the database is transitioning from RO to RW, reset the
|
||||
/* If the database is transitioning from RO to RW, reset the
|
||||
* in-memory DBB flag which indicates that the database is RO.
|
||||
* This will allow the CCH subsystem to allow pages to be MARK'ed
|
||||
* for WRITE operations
|
||||
@ -2054,4 +2047,4 @@ static BOOLEAN find_type(
|
||||
}
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
} // extern "C"
|
@ -19,6 +19,9 @@
|
||||
*
|
||||
* All Rights Reserved.
|
||||
* Contributor(s): ______________________________________.
|
||||
* 2001.07.06 Sean Leyne - Code Cleanup, removed "#ifdef READONLY_DATABASE"
|
||||
* conditionals, as the engine now fully supports
|
||||
* readonly databases.
|
||||
*/
|
||||
|
||||
#include "../jrd/jrd.h"
|
||||
@ -76,9 +79,9 @@ LCK RLCK_lock_record(RPB * rpb,
|
||||
|
||||
tdbb = GET_THREAD_DATA;
|
||||
|
||||
/*
|
||||
/*
|
||||
if the record is trying to be locked, check
|
||||
whether the record has already been updated on page
|
||||
whether the record has already been updated on page
|
||||
by a transaction whose updates we cannot see yet--
|
||||
in which case we effectively cannot get the lock */
|
||||
|
||||
@ -140,27 +143,27 @@ LCK RLCK_lock_record_implicit(TRA transaction,
|
||||
lock->lck_ast = ast;
|
||||
lock->lck_object = ast_arg;
|
||||
|
||||
/* To ensure that relation and record locks respect each other,
|
||||
/* To ensure that relation and record locks respect each other,
|
||||
utilize a multigranularity locking scheme, establishing
|
||||
an interest lock level in the parent relation according to
|
||||
an interest lock level in the parent relation according to
|
||||
the following scheme:
|
||||
read lock on record := protected read
|
||||
(implies) interest read lock on relation := shared read
|
||||
write lock on record := exclusive
|
||||
(implies) interest write lock on relation := shared write
|
||||
Then as long as PR and EX locks are used to implement read
|
||||
and write locking on relations, the relation locks will
|
||||
(implies) interest write lock on relation := shared write
|
||||
Then as long as PR and EX locks are used to implement read
|
||||
and write locking on relations, the relation locks will
|
||||
be respected.
|
||||
|
||||
This also guarantees that implicit record locks won't result
|
||||
in interest locks being taken out, since implicit record locks
|
||||
are SW. Relations are already implicitly reserved in
|
||||
This also guarantees that implicit record locks won't result
|
||||
in interest locks being taken out, since implicit record locks
|
||||
are SW. Relations are already implicitly reserved in
|
||||
RLCK_reserve_relation(), so there is no need for an additional
|
||||
interest lock.
|
||||
implicit read lock on record := NO LOCK
|
||||
(implies) NO interest read lock on relation
|
||||
(implies) NO interest read lock on relation
|
||||
implicit write lock on record := shared write
|
||||
(implies) interest write lock on relation := shared write
|
||||
(implies) interest write lock on relation := shared write
|
||||
*/
|
||||
|
||||
relation = rpb->rpb_relation;
|
||||
@ -175,7 +178,7 @@ LCK RLCK_lock_record_implicit(TRA transaction,
|
||||
relation->rel_lock_total++;
|
||||
}
|
||||
|
||||
/* first attempt to get the parent lock then get the record lock,
|
||||
/* first attempt to get the parent lock then get the record lock,
|
||||
using two-phase locking to help prevent deadlocks */
|
||||
|
||||
if (interest_lock_level
|
||||
@ -207,7 +210,7 @@ LCK RLCK_lock_relation(REL relation,
|
||||
LCK lock;
|
||||
|
||||
/* allocate a relation lock hanging off the attachment
|
||||
block, then keep a count of the number of times it
|
||||
block, then keep a count of the number of times it
|
||||
is used so that we know when to release it (bug #7478) */
|
||||
|
||||
lock = attachment_relation_lock(relation);
|
||||
@ -309,13 +312,13 @@ LCK RLCK_record_locking(REL relation)
|
||||
lock->lck_key.lck_long = relation->rel_id;
|
||||
relation->rel_record_locking = lock;
|
||||
|
||||
/* set up an ast to start record locking if
|
||||
/* set up an ast to start record locking if
|
||||
someone gets an incompatible lock */
|
||||
|
||||
lock->lck_ast = start_record_locking;
|
||||
lock->lck_object = (BLK) relation;
|
||||
|
||||
/* now attempt to get a PR on the lock to detect when
|
||||
/* now attempt to get a PR on the lock to detect when
|
||||
anyone locks a record explicitly */
|
||||
|
||||
LCK_lock(tdbb, _non_blocking(lock, LCK_PR, FALSE));
|
||||
@ -346,7 +349,7 @@ void RLCK_release_lock(LCK lock)
|
||||
ERR_post(gds__bad_lock_handle, 0);
|
||||
if (((BLK) lock)->blk_type != (UCHAR) type_lck)
|
||||
ERR_post(gds__bad_lock_handle, 0);
|
||||
/* now use the lock type to determine the type
|
||||
/* now use the lock type to determine the type
|
||||
of lock to release */
|
||||
if (lock->lck_type == LCK_relation)
|
||||
RLCK_unlock_relation(0, (REL) lock->lck_object);
|
||||
@ -412,10 +415,8 @@ LCK RLCK_reserve_relation(TDBB tdbb,
|
||||
USHORT result;
|
||||
if (transaction->tra_flags & TRA_system)
|
||||
return NULL;
|
||||
#ifdef READONLY_DATABASE
|
||||
if (write_flag && (tdbb->tdbb_database->dbb_flags & DBB_read_only))
|
||||
ERR_post(isc_read_only_database, 0);
|
||||
#endif /* READONLY_DATABASE */
|
||||
if (write_flag && (transaction->tra_flags & TRA_readonly))
|
||||
ERR_post(gds__read_only_trans, 0);
|
||||
lock = RLCK_transaction_relation_lock(transaction, relation);
|
||||
@ -583,7 +584,7 @@ LCK RLCK_transaction_relation_lock(TRA transaction, REL relation)
|
||||
**************************************
|
||||
*
|
||||
* Functional description
|
||||
* Take out a relation lock within the context of
|
||||
* Take out a relation lock within the context of
|
||||
* a transaction.
|
||||
*
|
||||
**************************************/
|
||||
@ -600,7 +601,7 @@ LCK RLCK_transaction_relation_lock(TRA transaction, REL relation)
|
||||
return lock;
|
||||
lock = allocate_relation_lock(transaction->tra_pool, relation);
|
||||
lock->lck_owner = (BLK) transaction;
|
||||
/* for relations locked within a transaction, add a second level of
|
||||
/* for relations locked within a transaction, add a second level of
|
||||
compatibility within the intra-process lock manager which specifies
|
||||
that relation locks are incompatible with locks taken out by other
|
||||
transactions, if a transaction is specified */
|
||||
@ -621,7 +622,7 @@ void RLCK_unlock_record(LCK lock, RPB * rpb)
|
||||
*
|
||||
* Functional description
|
||||
* Unlock the specified record lock, or if
|
||||
* it's not available use the current record
|
||||
* it's not available use the current record
|
||||
* in the specified record parameter block.
|
||||
*
|
||||
**************************************/
|
||||
@ -665,7 +666,7 @@ void RLCK_unlock_record_implicit(LCK lock, RPB * rpb)
|
||||
**************************************
|
||||
*
|
||||
* Functional description
|
||||
* Unlock a record-level lock.
|
||||
* Unlock a record-level lock.
|
||||
*
|
||||
**************************************/
|
||||
REL relation;
|
||||
@ -686,7 +687,7 @@ void RLCK_unlock_record_implicit(LCK lock, RPB * rpb)
|
||||
|
||||
/* handle the release half of the multigranularity locking scheme:
|
||||
if there are no more write locks, downgrade the interest
|
||||
lock on the parent relation; if there are no more read or
|
||||
lock on the parent relation; if there are no more read or
|
||||
write locks, release the lock entirely
|
||||
|
||||
For implicit locks, there are no relation intrest locks.
|
||||
@ -746,8 +747,8 @@ void RLCK_unlock_relation(LCK lock, REL relation)
|
||||
break;
|
||||
if (!lock)
|
||||
return;
|
||||
/* decrement the use count; if it goes to zero,
|
||||
there are no further locks taken out in this
|
||||
/* decrement the use count; if it goes to zero,
|
||||
there are no further locks taken out in this
|
||||
attachment so we can release the lock (bug #7478) */
|
||||
if (lock->lck_count > 1) {
|
||||
lock->lck_count--;
|
||||
@ -806,12 +807,12 @@ static LCK allocate_record_lock(TRA transaction, RPB * rpb)
|
||||
}
|
||||
|
||||
/* indicate that this lock should be compatible at the attachment
|
||||
level--meaning that two record locks taken out within the same
|
||||
level--meaning that two record locks taken out within the same
|
||||
attachment should always be compatible; ditto for the interest lock */
|
||||
|
||||
lock->lck_compatible = (BLK) attachment;
|
||||
lock->lck_parent->lck_compatible = (BLK) attachment;
|
||||
/* link in the record lock with the other record locks
|
||||
/* link in the record lock with the other record locks
|
||||
taken out by this attachment */
|
||||
lock->lck_att_next = attachment->att_record_locks;
|
||||
attachment->att_record_locks = lock;
|
||||
@ -848,7 +849,7 @@ static LCK allocate_relation_lock(PLB pool, REL relation)
|
||||
lock->lck_type = LCK_relation;
|
||||
lock->lck_owner_handle = LCK_get_owner_handle(tdbb, lock->lck_type);
|
||||
lock->lck_parent = dbb->dbb_lock;
|
||||
/* enter all relation locks into the intra-process lock manager and treat
|
||||
/* enter all relation locks into the intra-process lock manager and treat
|
||||
them as compatible within the attachment according to IPLM rules */
|
||||
lock->lck_compatible = (BLK) tdbb->tdbb_attachment;
|
||||
/* the lck_object is used here to find the relation
|
||||
@ -935,7 +936,7 @@ static LCK find_record_lock(RPB * rpb)
|
||||
**************************************
|
||||
*
|
||||
* Functional description
|
||||
* Find the record lock previously
|
||||
* Find the record lock previously
|
||||
* defined for a record.
|
||||
*
|
||||
**************************************/
|
||||
@ -965,7 +966,7 @@ static BOOLEAN obtain_lock(TRA transaction, LCK lock, USHORT lock_level)
|
||||
**************************************
|
||||
*
|
||||
* Functional description
|
||||
* Obtain the specified lock at the
|
||||
* Obtain the specified lock at the
|
||||
* necessary level.
|
||||
*
|
||||
**************************************/
|
||||
@ -1006,7 +1007,7 @@ static void start_record_locking(REL relation)
|
||||
**************************************/
|
||||
LCK record_locking;
|
||||
record_locking = relation->rel_record_locking;
|
||||
/* if we have shared write, it means we have records
|
||||
/* if we have shared write, it means we have records
|
||||
locked; we won't give up this lock for anyone! */
|
||||
if (record_locking->lck_physical == LCK_SW)
|
||||
return;
|
||||
@ -1014,4 +1015,4 @@ static void start_record_locking(REL relation)
|
||||
LCK_release(NULL_TDBB, record_locking);
|
||||
ISC_ast_exit();
|
||||
}
|
||||
#endif
|
||||
#endif
|
@ -19,6 +19,9 @@
|
||||
*
|
||||
* All Rights Reserved.
|
||||
* Contributor(s): ______________________________________.
|
||||
* 2001.07.06 Sean Leyne - Code Cleanup, removed "#ifdef READONLY_DATABASE"
|
||||
* conditionals, as the engine now fully supports
|
||||
* readonly databases.
|
||||
*/
|
||||
|
||||
#include "../jrd/ibsetjmp.h"
|
||||
@ -153,7 +156,6 @@ BOOLEAN TRA_active_transactions(TDBB tdbb, DBB dbb)
|
||||
oldest = dbb->dbb_oldest_transaction;
|
||||
active = MAX(dbb->dbb_oldest_active, dbb->dbb_oldest_transaction);
|
||||
#else
|
||||
#ifdef READONLY_DATABASE
|
||||
if (dbb->dbb_flags & DBB_read_only) {
|
||||
number = dbb->dbb_next_transaction;
|
||||
oldest = dbb->dbb_oldest_transaction;
|
||||
@ -168,14 +170,6 @@ BOOLEAN TRA_active_transactions(TDBB tdbb, DBB dbb)
|
||||
MAX(header->hdr_oldest_active, header->hdr_oldest_transaction);
|
||||
CCH_RELEASE(tdbb, &window);
|
||||
}
|
||||
#else
|
||||
window.win_page = HEADER_PAGE;
|
||||
header = (HDR) CCH_FETCH(tdbb, &window, LCK_read, pag_header);
|
||||
number = header->hdr_next_transaction;
|
||||
oldest = header->hdr_oldest_transaction;
|
||||
active = MAX(header->hdr_oldest_active, header->hdr_oldest_transaction);
|
||||
CCH_RELEASE(tdbb, &window);
|
||||
#endif /* READONLY_DATABASE */
|
||||
#endif /* SUPERSERVER_V2 */
|
||||
|
||||
base = oldest & ~TRA_MASK;
|
||||
@ -245,11 +239,9 @@ void TRA_cleanup(TDBB tdbb)
|
||||
dbb = tdbb->tdbb_database;
|
||||
CHECK_DBB(dbb);
|
||||
|
||||
#ifdef READONLY_DATABASE
|
||||
/* Return without cleaning up the TIP's for a ReadOnly database */
|
||||
if (dbb->dbb_flags & DBB_read_only)
|
||||
return;
|
||||
#endif /* READONLY_DATABASE */
|
||||
|
||||
/* First, make damn sure there are no outstanding transactions */
|
||||
|
||||
@ -536,9 +528,9 @@ int TRA_fetch_state(TDBB tdbb, SLONG number)
|
||||
**************************************
|
||||
*
|
||||
* Functional description
|
||||
* Physically fetch the state of a given
|
||||
* transaction on the transaction inventory
|
||||
* page.
|
||||
* Physically fetch the state of a given
|
||||
* transaction on the transaction inventory
|
||||
* page.
|
||||
*
|
||||
**************************************/
|
||||
DBB dbb;
|
||||
@ -583,7 +575,7 @@ void TRA_get_inventory(TDBB tdbb, UCHAR * bit_vector, ULONG base, ULONG top)
|
||||
* Get an inventory of the state of all transactions
|
||||
* between the base and top transactions passed.
|
||||
* To get a consistent view of the transaction
|
||||
* inventory (in case we ever implement sub-transactions),
|
||||
* inventory (in case we ever implement sub-transactions),
|
||||
* do handoffs to read the pages in order.
|
||||
*
|
||||
**************************************/
|
||||
@ -650,7 +642,7 @@ int TRA_get_state(TDBB tdbb, SLONG number)
|
||||
**************************************
|
||||
*
|
||||
* Functional description
|
||||
* Get the state of a given transaction on the
|
||||
* Get the state of a given transaction on the
|
||||
* transaction inventory page.
|
||||
*
|
||||
**************************************/
|
||||
@ -884,8 +876,8 @@ BOOLEAN TRA_precommited(TDBB tdbb, SLONG old_number, SLONG new_number)
|
||||
**************************************
|
||||
*
|
||||
* Functional description
|
||||
* Maintain a vector of active precommitted
|
||||
* transactions. If old_number <> new_number
|
||||
* Maintain a vector of active precommitted
|
||||
* transactions. If old_number <> new_number
|
||||
* then swap old_number with new_number in
|
||||
* the vector. If old_number equals new_number
|
||||
* then test for that number's presence in
|
||||
@ -952,7 +944,7 @@ void TRA_prepare(TDBB tdbb, TRA transaction, USHORT length, UCHAR * msg)
|
||||
if (transaction->tra_flags & TRA_invalidated)
|
||||
ERR_post(gds_trans_invalid, 0);
|
||||
|
||||
/* If there's a transaction description message, log it to RDB$TRANSACTION
|
||||
/* If there's a transaction description message, log it to RDB$TRANSACTION
|
||||
We should only log a message to RDB$TRANSACTION if there is a message
|
||||
to log (if the length = 0, we won't log the transaction in RDB$TRANSACTION)
|
||||
These messages are used to recover transactions in limbo. The message indicates
|
||||
@ -962,7 +954,7 @@ void TRA_prepare(TDBB tdbb, TRA transaction, USHORT length, UCHAR * msg)
|
||||
|
||||
/* Make sure that if msg is NULL there is no length. The two
|
||||
should go hand in hand
|
||||
msg == NULL || *msg == NULL
|
||||
msg == NULL || *msg == NULL
|
||||
*/
|
||||
assert(!(!msg && length) || (msg && (!*msg && length)));
|
||||
|
||||
@ -1028,11 +1020,9 @@ TRA TRA_reconnect(TDBB tdbb, UCHAR * id, USHORT length)
|
||||
dbb = tdbb->tdbb_database;
|
||||
CHECK_DBB(dbb);
|
||||
|
||||
#ifdef READONLY_DATABASE
|
||||
/* Cannot work on limbo transactions for ReadOnly database */
|
||||
if (dbb->dbb_flags & DBB_read_only)
|
||||
ERR_post(isc_read_only_database, 0);
|
||||
#endif /* READONLY_DATABASE */
|
||||
|
||||
|
||||
tdbb->tdbb_default = ALL_pool();
|
||||
@ -1185,7 +1175,7 @@ void TRA_rollback(TDBB tdbb, TRA transaction, USHORT retaining_flag)
|
||||
#ifndef GATEWAY
|
||||
|
||||
/* If there is a transaction-level savepoint, then use that to undo
|
||||
this transaction's work and mark it committed in the TIP page
|
||||
this transaction's work and mark it committed in the TIP page
|
||||
instead (avoids a need for a database sweep). */
|
||||
|
||||
if (transaction->tra_save_point) {
|
||||
@ -1287,13 +1277,11 @@ void TRA_set_state(TDBB tdbb, TRA transaction, SLONG number, SSHORT state)
|
||||
transaction->tra_number == number &&
|
||||
transaction->tra_flags & TRA_precommitted) return;
|
||||
|
||||
#ifdef READONLY_DATABASE
|
||||
/* If it is a ReadOnly DB, set the new state in the TIP cache and return */
|
||||
if ((dbb->dbb_flags & DBB_read_only) && dbb->dbb_tip_cache) {
|
||||
TPC_set_state(tdbb, number, state);
|
||||
return;
|
||||
}
|
||||
#endif /* READONLY_DATABASE */
|
||||
|
||||
trans_per_tip = dbb->dbb_pcontrol->pgc_tpt;
|
||||
sequence = number / trans_per_tip;
|
||||
@ -1424,7 +1412,7 @@ int TRA_snapshot_state(TDBB tdbb, TRA trans, SLONG number)
|
||||
if (number == trans->tra_number)
|
||||
return tra_us;
|
||||
|
||||
/* If the transaction is older than the oldest
|
||||
/* If the transaction is older than the oldest
|
||||
interesting transaction, it must be committed. */
|
||||
|
||||
if (number < trans->tra_oldest)
|
||||
@ -1436,7 +1424,7 @@ int TRA_snapshot_state(TDBB tdbb, TRA trans, SLONG number)
|
||||
return tra_committed;
|
||||
|
||||
/* If the transaction is a commited sub-transction - do the easy lookup.
|
||||
Since this is not the most common case, and looking up the
|
||||
Since this is not the most common case, and looking up the
|
||||
transaction cache for read committed transactions is equally
|
||||
fast, just to that instead. */
|
||||
|
||||
@ -1522,7 +1510,6 @@ TRA TRA_start(TDBB tdbb, int tpb_length, SCHAR * tpb)
|
||||
oldest_snapshot = dbb->dbb_oldest_snapshot;
|
||||
|
||||
#else /* SUPERSERVER_V2 */
|
||||
#ifdef READONLY_DATABASE
|
||||
if (dbb->dbb_flags & DBB_read_only) {
|
||||
number = ++dbb->dbb_next_transaction;
|
||||
oldest = dbb->dbb_oldest_transaction;
|
||||
@ -1539,14 +1526,6 @@ TRA TRA_start(TDBB tdbb, int tpb_length, SCHAR * tpb)
|
||||
oldest_active = header->hdr_oldest_active;
|
||||
oldest_snapshot = header->hdr_oldest_snapshot;
|
||||
}
|
||||
#else
|
||||
header = bump_transaction_id(tdbb, &window);
|
||||
number = header->hdr_next_transaction;
|
||||
oldest = header->hdr_oldest_transaction;
|
||||
active = MAX(header->hdr_oldest_active, header->hdr_oldest_transaction);
|
||||
oldest_active = header->hdr_oldest_active;
|
||||
oldest_snapshot = header->hdr_oldest_snapshot;
|
||||
#endif /* READONLY_DATABASE */
|
||||
|
||||
#endif /* SUPERSERVER_V2 */
|
||||
|
||||
@ -1594,9 +1573,7 @@ TRA TRA_start(TDBB tdbb, int tpb_length, SCHAR * tpb)
|
||||
|
||||
if (!LCK_lock_non_blocking(tdbb, lock, LCK_write, TRUE)) {
|
||||
#ifndef SUPERSERVER_V2
|
||||
#ifdef READONLY_DATABASE
|
||||
if (!(dbb->dbb_flags & DBB_read_only))
|
||||
#endif /* READONLY_DATABASE */
|
||||
CCH_RELEASE(tdbb, &window);
|
||||
#endif
|
||||
ALL_release(reinterpret_cast < frb * >(trans));
|
||||
@ -1609,9 +1586,7 @@ TRA TRA_start(TDBB tdbb, int tpb_length, SCHAR * tpb)
|
||||
TRA_link_transaction(tdbb, trans);
|
||||
|
||||
#ifndef SUPERSERVER_V2
|
||||
#ifdef READONLY_DATABASE
|
||||
if (!(dbb->dbb_flags & DBB_read_only))
|
||||
#endif /* READONLY_DATABASE */
|
||||
CCH_RELEASE(tdbb, &window);
|
||||
#endif
|
||||
|
||||
@ -1619,12 +1594,10 @@ TRA TRA_start(TDBB tdbb, int tpb_length, SCHAR * tpb)
|
||||
TRA_link_transaction(tdbb, trans);
|
||||
#endif
|
||||
|
||||
#ifdef READONLY_DATABASE
|
||||
if (dbb->dbb_flags & DBB_read_only) {
|
||||
/* Set transaction flags to TRA_precommitted, TRA_readonly */
|
||||
trans->tra_flags |= (TRA_readonly | TRA_precommitted);
|
||||
}
|
||||
#endif /* READONLY_DATABASE */
|
||||
|
||||
#ifndef GATEWAY
|
||||
/* Next, take a snapshot of all transactions between the oldest interesting
|
||||
@ -1681,7 +1654,7 @@ TRA TRA_start(TDBB tdbb, int tpb_length, SCHAR * tpb)
|
||||
oldest_active = MIN(oldest_active, active);
|
||||
|
||||
/* Find the oldest record version that cannot be garbage collected yet
|
||||
by taking the minimum of all all versions needed by all active
|
||||
by taking the minimum of all all versions needed by all active
|
||||
transactions. */
|
||||
|
||||
if (data < trans->tra_oldest_active)
|
||||
@ -1874,11 +1847,9 @@ int TRA_sweep(TDBB tdbb, TRA trans)
|
||||
dbb = tdbb->tdbb_database;
|
||||
CHECK_DBB(dbb);
|
||||
|
||||
#ifdef READONLY_DATABASE
|
||||
/* No point trying to sweep a ReadOnly database */
|
||||
if (dbb->dbb_flags & DBB_read_only)
|
||||
return FALSE;
|
||||
#endif /* READONLY_DATABASE */
|
||||
|
||||
if (dbb->dbb_flags & DBB_sweep_in_progress)
|
||||
return TRUE;
|
||||
@ -2195,11 +2166,9 @@ static SLONG bump_transaction_id(TDBB tdbb, WIN * window)
|
||||
|
||||
number = ++dbb->dbb_next_transaction;
|
||||
|
||||
#ifdef READONLY_DATABASE
|
||||
/* No need to write TID onto the TIP page, for a RO DB */
|
||||
if (dbb->dbb_flags & DBB_read_only)
|
||||
return number;
|
||||
#endif /* READONLY_DATABASE */
|
||||
|
||||
/* If this is the first transaction on a TIP, allocate the TIP now. */
|
||||
|
||||
@ -2447,7 +2416,7 @@ static void downgrade_lock(TRA transaction)
|
||||
* Someone is trying to establish an interest
|
||||
* lock in this transaction. Downgrade to a
|
||||
* shared write, to allow transactions to wait
|
||||
* on this transaction or, alternatively, be
|
||||
* on this transaction or, alternatively, be
|
||||
* notified if and when the transaction commits.
|
||||
*
|
||||
**************************************/
|
||||
@ -2680,8 +2649,8 @@ static void restart_requests(TDBB tdbb, TRA trans)
|
||||
**************************************
|
||||
*
|
||||
* Functional description
|
||||
* Restart all requests in the current
|
||||
* attachment to utilize the passed
|
||||
* Restart all requests in the current
|
||||
* attachment to utilize the passed
|
||||
* transaction.
|
||||
*
|
||||
**************************************/
|
||||
@ -2756,17 +2725,12 @@ static void retain_context(TDBB tdbb, TRA transaction, USHORT commit)
|
||||
#ifdef SUPERSERVER_V2
|
||||
new_number = bump_transaction_id(tdbb, &window);
|
||||
#else
|
||||
#ifdef READONLY_DATABASE
|
||||
if (dbb->dbb_flags & DBB_read_only)
|
||||
new_number = ++dbb->dbb_next_transaction;
|
||||
else {
|
||||
header = bump_transaction_id(tdbb, &window);
|
||||
new_number = header->hdr_next_transaction;
|
||||
}
|
||||
#else
|
||||
header = bump_transaction_id(tdbb, &window);
|
||||
new_number = header->hdr_next_transaction;
|
||||
#endif /* READONLY_DATABASE */
|
||||
#endif
|
||||
|
||||
if (old_lock = transaction->tra_lock) {
|
||||
@ -2784,9 +2748,7 @@ static void retain_context(TDBB tdbb, TRA transaction, USHORT commit)
|
||||
|
||||
if (!LCK_lock_non_blocking(tdbb, new_lock, LCK_write, TRUE)) {
|
||||
#ifndef SUPERSERVER_V2
|
||||
#ifdef READONLY_DATABASE
|
||||
if (!(dbb->dbb_flags & DBB_read_only))
|
||||
#endif
|
||||
CCH_RELEASE(tdbb, &window);
|
||||
#endif
|
||||
ERR_post(gds_lock_conflict, 0);
|
||||
@ -2794,9 +2756,7 @@ static void retain_context(TDBB tdbb, TRA transaction, USHORT commit)
|
||||
}
|
||||
|
||||
#ifndef SUPERSERVER_V2
|
||||
#ifdef READONLY_DATABASE
|
||||
if (!(dbb->dbb_flags & DBB_read_only))
|
||||
#endif
|
||||
CCH_RELEASE(tdbb, &window);
|
||||
#endif
|
||||
|
||||
@ -2812,17 +2772,13 @@ static void retain_context(TDBB tdbb, TRA transaction, USHORT commit)
|
||||
transaction->tra_number = old_number;
|
||||
#endif
|
||||
|
||||
#ifdef READONLY_DATABASE
|
||||
if (!(dbb->dbb_flags & DBB_read_only)) {
|
||||
#endif /* READONLY_DATABASE */
|
||||
/* Set the state on the inventory page */
|
||||
if (commit)
|
||||
TRA_set_state(tdbb, transaction, old_number, tra_committed);
|
||||
else
|
||||
TRA_set_state(tdbb, transaction, old_number, tra_dead);
|
||||
#ifdef READONLY_DATABASE
|
||||
}
|
||||
#endif /* READONLY_DATABASE */
|
||||
transaction->tra_number = new_number;
|
||||
|
||||
/* Release transaction lock since it isn't needed
|
||||
@ -2858,9 +2814,7 @@ static void retain_context(TDBB tdbb, TRA transaction, USHORT commit)
|
||||
}
|
||||
|
||||
if (transaction->tra_flags & TRA_precommitted) {
|
||||
#ifdef READONLY_DATABASE
|
||||
if (!(dbb->dbb_flags & DBB_read_only))
|
||||
#endif
|
||||
{
|
||||
transaction->tra_flags &= ~TRA_precommitted;
|
||||
TRA_set_state(tdbb, transaction, new_number, tra_committed);
|
||||
@ -2978,7 +2932,7 @@ static void THREAD_ROUTINE sweep_database(UCHAR * database)
|
||||
*dpb++ = gds_dpb_sweep;
|
||||
*dpb++ = 1;
|
||||
*dpb++ = gds_dpb_records;
|
||||
|
||||
|
||||
const SSHORT dpb_length = dpb - sweep_dpb;
|
||||
|
||||
/* Register as internal database handle */
|
||||
@ -3178,7 +3132,7 @@ static void transaction_options(
|
||||
if (!(vector = transaction->tra_relation_locks))
|
||||
return;
|
||||
|
||||
/* Try to seize all relation locks.
|
||||
/* Try to seize all relation locks.
|
||||
If any can't be seized, release all and try again. */
|
||||
|
||||
id = 0;
|
||||
@ -3261,4 +3215,4 @@ static BOOLEAN vms_convert(LCK lock, SLONG * data, SCHAR type, BOOLEAN wait)
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
@ -19,6 +19,9 @@
|
||||
*
|
||||
* All Rights Reserved.
|
||||
* Contributor(s): ______________________________________.
|
||||
* 2001.07.06 Sean Leyne - Code Cleanup, removed "#ifdef READONLY_DATABASE"
|
||||
* conditionals, as the engine now fully supports
|
||||
* readonly databases.
|
||||
*/
|
||||
|
||||
#ifdef SHLIB_DEFS
|
||||
@ -60,7 +63,7 @@
|
||||
|
||||
/* SUPERSERVER uses a mutex to allow atomic seek/read(write) sequences.
|
||||
SUPERSERVER_V2 uses "positioned" read (write) calls to avoid a seek
|
||||
and allow multiple threads to overlap database I/O.
|
||||
and allow multiple threads to overlap database I/O.
|
||||
17-Oct-1996 Enabled positioned I/O calls on SOLARIS Superserver. */
|
||||
|
||||
#if (defined SUPERSERVER && (defined SOLARIS_MT || defined LINUX))
|
||||
@ -68,7 +71,7 @@
|
||||
#if !(defined SOLARIS_MT || defined LINUX)
|
||||
/* pread() and pwrite() function calls are provided on SOLARIS.
|
||||
The aio_read(), aio_*() etc. calls are not implemented on
|
||||
the HP-UX systems. Once it is implemented, this #include could
|
||||
the HP-UX systems. Once it is implemented, this #include could
|
||||
be enabled only for HP-UX systems (POSIX). */
|
||||
#include <aio.h>
|
||||
#endif /* SOLARIS_MT */
|
||||
@ -570,7 +573,7 @@ SLONG PIO_act_alloc(DBB dbb)
|
||||
SLONG tot_pages = 0;
|
||||
|
||||
/**
|
||||
** Traverse the linked list of files and add up the number of pages
|
||||
** Traverse the linked list of files and add up the number of pages
|
||||
** in each file
|
||||
**/
|
||||
for (file = dbb->dbb_file; file != NULL; file = file->fil_next) {
|
||||
@ -646,20 +649,17 @@ FIL PIO_open(DBB dbb,
|
||||
}
|
||||
|
||||
if (desc == -1) {
|
||||
#ifdef READONLY_DATABASE
|
||||
/* Try opening the database file in ReadOnly mode. The database file could
|
||||
* be on a RO medium (CD-ROM etc.). If this fileopen fails, return error.
|
||||
*/
|
||||
flag &= ~O_RDWR;
|
||||
flag |= O_RDONLY;
|
||||
if ((desc = open(ptr, flag)) == -1) {
|
||||
#endif /* READONLY_DATABASE */
|
||||
ERR_post(isc_io_error,
|
||||
gds_arg_string, "open",
|
||||
gds_arg_cstring, file_length, ERR_string(file_name,
|
||||
file_length),
|
||||
isc_arg_gds, isc_io_open_err, gds_arg_unix, errno, 0);
|
||||
#ifdef READONLY_DATABASE
|
||||
}
|
||||
else {
|
||||
/* If this is the primary file, set DBB flag to indicate that it is
|
||||
@ -670,7 +670,6 @@ FIL PIO_open(DBB dbb,
|
||||
if (!dbb->dbb_file)
|
||||
dbb->dbb_flags |= DBB_being_opened_read_only;
|
||||
}
|
||||
#endif /* READONLY_DATABASE */
|
||||
}
|
||||
|
||||
return setup_file(dbb, string, length, desc);
|
||||
@ -1090,7 +1089,7 @@ static SLONG pread(int fd, SCHAR * buf, SLONG nbytes, SLONG offset)
|
||||
*
|
||||
* Functional description
|
||||
*
|
||||
* This function uses Asynchronous I/O calls to implement
|
||||
* This function uses Asynchronous I/O calls to implement
|
||||
* positioned read from a given offset
|
||||
**************************************/
|
||||
{
|
||||
@ -1123,7 +1122,7 @@ static SLONG pwrite(int fd, SCHAR * buf, SLONG nbytes, SLONG offset)
|
||||
*
|
||||
* Functional description
|
||||
*
|
||||
* This function uses Asynchronous I/O calls to implement
|
||||
* This function uses Asynchronous I/O calls to implement
|
||||
* positioned write from a given offset
|
||||
**************************************/
|
||||
{
|
||||
@ -1150,4 +1149,4 @@ static SLONG pwrite(int fd, SCHAR * buf, SLONG nbytes, SLONG offset)
|
||||
#endif /* defined PREAD_PWRITE && ! (defined SOLARIS_MT || LINUX) */
|
||||
|
||||
|
||||
} // extern "C"
|
||||
} // extern "C"
|
@ -19,6 +19,9 @@
|
||||
*
|
||||
* All Rights Reserved.
|
||||
* Contributor(s): ______________________________________.
|
||||
* 2001.07.06 Sean Leyne - Code Cleanup, removed "#ifdef READONLY_DATABASE"
|
||||
* conditionals, as the engine now fully supports
|
||||
* readonly databases.
|
||||
*/
|
||||
|
||||
#include "../jrd/ib_stdio.h"
|
||||
@ -137,9 +140,9 @@ void VIO_backout(TDBB tdbb, RPB * rpb, TRA transaction)
|
||||
* Backout the current version of a record. This may called
|
||||
* either because of transaction death or because the record
|
||||
* violated a unique index. In either case, get rid of the
|
||||
* current version and back an old version.
|
||||
* current version and back an old version.
|
||||
*
|
||||
* This routine is called with an inactive RPB, and has to
|
||||
* This routine is called with an inactive RPB, and has to
|
||||
* take great pains to avoid conflicting with another process
|
||||
* which is also trying to backout the same record. On exit
|
||||
* there is no active RPB, and the record may or may not have
|
||||
@ -496,7 +499,7 @@ int VIO_chase_record_version(
|
||||
|
||||
/* refetch the record and try again. The active transaction
|
||||
* could have updated the record a second time.
|
||||
* go back to outer loop
|
||||
* go back to outer loop
|
||||
*/
|
||||
|
||||
if (!DPM_get(tdbb, rpb, LCK_read))
|
||||
@ -792,7 +795,7 @@ int VIO_check_if_updated(TDBB tdbb, RPB * rpb)
|
||||
* Functional description
|
||||
* Check to see if the record specified in the passed
|
||||
* rpb has been updated by an uncommitted transaction.
|
||||
* This involves looking at the latest and greatest
|
||||
* This involves looking at the latest and greatest
|
||||
* version of the record, checking its transaction id,
|
||||
* then checking the TIP page to see if that transaction
|
||||
* has been committed.
|
||||
@ -803,7 +806,7 @@ int VIO_check_if_updated(TDBB tdbb, RPB * rpb)
|
||||
|
||||
SET_TDBB(tdbb);
|
||||
|
||||
/* loop through till we find a real version of the record;
|
||||
/* loop through till we find a real version of the record;
|
||||
one that isn't going to be garbage collected */
|
||||
|
||||
transaction = tdbb->tdbb_request->req_transaction;
|
||||
@ -885,7 +888,7 @@ void VIO_data(TDBB tdbb, register RPB * rpb, BLK pool)
|
||||
* Functional description
|
||||
* Given an active record parameter block, fetch the full record.
|
||||
*
|
||||
* This routine is called with an active RPB and exits with
|
||||
* This routine is called with an active RPB and exits with
|
||||
* an INactive RPB. Yes, Virginia, getting the data for a
|
||||
* record means losing control of the record. This turns out
|
||||
* to matter a lot.
|
||||
@ -959,7 +962,7 @@ void VIO_data(TDBB tdbb, register RPB * rpb, BLK pool)
|
||||
while (rpb->rpb_flags & rpb_incomplete)
|
||||
{
|
||||
DPM_fetch_fragment(tdbb, rpb, LCK_read);
|
||||
|
||||
|
||||
SCHAR* pIn = reinterpret_cast<char*>(rpb->rpb_address);
|
||||
SCHAR* pOut = reinterpret_cast<char*>(tail);
|
||||
SCHAR* pOutEnd = reinterpret_cast<char*>(tail_end);
|
||||
@ -1594,7 +1597,7 @@ int VIO_get_current(
|
||||
* FALSE. If the record is committed, return TRUE.
|
||||
* If foreign_key is true, we are checking for a foreign key,
|
||||
* looking to see if a primary key/unique key exists. For a
|
||||
* no wait transaction, if state of transaction inserting primary key
|
||||
* no wait transaction, if state of transaction inserting primary key
|
||||
* record is tra_active, we should not see the uncommitted record
|
||||
*
|
||||
**************************************/
|
||||
@ -1638,7 +1641,7 @@ int VIO_get_current(
|
||||
if (rpb->rpb_transaction == transaction->tra_number)
|
||||
break;
|
||||
|
||||
/* check the state of transaction - tra_us is taken care of above
|
||||
/* check the state of transaction - tra_us is taken care of above
|
||||
* For now check the state in the tip_cache or tip bitmap. If
|
||||
* record is committed (most cases), this will be faster.
|
||||
*/
|
||||
@ -1787,10 +1790,8 @@ void VIO_init(TDBB tdbb)
|
||||
dbb = tdbb->tdbb_database;
|
||||
attachment = tdbb->tdbb_attachment;
|
||||
|
||||
#ifdef READONLY_DATABASE
|
||||
if (dbb->dbb_flags & DBB_read_only)
|
||||
return;
|
||||
#endif
|
||||
|
||||
/* If there's no presence of a garbage collector running
|
||||
then start one up. */
|
||||
@ -2429,7 +2430,7 @@ void VIO_verb_cleanup(TDBB tdbb, TRA transaction)
|
||||
* relation. A second bitmap per relation tracks records for which
|
||||
* we have old data. The actual data is kept in a linked list stack.
|
||||
* Note that although a record may be changed several times, it will
|
||||
* have only ONE old value -- the value it had before this verb
|
||||
* have only ONE old value -- the value it had before this verb
|
||||
* started.
|
||||
*
|
||||
**************************************/
|
||||
@ -2685,8 +2686,8 @@ void VIO_merge_proc_sav_points(
|
||||
*
|
||||
* Functional description
|
||||
* Merge all the work done in all the save points in
|
||||
* sav_point_list to the current save point in the
|
||||
* transaction block.
|
||||
* sav_point_list to the current save point in the
|
||||
* transaction block.
|
||||
*
|
||||
**************************************/
|
||||
SAV sav_point;
|
||||
@ -2819,7 +2820,7 @@ static void check_control(TDBB tdbb)
|
||||
**************************************
|
||||
*
|
||||
* Functional description
|
||||
* Check to see if we have control
|
||||
* Check to see if we have control
|
||||
* privilege on the current database.
|
||||
*
|
||||
**************************************/
|
||||
@ -2854,7 +2855,7 @@ static BOOLEAN check_user(TDBB tdbb, DSC * desc)
|
||||
end = p + desc->dsc_length;
|
||||
q = tdbb->tdbb_attachment->att_user->usr_user_name;
|
||||
|
||||
/* It is OK to not internationalize this function for v4.00 as
|
||||
/* It is OK to not internationalize this function for v4.00 as
|
||||
* User names are limited to 7-bit ASCII for v4.00
|
||||
*/
|
||||
|
||||
@ -2972,7 +2973,7 @@ static UCHAR *delete_tail(
|
||||
rpb->rpb_page = rpb->rpb_f_page;
|
||||
rpb->rpb_line = rpb->rpb_f_line;
|
||||
|
||||
/* Since the callers are modifying this record, it should not be
|
||||
/* Since the callers are modifying this record, it should not be
|
||||
garbage collected. */
|
||||
|
||||
if (!DPM_fetch(tdbb, rpb, LCK_write))
|
||||
@ -3071,7 +3072,7 @@ static void garbage_collect(
|
||||
* Functional description
|
||||
* Garbage collect a chain of back record. This is called from
|
||||
* "purge" and "expunge." One enters this routine with an
|
||||
* inactive RPB, describing a records which has either
|
||||
* inactive RPB, describing a records which has either
|
||||
* 1) just been deleted or
|
||||
* 2) just had its back pointers set to zero
|
||||
* Therefor we can do a fetch on the back pointers we've got
|
||||
@ -3137,7 +3138,7 @@ static void garbage_collect_idx(
|
||||
*
|
||||
* Functional description
|
||||
* Garbage collect indices for which it is
|
||||
* OK for other transactions to create indices with the same
|
||||
* OK for other transactions to create indices with the same
|
||||
* values.
|
||||
*
|
||||
**************************************/
|
||||
@ -3568,7 +3569,7 @@ static void list_staying(TDBB tdbb, RPB * rpb, LLS * staying)
|
||||
}
|
||||
|
||||
/* If the current number of back versions (depth) is smaller than the number
|
||||
of back versions that we saw in a previous iteration (max_depth), then
|
||||
of back versions that we saw in a previous iteration (max_depth), then
|
||||
somebody else must have been garbage collecting also. Remove the entries
|
||||
in 'staying' that have already been garbage collected. */
|
||||
while (depth < max_depth--)
|
||||
@ -3682,7 +3683,7 @@ static void prepare_update(
|
||||
wait for it to finish. If it commits, we can't procede and must
|
||||
return an update conflict. If the transaction is dead, back out the
|
||||
old version of the record and try again. If in limbo, punt.
|
||||
|
||||
|
||||
The above is true only for concurrency & consistency mode transactions.
|
||||
For read committed transactions, check if the latest commited version
|
||||
is the same as the version that was read for the update. If yes,
|
||||
@ -3799,9 +3800,9 @@ static void prepare_update(
|
||||
IBERROR(188); /* msg 188 cannot update erased record */
|
||||
}
|
||||
|
||||
/* For read committed transactions, if the record version we read
|
||||
/* For read committed transactions, if the record version we read
|
||||
* and started the update
|
||||
* has been updated by another transaction which committed in the
|
||||
* has been updated by another transaction which committed in the
|
||||
* meantime, we cannot proceed further - update conflict error.
|
||||
*/
|
||||
|
||||
@ -3820,8 +3821,8 @@ static void prepare_update(
|
||||
* errors and the "cannot update erased record" within the same
|
||||
* transaction. We were getting these erroe in case of triggers.
|
||||
* A pre-delete trigger could update or delete a record which we
|
||||
* are then tring to change.
|
||||
* In order to remove these changes and restore original behaviour,
|
||||
* are then tring to change.
|
||||
* In order to remove these changes and restore original behaviour,
|
||||
* move this case statement above the 2 "if" statements.
|
||||
* smistry 23-Aug-99
|
||||
*/
|
||||
@ -3842,9 +3843,9 @@ static void prepare_update(
|
||||
&& (rpb->rpb_f_page != org_rpb.rpb_f_page
|
||||
|| rpb->rpb_f_line != org_rpb.rpb_f_line)) {
|
||||
|
||||
/* the primary copy of the record was dead and someone else
|
||||
backed it out for us. Our data is OK but our pointers
|
||||
aren't, so get rid of the record we created and try again
|
||||
/* the primary copy of the record was dead and someone else
|
||||
backed it out for us. Our data is OK but our pointers
|
||||
aren't, so get rid of the record we created and try again
|
||||
*/
|
||||
|
||||
CCH_RELEASE(tdbb, &rpb->rpb_window);
|
||||
@ -3973,7 +3974,7 @@ static BOOLEAN purge(TDBB tdbb, RPB * rpb)
|
||||
* Purge old versions of a fully mature record. The record is
|
||||
* guaranteed not to be deleted. Return TRUE if the record
|
||||
* didn't need to be purged or if the purge was done. Return
|
||||
* FALSE if the purge couldn't happen because somebody else
|
||||
* FALSE if the purge couldn't happen because somebody else
|
||||
* had the record.
|
||||
*
|
||||
**************************************/
|
||||
@ -4132,7 +4133,7 @@ static SLONG savepoint_size(TRA transaction)
|
||||
*
|
||||
* Functional description
|
||||
* Return a measure of how big the current savepoint has gotten.
|
||||
* The number returned is the number of 'sbm' and 'bms' structs
|
||||
* The number returned is the number of 'sbm' and 'bms' structs
|
||||
* that are allocated. This number does not take into account
|
||||
* the data allocated to 'vct_undo'.
|
||||
*
|
||||
@ -4329,7 +4330,7 @@ static void verb_post(
|
||||
**************************************
|
||||
*
|
||||
* Functional description
|
||||
* Post a record update under verb control to a transaction.
|
||||
* Post a record update under verb control to a transaction.
|
||||
* If the previous version of the record was created by
|
||||
* this transaction in a different verb, save the data as well.
|
||||
*
|
||||
@ -4337,7 +4338,7 @@ static void verb_post(
|
||||
* old_data: Only supplied if an in-place operation was performed
|
||||
* (i.e. update_in_place).
|
||||
* new_rpb: Only used to pass to garbage_collect_idx.
|
||||
* same_tx: TRUE if this transaction inserted/updated this record
|
||||
* same_tx: TRUE if this transaction inserted/updated this record
|
||||
* and then deleted it.
|
||||
* FALSE in all other cases.
|
||||
*
|
||||
@ -4447,4 +4448,4 @@ static void verb_post(
|
||||
}
|
||||
|
||||
|
||||
} // extern "C"
|
||||
} // extern "C"
|
@ -19,6 +19,9 @@
|
||||
*
|
||||
* All Rights Reserved.
|
||||
* Contributor(s): ______________________________________.
|
||||
* 2001.07.06 Sean Leyne - Code Cleanup, removed "#ifdef READONLY_DATABASE"
|
||||
* conditionals, as the engine now fully supports
|
||||
* readonly databases.
|
||||
*/
|
||||
|
||||
#ifdef _MSC_VER
|
||||
@ -529,7 +532,6 @@ FIL PIO_open(DBB dbb,
|
||||
FILE_FLAG_RANDOM_ACCESS | dwExtraFlags, 0);
|
||||
|
||||
if (desc == INVALID_HANDLE_VALUE) {
|
||||
#ifdef READONLY_DATABASE
|
||||
/* Try opening the database file in ReadOnly mode.
|
||||
* The database file could be on a RO medium (CD-ROM etc.).
|
||||
* If this fileopen fails, return error.
|
||||
@ -543,7 +545,6 @@ FIL PIO_open(DBB dbb,
|
||||
FILE_FLAG_RANDOM_ACCESS | dwExtraFlags, 0);
|
||||
|
||||
if (desc == INVALID_HANDLE_VALUE) {
|
||||
#endif /* READONLY_DATABASE */
|
||||
ERR_post(isc_io_error,
|
||||
gds_arg_string,
|
||||
"CreateFile (open)",
|
||||
@ -552,7 +553,6 @@ FIL PIO_open(DBB dbb,
|
||||
ERR_string(file_name, file_length),
|
||||
isc_arg_gds,
|
||||
isc_io_open_err, gds_arg_win32, GetLastError(), 0);
|
||||
#ifdef READONLY_DATABASE
|
||||
}
|
||||
else {
|
||||
/* If this is the primary file, set DBB flag to indicate that it is
|
||||
@ -563,7 +563,6 @@ FIL PIO_open(DBB dbb,
|
||||
if (!dbb->dbb_file)
|
||||
dbb->dbb_flags |= DBB_being_opened_read_only;
|
||||
}
|
||||
#endif /* READONLY_DATABASE */
|
||||
}
|
||||
|
||||
return setup_file(dbb, string, length, desc);
|
||||
@ -1121,4 +1120,4 @@ static BOOLEAN nt_error(TEXT* string,
|
||||
}
|
||||
|
||||
|
||||
} // extern "C"
|
||||
} // extern "C"
|
@ -19,6 +19,9 @@
|
||||
*
|
||||
* All Rights Reserved.
|
||||
* Contributor(s): ______________________________________.
|
||||
* 2001.07.06 Sean Leyne - Code Cleanup, removed "#ifdef READONLY_DATABASE"
|
||||
* conditionals, as the engine now fully supports
|
||||
* readonly databases.
|
||||
*/
|
||||
|
||||
#include "../jrd/ib_stdio.h"
|
||||
@ -750,7 +753,7 @@ int CLIB_ROUTINE main( int argc, char **argv)
|
||||
|
||||
FOR(TRANSACTION_HANDLE transact1 REQUEST_HANDLE request2)
|
||||
Y IN RDB$PAGES WITH Y.RDB$RELATION_ID EQ relation->rel_id AND
|
||||
Y.RDB$PAGE_SEQUENCE EQ 0
|
||||
Y.RDB$PAGE_SEQUENCE EQ 0
|
||||
|
||||
if (Y.RDB$PAGE_TYPE == pag_pointer)
|
||||
relation->rel_pointer_page = Y.RDB$PAGE_NUMBER;
|
||||
@ -763,7 +766,7 @@ int CLIB_ROUTINE main( int argc, char **argv)
|
||||
if (sw_index)
|
||||
FOR(TRANSACTION_HANDLE transact1 REQUEST_HANDLE request3)
|
||||
Y IN RDB$INDICES WITH Y.RDB$RELATION_NAME EQ relation->rel_name
|
||||
SORTED BY DESC Y.RDB$INDEX_NAME
|
||||
SORTED BY DESC Y.RDB$INDEX_NAME
|
||||
if (Y.RDB$INDEX_INACTIVE)
|
||||
continue;
|
||||
index = (DBA_IDX) ALLOC(sizeof(struct dba_idx));
|
||||
@ -1307,17 +1310,10 @@ static DBA_FIL db_open( UCHAR * file_name, USHORT file_length)
|
||||
fil->fil_fudge = 0;
|
||||
fil->fil_max_page = 0L;
|
||||
|
||||
#ifdef READONLY_DATABASE
|
||||
if (
|
||||
(fil->fil_desc =
|
||||
FEsopen(expanded_filename, O_RDONLY | O_BINARY, SH_DENYNO, 0, 0,
|
||||
PrimaryDataStream)) == -1)
|
||||
#else
|
||||
if (
|
||||
(fil->fil_desc =
|
||||
FEsopen(expanded_filename, O_RDWR | O_BINARY, SH_DENYNO, 0, 0,
|
||||
PrimaryDataStream)) == -1)
|
||||
#endif /* READONLY_DATABASE */
|
||||
{
|
||||
#ifdef SUPERSERVER
|
||||
CMD_UTIL_put_svc_status(tddba->dba_service_blk->svc_status,
|
||||
@ -1492,11 +1488,7 @@ static DBA_FIL db_open( UCHAR * file_name, USHORT file_length)
|
||||
fil->fil_max_page = 0L;
|
||||
|
||||
if ((fil->fil_desc = CreateFile(file_name,
|
||||
#ifdef READONLY_DATABASE
|
||||
GENERIC_READ,
|
||||
#else
|
||||
GENERIC_READ | GENERIC_WRITE,
|
||||
#endif /* READONLY_DATABASE */
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
NULL,
|
||||
OPEN_EXISTING,
|
||||
@ -1686,11 +1678,7 @@ static DBA_FIL db_open( UCHAR * file_name, USHORT file_length)
|
||||
fil->fil_fudge = 0;
|
||||
fil->fil_max_page = 0L;
|
||||
|
||||
#ifdef READONLY_DATABASE
|
||||
if ((fil->fil_desc = open(file_name, O_RDONLY)) == -1)
|
||||
#else
|
||||
if ((fil->fil_desc = open(file_name, 2)) == -1)
|
||||
#endif /* READONLY_DATABASE */
|
||||
{
|
||||
#ifdef SUPERSERVER
|
||||
CMD_UTIL_put_svc_status(tddba->dba_service_blk->svc_status,
|
||||
@ -1934,4 +1922,4 @@ static void truncate_name( SCHAR * string)
|
||||
*string = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user