mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-22 20:03: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;
|
errNum = IN_SW_BURP_S;
|
||||||
else if (tdgbl->gbl_sw_no_reserve)
|
else if (tdgbl->gbl_sw_no_reserve)
|
||||||
errNum = IN_SW_BURP_US;
|
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;
|
errNum = IN_SW_BURP_REPLICA;
|
||||||
|
|
||||||
if (errNum != IN_SW_BURP_0)
|
if (errNum != IN_SW_BURP_0)
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
#ifndef BURP_BURP_H
|
#ifndef BURP_BURP_H
|
||||||
#define BURP_BURP_H
|
#define BURP_BURP_H
|
||||||
|
|
||||||
|
#include <optional>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "ibase.h"
|
#include "ibase.h"
|
||||||
#include "firebird/Interface.h"
|
#include "firebird/Interface.h"
|
||||||
@ -1033,7 +1034,7 @@ public:
|
|||||||
ULONG io_buffer_size;
|
ULONG io_buffer_size;
|
||||||
redirect_vals sw_redirect;
|
redirect_vals sw_redirect;
|
||||||
bool burp_throw;
|
bool burp_throw;
|
||||||
Nullable<ReplicaMode> gbl_sw_replica;
|
std::optional<ReplicaMode> gbl_sw_replica;
|
||||||
|
|
||||||
UCHAR* blk_io_ptr;
|
UCHAR* blk_io_ptr;
|
||||||
int blk_io_cnt;
|
int blk_io_cnt;
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "firebird.h"
|
#include "firebird.h"
|
||||||
|
#include <optional>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.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);
|
dpb.insertByte(isc_dpb_force_write, tdgbl->hdr_forced_writes ? 1 : 0);
|
||||||
|
|
||||||
// set up the replica mode, if needed
|
// set up the replica mode, if needed
|
||||||
if (tdgbl->gbl_sw_replica.isAssigned())
|
if (tdgbl->gbl_sw_replica.has_value())
|
||||||
dpb.insertByte(isc_dpb_set_db_replica, tdgbl->gbl_sw_replica.value);
|
dpb.insertByte(isc_dpb_set_db_replica, tdgbl->gbl_sw_replica.value());
|
||||||
|
|
||||||
Firebird::IAttachment* db_handle = provider->attachDatabase(&tdgbl->status_vector, database_name,
|
Firebird::IAttachment* db_handle = provider->attachDatabase(&tdgbl->status_vector, database_name,
|
||||||
dpb.getBufferLength(), dpb.getBuffer());
|
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
|
bool forced_writes = true; // turned on by default
|
||||||
ULONG page_buffers = 0;
|
ULONG page_buffers = 0;
|
||||||
USHORT SQL_dialect = 0;
|
USHORT SQL_dialect = 0;
|
||||||
Nullable<ReplicaMode> replica_mode;
|
std::optional<ReplicaMode> replica_mode;
|
||||||
|
|
||||||
tdgbl->gbl_database_file_name = file_name;
|
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;
|
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;
|
tdgbl->gbl_sw_replica = replica_mode;
|
||||||
|
|
||||||
if (tdgbl->gbl_sw_page_buffers)
|
if (tdgbl->gbl_sw_page_buffers)
|
||||||
|
@ -133,32 +133,32 @@ unsigned StatementMetadata::buildInfoFlags(unsigned itemsLength, const UCHAR* it
|
|||||||
// Get statement type.
|
// Get statement type.
|
||||||
unsigned StatementMetadata::getType()
|
unsigned StatementMetadata::getType()
|
||||||
{
|
{
|
||||||
if (!type.specified)
|
if (!type.has_value())
|
||||||
{
|
{
|
||||||
UCHAR info[] = {isc_info_sql_stmt_type};
|
UCHAR info[] = {isc_info_sql_stmt_type};
|
||||||
UCHAR result[16];
|
UCHAR result[16];
|
||||||
|
|
||||||
getAndParse(sizeof(info), info, sizeof(result), result);
|
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()
|
unsigned StatementMetadata::getFlags()
|
||||||
{
|
{
|
||||||
if (!flags.specified)
|
if (!flags.has_value())
|
||||||
{
|
{
|
||||||
UCHAR info[] = {isc_info_sql_stmt_flags};
|
UCHAR info[] = {isc_info_sql_stmt_flags};
|
||||||
UCHAR result[16];
|
UCHAR result[16];
|
||||||
|
|
||||||
getAndParse(sizeof(info), info, sizeof(result), result);
|
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.
|
// Get statement plan.
|
||||||
@ -228,7 +228,7 @@ ISC_UINT64 StatementMetadata::getAffectedRecords()
|
|||||||
// Reset the object to its initial state.
|
// Reset the object to its initial state.
|
||||||
void StatementMetadata::clear()
|
void StatementMetadata::clear()
|
||||||
{
|
{
|
||||||
type.specified = false;
|
type.reset();
|
||||||
legacyPlan = detailedPlan = "";
|
legacyPlan = detailedPlan = "";
|
||||||
inputParameters->items.clear();
|
inputParameters->items.clear();
|
||||||
outputParameters->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) ||
|
if (((itemsLength == 1 && items[0] == isc_info_sql_stmt_type) ||
|
||||||
(itemsLength == 2 && items[0] == isc_info_sql_stmt_type &&
|
(itemsLength == 2 && items[0] == isc_info_sql_stmt_type &&
|
||||||
(items[1] == isc_info_end || items[1] == 0))) &&
|
(items[1] == isc_info_end || items[1] == 0))) &&
|
||||||
type.specified)
|
type.has_value())
|
||||||
{
|
{
|
||||||
if (bufferLength >= 8)
|
if (bufferLength >= 8)
|
||||||
{
|
{
|
||||||
*buffer++ = isc_info_sql_stmt_type;
|
*buffer++ = isc_info_sql_stmt_type;
|
||||||
put_vax_short(buffer, 4);
|
put_vax_short(buffer, 4);
|
||||||
buffer += 2;
|
buffer += 2;
|
||||||
put_vax_long(buffer, type.value);
|
put_vax_long(buffer, type.value());
|
||||||
buffer += 4;
|
buffer += 4;
|
||||||
*buffer = isc_info_end;
|
*buffer = isc_info_end;
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#ifndef COMMON_STATEMENT_METADATA_H
|
#ifndef COMMON_STATEMENT_METADATA_H
|
||||||
#define COMMON_STATEMENT_METADATA_H
|
#define COMMON_STATEMENT_METADATA_H
|
||||||
|
|
||||||
|
#include <optional>
|
||||||
#include "firebird/Interface.h"
|
#include "firebird/Interface.h"
|
||||||
#include "iberror.h"
|
#include "iberror.h"
|
||||||
#include "../common/classes/Nullable.h"
|
#include "../common/classes/Nullable.h"
|
||||||
@ -82,7 +83,7 @@ private:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
IStatement* statement;
|
IStatement* statement;
|
||||||
Nullable<unsigned> type, flags;
|
std::optional<unsigned> type, flags;
|
||||||
string legacyPlan, detailedPlan;
|
string legacyPlan, detailedPlan;
|
||||||
RefPtr<Parameters> inputParameters, outputParameters;
|
RefPtr<Parameters> inputParameters, outputParameters;
|
||||||
};
|
};
|
||||||
|
@ -341,7 +341,7 @@ void defineComputed(DsqlCompilerScratch* dsqlScratch, RelationSourceNode* relati
|
|||||||
fb_assert(field->scale <= MAX_SCHAR);
|
fb_assert(field->scale <= MAX_SCHAR);
|
||||||
saveDesc.dsc_scale = (SCHAR) field->scale;
|
saveDesc.dsc_scale = (SCHAR) field->scale;
|
||||||
saveDesc.dsc_sub_type = field->subType;
|
saveDesc.dsc_sub_type = field->subType;
|
||||||
saveCharSetIdSpecified = field->charSetId.specified;
|
saveCharSetIdSpecified = field->charSetId.has_value();
|
||||||
|
|
||||||
field->dtype = 0;
|
field->dtype = 0;
|
||||||
field->length = 0;
|
field->length = 0;
|
||||||
@ -376,8 +376,7 @@ void defineComputed(DsqlCompilerScratch* dsqlScratch, RelationSourceNode* relati
|
|||||||
|
|
||||||
if (field->dtype <= dtype_any_text)
|
if (field->dtype <= dtype_any_text)
|
||||||
{
|
{
|
||||||
field->charSetId = DSC_GET_CHARSET(&saveDesc);
|
field->charSetId = saveCharSetIdSpecified ? std::optional{DSC_GET_CHARSET(&saveDesc)} : std::nullopt;
|
||||||
field->charSetId.specified = saveCharSetIdSpecified;
|
|
||||||
field->collationId = DSC_GET_COLLATE(&saveDesc);
|
field->collationId = DSC_GET_COLLATE(&saveDesc);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -396,7 +395,7 @@ void defineComputed(DsqlCompilerScratch* dsqlScratch, RelationSourceNode* relati
|
|||||||
field->collationId = DSC_GET_COLLATE(&desc);
|
field->collationId = DSC_GET_COLLATE(&desc);
|
||||||
|
|
||||||
const USHORT adjust = field->dtype == dtype_varying ? sizeof(USHORT) : 0;
|
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;
|
field->charLength = (field->length - adjust) / bpc;
|
||||||
}
|
}
|
||||||
else if (field->dtype == dtype_blob)
|
else if (field->dtype == dtype_blob)
|
||||||
@ -845,7 +844,7 @@ static void updateRdbFields(const TypeClause* type,
|
|||||||
if (type->subType == isc_blob_text)
|
if (type->subType == isc_blob_text)
|
||||||
{
|
{
|
||||||
characterSetIdNull = FALSE;
|
characterSetIdNull = FALSE;
|
||||||
characterSetId = type->charSetId.value;
|
characterSetId = type->charSetId.value_or(CS_NONE);
|
||||||
|
|
||||||
collationIdNull = FALSE;
|
collationIdNull = FALSE;
|
||||||
collationId = type->collationId;
|
collationId = type->collationId;
|
||||||
@ -872,7 +871,7 @@ static void updateRdbFields(const TypeClause* type,
|
|||||||
}
|
}
|
||||||
|
|
||||||
characterSetIdNull = FALSE;
|
characterSetIdNull = FALSE;
|
||||||
characterSetId = type->charSetId.value;
|
characterSetId = type->charSetId.value_or(CS_NONE);
|
||||||
|
|
||||||
collationIdNull = FALSE;
|
collationIdNull = FALSE;
|
||||||
collationId = type->collationId;
|
collationId = type->collationId;
|
||||||
@ -1605,7 +1604,7 @@ void CommentOnNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Nullable<string> description;
|
std::optional<string> description;
|
||||||
if (text.hasData())
|
if (text.hasData())
|
||||||
description = text;
|
description = text;
|
||||||
|
|
||||||
@ -1916,7 +1915,7 @@ bool CreateAlterFunctionNode::executeAlter(thread_db* tdbb, DsqlCompilerScratch*
|
|||||||
// CVC: This is case of "returns <type> [by value|reference]".
|
// CVC: This is case of "returns <type> [by value|reference]".
|
||||||
// Some data types can not be returned as value.
|
// 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_text || field->dtype == dtype_varying ||
|
||||||
field->dtype == dtype_cstring || field->dtype == dtype_blob ||
|
field->dtype == dtype_cstring || field->dtype == dtype_blob ||
|
||||||
field->dtype == dtype_timestamp))
|
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.
|
// We'll verify that SCALAR_ARRAY can't be used as a return type.
|
||||||
// The support for SCALAR_ARRAY is only for input parameters.
|
// The support for SCALAR_ARRAY is only for input parameters.
|
||||||
|
|
||||||
if (parameters[udfReturnPos - 1]->udfMechanism.specified &&
|
if (parameters[udfReturnPos - 1]->udfMechanism.has_value() &&
|
||||||
parameters[udfReturnPos - 1]->udfMechanism.value == FUN_scalar_array)
|
parameters[udfReturnPos - 1]->udfMechanism.value() == FUN_scalar_array)
|
||||||
{
|
{
|
||||||
status_exception::raise(
|
status_exception::raise(
|
||||||
Arg::Gds(isc_sqlerr) << Arg::Num(-607) <<
|
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
|
// CVC: I need to test returning blobs by descriptor before allowing the
|
||||||
// change there. For now, I ignore the return type specification.
|
// 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);
|
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.
|
// If we have the FREE_IT set then the blob has to be freed on return.
|
||||||
}
|
}
|
||||||
else if (parameter->udfMechanism.specified)
|
else if (parameter->udfMechanism.has_value())
|
||||||
ARG.RDB$MECHANISM = (SSHORT) parameter->udfMechanism.value;
|
ARG.RDB$MECHANISM = (SSHORT) parameter->udfMechanism.value();
|
||||||
else if (type->dtype == dtype_blob)
|
else if (type->dtype == dtype_blob)
|
||||||
ARG.RDB$MECHANISM = (SSHORT) FUN_blob_struct;
|
ARG.RDB$MECHANISM = (SSHORT) FUN_blob_struct;
|
||||||
else
|
else
|
||||||
@ -3354,10 +3353,10 @@ void TriggerDefinition::store(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
|
|||||||
TRG.RDB$RELATION_NAME.NULL = relationName.isEmpty();
|
TRG.RDB$RELATION_NAME.NULL = relationName.isEmpty();
|
||||||
strcpy(TRG.RDB$RELATION_NAME, relationName.c_str());
|
strcpy(TRG.RDB$RELATION_NAME, relationName.c_str());
|
||||||
|
|
||||||
fb_assert(type.specified);
|
fb_assert(type.has_value());
|
||||||
TRG.RDB$TRIGGER_TYPE = type.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);
|
TRG.RDB$TRIGGER_INACTIVE = (!active.specified ? 0 : (USHORT) !active.value);
|
||||||
}
|
}
|
||||||
END_STORE
|
END_STORE
|
||||||
@ -3377,7 +3376,7 @@ bool TriggerDefinition::modify(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch
|
|||||||
TRG IN RDB$TRIGGERS
|
TRG IN RDB$TRIGGERS
|
||||||
WITH TRG.RDB$TRIGGER_NAME EQ name.c_str()
|
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)
|
TRG.RDB$RELATION_NAME.NULL)
|
||||||
{
|
{
|
||||||
status_exception::raise(
|
status_exception::raise(
|
||||||
@ -3424,11 +3423,11 @@ bool TriggerDefinition::modify(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch
|
|||||||
if (relationName.hasData())
|
if (relationName.hasData())
|
||||||
strcpy(TRG.RDB$RELATION_NAME, relationName.c_str());
|
strcpy(TRG.RDB$RELATION_NAME, relationName.c_str());
|
||||||
|
|
||||||
if (type.specified)
|
if (type.has_value())
|
||||||
TRG.RDB$TRIGGER_TYPE = type.value;
|
TRG.RDB$TRIGGER_TYPE = type.value();
|
||||||
|
|
||||||
if (position.specified)
|
if (position.has_value())
|
||||||
TRG.RDB$TRIGGER_SEQUENCE = position.value;
|
TRG.RDB$TRIGGER_SEQUENCE = position.value();
|
||||||
|
|
||||||
if (active.specified)
|
if (active.specified)
|
||||||
TRG.RDB$TRIGGER_INACTIVE = (USHORT) !active.value;
|
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);
|
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.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
|
else
|
||||||
TRG.RDB$SQL_SECURITY.NULL = TRUE;
|
TRG.RDB$SQL_SECURITY.NULL = TRUE;
|
||||||
@ -3509,14 +3508,14 @@ DdlNode* CreateAlterTriggerNode::dsqlPass(DsqlCompilerScratch* dsqlScratch)
|
|||||||
{
|
{
|
||||||
dsqlScratch->flags |= (DsqlCompilerScratch::FLAG_BLOCK | DsqlCompilerScratch::FLAG_TRIGGER);
|
dsqlScratch->flags |= (DsqlCompilerScratch::FLAG_BLOCK | DsqlCompilerScratch::FLAG_TRIGGER);
|
||||||
|
|
||||||
if (type.specified)
|
if (type.has_value())
|
||||||
{
|
{
|
||||||
if (create && // ALTER TRIGGER doesn't accept table name
|
if (create && // ALTER TRIGGER doesn't accept table name
|
||||||
((relationName.hasData() &&
|
((relationName.hasData() &&
|
||||||
(type.value & (unsigned) TRIGGER_TYPE_MASK) != (unsigned) TRIGGER_TYPE_DML) ||
|
(type.value() & (unsigned) TRIGGER_TYPE_MASK) != (unsigned) TRIGGER_TYPE_DML) ||
|
||||||
(relationName.isEmpty() &&
|
(relationName.isEmpty() &&
|
||||||
(type.value & (unsigned) TRIGGER_TYPE_MASK) != (unsigned) TRIGGER_TYPE_DB &&
|
(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_DDL)))
|
||||||
{
|
{
|
||||||
status_exception::raise(
|
status_exception::raise(
|
||||||
Arg::Gds(isc_dsql_command_err) <<
|
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));
|
status_exception::raise(Arg::Gds(isc_dsql_command_err) << Arg::Gds(isc_dsql_invalid_drop_ss_clause));
|
||||||
|
|
||||||
return DdlNode::dsqlPass(dsqlScratch);
|
return DdlNode::dsqlPass(dsqlScratch);
|
||||||
@ -3540,7 +3539,7 @@ void CreateAlterTriggerNode::checkPermission(thread_db* tdbb, jrd_tra* transacti
|
|||||||
TRG IN RDB$TRIGGERS
|
TRG IN RDB$TRIGGERS
|
||||||
WITH TRG.RDB$TRIGGER_NAME EQ name.c_str()
|
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;
|
type = TRG.RDB$TRIGGER_TYPE;
|
||||||
|
|
||||||
if (relationName.isEmpty() && !TRG.RDB$RELATION_NAME.NULL)
|
if (relationName.isEmpty() && !TRG.RDB$RELATION_NAME.NULL)
|
||||||
@ -3548,7 +3547,7 @@ void CreateAlterTriggerNode::checkPermission(thread_db* tdbb, jrd_tra* transacti
|
|||||||
}
|
}
|
||||||
END_FOR
|
END_FOR
|
||||||
|
|
||||||
if (!type.specified)
|
if (!type.has_value())
|
||||||
status_exception::raise(Arg::Gds(isc_dyn_trig_not_found) << Arg::Str(name));
|
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?
|
const string temp = relationNode->alias; // always empty?
|
||||||
|
|
||||||
if (hasOldContext(type.value))
|
if (hasOldContext(type.value()))
|
||||||
{
|
{
|
||||||
relationNode->alias = OLD_CONTEXT_NAME;
|
relationNode->alias = OLD_CONTEXT_NAME;
|
||||||
dsql_ctx* oldContext = PASS1_make_context(dsqlScratch, relationNode);
|
dsql_ctx* oldContext = PASS1_make_context(dsqlScratch, relationNode);
|
||||||
@ -3646,7 +3645,7 @@ void CreateAlterTriggerNode::compile(thread_db* /*tdbb*/, DsqlCompilerScratch* d
|
|||||||
else
|
else
|
||||||
dsqlScratch->contextNumber++;
|
dsqlScratch->contextNumber++;
|
||||||
|
|
||||||
if (hasNewContext(type.value))
|
if (hasNewContext(type.value()))
|
||||||
{
|
{
|
||||||
relationNode->alias = NEW_CONTEXT_NAME;
|
relationNode->alias = NEW_CONTEXT_NAME;
|
||||||
dsql_ctx* newContext = PASS1_make_context(dsqlScratch, relationNode);
|
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,
|
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_fld_name = name;
|
||||||
newDom.dyn_charbytelen = typeLength;
|
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,
|
executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_BEFORE, DDL_TRIGGER_CREATE_SEQUENCE,
|
||||||
name, NULL);
|
name, NULL);
|
||||||
|
|
||||||
const SINT64 val = value.orElse(1);
|
const SINT64 val = value.value_or(1);
|
||||||
SLONG initialStep = 1;
|
SLONG initialStep = 1;
|
||||||
if (step.specified)
|
if (step.has_value())
|
||||||
{
|
{
|
||||||
initialStep = step.value;
|
initialStep = step.value();
|
||||||
if (initialStep == 0)
|
if (initialStep == 0)
|
||||||
status_exception::raise(Arg::Gds(isc_dyn_cant_use_zero_increment) << Arg::Str(name));
|
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,
|
executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_BEFORE, DDL_TRIGGER_ALTER_SEQUENCE,
|
||||||
name, NULL);
|
name, NULL);
|
||||||
|
|
||||||
fb_assert(restartSpecified && value.specified);
|
fb_assert(restartSpecified && value.has_value());
|
||||||
const SINT64 val = value.specified ? value.value : 0;
|
const SINT64 val = value.value_or(0);
|
||||||
if (step.specified)
|
if (step.has_value())
|
||||||
{
|
{
|
||||||
const SLONG newStep = step.value;
|
const SLONG newStep = step.value();
|
||||||
if (newStep == 0)
|
if (newStep == 0)
|
||||||
status_exception::raise(Arg::Gds(isc_dyn_cant_use_zero_increment) << Arg::Str(name));
|
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;
|
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)
|
if (newStep == 0)
|
||||||
status_exception::raise(Arg::Gds(isc_dyn_cant_use_zero_increment) << Arg::Str(name));
|
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)
|
if (restartSpecified)
|
||||||
{
|
{
|
||||||
const SINT64 oldValue = !X.RDB$INITIAL_VALUE.NULL ? X.RDB$INITIAL_VALUE : 0;
|
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,
|
transaction->getGenIdCache()->put(id,
|
||||||
newValue - (!X.RDB$GENERATOR_INCREMENT.NULL ? X.RDB$GENERATOR_INCREMENT : 1));
|
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$BASE_FIELD.NULL = TRUE;
|
||||||
///RFR.RDB$UPDATE_FLAG.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.NULL = FALSE;
|
||||||
RFR.RDB$COLLATION_ID = collationId.value;
|
RFR.RDB$COLLATION_ID = collationId.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
SLONG fieldPos = -1;
|
SLONG fieldPos = -1;
|
||||||
|
|
||||||
if (position.specified)
|
if (position.has_value())
|
||||||
fieldPos = position.value;
|
fieldPos = position.value();
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DYN_UTIL_generate_field_position(tdbb, relationName, &fieldPos);
|
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());
|
strcpy(RFR.RDB$BASE_FIELD, baseField.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (viewContext.specified)
|
if (viewContext.has_value())
|
||||||
{
|
{
|
||||||
fb_assert(baseField.hasData());
|
fb_assert(baseField.hasData());
|
||||||
|
|
||||||
RFR.RDB$VIEW_CONTEXT.NULL = FALSE;
|
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);
|
baseField.c_str(), RFR.RDB$FIELD_SOURCE);
|
||||||
}
|
}
|
||||||
END_MODIFY
|
END_MODIFY
|
||||||
@ -6017,10 +6016,10 @@ void RelationNode::FieldDefinition::store(thread_db* tdbb, jrd_tra* transaction)
|
|||||||
RFR.RDB$BASE_FIELD.NULL = TRUE;
|
RFR.RDB$BASE_FIELD.NULL = TRUE;
|
||||||
///RFR.RDB$UPDATE_FLAG.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.NULL = FALSE;
|
||||||
RFR.RDB$COLLATION_ID = collationId.value;
|
RFR.RDB$COLLATION_ID = collationId.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (identitySequence.hasData())
|
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());
|
strcpy(RFR.RDB$GENERATOR_NAME, identitySequence.c_str());
|
||||||
|
|
||||||
RFR.RDB$IDENTITY_TYPE.NULL = FALSE;
|
RFR.RDB$IDENTITY_TYPE.NULL = FALSE;
|
||||||
RFR.RDB$IDENTITY_TYPE = identityType.value;
|
RFR.RDB$IDENTITY_TYPE = identityType.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (notNullFlag.specified)
|
if (notNullFlag.specified)
|
||||||
@ -6053,8 +6052,8 @@ void RelationNode::FieldDefinition::store(thread_db* tdbb, jrd_tra* transaction)
|
|||||||
|
|
||||||
SLONG fieldPos = -1;
|
SLONG fieldPos = -1;
|
||||||
|
|
||||||
if (position.specified)
|
if (position.has_value())
|
||||||
fieldPos = position.value;
|
fieldPos = position.value();
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DYN_UTIL_generate_field_position(tdbb, relationName, &fieldPos);
|
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());
|
strcpy(RFR.RDB$BASE_FIELD, baseField.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (viewContext.specified)
|
if (viewContext.has_value())
|
||||||
{
|
{
|
||||||
fb_assert(baseField.hasData());
|
fb_assert(baseField.hasData());
|
||||||
|
|
||||||
RFR.RDB$VIEW_CONTEXT.NULL = FALSE;
|
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);
|
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)
|
||||||
{
|
{
|
||||||
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) <<
|
status_exception::raise(Arg::Gds(isc_dyn_cant_use_zero_inc_ident) <<
|
||||||
Arg::Str(field->fld_name) <<
|
Arg::Str(field->fld_name) <<
|
||||||
@ -6378,8 +6377,8 @@ void RelationNode::defineField(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch
|
|||||||
|
|
||||||
CreateAlterSequenceNode::store(tdbb, transaction, fieldDefinition.identitySequence,
|
CreateAlterSequenceNode::store(tdbb, transaction, fieldDefinition.identitySequence,
|
||||||
fb_sysflag_identity_generator,
|
fb_sysflag_identity_generator,
|
||||||
clause->identityOptions->startValue.orElse(1),
|
clause->identityOptions->startValue.value_or(1),
|
||||||
clause->identityOptions->increment.orElse(1));
|
clause->identityOptions->increment.value_or(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
BlrDebugWriter::BlrData defaultValue;
|
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);
|
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);
|
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());
|
strcpy(REL.RDB$RELATION_NAME, name.c_str());
|
||||||
REL.RDB$SYSTEM_FLAG = 0;
|
REL.RDB$SYSTEM_FLAG = 0;
|
||||||
REL.RDB$FLAGS = REL_sql;
|
REL.RDB$FLAGS = REL_sql;
|
||||||
REL.RDB$RELATION_TYPE = relationType.value;
|
REL.RDB$RELATION_TYPE = relationType.value();
|
||||||
|
|
||||||
if (ssDefiner.specified)
|
if (ssDefiner.specified)
|
||||||
{
|
{
|
||||||
@ -8041,23 +8040,23 @@ void AlterRelationNode::modifyField(thread_db* tdbb, DsqlCompilerScratch* dsqlSc
|
|||||||
{
|
{
|
||||||
const SINT64 val =
|
const SINT64 val =
|
||||||
clause->identityOptions->startValue
|
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
|
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);
|
transaction->getGenIdCache()->put(id, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (clause->identityOptions->type.specified)
|
if (clause->identityOptions->type.has_value())
|
||||||
{
|
{
|
||||||
MODIFY RFR
|
MODIFY RFR
|
||||||
RFR.RDB$IDENTITY_TYPE = clause->identityOptions->type.value;
|
RFR.RDB$IDENTITY_TYPE = clause->identityOptions->type.value();
|
||||||
END_MODIFY
|
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) <<
|
status_exception::raise(Arg::Gds(isc_dyn_cant_use_zero_inc_ident) <<
|
||||||
Arg::Str(field->fld_name) <<
|
Arg::Str(field->fld_name) <<
|
||||||
@ -8065,7 +8064,7 @@ void AlterRelationNode::modifyField(thread_db* tdbb, DsqlCompilerScratch* dsqlSc
|
|||||||
}
|
}
|
||||||
|
|
||||||
MET_update_generator_increment(tdbb, id,
|
MET_update_generator_increment(tdbb, id,
|
||||||
clause->identityOptions->increment.value);
|
clause->identityOptions->increment.value());
|
||||||
}
|
}
|
||||||
|
|
||||||
dsc desc;
|
dsc desc;
|
||||||
@ -9014,7 +9013,7 @@ void CreateAlterViewNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScra
|
|||||||
const USHORT adjust =
|
const USHORT adjust =
|
||||||
(desc.dsc_dtype == dtype_varying) ? sizeof(USHORT) : 0;
|
(desc.dsc_dtype == dtype_varying) ? sizeof(USHORT) : 0;
|
||||||
const USHORT bpc =
|
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;
|
newField.charLength = (newField.length - adjust) / bpc;
|
||||||
}
|
}
|
||||||
@ -10182,7 +10181,6 @@ string CreateShadowNode::internalPrint(NodePrinter& printer) const
|
|||||||
NODE_PRINT(printer, number);
|
NODE_PRINT(printer, number);
|
||||||
NODE_PRINT(printer, manual);
|
NODE_PRINT(printer, manual);
|
||||||
NODE_PRINT(printer, conditional);
|
NODE_PRINT(printer, conditional);
|
||||||
NODE_PRINT(printer, firstLength);
|
|
||||||
NODE_PRINT(printer, files);
|
NODE_PRINT(printer, files);
|
||||||
|
|
||||||
return "CreateShadowNode";
|
return "CreateShadowNode";
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#ifndef DSQL_DDL_NODES_H
|
#ifndef DSQL_DDL_NODES_H
|
||||||
#define DSQL_DDL_NODES_H
|
#define DSQL_DDL_NODES_H
|
||||||
|
|
||||||
|
#include <optional>
|
||||||
#include "firebird/impl/blr.h"
|
#include "firebird/impl/blr.h"
|
||||||
#include "../jrd/dyn.h"
|
#include "../jrd/dyn.h"
|
||||||
#include "../common/msg_encode.h"
|
#include "../common/msg_encode.h"
|
||||||
@ -174,7 +175,7 @@ public:
|
|||||||
NestConst<dsql_fld> type;
|
NestConst<dsql_fld> type;
|
||||||
NestConst<ValueSourceClause> defaultClause;
|
NestConst<ValueSourceClause> defaultClause;
|
||||||
NestConst<ValueExprNode> parameterExpr;
|
NestConst<ValueExprNode> parameterExpr;
|
||||||
Nullable<int> udfMechanism;
|
std::optional<int> udfMechanism;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -696,16 +697,16 @@ protected:
|
|||||||
public:
|
public:
|
||||||
MetaName name;
|
MetaName name;
|
||||||
MetaName relationName;
|
MetaName relationName;
|
||||||
Nullable<FB_UINT64> type;
|
std::optional<FB_UINT64> type;
|
||||||
Nullable<bool> active;
|
Nullable<bool> active;
|
||||||
Nullable<int> position;
|
std::optional<int> position;
|
||||||
NestConst<ExternalClause> external;
|
NestConst<ExternalClause> external;
|
||||||
Firebird::string source;
|
Firebird::string source;
|
||||||
Firebird::ByteChunk blrData;
|
Firebird::ByteChunk blrData;
|
||||||
Firebird::ByteChunk debugData;
|
Firebird::ByteChunk debugData;
|
||||||
USHORT systemFlag;
|
USHORT systemFlag;
|
||||||
bool fkTrigger;
|
bool fkTrigger;
|
||||||
Nullable<SqlSecurity> ssDefiner;
|
std::optional<SqlSecurity> ssDefiner;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -1116,7 +1117,6 @@ public:
|
|||||||
Arg::Num(this->column));
|
Arg::Num(this->column));
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
value.specified = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static SSHORT store(thread_db* tdbb, jrd_tra* transaction, const MetaName& name,
|
static SSHORT store(thread_db* tdbb, jrd_tra* transaction, const MetaName& name,
|
||||||
@ -1147,8 +1147,8 @@ public:
|
|||||||
bool legacy;
|
bool legacy;
|
||||||
bool restartSpecified;
|
bool restartSpecified;
|
||||||
const MetaName name;
|
const MetaName name;
|
||||||
BaseNullable<SINT64> value;
|
std::optional<SINT64> value;
|
||||||
Nullable<SLONG> step;
|
std::optional<SLONG> step;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -1210,13 +1210,13 @@ public:
|
|||||||
MetaName relationName;
|
MetaName relationName;
|
||||||
MetaName fieldSource;
|
MetaName fieldSource;
|
||||||
MetaName identitySequence;
|
MetaName identitySequence;
|
||||||
Nullable<IdentityType> identityType;
|
std::optional<IdentityType> identityType;
|
||||||
Nullable<USHORT> collationId;
|
std::optional<USHORT> collationId;
|
||||||
Nullable<bool> notNullFlag; // true = NOT NULL / false = NULL
|
Nullable<bool> notNullFlag; // true = NOT NULL / false = NULL
|
||||||
Nullable<USHORT> position;
|
std::optional<USHORT> position;
|
||||||
Firebird::string defaultSource;
|
Firebird::string defaultSource;
|
||||||
Firebird::ByteChunk defaultValue;
|
Firebird::ByteChunk defaultValue;
|
||||||
Nullable<USHORT> viewContext;
|
std::optional<USHORT> viewContext;
|
||||||
MetaName baseField;
|
MetaName baseField;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1386,9 +1386,9 @@ public:
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
Nullable<IdentityType> type;
|
std::optional<IdentityType> type;
|
||||||
Nullable<SINT64> startValue;
|
std::optional<SINT64> startValue;
|
||||||
Nullable<SLONG> increment;
|
std::optional<SLONG> increment;
|
||||||
bool restart; // used in ALTER
|
bool restart; // used in ALTER
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1562,8 +1562,7 @@ public:
|
|||||||
CreateRelationNode(MemoryPool& p, RelationSourceNode* aDsqlNode,
|
CreateRelationNode(MemoryPool& p, RelationSourceNode* aDsqlNode,
|
||||||
const Firebird::string* aExternalFile = NULL)
|
const Firebird::string* aExternalFile = NULL)
|
||||||
: RelationNode(p, aDsqlNode),
|
: RelationNode(p, aDsqlNode),
|
||||||
externalFile(aExternalFile),
|
externalFile(aExternalFile)
|
||||||
relationType(rel_persistent)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1583,7 +1582,7 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
const Firebird::string* externalFile;
|
const Firebird::string* externalFile;
|
||||||
Nullable<rel_t> relationType;
|
std::optional<rel_t> relationType = rel_persistent;
|
||||||
bool preserveRowsOpt;
|
bool preserveRowsOpt;
|
||||||
bool deleteRowsOpt;
|
bool deleteRowsOpt;
|
||||||
};
|
};
|
||||||
@ -1977,7 +1976,6 @@ public:
|
|||||||
SSHORT number;
|
SSHORT number;
|
||||||
bool manual;
|
bool manual;
|
||||||
bool conditional;
|
bool conditional;
|
||||||
Nullable<SLONG> firstLength;
|
|
||||||
Firebird::Array<NestConst<DbFileClause> > files;
|
Firebird::Array<NestConst<DbFileClause> > files;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -2468,14 +2466,4 @@ public:
|
|||||||
|
|
||||||
} // namespace
|
} // 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
|
#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 op1_is_time = op1_desc->isTime();
|
||||||
bool op2_is_time = op2_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)
|
if (op1_desc->dsc_dtype == dtype_sql_time_tz)
|
||||||
op1_tz = ((ISC_TIME_TZ*) op1_desc->dsc_address)->time_zone;
|
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;
|
dsc op1_tz_desc, op2_tz_desc;
|
||||||
ISC_TIME_TZ op1_time_tz, op2_time_tz;
|
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);
|
op1_tz_desc.makeTimeTz(&op1_time_tz);
|
||||||
MOV_move(tdbb, const_cast<dsc*>(op1_desc), &op1_tz_desc);
|
MOV_move(tdbb, const_cast<dsc*>(op1_desc), &op1_tz_desc);
|
||||||
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);
|
op2_tz_desc.makeTimeTz(&op2_time_tz);
|
||||||
MOV_move(tdbb, const_cast<dsc*>(op2_desc), &op2_tz_desc);
|
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;
|
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_length = type_lengths[result->dsc_dtype];
|
||||||
result->dsc_scale = 0;
|
result->dsc_scale = 0;
|
||||||
result->dsc_sub_type = 0;
|
result->dsc_sub_type = 0;
|
||||||
result->dsc_address = (UCHAR*) &value->vlu_misc.vlu_sql_time_tz;
|
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)
|
if (op1_tz.has_value())
|
||||||
value->vlu_misc.vlu_sql_time_tz.time_zone = op1_tz.value;
|
value->vlu_misc.vlu_sql_time_tz.time_zone = op1_tz.value();
|
||||||
else if (op2_tz.specified)
|
else if (op2_tz.has_value())
|
||||||
value->vlu_misc.vlu_sql_time_tz.time_zone = op2_tz.value;
|
value->vlu_misc.vlu_sql_time_tz.time_zone = op2_tz.value();
|
||||||
|
|
||||||
return result;
|
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* op1_desc = &value->vlu_desc;
|
||||||
const dsc* op2_desc = 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)
|
if (op1_desc->dsc_dtype == dtype_sql_time_tz)
|
||||||
op1_tz = ((ISC_TIME_TZ*) op1_desc->dsc_address)->time_zone;
|
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;
|
ISC_TIME_TZ op1_time_tz, op2_time_tz;
|
||||||
|
|
||||||
if ((op1_desc->dsc_dtype == dtype_sql_time || op1_desc->dsc_dtype == dtype_timestamp) &&
|
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)
|
if (op1_desc->dsc_dtype == dtype_sql_time)
|
||||||
op1_tz_desc.makeTimeTz(&op1_time_tz);
|
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) &&
|
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)
|
if (op2_desc->dsc_dtype == dtype_sql_time)
|
||||||
op2_tz_desc.makeTimeTz(&op2_time_tz);
|
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));
|
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_length = type_lengths[result->dsc_dtype];
|
||||||
result->dsc_scale = 0;
|
result->dsc_scale = 0;
|
||||||
result->dsc_sub_type = 0;
|
result->dsc_sub_type = 0;
|
||||||
result->dsc_address = (UCHAR*) &value->vlu_misc.vlu_timestamp_tz;
|
result->dsc_address = (UCHAR*) &value->vlu_misc.vlu_timestamp_tz;
|
||||||
|
|
||||||
if (op1_tz.specified)
|
if (op1_tz.has_value())
|
||||||
value->vlu_misc.vlu_timestamp_tz.time_zone = op1_tz.value;
|
value->vlu_misc.vlu_timestamp_tz.time_zone = op1_tz.value();
|
||||||
else if (op2_tz.specified)
|
else if (op2_tz.has_value())
|
||||||
value->vlu_misc.vlu_timestamp_tz.time_zone = op2_tz.value;
|
value->vlu_misc.vlu_timestamp_tz.time_zone = op2_tz.value();
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -5180,7 +5180,7 @@ ValueExprNode* DerivedExprNode::copy(thread_db* tdbb, NodeCopier& copier) const
|
|||||||
i = copier.remap[i];
|
i = copier.remap[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
fb_assert(!cursorNumber.specified);
|
fb_assert(!cursorNumber.has_value());
|
||||||
|
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
@ -5230,8 +5230,8 @@ ValueExprNode* DerivedExprNode::pass2(thread_db* tdbb, CompilerScratch* csb)
|
|||||||
|
|
||||||
dsc* DerivedExprNode::execute(thread_db* tdbb, Request* request) const
|
dsc* DerivedExprNode::execute(thread_db* tdbb, Request* request) const
|
||||||
{
|
{
|
||||||
if (cursorNumber.specified)
|
if (cursorNumber.has_value())
|
||||||
request->req_cursors[cursorNumber.value]->checkState(request);
|
request->req_cursors[cursorNumber.value()]->checkState(request);
|
||||||
|
|
||||||
dsc* value = NULL;
|
dsc* value = NULL;
|
||||||
|
|
||||||
@ -6652,7 +6652,7 @@ ValueExprNode* FieldNode::copy(thread_db* tdbb, NodeCopier& copier) const
|
|||||||
stream = copier.remap[stream];
|
stream = copier.remap[stream];
|
||||||
}
|
}
|
||||||
|
|
||||||
fb_assert(!cursorNumber.specified);
|
fb_assert(!cursorNumber.has_value());
|
||||||
return PAR_gen_field(tdbb, stream, fldId, byId);
|
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);
|
impure_value* const impure = request->getImpure<impure_value>(impureOffset);
|
||||||
|
|
||||||
if (cursorNumber.specified)
|
if (cursorNumber.has_value())
|
||||||
request->req_cursors[cursorNumber.value]->checkState(request);
|
request->req_cursors[cursorNumber.value()]->checkState(request);
|
||||||
|
|
||||||
record_param& rpb = request->req_rpb[fieldStream];
|
record_param& rpb = request->req_rpb[fieldStream];
|
||||||
Record* record = rpb.rpb_record;
|
Record* record = rpb.rpb_record;
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#ifndef DSQL_EXPR_NODES_H
|
#ifndef DSQL_EXPR_NODES_H
|
||||||
#define DSQL_EXPR_NODES_H
|
#define DSQL_EXPR_NODES_H
|
||||||
|
|
||||||
|
#include <optional>
|
||||||
#include "firebird/impl/blr.h"
|
#include "firebird/impl/blr.h"
|
||||||
#include "../dsql/Nodes.h"
|
#include "../dsql/Nodes.h"
|
||||||
#include "../dsql/NodePrinter.h"
|
#include "../dsql/NodePrinter.h"
|
||||||
@ -683,7 +684,7 @@ public:
|
|||||||
public:
|
public:
|
||||||
NestConst<ValueExprNode> arg;
|
NestConst<ValueExprNode> arg;
|
||||||
Firebird::Array<StreamType> internalStreamList;
|
Firebird::Array<StreamType> internalStreamList;
|
||||||
Nullable<USHORT> cursorNumber;
|
std::optional<USHORT> cursorNumber;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -825,7 +826,7 @@ public:
|
|||||||
NestConst<ValueListNode> dsqlIndices;
|
NestConst<ValueListNode> dsqlIndices;
|
||||||
const Format* format;
|
const Format* format;
|
||||||
const StreamType fieldStream;
|
const StreamType fieldStream;
|
||||||
Nullable<USHORT> cursorNumber;
|
std::optional<USHORT> cursorNumber;
|
||||||
const USHORT fieldId;
|
const USHORT fieldId;
|
||||||
const bool byId;
|
const bool byId;
|
||||||
bool dsqlCursorField;
|
bool dsqlCursorField;
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#ifndef DSQL_NODE_PRINTER_H
|
#ifndef DSQL_NODE_PRINTER_H
|
||||||
#define DSQL_NODE_PRINTER_H
|
#define DSQL_NODE_PRINTER_H
|
||||||
|
|
||||||
|
#include <optional>
|
||||||
#include "../dsql/Nodes.h"
|
#include "../dsql/Nodes.h"
|
||||||
|
|
||||||
#define NODE_PRINT(var, property) var.print(STRINGIZE(property), property)
|
#define NODE_PRINT(var, property) var.print(STRINGIZE(property), property)
|
||||||
@ -272,6 +273,13 @@ public:
|
|||||||
print(s, nullable.value);
|
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>
|
template <typename T>
|
||||||
void print(const Firebird::string&, const Firebird::Pair<T>&)
|
void print(const Firebird::string&, const Firebird::Pair<T>&)
|
||||||
{
|
{
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#ifndef DSQL_PARSER_H
|
#ifndef DSQL_PARSER_H
|
||||||
#define DSQL_PARSER_H
|
#define DSQL_PARSER_H
|
||||||
|
|
||||||
|
#include <optional>
|
||||||
#include "../dsql/dsql.h"
|
#include "../dsql/dsql.h"
|
||||||
#include "../dsql/DdlNodes.h"
|
#include "../dsql/DdlNodes.h"
|
||||||
#include "../dsql/BoolNodes.h"
|
#include "../dsql/BoolNodes.h"
|
||||||
@ -250,6 +251,13 @@ private:
|
|||||||
clause = value;
|
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>
|
template <typename T>
|
||||||
void setClause(BaseNullable<T>& clause, const char* duplicateMsg, const BaseNullable<T>& value)
|
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>
|
template <typename T1, typename T2>
|
||||||
void setClause(NestConst<T1>& clause, const char* duplicateMsg, const T2& value)
|
void setClause(NestConst<T1>& clause, const char* duplicateMsg, const T2& value)
|
||||||
{
|
{
|
||||||
@ -312,6 +330,12 @@ private:
|
|||||||
return clause.specified;
|
return clause.specified;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
bool isDuplicateClause(const std::optional<T>& clause)
|
||||||
|
{
|
||||||
|
return clause.has_value();
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
bool isDuplicateClause(const Firebird::Array<T>& clause)
|
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 dsql_par* dsqlFindRecordVersion(const DsqlDmlStatement*, const RelationSourceNode*);
|
||||||
static void dsqlGenEofAssignment(DsqlCompilerScratch* dsqlScratch, SSHORT value);
|
static void dsqlGenEofAssignment(DsqlCompilerScratch* dsqlScratch, SSHORT value);
|
||||||
static void dsqlGenReturning(DsqlCompilerScratch* dsqlScratch, ReturningClause* returning,
|
static void dsqlGenReturning(DsqlCompilerScratch* dsqlScratch, ReturningClause* returning,
|
||||||
Nullable<USHORT> localTableNumber);
|
std::optional<USHORT> localTableNumber);
|
||||||
static void dsqlGenReturningLocalTableCursor(DsqlCompilerScratch* dsqlScratch, ReturningClause* returning,
|
static void dsqlGenReturningLocalTableCursor(DsqlCompilerScratch* dsqlScratch, ReturningClause* returning,
|
||||||
USHORT localTableNumber);
|
USHORT localTableNumber);
|
||||||
static void dsqlGenReturningLocalTableDecl(DsqlCompilerScratch* dsqlScratch, USHORT tableNumber);
|
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,
|
static void preModifyEraseTriggers(thread_db* tdbb, TrigVector** trigs,
|
||||||
StmtNode::WhichTrigger whichTrig, record_param* rpb, record_param* rec, TriggerAction op);
|
StmtNode::WhichTrigger whichTrig, record_param* rpb, record_param* rec, TriggerAction op);
|
||||||
static void preprocessAssignments(thread_db* tdbb, CompilerScratch* csb,
|
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 restartRequest(const Request* request, jrd_tra* transaction);
|
||||||
static void validateExpressions(thread_db* tdbb, const Array<ValidateInfo>& validations);
|
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.
|
// Assignment to cursor fields are always prohibited.
|
||||||
// But we cannot detect FOR cursors here. They are treated in dsqlPass.
|
// 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;
|
error = true;
|
||||||
|
|
||||||
if (error)
|
if (error)
|
||||||
@ -1637,7 +1637,7 @@ DeclareSubFuncNode* DeclareSubFuncNode::dsqlPass(DsqlCompilerScratch* dsqlScratc
|
|||||||
dsqlFunction->udf_scale = returnType->scale;
|
dsqlFunction->udf_scale = returnType->scale;
|
||||||
dsqlFunction->udf_sub_type = returnType->subType;
|
dsqlFunction->udf_sub_type = returnType->subType;
|
||||||
dsqlFunction->udf_length = returnType->length;
|
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)
|
if (dsqlDeterministic)
|
||||||
dsqlSignature.flags |= Signature::FLAG_DETERMINISTIC;
|
dsqlSignature.flags |= Signature::FLAG_DETERMINISTIC;
|
||||||
@ -2358,7 +2358,7 @@ string EraseNode::internalPrint(NodePrinter& printer) const
|
|||||||
|
|
||||||
void EraseNode::genBlr(DsqlCompilerScratch* dsqlScratch)
|
void EraseNode::genBlr(DsqlCompilerScratch* dsqlScratch)
|
||||||
{
|
{
|
||||||
Nullable<USHORT> tableNumber;
|
std::optional<USHORT> tableNumber;
|
||||||
|
|
||||||
if (dsqlReturning && !dsqlScratch->isPsql())
|
if (dsqlReturning && !dsqlScratch->isPsql())
|
||||||
{
|
{
|
||||||
@ -2367,7 +2367,7 @@ void EraseNode::genBlr(DsqlCompilerScratch* dsqlScratch)
|
|||||||
dsqlScratch->appendUChar(blr_begin);
|
dsqlScratch->appendUChar(blr_begin);
|
||||||
|
|
||||||
tableNumber = dsqlScratch->localTableNumber++;
|
tableNumber = dsqlScratch->localTableNumber++;
|
||||||
dsqlGenReturningLocalTableDecl(dsqlScratch, tableNumber.value);
|
dsqlGenReturningLocalTableDecl(dsqlScratch, tableNumber.value());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -2403,7 +2403,7 @@ void EraseNode::genBlr(DsqlCompilerScratch* dsqlScratch)
|
|||||||
|
|
||||||
if (!dsqlScratch->isPsql() && dsqlCursorName.isEmpty())
|
if (!dsqlScratch->isPsql() && dsqlCursorName.isEmpty())
|
||||||
{
|
{
|
||||||
dsqlGenReturningLocalTableCursor(dsqlScratch, dsqlReturning, tableNumber.value);
|
dsqlGenReturningLocalTableCursor(dsqlScratch, dsqlReturning, tableNumber.value());
|
||||||
|
|
||||||
dsqlScratch->appendUChar(blr_end);
|
dsqlScratch->appendUChar(blr_end);
|
||||||
}
|
}
|
||||||
@ -6164,14 +6164,14 @@ string MergeNode::internalPrint(NodePrinter& printer) const
|
|||||||
|
|
||||||
void MergeNode::genBlr(DsqlCompilerScratch* dsqlScratch)
|
void MergeNode::genBlr(DsqlCompilerScratch* dsqlScratch)
|
||||||
{
|
{
|
||||||
Nullable<USHORT> tableNumber;
|
std::optional<USHORT> tableNumber;
|
||||||
|
|
||||||
if (returning && !dsqlScratch->isPsql())
|
if (returning && !dsqlScratch->isPsql())
|
||||||
{
|
{
|
||||||
dsqlScratch->appendUChar(blr_begin);
|
dsqlScratch->appendUChar(blr_begin);
|
||||||
|
|
||||||
tableNumber = dsqlScratch->localTableNumber++;
|
tableNumber = dsqlScratch->localTableNumber++;
|
||||||
dsqlGenReturningLocalTableDecl(dsqlScratch, tableNumber.value);
|
dsqlGenReturningLocalTableDecl(dsqlScratch, tableNumber.value());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Put src info for blr_for.
|
// 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)
|
if (notMatched->overrideClause.has_value())
|
||||||
dsqlScratch->appendUChar(UCHAR(notMatched->overrideClause.value));
|
dsqlScratch->appendUChar(UCHAR(notMatched->overrideClause.value()));
|
||||||
|
|
||||||
GEN_expr(dsqlScratch, notMatched->storeRelation);
|
GEN_expr(dsqlScratch, notMatched->storeRelation);
|
||||||
|
|
||||||
@ -6332,7 +6332,7 @@ void MergeNode::genBlr(DsqlCompilerScratch* dsqlScratch)
|
|||||||
|
|
||||||
if (returning)
|
if (returning)
|
||||||
dsqlGenReturning(dsqlScratch, notMatched->processedReturning, tableNumber);
|
dsqlGenReturning(dsqlScratch, notMatched->processedReturning, tableNumber);
|
||||||
else if (notMatched->overrideClause.specified)
|
else if (notMatched->overrideClause.has_value())
|
||||||
dsqlScratch->appendUChar(blr_null);
|
dsqlScratch->appendUChar(blr_null);
|
||||||
|
|
||||||
if (notMatched->condition && isLast)
|
if (notMatched->condition && isLast)
|
||||||
@ -6414,7 +6414,7 @@ void MergeNode::genBlr(DsqlCompilerScratch* dsqlScratch)
|
|||||||
|
|
||||||
if (returning && !dsqlScratch->isPsql())
|
if (returning && !dsqlScratch->isPsql())
|
||||||
{
|
{
|
||||||
dsqlGenReturningLocalTableCursor(dsqlScratch, returning, tableNumber.value);
|
dsqlGenReturningLocalTableCursor(dsqlScratch, returning, tableNumber.value());
|
||||||
|
|
||||||
dsqlScratch->appendUChar(blr_end);
|
dsqlScratch->appendUChar(blr_end);
|
||||||
}
|
}
|
||||||
@ -6635,7 +6635,7 @@ StmtNode* ModifyNode::internalDsqlPass(DsqlCompilerScratch* dsqlScratch, bool up
|
|||||||
if (dsqlReturning && !dsqlScratch->isPsql() && dsqlCursorName.isEmpty())
|
if (dsqlReturning && !dsqlScratch->isPsql() && dsqlCursorName.isEmpty())
|
||||||
{
|
{
|
||||||
node->dsqlReturningLocalTableNumber = updateOrInsert ?
|
node->dsqlReturningLocalTableNumber = updateOrInsert ?
|
||||||
dsqlReturningLocalTableNumber.value :
|
dsqlReturningLocalTableNumber.value() :
|
||||||
dsqlScratch->localTableNumber++;
|
dsqlScratch->localTableNumber++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6824,7 +6824,7 @@ void ModifyNode::genBlr(DsqlCompilerScratch* dsqlScratch)
|
|||||||
if (dsqlReturning && !dsqlScratch->isPsql())
|
if (dsqlReturning && !dsqlScratch->isPsql())
|
||||||
{
|
{
|
||||||
if (dsqlCursorName.isEmpty())
|
if (dsqlCursorName.isEmpty())
|
||||||
dsqlGenReturningLocalTableDecl(dsqlScratch, dsqlReturningLocalTableNumber.value);
|
dsqlGenReturningLocalTableDecl(dsqlScratch, dsqlReturningLocalTableNumber.value());
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
dsqlScratch->appendUChar(blr_send);
|
dsqlScratch->appendUChar(blr_send);
|
||||||
@ -6869,7 +6869,7 @@ void ModifyNode::genBlr(DsqlCompilerScratch* dsqlScratch)
|
|||||||
!(dsqlScratch->flags & DsqlCompilerScratch::FLAG_UPDATE_OR_INSERT) &&
|
!(dsqlScratch->flags & DsqlCompilerScratch::FLAG_UPDATE_OR_INSERT) &&
|
||||||
dsqlCursorName.isEmpty())
|
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());
|
node->overrideClause = static_cast<OverrideClause>(csb->csb_blr_reader.getByte());
|
||||||
|
|
||||||
switch (node->overrideClause.value)
|
switch (node->overrideClause.value())
|
||||||
{
|
{
|
||||||
case OverrideClause::USER_VALUE:
|
case OverrideClause::USER_VALUE:
|
||||||
case OverrideClause::SYSTEM_VALUE:
|
case OverrideClause::SYSTEM_VALUE:
|
||||||
@ -7851,7 +7851,7 @@ void StoreNode::genBlr(DsqlCompilerScratch* dsqlScratch)
|
|||||||
if (dsqlReturning && !dsqlScratch->isPsql())
|
if (dsqlReturning && !dsqlScratch->isPsql())
|
||||||
{
|
{
|
||||||
if (dsqlRse)
|
if (dsqlRse)
|
||||||
dsqlGenReturningLocalTableDecl(dsqlScratch, dsqlReturningLocalTableNumber.value);
|
dsqlGenReturningLocalTableDecl(dsqlScratch, dsqlReturningLocalTableNumber.value());
|
||||||
else if (!(dsqlScratch->flags & DsqlCompilerScratch::FLAG_UPDATE_OR_INSERT))
|
else if (!(dsqlScratch->flags & DsqlCompilerScratch::FLAG_UPDATE_OR_INSERT))
|
||||||
{
|
{
|
||||||
dsqlScratch->appendUChar(blr_send);
|
dsqlScratch->appendUChar(blr_send);
|
||||||
@ -7866,10 +7866,10 @@ void StoreNode::genBlr(DsqlCompilerScratch* dsqlScratch)
|
|||||||
GEN_expr(dsqlScratch, dsqlRse);
|
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)
|
if (overrideClause.has_value())
|
||||||
dsqlScratch->appendUChar(UCHAR(overrideClause.value));
|
dsqlScratch->appendUChar(UCHAR(overrideClause.value()));
|
||||||
|
|
||||||
GEN_expr(dsqlScratch, target);
|
GEN_expr(dsqlScratch, target);
|
||||||
|
|
||||||
@ -7879,15 +7879,15 @@ void StoreNode::genBlr(DsqlCompilerScratch* dsqlScratch)
|
|||||||
{
|
{
|
||||||
dsqlGenReturning(dsqlScratch, dsqlReturning, dsqlReturningLocalTableNumber);
|
dsqlGenReturning(dsqlScratch, dsqlReturning, dsqlReturningLocalTableNumber);
|
||||||
|
|
||||||
if (dsqlReturningLocalTableNumber.isAssigned())
|
if (dsqlReturningLocalTableNumber.has_value())
|
||||||
{
|
{
|
||||||
if (dsqlScratch->flags & DsqlCompilerScratch::FLAG_UPDATE_OR_INSERT)
|
if (dsqlScratch->flags & DsqlCompilerScratch::FLAG_UPDATE_OR_INSERT)
|
||||||
dsqlScratch->appendUChar(blr_end); // close blr_if (blr_eql, blr_internal_info)
|
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);
|
dsqlScratch->appendUChar(blr_null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -9013,8 +9013,7 @@ SetTransactionNode* SetTransactionNode::dsqlPass(DsqlCompilerScratch* dsqlScratc
|
|||||||
|
|
||||||
// Find out isolation level - if specified. This is required for
|
// Find out isolation level - if specified. This is required for
|
||||||
// specifying the correct lock level in reserving clause.
|
// specifying the correct lock level in reserving clause.
|
||||||
const USHORT lockLevel = isoLevel.specified && isoLevel.value == ISO_LEVEL_CONSISTENCY ?
|
const USHORT lockLevel = isoLevel == ISO_LEVEL_CONSISTENCY ? isc_tpb_protected : isc_tpb_shared;
|
||||||
isc_tpb_protected : isc_tpb_shared;
|
|
||||||
|
|
||||||
// Stuff some version info.
|
// Stuff some version info.
|
||||||
dsqlScratch->appendUChar(isc_tpb_version1);
|
dsqlScratch->appendUChar(isc_tpb_version1);
|
||||||
@ -9025,23 +9024,23 @@ SetTransactionNode* SetTransactionNode::dsqlPass(DsqlCompilerScratch* dsqlScratc
|
|||||||
if (wait.specified)
|
if (wait.specified)
|
||||||
dsqlScratch->appendUChar(wait.value ? isc_tpb_wait : isc_tpb_nowait);
|
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);
|
dsqlScratch->appendUChar(isc_tpb_concurrency);
|
||||||
else if (isoLevel.value == ISO_LEVEL_CONSISTENCY)
|
else if (isoLevel == ISO_LEVEL_CONSISTENCY)
|
||||||
dsqlScratch->appendUChar(isc_tpb_consistency);
|
dsqlScratch->appendUChar(isc_tpb_consistency);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
dsqlScratch->appendUChar(isc_tpb_read_committed);
|
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);
|
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);
|
dsqlScratch->appendUChar(isc_tpb_rec_version);
|
||||||
else
|
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);
|
dsqlScratch->appendUChar(isc_tpb_no_rec_version);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -9059,22 +9058,22 @@ SetTransactionNode* SetTransactionNode::dsqlPass(DsqlCompilerScratch* dsqlScratc
|
|||||||
if (autoCommit.specified)
|
if (autoCommit.specified)
|
||||||
dsqlScratch->appendUChar(isc_tpb_autocommit);
|
dsqlScratch->appendUChar(isc_tpb_autocommit);
|
||||||
|
|
||||||
if (lockTimeout.specified)
|
if (lockTimeout.has_value())
|
||||||
{
|
{
|
||||||
dsqlScratch->appendUChar(isc_tpb_lock_timeout);
|
dsqlScratch->appendUChar(isc_tpb_lock_timeout);
|
||||||
dsqlScratch->appendUChar(2);
|
dsqlScratch->appendUChar(2);
|
||||||
dsqlScratch->appendUShort(lockTimeout.value);
|
dsqlScratch->appendUShort(lockTimeout.value());
|
||||||
}
|
}
|
||||||
|
|
||||||
for (RestrictionOption** i = reserveList.begin(); i != reserveList.end(); ++i)
|
for (RestrictionOption** i = reserveList.begin(); i != reserveList.end(); ++i)
|
||||||
genTableLock(dsqlScratch, **i, lockLevel);
|
genTableLock(dsqlScratch, **i, lockLevel);
|
||||||
|
|
||||||
if (atSnapshotNumber.specified)
|
if (atSnapshotNumber.has_value())
|
||||||
{
|
{
|
||||||
dsqlScratch->appendUChar(isc_tpb_at_snapshot_number);
|
dsqlScratch->appendUChar(isc_tpb_at_snapshot_number);
|
||||||
static_assert(sizeof(CommitNumber) == sizeof(FB_UINT64), "sizeof(CommitNumber) == sizeof(FB_UINT64)");
|
static_assert(sizeof(CommitNumber) == sizeof(FB_UINT64), "sizeof(CommitNumber) == sizeof(FB_UINT64)");
|
||||||
dsqlScratch->appendUChar(sizeof(CommitNumber));
|
dsqlScratch->appendUChar(sizeof(CommitNumber));
|
||||||
dsqlScratch->appendUInt64(atSnapshotNumber.value);
|
dsqlScratch->appendUInt64(atSnapshotNumber.value());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dsqlScratch->getBlrData().getCount() > 1) // 1 -> isc_tpb_version1
|
if (dsqlScratch->getBlrData().getCount() > 1) // 1 -> isc_tpb_version1
|
||||||
@ -9643,7 +9642,7 @@ void UpdateOrInsertNode::genBlr(DsqlCompilerScratch* dsqlScratch)
|
|||||||
storeNode->genBlr(dsqlScratch);
|
storeNode->genBlr(dsqlScratch);
|
||||||
|
|
||||||
// StoreNode::genBlr closes our blr_if when RETURNING in DSQL is used.
|
// 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); // blr_if
|
||||||
|
|
||||||
dsqlScratch->appendUChar(blr_end);
|
dsqlScratch->appendUChar(blr_end);
|
||||||
@ -9908,16 +9907,16 @@ static void dsqlGenEofAssignment(DsqlCompilerScratch* dsqlScratch, SSHORT value)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void dsqlGenReturning(DsqlCompilerScratch* dsqlScratch, ReturningClause* returning,
|
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++;
|
const USHORT localStoreContext = dsqlScratch->contextNumber++;
|
||||||
|
|
||||||
dsqlScratch->appendUChar(blr_store);
|
dsqlScratch->appendUChar(blr_store);
|
||||||
dsqlScratch->putBlrMarkers(StmtNode::MARK_AVOID_COUNTERS);
|
dsqlScratch->putBlrMarkers(StmtNode::MARK_AVOID_COUNTERS);
|
||||||
dsqlScratch->appendUChar(blr_local_table_id);
|
dsqlScratch->appendUChar(blr_local_table_id);
|
||||||
dsqlScratch->appendUShort(localTableNumber.value);
|
dsqlScratch->appendUShort(localTableNumber.value());
|
||||||
dsqlScratch->appendMetaString(""); // alias
|
dsqlScratch->appendMetaString(""); // alias
|
||||||
GEN_stuff_context_number(dsqlScratch, localStoreContext);
|
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.
|
// 1. Remove assignments of DEFAULT to computed fields.
|
||||||
// 2. Remove assignments to identity column when OVERRIDING USER VALUE is specified in INSERT.
|
// 2. Remove assignments to identity column when OVERRIDING USER VALUE is specified in INSERT.
|
||||||
static void preprocessAssignments(thread_db* tdbb, CompilerScratch* csb,
|
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)
|
if (!compoundNode)
|
||||||
return;
|
return;
|
||||||
@ -11036,7 +11035,7 @@ static void preprocessAssignments(thread_db* tdbb, CompilerScratch* csb,
|
|||||||
if (!relation)
|
if (!relation)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Nullable<IdentityType> identityType;
|
std::optional<IdentityType> identityType;
|
||||||
|
|
||||||
for (FB_SIZE_T i = compoundNode->statements.getCount(); i--; )
|
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 &&
|
if (assignToField->fieldStream == stream &&
|
||||||
(fld = MET_get_field(relation, fieldId)))
|
(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;
|
identityType = fld->fld_identity_type;
|
||||||
|
|
||||||
if (*insertOverride == OverrideClause::USER_VALUE)
|
if (*insertOverride == OverrideClause::USER_VALUE)
|
||||||
@ -11096,9 +11095,9 @@ static void preprocessAssignments(thread_db* tdbb, CompilerScratch* csb,
|
|||||||
if (!insertOverride)
|
if (!insertOverride)
|
||||||
return;
|
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);
|
ERR_post(Arg::Gds(isc_overriding_without_identity) << relation->rel_name);
|
||||||
|
|
||||||
if (identityType == IDENT_TYPE_BY_DEFAULT && *insertOverride == OverrideClause::SYSTEM_VALUE)
|
if (identityType == IDENT_TYPE_BY_DEFAULT && *insertOverride == OverrideClause::SYSTEM_VALUE)
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#ifndef DSQL_STMT_NODES_H
|
#ifndef DSQL_STMT_NODES_H
|
||||||
#define DSQL_STMT_NODES_H
|
#define DSQL_STMT_NODES_H
|
||||||
|
|
||||||
|
#include <optional>
|
||||||
#include "../jrd/MetaName.h"
|
#include "../jrd/MetaName.h"
|
||||||
#include "firebird/impl/blr.h"
|
#include "firebird/impl/blr.h"
|
||||||
#include "../jrd/Function.h"
|
#include "../jrd/Function.h"
|
||||||
@ -1072,7 +1073,7 @@ public:
|
|||||||
Firebird::Array<NestConst<FieldNode>> fields;
|
Firebird::Array<NestConst<FieldNode>> fields;
|
||||||
NestConst<ValueListNode> values;
|
NestConst<ValueListNode> values;
|
||||||
NestConst<BoolExprNode> condition;
|
NestConst<BoolExprNode> condition;
|
||||||
Nullable<OverrideClause> overrideClause;
|
std::optional<OverrideClause> overrideClause;
|
||||||
|
|
||||||
NestConst<Jrd::RecordSourceNode> storeRelation;
|
NestConst<Jrd::RecordSourceNode> storeRelation;
|
||||||
NestValueArray processedFields;
|
NestValueArray processedFields;
|
||||||
@ -1188,7 +1189,7 @@ public:
|
|||||||
StreamType newStream = 0;
|
StreamType newStream = 0;
|
||||||
unsigned marks = 0; // see StmtNode::IUD_MARK_xxx
|
unsigned marks = 0; // see StmtNode::IUD_MARK_xxx
|
||||||
USHORT dsqlRseFlags = 0;
|
USHORT dsqlRseFlags = 0;
|
||||||
Nullable<USHORT> dsqlReturningLocalTableNumber;
|
std::optional<USHORT> dsqlReturningLocalTableNumber;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -1315,8 +1316,8 @@ public:
|
|||||||
NestConst<StmtNode> subStore;
|
NestConst<StmtNode> subStore;
|
||||||
Firebird::Array<ValidateInfo> validations;
|
Firebird::Array<ValidateInfo> validations;
|
||||||
unsigned marks;
|
unsigned marks;
|
||||||
Nullable<USHORT> dsqlReturningLocalTableNumber;
|
std::optional<USHORT> dsqlReturningLocalTableNumber;
|
||||||
Nullable<OverrideClause> overrideClause;
|
std::optional<OverrideClause> overrideClause;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -1621,9 +1622,9 @@ private:
|
|||||||
public:
|
public:
|
||||||
Firebird::Array<RestrictionOption*> reserveList;
|
Firebird::Array<RestrictionOption*> reserveList;
|
||||||
Firebird::UCharBuffer tpb;
|
Firebird::UCharBuffer tpb;
|
||||||
Nullable<CommitNumber> atSnapshotNumber;
|
std::optional<CommitNumber> atSnapshotNumber;
|
||||||
Nullable<unsigned> isoLevel;
|
std::optional<unsigned> isoLevel;
|
||||||
Nullable<USHORT> lockTimeout;
|
std::optional<USHORT> lockTimeout;
|
||||||
Nullable<bool> readOnly;
|
Nullable<bool> readOnly;
|
||||||
Nullable<bool> wait;
|
Nullable<bool> wait;
|
||||||
Nullable<bool> noAutoUndo;
|
Nullable<bool> noAutoUndo;
|
||||||
@ -2001,7 +2002,7 @@ public:
|
|||||||
NestConst<ValueListNode> order;
|
NestConst<ValueListNode> order;
|
||||||
NestConst<RowsClause> rows;
|
NestConst<RowsClause> rows;
|
||||||
NestConst<ReturningClause> returning;
|
NestConst<ReturningClause> returning;
|
||||||
Nullable<OverrideClause> overrideClause;
|
std::optional<OverrideClause> overrideClause;
|
||||||
NestConst<StoreNode> storeNode;
|
NestConst<StoreNode> storeNode;
|
||||||
NestConst<ModifyNode> modifyNode;
|
NestConst<ModifyNode> modifyNode;
|
||||||
Firebird::Array<NestConst<AssignmentNode>> varAssignments;
|
Firebird::Array<NestConst<AssignmentNode>> varAssignments;
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <optional>
|
||||||
#include "../dsql/Nodes.h"
|
#include "../dsql/Nodes.h"
|
||||||
#include "../dsql/AggNodes.h"
|
#include "../dsql/AggNodes.h"
|
||||||
#include "../dsql/DdlNodes.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 ||
|
if (field->dtype <= dtype_any_text ||
|
||||||
(field->dtype == dtype_blob && field->subType == isc_blob_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;
|
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
|
// This field has already been resolved once, and the collation
|
||||||
// hasn't changed. Therefore, no need to do it again.
|
// 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)
|
if (afield)
|
||||||
{
|
{
|
||||||
field->charSetId = afield->charSetId;
|
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->collationId = afield->collationId;
|
||||||
field->textType = afield->textType;
|
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)))
|
(field->flags & FLD_national)))
|
||||||
{
|
{
|
||||||
// Attach the database default character set, if not otherwise specified
|
// 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())
|
if (collation_name.hasData())
|
||||||
{
|
{
|
||||||
const dsql_intlsym* resolved_collation = METD_get_collation(dsqlScratch->getTransaction(),
|
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)
|
if (!resolved_collation)
|
||||||
{
|
{
|
||||||
@ -382,7 +382,7 @@ void DDL_resolve_intl_type(DsqlCompilerScratch* dsqlScratch, dsql_fld* field,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
charSetName = METD_get_charset_name(dsqlScratch->getTransaction(),
|
charSetName = METD_get_charset_name(dsqlScratch->getTransaction(),
|
||||||
field->charSetId.value);
|
field->charSetId.value_or(CS_NONE));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Specified collation not found
|
// Specified collation not found
|
||||||
@ -396,8 +396,8 @@ void DDL_resolve_intl_type(DsqlCompilerScratch* dsqlScratch, dsql_fld* field,
|
|||||||
|
|
||||||
resolved_type = resolved_collation;
|
resolved_type = resolved_collation;
|
||||||
|
|
||||||
if ((field->charSetId.value != resolved_type->intlsym_charset_id) &&
|
if ((field->charSetId.value_or(CS_NONE) != resolved_type->intlsym_charset_id) &&
|
||||||
(field->charSetId.value != ttype_dynamic))
|
(field->charSetId.value_or(CS_NONE) != ttype_dynamic))
|
||||||
{
|
{
|
||||||
ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-204) <<
|
ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-204) <<
|
||||||
Arg::Gds(isc_dsql_datatype_err) <<
|
Arg::Gds(isc_dsql_datatype_err) <<
|
||||||
|
@ -226,7 +226,7 @@ public:
|
|||||||
USHORT segLength = 0; // Segment length for blobs
|
USHORT segLength = 0; // Segment length for blobs
|
||||||
USHORT precision = 0; // Precision for exact numeric types
|
USHORT precision = 0; // Precision for exact numeric types
|
||||||
USHORT charLength = 0; // Length of field in characters
|
USHORT charLength = 0; // Length of field in characters
|
||||||
Nullable<SSHORT> charSetId;
|
std::optional<SSHORT> charSetId;
|
||||||
SSHORT collationId = 0;
|
SSHORT collationId = 0;
|
||||||
SSHORT textType = 0;
|
SSHORT textType = 0;
|
||||||
bool fullDomain = false; // Domain name without TYPE OF prefix
|
bool fullDomain = false; // Domain name without TYPE OF prefix
|
||||||
@ -725,19 +725,19 @@ struct SignatureParameter
|
|||||||
MetaName charSetName;
|
MetaName charSetName;
|
||||||
MetaName collationName;
|
MetaName collationName;
|
||||||
MetaName subTypeName;
|
MetaName subTypeName;
|
||||||
Nullable<SSHORT> collationId;
|
std::optional<SSHORT> collationId;
|
||||||
Nullable<SSHORT> nullFlag;
|
std::optional<SSHORT> nullFlag;
|
||||||
SSHORT mechanism = 0;
|
SSHORT mechanism = 0;
|
||||||
Nullable<SSHORT> fieldLength;
|
std::optional<SSHORT> fieldLength;
|
||||||
Nullable<SSHORT> fieldScale;
|
std::optional<SSHORT> fieldScale;
|
||||||
Nullable<SSHORT> fieldType;
|
std::optional<SSHORT> fieldType;
|
||||||
Nullable<SSHORT> fieldSubType;
|
std::optional<SSHORT> fieldSubType;
|
||||||
Nullable<SSHORT> fieldSegmentLength;
|
std::optional<SSHORT> fieldSegmentLength;
|
||||||
Nullable<SSHORT> fieldNullFlag;
|
std::optional<SSHORT> fieldNullFlag;
|
||||||
Nullable<SSHORT> fieldCharLength;
|
std::optional<SSHORT> fieldCharLength;
|
||||||
Nullable<SSHORT> fieldCollationId;
|
std::optional<SSHORT> fieldCollationId;
|
||||||
Nullable<SSHORT> fieldCharSetId;
|
std::optional<SSHORT> fieldCharSetId;
|
||||||
Nullable<SSHORT> fieldPrecision;
|
std::optional<SSHORT> fieldPrecision;
|
||||||
|
|
||||||
bool operator >(const SignatureParameter& o) const
|
bool operator >(const SignatureParameter& o) const
|
||||||
{
|
{
|
||||||
@ -755,19 +755,19 @@ struct SignatureParameter
|
|||||||
fieldName == o.fieldName &&
|
fieldName == o.fieldName &&
|
||||||
relationName == o.relationName &&
|
relationName == o.relationName &&
|
||||||
collationId == o.collationId &&
|
collationId == o.collationId &&
|
||||||
nullFlag.orElse(FALSE) == o.nullFlag.orElse(FALSE) &&
|
nullFlag.value_or(FALSE) == o.nullFlag.value_or(FALSE) &&
|
||||||
mechanism == o.mechanism &&
|
mechanism == o.mechanism &&
|
||||||
fieldLength == o.fieldLength &&
|
fieldLength == o.fieldLength &&
|
||||||
fieldScale == o.fieldScale &&
|
fieldScale == o.fieldScale &&
|
||||||
fieldType == o.fieldType &&
|
fieldType == o.fieldType &&
|
||||||
fieldSubType.orElse(0) == o.fieldSubType.orElse(0) &&
|
fieldSubType.value_or(0) == o.fieldSubType.value_or(0) &&
|
||||||
fieldSegmentLength == o.fieldSegmentLength &&
|
fieldSegmentLength == o.fieldSegmentLength &&
|
||||||
fieldNullFlag.orElse(FALSE) == o.fieldNullFlag.orElse(FALSE) &&
|
fieldNullFlag.value_or(FALSE) == o.fieldNullFlag.value_or(FALSE) &&
|
||||||
fieldCharLength == o.fieldCharLength &&
|
fieldCharLength == o.fieldCharLength &&
|
||||||
charSetName == o.charSetName &&
|
charSetName == o.charSetName &&
|
||||||
collationName == o.collationName &&
|
collationName == o.collationName &&
|
||||||
subTypeName == o.subTypeName &&
|
subTypeName == o.subTypeName &&
|
||||||
fieldCollationId.orElse(0) == o.fieldCollationId.orElse(0) &&
|
fieldCollationId.value_or(0) == o.fieldCollationId.value_or(0) &&
|
||||||
fieldCharSetId == o.fieldCharSetId &&
|
fieldCharSetId == o.fieldCharSetId &&
|
||||||
fieldPrecision == o.fieldPrecision;
|
fieldPrecision == o.fieldPrecision;
|
||||||
}
|
}
|
||||||
|
@ -69,14 +69,14 @@ void DsqlDescMaker::fromElement(dsc* desc, const TypeClause* field)
|
|||||||
{
|
{
|
||||||
composeDesc(desc,
|
composeDesc(desc,
|
||||||
field->elementDtype, field->scale, field->subType, field->elementLength,
|
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)
|
void DsqlDescMaker::fromField(dsc* desc, const TypeClause* field)
|
||||||
{
|
{
|
||||||
composeDesc(desc,
|
composeDesc(desc,
|
||||||
field->dtype, field->scale, field->subType, field->length,
|
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,
|
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->subType = FLX.RDB$FIELD_SUB_TYPE;
|
||||||
field->dimensions = FLX.RDB$DIMENSIONS.NULL ? 0 : FLX.RDB$DIMENSIONS;
|
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)
|
if (!FLX.RDB$CHARACTER_SET_ID.NULL)
|
||||||
field->charSetId = FLX.RDB$CHARACTER_SET_ID;
|
field->charSetId = FLX.RDB$CHARACTER_SET_ID;
|
||||||
field->collationId = 0;
|
field->collationId = 0;
|
||||||
|
@ -727,23 +727,24 @@ using namespace Firebird;
|
|||||||
%nonassoc ALTER
|
%nonassoc ALTER
|
||||||
%nonassoc COLUMN
|
%nonassoc COLUMN
|
||||||
|
|
||||||
%union
|
%union YYSTYPE
|
||||||
{
|
{
|
||||||
BaseNullable<int> nullableIntVal;
|
YYSTYPE()
|
||||||
|
{}
|
||||||
|
|
||||||
|
std::optional<int> nullableIntVal;
|
||||||
BaseNullable<bool> nullableBoolVal;
|
BaseNullable<bool> nullableBoolVal;
|
||||||
BaseNullable<Jrd::TriggerDefinition::SqlSecurity> nullableSqlSecurityVal;
|
std::optional<Jrd::TriggerDefinition::SqlSecurity> nullableSqlSecurityVal;
|
||||||
BaseNullable<Jrd::OverrideClause> nullableOverrideClause;
|
std::optional<Jrd::OverrideClause> nullableOverrideClause;
|
||||||
struct { bool first; bool second; } boolPair;
|
struct { bool first; bool second; } boolPair;
|
||||||
bool boolVal;
|
bool boolVal;
|
||||||
int intVal;
|
int intVal;
|
||||||
unsigned uintVal;
|
unsigned uintVal;
|
||||||
SLONG int32Val;
|
SLONG int32Val;
|
||||||
BaseNullable<SLONG> nullableInt32Val;
|
|
||||||
SINT64 int64Val;
|
SINT64 int64Val;
|
||||||
FB_UINT64 uint64Val;
|
FB_UINT64 uint64Val;
|
||||||
BaseNullable<SINT64> nullableInt64Val;
|
std::optional<SINT64> nullableInt64Val;
|
||||||
BaseNullable<BaseNullable<SINT64> > nullableNullableInt64Val;
|
std::optional<FB_UINT64> nullableUint64Val;
|
||||||
BaseNullable<FB_UINT64> nullableUint64Val;
|
|
||||||
Jrd::ScaledNumber scaledNumber;
|
Jrd::ScaledNumber scaledNumber;
|
||||||
UCHAR blrOp;
|
UCHAR blrOp;
|
||||||
Jrd::OrderNode::NullsPlacement nullsPlacement;
|
Jrd::OrderNode::NullsPlacement nullsPlacement;
|
||||||
@ -1449,10 +1450,10 @@ arg_desc($parameters)
|
|||||||
|
|
||||||
%type <nullableIntVal> param_mechanism
|
%type <nullableIntVal> param_mechanism
|
||||||
param_mechanism
|
param_mechanism
|
||||||
: /* nothing */ { $$ = Nullable<int>::empty(); } // Beware: This means FUN_reference or FUN_blob_struct.
|
: /* nothing */ { $$ = std::nullopt; } // Beware: This means FUN_reference or FUN_blob_struct.
|
||||||
| BY DESCRIPTOR { $$ = Nullable<int>::val(FUN_descriptor); }
|
| BY DESCRIPTOR { $$ = FUN_descriptor; }
|
||||||
| BY SCALAR_ARRAY { $$ = Nullable<int>::val(FUN_scalar_array); }
|
| BY SCALAR_ARRAY { $$ = FUN_scalar_array; }
|
||||||
| NULL { $$ = Nullable<int>::val(FUN_ref_with_null); }
|
| NULL { $$ = FUN_ref_with_null; }
|
||||||
;
|
;
|
||||||
|
|
||||||
%type return_value1(<createAlterFunctionNode>)
|
%type return_value1(<createAlterFunctionNode>)
|
||||||
@ -1852,7 +1853,7 @@ replace_sequence_clause
|
|||||||
replace_sequence_options($2)
|
replace_sequence_options($2)
|
||||||
{
|
{
|
||||||
// Remove this to implement CORE-5137
|
// Remove this to implement CORE-5137
|
||||||
if (!$2->restartSpecified && !$2->step.specified)
|
if (!$2->restartSpecified && !$2->step.has_value())
|
||||||
yyerrorIncompleteCmd(YYPOSNARG(3));
|
yyerrorIncompleteCmd(YYPOSNARG(3));
|
||||||
$$ = $2;
|
$$ = $2;
|
||||||
}
|
}
|
||||||
@ -1885,7 +1886,7 @@ alter_sequence_clause
|
|||||||
}
|
}
|
||||||
alter_sequence_options($2)
|
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));
|
yyerrorIncompleteCmd(YYPOSNARG(3));
|
||||||
$$ = $2;
|
$$ = $2;
|
||||||
}
|
}
|
||||||
@ -1913,8 +1914,8 @@ restart_option($seqNode)
|
|||||||
|
|
||||||
%type <nullableInt64Val> with_opt
|
%type <nullableInt64Val> with_opt
|
||||||
with_opt
|
with_opt
|
||||||
: /* Nothign */ { $$ = BaseNullable<SINT64>::empty(); }
|
: /* Nothign */ { $$ = std::nullopt; }
|
||||||
| WITH sequence_value { $$ = BaseNullable<SINT64>::val($2); }
|
| WITH sequence_value { $$ = $2; }
|
||||||
;
|
;
|
||||||
|
|
||||||
%type <createAlterSequenceNode> set_generator_clause
|
%type <createAlterSequenceNode> set_generator_clause
|
||||||
@ -1926,7 +1927,7 @@ set_generator_clause
|
|||||||
node->alter = true;
|
node->alter = true;
|
||||||
node->legacy = true;
|
node->legacy = true;
|
||||||
node->restartSpecified = true;
|
node->restartSpecified = true;
|
||||||
node->value = BaseNullable<SINT64>::val($5);
|
node->value = $5;
|
||||||
$$ = node;
|
$$ = node;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
@ -2278,12 +2279,12 @@ gtt_table_clause
|
|||||||
: simple_table_name
|
: simple_table_name
|
||||||
{
|
{
|
||||||
$<createRelationNode>$ = newNode<CreateRelationNode>($1);
|
$<createRelationNode>$ = newNode<CreateRelationNode>($1);
|
||||||
$<createRelationNode>$->relationType = Nullable<rel_t>::empty();
|
$<createRelationNode>$->relationType = std::nullopt;
|
||||||
}
|
}
|
||||||
'(' table_elements($2) ')' gtt_ops($2)
|
'(' table_elements($2) ')' gtt_ops($2)
|
||||||
{
|
{
|
||||||
$$ = $2;
|
$$ = $2;
|
||||||
if (!$$->relationType.specified)
|
if (!$$->relationType.has_value())
|
||||||
$$->relationType = rel_global_temp_delete;
|
$$->relationType = rel_global_temp_delete;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
@ -4025,8 +4026,8 @@ trigger_type_suffix
|
|||||||
|
|
||||||
%type <nullableIntVal> trigger_position
|
%type <nullableIntVal> trigger_position
|
||||||
trigger_position
|
trigger_position
|
||||||
: /* nothing */ { $$ = Nullable<int>::empty(); }
|
: /* nothing */ { $$ = std::nullopt; }
|
||||||
| POSITION nonneg_short_integer { $$ = Nullable<int>::val($2); }
|
| POSITION nonneg_short_integer { $$ = $2; }
|
||||||
;
|
;
|
||||||
|
|
||||||
// ALTER statement
|
// ALTER statement
|
||||||
@ -4594,21 +4595,21 @@ alter_trigger_clause
|
|||||||
%type <nullableUint64Val> trigger_type_opt
|
%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_opt // we do not allow alter database triggers, hence we do not use trigger_type here
|
||||||
: trigger_type_prefix trigger_type_suffix
|
: 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
|
%type <nullableSqlSecurityVal> trg_sql_security_clause
|
||||||
trg_sql_security_clause
|
trg_sql_security_clause
|
||||||
: // nothing
|
: // nothing
|
||||||
{ $$ = Nullable<TriggerDefinition::SqlSecurity>::empty(); }
|
{ $$ = std::nullopt; }
|
||||||
| SQL SECURITY DEFINER
|
| SQL SECURITY DEFINER
|
||||||
{ $$ = Nullable<TriggerDefinition::SqlSecurity>::val(TriggerDefinition::SS_DEFINER); }
|
{ $$ = TriggerDefinition::SS_DEFINER; }
|
||||||
| SQL SECURITY INVOKER
|
| SQL SECURITY INVOKER
|
||||||
{ $$ = Nullable<TriggerDefinition::SqlSecurity>::val(TriggerDefinition::SS_INVOKER); }
|
{ $$ = TriggerDefinition::SS_INVOKER; }
|
||||||
| DROP SQL SECURITY
|
| DROP SQL SECURITY
|
||||||
{ $$ = Nullable<TriggerDefinition::SqlSecurity>::val(TriggerDefinition::SS_DROP); }
|
{ $$ = TriggerDefinition::SS_DROP; }
|
||||||
;
|
;
|
||||||
|
|
||||||
// DROP metadata operations
|
// DROP metadata operations
|
||||||
@ -6619,9 +6620,9 @@ insert_start
|
|||||||
|
|
||||||
%type <nullableOverrideClause> override_opt
|
%type <nullableOverrideClause> override_opt
|
||||||
override_opt
|
override_opt
|
||||||
: /* nothing */ { $$ = Nullable<OverrideClause>::empty(); }
|
: /* nothing */ { $$ = std::nullopt; }
|
||||||
| OVERRIDING USER VALUE { $$ = Nullable<OverrideClause>::val(OverrideClause::USER_VALUE); }
|
| OVERRIDING USER VALUE { $$ = OverrideClause::USER_VALUE; }
|
||||||
| OVERRIDING SYSTEM VALUE { $$ = Nullable<OverrideClause>::val(OverrideClause::SYSTEM_VALUE); }
|
| OVERRIDING SYSTEM VALUE { $$ = OverrideClause::SYSTEM_VALUE; }
|
||||||
;
|
;
|
||||||
|
|
||||||
%type <valueListNode> value_or_default_list
|
%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)
|
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)
|
switch (i->type)
|
||||||
{
|
{
|
||||||
case TYPE_SSHORT:
|
case TYPE_SSHORT:
|
||||||
@ -192,11 +240,8 @@ void PreparedStatement::Builder::moveFromResultSet(thread_db* tdbb, ResultSet* r
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case TYPE_STRING:
|
case TYPE_STRING:
|
||||||
{
|
*(string*) i->address = rs->getString(tdbb, i->number);
|
||||||
AbstractString* str = (AbstractString*) i->address;
|
|
||||||
str->replace(0, str->length(), rs->getString(tdbb, i->number));
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
case TYPE_METANAME:
|
case TYPE_METANAME:
|
||||||
*(MetaName*) i->address = rs->getMetaName(tdbb, i->number);
|
*(MetaName*) i->address = rs->getMetaName(tdbb, i->number);
|
||||||
@ -209,9 +254,6 @@ void PreparedStatement::Builder::moveFromResultSet(thread_db* tdbb, ResultSet* r
|
|||||||
default:
|
default:
|
||||||
fb_assert(false);
|
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)
|
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);
|
stmt->setNull(i->number);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -246,7 +350,7 @@ void PreparedStatement::Builder::moveToStatement(thread_db* tdbb, PreparedStatem
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case TYPE_STRING:
|
case TYPE_STRING:
|
||||||
stmt->setString(tdbb, i->number, *(AbstractString*) i->address);
|
stmt->setString(tdbb, i->number, *(string*) i->address);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TYPE_METANAME:
|
case TYPE_METANAME:
|
||||||
|
@ -24,6 +24,8 @@
|
|||||||
#define JRD_PREPARED_STATEMENT_H
|
#define JRD_PREPARED_STATEMENT_H
|
||||||
|
|
||||||
#include "firebird.h"
|
#include "firebird.h"
|
||||||
|
#include <utility>
|
||||||
|
#include <optional>
|
||||||
#include "../common/dsc.h"
|
#include "../common/dsc.h"
|
||||||
#include "../common/MsgMetadata.h"
|
#include "../common/MsgMetadata.h"
|
||||||
#include "../jrd/intl.h"
|
#include "../jrd/intl.h"
|
||||||
@ -33,7 +35,6 @@
|
|||||||
#include "../common/classes/fb_string.h"
|
#include "../common/classes/fb_string.h"
|
||||||
#include "../common/classes/MetaString.h"
|
#include "../common/classes/MetaString.h"
|
||||||
#include "../jrd/MetaName.h"
|
#include "../jrd/MetaName.h"
|
||||||
#include "../common/classes/Nullable.h"
|
|
||||||
|
|
||||||
namespace Jrd {
|
namespace Jrd {
|
||||||
|
|
||||||
@ -45,6 +46,9 @@ class dsql_msg;
|
|||||||
class ResultSet;
|
class ResultSet;
|
||||||
|
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct PreparedStatementTypeDiscriminator {};
|
||||||
|
|
||||||
class PreparedStatement : public Firebird::PermanentStorage
|
class PreparedStatement : public Firebird::PermanentStorage
|
||||||
{
|
{
|
||||||
friend class ResultSet;
|
friend class ResultSet;
|
||||||
@ -52,7 +56,7 @@ friend class ResultSet;
|
|||||||
public:
|
public:
|
||||||
class Builder
|
class Builder
|
||||||
{
|
{
|
||||||
private:
|
public:
|
||||||
enum Type
|
enum Type
|
||||||
{
|
{
|
||||||
TYPE_SSHORT,
|
TYPE_SSHORT,
|
||||||
@ -83,7 +87,7 @@ public:
|
|||||||
Type type;
|
Type type;
|
||||||
unsigned number;
|
unsigned number;
|
||||||
const void* address;
|
const void* address;
|
||||||
const bool* specifiedAddress;
|
bool isOptional;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct OutputSlot
|
struct OutputSlot
|
||||||
@ -91,7 +95,7 @@ public:
|
|||||||
Type type;
|
Type type;
|
||||||
unsigned number;
|
unsigned number;
|
||||||
void* address;
|
void* address;
|
||||||
bool* specifiedAddress;
|
bool isOptional;
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -103,16 +107,15 @@ public:
|
|||||||
public:
|
public:
|
||||||
// Output variables.
|
// 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);
|
addOutput(PreparedStatementTypeDiscriminator<T>::TYPE, ¶m, true, outputSlots);
|
||||||
outputSlots[outputSlots.getCount() - 1].specifiedAddress = ¶m.specified;
|
return OutputParam(chunk, outputSlots.getCount() - 1);
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> OutputParam operator ()(const char* chunk, T& param)
|
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);
|
return OutputParam(chunk, outputSlots.getCount() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,16 +137,16 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> Builder& operator <<(const Nullable<T>& param)
|
template <typename T> Builder& operator <<(const std::optional<T>& param)
|
||||||
{
|
{
|
||||||
*this << param.value;
|
addInput(PreparedStatementTypeDiscriminator<T>::TYPE, ¶m, true, inputSlots);
|
||||||
inputSlots[inputSlots.getCount() - 1].specifiedAddress = ¶m.specified;
|
text += "?";
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> Builder& operator <<(const T& param)
|
template <typename T> Builder& operator <<(const T& param)
|
||||||
{
|
{
|
||||||
addInput(getType(param), ¶m, inputSlots);
|
addInput(PreparedStatementTypeDiscriminator<T>::TYPE, ¶m, false, inputSlots);
|
||||||
text += "?";
|
text += "?";
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@ -158,32 +161,23 @@ public:
|
|||||||
void moveToStatement(thread_db* tdbb, PreparedStatement* stmt) const;
|
void moveToStatement(thread_db* tdbb, PreparedStatement* stmt) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Make the C++ template engine return the constant for each type.
|
void addInput(Type type, const void* address, bool isOptional, Firebird::Array<InputSlot>& slots)
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
InputSlot slot;
|
InputSlot slot;
|
||||||
slot.type = type;
|
slot.type = type;
|
||||||
slot.number = (unsigned) slots.getCount() + 1;
|
slot.number = (unsigned) slots.getCount() + 1;
|
||||||
slot.address = address;
|
slot.address = address;
|
||||||
slot.specifiedAddress = NULL;
|
slot.isOptional = isOptional;
|
||||||
slots.add(slot);
|
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;
|
OutputSlot slot;
|
||||||
slot.type = type;
|
slot.type = type;
|
||||||
slot.number = (unsigned) slots.getCount() + 1;
|
slot.number = (unsigned) slots.getCount() + 1;
|
||||||
slot.address = address;
|
slot.address = address;
|
||||||
slot.specifiedAddress = NULL;
|
slot.isOptional = isOptional;
|
||||||
slots.add(slot);
|
slots.add(slot);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -324,7 +318,7 @@ public:
|
|||||||
setDesc(tdbb, param, desc);
|
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);
|
fb_assert(param > 0);
|
||||||
|
|
||||||
@ -378,6 +372,50 @@ private:
|
|||||||
|
|
||||||
typedef Firebird::AutoPtr<PreparedStatement> AutoPreparedStatement;
|
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
|
} // namespace
|
||||||
|
|
||||||
|
@ -335,8 +335,8 @@ void ProfilerPackage::startSessionFunction(ThrowStatusExceptionWrapper* /*status
|
|||||||
}
|
}
|
||||||
|
|
||||||
const string description(in->description.str, in->descriptionNull ? 0 : in->description.length);
|
const string description(in->description.str, in->descriptionNull ? 0 : in->description.length);
|
||||||
const Nullable<SLONG> flushInterval(in->flushIntervalNull ?
|
const std::optional<SLONG> flushInterval(in->flushIntervalNull ?
|
||||||
Nullable<SLONG>() : Nullable<SLONG>(in->flushInterval));
|
std::nullopt : std::optional{in->flushInterval});
|
||||||
const PathName pluginName(in->pluginName.str, in->pluginNameNull ? 0 : in->pluginName.length);
|
const PathName pluginName(in->pluginName.str, in->pluginNameNull ? 0 : in->pluginName.length);
|
||||||
const string pluginOptions(in->pluginOptions.str, in->pluginOptionsNull ? 0 : in->pluginOptions.length);
|
const string pluginOptions(in->pluginOptions.str, in->pluginOptionsNull ? 0 : in->pluginOptions.length);
|
||||||
|
|
||||||
@ -398,11 +398,11 @@ int ProfilerManager::blockingAst(void* astObject)
|
|||||||
return 0;
|
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)
|
const PathName& pluginName, const string& description, const string& options)
|
||||||
{
|
{
|
||||||
if (flushInterval.isAssigned())
|
if (flushInterval.has_value())
|
||||||
checkFlushInterval(flushInterval.value);
|
checkFlushInterval(flushInterval.value());
|
||||||
|
|
||||||
AutoSetRestore<bool> pauseProfiler(&paused, true);
|
AutoSetRestore<bool> pauseProfiler(&paused, true);
|
||||||
|
|
||||||
@ -460,8 +460,8 @@ SINT64 ProfilerManager::startSession(thread_db* tdbb, Nullable<SLONG> flushInter
|
|||||||
|
|
||||||
paused = false;
|
paused = false;
|
||||||
|
|
||||||
if (flushInterval.isAssigned())
|
if (flushInterval.has_value())
|
||||||
setFlushInterval(flushInterval.value);
|
setFlushInterval(flushInterval.value());
|
||||||
|
|
||||||
return currentSession->pluginSession->getId();
|
return currentSession->pluginSession->getId();
|
||||||
}
|
}
|
||||||
@ -1038,8 +1038,8 @@ void ProfilerListener::processCommand(thread_db* tdbb)
|
|||||||
|
|
||||||
const string description(in->description.str,
|
const string description(in->description.str,
|
||||||
in->descriptionNull ? 0 : in->description.length);
|
in->descriptionNull ? 0 : in->description.length);
|
||||||
const Nullable<SLONG> flushInterval(in->flushIntervalNull ?
|
const std::optional<SLONG> flushInterval(in->flushIntervalNull ?
|
||||||
Nullable<SLONG>() : Nullable<SLONG>(in->flushInterval));
|
std::nullopt : std::optional{in->flushInterval});
|
||||||
const PathName pluginName(in->pluginName.str,
|
const PathName pluginName(in->pluginName.str,
|
||||||
in->pluginNameNull ? 0 : in->pluginName.length);
|
in->pluginNameNull ? 0 : in->pluginName.length);
|
||||||
const string pluginOptions(in->pluginOptions.str,
|
const string pluginOptions(in->pluginOptions.str,
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
#include "firebird.h"
|
#include "firebird.h"
|
||||||
#include "firebird/Message.h"
|
#include "firebird/Message.h"
|
||||||
|
#include <optional>
|
||||||
#include "../common/PerformanceStopWatch.h"
|
#include "../common/PerformanceStopWatch.h"
|
||||||
#include "../common/classes/auto.h"
|
#include "../common/classes/auto.h"
|
||||||
#include "../common/classes/fb_string.h"
|
#include "../common/classes/fb_string.h"
|
||||||
@ -187,7 +188,7 @@ public:
|
|||||||
void operator=(const ProfilerManager&) = delete;
|
void operator=(const ProfilerManager&) = delete;
|
||||||
|
|
||||||
public:
|
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);
|
const Firebird::PathName& pluginName, const Firebird::string& description, const Firebird::string& options);
|
||||||
|
|
||||||
void prepareCursor(thread_db* tdbb, Request* request, const Select* select);
|
void prepareCursor(thread_db* tdbb, Request* request, const Select* select);
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#ifndef JRD_RELATION_H
|
#ifndef JRD_RELATION_H
|
||||||
#define JRD_RELATION_H
|
#define JRD_RELATION_H
|
||||||
|
|
||||||
|
#include <optional>
|
||||||
#include "../jrd/jrd.h"
|
#include "../jrd/jrd.h"
|
||||||
#include "../jrd/btr.h"
|
#include "../jrd/btr.h"
|
||||||
#include "../jrd/lck.h"
|
#include "../jrd/lck.h"
|
||||||
@ -490,7 +491,7 @@ public:
|
|||||||
MetaName fld_security_name; // security class name for field
|
MetaName fld_security_name; // security class name for field
|
||||||
MetaName fld_generator_name; // identity generator name
|
MetaName fld_generator_name; // identity generator name
|
||||||
MetaNamePair fld_source_rel_field; // Relation/field source name
|
MetaNamePair fld_source_rel_field; // Relation/field source name
|
||||||
Nullable<IdentityType> fld_identity_type;
|
std::optional<IdentityType> fld_identity_type;
|
||||||
USHORT fld_flags;
|
USHORT fld_flags;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -1039,10 +1039,10 @@ namespace
|
|||||||
dependencies.push(dependency);
|
dependencies.push(dependency);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parameter->prm_text_type.isAssigned())
|
if (parameter->prm_text_type.has_value())
|
||||||
{
|
{
|
||||||
CompilerScratch::Dependency dependency(obj_collation);
|
CompilerScratch::Dependency dependency(obj_collation);
|
||||||
dependency.number = parameter->prm_text_type.value;
|
dependency.number = parameter->prm_text_type.value();
|
||||||
dependencies.push(dependency);
|
dependencies.push(dependency);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
#ifndef JRD_EXE_H
|
#ifndef JRD_EXE_H
|
||||||
#define JRD_EXE_H
|
#define JRD_EXE_H
|
||||||
|
|
||||||
|
#include <optional>
|
||||||
#include "../jrd/blb.h"
|
#include "../jrd/blb.h"
|
||||||
#include "../jrd/Relation.h"
|
#include "../jrd/Relation.h"
|
||||||
#include "../common/classes/array.h"
|
#include "../common/classes/array.h"
|
||||||
@ -610,7 +611,7 @@ public:
|
|||||||
void activate(bool subStream = false);
|
void activate(bool subStream = false);
|
||||||
void deactivate();
|
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_stream; // Map user context to internal stream
|
||||||
StreamType csb_view_stream; // stream number for view relation, below
|
StreamType csb_view_stream; // stream number for view relation, below
|
||||||
USHORT csb_flags;
|
USHORT csb_flags;
|
||||||
|
@ -223,7 +223,8 @@ namespace
|
|||||||
return formatNumber;
|
return formatNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool getCharsetByTextType(SSHORT& charSet, const USHORT subType)
|
template <typename T>
|
||||||
|
bool getCharsetByTextType(T& charSet, const USHORT subType)
|
||||||
{
|
{
|
||||||
switch (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 (DTYPE_IS_TEXT(gfield->gfld_dtype))
|
||||||
{
|
getCharsetByTextType(field->charSetId, gfield->gfld_sub_type);
|
||||||
if (getCharsetByTextType(field->charSetId.value, gfield->gfld_sub_type))
|
|
||||||
field->charSetId.specified = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gfield->gfld_nullable)
|
if (gfield->gfld_nullable)
|
||||||
field->flags |= FLD_nullable;
|
field->flags |= FLD_nullable;
|
||||||
|
@ -291,7 +291,7 @@ public:
|
|||||||
MetaName prm_field_source;
|
MetaName prm_field_source;
|
||||||
MetaName prm_type_of_column;
|
MetaName prm_type_of_column;
|
||||||
MetaName prm_type_of_table;
|
MetaName prm_type_of_table;
|
||||||
Nullable<USHORT> prm_text_type;
|
std::optional<USHORT> prm_text_type;
|
||||||
FUN_T prm_fun_mechanism;
|
FUN_T prm_fun_mechanism;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -4290,7 +4290,7 @@ void MET_scan_relation(thread_db* tdbb, jrd_rel* relation)
|
|||||||
|
|
||||||
case RSR_field_generator_name:
|
case RSR_field_generator_name:
|
||||||
field->fld_generator_name = (const TEXT*) p;
|
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;
|
field->fld_identity_type = IDENT_TYPE_BY_DEFAULT;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
|
|
||||||
#include "firebird.h"
|
#include "firebird.h"
|
||||||
#include "firebird/Message.h"
|
#include "firebird/Message.h"
|
||||||
|
#include <optional>
|
||||||
#include "../common/Int128.h"
|
#include "../common/Int128.h"
|
||||||
#include "../common/classes/ImplementHelper.h"
|
#include "../common/classes/ImplementHelper.h"
|
||||||
#include "../common/classes/auto.h"
|
#include "../common/classes/auto.h"
|
||||||
@ -29,7 +30,6 @@
|
|||||||
#include "../common/classes/fb_string.h"
|
#include "../common/classes/fb_string.h"
|
||||||
#include "../common/classes/GenericMap.h"
|
#include "../common/classes/GenericMap.h"
|
||||||
#include "../common/classes/MetaString.h"
|
#include "../common/classes/MetaString.h"
|
||||||
#include "../common/classes/Nullable.h"
|
|
||||||
#include "../common/classes/objects_array.h"
|
#include "../common/classes/objects_array.h"
|
||||||
#include "../common/classes/stack.h"
|
#include "../common/classes/stack.h"
|
||||||
#include "../common/status.h"
|
#include "../common/status.h"
|
||||||
@ -105,7 +105,7 @@ struct Cursor
|
|||||||
|
|
||||||
struct RecordSource
|
struct RecordSource
|
||||||
{
|
{
|
||||||
Nullable<ULONG> parentId;
|
std::optional<ULONG> parentId;
|
||||||
unsigned level;
|
unsigned level;
|
||||||
string accessPath{defaultPool()};
|
string accessPath{defaultPool()};
|
||||||
};
|
};
|
||||||
@ -137,8 +137,8 @@ struct Request
|
|||||||
SINT64 callerStatementId = 0;
|
SINT64 callerStatementId = 0;
|
||||||
SINT64 callerRequestId = 0;
|
SINT64 callerRequestId = 0;
|
||||||
ISC_TIMESTAMP_TZ startTimestamp;
|
ISC_TIMESTAMP_TZ startTimestamp;
|
||||||
Nullable<ISC_TIMESTAMP_TZ> finishTimestamp;
|
std::optional<ISC_TIMESTAMP_TZ> finishTimestamp;
|
||||||
Nullable<FB_UINT64> totalElapsedTicks;
|
std::optional<FB_UINT64> totalElapsedTicks;
|
||||||
NonPooledMap<CursorRecSourceKey, RecordSourceStats> recordSourcesStats{defaultPool()};
|
NonPooledMap<CursorRecSourceKey, RecordSourceStats> recordSourcesStats{defaultPool()};
|
||||||
NonPooledMap<LineColumnKey, Stats> psqlStats{defaultPool()};
|
NonPooledMap<LineColumnKey, Stats> psqlStats{defaultPool()};
|
||||||
};
|
};
|
||||||
@ -226,7 +226,7 @@ public:
|
|||||||
NonPooledMap<SINT64, Request> requests{defaultPool()};
|
NonPooledMap<SINT64, Request> requests{defaultPool()};
|
||||||
SINT64 id;
|
SINT64 id;
|
||||||
ISC_TIMESTAMP_TZ startTimestamp;
|
ISC_TIMESTAMP_TZ startTimestamp;
|
||||||
Nullable<ISC_TIMESTAMP_TZ> finishTimestamp;
|
std::optional<ISC_TIMESTAMP_TZ> finishTimestamp;
|
||||||
string description{defaultPool()};
|
string description{defaultPool()};
|
||||||
bool detailedRequests = false;
|
bool detailedRequests = false;
|
||||||
bool dirty = true;
|
bool dirty = true;
|
||||||
@ -649,8 +649,9 @@ void ProfilerPlugin::flush(ThrowStatusExceptionWrapper* status)
|
|||||||
sessionMessage->startTimestampNull = FB_FALSE;
|
sessionMessage->startTimestampNull = FB_FALSE;
|
||||||
sessionMessage->startTimestamp = session->startTimestamp;
|
sessionMessage->startTimestamp = session->startTimestamp;
|
||||||
|
|
||||||
sessionMessage->finishTimestampNull = session->finishTimestamp.isUnknown();
|
sessionMessage->finishTimestampNull = !session->finishTimestamp.has_value();
|
||||||
sessionMessage->finishTimestamp = session->finishTimestamp.value;
|
if (session->finishTimestamp.has_value())
|
||||||
|
sessionMessage->finishTimestamp = session->finishTimestamp.value();
|
||||||
|
|
||||||
sessionStmt->execute(status, transaction, sessionMessage.getMetadata(),
|
sessionStmt->execute(status, transaction, sessionMessage.getMetadata(),
|
||||||
sessionMessage.getData(), nullptr, nullptr);
|
sessionMessage.getData(), nullptr, nullptr);
|
||||||
@ -772,8 +773,8 @@ void ProfilerPlugin::flush(ThrowStatusExceptionWrapper* status)
|
|||||||
recSrcMessage->recordSourceIdNull = FB_FALSE;
|
recSrcMessage->recordSourceIdNull = FB_FALSE;
|
||||||
recSrcMessage->recordSourceId = recSourceId;
|
recSrcMessage->recordSourceId = recSourceId;
|
||||||
|
|
||||||
recSrcMessage->parentRecordSourceIdNull = !recSrc.parentId.specified;
|
recSrcMessage->parentRecordSourceIdNull = !recSrc.parentId.has_value();
|
||||||
recSrcMessage->parentRecordSourceId = recSrc.parentId.value;
|
recSrcMessage->parentRecordSourceId = recSrc.parentId.value_or(0);
|
||||||
|
|
||||||
recSrcMessage->levelNull = FB_FALSE;
|
recSrcMessage->levelNull = FB_FALSE;
|
||||||
recSrcMessage->level = recSrc.level;
|
recSrcMessage->level = recSrc.level;
|
||||||
@ -839,15 +840,16 @@ void ProfilerPlugin::flush(ThrowStatusExceptionWrapper* status)
|
|||||||
requestMessage->startTimestampNull = FB_FALSE;
|
requestMessage->startTimestampNull = FB_FALSE;
|
||||||
requestMessage->startTimestamp = profileRequest.startTimestamp;
|
requestMessage->startTimestamp = profileRequest.startTimestamp;
|
||||||
|
|
||||||
requestMessage->finishTimestampNull = profileRequest.finishTimestamp.isUnknown();
|
requestMessage->finishTimestampNull = !profileRequest.finishTimestamp.has_value();
|
||||||
requestMessage->finishTimestamp = profileRequest.finishTimestamp.value;
|
if (profileRequest.finishTimestamp.has_value())
|
||||||
|
requestMessage->finishTimestamp = profileRequest.finishTimestamp.value();
|
||||||
|
|
||||||
requestMessage->totalElapsedTimeNull = profileRequest.totalElapsedTicks.isUnknown();
|
requestMessage->totalElapsedTimeNull = !profileRequest.totalElapsedTicks.has_value();
|
||||||
requestMessage->totalElapsedTime = ticksToNanoseconds(profileRequest.totalElapsedTicks.value);
|
requestMessage->totalElapsedTime = ticksToNanoseconds(profileRequest.totalElapsedTicks.value_or(0));
|
||||||
|
|
||||||
addBatch(requestBatch, requestBatchSize, requestMessage);
|
addBatch(requestBatch, requestBatchSize, requestMessage);
|
||||||
|
|
||||||
if (profileRequest.finishTimestamp.isAssigned())
|
if (profileRequest.finishTimestamp.has_value())
|
||||||
finishedRequests.add(requestIt->first);
|
finishedRequests.add(requestIt->first);
|
||||||
|
|
||||||
profileRequest.dirty = false;
|
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->statements.clear();
|
||||||
session->recordSources.clear();
|
session->recordSources.clear();
|
||||||
|
Loading…
Reference in New Issue
Block a user