diff --git a/builds/win32/msvc15/common.vcxproj b/builds/win32/msvc15/common.vcxproj index 3d3a267fdf..be408275d9 100644 --- a/builds/win32/msvc15/common.vcxproj +++ b/builds/win32/msvc15/common.vcxproj @@ -141,7 +141,6 @@ - @@ -159,6 +158,7 @@ + @@ -356,4 +356,4 @@ - \ No newline at end of file + diff --git a/builds/win32/msvc15/common.vcxproj.filters b/builds/win32/msvc15/common.vcxproj.filters index 0db3a15acb..26e835bc64 100644 --- a/builds/win32/msvc15/common.vcxproj.filters +++ b/builds/win32/msvc15/common.vcxproj.filters @@ -437,9 +437,6 @@ headers - - headers - headers @@ -479,6 +476,9 @@ headers + + headers + headers diff --git a/src/burp/burp.h b/src/burp/burp.h index b68d74642a..2c5220b5de 100644 --- a/src/burp/burp.h +++ b/src/burp/burp.h @@ -43,7 +43,6 @@ #include "../common/classes/array.h" #include "../common/classes/fb_pair.h" #include "../common/classes/MetaString.h" -#include "../common/classes/Nullable.h" #include "../common/SimilarToRegex.h" #include "../common/status.h" #include "../common/sha.h" diff --git a/src/common/StatementMetadata.h b/src/common/StatementMetadata.h index 01c06a2265..a12472dddb 100644 --- a/src/common/StatementMetadata.h +++ b/src/common/StatementMetadata.h @@ -28,7 +28,6 @@ #include #include "firebird/Interface.h" #include "iberror.h" -#include "../common/classes/Nullable.h" #include "../common/classes/array.h" #include "../common/classes/fb_string.h" #include "../common/classes/objects_array.h" diff --git a/src/common/classes/Nullable.h b/src/common/classes/Nullable.h deleted file mode 100644 index 9752199ed6..0000000000 --- a/src/common/classes/Nullable.h +++ /dev/null @@ -1,183 +0,0 @@ -/* - * The contents of this file are subject to the Initial - * Developer's 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.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl. - * - * Software distributed under the License is distributed AS IS, - * 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 Adriano dos Santos Fernandes - * for the Firebird Open Source RDBMS project. - * - * Copyright (c) 2010 Adriano dos Santos Fernandes - * and all contributors signed below. - * - * All Rights Reserved. - * Contributor(s): ______________________________________. - */ - -#ifndef CLASSES_NULLABLE_H -#define CLASSES_NULLABLE_H - -#include "firebird.h" -#include "../common/classes/fb_string.h" -#include "../jrd/constants.h" - - -// Auxiliary template to build an empty value. -template // Generic NullableClear -class NullableClear -{ -public: - static void clear(T& v) - { - v = T(); - } -}; - - -// Nullable support without constructor, to allow usage in unions (used in the parser). -template class BaseNullable -{ -public: - static BaseNullable val(const T& v) - { - BaseNullable nullable; - nullable.value = v; - nullable.specified = true; - return nullable; - } - - static BaseNullable empty() - { - BaseNullable nullable; - NullableClear::clear(nullable.value); - nullable.specified = false; - return nullable; - } - - T orElse(T elseValue) const - { - return specified ? value : elseValue; - } - - bool operator ==(const BaseNullable& o) const - { - return (!specified && !o.specified) || (specified == o.specified && value == o.value); - } - - bool operator !=(const BaseNullable& o) const - { - return !(*this == o); - } - - bool operator ==(const T& o) const - { - return specified && value == o; - } - - bool operator !=(const T& o) const - { - return !(*this == o); - } - - void operator =(const T& v) - { - this->value = v; - this->specified = true; - } - - bool isUnknown() const - { - return !specified; - } - - bool isAssigned() const - { - return specified; - } - -public: - T value; - bool specified; -}; - - -// NullableClear specializations. - -template -class NullableClear > -{ -public: - static void clear(BaseNullable& v) - { - v.specified = false; - } -}; - -template <> -class NullableClear -{ -public: - static void clear(rel_t& v) - { - v = rel_persistent; - } -}; - -// Actual Nullable template. -template class Nullable : public BaseNullable -{ -public: - explicit Nullable(const T& v) - { - this->value = v; - this->specified = true; - } - - Nullable(const Nullable& o) - { - this->value = o.value; - this->specified = o.specified; - } - - Nullable() - { - invalidate(); - } - - void operator =(const BaseNullable& o) - { - this->value = o.value; - this->specified = o.specified; - } - - void operator =(const T& v) - { - this->value = v; - this->specified = true; - } - - bool assignOnce(const T& v) - { - if (this->specified) - return false; - - *this = v; - return true; - } - - void invalidate() - { - NullableClear::clear(this->value); - this->specified = false; - } -}; - -typedef Nullable TriState; - -#endif // CLASSES_NULLABLE_H diff --git a/src/common/classes/TriState.h b/src/common/classes/TriState.h new file mode 100644 index 0000000000..08347d0aea --- /dev/null +++ b/src/common/classes/TriState.h @@ -0,0 +1,133 @@ +/* + * PROGRAM: Firebird aux classes. + * MODULE: TriState.h + * DESCRIPTION: Firebird's SQL tri-state emulation class. + * + * The contents of this file are subject to the Initial + * Developer's 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.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl. + * + * Software distributed under the License is distributed AS IS, + * 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 Claudio Valderrama on 28-Aug-2007 + * for the Firebird Open Source RDBMS project. + * + * Copyright (c) 2007 Claudio Valderrama + * and all contributors signed below. + * + * All Rights Reserved. + * Contributor(s): ______________________________________. + * + * + */ + +#ifndef CLASSES_TRISTATE_H +#define CLASSES_TRISTATE_H + + +class TriState +{ +public: + TriState(); + explicit TriState(bool input); + + bool operator ==(const TriState& o) const + { + return m_init == o.m_init && m_val == o.m_val; + } + + bool operator !=(const TriState& o) const + { + return m_init != o.m_init || m_val != o.m_val; + } + + void operator=(bool input); + + bool asBool() const; + bool valueOr(bool value) const; + void reset(); + bool assignOnce(bool input); + bool isUnknown() const; + bool isAssigned() const; + bool toggle(); + +private: + bool m_init, m_val; +}; + +// The var is left uninitialized. +inline TriState::TriState() + : m_init(false), m_val(false) +{ +} + +// The var is initialized to the explicit value. +inline TriState::TriState(bool input) + : m_init(true), m_val(input) +{ +} + +// The var receives a T/F value. +inline void TriState::operator=(bool input) +{ + m_init = true; + m_val = input; +} + +// The var is coerced to a T/F value as result. +inline bool TriState::asBool() const +{ + return m_init && m_val; +} + +inline bool TriState::valueOr(bool otherValue) const +{ + return m_init ? m_val : otherValue; +} + +// The var is returned to its uninitialized state. +inline void TriState::reset() +{ + m_init = m_val = false; +} + +// The assignment succeeds only if the var is uninitialized. +inline bool TriState::assignOnce(bool input) +{ + if (m_init) + return false; + + m_init = true; + m_val = input; + return true; +} + +// Tests whether the var is uninitialized. +inline bool TriState::isUnknown() const +{ + return !m_init; +} + +// Tests whether the var is initialized. +inline bool TriState::isAssigned() const +{ + return m_init; +} + +// The var is toggled between T and F only if it's already initialized. +inline bool TriState::toggle() +{ + if (!m_init) + return false; + + m_val = !m_val; + return true; +} + + +#endif // CLASSES_TRISTATE_H diff --git a/src/dsql/BoolNodes.cpp b/src/dsql/BoolNodes.cpp index f6c2ff4999..fb09d8e9f9 100644 --- a/src/dsql/BoolNodes.cpp +++ b/src/dsql/BoolNodes.cpp @@ -1382,7 +1382,7 @@ bool InListBoolNode::execute(thread_db* tdbb, Request* request) const const auto res = lookup->find(tdbb, request, arg, argDesc); if (res.isAssigned()) - return res.value; + return res.asBool(); fb_assert(list->items.hasData()); request->req_flags |= req_null; diff --git a/src/dsql/DdlNodes.epp b/src/dsql/DdlNodes.epp index eebb471c13..454561faba 100644 --- a/src/dsql/DdlNodes.epp +++ b/src/dsql/DdlNodes.epp @@ -1695,7 +1695,7 @@ DdlNode* CreateAlterFunctionNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) returnType->type->resolve(dsqlScratch); // check SQL SECURITY is not set if function declared in package - if (package.hasData() && ssDefiner.specified) + if (package.hasData() && ssDefiner.isAssigned()) { ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-204) << Arg::Gds(isc_invalid_clause) << Arg::Str("SQL SECURITY for functions is prohibit in packages")); @@ -1895,10 +1895,10 @@ bool CreateAlterFunctionNode::executeAlter(thread_db* tdbb, DsqlCompilerScratch* FUN.RDB$DETERMINISTIC_FLAG = deterministic ? TRUE : FALSE; FUN.RDB$RETURN_ARGUMENT = 0; - if (ssDefiner.specified) + if (ssDefiner.isAssigned()) { FUN.RDB$SQL_SECURITY.NULL = FALSE; - FUN.RDB$SQL_SECURITY = ssDefiner.value ? FB_TRUE : FB_FALSE; + FUN.RDB$SQL_SECURITY = ssDefiner.asBool() ? FB_TRUE : FB_FALSE; } else FUN.RDB$SQL_SECURITY.NULL = TRUE; @@ -2648,7 +2648,7 @@ DdlNode* CreateAlterProcedureNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) returns[i]->type->resolve(dsqlScratch); // check SQL SECURITY is not set if procedure declared in package - if (package.hasData() && ssDefiner.specified) + if (package.hasData() && ssDefiner.isAssigned()) { ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-204) << Arg::Gds(isc_invalid_clause) << Arg::Str("SQL SECURITY for procedures is prohibit in packages")); @@ -2846,10 +2846,10 @@ bool CreateAlterProcedureNode::executeAlter(thread_db* tdbb, DsqlCompilerScratch else P.RDB$PRIVATE_FLAG.NULL = TRUE; - if (ssDefiner.specified) + if (ssDefiner.isAssigned()) { P.RDB$SQL_SECURITY.NULL = FALSE; - P.RDB$SQL_SECURITY = ssDefiner.value ? FB_TRUE : FB_FALSE; + P.RDB$SQL_SECURITY = ssDefiner.asBool() ? FB_TRUE : FB_FALSE; } else P.RDB$SQL_SECURITY.NULL = TRUE; @@ -3357,7 +3357,7 @@ void TriggerDefinition::store(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, TRG.RDB$TRIGGER_TYPE = type.value(); TRG.RDB$TRIGGER_SEQUENCE = position.value_or(0); - TRG.RDB$TRIGGER_INACTIVE = (!active.specified ? 0 : (USHORT) !active.value); + TRG.RDB$TRIGGER_INACTIVE = (active.isUnknown() ? 0 : (USHORT) !active.asBool()); } END_STORE @@ -3429,8 +3429,8 @@ bool TriggerDefinition::modify(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch if (position.has_value()) TRG.RDB$TRIGGER_SEQUENCE = position.value(); - if (active.specified) - TRG.RDB$TRIGGER_INACTIVE = (USHORT) !active.value; + if (active.isAssigned()) + TRG.RDB$TRIGGER_INACTIVE = (USHORT) !active.asBool(); if (external) { @@ -5007,12 +5007,12 @@ void AlterDomainNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, dsqlScratch->getBlrData()); } - if (notNullFlag.specified) + if (notNullFlag.isAssigned()) { FLD.RDB$NULL_FLAG.NULL = FALSE; - FLD.RDB$NULL_FLAG = notNullFlag.value; + FLD.RDB$NULL_FLAG = notNullFlag.asBool(); - if (!notNullFlag.value) + if (!notNullFlag.asBool()) { AutoRequest request2; @@ -6031,10 +6031,10 @@ void RelationNode::FieldDefinition::store(thread_db* tdbb, jrd_tra* transaction) RFR.RDB$IDENTITY_TYPE = identityType.value(); } - if (notNullFlag.specified) + if (notNullFlag.isAssigned()) { RFR.RDB$NULL_FLAG.NULL = FALSE; - RFR.RDB$NULL_FLAG = notNullFlag.value; + RFR.RDB$NULL_FLAG = notNullFlag.asBool(); } if (defaultSource.hasData()) @@ -7354,10 +7354,10 @@ void CreateRelationNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScrat REL.RDB$FLAGS = REL_sql; REL.RDB$RELATION_TYPE = relationType.value(); - if (ssDefiner.specified) + if (ssDefiner.isAssigned()) { REL.RDB$SQL_SECURITY.NULL = FALSE; - REL.RDB$SQL_SECURITY = ssDefiner.value ? FB_TRUE : FB_FALSE; + REL.RDB$SQL_SECURITY = ssDefiner.asBool() ? FB_TRUE : FB_FALSE; } else REL.RDB$SQL_SECURITY.NULL = TRUE; @@ -7383,8 +7383,8 @@ void CreateRelationNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScrat bool replicationEnabled; - if (replicationState.specified) - replicationEnabled = replicationState.value; + if (replicationState.isAssigned()) + replicationEnabled = replicationState.asBool(); else { // Apply the default replication state to the table being created @@ -7733,10 +7733,10 @@ void AlterRelationNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratc { MODIFY REL { - if (ssDefiner.specified) + if (ssDefiner.isAssigned()) { REL.RDB$SQL_SECURITY.NULL = FALSE; - REL.RDB$SQL_SECURITY = ssDefiner.value ? FB_TRUE : FB_FALSE; + REL.RDB$SQL_SECURITY = ssDefiner.asBool() ? FB_TRUE : FB_FALSE; } else REL.RDB$SQL_SECURITY.NULL = TRUE; @@ -7750,9 +7750,9 @@ void AlterRelationNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratc case Clause::TYPE_ALTER_PUBLICATION: { - fb_assert(replicationState.specified); + fb_assert(replicationState.isAssigned()); - if (replicationState.value) + if (replicationState.asBool()) { // Add table to the publication @@ -9430,22 +9430,22 @@ void CreateIndexNode::store(thread_db* tdbb, jrd_tra* transaction, MetaName& nam } END_FOR - if (definition.unique.specified) + if (definition.unique.isAssigned()) { IDX.RDB$UNIQUE_FLAG.NULL = FALSE; - IDX.RDB$UNIQUE_FLAG = SSHORT(definition.unique.value); + IDX.RDB$UNIQUE_FLAG = SSHORT(definition.unique.asBool()); } - if (definition.inactive.specified) + if (definition.inactive.isAssigned()) { IDX.RDB$INDEX_INACTIVE.NULL = FALSE; - IDX.RDB$INDEX_INACTIVE = SSHORT(definition.inactive.value); + IDX.RDB$INDEX_INACTIVE = SSHORT(definition.inactive.asBool()); } - if (definition.descending.specified) + if (definition.descending.isAssigned()) { IDX.RDB$INDEX_TYPE.NULL = FALSE; - IDX.RDB$INDEX_TYPE = SSHORT(definition.descending.value); + IDX.RDB$INDEX_TYPE = SSHORT(definition.descending.asBool()); } request2.reset(tdbb, drq_l_lfield, DYN_REQUESTS); @@ -11038,7 +11038,7 @@ void CreateAlterUserNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScra if (mode != USER_ADD) { if (!password && !firstName && !middleName && !lastName && - !adminRole.specified && !active.specified && !comment && !properties.hasData()) + adminRole.isUnknown() && active.isUnknown() && !comment && !properties.hasData()) { // 283: ALTER USER requires at least one clause to be specified status_exception::raise(Arg::PrivateDyn(283)); @@ -11093,17 +11093,17 @@ void CreateAlterUserNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScra if (plugin) userData->plugin = *plugin; - if (adminRole.specified) + if (adminRole.isAssigned()) { - userData->adm.set(&statusWrapper, adminRole.value); + userData->adm.set(&statusWrapper, adminRole.asBool()); check(&statusWrapper); userData->adm.setEntered(&statusWrapper, 1); check(&statusWrapper); } - if (active.specified) + if (active.isAssigned()) { - userData->act.set(&statusWrapper, (int) active.value); + userData->act.set(&statusWrapper, (int) active.asBool()); check(&statusWrapper); userData->act.setEntered(&statusWrapper, 1); check(&statusWrapper); @@ -12645,7 +12645,7 @@ void AlterDatabaseNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratc changeBackupMode(tdbb, transaction, CLAUSE_END_BACKUP); if (setDefaultCharSet.hasData() || setDefaultCollation.hasData() || linger >= 0 || - ssDefiner.specified) + ssDefiner.isAssigned()) { AutoCacheRequest request(tdbb, drq_m_database, DYN_REQUESTS); FOR(REQUEST_HANDLE request TRANSACTION_HANDLE transaction) @@ -12681,10 +12681,10 @@ void AlterDatabaseNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratc DBB.RDB$LINGER = linger; } - if (ssDefiner.specified) + if (ssDefiner.isAssigned()) { DBB.RDB$SQL_SECURITY.NULL = FALSE; - DBB.RDB$SQL_SECURITY = ssDefiner.value ? FB_TRUE : FB_FALSE; + DBB.RDB$SQL_SECURITY = ssDefiner.asBool() ? FB_TRUE : FB_FALSE; } END_MODIFY diff --git a/src/dsql/DdlNodes.h b/src/dsql/DdlNodes.h index 4ad3d0f338..cd9c369a3f 100644 --- a/src/dsql/DdlNodes.h +++ b/src/dsql/DdlNodes.h @@ -34,7 +34,7 @@ #include "../dsql/NodePrinter.h" #include "../common/classes/array.h" #include "../common/classes/ByteChunk.h" -#include "../common/classes/Nullable.h" +#include "../common/classes/TriState.h" #include "../jrd/Savepoint.h" #include "../dsql/errd_proto.h" @@ -480,7 +480,7 @@ public: bool privateScope; bool preserveDefaults; SLONG udfReturnPos; - Nullable ssDefiner; + TriState ssDefiner; }; @@ -614,7 +614,7 @@ public: MetaName packageOwner; bool privateScope; bool preserveDefaults; - Nullable ssDefiner; + TriState ssDefiner; }; @@ -698,7 +698,7 @@ public: MetaName name; MetaName relationName; std::optional type; - Nullable active; + TriState active; std::optional position; NestConst external; Firebird::string source; @@ -988,7 +988,7 @@ public: NestConst setDefault; MetaName renameTo; Firebird::AutoPtr type; - Nullable notNullFlag; // true = NOT NULL / false = NULL + TriState notNullFlag; // true = NOT NULL / false = NULL }; @@ -1212,7 +1212,7 @@ public: MetaName identitySequence; std::optional identityType; std::optional collationId; - Nullable notNullFlag; // true = NOT NULL / false = NULL + TriState notNullFlag; // true = NOT NULL / false = NULL std::optional position; Firebird::string defaultSource; Firebird::ByteChunk defaultValue; @@ -1551,8 +1551,8 @@ public: NestConst dsqlNode; MetaName name; Firebird::Array > clauses; - Nullable ssDefiner; - Nullable replicationState; + TriState ssDefiner; + TriState replicationState; }; @@ -1724,9 +1724,9 @@ public: MetaName relation; Firebird::ObjectsArray columns; - Nullable unique; - Nullable descending; - Nullable inactive; + TriState unique; + TriState descending; + TriState inactive; SSHORT type; bid expressionBlr; bid expressionSource; @@ -2217,8 +2217,8 @@ public: Firebird::string* lastName; MetaName* plugin; Firebird::string* comment; - Nullable adminRole; - Nullable active; + TriState adminRole; + TriState active; Mode mode; void addProperty(MetaName* pr, Firebird::string* val = NULL) @@ -2459,7 +2459,7 @@ public: Firebird::Array > files; MetaName cryptPlugin; MetaName keyName; - Nullable ssDefiner; + TriState ssDefiner; Firebird::Array pubTables; }; diff --git a/src/dsql/ExprNodes.cpp b/src/dsql/ExprNodes.cpp index dbe0dce2e9..ecbd6c835f 100644 --- a/src/dsql/ExprNodes.cpp +++ b/src/dsql/ExprNodes.cpp @@ -6830,7 +6830,7 @@ ValueExprNode* FieldNode::pass1(thread_db* tdbb, CompilerScratch* csb) } AutoSetRestore autoRelationStream(&csb->csb_parent_relation, - relation->rel_ss_definer.value ? relation : NULL); + relation->rel_ss_definer.asBool() ? relation : NULL); if (relation->rel_view_rse) { @@ -13047,7 +13047,7 @@ ValueExprNode* UdfCallNode::pass1(thread_db* tdbb, CompilerScratch* csb) if (!ssRelationId && csb->csb_parent_relation) { - fb_assert(csb->csb_parent_relation->rel_ss_definer.value); + fb_assert(csb->csb_parent_relation->rel_ss_definer.asBool()); ssRelationId = csb->csb_parent_relation->rel_id; } diff --git a/src/dsql/ExprNodes.h b/src/dsql/ExprNodes.h index 6de804709c..9f763f9ada 100644 --- a/src/dsql/ExprNodes.h +++ b/src/dsql/ExprNodes.h @@ -28,6 +28,7 @@ #include "../dsql/Nodes.h" #include "../dsql/NodePrinter.h" #include "../common/classes/init.h" +#include "../common/classes/TriState.h" #include "../dsql/pass1_proto.h" class SysFunction; diff --git a/src/dsql/NodePrinter.h b/src/dsql/NodePrinter.h index 163f82e49a..271993d17e 100644 --- a/src/dsql/NodePrinter.h +++ b/src/dsql/NodePrinter.h @@ -25,6 +25,7 @@ #include #include "../dsql/Nodes.h" +#include "../common/classes/TriState.h" #define NODE_PRINT(var, property) var.print(STRINGIZE(property), property) #define NODE_PRINT_ENUM(var, property) var.print(STRINGIZE(property), (int) property) @@ -266,11 +267,10 @@ public: print(s, *array); } - template - void print(const Firebird::string& s, const BaseNullable& nullable) + void print(const Firebird::string& s, const TriState& triState) { - if (nullable.specified) - print(s, nullable.value); + if (triState.isAssigned()) + print(s, triState.asBool()); } template diff --git a/src/dsql/PackageNodes.epp b/src/dsql/PackageNodes.epp index e58fa27d20..93cc622ccb 100644 --- a/src/dsql/PackageNodes.epp +++ b/src/dsql/PackageNodes.epp @@ -33,6 +33,7 @@ #include "../dsql/make_proto.h" #include "../dsql/pass1_proto.h" #include "../common/StatusArg.h" +#include "../common/classes/TriState.h" #include "../jrd/Attachment.h" #include "../jrd/scl_proto.h" @@ -370,10 +371,10 @@ void CreateAlterPackageNode::executeCreate(thread_db* tdbb, DsqlCompilerScratch* PKG.RDB$PACKAGE_HEADER_SOURCE.NULL = FALSE; attachment->storeMetaDataBlob(tdbb, transaction, &PKG.RDB$PACKAGE_HEADER_SOURCE, source); - if (ssDefiner.specified) + if (ssDefiner.isAssigned()) { PKG.RDB$SQL_SECURITY.NULL = FALSE; - PKG.RDB$SQL_SECURITY = ssDefiner.value ? FB_TRUE : FB_FALSE; + PKG.RDB$SQL_SECURITY = ssDefiner.asBool() ? FB_TRUE : FB_FALSE; } else PKG.RDB$SQL_SECURITY.NULL = TRUE; @@ -444,10 +445,10 @@ bool CreateAlterPackageNode::executeAlter(thread_db* tdbb, DsqlCompilerScratch* if (!PKG.RDB$VALID_BODY_FLAG.NULL) PKG.RDB$VALID_BODY_FLAG = FALSE; - if (ssDefiner.specified) + if (ssDefiner.isAssigned()) { PKG.RDB$SQL_SECURITY.NULL = FALSE; - PKG.RDB$SQL_SECURITY = ssDefiner.value ? FB_TRUE : FB_FALSE; + PKG.RDB$SQL_SECURITY = ssDefiner.asBool() ? FB_TRUE : FB_FALSE; } else PKG.RDB$SQL_SECURITY.NULL = TRUE; diff --git a/src/dsql/PackageNodes.h b/src/dsql/PackageNodes.h index 0dfb8ccc6f..0e1ad83d2b 100644 --- a/src/dsql/PackageNodes.h +++ b/src/dsql/PackageNodes.h @@ -110,7 +110,7 @@ public: Firebird::Array* items; Firebird::SortedArray functionNames; Firebird::SortedArray procedureNames; - Nullable ssDefiner; + TriState ssDefiner; private: MetaName owner; diff --git a/src/dsql/Parser.h b/src/dsql/Parser.h index 487eff9231..229b8132f5 100644 --- a/src/dsql/Parser.h +++ b/src/dsql/Parser.h @@ -33,7 +33,7 @@ #include "../dsql/PackageNodes.h" #include "../dsql/StmtNodes.h" #include "../jrd/RecordSourceNodes.h" -#include "../common/classes/Nullable.h" +#include "../common/classes/TriState.h" #include "../common/classes/stack.h" #include "gen/parse.h" @@ -244,13 +244,6 @@ private: clause = value; } - template - void setClause(BaseNullable& clause, const char* duplicateMsg, const T& value) - { - checkDuplicateClause(clause, duplicateMsg); - clause = value; - } - template void setClause(std::optional& clause, const char* duplicateMsg, const T& value) { @@ -258,16 +251,6 @@ private: clause = value; } - template - void setClause(BaseNullable& clause, const char* duplicateMsg, const BaseNullable& value) - { - if (value.specified) - { - checkDuplicateClause(clause, duplicateMsg); - clause = value.value; - } - } - template void setClause(std::optional& clause, const char* duplicateMsg, const std::optional& value) { @@ -278,6 +261,21 @@ private: } } + void setClause(TriState& clause, const char* duplicateMsg, bool value) + { + checkDuplicateClause(clause, duplicateMsg); + clause = value; + } + + void setClause(TriState& clause, const char* duplicateMsg, const TriState& value) + { + if (value.isAssigned()) + { + checkDuplicateClause(clause, duplicateMsg); + clause = value; + } + } + template void setClause(NestConst& clause, const char* duplicateMsg, const T2& value) { @@ -324,10 +322,9 @@ private: return clause.hasData(); } - template - bool isDuplicateClause(const BaseNullable& clause) + bool isDuplicateClause(const TriState& clause) { - return clause.specified; + return clause.isAssigned(); } template diff --git a/src/dsql/StmtNodes.cpp b/src/dsql/StmtNodes.cpp index b10cebcc47..3d92cfbfbd 100644 --- a/src/dsql/StmtNodes.cpp +++ b/src/dsql/StmtNodes.cpp @@ -9018,11 +9018,11 @@ SetTransactionNode* SetTransactionNode::dsqlPass(DsqlCompilerScratch* dsqlScratc // Stuff some version info. dsqlScratch->appendUChar(isc_tpb_version1); - if (readOnly.specified) - dsqlScratch->appendUChar(readOnly.value ? isc_tpb_read : isc_tpb_write); + if (readOnly.isAssigned()) + dsqlScratch->appendUChar(readOnly.asBool() ? isc_tpb_read : isc_tpb_write); - if (wait.specified) - dsqlScratch->appendUChar(wait.value ? isc_tpb_wait : isc_tpb_nowait); + if (wait.isAssigned()) + dsqlScratch->appendUChar(wait.asBool() ? isc_tpb_wait : isc_tpb_nowait); if (isoLevel.has_value()) { @@ -9046,16 +9046,16 @@ SetTransactionNode* SetTransactionNode::dsqlPass(DsqlCompilerScratch* dsqlScratc } } - if (noAutoUndo.specified) + if (noAutoUndo.isAssigned()) dsqlScratch->appendUChar(isc_tpb_no_auto_undo); - if (ignoreLimbo.specified) + if (ignoreLimbo.isAssigned()) dsqlScratch->appendUChar(isc_tpb_ignore_limbo); - if (restartRequests.specified) + if (restartRequests.isAssigned()) dsqlScratch->appendUChar(isc_tpb_restart_requests); - if (autoCommit.specified) + if (autoCommit.isAssigned()) dsqlScratch->appendUChar(isc_tpb_autocommit); if (lockTimeout.has_value()) diff --git a/src/dsql/StmtNodes.h b/src/dsql/StmtNodes.h index e3fa2778ff..b62c27f8af 100644 --- a/src/dsql/StmtNodes.h +++ b/src/dsql/StmtNodes.h @@ -32,6 +32,7 @@ #include "../dsql/DdlNodes.h" #include "../dsql/NodePrinter.h" #include "../common/DecFloat.h" +#include "../common/classes/TriState.h" namespace Jrd { @@ -1625,12 +1626,12 @@ public: std::optional atSnapshotNumber; std::optional isoLevel; std::optional lockTimeout; - Nullable readOnly; - Nullable wait; - Nullable noAutoUndo; - Nullable ignoreLimbo; - Nullable restartRequests; - Nullable autoCommit; + TriState readOnly; + TriState wait; + TriState noAutoUndo; + TriState ignoreLimbo; + TriState restartRequests; + TriState autoCommit; }; diff --git a/src/dsql/btyacc_fb.ske b/src/dsql/btyacc_fb.ske index 43f0d4103d..061b91b5ca 100644 --- a/src/dsql/btyacc_fb.ske +++ b/src/dsql/btyacc_fb.ske @@ -27,7 +27,7 @@ #include "../dsql/StmtNodes.h" #include "../dsql/WinNodes.h" #include "../jrd/RecordSourceNodes.h" -#include "../common/classes/Nullable.h" +#include "../common/classes/TriState.h" #include "gen/parse.h" #include "../dsql/Parser.h" diff --git a/src/dsql/gen.cpp b/src/dsql/gen.cpp index 03098a620e..2ccf3f3d18 100644 --- a/src/dsql/gen.cpp +++ b/src/dsql/gen.cpp @@ -608,7 +608,7 @@ void GEN_rse(DsqlCompilerScratch* dsqlScratch, RseNode* rse) if (rse->firstRows.isAssigned()) { dsqlScratch->appendUChar(blr_optimize); - dsqlScratch->appendUChar(rse->firstRows.value); + dsqlScratch->appendUChar(static_cast(rse->firstRows.asBool())); } dsqlScratch->appendUChar(blr_end); diff --git a/src/dsql/parse.y b/src/dsql/parse.y index 6b6211f58a..c634dc3b42 100644 --- a/src/dsql/parse.y +++ b/src/dsql/parse.y @@ -733,7 +733,7 @@ using namespace Firebird; {} std::optional nullableIntVal; - BaseNullable nullableBoolVal; + TriState triState; std::optional nullableSqlSecurityVal; std::optional nullableOverrideClause; struct { bool first; bool second; } boolPair; @@ -2262,10 +2262,10 @@ sql_security_clause | SQL SECURITY INVOKER { $$ = false; } ; -%type sql_security_clause_opt +%type sql_security_clause_opt sql_security_clause_opt - : /* nothing */ { $$ = Nullable::empty(); } - | sql_security_clause { $$ = Nullable::val($1); } + : /* nothing */ { $$ = TriState(); } + | sql_security_clause { $$ = $1; } ; %type publication_state @@ -3902,14 +3902,14 @@ replace_trigger_clause } ; -%type trigger_active +%type trigger_active trigger_active : ACTIVE - { $$ = Nullable::val(true); } + { $$ = TriState(true); } | INACTIVE - { $$ = Nullable::val(false); } + { $$ = TriState(false); } | // nothing - { $$ = Nullable::empty(); } + { $$ = TriState(); } ; %type trigger_type() @@ -4236,7 +4236,7 @@ alter_op($relationNode) } | DROP SQL SECURITY { - setClause($relationNode->ssDefiner, "SQL SECURITY", Nullable::empty()); + setClause($relationNode->ssDefiner, "SQL SECURITY", TriState()); RelationNode::Clause* clause = newNode(RelationNode::Clause::TYPE_ALTER_SQL_SECURITY); $relationNode->clauses.add(clause); @@ -5836,12 +5836,12 @@ skip_locked_clause_opt | SKIP LOCKED { $$ = true; } ; -%type optimize_clause +%type optimize_clause optimize_clause : OPTIMIZE optimize_mode - { $$ = Nullable::val($2); } + { $$ = TriState($2); } | // nothing - { $$ = Nullable::empty(); } + { $$ = TriState(); } ; %type optimize_mode diff --git a/src/jrd/Attachment.cpp b/src/jrd/Attachment.cpp index 28ec35e890..79c87931b6 100644 --- a/src/jrd/Attachment.cpp +++ b/src/jrd/Attachment.cpp @@ -1138,7 +1138,7 @@ void Attachment::invalidateReplSet(thread_db* tdbb, bool broadcast) for (auto relation : *att_relations) { if (relation) - relation->rel_repl_state.invalidate(); + relation->rel_repl_state.reset(); } } diff --git a/src/jrd/Attachment.h b/src/jrd/Attachment.h index 20a8d1b2bd..0a858ff28d 100644 --- a/src/jrd/Attachment.h +++ b/src/jrd/Attachment.h @@ -42,6 +42,7 @@ #include "../common/classes/stack.h" #include "../common/classes/timestamp.h" #include "../common/classes/TimerImpl.h" +#include "../common/classes/TriState.h" #include "../common/ThreadStart.h" #include "../common/TimeZoneUtil.h" diff --git a/src/jrd/Database.cpp b/src/jrd/Database.cpp index 2a42213b58..8a731fb760 100644 --- a/src/jrd/Database.cpp +++ b/src/jrd/Database.cpp @@ -420,14 +420,14 @@ namespace Jrd } } - return dbb_repl_state.value; + return dbb_repl_state.asBool(); } void Database::invalidateReplState(thread_db* tdbb, bool broadcast) { SyncLockGuard guard(&dbb_repl_sync, SYNC_EXCLUSIVE, FB_FUNCTION); - dbb_repl_state.invalidate(); + dbb_repl_state.reset(); if (broadcast) { diff --git a/src/jrd/Database.h b/src/jrd/Database.h index 87ea2af2bb..1f7d5073dc 100644 --- a/src/jrd/Database.h +++ b/src/jrd/Database.h @@ -54,6 +54,7 @@ #include "../common/classes/GenericMap.h" #include "../common/classes/RefCounted.h" #include "../common/classes/semaphore.h" +#include "../common/classes/TriState.h" #include "../common/classes/XThreadMutex.h" #include "../common/utils_proto.h" #include "../jrd/RandomGenerator.h" diff --git a/src/jrd/ExtEngineManager.cpp b/src/jrd/ExtEngineManager.cpp index c548f8ebe8..459c37fddf 100644 --- a/src/jrd/ExtEngineManager.cpp +++ b/src/jrd/ExtEngineManager.cpp @@ -932,9 +932,10 @@ void ExtEngineManager::Trigger::execute(thread_db* tdbb, Request* request, unsig record_param* oldRpb, record_param* newRpb) const { EngineAttachmentInfo* attInfo = extManager->getEngineAttachment(tdbb, engine); - const Nullable& ssDefiner = trg->ssDefiner.specified ? trg->ssDefiner : - (trg->relation && trg->relation->rel_ss_definer.specified ? trg->relation->rel_ss_definer : Nullable() ); - const MetaString& userName = ssDefiner.specified && ssDefiner.value ? trg->relation->rel_owner_name.c_str() : ""; + const TriState& ssDefiner = trg->ssDefiner.isAssigned() ? trg->ssDefiner : + (trg->relation && trg->relation->rel_ss_definer.isAssigned() ? trg->relation->rel_ss_definer : TriState()); + const MetaString& userName = ssDefiner.asBool() ? + trg->relation->rel_owner_name.c_str() : ""; ContextManager ctxManager(tdbb, attInfo, trigger, CallerName(obj_trigger, trg->name, userName)); @@ -1606,7 +1607,7 @@ void ExtEngineManager::makeTrigger(thread_db* tdbb, CompilerScratch* csb, Jrd::T entryPointTrimmed.trim(); EngineAttachmentInfo* attInfo = getEngineAttachment(tdbb, engine); - const MetaString& userName = trg->ssDefiner.specified && trg->ssDefiner.value ? trg->owner.c_str() : ""; + const MetaString& userName = trg->ssDefiner.asBool() ? trg->owner.c_str() : ""; ContextManager ctxManager(tdbb, attInfo, attInfo->adminCharSet, CallerName(obj_trigger, trg->name, userName)); diff --git a/src/jrd/Function.epp b/src/jrd/Function.epp index c9c4e5bca9..e6531a10ce 100644 --- a/src/jrd/Function.epp +++ b/src/jrd/Function.epp @@ -224,7 +224,7 @@ Function* Function::loadMetadata(thread_db* tdbb, USHORT id, bool noscan, USHORT (X.RDB$PACKAGE_NAME.NULL ? NULL : X.RDB$PACKAGE_NAME))); function->owner = X.RDB$OWNER_NAME; - Nullable ssDefiner; + TriState ssDefiner; if (!X.RDB$SECURITY_CLASS.NULL) { @@ -250,7 +250,7 @@ Function* Function::loadMetadata(thread_db* tdbb, USHORT id, bool noscan, USHORT END_FOR } - if (!ssDefiner.specified) + if (!ssDefiner.isAssigned()) { if (!X.RDB$SQL_SECURITY.NULL) ssDefiner = (bool) X.RDB$SQL_SECURITY; @@ -258,7 +258,7 @@ Function* Function::loadMetadata(thread_db* tdbb, USHORT id, bool noscan, USHORT ssDefiner = MET_get_ss_definer(tdbb); } - if (ssDefiner.orElse(false)) + if (ssDefiner.asBool()) function->invoker = attachment->getUserId(function->owner); size_t count = 0; diff --git a/src/jrd/ProfilerManager.h b/src/jrd/ProfilerManager.h index 1d2d9093f5..1d8020d24c 100644 --- a/src/jrd/ProfilerManager.h +++ b/src/jrd/ProfilerManager.h @@ -29,7 +29,6 @@ #include "../common/PerformanceStopWatch.h" #include "../common/classes/auto.h" #include "../common/classes/fb_string.h" -#include "../common/classes/Nullable.h" #include "../common/classes/RefCounted.h" #include "../common/classes/TimerImpl.h" #include "../jrd/recsrc/RecordSource.h" diff --git a/src/jrd/Relation.cpp b/src/jrd/Relation.cpp index e8b41d14fb..f379ba4c1f 100644 --- a/src/jrd/Relation.cpp +++ b/src/jrd/Relation.cpp @@ -49,7 +49,7 @@ bool jrd_rel::isReplicating(thread_db* tdbb) if (rel_repl_state.isUnknown()) rel_repl_state = MET_get_repl_state(tdbb, rel_name); - return rel_repl_state.value; + return rel_repl_state.asBool(); } RelationPages* jrd_rel::getPagesInternal(thread_db* tdbb, TraNumber tran, bool allocPages) diff --git a/src/jrd/Relation.h b/src/jrd/Relation.h index f55af1de69..84ac8a22eb 100644 --- a/src/jrd/Relation.h +++ b/src/jrd/Relation.h @@ -29,6 +29,7 @@ #include "../jrd/pag.h" #include "../jrd/val.h" #include "../jrd/Attachment.h" +#include "../common/classes/TriState.h" namespace Jrd { @@ -263,7 +264,7 @@ public: TrigVector* rel_post_store; // Post-operation store trigger prim rel_primary_dpnds; // foreign dependencies on this relation's primary key frgn rel_foreign_refs; // foreign references to other relations' primary keys - Nullable rel_ss_definer; + TriState rel_ss_definer; TriState rel_repl_state; // replication state diff --git a/src/jrd/Routine.h b/src/jrd/Routine.h index 9002453ef9..6481ab29b3 100644 --- a/src/jrd/Routine.h +++ b/src/jrd/Routine.h @@ -28,7 +28,6 @@ #include "../jrd/QualifiedName.h" #include "../common/classes/NestConst.h" #include "../common/MsgMetadata.h" -#include "../common/classes/Nullable.h" namespace Jrd { diff --git a/src/jrd/Statement.cpp b/src/jrd/Statement.cpp index d503b47b1f..71aaacb840 100644 --- a/src/jrd/Statement.cpp +++ b/src/jrd/Statement.cpp @@ -779,7 +779,7 @@ void Statement::verifyTriggerAccess(thread_db* tdbb, jrd_rel* ownerRelation, if (view && (view->rel_flags & REL_sql_relation)) userName = view->rel_owner_name; } - else if (t.ssDefiner.specified && t.ssDefiner.value) + else if (t.ssDefiner.asBool()) userName = t.owner; Attachment* attachment = tdbb->getAttachment(); @@ -808,7 +808,7 @@ inline void Statement::triggersExternalAccess(thread_db* tdbb, ExternalAccessLis if (t.statement) { - const MetaName& userName = (t.ssDefiner.specified && t.ssDefiner.value) ? t.owner : user; + const MetaName& userName = t.ssDefiner.asBool() ? t.owner : user; t.statement->buildExternalAccess(tdbb, list, userName); } } @@ -874,7 +874,7 @@ void Statement::buildExternalAccess(thread_db* tdbb, ExternalAccessList& list, c continue; // should never happen, silence the compiler } - item->user = relation->rel_ss_definer.orElse(false) ? relation->rel_owner_name : user; + item->user = relation->rel_ss_definer.asBool() ? relation->rel_owner_name : user; if (list.find(*item, i)) continue; list.insert(i, *item); diff --git a/src/jrd/jrd.cpp b/src/jrd/jrd.cpp index 524e5e38ff..2ea490e162 100644 --- a/src/jrd/jrd.cpp +++ b/src/jrd/jrd.cpp @@ -941,7 +941,7 @@ void Trigger::compile(thread_db* tdbb) } statement->triggerName = name; - if (ssDefiner.orElse(false)) + if (ssDefiner.asBool()) statement->triggerInvoker = att->getUserId(owner); if (sysTrigger) diff --git a/src/jrd/jrd.h b/src/jrd/jrd.h index 7a706fdc48..438505e9e5 100644 --- a/src/jrd/jrd.h +++ b/src/jrd/jrd.h @@ -148,7 +148,7 @@ public: Firebird::string entryPoint; // External trigger entrypoint Firebird::string extBody; // External trigger body ExtEngineManager::Trigger* extTrigger; // External trigger - Nullable ssDefiner; + TriState ssDefiner; MetaName owner; // Owner for SQL SECURITY bool isActive() const; diff --git a/src/jrd/met.epp b/src/jrd/met.epp index 05bfc56fe2..97cb155ce3 100644 --- a/src/jrd/met.epp +++ b/src/jrd/met.epp @@ -116,7 +116,7 @@ static int partners_ast_relation(void*); static int rescan_ast_relation(void*); static ULONG get_rel_flags_from_FLAGS(USHORT); static void get_trigger(thread_db*, jrd_rel*, bid*, bid*, TrigVector**, const TEXT*, FB_UINT64, bool, - USHORT, const MetaName&, const string&, const bid*, Nullable ssDefiner); + USHORT, const MetaName&, const string&, const bid*, TriState ssDefiner); static bool get_type(thread_db*, USHORT*, const UCHAR*, const TEXT*); static void lookup_view_contexts(thread_db*, jrd_rel*); static void make_relation_scope_name(const TEXT*, const USHORT, string& str); @@ -125,7 +125,7 @@ static BoolExprNode* parse_field_validation_blr(thread_db* tdbb, bid* blob_id, c static bool resolve_charset_and_collation(thread_db*, USHORT*, const UCHAR*, const UCHAR*); static void save_trigger_data(thread_db*, TrigVector**, jrd_rel*, Statement*, blb*, blb*, const TEXT*, FB_UINT64, bool, USHORT, const MetaName&, const string&, - const bid*, Nullable ssDefiner); + const bid*, TriState ssDefiner); static void scan_partners(thread_db*, jrd_rel*); static bool verify_TRG_ignore_perm(thread_db*, const MetaName&); @@ -2025,7 +2025,7 @@ void MET_load_trigger(thread_db* tdbb, if (!TRG.RDB$ENTRYPOINT.NULL) // ODS_12_0 entryPoint = TRG.RDB$ENTRYPOINT; - Nullable ssDefiner; + TriState ssDefiner; // If SQL SECURITY for relation was not specified it will re-use DB default so we should not care about it if (!TRG.RDB$SQL_SECURITY.NULL) @@ -3351,7 +3351,7 @@ void MET_parse_sys_trigger(thread_db* tdbb, jrd_rel* relation) statement->flags |= Statement::FLAG_IGNORE_PERM; save_trigger_data(tdbb, ptr, relation, statement, NULL, NULL, NULL, type, true, 0, "", - "", NULL, Nullable()); + "", NULL, TriState()); } } END_FOR @@ -3506,7 +3506,7 @@ jrd_prc* MET_procedure(thread_db* tdbb, USHORT id, bool noscan, USHORT flags) } procedure->setId(P.RDB$PROCEDURE_ID); - Nullable ssDefiner; + TriState ssDefiner; if (!P.RDB$SECURITY_CLASS.NULL) procedure->setSecurityName(P.RDB$SECURITY_CLASS); @@ -3527,7 +3527,7 @@ jrd_prc* MET_procedure(thread_db* tdbb, USHORT id, bool noscan, USHORT flags) END_FOR } - if (!ssDefiner.specified) + if (ssDefiner.isUnknown()) { if (!P.RDB$SQL_SECURITY.NULL) ssDefiner = (bool) P.RDB$SQL_SECURITY; @@ -3537,7 +3537,7 @@ jrd_prc* MET_procedure(thread_db* tdbb, USHORT id, bool noscan, USHORT flags) procedure->owner = P.RDB$OWNER_NAME; - if (ssDefiner.orElse(false)) + if (ssDefiner.asBool()) procedure->invoker = attachment->getUserId(procedure->owner); procedure->setImplemented(true); @@ -4714,7 +4714,7 @@ static void get_trigger(thread_db* tdbb, jrd_rel* relation, const TEXT* name, FB_UINT64 type, bool sys_trigger, USHORT flags, const MetaName& engine, const string& entryPoint, - const bid* body, Nullable ssDefiner) + const bid* body, TriState ssDefiner) { /************************************** * @@ -5096,7 +5096,7 @@ static void save_trigger_data(thread_db* tdbb, TrigVector** ptr, jrd_rel* relati const TEXT* name, FB_UINT64 type, bool sys_trigger, USHORT flags, const MetaName& engine, const string& entryPoint, - const bid* body, Nullable ssDefiner) + const bid* body, TriState ssDefiner) { /************************************** * @@ -5644,7 +5644,7 @@ int MET_get_linger(thread_db* tdbb) return rc; } -Nullable MET_get_ss_definer(Jrd::thread_db* tdbb) +TriState MET_get_ss_definer(Jrd::thread_db* tdbb) { /************************************** * @@ -5658,7 +5658,7 @@ Nullable MET_get_ss_definer(Jrd::thread_db* tdbb) **************************************/ SET_TDBB(tdbb); Attachment* attachment = tdbb->getAttachment(); - Nullable r; + TriState r; AutoCacheRequest request(tdbb, irq_dbb_ss_definer, IRQ_REQUESTS); diff --git a/src/jrd/met_proto.h b/src/jrd/met_proto.h index 020eadb539..6e4b984912 100644 --- a/src/jrd/met_proto.h +++ b/src/jrd/met_proto.h @@ -148,6 +148,6 @@ void MET_store_dependencies(Jrd::thread_db*, Firebird::Array MET_get_ss_definer(Jrd::thread_db*); +TriState MET_get_ss_definer(Jrd::thread_db*); #endif // JRD_MET_PROTO_H diff --git a/src/jrd/optimizer/Optimizer.cpp b/src/jrd/optimizer/Optimizer.cpp index 7bfe9e5cb9..4c09fc8fb0 100644 --- a/src/jrd/optimizer/Optimizer.cpp +++ b/src/jrd/optimizer/Optimizer.cpp @@ -565,7 +565,7 @@ namespace Optimizer::Optimizer(thread_db* aTdbb, CompilerScratch* aCsb, RseNode* aRse, bool parentFirstRows) : PermanentStorage(*aTdbb->getDefaultPool()), tdbb(aTdbb), csb(aCsb), rse(aRse), - firstRows(rse->firstRows.orElse(parentFirstRows)), + firstRows(rse->firstRows.valueOr(parentFirstRows)), compileStreams(getPool()), bedStreams(getPool()), keyStreams(getPool()), diff --git a/src/jrd/optimizer/Optimizer.h b/src/jrd/optimizer/Optimizer.h index b9ad0e214f..ffd050c5ed 100644 --- a/src/jrd/optimizer/Optimizer.h +++ b/src/jrd/optimizer/Optimizer.h @@ -418,7 +418,7 @@ public: const auto defaultFirstRows = dbb->dbb_config->getOptimizeForFirstRows(); const auto attachment = tdbb->getAttachment(); - firstRows = attachment->att_opt_first_rows.orElse(defaultFirstRows); + firstRows = attachment->att_opt_first_rows.valueOr(defaultFirstRows); } return Optimizer(tdbb, csb, rse, firstRows).compile(nullptr); diff --git a/src/jrd/tra.cpp b/src/jrd/tra.cpp index 1e6b532f87..17507f1093 100644 --- a/src/jrd/tra.cpp +++ b/src/jrd/tra.cpp @@ -2990,7 +2990,7 @@ static void transaction_options(thread_db* tdbb, case isc_tpb_wait: if (!wait.assignOnce(true)) { - if (!wait.value) + if (!wait.asBool()) { ERR_post(Arg::Gds(isc_bad_tpb_content) << Arg::Gds(isc_tpb_conflicting_options) << Arg::Str("isc_tpb_wait") << @@ -3071,7 +3071,7 @@ static void transaction_options(thread_db* tdbb, ERR_post(Arg::Gds(isc_bad_tpb_content) << // 'Option @1 is not valid if @2 was used previously in TPB' Arg::Gds(isc_tpb_conflicting_options) << - Arg::Str("isc_tpb_read_consistency") << (rec_version.value ? + Arg::Str("isc_tpb_read_consistency") << (rec_version.asBool() ? Arg::Str("isc_tpb_rec_version") : Arg::Str("isc_tpb_no_rec_version")) ); } @@ -3079,7 +3079,7 @@ static void transaction_options(thread_db* tdbb, break; case isc_tpb_nowait: - if (lock_timeout.value) + if (lock_timeout.asBool()) { ERR_post(Arg::Gds(isc_bad_tpb_content) << Arg::Gds(isc_tpb_conflicting_options) << Arg::Str("isc_tpb_nowait") << @@ -3088,7 +3088,7 @@ static void transaction_options(thread_db* tdbb, if (!wait.assignOnce(false)) { - if (wait.value) + if (wait.asBool()) { ERR_post(Arg::Gds(isc_bad_tpb_content) << Arg::Gds(isc_tpb_conflicting_options) << Arg::Str("isc_tpb_nowait") << @@ -3107,7 +3107,7 @@ static void transaction_options(thread_db* tdbb, case isc_tpb_read: if (!read_only.assignOnce(true)) { - if (!read_only.value) + if (!read_only.asBool()) { ERR_post(Arg::Gds(isc_bad_tpb_content) << Arg::Gds(isc_tpb_conflicting_options) << Arg::Str("isc_tpb_read") << @@ -3133,7 +3133,7 @@ static void transaction_options(thread_db* tdbb, case isc_tpb_write: if (!read_only.assignOnce(false)) { - if (read_only.value) + if (read_only.asBool()) { ERR_post(Arg::Gds(isc_bad_tpb_content) << Arg::Gds(isc_tpb_conflicting_options) << Arg::Str("isc_tpb_write") << @@ -3159,7 +3159,7 @@ static void transaction_options(thread_db* tdbb, case isc_tpb_lock_write: // Cannot set a R/W table reservation if the whole txn is R/O. - if (read_only.value) + if (read_only.asBool()) { ERR_post(Arg::Gds(isc_bad_tpb_content) << Arg::Gds(isc_tpb_writelock_after_readtxn)); @@ -3285,7 +3285,7 @@ static void transaction_options(thread_db* tdbb, case isc_tpb_lock_timeout: { - if (wait.isAssigned() && !wait.value) + if (wait.isAssigned() && !wait.asBool()) { ERR_post(Arg::Gds(isc_bad_tpb_content) << Arg::Gds(isc_tpb_conflicting_options) << Arg::Str("isc_tpb_lock_timeout") << @@ -3419,7 +3419,7 @@ static void transaction_options(thread_db* tdbb, if (rec_version.isAssigned() && !(transaction->tra_flags & TRA_read_committed)) { - if (rec_version.value) + if (rec_version.asBool()) { ERR_post(Arg::Gds(isc_bad_tpb_content) << Arg::Gds(isc_tpb_option_without_rc) << Arg::Str("isc_tpb_rec_version")); diff --git a/src/jrd/val.h b/src/jrd/val.h index b564d57b16..c7c77714ed 100644 --- a/src/jrd/val.h +++ b/src/jrd/val.h @@ -31,7 +31,7 @@ #include "../include/fb_blk.h" #include "../common/classes/array.h" -#include "../common/classes/Nullable.h" +#include "../common/classes/TriState.h" #include "../jrd/intl_classes.h" #include "../jrd/MetaName.h" #include "../jrd/QualifiedName.h" diff --git a/src/jrd/vio.cpp b/src/jrd/vio.cpp index 36abd33a3c..59339451b7 100644 --- a/src/jrd/vio.cpp +++ b/src/jrd/vio.cpp @@ -6275,7 +6275,7 @@ static PrepareResult prepare_update(thread_db* tdbb, jrd_tra* transaction, TraNu // Wait as long as it takes (if not skipping locks) for an active // transaction which has modified the record. - state = writeLockSkipLocked == true ? + state = writeLockSkipLocked.asBool() ? TRA_wait(tdbb, transaction, rpb->rpb_transaction_nr, jrd_tra::tra_probe) : wait(tdbb, transaction, rpb); @@ -6309,7 +6309,7 @@ static PrepareResult prepare_update(thread_db* tdbb, jrd_tra* transaction, TraNu { tdbb->bumpRelStats(RuntimeStatistics::RECORD_CONFLICTS, relation->rel_id); - if (writeLockSkipLocked == true) + if (writeLockSkipLocked.asBool()) return PrepareResult::SKIP_LOCKED; // Cannot use Arg::Num here because transaction number is 64-bit unsigned integer @@ -6328,7 +6328,7 @@ static PrepareResult prepare_update(thread_db* tdbb, jrd_tra* transaction, TraNu // fall thru case tra_active: - return writeLockSkipLocked == true ? PrepareResult::SKIP_LOCKED : PrepareResult::LOCK_ERROR; + return writeLockSkipLocked.asBool() ? PrepareResult::SKIP_LOCKED : PrepareResult::LOCK_ERROR; case tra_dead: break;