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

Replace Nullable by std::optional.

This commit is contained in:
Adriano dos Santos Fernandes 2023-09-18 20:27:14 -03:00
parent bf72356edb
commit c170e4b089
30 changed files with 498 additions and 329 deletions

View File

@ -1318,7 +1318,7 @@ int gbak(Firebird::UtilSvc* uSvc)
errNum = IN_SW_BURP_S;
else if (tdgbl->gbl_sw_no_reserve)
errNum = IN_SW_BURP_US;
else if (tdgbl->gbl_sw_replica.isAssigned())
else if (tdgbl->gbl_sw_replica.has_value())
errNum = IN_SW_BURP_REPLICA;
if (errNum != IN_SW_BURP_0)

View File

@ -29,6 +29,7 @@
#ifndef BURP_BURP_H
#define BURP_BURP_H
#include <optional>
#include <stdio.h>
#include "ibase.h"
#include "firebird/Interface.h"
@ -1033,7 +1034,7 @@ public:
ULONG io_buffer_size;
redirect_vals sw_redirect;
bool burp_throw;
Nullable<ReplicaMode> gbl_sw_replica;
std::optional<ReplicaMode> gbl_sw_replica;
UCHAR* blk_io_ptr;
int blk_io_cnt;

View File

@ -27,6 +27,7 @@
*/
#include "firebird.h"
#include <optional>
#include <stdio.h>
#include <string.h>
#include <errno.h>
@ -577,8 +578,8 @@ int RESTORE_restore (const TEXT* file_name, const TEXT* database_name)
dpb.insertByte(isc_dpb_force_write, tdgbl->hdr_forced_writes ? 1 : 0);
// set up the replica mode, if needed
if (tdgbl->gbl_sw_replica.isAssigned())
dpb.insertByte(isc_dpb_set_db_replica, tdgbl->gbl_sw_replica.value);
if (tdgbl->gbl_sw_replica.has_value())
dpb.insertByte(isc_dpb_set_db_replica, tdgbl->gbl_sw_replica.value());
Firebird::IAttachment* db_handle = provider->attachDatabase(&tdgbl->status_vector, database_name,
dpb.getBufferLength(), dpb.getBuffer());
@ -860,7 +861,7 @@ void create_database(BurpGlobals* tdgbl, Firebird::IProvider* provider, const TE
bool forced_writes = true; // turned on by default
ULONG page_buffers = 0;
USHORT SQL_dialect = 0;
Nullable<ReplicaMode> replica_mode;
std::optional<ReplicaMode> replica_mode;
tdgbl->gbl_database_file_name = file_name;
@ -949,7 +950,7 @@ void create_database(BurpGlobals* tdgbl, Firebird::IProvider* provider, const TE
tdgbl->gbl_sw_mode_val = db_read_only;
}
if (!tdgbl->gbl_sw_replica.isAssigned())
if (!tdgbl->gbl_sw_replica.has_value())
tdgbl->gbl_sw_replica = replica_mode;
if (tdgbl->gbl_sw_page_buffers)

View File

@ -133,32 +133,32 @@ unsigned StatementMetadata::buildInfoFlags(unsigned itemsLength, const UCHAR* it
// Get statement type.
unsigned StatementMetadata::getType()
{
if (!type.specified)
if (!type.has_value())
{
UCHAR info[] = {isc_info_sql_stmt_type};
UCHAR result[16];
getAndParse(sizeof(info), info, sizeof(result), result);
fb_assert(type.specified);
fb_assert(type.has_value());
}
return type.value;
return type.value();
}
unsigned StatementMetadata::getFlags()
{
if (!flags.specified)
if (!flags.has_value())
{
UCHAR info[] = {isc_info_sql_stmt_flags};
UCHAR result[16];
getAndParse(sizeof(info), info, sizeof(result), result);
fb_assert(flags.specified);
fb_assert(flags.has_value());
}
return flags.value;
return flags.value();
}
// Get statement plan.
@ -228,7 +228,7 @@ ISC_UINT64 StatementMetadata::getAffectedRecords()
// Reset the object to its initial state.
void StatementMetadata::clear()
{
type.specified = false;
type.reset();
legacyPlan = detailedPlan = "";
inputParameters->items.clear();
outputParameters->items.clear();
@ -432,14 +432,14 @@ bool StatementMetadata::fillFromCache(unsigned itemsLength, const UCHAR* items,
if (((itemsLength == 1 && items[0] == isc_info_sql_stmt_type) ||
(itemsLength == 2 && items[0] == isc_info_sql_stmt_type &&
(items[1] == isc_info_end || items[1] == 0))) &&
type.specified)
type.has_value())
{
if (bufferLength >= 8)
{
*buffer++ = isc_info_sql_stmt_type;
put_vax_short(buffer, 4);
buffer += 2;
put_vax_long(buffer, type.value);
put_vax_long(buffer, type.value());
buffer += 4;
*buffer = isc_info_end;
}

View File

@ -25,6 +25,7 @@
#ifndef COMMON_STATEMENT_METADATA_H
#define COMMON_STATEMENT_METADATA_H
#include <optional>
#include "firebird/Interface.h"
#include "iberror.h"
#include "../common/classes/Nullable.h"
@ -82,7 +83,7 @@ private:
private:
IStatement* statement;
Nullable<unsigned> type, flags;
std::optional<unsigned> type, flags;
string legacyPlan, detailedPlan;
RefPtr<Parameters> inputParameters, outputParameters;
};

View File

@ -341,7 +341,7 @@ void defineComputed(DsqlCompilerScratch* dsqlScratch, RelationSourceNode* relati
fb_assert(field->scale <= MAX_SCHAR);
saveDesc.dsc_scale = (SCHAR) field->scale;
saveDesc.dsc_sub_type = field->subType;
saveCharSetIdSpecified = field->charSetId.specified;
saveCharSetIdSpecified = field->charSetId.has_value();
field->dtype = 0;
field->length = 0;
@ -376,8 +376,7 @@ void defineComputed(DsqlCompilerScratch* dsqlScratch, RelationSourceNode* relati
if (field->dtype <= dtype_any_text)
{
field->charSetId = DSC_GET_CHARSET(&saveDesc);
field->charSetId.specified = saveCharSetIdSpecified;
field->charSetId = saveCharSetIdSpecified ? std::optional{DSC_GET_CHARSET(&saveDesc)} : std::nullopt;
field->collationId = DSC_GET_COLLATE(&saveDesc);
}
else
@ -396,7 +395,7 @@ void defineComputed(DsqlCompilerScratch* dsqlScratch, RelationSourceNode* relati
field->collationId = DSC_GET_COLLATE(&desc);
const USHORT adjust = field->dtype == dtype_varying ? sizeof(USHORT) : 0;
const USHORT bpc = METD_get_charset_bpc(dsqlScratch->getTransaction(), field->charSetId.value);
const USHORT bpc = METD_get_charset_bpc(dsqlScratch->getTransaction(), field->charSetId.value_or(CS_NONE));
field->charLength = (field->length - adjust) / bpc;
}
else if (field->dtype == dtype_blob)
@ -845,7 +844,7 @@ static void updateRdbFields(const TypeClause* type,
if (type->subType == isc_blob_text)
{
characterSetIdNull = FALSE;
characterSetId = type->charSetId.value;
characterSetId = type->charSetId.value_or(CS_NONE);
collationIdNull = FALSE;
collationId = type->collationId;
@ -872,7 +871,7 @@ static void updateRdbFields(const TypeClause* type,
}
characterSetIdNull = FALSE;
characterSetId = type->charSetId.value;
characterSetId = type->charSetId.value_or(CS_NONE);
collationIdNull = FALSE;
collationId = type->collationId;
@ -1605,7 +1604,7 @@ void CommentOnNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
return;
}
Nullable<string> description;
std::optional<string> description;
if (text.hasData())
description = text;
@ -1916,7 +1915,7 @@ bool CreateAlterFunctionNode::executeAlter(thread_db* tdbb, DsqlCompilerScratch*
// CVC: This is case of "returns <type> [by value|reference]".
// Some data types can not be returned as value.
if (returnType->udfMechanism.value == FUN_value &&
if (returnType->udfMechanism.value() == FUN_value &&
(field->dtype == dtype_text || field->dtype == dtype_varying ||
field->dtype == dtype_cstring || field->dtype == dtype_blob ||
field->dtype == dtype_timestamp))
@ -1969,8 +1968,8 @@ bool CreateAlterFunctionNode::executeAlter(thread_db* tdbb, DsqlCompilerScratch*
// We'll verify that SCALAR_ARRAY can't be used as a return type.
// The support for SCALAR_ARRAY is only for input parameters.
if (parameters[udfReturnPos - 1]->udfMechanism.specified &&
parameters[udfReturnPos - 1]->udfMechanism.value == FUN_scalar_array)
if (parameters[udfReturnPos - 1]->udfMechanism.has_value() &&
parameters[udfReturnPos - 1]->udfMechanism.value() == FUN_scalar_array)
{
status_exception::raise(
Arg::Gds(isc_sqlerr) << Arg::Num(-607) <<
@ -2232,12 +2231,12 @@ void CreateAlterFunctionNode::storeArgument(thread_db* tdbb, DsqlCompilerScratch
{
// CVC: I need to test returning blobs by descriptor before allowing the
// change there. For now, I ignore the return type specification.
const bool freeIt = parameter->udfMechanism.value < 0;
const bool freeIt = parameter->udfMechanism.value() < 0;
ARG.RDB$MECHANISM = (SSHORT) ((freeIt ? -1 : 1) * FUN_blob_struct);
// If we have the FREE_IT set then the blob has to be freed on return.
}
else if (parameter->udfMechanism.specified)
ARG.RDB$MECHANISM = (SSHORT) parameter->udfMechanism.value;
else if (parameter->udfMechanism.has_value())
ARG.RDB$MECHANISM = (SSHORT) parameter->udfMechanism.value();
else if (type->dtype == dtype_blob)
ARG.RDB$MECHANISM = (SSHORT) FUN_blob_struct;
else
@ -3354,10 +3353,10 @@ void TriggerDefinition::store(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
TRG.RDB$RELATION_NAME.NULL = relationName.isEmpty();
strcpy(TRG.RDB$RELATION_NAME, relationName.c_str());
fb_assert(type.specified);
TRG.RDB$TRIGGER_TYPE = type.value;
fb_assert(type.has_value());
TRG.RDB$TRIGGER_TYPE = type.value();
TRG.RDB$TRIGGER_SEQUENCE = (!position.specified ? 0 : position.value);
TRG.RDB$TRIGGER_SEQUENCE = position.value_or(0);
TRG.RDB$TRIGGER_INACTIVE = (!active.specified ? 0 : (USHORT) !active.value);
}
END_STORE
@ -3377,7 +3376,7 @@ bool TriggerDefinition::modify(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch
TRG IN RDB$TRIGGERS
WITH TRG.RDB$TRIGGER_NAME EQ name.c_str()
{
if (type.specified && type.value != (FB_UINT64) TRG.RDB$TRIGGER_TYPE &&
if (type.has_value() && type != (FB_UINT64) TRG.RDB$TRIGGER_TYPE &&
TRG.RDB$RELATION_NAME.NULL)
{
status_exception::raise(
@ -3424,11 +3423,11 @@ bool TriggerDefinition::modify(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch
if (relationName.hasData())
strcpy(TRG.RDB$RELATION_NAME, relationName.c_str());
if (type.specified)
TRG.RDB$TRIGGER_TYPE = type.value;
if (type.has_value())
TRG.RDB$TRIGGER_TYPE = type.value();
if (position.specified)
TRG.RDB$TRIGGER_SEQUENCE = position.value;
if (position.has_value())
TRG.RDB$TRIGGER_SEQUENCE = position.value();
if (active.specified)
TRG.RDB$TRIGGER_INACTIVE = (USHORT) !active.value;
@ -3465,12 +3464,12 @@ bool TriggerDefinition::modify(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch
attachment->storeMetaDataBlob(tdbb, transaction, &TRG.RDB$TRIGGER_SOURCE, source);
}
if (ssDefiner.specified)
if (ssDefiner.has_value())
{
if (ssDefiner.value != SS_DROP)
if (ssDefiner.value() != SS_DROP)
{
TRG.RDB$SQL_SECURITY.NULL = FALSE;
TRG.RDB$SQL_SECURITY = ssDefiner.value == SS_DEFINER ? FB_TRUE : FB_FALSE;
TRG.RDB$SQL_SECURITY = ssDefiner.value() == SS_DEFINER ? FB_TRUE : FB_FALSE;
}
else
TRG.RDB$SQL_SECURITY.NULL = TRUE;
@ -3509,14 +3508,14 @@ DdlNode* CreateAlterTriggerNode::dsqlPass(DsqlCompilerScratch* dsqlScratch)
{
dsqlScratch->flags |= (DsqlCompilerScratch::FLAG_BLOCK | DsqlCompilerScratch::FLAG_TRIGGER);
if (type.specified)
if (type.has_value())
{
if (create && // ALTER TRIGGER doesn't accept table name
((relationName.hasData() &&
(type.value & (unsigned) TRIGGER_TYPE_MASK) != (unsigned) TRIGGER_TYPE_DML) ||
(type.value() & (unsigned) TRIGGER_TYPE_MASK) != (unsigned) TRIGGER_TYPE_DML) ||
(relationName.isEmpty() &&
(type.value & (unsigned) TRIGGER_TYPE_MASK) != (unsigned) TRIGGER_TYPE_DB &&
(type.value & (unsigned) TRIGGER_TYPE_MASK) != (unsigned) TRIGGER_TYPE_DDL)))
(type.value() & (unsigned) TRIGGER_TYPE_MASK) != (unsigned) TRIGGER_TYPE_DB &&
(type.value() & (unsigned) TRIGGER_TYPE_MASK) != (unsigned) TRIGGER_TYPE_DDL)))
{
status_exception::raise(
Arg::Gds(isc_dsql_command_err) <<
@ -3524,7 +3523,7 @@ DdlNode* CreateAlterTriggerNode::dsqlPass(DsqlCompilerScratch* dsqlScratch)
}
}
if (create && ssDefiner.specified && ssDefiner.value == TriggerDefinition::SS_DROP)
if (create && ssDefiner.has_value() && ssDefiner.value() == TriggerDefinition::SS_DROP)
status_exception::raise(Arg::Gds(isc_dsql_command_err) << Arg::Gds(isc_dsql_invalid_drop_ss_clause));
return DdlNode::dsqlPass(dsqlScratch);
@ -3540,7 +3539,7 @@ void CreateAlterTriggerNode::checkPermission(thread_db* tdbb, jrd_tra* transacti
TRG IN RDB$TRIGGERS
WITH TRG.RDB$TRIGGER_NAME EQ name.c_str()
{
if (!type.specified && !TRG.RDB$TRIGGER_TYPE.NULL)
if (!type.has_value() && !TRG.RDB$TRIGGER_TYPE.NULL)
type = TRG.RDB$TRIGGER_TYPE;
if (relationName.isEmpty() && !TRG.RDB$RELATION_NAME.NULL)
@ -3548,7 +3547,7 @@ void CreateAlterTriggerNode::checkPermission(thread_db* tdbb, jrd_tra* transacti
}
END_FOR
if (!type.specified)
if (!type.has_value())
status_exception::raise(Arg::Gds(isc_dyn_trig_not_found) << Arg::Str(name));
}
@ -3637,7 +3636,7 @@ void CreateAlterTriggerNode::compile(thread_db* /*tdbb*/, DsqlCompilerScratch* d
const string temp = relationNode->alias; // always empty?
if (hasOldContext(type.value))
if (hasOldContext(type.value()))
{
relationNode->alias = OLD_CONTEXT_NAME;
dsql_ctx* oldContext = PASS1_make_context(dsqlScratch, relationNode);
@ -3646,7 +3645,7 @@ void CreateAlterTriggerNode::compile(thread_db* /*tdbb*/, DsqlCompilerScratch* d
else
dsqlScratch->contextNumber++;
if (hasNewContext(type.value))
if (hasNewContext(type.value()))
{
relationNode->alias = NEW_CONTEXT_NAME;
dsql_ctx* newContext = PASS1_make_context(dsqlScratch, relationNode);
@ -5078,7 +5077,7 @@ void AlterDomainNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
}
DSC_make_descriptor(&newDom.dyn_dsc, blr_dtypes[type->dtype], type->scale,
typeLength, type->subType, type->charSetId.value, type->collationId);
typeLength, type->subType, type->charSetId.value_or(CS_NONE), type->collationId);
newDom.dyn_fld_name = name;
newDom.dyn_charbytelen = typeLength;
@ -5643,11 +5642,11 @@ void CreateAlterSequenceNode::executeCreate(thread_db* tdbb, DsqlCompilerScratch
executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_BEFORE, DDL_TRIGGER_CREATE_SEQUENCE,
name, NULL);
const SINT64 val = value.orElse(1);
const SINT64 val = value.value_or(1);
SLONG initialStep = 1;
if (step.specified)
if (step.has_value())
{
initialStep = step.value;
initialStep = step.value();
if (initialStep == 0)
status_exception::raise(Arg::Gds(isc_dyn_cant_use_zero_increment) << Arg::Str(name));
}
@ -5681,11 +5680,11 @@ bool CreateAlterSequenceNode::executeAlter(thread_db* tdbb, DsqlCompilerScratch*
executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_BEFORE, DDL_TRIGGER_ALTER_SEQUENCE,
name, NULL);
fb_assert(restartSpecified && value.specified);
const SINT64 val = value.specified ? value.value : 0;
if (step.specified)
fb_assert(restartSpecified && value.has_value());
const SINT64 val = value.value_or(0);
if (step.has_value())
{
const SLONG newStep = step.value;
const SLONG newStep = step.value();
if (newStep == 0)
status_exception::raise(Arg::Gds(isc_dyn_cant_use_zero_increment) << Arg::Str(name));
@ -5724,9 +5723,9 @@ bool CreateAlterSequenceNode::executeAlter(thread_db* tdbb, DsqlCompilerScratch*
const SLONG id = X.RDB$GENERATOR_ID;
if (step.specified)
if (step.has_value())
{
const SLONG newStep = step.value;
const SLONG newStep = step.value();
if (newStep == 0)
status_exception::raise(Arg::Gds(isc_dyn_cant_use_zero_increment) << Arg::Str(name));
@ -5741,7 +5740,7 @@ bool CreateAlterSequenceNode::executeAlter(thread_db* tdbb, DsqlCompilerScratch*
if (restartSpecified)
{
const SINT64 oldValue = !X.RDB$INITIAL_VALUE.NULL ? X.RDB$INITIAL_VALUE : 0;
const SINT64 newValue = value.specified ? value.value : oldValue;
const SINT64 newValue = value.value_or(oldValue);
transaction->getGenIdCache()->put(id,
newValue - (!X.RDB$GENERATOR_INCREMENT.NULL ? X.RDB$GENERATOR_INCREMENT : 1));
@ -5947,16 +5946,16 @@ void RelationNode::FieldDefinition::modify(thread_db* tdbb, jrd_tra* transaction
RFR.RDB$BASE_FIELD.NULL = TRUE;
///RFR.RDB$UPDATE_FLAG.NULL = TRUE;
if (collationId.specified)
if (collationId.has_value())
{
RFR.RDB$COLLATION_ID.NULL = FALSE;
RFR.RDB$COLLATION_ID = collationId.value;
RFR.RDB$COLLATION_ID = collationId.value();
}
SLONG fieldPos = -1;
if (position.specified)
fieldPos = position.value;
if (position.has_value())
fieldPos = position.value();
else
{
DYN_UTIL_generate_field_position(tdbb, relationName, &fieldPos);
@ -5976,14 +5975,14 @@ void RelationNode::FieldDefinition::modify(thread_db* tdbb, jrd_tra* transaction
strcpy(RFR.RDB$BASE_FIELD, baseField.c_str());
}
if (viewContext.specified)
if (viewContext.has_value())
{
fb_assert(baseField.hasData());
RFR.RDB$VIEW_CONTEXT.NULL = FALSE;
RFR.RDB$VIEW_CONTEXT = viewContext.value;
RFR.RDB$VIEW_CONTEXT = viewContext.value();
DYN_UTIL_find_field_source(tdbb, transaction, relationName, viewContext.value,
DYN_UTIL_find_field_source(tdbb, transaction, relationName, viewContext.value(),
baseField.c_str(), RFR.RDB$FIELD_SOURCE);
}
END_MODIFY
@ -6017,10 +6016,10 @@ void RelationNode::FieldDefinition::store(thread_db* tdbb, jrd_tra* transaction)
RFR.RDB$BASE_FIELD.NULL = TRUE;
///RFR.RDB$UPDATE_FLAG.NULL = TRUE;
if (collationId.specified)
if (collationId.has_value())
{
RFR.RDB$COLLATION_ID.NULL = FALSE;
RFR.RDB$COLLATION_ID = collationId.value;
RFR.RDB$COLLATION_ID = collationId.value();
}
if (identitySequence.hasData())
@ -6029,7 +6028,7 @@ void RelationNode::FieldDefinition::store(thread_db* tdbb, jrd_tra* transaction)
strcpy(RFR.RDB$GENERATOR_NAME, identitySequence.c_str());
RFR.RDB$IDENTITY_TYPE.NULL = FALSE;
RFR.RDB$IDENTITY_TYPE = identityType.value;
RFR.RDB$IDENTITY_TYPE = identityType.value();
}
if (notNullFlag.specified)
@ -6053,8 +6052,8 @@ void RelationNode::FieldDefinition::store(thread_db* tdbb, jrd_tra* transaction)
SLONG fieldPos = -1;
if (position.specified)
fieldPos = position.value;
if (position.has_value())
fieldPos = position.value();
else
{
DYN_UTIL_generate_field_position(tdbb, relationName, &fieldPos);
@ -6074,14 +6073,14 @@ void RelationNode::FieldDefinition::store(thread_db* tdbb, jrd_tra* transaction)
strcpy(RFR.RDB$BASE_FIELD, baseField.c_str());
}
if (viewContext.specified)
if (viewContext.has_value())
{
fb_assert(baseField.hasData());
RFR.RDB$VIEW_CONTEXT.NULL = FALSE;
RFR.RDB$VIEW_CONTEXT = viewContext.value;
RFR.RDB$VIEW_CONTEXT = viewContext.value();
DYN_UTIL_find_field_source(tdbb, transaction, relationName, viewContext.value,
DYN_UTIL_find_field_source(tdbb, transaction, relationName, viewContext.value(),
baseField.c_str(), RFR.RDB$FIELD_SOURCE);
}
}
@ -6357,7 +6356,7 @@ void RelationNode::defineField(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch
if (clause->identityOptions)
{
if (clause->identityOptions->increment.orElse(1) == 0)
if (clause->identityOptions->increment.value_or(1) == 0)
{
status_exception::raise(Arg::Gds(isc_dyn_cant_use_zero_inc_ident) <<
Arg::Str(field->fld_name) <<
@ -6378,8 +6377,8 @@ void RelationNode::defineField(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch
CreateAlterSequenceNode::store(tdbb, transaction, fieldDefinition.identitySequence,
fb_sysflag_identity_generator,
clause->identityOptions->startValue.orElse(1),
clause->identityOptions->increment.orElse(1));
clause->identityOptions->startValue.value_or(1),
clause->identityOptions->increment.value_or(1));
}
BlrDebugWriter::BlrData defaultValue;
@ -7341,9 +7340,9 @@ void CreateRelationNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScrat
DYN_UTIL_check_unique_name(tdbb, transaction, name, obj_relation);
fb_assert(relationType.specified);
fb_assert(relationType.has_value());
checkRelationTempScope(tdbb, transaction, name, relationType.value);
checkRelationTempScope(tdbb, transaction, name, relationType.value());
AutoCacheRequest request(tdbb, drq_s_rels2, DYN_REQUESTS);
@ -7353,7 +7352,7 @@ void CreateRelationNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScrat
strcpy(REL.RDB$RELATION_NAME, name.c_str());
REL.RDB$SYSTEM_FLAG = 0;
REL.RDB$FLAGS = REL_sql;
REL.RDB$RELATION_TYPE = relationType.value;
REL.RDB$RELATION_TYPE = relationType.value();
if (ssDefiner.specified)
{
@ -8041,23 +8040,23 @@ void AlterRelationNode::modifyField(thread_db* tdbb, DsqlCompilerScratch* dsqlSc
{
const SINT64 val =
clause->identityOptions->startValue
.orElse(!GEN.RDB$INITIAL_VALUE.NULL ? GEN.RDB$INITIAL_VALUE : 0) -
.value_or(!GEN.RDB$INITIAL_VALUE.NULL ? GEN.RDB$INITIAL_VALUE : 0) -
clause->identityOptions->increment
.orElse(!GEN.RDB$GENERATOR_INCREMENT.NULL ? GEN.RDB$GENERATOR_INCREMENT : 1);
.value_or(!GEN.RDB$GENERATOR_INCREMENT.NULL ? GEN.RDB$GENERATOR_INCREMENT : 1);
transaction->getGenIdCache()->put(id, val);
}
if (clause->identityOptions->type.specified)
if (clause->identityOptions->type.has_value())
{
MODIFY RFR
RFR.RDB$IDENTITY_TYPE = clause->identityOptions->type.value;
RFR.RDB$IDENTITY_TYPE = clause->identityOptions->type.value();
END_MODIFY
}
if (clause->identityOptions->increment.specified)
if (clause->identityOptions->increment.has_value())
{
if (clause->identityOptions->increment.value == 0)
if (clause->identityOptions->increment.value() == 0)
{
status_exception::raise(Arg::Gds(isc_dyn_cant_use_zero_inc_ident) <<
Arg::Str(field->fld_name) <<
@ -8065,7 +8064,7 @@ void AlterRelationNode::modifyField(thread_db* tdbb, DsqlCompilerScratch* dsqlSc
}
MET_update_generator_increment(tdbb, id,
clause->identityOptions->increment.value);
clause->identityOptions->increment.value());
}
dsc desc;
@ -9014,7 +9013,7 @@ void CreateAlterViewNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScra
const USHORT adjust =
(desc.dsc_dtype == dtype_varying) ? sizeof(USHORT) : 0;
const USHORT bpc =
METD_get_charset_bpc(dsqlScratch->getTransaction(), newField.charSetId.value);
METD_get_charset_bpc(dsqlScratch->getTransaction(), newField.charSetId.value_or(CS_NONE));
newField.charLength = (newField.length - adjust) / bpc;
}
@ -10182,7 +10181,6 @@ string CreateShadowNode::internalPrint(NodePrinter& printer) const
NODE_PRINT(printer, number);
NODE_PRINT(printer, manual);
NODE_PRINT(printer, conditional);
NODE_PRINT(printer, firstLength);
NODE_PRINT(printer, files);
return "CreateShadowNode";

View File

@ -23,6 +23,7 @@
#ifndef DSQL_DDL_NODES_H
#define DSQL_DDL_NODES_H
#include <optional>
#include "firebird/impl/blr.h"
#include "../jrd/dyn.h"
#include "../common/msg_encode.h"
@ -174,7 +175,7 @@ public:
NestConst<dsql_fld> type;
NestConst<ValueSourceClause> defaultClause;
NestConst<ValueExprNode> parameterExpr;
Nullable<int> udfMechanism;
std::optional<int> udfMechanism;
};
@ -696,16 +697,16 @@ protected:
public:
MetaName name;
MetaName relationName;
Nullable<FB_UINT64> type;
std::optional<FB_UINT64> type;
Nullable<bool> active;
Nullable<int> position;
std::optional<int> position;
NestConst<ExternalClause> external;
Firebird::string source;
Firebird::ByteChunk blrData;
Firebird::ByteChunk debugData;
USHORT systemFlag;
bool fkTrigger;
Nullable<SqlSecurity> ssDefiner;
std::optional<SqlSecurity> ssDefiner;
};
@ -1116,7 +1117,6 @@ public:
Arg::Num(this->column));
}
*/
value.specified = false;
}
static SSHORT store(thread_db* tdbb, jrd_tra* transaction, const MetaName& name,
@ -1147,8 +1147,8 @@ public:
bool legacy;
bool restartSpecified;
const MetaName name;
BaseNullable<SINT64> value;
Nullable<SLONG> step;
std::optional<SINT64> value;
std::optional<SLONG> step;
};
@ -1210,13 +1210,13 @@ public:
MetaName relationName;
MetaName fieldSource;
MetaName identitySequence;
Nullable<IdentityType> identityType;
Nullable<USHORT> collationId;
std::optional<IdentityType> identityType;
std::optional<USHORT> collationId;
Nullable<bool> notNullFlag; // true = NOT NULL / false = NULL
Nullable<USHORT> position;
std::optional<USHORT> position;
Firebird::string defaultSource;
Firebird::ByteChunk defaultValue;
Nullable<USHORT> viewContext;
std::optional<USHORT> viewContext;
MetaName baseField;
};
@ -1386,9 +1386,9 @@ public:
{
}
Nullable<IdentityType> type;
Nullable<SINT64> startValue;
Nullable<SLONG> increment;
std::optional<IdentityType> type;
std::optional<SINT64> startValue;
std::optional<SLONG> increment;
bool restart; // used in ALTER
};
@ -1562,8 +1562,7 @@ public:
CreateRelationNode(MemoryPool& p, RelationSourceNode* aDsqlNode,
const Firebird::string* aExternalFile = NULL)
: RelationNode(p, aDsqlNode),
externalFile(aExternalFile),
relationType(rel_persistent)
externalFile(aExternalFile)
{
}
@ -1583,7 +1582,7 @@ private:
public:
const Firebird::string* externalFile;
Nullable<rel_t> relationType;
std::optional<rel_t> relationType = rel_persistent;
bool preserveRowsOpt;
bool deleteRowsOpt;
};
@ -1977,7 +1976,6 @@ public:
SSHORT number;
bool manual;
bool conditional;
Nullable<SLONG> firstLength;
Firebird::Array<NestConst<DbFileClause> > files;
};
@ -2468,14 +2466,4 @@ public:
} // namespace
template <>
class NullableClear<Jrd::TriggerDefinition::SqlSecurity> // TriggerDefinition::SqlSecurity especialization for NullableClear
{
public:
static void clear(Jrd::TriggerDefinition::SqlSecurity& v)
{
v = Jrd::TriggerDefinition::SS_INVOKER;
}
};
#endif // DSQL_DDL_NODES_H

View File

@ -2802,7 +2802,7 @@ dsc* ArithmeticNode::addSqlTime(thread_db* tdbb, const dsc* desc, impure_value*
bool op1_is_time = op1_desc->isTime();
bool op2_is_time = op2_desc->isTime();
Nullable<USHORT> op1_tz, op2_tz;
std::optional<USHORT> op1_tz, op2_tz;
if (op1_desc->dsc_dtype == dtype_sql_time_tz)
op1_tz = ((ISC_TIME_TZ*) op1_desc->dsc_address)->time_zone;
@ -2813,14 +2813,14 @@ dsc* ArithmeticNode::addSqlTime(thread_db* tdbb, const dsc* desc, impure_value*
dsc op1_tz_desc, op2_tz_desc;
ISC_TIME_TZ op1_time_tz, op2_time_tz;
if (op1_desc->dsc_dtype == dtype_sql_time && op2_is_time && op2_tz.specified)
if (op1_desc->dsc_dtype == dtype_sql_time && op2_is_time && op2_tz.has_value())
{
op1_tz_desc.makeTimeTz(&op1_time_tz);
MOV_move(tdbb, const_cast<dsc*>(op1_desc), &op1_tz_desc);
op1_desc = &op1_tz_desc;
}
if (op2_desc->dsc_dtype == dtype_sql_time && op1_is_time && op1_tz.specified)
if (op2_desc->dsc_dtype == dtype_sql_time && op1_is_time && op1_tz.has_value())
{
op2_tz_desc.makeTimeTz(&op2_time_tz);
MOV_move(tdbb, const_cast<dsc*>(op2_desc), &op2_tz_desc);
@ -2888,18 +2888,18 @@ dsc* ArithmeticNode::addSqlTime(thread_db* tdbb, const dsc* desc, impure_value*
value->vlu_misc.vlu_sql_time_tz.utc_time = d2;
result->dsc_dtype = op1_tz.specified || op2_tz.specified ? dtype_sql_time_tz : dtype_sql_time;
result->dsc_dtype = op1_tz.has_value() || op2_tz.has_value() ? dtype_sql_time_tz : dtype_sql_time;
result->dsc_length = type_lengths[result->dsc_dtype];
result->dsc_scale = 0;
result->dsc_sub_type = 0;
result->dsc_address = (UCHAR*) &value->vlu_misc.vlu_sql_time_tz;
fb_assert(!(op1_tz.specified && op2_tz.specified));
fb_assert(!(op1_tz.has_value() && op2_tz.has_value()));
if (op1_tz.specified)
value->vlu_misc.vlu_sql_time_tz.time_zone = op1_tz.value;
else if (op2_tz.specified)
value->vlu_misc.vlu_sql_time_tz.time_zone = op2_tz.value;
if (op1_tz.has_value())
value->vlu_misc.vlu_sql_time_tz.time_zone = op1_tz.value();
else if (op2_tz.has_value())
value->vlu_misc.vlu_sql_time_tz.time_zone = op2_tz.value();
return result;
}
@ -2917,7 +2917,7 @@ dsc* ArithmeticNode::addTimeStamp(thread_db* tdbb, const dsc* desc, impure_value
const dsc* op1_desc = &value->vlu_desc;
const dsc* op2_desc = desc;
Nullable<USHORT> op1_tz, op2_tz;
std::optional<USHORT> op1_tz, op2_tz;
if (op1_desc->dsc_dtype == dtype_sql_time_tz)
op1_tz = ((ISC_TIME_TZ*) op1_desc->dsc_address)->time_zone;
@ -2934,7 +2934,7 @@ dsc* ArithmeticNode::addTimeStamp(thread_db* tdbb, const dsc* desc, impure_value
ISC_TIME_TZ op1_time_tz, op2_time_tz;
if ((op1_desc->dsc_dtype == dtype_sql_time || op1_desc->dsc_dtype == dtype_timestamp) &&
op2_desc->isDateTime() && op2_tz.specified)
op2_desc->isDateTime() && op2_tz.has_value())
{
if (op1_desc->dsc_dtype == dtype_sql_time)
op1_tz_desc.makeTimeTz(&op1_time_tz);
@ -2946,7 +2946,7 @@ dsc* ArithmeticNode::addTimeStamp(thread_db* tdbb, const dsc* desc, impure_value
}
if ((op2_desc->dsc_dtype == dtype_sql_time || op2_desc->dsc_dtype == dtype_timestamp) &&
op1_desc->isDateTime() && op1_tz.specified)
op1_desc->isDateTime() && op1_tz.has_value())
{
if (op2_desc->dsc_dtype == dtype_sql_time)
op2_tz_desc.makeTimeTz(&op2_time_tz);
@ -3122,18 +3122,18 @@ dsc* ArithmeticNode::addTimeStamp(thread_db* tdbb, const dsc* desc, impure_value
ERR_post(Arg::Gds(isc_datetime_range_exceeded));
}
fb_assert(!(op1_tz.specified && op2_tz.specified));
fb_assert(!(op1_tz.has_value() && op2_tz.has_value()));
result->dsc_dtype = op1_tz.specified || op2_tz.specified ? dtype_timestamp_tz : dtype_timestamp;
result->dsc_dtype = op1_tz.has_value() || op2_tz.has_value() ? dtype_timestamp_tz : dtype_timestamp;
result->dsc_length = type_lengths[result->dsc_dtype];
result->dsc_scale = 0;
result->dsc_sub_type = 0;
result->dsc_address = (UCHAR*) &value->vlu_misc.vlu_timestamp_tz;
if (op1_tz.specified)
value->vlu_misc.vlu_timestamp_tz.time_zone = op1_tz.value;
else if (op2_tz.specified)
value->vlu_misc.vlu_timestamp_tz.time_zone = op2_tz.value;
if (op1_tz.has_value())
value->vlu_misc.vlu_timestamp_tz.time_zone = op1_tz.value();
else if (op2_tz.has_value())
value->vlu_misc.vlu_timestamp_tz.time_zone = op2_tz.value();
return result;
}
@ -5180,7 +5180,7 @@ ValueExprNode* DerivedExprNode::copy(thread_db* tdbb, NodeCopier& copier) const
i = copier.remap[i];
}
fb_assert(!cursorNumber.specified);
fb_assert(!cursorNumber.has_value());
return node;
}
@ -5230,8 +5230,8 @@ ValueExprNode* DerivedExprNode::pass2(thread_db* tdbb, CompilerScratch* csb)
dsc* DerivedExprNode::execute(thread_db* tdbb, Request* request) const
{
if (cursorNumber.specified)
request->req_cursors[cursorNumber.value]->checkState(request);
if (cursorNumber.has_value())
request->req_cursors[cursorNumber.value()]->checkState(request);
dsc* value = NULL;
@ -6652,7 +6652,7 @@ ValueExprNode* FieldNode::copy(thread_db* tdbb, NodeCopier& copier) const
stream = copier.remap[stream];
}
fb_assert(!cursorNumber.specified);
fb_assert(!cursorNumber.has_value());
return PAR_gen_field(tdbb, stream, fldId, byId);
}
@ -6910,8 +6910,8 @@ dsc* FieldNode::execute(thread_db* tdbb, Request* request) const
{
impure_value* const impure = request->getImpure<impure_value>(impureOffset);
if (cursorNumber.specified)
request->req_cursors[cursorNumber.value]->checkState(request);
if (cursorNumber.has_value())
request->req_cursors[cursorNumber.value()]->checkState(request);
record_param& rpb = request->req_rpb[fieldStream];
Record* record = rpb.rpb_record;

View File

@ -23,6 +23,7 @@
#ifndef DSQL_EXPR_NODES_H
#define DSQL_EXPR_NODES_H
#include <optional>
#include "firebird/impl/blr.h"
#include "../dsql/Nodes.h"
#include "../dsql/NodePrinter.h"
@ -683,7 +684,7 @@ public:
public:
NestConst<ValueExprNode> arg;
Firebird::Array<StreamType> internalStreamList;
Nullable<USHORT> cursorNumber;
std::optional<USHORT> cursorNumber;
};
@ -825,7 +826,7 @@ public:
NestConst<ValueListNode> dsqlIndices;
const Format* format;
const StreamType fieldStream;
Nullable<USHORT> cursorNumber;
std::optional<USHORT> cursorNumber;
const USHORT fieldId;
const bool byId;
bool dsqlCursorField;

View File

@ -23,6 +23,7 @@
#ifndef DSQL_NODE_PRINTER_H
#define DSQL_NODE_PRINTER_H
#include <optional>
#include "../dsql/Nodes.h"
#define NODE_PRINT(var, property) var.print(STRINGIZE(property), property)
@ -272,6 +273,13 @@ public:
print(s, nullable.value);
}
template <typename T>
void print(const Firebird::string& s, const std::optional<T>& optional)
{
if (optional.has_value())
print(s, optional.value());
}
template <typename T>
void print(const Firebird::string&, const Firebird::Pair<T>&)
{

View File

@ -23,6 +23,7 @@
#ifndef DSQL_PARSER_H
#define DSQL_PARSER_H
#include <optional>
#include "../dsql/dsql.h"
#include "../dsql/DdlNodes.h"
#include "../dsql/BoolNodes.h"
@ -250,6 +251,13 @@ private:
clause = value;
}
template <typename T>
void setClause(std::optional<T>& clause, const char* duplicateMsg, const T& value)
{
checkDuplicateClause(clause, duplicateMsg);
clause = value;
}
template <typename T>
void setClause(BaseNullable<T>& clause, const char* duplicateMsg, const BaseNullable<T>& value)
{
@ -260,6 +268,16 @@ private:
}
}
template <typename T>
void setClause(std::optional<T>& clause, const char* duplicateMsg, const std::optional<T>& value)
{
if (value.has_value())
{
checkDuplicateClause(clause, duplicateMsg);
clause = value.value();
}
}
template <typename T1, typename T2>
void setClause(NestConst<T1>& clause, const char* duplicateMsg, const T2& value)
{
@ -312,6 +330,12 @@ private:
return clause.specified;
}
template <typename T>
bool isDuplicateClause(const std::optional<T>& clause)
{
return clause.has_value();
}
template <typename T>
bool isDuplicateClause(const Firebird::Array<T>& clause)
{

View File

@ -77,7 +77,7 @@ static dsql_par* dsqlFindDbKey(const DsqlDmlStatement*, const RelationSourceNode
static dsql_par* dsqlFindRecordVersion(const DsqlDmlStatement*, const RelationSourceNode*);
static void dsqlGenEofAssignment(DsqlCompilerScratch* dsqlScratch, SSHORT value);
static void dsqlGenReturning(DsqlCompilerScratch* dsqlScratch, ReturningClause* returning,
Nullable<USHORT> localTableNumber);
std::optional<USHORT> localTableNumber);
static void dsqlGenReturningLocalTableCursor(DsqlCompilerScratch* dsqlScratch, ReturningClause* returning,
USHORT localTableNumber);
static void dsqlGenReturningLocalTableDecl(DsqlCompilerScratch* dsqlScratch, USHORT tableNumber);
@ -111,7 +111,7 @@ static void postTriggerAccess(CompilerScratch* csb, jrd_rel* ownerRelation,
static void preModifyEraseTriggers(thread_db* tdbb, TrigVector** trigs,
StmtNode::WhichTrigger whichTrig, record_param* rpb, record_param* rec, TriggerAction op);
static void preprocessAssignments(thread_db* tdbb, CompilerScratch* csb,
StreamType stream, CompoundStmtNode* compoundNode, const Nullable<OverrideClause>* insertOverride);
StreamType stream, CompoundStmtNode* compoundNode, const std::optional<OverrideClause>* insertOverride);
static void restartRequest(const Request* request, jrd_tra* transaction);
static void validateExpressions(thread_db* tdbb, const Array<ValidateInfo>& validations);
@ -207,7 +207,7 @@ void AssignmentNode::validateTarget(CompilerScratch* csb, const ValueExprNode* t
// Assignment to cursor fields are always prohibited.
// But we cannot detect FOR cursors here. They are treated in dsqlPass.
else if (fieldNode->cursorNumber.specified)
else if (fieldNode->cursorNumber.has_value())
error = true;
if (error)
@ -1637,7 +1637,7 @@ DeclareSubFuncNode* DeclareSubFuncNode::dsqlPass(DsqlCompilerScratch* dsqlScratc
dsqlFunction->udf_scale = returnType->scale;
dsqlFunction->udf_sub_type = returnType->subType;
dsqlFunction->udf_length = returnType->length;
dsqlFunction->udf_character_set_id = returnType->charSetId.value;
dsqlFunction->udf_character_set_id = returnType->charSetId.value_or(CS_NONE);
if (dsqlDeterministic)
dsqlSignature.flags |= Signature::FLAG_DETERMINISTIC;
@ -2358,7 +2358,7 @@ string EraseNode::internalPrint(NodePrinter& printer) const
void EraseNode::genBlr(DsqlCompilerScratch* dsqlScratch)
{
Nullable<USHORT> tableNumber;
std::optional<USHORT> tableNumber;
if (dsqlReturning && !dsqlScratch->isPsql())
{
@ -2367,7 +2367,7 @@ void EraseNode::genBlr(DsqlCompilerScratch* dsqlScratch)
dsqlScratch->appendUChar(blr_begin);
tableNumber = dsqlScratch->localTableNumber++;
dsqlGenReturningLocalTableDecl(dsqlScratch, tableNumber.value);
dsqlGenReturningLocalTableDecl(dsqlScratch, tableNumber.value());
}
else
{
@ -2403,7 +2403,7 @@ void EraseNode::genBlr(DsqlCompilerScratch* dsqlScratch)
if (!dsqlScratch->isPsql() && dsqlCursorName.isEmpty())
{
dsqlGenReturningLocalTableCursor(dsqlScratch, dsqlReturning, tableNumber.value);
dsqlGenReturningLocalTableCursor(dsqlScratch, dsqlReturning, tableNumber.value());
dsqlScratch->appendUChar(blr_end);
}
@ -6164,14 +6164,14 @@ string MergeNode::internalPrint(NodePrinter& printer) const
void MergeNode::genBlr(DsqlCompilerScratch* dsqlScratch)
{
Nullable<USHORT> tableNumber;
std::optional<USHORT> tableNumber;
if (returning && !dsqlScratch->isPsql())
{
dsqlScratch->appendUChar(blr_begin);
tableNumber = dsqlScratch->localTableNumber++;
dsqlGenReturningLocalTableDecl(dsqlScratch, tableNumber.value);
dsqlGenReturningLocalTableDecl(dsqlScratch, tableNumber.value());
}
// Put src info for blr_for.
@ -6311,10 +6311,10 @@ void MergeNode::genBlr(DsqlCompilerScratch* dsqlScratch)
}
}
dsqlScratch->appendUChar(notMatched->overrideClause.specified ? blr_store3 : (returning ? blr_store2 : blr_store));
dsqlScratch->appendUChar(notMatched->overrideClause.has_value() ? blr_store3 : (returning ? blr_store2 : blr_store));
if (notMatched->overrideClause.specified)
dsqlScratch->appendUChar(UCHAR(notMatched->overrideClause.value));
if (notMatched->overrideClause.has_value())
dsqlScratch->appendUChar(UCHAR(notMatched->overrideClause.value()));
GEN_expr(dsqlScratch, notMatched->storeRelation);
@ -6332,7 +6332,7 @@ void MergeNode::genBlr(DsqlCompilerScratch* dsqlScratch)
if (returning)
dsqlGenReturning(dsqlScratch, notMatched->processedReturning, tableNumber);
else if (notMatched->overrideClause.specified)
else if (notMatched->overrideClause.has_value())
dsqlScratch->appendUChar(blr_null);
if (notMatched->condition && isLast)
@ -6414,7 +6414,7 @@ void MergeNode::genBlr(DsqlCompilerScratch* dsqlScratch)
if (returning && !dsqlScratch->isPsql())
{
dsqlGenReturningLocalTableCursor(dsqlScratch, returning, tableNumber.value);
dsqlGenReturningLocalTableCursor(dsqlScratch, returning, tableNumber.value());
dsqlScratch->appendUChar(blr_end);
}
@ -6635,7 +6635,7 @@ StmtNode* ModifyNode::internalDsqlPass(DsqlCompilerScratch* dsqlScratch, bool up
if (dsqlReturning && !dsqlScratch->isPsql() && dsqlCursorName.isEmpty())
{
node->dsqlReturningLocalTableNumber = updateOrInsert ?
dsqlReturningLocalTableNumber.value :
dsqlReturningLocalTableNumber.value() :
dsqlScratch->localTableNumber++;
}
@ -6824,7 +6824,7 @@ void ModifyNode::genBlr(DsqlCompilerScratch* dsqlScratch)
if (dsqlReturning && !dsqlScratch->isPsql())
{
if (dsqlCursorName.isEmpty())
dsqlGenReturningLocalTableDecl(dsqlScratch, dsqlReturningLocalTableNumber.value);
dsqlGenReturningLocalTableDecl(dsqlScratch, dsqlReturningLocalTableNumber.value());
else
{
dsqlScratch->appendUChar(blr_send);
@ -6869,7 +6869,7 @@ void ModifyNode::genBlr(DsqlCompilerScratch* dsqlScratch)
!(dsqlScratch->flags & DsqlCompilerScratch::FLAG_UPDATE_OR_INSERT) &&
dsqlCursorName.isEmpty())
{
dsqlGenReturningLocalTableCursor(dsqlScratch, dsqlReturning, dsqlReturningLocalTableNumber.value);
dsqlGenReturningLocalTableCursor(dsqlScratch, dsqlReturning, dsqlReturningLocalTableNumber.value());
}
}
}
@ -7600,7 +7600,7 @@ DmlNode* StoreNode::parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* cs
{
node->overrideClause = static_cast<OverrideClause>(csb->csb_blr_reader.getByte());
switch (node->overrideClause.value)
switch (node->overrideClause.value())
{
case OverrideClause::USER_VALUE:
case OverrideClause::SYSTEM_VALUE:
@ -7851,7 +7851,7 @@ void StoreNode::genBlr(DsqlCompilerScratch* dsqlScratch)
if (dsqlReturning && !dsqlScratch->isPsql())
{
if (dsqlRse)
dsqlGenReturningLocalTableDecl(dsqlScratch, dsqlReturningLocalTableNumber.value);
dsqlGenReturningLocalTableDecl(dsqlScratch, dsqlReturningLocalTableNumber.value());
else if (!(dsqlScratch->flags & DsqlCompilerScratch::FLAG_UPDATE_OR_INSERT))
{
dsqlScratch->appendUChar(blr_send);
@ -7866,10 +7866,10 @@ void StoreNode::genBlr(DsqlCompilerScratch* dsqlScratch)
GEN_expr(dsqlScratch, dsqlRse);
}
dsqlScratch->appendUChar(overrideClause.specified ? blr_store3 : (dsqlReturning ? blr_store2 : blr_store));
dsqlScratch->appendUChar(overrideClause.has_value() ? blr_store3 : (dsqlReturning ? blr_store2 : blr_store));
if (overrideClause.specified)
dsqlScratch->appendUChar(UCHAR(overrideClause.value));
if (overrideClause.has_value())
dsqlScratch->appendUChar(UCHAR(overrideClause.value()));
GEN_expr(dsqlScratch, target);
@ -7879,15 +7879,15 @@ void StoreNode::genBlr(DsqlCompilerScratch* dsqlScratch)
{
dsqlGenReturning(dsqlScratch, dsqlReturning, dsqlReturningLocalTableNumber);
if (dsqlReturningLocalTableNumber.isAssigned())
if (dsqlReturningLocalTableNumber.has_value())
{
if (dsqlScratch->flags & DsqlCompilerScratch::FLAG_UPDATE_OR_INSERT)
dsqlScratch->appendUChar(blr_end); // close blr_if (blr_eql, blr_internal_info)
dsqlGenReturningLocalTableCursor(dsqlScratch, dsqlReturning, dsqlReturningLocalTableNumber.value);
dsqlGenReturningLocalTableCursor(dsqlScratch, dsqlReturning, dsqlReturningLocalTableNumber.value());
}
}
else if (overrideClause.specified)
else if (overrideClause.has_value())
dsqlScratch->appendUChar(blr_null);
}
@ -9013,8 +9013,7 @@ SetTransactionNode* SetTransactionNode::dsqlPass(DsqlCompilerScratch* dsqlScratc
// Find out isolation level - if specified. This is required for
// specifying the correct lock level in reserving clause.
const USHORT lockLevel = isoLevel.specified && isoLevel.value == ISO_LEVEL_CONSISTENCY ?
isc_tpb_protected : isc_tpb_shared;
const USHORT lockLevel = isoLevel == ISO_LEVEL_CONSISTENCY ? isc_tpb_protected : isc_tpb_shared;
// Stuff some version info.
dsqlScratch->appendUChar(isc_tpb_version1);
@ -9025,23 +9024,23 @@ SetTransactionNode* SetTransactionNode::dsqlPass(DsqlCompilerScratch* dsqlScratc
if (wait.specified)
dsqlScratch->appendUChar(wait.value ? isc_tpb_wait : isc_tpb_nowait);
if (isoLevel.specified)
if (isoLevel.has_value())
{
if (isoLevel.value == ISO_LEVEL_CONCURRENCY)
if (isoLevel == ISO_LEVEL_CONCURRENCY)
dsqlScratch->appendUChar(isc_tpb_concurrency);
else if (isoLevel.value == ISO_LEVEL_CONSISTENCY)
else if (isoLevel == ISO_LEVEL_CONSISTENCY)
dsqlScratch->appendUChar(isc_tpb_consistency);
else
{
dsqlScratch->appendUChar(isc_tpb_read_committed);
if (isoLevel.value == ISO_LEVEL_READ_COMMITTED_READ_CONSISTENCY)
if (isoLevel == ISO_LEVEL_READ_COMMITTED_READ_CONSISTENCY)
dsqlScratch->appendUChar(isc_tpb_read_consistency);
else if (isoLevel.value == ISO_LEVEL_READ_COMMITTED_REC_VERSION)
else if (isoLevel == ISO_LEVEL_READ_COMMITTED_REC_VERSION)
dsqlScratch->appendUChar(isc_tpb_rec_version);
else
{
fb_assert(isoLevel.value == ISO_LEVEL_READ_COMMITTED_NO_REC_VERSION);
fb_assert(isoLevel == ISO_LEVEL_READ_COMMITTED_NO_REC_VERSION);
dsqlScratch->appendUChar(isc_tpb_no_rec_version);
}
}
@ -9059,22 +9058,22 @@ SetTransactionNode* SetTransactionNode::dsqlPass(DsqlCompilerScratch* dsqlScratc
if (autoCommit.specified)
dsqlScratch->appendUChar(isc_tpb_autocommit);
if (lockTimeout.specified)
if (lockTimeout.has_value())
{
dsqlScratch->appendUChar(isc_tpb_lock_timeout);
dsqlScratch->appendUChar(2);
dsqlScratch->appendUShort(lockTimeout.value);
dsqlScratch->appendUShort(lockTimeout.value());
}
for (RestrictionOption** i = reserveList.begin(); i != reserveList.end(); ++i)
genTableLock(dsqlScratch, **i, lockLevel);
if (atSnapshotNumber.specified)
if (atSnapshotNumber.has_value())
{
dsqlScratch->appendUChar(isc_tpb_at_snapshot_number);
static_assert(sizeof(CommitNumber) == sizeof(FB_UINT64), "sizeof(CommitNumber) == sizeof(FB_UINT64)");
dsqlScratch->appendUChar(sizeof(CommitNumber));
dsqlScratch->appendUInt64(atSnapshotNumber.value);
dsqlScratch->appendUInt64(atSnapshotNumber.value());
}
if (dsqlScratch->getBlrData().getCount() > 1) // 1 -> isc_tpb_version1
@ -9643,7 +9642,7 @@ void UpdateOrInsertNode::genBlr(DsqlCompilerScratch* dsqlScratch)
storeNode->genBlr(dsqlScratch);
// StoreNode::genBlr closes our blr_if when RETURNING in DSQL is used.
if (storeNode->dsqlReturningLocalTableNumber.isUnknown())
if (!storeNode->dsqlReturningLocalTableNumber.has_value())
dsqlScratch->appendUChar(blr_end); // blr_if
dsqlScratch->appendUChar(blr_end);
@ -9908,16 +9907,16 @@ static void dsqlGenEofAssignment(DsqlCompilerScratch* dsqlScratch, SSHORT value)
}
static void dsqlGenReturning(DsqlCompilerScratch* dsqlScratch, ReturningClause* returning,
Nullable<USHORT> localTableNumber)
std::optional<USHORT> localTableNumber)
{
if (localTableNumber.isAssigned())
if (localTableNumber.has_value())
{
const USHORT localStoreContext = dsqlScratch->contextNumber++;
dsqlScratch->appendUChar(blr_store);
dsqlScratch->putBlrMarkers(StmtNode::MARK_AVOID_COUNTERS);
dsqlScratch->appendUChar(blr_local_table_id);
dsqlScratch->appendUShort(localTableNumber.value);
dsqlScratch->appendUShort(localTableNumber.value());
dsqlScratch->appendMetaString(""); // alias
GEN_stuff_context_number(dsqlScratch, localStoreContext);
@ -11025,7 +11024,7 @@ static void preModifyEraseTriggers(thread_db* tdbb, TrigVector** trigs,
// 1. Remove assignments of DEFAULT to computed fields.
// 2. Remove assignments to identity column when OVERRIDING USER VALUE is specified in INSERT.
static void preprocessAssignments(thread_db* tdbb, CompilerScratch* csb,
StreamType stream, CompoundStmtNode* compoundNode, const Nullable<OverrideClause>* insertOverride)
StreamType stream, CompoundStmtNode* compoundNode, const std::optional<OverrideClause>* insertOverride)
{
if (!compoundNode)
return;
@ -11036,7 +11035,7 @@ static void preprocessAssignments(thread_db* tdbb, CompilerScratch* csb,
if (!relation)
return;
Nullable<IdentityType> identityType;
std::optional<IdentityType> identityType;
for (FB_SIZE_T i = compoundNode->statements.getCount(); i--; )
{
@ -11058,9 +11057,9 @@ static void preprocessAssignments(thread_db* tdbb, CompilerScratch* csb,
if (assignToField->fieldStream == stream &&
(fld = MET_get_field(relation, fieldId)))
{
if (insertOverride && fld->fld_identity_type.specified)
if (insertOverride && fld->fld_identity_type.has_value())
{
if (insertOverride->specified || !nodeIs<DefaultNode>(assignFrom))
if (insertOverride->has_value() || !nodeIs<DefaultNode>(assignFrom))
identityType = fld->fld_identity_type;
if (*insertOverride == OverrideClause::USER_VALUE)
@ -11096,9 +11095,9 @@ static void preprocessAssignments(thread_db* tdbb, CompilerScratch* csb,
if (!insertOverride)
return;
if (insertOverride->specified)
if (insertOverride->has_value())
{
if (!identityType.specified)
if (!identityType.has_value())
ERR_post(Arg::Gds(isc_overriding_without_identity) << relation->rel_name);
if (identityType == IDENT_TYPE_BY_DEFAULT && *insertOverride == OverrideClause::SYSTEM_VALUE)

View File

@ -23,6 +23,7 @@
#ifndef DSQL_STMT_NODES_H
#define DSQL_STMT_NODES_H
#include <optional>
#include "../jrd/MetaName.h"
#include "firebird/impl/blr.h"
#include "../jrd/Function.h"
@ -1072,7 +1073,7 @@ public:
Firebird::Array<NestConst<FieldNode>> fields;
NestConst<ValueListNode> values;
NestConst<BoolExprNode> condition;
Nullable<OverrideClause> overrideClause;
std::optional<OverrideClause> overrideClause;
NestConst<Jrd::RecordSourceNode> storeRelation;
NestValueArray processedFields;
@ -1188,7 +1189,7 @@ public:
StreamType newStream = 0;
unsigned marks = 0; // see StmtNode::IUD_MARK_xxx
USHORT dsqlRseFlags = 0;
Nullable<USHORT> dsqlReturningLocalTableNumber;
std::optional<USHORT> dsqlReturningLocalTableNumber;
};
@ -1315,8 +1316,8 @@ public:
NestConst<StmtNode> subStore;
Firebird::Array<ValidateInfo> validations;
unsigned marks;
Nullable<USHORT> dsqlReturningLocalTableNumber;
Nullable<OverrideClause> overrideClause;
std::optional<USHORT> dsqlReturningLocalTableNumber;
std::optional<OverrideClause> overrideClause;
};
@ -1621,9 +1622,9 @@ private:
public:
Firebird::Array<RestrictionOption*> reserveList;
Firebird::UCharBuffer tpb;
Nullable<CommitNumber> atSnapshotNumber;
Nullable<unsigned> isoLevel;
Nullable<USHORT> lockTimeout;
std::optional<CommitNumber> atSnapshotNumber;
std::optional<unsigned> isoLevel;
std::optional<USHORT> lockTimeout;
Nullable<bool> readOnly;
Nullable<bool> wait;
Nullable<bool> noAutoUndo;
@ -2001,7 +2002,7 @@ public:
NestConst<ValueListNode> order;
NestConst<RowsClause> rows;
NestConst<ReturningClause> returning;
Nullable<OverrideClause> overrideClause;
std::optional<OverrideClause> overrideClause;
NestConst<StoreNode> storeNode;
NestConst<ModifyNode> modifyNode;
Firebird::Array<NestConst<AssignmentNode>> varAssignments;

View File

@ -17,6 +17,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <optional>
#include "../dsql/Nodes.h"
#include "../dsql/AggNodes.h"
#include "../dsql/DdlNodes.h"

View File

@ -211,7 +211,7 @@ void DDL_resolve_intl_type(DsqlCompilerScratch* dsqlScratch, dsql_fld* field,
if (field->dtype <= dtype_any_text ||
(field->dtype == dtype_blob && field->subType == isc_blob_text))
{
field->charSet = METD_get_charset_name(dsqlScratch->getTransaction(), field->charSetId.value);
field->charSet = METD_get_charset_name(dsqlScratch->getTransaction(), field->charSetId.value_or(CS_NONE));
}
}
@ -269,7 +269,7 @@ void DDL_resolve_intl_type(DsqlCompilerScratch* dsqlScratch, dsql_fld* field,
return;
}
if (field->charSetId.specified && collation_name.isEmpty())
if (field->charSetId.has_value() && collation_name.isEmpty())
{
// This field has already been resolved once, and the collation
// hasn't changed. Therefore, no need to do it again.
@ -296,7 +296,7 @@ void DDL_resolve_intl_type(DsqlCompilerScratch* dsqlScratch, dsql_fld* field,
if (afield)
{
field->charSetId = afield->charSetId;
bpc = METD_get_charset_bpc(dsqlScratch->getTransaction(), field->charSetId.value);
bpc = METD_get_charset_bpc(dsqlScratch->getTransaction(), field->charSetId.value_or(CS_NONE));
field->collationId = afield->collationId;
field->textType = afield->textType;
@ -310,7 +310,7 @@ void DDL_resolve_intl_type(DsqlCompilerScratch* dsqlScratch, dsql_fld* field,
}
}
if (!(field->charSet.hasData() || field->charSetId.specified || // set if a domain
if (!(field->charSet.hasData() || field->charSetId.has_value() || // set if a domain
(field->flags & FLD_national)))
{
// Attach the database default character set, if not otherwise specified
@ -371,7 +371,7 @@ void DDL_resolve_intl_type(DsqlCompilerScratch* dsqlScratch, dsql_fld* field,
if (collation_name.hasData())
{
const dsql_intlsym* resolved_collation = METD_get_collation(dsqlScratch->getTransaction(),
collation_name, field->charSetId.value);
collation_name, field->charSetId.value_or(CS_NONE));
if (!resolved_collation)
{
@ -382,7 +382,7 @@ void DDL_resolve_intl_type(DsqlCompilerScratch* dsqlScratch, dsql_fld* field,
else
{
charSetName = METD_get_charset_name(dsqlScratch->getTransaction(),
field->charSetId.value);
field->charSetId.value_or(CS_NONE));
}
// Specified collation not found
@ -396,8 +396,8 @@ void DDL_resolve_intl_type(DsqlCompilerScratch* dsqlScratch, dsql_fld* field,
resolved_type = resolved_collation;
if ((field->charSetId.value != resolved_type->intlsym_charset_id) &&
(field->charSetId.value != ttype_dynamic))
if ((field->charSetId.value_or(CS_NONE) != resolved_type->intlsym_charset_id) &&
(field->charSetId.value_or(CS_NONE) != ttype_dynamic))
{
ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-204) <<
Arg::Gds(isc_dsql_datatype_err) <<

View File

@ -226,7 +226,7 @@ public:
USHORT segLength = 0; // Segment length for blobs
USHORT precision = 0; // Precision for exact numeric types
USHORT charLength = 0; // Length of field in characters
Nullable<SSHORT> charSetId;
std::optional<SSHORT> charSetId;
SSHORT collationId = 0;
SSHORT textType = 0;
bool fullDomain = false; // Domain name without TYPE OF prefix
@ -725,19 +725,19 @@ struct SignatureParameter
MetaName charSetName;
MetaName collationName;
MetaName subTypeName;
Nullable<SSHORT> collationId;
Nullable<SSHORT> nullFlag;
std::optional<SSHORT> collationId;
std::optional<SSHORT> nullFlag;
SSHORT mechanism = 0;
Nullable<SSHORT> fieldLength;
Nullable<SSHORT> fieldScale;
Nullable<SSHORT> fieldType;
Nullable<SSHORT> fieldSubType;
Nullable<SSHORT> fieldSegmentLength;
Nullable<SSHORT> fieldNullFlag;
Nullable<SSHORT> fieldCharLength;
Nullable<SSHORT> fieldCollationId;
Nullable<SSHORT> fieldCharSetId;
Nullable<SSHORT> fieldPrecision;
std::optional<SSHORT> fieldLength;
std::optional<SSHORT> fieldScale;
std::optional<SSHORT> fieldType;
std::optional<SSHORT> fieldSubType;
std::optional<SSHORT> fieldSegmentLength;
std::optional<SSHORT> fieldNullFlag;
std::optional<SSHORT> fieldCharLength;
std::optional<SSHORT> fieldCollationId;
std::optional<SSHORT> fieldCharSetId;
std::optional<SSHORT> fieldPrecision;
bool operator >(const SignatureParameter& o) const
{
@ -755,19 +755,19 @@ struct SignatureParameter
fieldName == o.fieldName &&
relationName == o.relationName &&
collationId == o.collationId &&
nullFlag.orElse(FALSE) == o.nullFlag.orElse(FALSE) &&
nullFlag.value_or(FALSE) == o.nullFlag.value_or(FALSE) &&
mechanism == o.mechanism &&
fieldLength == o.fieldLength &&
fieldScale == o.fieldScale &&
fieldType == o.fieldType &&
fieldSubType.orElse(0) == o.fieldSubType.orElse(0) &&
fieldSubType.value_or(0) == o.fieldSubType.value_or(0) &&
fieldSegmentLength == o.fieldSegmentLength &&
fieldNullFlag.orElse(FALSE) == o.fieldNullFlag.orElse(FALSE) &&
fieldNullFlag.value_or(FALSE) == o.fieldNullFlag.value_or(FALSE) &&
fieldCharLength == o.fieldCharLength &&
charSetName == o.charSetName &&
collationName == o.collationName &&
subTypeName == o.subTypeName &&
fieldCollationId.orElse(0) == o.fieldCollationId.orElse(0) &&
fieldCollationId.value_or(0) == o.fieldCollationId.value_or(0) &&
fieldCharSetId == o.fieldCharSetId &&
fieldPrecision == o.fieldPrecision;
}

View File

@ -69,14 +69,14 @@ void DsqlDescMaker::fromElement(dsc* desc, const TypeClause* field)
{
composeDesc(desc,
field->elementDtype, field->scale, field->subType, field->elementLength,
field->charSetId.value, field->collationId, field->flags & FLD_nullable);
field->charSetId.value_or(CS_NONE), field->collationId, field->flags & FLD_nullable);
}
void DsqlDescMaker::fromField(dsc* desc, const TypeClause* field)
{
composeDesc(desc,
field->dtype, field->scale, field->subType, field->length,
field->charSetId.value, field->collationId, field->flags & FLD_nullable);
field->charSetId.value_or(CS_NONE), field->collationId, field->flags & FLD_nullable);
}
void DsqlDescMaker::fromList(DsqlCompilerScratch* scratch, dsc* desc,

View File

@ -561,7 +561,7 @@ bool METD_get_domain(jrd_tra* transaction, TypeClause* field, const MetaName& na
field->subType = FLX.RDB$FIELD_SUB_TYPE;
field->dimensions = FLX.RDB$DIMENSIONS.NULL ? 0 : FLX.RDB$DIMENSIONS;
field->charSetId = Nullable<SSHORT>::empty();
field->charSetId = std::nullopt;
if (!FLX.RDB$CHARACTER_SET_ID.NULL)
field->charSetId = FLX.RDB$CHARACTER_SET_ID;
field->collationId = 0;

View File

@ -727,23 +727,24 @@ using namespace Firebird;
%nonassoc ALTER
%nonassoc COLUMN
%union
%union YYSTYPE
{
BaseNullable<int> nullableIntVal;
YYSTYPE()
{}
std::optional<int> nullableIntVal;
BaseNullable<bool> nullableBoolVal;
BaseNullable<Jrd::TriggerDefinition::SqlSecurity> nullableSqlSecurityVal;
BaseNullable<Jrd::OverrideClause> nullableOverrideClause;
std::optional<Jrd::TriggerDefinition::SqlSecurity> nullableSqlSecurityVal;
std::optional<Jrd::OverrideClause> nullableOverrideClause;
struct { bool first; bool second; } boolPair;
bool boolVal;
int intVal;
unsigned uintVal;
SLONG int32Val;
BaseNullable<SLONG> nullableInt32Val;
SINT64 int64Val;
FB_UINT64 uint64Val;
BaseNullable<SINT64> nullableInt64Val;
BaseNullable<BaseNullable<SINT64> > nullableNullableInt64Val;
BaseNullable<FB_UINT64> nullableUint64Val;
std::optional<SINT64> nullableInt64Val;
std::optional<FB_UINT64> nullableUint64Val;
Jrd::ScaledNumber scaledNumber;
UCHAR blrOp;
Jrd::OrderNode::NullsPlacement nullsPlacement;
@ -1449,10 +1450,10 @@ arg_desc($parameters)
%type <nullableIntVal> param_mechanism
param_mechanism
: /* nothing */ { $$ = Nullable<int>::empty(); } // Beware: This means FUN_reference or FUN_blob_struct.
| BY DESCRIPTOR { $$ = Nullable<int>::val(FUN_descriptor); }
| BY SCALAR_ARRAY { $$ = Nullable<int>::val(FUN_scalar_array); }
| NULL { $$ = Nullable<int>::val(FUN_ref_with_null); }
: /* nothing */ { $$ = std::nullopt; } // Beware: This means FUN_reference or FUN_blob_struct.
| BY DESCRIPTOR { $$ = FUN_descriptor; }
| BY SCALAR_ARRAY { $$ = FUN_scalar_array; }
| NULL { $$ = FUN_ref_with_null; }
;
%type return_value1(<createAlterFunctionNode>)
@ -1852,7 +1853,7 @@ replace_sequence_clause
replace_sequence_options($2)
{
// Remove this to implement CORE-5137
if (!$2->restartSpecified && !$2->step.specified)
if (!$2->restartSpecified && !$2->step.has_value())
yyerrorIncompleteCmd(YYPOSNARG(3));
$$ = $2;
}
@ -1885,7 +1886,7 @@ alter_sequence_clause
}
alter_sequence_options($2)
{
if (!$2->restartSpecified && !$2->value.specified && !$2->step.specified)
if (!$2->restartSpecified && !$2->value.has_value() && !$2->step.has_value())
yyerrorIncompleteCmd(YYPOSNARG(3));
$$ = $2;
}
@ -1913,8 +1914,8 @@ restart_option($seqNode)
%type <nullableInt64Val> with_opt
with_opt
: /* Nothign */ { $$ = BaseNullable<SINT64>::empty(); }
| WITH sequence_value { $$ = BaseNullable<SINT64>::val($2); }
: /* Nothign */ { $$ = std::nullopt; }
| WITH sequence_value { $$ = $2; }
;
%type <createAlterSequenceNode> set_generator_clause
@ -1926,7 +1927,7 @@ set_generator_clause
node->alter = true;
node->legacy = true;
node->restartSpecified = true;
node->value = BaseNullable<SINT64>::val($5);
node->value = $5;
$$ = node;
}
;
@ -2278,12 +2279,12 @@ gtt_table_clause
: simple_table_name
{
$<createRelationNode>$ = newNode<CreateRelationNode>($1);
$<createRelationNode>$->relationType = Nullable<rel_t>::empty();
$<createRelationNode>$->relationType = std::nullopt;
}
'(' table_elements($2) ')' gtt_ops($2)
{
$$ = $2;
if (!$$->relationType.specified)
if (!$$->relationType.has_value())
$$->relationType = rel_global_temp_delete;
}
;
@ -4025,8 +4026,8 @@ trigger_type_suffix
%type <nullableIntVal> trigger_position
trigger_position
: /* nothing */ { $$ = Nullable<int>::empty(); }
| POSITION nonneg_short_integer { $$ = Nullable<int>::val($2); }
: /* nothing */ { $$ = std::nullopt; }
| POSITION nonneg_short_integer { $$ = $2; }
;
// ALTER statement
@ -4594,21 +4595,21 @@ alter_trigger_clause
%type <nullableUint64Val> trigger_type_opt
trigger_type_opt // we do not allow alter database triggers, hence we do not use trigger_type here
: trigger_type_prefix trigger_type_suffix
{ $$ = Nullable<FB_UINT64>::val($1 + $2 - 1); }
{ $$ = $1 + $2 - 1; }
|
{ $$ = Nullable<FB_UINT64>::empty(); }
{ $$ = std::nullopt; }
;
%type <nullableSqlSecurityVal> trg_sql_security_clause
trg_sql_security_clause
: // nothing
{ $$ = Nullable<TriggerDefinition::SqlSecurity>::empty(); }
{ $$ = std::nullopt; }
| SQL SECURITY DEFINER
{ $$ = Nullable<TriggerDefinition::SqlSecurity>::val(TriggerDefinition::SS_DEFINER); }
{ $$ = TriggerDefinition::SS_DEFINER; }
| SQL SECURITY INVOKER
{ $$ = Nullable<TriggerDefinition::SqlSecurity>::val(TriggerDefinition::SS_INVOKER); }
{ $$ = TriggerDefinition::SS_INVOKER; }
| DROP SQL SECURITY
{ $$ = Nullable<TriggerDefinition::SqlSecurity>::val(TriggerDefinition::SS_DROP); }
{ $$ = TriggerDefinition::SS_DROP; }
;
// DROP metadata operations
@ -6619,9 +6620,9 @@ insert_start
%type <nullableOverrideClause> override_opt
override_opt
: /* nothing */ { $$ = Nullable<OverrideClause>::empty(); }
| OVERRIDING USER VALUE { $$ = Nullable<OverrideClause>::val(OverrideClause::USER_VALUE); }
| OVERRIDING SYSTEM VALUE { $$ = Nullable<OverrideClause>::val(OverrideClause::SYSTEM_VALUE); }
: /* nothing */ { $$ = std::nullopt; }
| OVERRIDING USER VALUE { $$ = OverrideClause::USER_VALUE; }
| OVERRIDING SYSTEM VALUE { $$ = OverrideClause::SYSTEM_VALUE; }
;
%type <valueListNode> value_or_default_list

View File

@ -173,6 +173,54 @@ void PreparedStatement::Builder::moveFromResultSet(thread_db* tdbb, ResultSet* r
{
for (Array<OutputSlot>::const_iterator i = outputSlots.begin(); i != outputSlots.end(); ++i)
{
if (i->isOptional)
{
const bool isNull = rs->isNull(i->number);
switch (i->type)
{
case TYPE_SSHORT:
*(std::optional<SSHORT>*) i->address = isNull ?
std::nullopt : std::optional{rs->getSmallInt(tdbb, i->number)};
break;
case TYPE_SLONG:
*(std::optional<SLONG>*) i->address = isNull ?
std::nullopt : std::optional{rs->getInt(tdbb, i->number)};
break;
case TYPE_SINT64:
*(std::optional<SINT64>*) i->address = isNull ?
std::nullopt : std::optional{rs->getBigInt(tdbb, i->number)};
break;
case TYPE_DOUBLE:
*(std::optional<double>*) i->address = isNull ?
std::nullopt : std::optional{rs->getDouble(tdbb, i->number)};
break;
case TYPE_STRING:
*(std::optional<string>*) i->address = isNull ?
std::nullopt : std::optional{rs->getString(tdbb, i->number)};
break;
case TYPE_METANAME:
*(std::optional<MetaName>*) i->address = isNull ?
std::nullopt : std::optional{rs->getMetaName(tdbb, i->number)};
break;
case TYPE_METASTRING:
*(std::optional<MetaString>*) i->address = isNull ?
std::nullopt : std::optional{rs->getMetaString(tdbb, i->number)};
break;
default:
fb_assert(false);
}
continue;
}
switch (i->type)
{
case TYPE_SSHORT:
@ -192,11 +240,8 @@ void PreparedStatement::Builder::moveFromResultSet(thread_db* tdbb, ResultSet* r
break;
case TYPE_STRING:
{
AbstractString* str = (AbstractString*) i->address;
str->replace(0, str->length(), rs->getString(tdbb, i->number));
*(string*) i->address = rs->getString(tdbb, i->number);
break;
}
case TYPE_METANAME:
*(MetaName*) i->address = rs->getMetaName(tdbb, i->number);
@ -209,9 +254,6 @@ void PreparedStatement::Builder::moveFromResultSet(thread_db* tdbb, ResultSet* r
default:
fb_assert(false);
}
if (i->specifiedAddress && rs->isNull(i->number))
*i->specifiedAddress = false;
}
}
@ -221,8 +263,70 @@ void PreparedStatement::Builder::moveToStatement(thread_db* tdbb, PreparedStatem
{
for (Array<InputSlot>::const_iterator i = inputSlots.begin(); i != inputSlots.end(); ++i)
{
if (i->specifiedAddress && !*i->specifiedAddress)
if (i->isOptional)
{
switch (i->type)
{
case TYPE_SSHORT:
if (const auto optional = (std::optional<SSHORT>*) i->address; optional->has_value())
{
stmt->setSmallInt(tdbb, i->number, optional->value());
continue;
}
break;
case TYPE_SLONG:
if (const auto optional = (std::optional<SLONG>*) i->address; optional->has_value())
{
stmt->setInt(tdbb, i->number, optional->value());
continue;
}
break;
case TYPE_SINT64:
if (const auto optional = (std::optional<SINT64>*) i->address; optional->has_value())
{
stmt->setBigInt(tdbb, i->number, optional->value());
continue;
}
break;
case TYPE_DOUBLE:
if (const auto optional = (std::optional<double>*) i->address; optional->has_value())
{
stmt->setDouble(tdbb, i->number, optional->value());
continue;
}
break;
case TYPE_STRING:
if (const auto optional = (std::optional<string>*) i->address; optional->has_value())
{
stmt->setString(tdbb, i->number, optional->value());
continue;
}
break;
case TYPE_METANAME:
if (const auto optional = (std::optional<MetaName>*) i->address; optional->has_value())
{
stmt->setMetaName(tdbb, i->number, optional->value());
continue;
}
break;
case TYPE_METASTRING:
if (const auto optional = (std::optional<MetaString>*) i->address; optional->has_value())
{
stmt->setMetaString(tdbb, i->number, optional->value());
continue;
}
break;
default:
fb_assert(false);
}
stmt->setNull(i->number);
continue;
}
@ -246,7 +350,7 @@ void PreparedStatement::Builder::moveToStatement(thread_db* tdbb, PreparedStatem
break;
case TYPE_STRING:
stmt->setString(tdbb, i->number, *(AbstractString*) i->address);
stmt->setString(tdbb, i->number, *(string*) i->address);
break;
case TYPE_METANAME:

View File

@ -24,6 +24,8 @@
#define JRD_PREPARED_STATEMENT_H
#include "firebird.h"
#include <utility>
#include <optional>
#include "../common/dsc.h"
#include "../common/MsgMetadata.h"
#include "../jrd/intl.h"
@ -33,7 +35,6 @@
#include "../common/classes/fb_string.h"
#include "../common/classes/MetaString.h"
#include "../jrd/MetaName.h"
#include "../common/classes/Nullable.h"
namespace Jrd {
@ -45,6 +46,9 @@ class dsql_msg;
class ResultSet;
template <typename T>
struct PreparedStatementTypeDiscriminator {};
class PreparedStatement : public Firebird::PermanentStorage
{
friend class ResultSet;
@ -52,7 +56,7 @@ friend class ResultSet;
public:
class Builder
{
private:
public:
enum Type
{
TYPE_SSHORT,
@ -83,7 +87,7 @@ public:
Type type;
unsigned number;
const void* address;
const bool* specifiedAddress;
bool isOptional;
};
struct OutputSlot
@ -91,7 +95,7 @@ public:
Type type;
unsigned number;
void* address;
bool* specifiedAddress;
bool isOptional;
};
public:
@ -103,16 +107,15 @@ public:
public:
// Output variables.
template <typename T> OutputParam operator ()(const char* chunk, Nullable<T>& param)
template <typename T> OutputParam operator ()(const char* chunk, std::optional<T>& param)
{
OutputParam ret = (*this)(chunk, param.value);
outputSlots[outputSlots.getCount() - 1].specifiedAddress = &param.specified;
return ret;
addOutput(PreparedStatementTypeDiscriminator<T>::TYPE, &param, true, outputSlots);
return OutputParam(chunk, outputSlots.getCount() - 1);
}
template <typename T> OutputParam operator ()(const char* chunk, T& param)
{
addOutput(getType(param), &param, outputSlots);
addOutput(PreparedStatementTypeDiscriminator<T>::TYPE, &param, false, outputSlots);
return OutputParam(chunk, outputSlots.getCount() - 1);
}
@ -134,16 +137,16 @@ public:
return *this;
}
template <typename T> Builder& operator <<(const Nullable<T>& param)
template <typename T> Builder& operator <<(const std::optional<T>& param)
{
*this << param.value;
inputSlots[inputSlots.getCount() - 1].specifiedAddress = &param.specified;
addInput(PreparedStatementTypeDiscriminator<T>::TYPE, &param, true, inputSlots);
text += "?";
return *this;
}
template <typename T> Builder& operator <<(const T& param)
{
addInput(getType(param), &param, inputSlots);
addInput(PreparedStatementTypeDiscriminator<T>::TYPE, &param, false, inputSlots);
text += "?";
return *this;
}
@ -158,32 +161,23 @@ public:
void moveToStatement(thread_db* tdbb, PreparedStatement* stmt) const;
private:
// Make the C++ template engine return the constant for each type.
static Type getType(SSHORT) { return TYPE_SSHORT; }
static Type getType(SLONG) { return TYPE_SLONG; }
static Type getType(SINT64) { return TYPE_SINT64; }
static Type getType(double) { return TYPE_DOUBLE; }
static Type getType(const Firebird::AbstractString&) { return TYPE_STRING; }
static Type getType(const MetaName&) { return TYPE_METANAME; }
static Type getType(const Firebird::MetaString&) { return TYPE_METASTRING; }
void addInput(Type type, const void* address, Firebird::Array<InputSlot>& slots)
void addInput(Type type, const void* address, bool isOptional, Firebird::Array<InputSlot>& slots)
{
InputSlot slot;
slot.type = type;
slot.number = (unsigned) slots.getCount() + 1;
slot.address = address;
slot.specifiedAddress = NULL;
slot.isOptional = isOptional;
slots.add(slot);
}
void addOutput(Type type, void* address, Firebird::Array<OutputSlot>& slots)
void addOutput(Type type, void* address, bool isOptional, Firebird::Array<OutputSlot>& slots)
{
OutputSlot slot;
slot.type = type;
slot.number = (unsigned) slots.getCount() + 1;
slot.address = address;
slot.specifiedAddress = NULL;
slot.isOptional = isOptional;
slots.add(slot);
}
@ -324,7 +318,7 @@ public:
setDesc(tdbb, param, desc);
}
void setString(thread_db* tdbb, unsigned param, const Firebird::AbstractString& value)
void setString(thread_db* tdbb, unsigned param, const Firebird::string& value)
{
fb_assert(param > 0);
@ -378,6 +372,50 @@ private:
typedef Firebird::AutoPtr<PreparedStatement> AutoPreparedStatement;
// PreparedStatementTypeDiscriminator specializations.
template <>
struct PreparedStatementTypeDiscriminator<SSHORT>
{
static constexpr PreparedStatement::Builder::Type TYPE = PreparedStatement::Builder::TYPE_SSHORT;
};
template <>
struct PreparedStatementTypeDiscriminator<SLONG>
{
static constexpr PreparedStatement::Builder::Type TYPE = PreparedStatement::Builder::TYPE_SLONG;
};
template <>
struct PreparedStatementTypeDiscriminator<SINT64>
{
static constexpr PreparedStatement::Builder::Type TYPE = PreparedStatement::Builder::TYPE_SINT64;
};
template <>
struct PreparedStatementTypeDiscriminator<double>
{
static constexpr PreparedStatement::Builder::Type TYPE = PreparedStatement::Builder::TYPE_DOUBLE;
};
template <>
struct PreparedStatementTypeDiscriminator<Firebird::string>
{
static constexpr PreparedStatement::Builder::Type TYPE = PreparedStatement::Builder::TYPE_STRING;
};
template <>
struct PreparedStatementTypeDiscriminator<MetaName>
{
static constexpr PreparedStatement::Builder::Type TYPE = PreparedStatement::Builder::TYPE_METANAME;
};
template <>
struct PreparedStatementTypeDiscriminator<Firebird::MetaString>
{
static constexpr PreparedStatement::Builder::Type TYPE = PreparedStatement::Builder::TYPE_METASTRING;
};
} // namespace

View File

@ -335,8 +335,8 @@ void ProfilerPackage::startSessionFunction(ThrowStatusExceptionWrapper* /*status
}
const string description(in->description.str, in->descriptionNull ? 0 : in->description.length);
const Nullable<SLONG> flushInterval(in->flushIntervalNull ?
Nullable<SLONG>() : Nullable<SLONG>(in->flushInterval));
const std::optional<SLONG> flushInterval(in->flushIntervalNull ?
std::nullopt : std::optional{in->flushInterval});
const PathName pluginName(in->pluginName.str, in->pluginNameNull ? 0 : in->pluginName.length);
const string pluginOptions(in->pluginOptions.str, in->pluginOptionsNull ? 0 : in->pluginOptions.length);
@ -398,11 +398,11 @@ int ProfilerManager::blockingAst(void* astObject)
return 0;
}
SINT64 ProfilerManager::startSession(thread_db* tdbb, Nullable<SLONG> flushInterval,
SINT64 ProfilerManager::startSession(thread_db* tdbb, std::optional<SLONG> flushInterval,
const PathName& pluginName, const string& description, const string& options)
{
if (flushInterval.isAssigned())
checkFlushInterval(flushInterval.value);
if (flushInterval.has_value())
checkFlushInterval(flushInterval.value());
AutoSetRestore<bool> pauseProfiler(&paused, true);
@ -460,8 +460,8 @@ SINT64 ProfilerManager::startSession(thread_db* tdbb, Nullable<SLONG> flushInter
paused = false;
if (flushInterval.isAssigned())
setFlushInterval(flushInterval.value);
if (flushInterval.has_value())
setFlushInterval(flushInterval.value());
return currentSession->pluginSession->getId();
}
@ -1038,8 +1038,8 @@ void ProfilerListener::processCommand(thread_db* tdbb)
const string description(in->description.str,
in->descriptionNull ? 0 : in->description.length);
const Nullable<SLONG> flushInterval(in->flushIntervalNull ?
Nullable<SLONG>() : Nullable<SLONG>(in->flushInterval));
const std::optional<SLONG> flushInterval(in->flushIntervalNull ?
std::nullopt : std::optional{in->flushInterval});
const PathName pluginName(in->pluginName.str,
in->pluginNameNull ? 0 : in->pluginName.length);
const string pluginOptions(in->pluginOptions.str,

View File

@ -25,6 +25,7 @@
#include "firebird.h"
#include "firebird/Message.h"
#include <optional>
#include "../common/PerformanceStopWatch.h"
#include "../common/classes/auto.h"
#include "../common/classes/fb_string.h"
@ -187,7 +188,7 @@ public:
void operator=(const ProfilerManager&) = delete;
public:
SINT64 startSession(thread_db* tdbb, Nullable<SLONG> flushInterval,
SINT64 startSession(thread_db* tdbb, std::optional<SLONG> flushInterval,
const Firebird::PathName& pluginName, const Firebird::string& description, const Firebird::string& options);
void prepareCursor(thread_db* tdbb, Request* request, const Select* select);

View File

@ -22,6 +22,7 @@
#ifndef JRD_RELATION_H
#define JRD_RELATION_H
#include <optional>
#include "../jrd/jrd.h"
#include "../jrd/btr.h"
#include "../jrd/lck.h"
@ -490,7 +491,7 @@ public:
MetaName fld_security_name; // security class name for field
MetaName fld_generator_name; // identity generator name
MetaNamePair fld_source_rel_field; // Relation/field source name
Nullable<IdentityType> fld_identity_type;
std::optional<IdentityType> fld_identity_type;
USHORT fld_flags;
public:

View File

@ -1039,10 +1039,10 @@ namespace
dependencies.push(dependency);
}
if (parameter->prm_text_type.isAssigned())
if (parameter->prm_text_type.has_value())
{
CompilerScratch::Dependency dependency(obj_collation);
dependency.number = parameter->prm_text_type.value;
dependency.number = parameter->prm_text_type.value();
dependencies.push(dependency);
}
}

View File

@ -32,6 +32,7 @@
#ifndef JRD_EXE_H
#define JRD_EXE_H
#include <optional>
#include "../jrd/blb.h"
#include "../jrd/Relation.h"
#include "../common/classes/array.h"
@ -610,7 +611,7 @@ public:
void activate(bool subStream = false);
void deactivate();
Nullable<USHORT> csb_cursor_number; // Cursor number for this stream
std::optional<USHORT> csb_cursor_number; // Cursor number for this stream
StreamType csb_stream; // Map user context to internal stream
StreamType csb_view_stream; // stream number for view relation, below
USHORT csb_flags;

View File

@ -223,7 +223,8 @@ namespace
return formatNumber;
}
bool getCharsetByTextType(SSHORT& charSet, const USHORT subType)
template <typename T>
bool getCharsetByTextType(T& charSet, const USHORT subType)
{
switch (subType)
{
@ -1169,10 +1170,7 @@ void INI_init_dsql(thread_db* tdbb, dsql_dbb* database)
}
if (DTYPE_IS_TEXT(gfield->gfld_dtype))
{
if (getCharsetByTextType(field->charSetId.value, gfield->gfld_sub_type))
field->charSetId.specified = true;
}
getCharsetByTextType(field->charSetId, gfield->gfld_sub_type);
if (gfield->gfld_nullable)
field->flags |= FLD_nullable;

View File

@ -291,7 +291,7 @@ public:
MetaName prm_field_source;
MetaName prm_type_of_column;
MetaName prm_type_of_table;
Nullable<USHORT> prm_text_type;
std::optional<USHORT> prm_text_type;
FUN_T prm_fun_mechanism;
public:

View File

@ -4290,7 +4290,7 @@ void MET_scan_relation(thread_db* tdbb, jrd_rel* relation)
case RSR_field_generator_name:
field->fld_generator_name = (const TEXT*) p;
if (!field->fld_identity_type.specified)
if (!field->fld_identity_type.has_value())
field->fld_identity_type = IDENT_TYPE_BY_DEFAULT;
break;

View File

@ -22,6 +22,7 @@
#include "firebird.h"
#include "firebird/Message.h"
#include <optional>
#include "../common/Int128.h"
#include "../common/classes/ImplementHelper.h"
#include "../common/classes/auto.h"
@ -29,7 +30,6 @@
#include "../common/classes/fb_string.h"
#include "../common/classes/GenericMap.h"
#include "../common/classes/MetaString.h"
#include "../common/classes/Nullable.h"
#include "../common/classes/objects_array.h"
#include "../common/classes/stack.h"
#include "../common/status.h"
@ -105,7 +105,7 @@ struct Cursor
struct RecordSource
{
Nullable<ULONG> parentId;
std::optional<ULONG> parentId;
unsigned level;
string accessPath{defaultPool()};
};
@ -137,8 +137,8 @@ struct Request
SINT64 callerStatementId = 0;
SINT64 callerRequestId = 0;
ISC_TIMESTAMP_TZ startTimestamp;
Nullable<ISC_TIMESTAMP_TZ> finishTimestamp;
Nullable<FB_UINT64> totalElapsedTicks;
std::optional<ISC_TIMESTAMP_TZ> finishTimestamp;
std::optional<FB_UINT64> totalElapsedTicks;
NonPooledMap<CursorRecSourceKey, RecordSourceStats> recordSourcesStats{defaultPool()};
NonPooledMap<LineColumnKey, Stats> psqlStats{defaultPool()};
};
@ -226,7 +226,7 @@ public:
NonPooledMap<SINT64, Request> requests{defaultPool()};
SINT64 id;
ISC_TIMESTAMP_TZ startTimestamp;
Nullable<ISC_TIMESTAMP_TZ> finishTimestamp;
std::optional<ISC_TIMESTAMP_TZ> finishTimestamp;
string description{defaultPool()};
bool detailedRequests = false;
bool dirty = true;
@ -649,8 +649,9 @@ void ProfilerPlugin::flush(ThrowStatusExceptionWrapper* status)
sessionMessage->startTimestampNull = FB_FALSE;
sessionMessage->startTimestamp = session->startTimestamp;
sessionMessage->finishTimestampNull = session->finishTimestamp.isUnknown();
sessionMessage->finishTimestamp = session->finishTimestamp.value;
sessionMessage->finishTimestampNull = !session->finishTimestamp.has_value();
if (session->finishTimestamp.has_value())
sessionMessage->finishTimestamp = session->finishTimestamp.value();
sessionStmt->execute(status, transaction, sessionMessage.getMetadata(),
sessionMessage.getData(), nullptr, nullptr);
@ -772,8 +773,8 @@ void ProfilerPlugin::flush(ThrowStatusExceptionWrapper* status)
recSrcMessage->recordSourceIdNull = FB_FALSE;
recSrcMessage->recordSourceId = recSourceId;
recSrcMessage->parentRecordSourceIdNull = !recSrc.parentId.specified;
recSrcMessage->parentRecordSourceId = recSrc.parentId.value;
recSrcMessage->parentRecordSourceIdNull = !recSrc.parentId.has_value();
recSrcMessage->parentRecordSourceId = recSrc.parentId.value_or(0);
recSrcMessage->levelNull = FB_FALSE;
recSrcMessage->level = recSrc.level;
@ -839,15 +840,16 @@ void ProfilerPlugin::flush(ThrowStatusExceptionWrapper* status)
requestMessage->startTimestampNull = FB_FALSE;
requestMessage->startTimestamp = profileRequest.startTimestamp;
requestMessage->finishTimestampNull = profileRequest.finishTimestamp.isUnknown();
requestMessage->finishTimestamp = profileRequest.finishTimestamp.value;
requestMessage->finishTimestampNull = !profileRequest.finishTimestamp.has_value();
if (profileRequest.finishTimestamp.has_value())
requestMessage->finishTimestamp = profileRequest.finishTimestamp.value();
requestMessage->totalElapsedTimeNull = profileRequest.totalElapsedTicks.isUnknown();
requestMessage->totalElapsedTime = ticksToNanoseconds(profileRequest.totalElapsedTicks.value);
requestMessage->totalElapsedTimeNull = !profileRequest.totalElapsedTicks.has_value();
requestMessage->totalElapsedTime = ticksToNanoseconds(profileRequest.totalElapsedTicks.value_or(0));
addBatch(requestBatch, requestBatchSize, requestMessage);
if (profileRequest.finishTimestamp.isAssigned())
if (profileRequest.finishTimestamp.has_value())
finishedRequests.add(requestIt->first);
profileRequest.dirty = false;
@ -937,7 +939,7 @@ void ProfilerPlugin::flush(ThrowStatusExceptionWrapper* status)
}
}
if (session->finishTimestamp.isUnknown())
if (!session->finishTimestamp.has_value())
{
session->statements.clear();
session->recordSources.clear();