8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-24 12:03:02 +01:00

CURRENT_DATABASE implementation. Established identity may also be used for isc_info_db_id datum

This commit is contained in:
skidder 2004-11-11 05:37:52 +00:00
parent 74e1c48585
commit 1e26d6c80d
19 changed files with 129 additions and 10 deletions

View File

@ -2230,6 +2230,9 @@ void DSQL_pretty(const dsql_nod* node, int column)
case nod_current_role: case nod_current_role:
verb = "current_role"; verb = "current_role";
break; break;
case nod_current_database:
verb = "current_database";
break;
case nod_via: case nod_via:
verb = "via"; verb = "via";
break; break;

View File

@ -181,6 +181,10 @@ void GEN_expr( dsql_req* request, dsql_nod* node)
stuff(request, blr_current_role); stuff(request, blr_current_role);
return; return;
case nod_current_database:
stuff(request, blr_current_database);
return;
case nod_udf: case nod_udf:
gen_udf(request, node); gen_udf(request, node);
return; return;
@ -2430,6 +2434,9 @@ static void gen_select( dsql_req* request, dsql_nod* rse)
case nod_current_role: case nod_current_role:
name_alias = "ROLE"; name_alias = "ROLE";
break; break;
case nod_current_database:
name_alias = "CURRENT_DATABASE";
break;
case nod_internal_info: case nod_internal_info:
{ {
internal_info_id id = internal_info_id id =

View File

@ -28,7 +28,7 @@
* Contributor(s): * Contributor(s):
* *
* *
* $Id: keywords.cpp,v 1.36 2004-10-17 08:47:12 dimitr Exp $ * $Id: keywords.cpp,v 1.37 2004-11-11 05:37:20 skidder Exp $
* *
*/ */
@ -104,6 +104,7 @@ static const TOK tokens[] = {
{CSTRING, "CSTRING", 1}, {CSTRING, "CSTRING", 1},
{CURRENT, "CURRENT", 1}, {CURRENT, "CURRENT", 1},
{CURRENT_CONNECTION, "CURRENT_CONNECTION", 2}, {CURRENT_CONNECTION, "CURRENT_CONNECTION", 2},
{CURRENT_DATABASE, "CURRENT_DATABASE", 2},
{CURRENT_DATE, "CURRENT_DATE", 2}, {CURRENT_DATE, "CURRENT_DATE", 2},
{CURRENT_ROLE, "CURRENT_ROLE", 2}, {CURRENT_ROLE, "CURRENT_ROLE", 2},
{CURRENT_TIME, "CURRENT_TIME", 2}, {CURRENT_TIME, "CURRENT_TIME", 2},

View File

@ -1109,6 +1109,14 @@ void MAKE_desc(dsc* desc, dsql_nod* node, dsql_nod* null_replacement)
desc->dsc_length = USERNAME_LENGTH + sizeof(USHORT); desc->dsc_length = USERNAME_LENGTH + sizeof(USHORT);
return; return;
case nod_current_database:
desc->dsc_dtype = dtype_varying;
desc->dsc_scale = 0;
desc->dsc_flags = 0;
desc->dsc_ttype() = ttype_dynamic;
desc->dsc_length = DATABASE_NAME_LENGTH + sizeof(USHORT);
return;
case nod_internal_info: case nod_internal_info:
desc->dsc_dtype = dtype_long; desc->dsc_dtype = dtype_long;
desc->dsc_scale = 0; desc->dsc_scale = 0;

View File

@ -334,7 +334,8 @@ enum nod_t
nod_param_val, // default value for SP parameters support nod_param_val, // default value for SP parameters support
nod_rows, // ROWS support nod_rows, // ROWS support
nod_query_spec, nod_query_spec,
nod_equiv nod_equiv,
nod_current_database
}; };
typedef nod_t NOD_TYPE; typedef nod_t NOD_TYPE;

View File

@ -507,6 +507,7 @@ static LexerState lex;
%token IIF %token IIF
%token SCALAR_ARRAY %token SCALAR_ARRAY
%token CROSS %token CROSS
%token CURRENT_DATABASE
/* precedence declarations for expression evaluation */ /* precedence declarations for expression evaluation */
@ -1334,6 +1335,7 @@ default_value : constant
{ $$ = make_node (nod_user_name, (int) 0, NULL); }*/ { $$ = make_node (nod_user_name, (int) 0, NULL); }*/
| current_user | current_user
| current_role | current_role
| current_database
| internal_info | internal_info
| null_value | null_value
| datetime_value_expression | datetime_value_expression
@ -2124,6 +2126,7 @@ keyword_or_column : valid_symbol_name
| ROWS | ROWS
| USING | USING
| CROSS | CROSS
| CURRENT_DATABASE
; ;
col_opt : ALTER col_opt : ALTER
@ -3676,6 +3679,7 @@ value : column_name
{ $$ = $2; } { $$ = $2; }
| current_user | current_user
| current_role | current_role
| current_database
| internal_info | internal_info
| DB_KEY | DB_KEY
{ $$ = make_node (nod_dbkey, 1, NULL); } { $$ = make_node (nod_dbkey, 1, NULL); }
@ -3804,6 +3808,10 @@ current_role : CURRENT_ROLE
{ $$ = make_node (nod_current_role, 0, NULL); } { $$ = make_node (nod_current_role, 0, NULL); }
; ;
current_database : CURRENT_DATABASE
{ $$ = make_node (nod_current_database, 0, NULL); }
;
internal_info : CURRENT_CONNECTION internal_info : CURRENT_CONNECTION
{ $$ = make_node (nod_internal_info, (int) e_internal_info_count, { $$ = make_node (nod_internal_info, (int) e_internal_info_count,
MAKE_constant ((dsql_str*) internal_connection_id, CONSTANT_SLONG)); } MAKE_constant ((dsql_str*) internal_connection_id, CONSTANT_SLONG)); }

View File

@ -2644,6 +2644,7 @@ static bool invalid_reference(const dsql_ctx* context, const dsql_nod* node,
case nod_current_timestamp: case nod_current_timestamp:
case nod_user_name: case nod_user_name:
case nod_current_role: case nod_current_role:
case nod_current_database:
case nod_internal_info: case nod_internal_info:
case nod_dbkey: case nod_dbkey:
case nod_derived_table: case nod_derived_table:
@ -4260,6 +4261,7 @@ static bool pass1_found_aggregate(const dsql_nod* node, USHORT check_scope_level
case nod_current_timestamp: case nod_current_timestamp:
case nod_user_name: case nod_user_name:
case nod_current_role: case nod_current_role:
case nod_current_database:
case nod_internal_info: case nod_internal_info:
return false; return false;
@ -4458,6 +4460,7 @@ static bool pass1_found_field(const dsql_nod* node, USHORT check_scope_level,
case nod_current_timestamp: case nod_current_timestamp:
case nod_user_name: case nod_user_name:
case nod_current_role: case nod_current_role:
case nod_current_database:
case nod_internal_info: case nod_internal_info:
return false; return false;

View File

@ -137,13 +137,18 @@ static const struct
/* New BLR in 6.0 */ /* New BLR in 6.0 */
{"extract", extract}, {"current_date", zero}, /* 160 */ {"extract", extract}, {"current_date", zero}, /* 160 */
{"current_timestamp", zero}, {"current_time", zero}, {"current_timestamp", zero}, {"current_time", zero},
/* These verbs were added in 6.0, primarily to support 64-bit integers */
{"post_arg", two}, {"post_arg", two},
{"exec_into", exec_into}, {"exec_into", exec_into},
{"user_savepoint", user_savepoint}, {"user_savepoint", user_savepoint},
/* These are actually cursor operations added in Firebird 2.0 */
{"divide2", two}, {"divide2", two},
{"agg_total2", one}, {"agg_total2", one},
{"agg_total_distinct2", one}, {"agg_average2", one}, {"agg_average_distinct2", one}, /* 170 */
{"current_database", zero},
/* These verbs were added in 6.0, primarily to support 64-bit integers, now obsolete */
{"agg_average2", one}, {"agg_average_distinct2", one}, /* 170 */
{"average2", two}, {"average2", two},
{"gen_id2", gen_id}, {"gen_id2", gen_id},
{"set_generator2", gen_id}, {"set_generator2", gen_id},
@ -156,6 +161,7 @@ static const struct
{"nullsfirst", zero}, {"nullsfirst", zero},
{"writelock", zero}, {"writelock", zero},
{"nullslast", zero}, /* 180 */ {"nullslast", zero}, /* 180 */
{"current_database", zero},
{0, 0} {0, 0}
}; };

View File

@ -292,6 +292,7 @@
#define blr_user_savepoint (unsigned char)165 #define blr_user_savepoint (unsigned char)165
#define blr_dcl_cursor (unsigned char)166 #define blr_dcl_cursor (unsigned char)166
#define blr_cursor_stmt (unsigned char)167 #define blr_cursor_stmt (unsigned char)167
#define blr_current_database (unsigned char)168
/* These codes are actions for user-defined savepoints */ /* These codes are actions for user-defined savepoints */

View File

@ -1696,6 +1696,14 @@ void CMP_get_desc(thread_db* tdbb, CompilerScratch* csb, jrd_nod* node, DSC * de
desc->dsc_flags = 0; desc->dsc_flags = 0;
return; return;
case nod_current_database:
desc->dsc_dtype = dtype_text;
desc->dsc_ttype() = ttype_metadata;
desc->dsc_length = DATABASE_NAME_LENGTH;
desc->dsc_scale = 0;
desc->dsc_flags = 0;
return;
case nod_internal_info: case nod_internal_info:
desc->dsc_dtype = dtype_long; desc->dsc_dtype = dtype_long;
desc->dsc_length = sizeof(SLONG); desc->dsc_length = sizeof(SLONG);
@ -4942,6 +4950,7 @@ static jrd_nod* pass2(thread_db* tdbb, CompilerScratch* csb, jrd_nod* const node
case nod_null: case nod_null:
case nod_user_name: case nod_user_name:
case nod_current_role: case nod_current_role:
case nod_current_database:
case nod_internal_info: case nod_internal_info:
case nod_gen_id: case nod_gen_id:
case nod_gen_id2: case nod_gen_id2:

View File

@ -58,6 +58,10 @@ const ULONG MAX_COLUMN_SIZE = 32767; /* Bytes */
const int USERNAME_LENGTH = 31; /* Bytes */ const int USERNAME_LENGTH = 31; /* Bytes */
// Maximum length of database file name. Since it is stored in system tables and
// clumplet structures it is highly non-trivial to increase
const int DATABASE_NAME_LENGTH = 255; /* Bytes */
const size_t MAX_SQL_IDENTIFIER_SIZE = 32; const size_t MAX_SQL_IDENTIFIER_SIZE = 32;
const size_t MAX_SQL_IDENTIFIER_LEN = 31; const size_t MAX_SQL_IDENTIFIER_LEN = 31;
typedef TEXT SqlIdentifier[MAX_SQL_IDENTIFIER_SIZE]; typedef TEXT SqlIdentifier[MAX_SQL_IDENTIFIER_SIZE];

View File

@ -19,7 +19,7 @@
* *
* All Rights Reserved. * All Rights Reserved.
* Contributor(s): ______________________________________. * Contributor(s): ______________________________________.
* $Id: evl.cpp,v 1.121 2004-11-07 10:47:19 robocop Exp $ * $Id: evl.cpp,v 1.122 2004-11-11 05:37:44 skidder Exp $
*/ */
/* /*
@ -1015,6 +1015,20 @@ dsc* EVL_expr(thread_db* tdbb, jrd_nod* node)
} }
return &impure->vlu_desc; return &impure->vlu_desc;
case nod_current_database:
impure->vlu_desc.dsc_dtype = dtype_text;
impure->vlu_desc.dsc_sub_type = 0;
impure->vlu_desc.dsc_scale = 0;
INTL_ASSIGN_TTYPE(&impure->vlu_desc, ttype_metadata);
impure->vlu_desc.dsc_address =
(UCHAR*) tdbb->tdbb_database->dbb_database_name.c_str();
impure->vlu_desc.dsc_length =
tdbb->tdbb_database->dbb_database_name.length();
return &impure->vlu_desc;
case nod_extract: case nod_extract:
{ {
impure = (impure_value*) ((SCHAR *) request + node->nod_impure); impure = (impure_value*) ((SCHAR *) request + node->nod_impure);
@ -1326,6 +1340,22 @@ bool EVL_field(jrd_rel* relation, Record* record, USHORT id, dsc* desc)
return true; return true;
} }
if (temp_nod_type == nod_current_database)
{
thread_db* tdbb = NULL;
SET_TDBB(tdbb);
desc->dsc_dtype = dtype_text;
desc->dsc_sub_type = 0;
desc->dsc_scale = 0;
INTL_ASSIGN_TTYPE(desc, ttype_metadata);
desc->dsc_address =
(UCHAR *) tdbb->tdbb_database->dbb_database_name.c_str();
desc->dsc_length =
tdbb->tdbb_database->dbb_database_name.length();
return true;
}
if (temp_nod_type == nod_current_date || if (temp_nod_type == nod_current_date ||
temp_nod_type == nod_current_time || temp_nod_type == nod_current_time ||
temp_nod_type == nod_current_timestamp) temp_nod_type == nod_current_timestamp)

View File

@ -508,6 +508,7 @@ const int e_extract_length = 2; /* Number of entries in nod_args */
const int e_current_date_length = 1; const int e_current_date_length = 1;
const int e_current_time_length = 1; const int e_current_time_length = 1;
const int e_current_timestamp_length= 1; const int e_current_timestamp_length= 1;
const int e_current_database_length = 1;
const int e_dcl_cursor_number = 0; const int e_dcl_cursor_number = 0;
const int e_dcl_cursor_rse = 1; const int e_dcl_cursor_rse = 1;

View File

@ -570,13 +570,15 @@ ISC_STATUS GDS_ATTACH_DATABASE(ISC_STATUS* user_status,
thread_db thd_context; thread_db thd_context;
thread_db* tdbb = JRD_MAIN_set_thread_data(thd_context); thread_db* tdbb = JRD_MAIN_set_thread_data(thd_context);
/* If database name is not alias, check it against conf file */ /* Check database against conf file. */
const vdnResult vdn = verify_database_name(expanded_filename, user_status); const vdnResult vdn = verify_database_name(expanded_name, user_status);
if (!is_alias && vdn == vdnFail) if (!is_alias && vdn == vdnFail)
{ {
JRD_restore_context(); JRD_restore_context();
return user_status[1]; return user_status[1];
} }
else
user_status[0] = 0; // Clear status vector
/* Unless we're already attached, do some initialization */ /* Unless we're already attached, do some initialization */
@ -731,6 +733,18 @@ ISC_STATUS GDS_ATTACH_DATABASE(ISC_STATUS* user_status,
{ {
first = true; first = true;
dbb->dbb_filename = expanded_name; dbb->dbb_filename = expanded_name;
// NS: Use alias as database ID only if accessing database using file name is not possible.
//
// This way we:
// 1. Ensure uniqueness of ID even in presence of multiple processes
// 2. Make sure that ID value can be used to connect back to database
//
if (is_alias && vdn == vdnFail)
dbb->dbb_database_name.assign(file_name, file_length ? file_length : strlen(file_name));
else
dbb->dbb_database_name = expanded_name;
/* Extra LCK_init() done to keep the lock table until the /* Extra LCK_init() done to keep the lock table until the
database is shutdown() after the last detach. */ database is shutdown() after the last detach. */
LCK_init(tdbb, LCK_OWNER_database); LCK_init(tdbb, LCK_OWNER_database);
@ -1794,10 +1808,14 @@ ISC_STATUS GDS_CREATE_DATABASE(ISC_STATUS* user_status,
} }
// Check for DatabaseAccess // Check for DatabaseAccess
if (!is_alias && verify_database_name(expanded_name, user_status) == vdnFail) const vdnResult vdn = verify_database_name(expanded_name, user_status);
if (!is_alias && vdn == vdnFail)
{ {
ERR_punt(); ERR_punt();
} }
else
user_status[0] = 0; // Clear status vector.
if (options.dpb_key) if (options.dpb_key)
{ {
@ -1989,6 +2007,17 @@ ISC_STATUS GDS_CREATE_DATABASE(ISC_STATUS* user_status,
dbb->dbb_filename = expanded_name; dbb->dbb_filename = expanded_name;
#endif #endif
// NS: Use alias as database ID only if accessing database using file name is not possible.
//
// This way we:
// 1. Ensure uniqueness of ID even in presence of multiple processes
// 2. Make sure that ID value can be used to connect back to database
//
if (is_alias && vdn == vdnFail)
dbb->dbb_database_name.assign(file_name, file_length ? file_length : strlen(file_name));
else
dbb->dbb_database_name = dbb->dbb_filename;
#ifdef GOVERNOR #ifdef GOVERNOR
if (!options.dpb_sec_attach) { if (!options.dpb_sec_attach) {
if (JRD_max_users) { if (JRD_max_users) {

View File

@ -207,6 +207,7 @@ public:
USHORT dbb_prefetch_pages; /* prefetch pages per request */ USHORT dbb_prefetch_pages; /* prefetch pages per request */
Firebird::string dbb_spare_string; /* random buffer */ Firebird::string dbb_spare_string; /* random buffer */
Firebird::PathName dbb_filename; /* filename string */ Firebird::PathName dbb_filename; /* filename string */
Firebird::PathName dbb_database_name; /* database ID (file name or alias) */
Firebird::string dbb_encrypt_key; /* encryption key */ Firebird::string dbb_encrypt_key; /* encryption key */
JrdMemoryPool* dbb_permanent; JrdMemoryPool* dbb_permanent;
@ -273,6 +274,7 @@ private:
: dbb_modules(p), : dbb_modules(p),
dbb_spare_string(p), dbb_spare_string(p),
dbb_filename(p), dbb_filename(p),
dbb_database_name(p),
dbb_encrypt_key(p), dbb_encrypt_key(p),
dbb_pools(1, p, type_dbb), dbb_pools(1, p, type_dbb),
dbb_text_objects(p), dbb_text_objects(p),

View File

@ -207,3 +207,4 @@ NODE(nod_asn_list, asn_list, "")
NODE(nod_dcl_cursor, declare_cursor, "DECLARE CURSOR") NODE(nod_dcl_cursor, declare_cursor, "DECLARE CURSOR")
NODE(nod_cursor_stmt, cursor_stmt, "CURSOR STATEMENT") NODE(nod_cursor_stmt, cursor_stmt, "CURSOR STATEMENT")
NODE(nod_equiv, equiv, " == ") NODE(nod_equiv, equiv, " == ")
NODE(nod_current_database, current_database, "")

View File

@ -2821,6 +2821,7 @@ static bool expression_possible_unknown(const jrd_nod* node)
case nod_argument: case nod_argument:
case nod_current_date: case nod_current_date:
case nod_current_role: case nod_current_role:
case nod_current_database:
case nod_current_time: case nod_current_time:
case nod_current_timestamp: case nod_current_timestamp:
case nod_gen_id: case nod_gen_id:
@ -2931,6 +2932,7 @@ static bool expression_contains_stream(const jrd_nod* node, UCHAR stream)
case nod_argument: case nod_argument:
case nod_current_date: case nod_current_date:
case nod_current_role: case nod_current_role:
case nod_current_database:
case nod_current_time: case nod_current_time:
case nod_current_timestamp: case nod_current_timestamp:
case nod_gen_id: case nod_gen_id:
@ -3251,6 +3253,7 @@ static bool expression_equal2(thread_db* tdbb, OptimizerBlk* opt,
case nod_null: case nod_null:
case nod_user_name: case nod_user_name:
case nod_current_role: case nod_current_role:
case nod_current_database:
case nod_current_time: case nod_current_time:
case nod_current_date: case nod_current_date:
case nod_current_timestamp: case nod_current_timestamp:

View File

@ -2418,6 +2418,7 @@ static jrd_nod* parse(thread_db* tdbb, CompilerScratch* csb, USHORT expected,
case blr_agg_count: case blr_agg_count:
case blr_user_name: case blr_user_name:
case blr_current_role: case blr_current_role:
case blr_current_database:
case blr_current_date: case blr_current_date:
case blr_current_time: case blr_current_time:
case blr_current_timestamp: case blr_current_timestamp:

View File

@ -226,6 +226,7 @@ static const VERB verbs[] =
PAIR(nod_current_role, blr_current_role, 1, 0, VALUE, VALUE), PAIR(nod_current_role, blr_current_role, 1, 0, VALUE, VALUE),
PAIR(nod_dcl_cursor, blr_dcl_cursor, e_dcl_cursor_length, 0, STATEMENT, OTHER), PAIR(nod_dcl_cursor, blr_dcl_cursor, e_dcl_cursor_length, 0, STATEMENT, OTHER),
PAIR(nod_cursor_stmt, blr_cursor_stmt, e_cursor_stmt_length, 0, STATEMENT, OTHER), PAIR(nod_cursor_stmt, blr_cursor_stmt, e_cursor_stmt_length, 0, STATEMENT, OTHER),
PAIR(nod_current_database, blr_current_database, e_current_database_length, 0, VALUE, VALUE),
{0, NULL, NULL, NULL, NULL, NULL, NULL} {0, NULL, NULL, NULL, NULL, NULL, NULL}
}; };