mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-22 19:23:02 +01:00
Replace Nullable by std::optional.
This commit is contained in:
parent
bf72356edb
commit
c170e4b089
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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";
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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>&)
|
||||
{
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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"
|
||||
|
@ -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) <<
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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 = ¶m.specified;
|
||||
return ret;
|
||||
addOutput(PreparedStatementTypeDiscriminator<T>::TYPE, ¶m, true, outputSlots);
|
||||
return OutputParam(chunk, outputSlots.getCount() - 1);
|
||||
}
|
||||
|
||||
template <typename T> OutputParam operator ()(const char* chunk, T& param)
|
||||
{
|
||||
addOutput(getType(param), ¶m, outputSlots);
|
||||
addOutput(PreparedStatementTypeDiscriminator<T>::TYPE, ¶m, 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 = ¶m.specified;
|
||||
addInput(PreparedStatementTypeDiscriminator<T>::TYPE, ¶m, true, inputSlots);
|
||||
text += "?";
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T> Builder& operator <<(const T& param)
|
||||
{
|
||||
addInput(getType(param), ¶m, inputSlots);
|
||||
addInput(PreparedStatementTypeDiscriminator<T>::TYPE, ¶m, 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
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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:
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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();
|
||||
|
Loading…
Reference in New Issue
Block a user