8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-22 14:43:03 +01:00

read only databases are supported unconditionally in fb2

This commit is contained in:
awharrison 2001-07-10 17:35:13 +00:00
parent 9587c717b3
commit baa3485651
26 changed files with 1216 additions and 1298 deletions

View File

@ -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"

View File

@ -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 */

View File

@ -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

View 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/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"

View 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.
*/
#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

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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 */

View File

@ -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);
}
}

View 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/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"

View 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 <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"

View 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 <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;
}
}

View 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.
*/
#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"

View File

@ -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;
}
}

View File

@ -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"

View File

@ -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"

View 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/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

View 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"
@ -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

View 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.
*/
#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"

View 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/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"

View 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.
*/
#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"

View 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/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;
}
}
}