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;