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

Merge remote-tracking branch 'origin/master' into work/core-6322

This commit is contained in:
Adriano dos Santos Fernandes 2020-06-17 11:31:11 -03:00
commit b6ccc62956
12 changed files with 118 additions and 128 deletions

View File

@ -45,9 +45,9 @@ New items for isc_database_info
isc_dpb_addr_flag_conn_encrypted - connection is encrypted; isc_dpb_addr_flag_conn_encrypted - connection is encrypted;
fb_info_wire_crypt - name of connection encryption plugin. fb_info_wire_crypt - name of connection encryption plugin.
6. fb_info_provider_features: 6. fb_info_features:
return list of features supported by current connection's provider. return list of features supported by current connection's provider.
Each byte in returned array shall be one of following info_provider_features: Each byte in returned array shall be one of following info_features:
fb_feature_multi_statements - multiple prepared statements in single attachment fb_feature_multi_statements - multiple prepared statements in single attachment
fb_feature_multi_transactions - multiple concurrent transactions in single attachment fb_feature_multi_transactions - multiple concurrent transactions in single attachment
@ -55,6 +55,7 @@ New items for isc_database_info
fb_feature_session_reset - ALTER SESSION RESET is supported fb_feature_session_reset - ALTER SESSION RESET is supported
fb_feature_read_consistency - read consistency TIL is supported fb_feature_read_consistency - read consistency TIL is supported
fb_feature_statement_timeout - statement timeout is supported fb_feature_statement_timeout - statement timeout is supported
fb_feature_statement_long_life - prepared statements are not dropped on transaction end
New items for isc_transaction_info: New items for isc_transaction_info:

View File

@ -6535,47 +6535,36 @@ ValueExprNode* FieldNode::pass1(thread_db* tdbb, CompilerScratch* csb)
} }
*/ */
// posting the required privilege access to the current relation and field // Unless this is a validation expression, post the required privilege access
// to the current relation and field
// If this is in a "validate_subtree" then we must not if (!csb->csb_validate_expr)
// post access checks to the table and the fields in the table.
// If any node of the parse tree is a nod_validate type node,
// the nodes in the subtree are involved in a validation
// clause only, the subtree is a validate_subtree in our notation.
const SLONG ssRelationId = tail->csb_view ?
tail->csb_view->rel_id : (csb->csb_view ? csb->csb_view->rel_id : 0);
if (tail->csb_flags & csb_modify)
{ {
if (!csb->csb_validate_expr) SecurityClass::flags_t privilege = SCL_select;
if (!csb->csb_returning_expr)
{ {
SecurityClass::flags_t priv = csb->csb_returning_expr ? if (tail->csb_flags & csb_store)
SCL_select : SCL_update; privilege = SCL_insert;
CMP_post_access(tdbb, csb, relation->rel_security_name, ssRelationId, else if (tail->csb_flags & csb_modify)
priv, SCL_object_table, relation->rel_name); privilege = SCL_update;
CMP_post_access(tdbb, csb, field->fld_security_name, ssRelationId, else if (tail->csb_flags & csb_erase)
priv, SCL_object_column, field->fld_name, relation->rel_name); privilege = SCL_delete;
} }
}
else if (tail->csb_flags & csb_erase) const SLONG ssRelationId = tail->csb_view ?
{ tail->csb_view->rel_id : (csb->csb_view ? csb->csb_view->rel_id : 0);
CMP_post_access(tdbb, csb, relation->rel_security_name, ssRelationId, CMP_post_access(tdbb, csb, relation->rel_security_name, ssRelationId,
SCL_delete, SCL_object_table, relation->rel_name); privilege, SCL_object_table, relation->rel_name);
}
else if (tail->csb_flags & csb_store) // Field-level privilege access is posted for every operation except DELETE
{
CMP_post_access(tdbb, csb, relation->rel_security_name, ssRelationId, if (privilege != SCL_delete)
SCL_insert, SCL_object_table, relation->rel_name); {
CMP_post_access(tdbb, csb, field->fld_security_name, ssRelationId, CMP_post_access(tdbb, csb, field->fld_security_name, ssRelationId,
SCL_insert, SCL_object_column, field->fld_name, relation->rel_name); privilege, SCL_object_column, field->fld_name, relation->rel_name);
} }
else
{
CMP_post_access(tdbb, csb, relation->rel_security_name, ssRelationId,
SCL_select, SCL_object_table, relation->rel_name);
CMP_post_access(tdbb, csb, field->fld_security_name, ssRelationId,
SCL_select, SCL_object_column, field->fld_name, relation->rel_name);
} }
ValueExprNode* sub; ValueExprNode* sub;

View File

@ -7241,7 +7241,12 @@ StoreNode* StoreNode::pass1(thread_db* tdbb, CompilerScratch* csb)
makeDefaults(tdbb, csb); makeDefaults(tdbb, csb);
doPass1(tdbb, csb, statement.getAddress()); doPass1(tdbb, csb, statement.getAddress());
doPass1(tdbb, csb, statement2.getAddress());
{ // scope
AutoSetRestore<bool> autoReturningExpr(&csb->csb_returning_expr, true);
doPass1(tdbb, csb, statement2.getAddress());
}
doPass1(tdbb, csb, subStore.getAddress()); doPass1(tdbb, csb, subStore.getAddress());
pass1Validations(tdbb, csb, validations); pass1Validations(tdbb, csb, validations);

View File

@ -163,7 +163,7 @@ enum db_info_types
fb_info_wire_crypt = 140, fb_info_wire_crypt = 140,
// Return list of features supported by provider of current connection // Return list of features supported by provider of current connection
fb_info_provider_features = 141, fb_info_features = 141,
isc_info_db_last_value /* Leave this LAST! */ isc_info_db_last_value /* Leave this LAST! */
}; };
@ -174,7 +174,7 @@ enum db_info_crypt /* flags set in fb_info_crypt_state */
fb_info_crypt_process = 0x02 fb_info_crypt_process = 0x02
}; };
enum info_provider_features // response to fb_info_provider_features enum info_features // response to fb_info_features
{ {
fb_feature_multi_statements = 1, // Multiple prepared statements in single attachment fb_feature_multi_statements = 1, // Multiple prepared statements in single attachment
fb_feature_multi_transactions = 2, // Multiple concurrent transaction in single attachment fb_feature_multi_transactions = 2, // Multiple concurrent transaction in single attachment
@ -182,7 +182,7 @@ enum info_provider_features // response to fb_info_provider_features
fb_feature_session_reset = 4, // ALTER SESSION RESET is supported fb_feature_session_reset = 4, // ALTER SESSION RESET is supported
fb_feature_read_consistency = 5, // Read consistency TIL is supported fb_feature_read_consistency = 5, // Read consistency TIL is supported
fb_feature_statement_timeout = 6, // Statement timeout is supported fb_feature_statement_timeout = 6, // Statement timeout is supported
fb_feature_statement_long_life = 7, // Prepared statement can survive transaction end fb_feature_statement_long_life = 7, // Prepared statements are not dropped on transaction end
info_provider_features_max // Not really a feature. Keep this last. info_provider_features_max // Not really a feature. Keep this last.
}; };

View File

@ -3,16 +3,16 @@
*** DO NOT EDIT *** *** DO NOT EDIT ***
TO CHANGE ANY INFORMATION IN HERE PLEASE TO CHANGE ANY INFORMATION IN HERE PLEASE
EDIT src/misc/writeBuildNum.sh EDIT src/misc/writeBuildNum.sh
FORMAL BUILD NUMBER:2048 FORMAL BUILD NUMBER:2049
*/ */
#define PRODUCT_VER_STRING "4.0.0.2048" #define PRODUCT_VER_STRING "4.0.0.2049"
#define FILE_VER_STRING "WI-V4.0.0.2048" #define FILE_VER_STRING "WI-V4.0.0.2049"
#define LICENSE_VER_STRING "WI-V4.0.0.2048" #define LICENSE_VER_STRING "WI-V4.0.0.2049"
#define FILE_VER_NUMBER 4, 0, 0, 2048 #define FILE_VER_NUMBER 4, 0, 0, 2049
#define FB_MAJOR_VER "4" #define FB_MAJOR_VER "4"
#define FB_MINOR_VER "0" #define FB_MINOR_VER "0"
#define FB_REV_NO "0" #define FB_REV_NO "0"
#define FB_BUILD_NO "2048" #define FB_BUILD_NO "2049"
#define FB_BUILD_TYPE "V" #define FB_BUILD_TYPE "V"
#define FB_BUILD_SUFFIX "Firebird 4.0 Release Candidate 1" #define FB_BUILD_SUFFIX "Firebird 4.0 Release Candidate 1"

View File

@ -466,7 +466,7 @@ const int OPT_STATIC_ITEMS = 64;
#define CURRENT_ENGINE "Engine13" #define CURRENT_ENGINE "Engine13"
#define EMBEDDED_PROVIDERS "Providers=" CURRENT_ENGINE #define EMBEDDED_PROVIDERS "Providers=" CURRENT_ENGINE
// Feature mask for current version of engine provider // Features set for current version of engine provider
#define ENGINE_FEATURES {fb_feature_multi_statements, \ #define ENGINE_FEATURES {fb_feature_multi_statements, \
fb_feature_multi_transactions, \ fb_feature_multi_transactions, \
fb_feature_session_reset, \ fb_feature_session_reset, \

View File

@ -492,11 +492,11 @@ public:
virtual Blob* createBlob() = 0; virtual Blob* createBlob() = 0;
// Test specified feature flag // Test specified feature flag
bool testFeature(info_provider_features value) const { return m_features[value]; } bool testFeature(info_features value) const { return m_features[value]; }
// Set specified flag // Set specified flag
void setFeature(info_provider_features value) { m_features[value] = true; } void setFeature(info_features value) { m_features[value] = true; }
// Clear specified flag // Clear specified flag
void clearFeature(info_provider_features value) { m_features[value] = false; } void clearFeature(info_features value) { m_features[value] = false; }
protected: protected:
virtual Transaction* doCreateTransaction() = 0; virtual Transaction* doCreateTransaction() = 0;

View File

@ -189,8 +189,8 @@ void InternalConnection::attach(thread_db* tdbb)
SQL_DIALECT_V6 : SQL_DIALECT_V5; SQL_DIALECT_V6 : SQL_DIALECT_V5;
memset(m_features, false, sizeof(m_features)); memset(m_features, false, sizeof(m_features));
static const info_provider_features features[] = ENGINE_FEATURES; static const info_features features[] = ENGINE_FEATURES;
for (int i = 0; i < sizeof(features); i++) for (int i = 0; i < FB_NELEM(features); i++)
setFeature(features[i]); setFeature(features[i]);
} }
@ -450,50 +450,51 @@ void InternalStatement::doPrepare(thread_db* tdbb, const string& sql)
fb_assert(!m_allocated); fb_assert(!m_allocated);
} }
CallerName save_caller_name(tran->getHandle()->tra_caller_name);
if (m_callerPrivileges)
{
jrd_req* request = tdbb->getRequest();
JrdStatement* statement = request ? request->getStatement() : NULL;
CallerName callerName;
const Routine* routine;
if (statement && statement->parentStatement)
statement = statement->parentStatement;
if (statement && statement->triggerInvoker)
tran->getHandle()->tra_caller_name = CallerName(obj_trigger,
statement->triggerName,
statement->triggerInvoker->getUserName());
else if (statement && (routine = statement->getRoutine()) &&
routine->getName().identifier.hasData())
{
const MetaString& userName = routine->invoker ? routine->invoker->getUserName() : "";
if (routine->getName().package.isEmpty())
{
tran->getHandle()->tra_caller_name = CallerName(routine->getObjectType(),
routine->getName().identifier, userName);
}
else
{
tran->getHandle()->tra_caller_name = CallerName(obj_package_header,
routine->getName().package, userName);
}
}
else
tran->getHandle()->tra_caller_name = CallerName();
}
{ {
EngineCallbackGuard guard(tdbb, *this, FB_FUNCTION); EngineCallbackGuard guard(tdbb, *this, FB_FUNCTION);
CallerName save_caller_name(tran->getHandle()->tra_caller_name);
if (m_callerPrivileges)
{
jrd_req* request = tdbb->getRequest();
JrdStatement* statement = request ? request->getStatement() : NULL;
CallerName callerName;
const Routine* routine;
if (statement && statement->parentStatement)
statement = statement->parentStatement;
if (statement && statement->triggerInvoker)
tran->getHandle()->tra_caller_name = CallerName(obj_trigger,
statement->triggerName,
statement->triggerInvoker->getUserName());
else if (statement && (routine = statement->getRoutine()) &&
routine->getName().identifier.hasData())
{
const MetaString& userName = routine->invoker ? routine->invoker->getUserName() : "";
if (routine->getName().package.isEmpty())
{
tran->getHandle()->tra_caller_name = CallerName(routine->getObjectType(),
routine->getName().identifier, userName);
}
else
{
tran->getHandle()->tra_caller_name = CallerName(obj_package_header,
routine->getName().package, userName);
}
}
else
tran->getHandle()->tra_caller_name = CallerName();
}
m_request.assignRefNoIncr(att->prepare(&status, tran, sql.length(), sql.c_str(), m_request.assignRefNoIncr(att->prepare(&status, tran, sql.length(), sql.c_str(),
m_connection.getSqlDialect(), 0)); m_connection.getSqlDialect(), 0));
m_allocated = (m_request != NULL);
tran->getHandle()->tra_caller_name = save_caller_name;
} }
m_allocated = (m_request != NULL);
if (tran->getHandle())
tran->getHandle()->tra_caller_name = save_caller_name;
if (status->getState() & IStatus::STATE_ERRORS) if (status->getState() & IStatus::STATE_ERRORS)
raise(&status, tdbb, "JAttachment::prepare", &sql); raise(&status, tdbb, "JAttachment::prepare", &sql);

View File

@ -148,7 +148,7 @@ void IscConnection::attach(thread_db* tdbb)
{ {
EngineCallbackGuard guard(tdbb, *this, FB_FUNCTION); EngineCallbackGuard guard(tdbb, *this, FB_FUNCTION);
const unsigned char info[] = {isc_info_db_sql_dialect, fb_info_provider_features, isc_info_end}; const unsigned char info[] = {isc_info_db_sql_dialect, fb_info_features, isc_info_end};
m_iscProvider.isc_database_info(&status, &m_handle, sizeof(info), info, sizeof(buff), buff); m_iscProvider.isc_database_info(&status, &m_handle, sizeof(info), info, sizeof(buff), buff);
} }
if (status->getState() & IStatus::STATE_ERRORS) { if (status->getState() & IStatus::STATE_ERRORS) {
@ -171,7 +171,7 @@ void IscConnection::attach(thread_db* tdbb)
m_sqlDialect = m_iscProvider.isc_vax_integer(p, len); m_sqlDialect = m_iscProvider.isc_vax_integer(p, len);
break; break;
case fb_info_provider_features: case fb_info_features:
for (int i = 0; i < len; i++) for (int i = 0; i < len; i++)
{ {
if (p[i] == 0) if (p[i] == 0)
@ -181,7 +181,7 @@ void IscConnection::attach(thread_db* tdbb)
if (p[i] < info_provider_features_max) if (p[i] < info_provider_features_max)
{ {
setFeature(static_cast<info_provider_features>(p[i])); setFeature(static_cast<info_features>(p[i]));
} }
// else this provider supports unknown feature, ignore it. // else this provider supports unknown feature, ignore it.
} }
@ -192,7 +192,7 @@ void IscConnection::attach(thread_db* tdbb)
const ULONG err = m_iscProvider.isc_vax_integer(p + 1, len - 1); const ULONG err = m_iscProvider.isc_vax_integer(p + 1, len - 1);
if (err == isc_infunk) if (err == isc_infunk)
{ {
if (*p == fb_info_provider_features) if (*p == fb_info_features)
{ {
// Used provider follow Firebird error reporting conventions but is not aware of // Used provider follow Firebird error reporting conventions but is not aware of
// this info item. Assume Firebird 3 or earlier. // this info item. Assume Firebird 3 or earlier.

View File

@ -227,7 +227,7 @@ void INF_database_info(thread_db* tdbb,
CHECK_INPUT("INF_database_info"); CHECK_INPUT("INF_database_info");
CountsBuffer counts_buffer; CountsBuffer counts_buffer;
UCHAR* buffer = counts_buffer.getBuffer(BUFFER_SMALL); UCHAR* buffer = counts_buffer.getBuffer(BUFFER_SMALL, false);
USHORT length; USHORT length;
ULONG err_val; ULONG err_val;
bool header_refreshed = false; bool header_refreshed = false;
@ -458,31 +458,24 @@ void INF_database_info(thread_db* tdbb,
case isc_info_db_id: case isc_info_db_id:
{ {
counts_buffer.resize(BUFFER_SMALL); counts_buffer.clear();
const UCHAR* const end_buf = counts_buffer.end();
// May be simpler to code using a server-side version of isql's Extender class.
const PathName& str_fn = dbb->dbb_database_name; const PathName& str_fn = dbb->dbb_database_name;
STUFF(p, 2); counts_buffer.push(2);
USHORT len = str_fn.length(); PathName::size_type len = str_fn.length();
if (p + len + 1 >= end_buf)
len = end_buf - p - 1;
if (len > 255) if (len > 255)
len = 255; // Cannot put more in one byte, will truncate instead. len = 255; // Cannot put more in one byte, will truncate instead.
*p++ = len; counts_buffer.push(static_cast<UCHAR>(len));
memcpy(p, str_fn.c_str(), len); counts_buffer.push(reinterpret_cast<const UCHAR*>(str_fn.c_str()), len);
p += len;
if (p + 2 < end_buf) TEXT site[256];
{ ISC_get_host(site, sizeof(site));
SCHAR site[256]; UCHAR siteLen = static_cast<UCHAR>(strlen(site));
ISC_get_host(site, sizeof(site)); counts_buffer.push(siteLen);
len = static_cast<USHORT>(strlen(site)); counts_buffer.push(reinterpret_cast<UCHAR*>(site), siteLen);
if (p + len + 1 >= end_buf)
len = end_buf - p - 1; buffer = counts_buffer.begin();
*p++ = len; length = counts_buffer.getCount();
memcpy(p, site, len);
p += len;
}
length = p - buffer;
} }
break; break;
@ -855,13 +848,14 @@ void INF_database_info(thread_db* tdbb,
length = INF_convert(att->getActualIdleTimeout(), buffer); length = INF_convert(att->getActualIdleTimeout(), buffer);
break; break;
case fb_info_provider_features: case fb_info_features:
{ {
static const unsigned char features[] = ENGINE_FEATURES; static const unsigned char features[] = ENGINE_FEATURES;
length = sizeof(features); length = sizeof(features);
memcpy(buffer, features, length); counts_buffer.assign(features, length);
break; buffer = counts_buffer.begin();
} break;
}
default: default:
buffer[0] = item; buffer[0] = item;

View File

@ -1789,7 +1789,7 @@ USHORT SCL_convert_privilege(thread_db* tdbb, jrd_tra* transaction, const Firebi
{ {
static GlobalPtr<Mutex> privCacheMutex; static GlobalPtr<Mutex> privCacheMutex;
static bool cacheFlag = false; static bool cacheFlag = false;
typedef NonPooled<MetaName, USHORT> CachedPriv; typedef NonPooled<MetaString, USHORT> CachedPriv;
static GlobalPtr<GenericMap<CachedPriv> > privCache; static GlobalPtr<GenericMap<CachedPriv> > privCache;
if (!cacheFlag) if (!cacheFlag)

View File

@ -9,7 +9,7 @@ BuildType=V
MajorVer=4 MajorVer=4
MinorVer=0 MinorVer=0
RevNo=0 RevNo=0
BuildNum=2048 BuildNum=2049
NowAt=`pwd` NowAt=`pwd`
cd `dirname $0` cd `dirname $0`