mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-22 20:43:02 +01:00
First edition of SET BIND statement
This commit is contained in:
parent
8086e06ee1
commit
e8787500d7
@ -31,10 +31,14 @@
|
||||
|
||||
using namespace Firebird;
|
||||
|
||||
ParsedList::ParsedList(PathName list)
|
||||
ParsedList::ParsedList(const PathName& list)
|
||||
{
|
||||
parse(list, " \t,;");
|
||||
}
|
||||
|
||||
void ParsedList::parse(PathName list, const char* sep)
|
||||
{
|
||||
list.alltrim(" \t");
|
||||
const char* sep = " \t,;";
|
||||
|
||||
for (;;)
|
||||
{
|
||||
@ -54,6 +58,11 @@ ParsedList::ParsedList(PathName list)
|
||||
}
|
||||
}
|
||||
|
||||
ParsedList::ParsedList(const PathName& list, const char* delimiters)
|
||||
{
|
||||
parse(list, delimiters);
|
||||
}
|
||||
|
||||
void ParsedList::makeList(PathName& list) const
|
||||
{
|
||||
fb_assert(this->hasData());
|
||||
|
@ -37,7 +37,7 @@ namespace Firebird {
|
||||
class ParsedList : public Firebird::ObjectsArray<Firebird::PathName>
|
||||
{
|
||||
public:
|
||||
explicit ParsedList(Firebird::PathName list);
|
||||
explicit ParsedList(const Firebird::PathName& list);
|
||||
|
||||
ParsedList()
|
||||
{ }
|
||||
@ -46,6 +46,8 @@ public:
|
||||
: Firebird::ObjectsArray<Firebird::PathName>(p)
|
||||
{ }
|
||||
|
||||
ParsedList(const Firebird::PathName& list, const char* delimiters);
|
||||
|
||||
// create plane list from this parsed
|
||||
void makeList(Firebird::PathName& list) const;
|
||||
|
||||
@ -55,6 +57,9 @@ public:
|
||||
|
||||
// get providers list for particular database amd remove "Loopback" provider from it
|
||||
static Firebird::PathName getNonLoopbackProviders(const Firebird::PathName& aliasDb);
|
||||
|
||||
private:
|
||||
void parse(Firebird::PathName list, const char* delimiters);
|
||||
};
|
||||
|
||||
} // namespace Firebird
|
||||
|
@ -246,6 +246,12 @@ public:
|
||||
return count++;
|
||||
}
|
||||
|
||||
T& add()
|
||||
{
|
||||
ensureCapacity(count + 1);
|
||||
return *new(&data[count++]) T(); // initialize new empty data member
|
||||
}
|
||||
|
||||
void add(const T* items, const size_type itemsCount)
|
||||
{
|
||||
fb_assert(count <= FB_MAX_SIZEOF - itemsCount);
|
||||
|
@ -229,7 +229,8 @@ const Config::ConfigEntry Config::entries[MAX_CONFIG_KEY] =
|
||||
{TYPE_INTEGER, "SnapshotsMemSize", (ConfigValue) 65536}, // bytes
|
||||
{TYPE_INTEGER, "TipCacheBlockSize", (ConfigValue) 4194304}, // bytes
|
||||
{TYPE_BOOLEAN, "ReadConsistency", (ConfigValue) true},
|
||||
{TYPE_BOOLEAN, "ClearGTTAtRetaining", (ConfigValue) false}
|
||||
{TYPE_BOOLEAN, "ClearGTTAtRetaining", (ConfigValue) false},
|
||||
{TYPE_STRING, "SetBind", (ConfigValue) NULL}
|
||||
};
|
||||
|
||||
/******************************************************************************
|
||||
@ -930,3 +931,8 @@ bool Config::getClearGTTAtRetaining() const
|
||||
{
|
||||
return get<bool>(KEY_CLEAR_GTT_RETAINING);
|
||||
}
|
||||
|
||||
const char* Config::getBind() const
|
||||
{
|
||||
return get<const char*>(KEY_SET_BIND);
|
||||
}
|
||||
|
@ -155,6 +155,7 @@ public:
|
||||
KEY_TIP_CACHE_BLOCK_SIZE,
|
||||
KEY_READ_CONSISTENCY,
|
||||
KEY_CLEAR_GTT_RETAINING,
|
||||
KEY_SET_BIND,
|
||||
MAX_CONFIG_KEY // keep it last
|
||||
};
|
||||
|
||||
@ -390,6 +391,8 @@ public:
|
||||
bool getReadConsistency() const;
|
||||
|
||||
bool getClearGTTAtRetaining() const;
|
||||
|
||||
const char* getBind() const;
|
||||
};
|
||||
|
||||
// Implementation of interface to access master configuration file
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "../jrd/align.h"
|
||||
#include "firebird/impl/blr.h"
|
||||
#include "../jrd/tra.h"
|
||||
#include "../jrd/Coercion.h"
|
||||
#include "../jrd/Function.h"
|
||||
#include "../jrd/Optimizer.h"
|
||||
#include "../jrd/RecordSourceNodes.h"
|
||||
@ -8360,14 +8361,39 @@ void SetDecFloatTrapsNode::execute(thread_db* tdbb, dsql_req* /*request*/, jrd_t
|
||||
//--------------------
|
||||
|
||||
|
||||
void SetHighPrecBindNode::execute(thread_db* tdbb, dsql_req* /*request*/, jrd_tra** /*traHandle*/) const
|
||||
void CoercionRule::setRule(TypeClause* from, TypeClause *to)
|
||||
{
|
||||
static const USHORT FROM_MASK = FLD_has_len | FLD_has_chset | FLD_has_scale;
|
||||
static const USHORT TO_MASK = FLD_has_len | FLD_has_chset | FLD_has_scale | FLD_legacy;
|
||||
|
||||
fromMask = from->flags & FROM_MASK;
|
||||
DsqlDescMaker::fromField(&fromDsc, from);
|
||||
|
||||
toMask = to->flags & TO_MASK;
|
||||
DsqlDescMaker::fromField(&toDsc, to);
|
||||
}
|
||||
|
||||
|
||||
SessionManagementNode* SetBindNode::dsqlPass(DsqlCompilerScratch* dsqlScratch)
|
||||
{
|
||||
from->resolve(dsqlScratch);
|
||||
if (!(to->flags & FLD_legacy))
|
||||
to->resolve(dsqlScratch);
|
||||
|
||||
return SessionManagementNode::dsqlPass(dsqlScratch);
|
||||
}
|
||||
|
||||
|
||||
void SetBindNode::execute(thread_db* tdbb, dsql_req* /*request*/, jrd_tra** /*traHandle*/) const
|
||||
{
|
||||
SET_TDBB(tdbb);
|
||||
|
||||
fb_assert(from);
|
||||
fb_assert(to);
|
||||
|
||||
Attachment* const attachment = tdbb->getAttachment();
|
||||
if (bindInt128)
|
||||
attachment->att_i128_binding = bind;
|
||||
else
|
||||
attachment->att_dec_binding = bind;
|
||||
CoercionRule& coercion = attachment->att_dest_bind->add();
|
||||
coercion.setRule(from, to);
|
||||
}
|
||||
|
||||
|
||||
@ -8456,17 +8482,6 @@ void SetTimeZoneNode::execute(thread_db* tdbb, dsql_req* request, jrd_tra** /*tr
|
||||
//--------------------
|
||||
|
||||
|
||||
void SetTimeZoneBindNode::execute(thread_db* tdbb, dsql_req* /*request*/, jrd_tra** /*traHandle*/) const
|
||||
{
|
||||
SET_TDBB(tdbb);
|
||||
Attachment* const attachment = tdbb->getAttachment();
|
||||
attachment->att_timezone_bind = bind;
|
||||
}
|
||||
|
||||
|
||||
//--------------------
|
||||
|
||||
|
||||
StmtNode* UpdateOrInsertNode::dsqlPass(DsqlCompilerScratch* dsqlScratch)
|
||||
{
|
||||
thread_db* tdbb = JRD_get_thread_data(); // necessary?
|
||||
|
@ -1749,13 +1749,13 @@ public:
|
||||
};
|
||||
|
||||
|
||||
class SetHighPrecBindNode : public SessionManagementNode
|
||||
class SetBindNode : public SessionManagementNode
|
||||
{
|
||||
public:
|
||||
SetHighPrecBindNode(MemoryPool& pool, bool isInt128)
|
||||
SetBindNode(MemoryPool& pool)
|
||||
: SessionManagementNode(pool),
|
||||
bind(Firebird::NumericBinding::NUM_NATIVE),
|
||||
bindInt128(isInt128)
|
||||
from(nullptr),
|
||||
to(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
@ -1764,17 +1764,18 @@ public:
|
||||
{
|
||||
SessionManagementNode::internalPrint(printer);
|
||||
|
||||
NODE_PRINT(printer, bind.bind);
|
||||
NODE_PRINT(printer, bind.numScale);
|
||||
NODE_PRINT(printer, from);
|
||||
NODE_PRINT(printer, to);
|
||||
|
||||
return "SetHighPrecBindNode";
|
||||
return "SetBindNode";
|
||||
}
|
||||
|
||||
virtual SessionManagementNode* dsqlPass(DsqlCompilerScratch* dsqlScratch);
|
||||
virtual void execute(thread_db* tdbb, dsql_req* request, jrd_tra** traHandle) const;
|
||||
|
||||
public:
|
||||
Firebird::NumericBinding bind;
|
||||
bool bindInt128;
|
||||
dsql_fld *from;
|
||||
dsql_fld *to;
|
||||
};
|
||||
|
||||
|
||||
@ -1814,32 +1815,6 @@ public:
|
||||
};
|
||||
|
||||
|
||||
class SetTimeZoneBindNode : public SessionManagementNode
|
||||
{
|
||||
public:
|
||||
SetTimeZoneBindNode(MemoryPool& pool, Firebird::TimeZoneUtil::Bind aBind)
|
||||
: SessionManagementNode(pool),
|
||||
bind(aBind)
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
virtual Firebird::string internalPrint(NodePrinter& printer) const
|
||||
{
|
||||
SessionManagementNode::internalPrint(printer);
|
||||
|
||||
NODE_PRINT(printer, bind);
|
||||
|
||||
return "SetTimeZoneBindNode";
|
||||
}
|
||||
|
||||
virtual void execute(thread_db* tdbb, dsql_req* request, jrd_tra** traHandle) const;
|
||||
|
||||
public:
|
||||
Firebird::TimeZoneUtil::Bind bind;
|
||||
};
|
||||
|
||||
|
||||
class UpdateOrInsertNode : public TypedNode<DsqlOnlyStmtNode, StmtNode::TYPE_UPDATE_OR_INSERT>
|
||||
{
|
||||
public:
|
||||
|
@ -325,7 +325,11 @@ enum fld_flags_vals {
|
||||
FLD_computed = 1,
|
||||
FLD_national = 2, // field uses NATIONAL character set
|
||||
FLD_nullable = 4,
|
||||
FLD_system = 8
|
||||
FLD_system = 8,
|
||||
FLD_has_len = 16,
|
||||
FLD_has_chset = 32,
|
||||
FLD_has_scale = 64,
|
||||
FLD_legacy = 128
|
||||
};
|
||||
|
||||
//! Stored Procedure block
|
||||
|
@ -203,48 +203,6 @@ void GEN_port(DsqlCompilerScratch* dsqlScratch, dsql_msg* message)
|
||||
if (fromCharSet != toCharSet)
|
||||
parameter->par_desc.setTextType(toCharSet);
|
||||
}
|
||||
else if (parameter->par_desc.isDecFloat() ||
|
||||
parameter->par_desc.dsc_dtype == dtype_int128)
|
||||
{
|
||||
const NumericBinding& b(parameter->par_desc.dsc_dtype == dtype_int128 ?
|
||||
tdbb->getAttachment()->att_i128_binding : tdbb->getAttachment()->att_dec_binding);
|
||||
switch (b.bind)
|
||||
{
|
||||
case NumericBinding::NUM_NATIVE:
|
||||
break;
|
||||
case NumericBinding::NUM_TEXT:
|
||||
parameter->par_desc.makeText((parameter->par_desc.dsc_dtype == dtype_dec64 ?
|
||||
IDecFloat16::STRING_SIZE : parameter->par_desc.dsc_dtype == dtype_dec128 ?
|
||||
IDecFloat34::STRING_SIZE : IInt128::STRING_SIZE) - 1, ttype_ascii);
|
||||
break;
|
||||
case NumericBinding::NUM_DOUBLE:
|
||||
parameter->par_desc.makeDouble();
|
||||
break;
|
||||
case NumericBinding::NUM_INT64:
|
||||
parameter->par_desc.makeInt64(b.numScale);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (parameter->par_desc.isDateTimeTz())
|
||||
{
|
||||
switch (tdbb->getAttachment()->att_timezone_bind)
|
||||
{
|
||||
case TimeZoneUtil::BIND_LEGACY:
|
||||
if (parameter->par_desc.isTime())
|
||||
parameter->par_desc.makeTime();
|
||||
else if (parameter->par_desc.isTimeStamp())
|
||||
parameter->par_desc.makeTimestamp();
|
||||
else
|
||||
fb_assert(false);
|
||||
break;
|
||||
|
||||
case TimeZoneUtil::BIND_NATIVE:
|
||||
break;
|
||||
|
||||
default:
|
||||
fb_assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
if (parameter->par_desc.dsc_dtype == dtype_text && parameter->par_index != 0)
|
||||
{
|
||||
@ -257,6 +215,14 @@ void GEN_port(DsqlCompilerScratch* dsqlScratch, dsql_msg* message)
|
||||
¶meter->par_desc, parameter->par_desc.dsc_length) + sizeof(USHORT);
|
||||
}
|
||||
|
||||
if (!(dsqlScratch->flags & DsqlCompilerScratch::FLAG_INTERNAL_REQUEST))
|
||||
{
|
||||
Attachment* att = tdbb->getAttachment();
|
||||
if (!att->att_bindings.coerce(¶meter->par_desc))
|
||||
if (!att->getInitialBindings()->coerce(¶meter->par_desc))
|
||||
tdbb->getDatabase()->getBindings()->coerce(¶meter->par_desc);
|
||||
}
|
||||
|
||||
const USHORT align = type_alignments[parameter->par_desc.dsc_dtype];
|
||||
if (align)
|
||||
offset = FB_ALIGN(offset, align);
|
||||
|
@ -65,14 +65,14 @@ using namespace Firebird;
|
||||
|
||||
// DsqlDescMaker methods
|
||||
|
||||
void DsqlDescMaker::fromElement(dsc* desc, const dsql_fld* field)
|
||||
void DsqlDescMaker::fromElement(dsc* desc, const TypeClause* field)
|
||||
{
|
||||
composeDesc(desc,
|
||||
field->elementDtype, field->scale, field->subType, field->elementLength,
|
||||
field->charSetId.value, field->collationId, field->flags & FLD_nullable);
|
||||
}
|
||||
|
||||
void DsqlDescMaker::fromField(dsc* desc, const dsql_fld* field)
|
||||
void DsqlDescMaker::fromField(dsc* desc, const TypeClause* field)
|
||||
{
|
||||
composeDesc(desc,
|
||||
field->dtype, field->scale, field->subType, field->length,
|
||||
|
@ -31,6 +31,7 @@
|
||||
namespace Jrd {
|
||||
class dsql_ctx;
|
||||
class dsql_fld;
|
||||
class TypeClause;
|
||||
class dsql_msg;
|
||||
class dsql_par;
|
||||
class dsql_req;
|
||||
@ -57,8 +58,8 @@ namespace Jrd {
|
||||
class DsqlDescMaker
|
||||
{
|
||||
public:
|
||||
static void fromElement(dsc*, const dsql_fld*);
|
||||
static void fromField(dsc*, const dsql_fld*);
|
||||
static void fromElement(dsc*, const TypeClause*);
|
||||
static void fromField(dsc*, const TypeClause*);
|
||||
static void fromList(DsqlCompilerScratch*, dsc*,
|
||||
ValueListNode*, const char*, bool = false);
|
||||
static void fromNode(DsqlCompilerScratch*, dsc*,
|
||||
|
@ -817,7 +817,7 @@ using namespace Firebird;
|
||||
Jrd::CreateAlterRoleNode* createAlterRoleNode;
|
||||
Jrd::SetDecFloatRoundNode* setDecFloatRoundNode;
|
||||
Jrd::SetDecFloatTrapsNode* setDecFloatTrapsNode;
|
||||
Jrd::SetHighPrecBindNode* setHighPrecBindNode;
|
||||
Jrd::SetBindNode* setBindNode;
|
||||
Jrd::SessionResetNode* sessionResetNode;
|
||||
}
|
||||
|
||||
@ -878,12 +878,11 @@ tra_statement
|
||||
mng_statement
|
||||
: set_decfloat_round { $$ = $1; }
|
||||
| set_decfloat_traps { $$ = $1; }
|
||||
| set_decfloat_bind { $$ = $1; }
|
||||
| session_statement { $$ = $1; }
|
||||
| set_role { $$ = $1; }
|
||||
| session_reset { $$ = $1; }
|
||||
| set_time_zone { $$ = $1; }
|
||||
| set_time_zone_bind { $$ = $1; }
|
||||
| set_bind { $$ = $1; }
|
||||
;
|
||||
|
||||
|
||||
@ -4616,7 +4615,10 @@ simple_type
|
||||
{
|
||||
$$ = $1;
|
||||
if ($2)
|
||||
{
|
||||
$$->charSet = *$2;
|
||||
$$->flags |= FLD_has_chset;
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
@ -4822,7 +4824,7 @@ national_character_type
|
||||
$$ = newNode<dsql_fld>();
|
||||
$$->dtype = dtype_text;
|
||||
$$->charLength = (USHORT) $3;
|
||||
$$->flags |= FLD_national;
|
||||
$$->flags |= (FLD_national | FLD_has_len);
|
||||
}
|
||||
| national_character_keyword
|
||||
{
|
||||
@ -4836,7 +4838,7 @@ national_character_type
|
||||
$$ = newNode<dsql_fld>();
|
||||
$$->dtype = dtype_varying;
|
||||
$$->charLength = (USHORT) $4;
|
||||
$$->flags |= FLD_national;
|
||||
$$->flags |= (FLD_national | FLD_has_len);
|
||||
}
|
||||
;
|
||||
|
||||
@ -4851,6 +4853,7 @@ binary_character_type
|
||||
$$->textType = ttype_binary;
|
||||
$$->charSetId = CS_BINARY;
|
||||
$$->subType = fb_text_subtype_binary;
|
||||
$$->flags |= (FLD_has_len | FLD_has_chset);
|
||||
}
|
||||
| binary_character_keyword
|
||||
{
|
||||
@ -4861,6 +4864,7 @@ binary_character_type
|
||||
$$->textType = ttype_binary;
|
||||
$$->charSetId = CS_BINARY;
|
||||
$$->subType = fb_text_subtype_binary;
|
||||
$$->flags |= FLD_has_chset;
|
||||
}
|
||||
| varbinary_character_keyword '(' pos_short_integer ')'
|
||||
{
|
||||
@ -4871,6 +4875,7 @@ binary_character_type
|
||||
$$->textType = ttype_binary;
|
||||
$$->charSetId = CS_BINARY;
|
||||
$$->subType = fb_text_subtype_binary;
|
||||
$$->flags |= (FLD_has_len | FLD_has_chset);
|
||||
}
|
||||
;
|
||||
|
||||
@ -4881,6 +4886,7 @@ character_type
|
||||
$$ = newNode<dsql_fld>();
|
||||
$$->dtype = dtype_text;
|
||||
$$->charLength = (USHORT) $3;
|
||||
$$->flags |= FLD_has_len;
|
||||
}
|
||||
| character_keyword
|
||||
{
|
||||
@ -4893,6 +4899,7 @@ character_type
|
||||
$$ = newNode<dsql_fld>();
|
||||
$$->dtype = dtype_varying;
|
||||
$$->charLength = (USHORT) $3;
|
||||
$$->flags |= FLD_has_len;
|
||||
}
|
||||
;
|
||||
|
||||
@ -4934,6 +4941,8 @@ decfloat_type
|
||||
yyabandon(YYPOSNARG(2), -842, isc_decprecision_err); // DecFloat precision must be 16 or 34.
|
||||
|
||||
$$ = newNode<dsql_fld>();
|
||||
if (precision)
|
||||
$$->flags |= FLD_has_scale;
|
||||
$$->precision = precision == 0 ? 34 : (USHORT) precision;
|
||||
$$->dtype = precision == 16 ? dtype_dec64 : dtype_dec128;
|
||||
$$->length = precision == 16 ? sizeof(Decimal64) : sizeof(Decimal128);
|
||||
@ -4972,6 +4981,7 @@ prec_scale
|
||||
| '(' signed_long_integer ')'
|
||||
{
|
||||
$$ = newNode<dsql_fld>();
|
||||
$$->flags |= FLD_has_len;
|
||||
|
||||
if ($2 < 1 || $2 > 38)
|
||||
yyabandon(YYPOSNARG(2), -842, Arg::Gds(isc_precision_err2) << Arg::Num(1) << Arg::Num(38));
|
||||
@ -5028,6 +5038,7 @@ prec_scale
|
||||
| '(' signed_long_integer ',' signed_long_integer ')'
|
||||
{
|
||||
$$ = newNode<dsql_fld>();
|
||||
$$->flags |= (FLD_has_len | FLD_has_scale);
|
||||
|
||||
if ($2 < 1 || $2 > 38)
|
||||
yyabandon(YYPOSNARG(2), -842, Arg::Gds(isc_precision_err2) << Arg::Num(1) << Arg::Num(38));
|
||||
@ -5272,18 +5283,30 @@ set_decfloat_traps
|
||||
{ $$ = $5; }
|
||||
;
|
||||
|
||||
%type <setHighPrecBindNode> set_decfloat_bind
|
||||
set_decfloat_bind
|
||||
: SET bind_to_type BIND
|
||||
{ $$ = newNode<SetHighPrecBindNode>($2); }
|
||||
decfloat_bind_clause($4)
|
||||
{ $$ = $4; }
|
||||
%type <setBindNode> set_bind
|
||||
set_bind
|
||||
: SET BIND OF set_bind_from
|
||||
{ $$ = newNode<SetBindNode>(); $$->from = $4; }
|
||||
TO set_bind_to
|
||||
{ $$ = $5; $$->to = $7; }
|
||||
;
|
||||
|
||||
%type <boolVal> bind_to_type
|
||||
bind_to_type
|
||||
: DECFLOAT { $$ = false; }
|
||||
| INT128 { $$ = true; }
|
||||
%type <legacyField> set_bind_from
|
||||
set_bind_from
|
||||
: simple_type
|
||||
;
|
||||
|
||||
%type <legacyField> set_bind_to
|
||||
set_bind_to
|
||||
: simple_type
|
||||
{
|
||||
$$ = $1;
|
||||
}
|
||||
| LEGACY
|
||||
{
|
||||
$$ = newNode<dsql_fld>();
|
||||
$$->flags = FLD_legacy;
|
||||
}
|
||||
;
|
||||
|
||||
%type decfloat_traps_list_opt(<setDecFloatTrapsNode>)
|
||||
@ -5304,28 +5327,6 @@ decfloat_trap($setDecFloatTrapsNode)
|
||||
{ $setDecFloatTrapsNode->trap($1); }
|
||||
;
|
||||
|
||||
%type decfloat_bind_clause(<setHighPrecBindNode>)
|
||||
decfloat_bind_clause($setHighPrecBindNode)
|
||||
: NATIVE
|
||||
// do nothing
|
||||
| character_keyword
|
||||
{ $setHighPrecBindNode->bind.bind = NumericBinding::NUM_TEXT; }
|
||||
| DOUBLE PRECISION
|
||||
{ $setHighPrecBindNode->bind.bind = NumericBinding::NUM_DOUBLE; }
|
||||
| BIGINT decfloat_scale_clause($setHighPrecBindNode)
|
||||
{ $setHighPrecBindNode->bind.bind = NumericBinding::NUM_INT64; }
|
||||
;
|
||||
|
||||
%type decfloat_scale_clause(<setHighPrecBindNode>)
|
||||
decfloat_scale_clause($setHighPrecBindNode)
|
||||
: // nothing
|
||||
| ',' signed_long_integer
|
||||
{
|
||||
if ($2 > NumericBinding::MAX_SCALE || $2 < 0)
|
||||
yyabandon(YYPOSNARG(2), -842, isc_scale_nogt); // Scale must be between 0 and precision
|
||||
$setHighPrecBindNode->bind.numScale = -$2;
|
||||
}
|
||||
|
||||
%type <setSessionNode> session_statement
|
||||
session_statement
|
||||
: SET SESSION IDLE TIMEOUT long_integer timepart_sesion_idle_tout
|
||||
@ -5362,17 +5363,6 @@ set_time_zone_option
|
||||
| LOCAL { $$ = newNode<SetTimeZoneNode>(); }
|
||||
;
|
||||
|
||||
%type <mngNode> set_time_zone_bind
|
||||
set_time_zone_bind
|
||||
: SET TIME ZONE BIND set_time_zone_bind_option { $$ = $5; }
|
||||
;
|
||||
|
||||
%type <mngNode> set_time_zone_bind_option
|
||||
set_time_zone_bind_option
|
||||
: LEGACY { $$ = newNode<SetTimeZoneBindNode>(TimeZoneUtil::BIND_LEGACY); }
|
||||
| NATIVE { $$ = newNode<SetTimeZoneBindNode>(TimeZoneUtil::BIND_NATIVE); }
|
||||
;
|
||||
|
||||
%type tran_option_list_opt(<setTransactionNode>)
|
||||
tran_option_list_opt($setTransactionNode)
|
||||
: // nothing
|
||||
|
@ -125,11 +125,9 @@
|
||||
#define isc_dpb_map_attach 90
|
||||
#define isc_dpb_session_time_zone 91
|
||||
#define isc_dpb_set_db_replica 92
|
||||
#define isc_dpb_time_zone_bind 93
|
||||
#define isc_dpb_decfloat_bind 94
|
||||
#define isc_dpb_decfloat_round 95
|
||||
#define isc_dpb_decfloat_traps 96
|
||||
#define isc_dpb_int128_bind 97
|
||||
#define isc_dpb_set_bind 93
|
||||
#define isc_dpb_decfloat_round 94
|
||||
#define isc_dpb_decfloat_traps 95
|
||||
|
||||
|
||||
/**************************************************/
|
||||
|
@ -84,13 +84,13 @@ CommitNumber ActiveSnapshots::getSnapshotForVersion(CommitNumber version_cn)
|
||||
|
||||
|
||||
// static method
|
||||
Jrd::Attachment* Jrd::Attachment::create(Database* dbb, const InitialOptions* initialOptions)
|
||||
Jrd::Attachment* Jrd::Attachment::create(Database* dbb)
|
||||
{
|
||||
MemoryPool* const pool = dbb->createPool();
|
||||
|
||||
try
|
||||
{
|
||||
Attachment* const attachment = FB_NEW_POOL(*pool) Attachment(pool, dbb, initialOptions);
|
||||
Attachment* const attachment = FB_NEW_POOL(*pool) Attachment(pool, dbb);
|
||||
pool->setStatsGroup(attachment->att_memory_stats);
|
||||
return attachment;
|
||||
}
|
||||
@ -203,7 +203,7 @@ void Jrd::Attachment::backupStateReadUnLock(thread_db* tdbb)
|
||||
}
|
||||
|
||||
|
||||
Jrd::Attachment::Attachment(MemoryPool* pool, Database* dbb, const InitialOptions* initialOptions)
|
||||
Jrd::Attachment::Attachment(MemoryPool* pool, Database* dbb)
|
||||
: att_pool(pool),
|
||||
att_memory_stats(&dbb->dbb_memory_stats),
|
||||
att_database(dbb),
|
||||
@ -233,7 +233,8 @@ Jrd::Attachment::Attachment(MemoryPool* pool, Database* dbb, const InitialOption
|
||||
att_ext_parent(NULL),
|
||||
att_ext_call_depth(0),
|
||||
att_trace_manager(FB_NEW_POOL(*att_pool) TraceManager(this)),
|
||||
att_timezone_bind(TimeZoneUtil::BIND_NATIVE),
|
||||
att_bindings(*pool),
|
||||
att_dest_bind(&att_bindings),
|
||||
att_original_timezone(TimeZoneUtil::getSystemTimeZone()),
|
||||
att_current_timezone(att_original_timezone),
|
||||
att_utility(UTIL_NONE),
|
||||
@ -243,21 +244,16 @@ Jrd::Attachment::Attachment(MemoryPool* pool, Database* dbb, const InitialOption
|
||||
att_internal(*pool),
|
||||
att_dyn_req(*pool),
|
||||
att_dec_status(DecimalStatus::DEFAULT),
|
||||
att_dec_binding(NumericBinding::DEFAULT),
|
||||
att_charsets(*pool),
|
||||
att_charset_ids(*pool),
|
||||
att_pools(*pool),
|
||||
att_idle_timeout(0),
|
||||
att_stmt_timeout(0),
|
||||
att_batches(*pool)
|
||||
att_batches(*pool),
|
||||
att_initial_options(*pool)
|
||||
{
|
||||
att_internal.grow(irq_MAX);
|
||||
att_dyn_req.grow(drq_MAX);
|
||||
|
||||
if (initialOptions)
|
||||
att_initial_options = *initialOptions;
|
||||
|
||||
att_initial_options.resetAttachment(this);
|
||||
}
|
||||
|
||||
|
||||
@ -1089,3 +1085,4 @@ void Attachment::IdleTimer::reset(unsigned int timeout)
|
||||
check(&s);
|
||||
m_fireTime = m_expTime;
|
||||
}
|
||||
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include "../jrd/PreparedStatement.h"
|
||||
#include "../jrd/RandomGenerator.h"
|
||||
#include "../jrd/RuntimeStatistics.h"
|
||||
#include "../jrd/Coercion.h"
|
||||
|
||||
#include "../common/classes/ByteChunk.h"
|
||||
#include "../common/classes/GenericMap.h"
|
||||
@ -92,6 +93,7 @@ namespace Jrd
|
||||
class Validation;
|
||||
class Applier;
|
||||
|
||||
|
||||
struct DSqlCacheItem
|
||||
{
|
||||
DSqlCacheItem(MemoryPool& pool)
|
||||
@ -363,28 +365,35 @@ public:
|
||||
class InitialOptions
|
||||
{
|
||||
public:
|
||||
InitialOptions(const DatabaseOptions& options);
|
||||
|
||||
InitialOptions()
|
||||
InitialOptions(MemoryPool& p)
|
||||
: bindings(p)
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
void setInitialOptions(thread_db* tdbb, const DatabaseOptions& options);
|
||||
static void setBind(thread_db* tdbb, const Firebird::PathName& bind, CoercionArray* target);
|
||||
void resetAttachment(Attachment* attachment) const;
|
||||
|
||||
CoercionArray *getBindings()
|
||||
{
|
||||
return &bindings;
|
||||
}
|
||||
|
||||
const CoercionArray *getBindings() const
|
||||
{
|
||||
return &bindings;
|
||||
}
|
||||
|
||||
private:
|
||||
void setBinding(Firebird::string option, Firebird::NumericBinding& bind);
|
||||
|
||||
Firebird::DecimalStatus decFloatStatus = Firebird::DecimalStatus::DEFAULT;
|
||||
Firebird::NumericBinding decFloatBinding = Firebird::NumericBinding::DEFAULT;
|
||||
Firebird::NumericBinding int128Binding = Firebird::NumericBinding::DEFAULT;
|
||||
CoercionArray bindings;
|
||||
|
||||
Firebird::TimeZoneUtil::Bind timeZoneBind = Firebird::TimeZoneUtil::BIND_NATIVE;
|
||||
USHORT originalTimeZone = Firebird::TimeZoneUtil::GMT_ZONE;
|
||||
};
|
||||
|
||||
public:
|
||||
static Attachment* create(Database* dbb, const InitialOptions* initialOptions);
|
||||
static Attachment* create(Database* dbb);
|
||||
static void destroy(Attachment* const attachment);
|
||||
|
||||
MemoryPool* const att_pool; // Memory pool
|
||||
@ -454,7 +463,8 @@ public:
|
||||
ULONG att_ext_call_depth; // external connection call depth, 0 for user attachment
|
||||
TraceManager* att_trace_manager; // Trace API manager
|
||||
|
||||
Firebird::TimeZoneUtil::Bind att_timezone_bind;
|
||||
CoercionArray att_bindings;
|
||||
CoercionArray* att_dest_bind;
|
||||
USHORT att_original_timezone;
|
||||
USHORT att_current_timezone;
|
||||
|
||||
@ -479,8 +489,6 @@ public:
|
||||
Firebird::Array<JrdStatement*> att_dyn_req; // internal dyn statements
|
||||
Firebird::ICryptKeyCallback* att_crypt_callback; // callback for DB crypt
|
||||
Firebird::DecimalStatus att_dec_status; // error handling and rounding
|
||||
Firebird::NumericBinding att_dec_binding; // use legacy datatype for DecFloat in outer world
|
||||
Firebird::NumericBinding att_i128_binding; // use legacy datatype for INT128 in outer world
|
||||
|
||||
jrd_req* findSystemRequest(thread_db* tdbb, USHORT id, USHORT which);
|
||||
|
||||
@ -620,8 +628,15 @@ public:
|
||||
return att_user;
|
||||
}
|
||||
|
||||
void setInitialOptions(thread_db* tdbb, DatabaseOptions& options, bool newDb);
|
||||
const CoercionArray* getInitialBindings() const
|
||||
{
|
||||
return att_initial_options.getBindings();
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
Attachment(MemoryPool* pool, Database* dbb, const InitialOptions* initialOptions);
|
||||
Attachment(MemoryPool* pool, Database* dbb);
|
||||
~Attachment();
|
||||
|
||||
class IdleTimer FB_FINAL :
|
||||
|
149
src/jrd/Coercion.cpp
Normal file
149
src/jrd/Coercion.cpp
Normal file
@ -0,0 +1,149 @@
|
||||
/*
|
||||
* PROGRAM: JRD access method
|
||||
* MODULE: Coercion.cpp
|
||||
* DESCRIPTION: Automatically coercing user datatypes
|
||||
*
|
||||
* The contents of this file are subject to the Initial
|
||||
* Developer's Public License Version 1.0 (the "License");
|
||||
* you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
* http://www.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl.
|
||||
*
|
||||
* Software distributed under the License is distributed AS IS,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing rights
|
||||
* and limitations under the License.
|
||||
*
|
||||
* The Original Code was created by Alex Peshkov
|
||||
* for the Firebird Open Source RDBMS project.
|
||||
*
|
||||
* Copyright (c) 2019 Alex Peshkov <peshkoff@mail.ru>
|
||||
* and all contributors signed below.
|
||||
*
|
||||
* All Rights Reserved.
|
||||
* Contributor(s): ______________________________________.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "firebird.h"
|
||||
#include "../jrd/Coercion.h"
|
||||
|
||||
#include "../dsql/dsql.h"
|
||||
#include "../jrd/align.h"
|
||||
|
||||
using namespace Jrd;
|
||||
using namespace Firebird;
|
||||
|
||||
bool CoercionArray::coerce(dsc* d) const
|
||||
{
|
||||
// move down through array to ensure correct order: newer rule overrides older one
|
||||
for (unsigned n = getCount(); n--;)
|
||||
{
|
||||
if (getElement(n).coerce(d))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CoercionRule::coerce(dsc* d) const
|
||||
{
|
||||
bool found = false;
|
||||
|
||||
// check for exact match (taking flags into an account)
|
||||
if ((!found) &&
|
||||
(d->dsc_dtype == fromDsc.dsc_dtype) &&
|
||||
((d->dsc_length == fromDsc.dsc_length) || (!(fromMask & FLD_has_len))) &&
|
||||
((d->getCharSet() == fromDsc.getCharSet()) || (!(fromMask & FLD_has_chset))) &&
|
||||
((d->dsc_scale == fromDsc.dsc_scale) || (!(fromMask & FLD_has_scale))))
|
||||
{
|
||||
found = true;
|
||||
}
|
||||
|
||||
// check for inexact datatype match when FLD_has_len is not set
|
||||
if ((!found) && (!(fromMask & FLD_has_len)))
|
||||
{
|
||||
switch(fromDsc.dsc_dtype)
|
||||
{
|
||||
case dtype_dec64:
|
||||
case dtype_dec128:
|
||||
if (d->dsc_dtype == dtype_dec64 || d->dsc_dtype == dtype_dec128)
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
return false;
|
||||
|
||||
// now define output descriptor
|
||||
// first of all process LEGACY case
|
||||
if (toMask & FLD_legacy)
|
||||
{
|
||||
found = true;
|
||||
switch(d->dsc_dtype)
|
||||
{
|
||||
case dtype_dec64:
|
||||
case dtype_dec128:
|
||||
d->dsc_dtype = dtype_double;
|
||||
d->dsc_length = 8;
|
||||
break;
|
||||
case dtype_sql_time_tz:
|
||||
d->dsc_dtype = dtype_sql_time;
|
||||
d->dsc_length = 4;
|
||||
break;
|
||||
case dtype_timestamp_tz:
|
||||
d->dsc_dtype = dtype_timestamp;
|
||||
d->dsc_length = 8;
|
||||
break;
|
||||
case dtype_int128:
|
||||
d->dsc_dtype = dtype_int64;
|
||||
d->dsc_length = 8;
|
||||
break;
|
||||
case dtype_boolean:
|
||||
d->dsc_dtype = dtype_text;
|
||||
d->dsc_length = 5;
|
||||
break;
|
||||
default:
|
||||
found = false;
|
||||
break;
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
// Final pass - order is important
|
||||
|
||||
// length
|
||||
if (toMask & FLD_has_len)
|
||||
d->dsc_length = toDsc.dsc_length;
|
||||
else
|
||||
{
|
||||
if (!type_lengths[toDsc.dsc_dtype])
|
||||
{
|
||||
fb_assert(toDsc.isText());
|
||||
d->dsc_length = d->getStringLength();
|
||||
}
|
||||
else
|
||||
d->dsc_length = type_lengths[toDsc.dsc_dtype];
|
||||
}
|
||||
|
||||
// scale
|
||||
if (toMask & FLD_has_scale)
|
||||
d->dsc_scale = toDsc.dsc_scale;
|
||||
else if (!(DTYPE_IS_EXACT(d->dsc_dtype) && DTYPE_IS_EXACT(toDsc.dsc_dtype)))
|
||||
d->dsc_scale = 0;
|
||||
|
||||
// type
|
||||
d->dsc_dtype = toDsc.dsc_dtype;
|
||||
d->dsc_sub_type = toDsc.dsc_sub_type;
|
||||
|
||||
// charset
|
||||
if (toMask & FLD_has_chset)
|
||||
d->setTextType(toDsc.getTextType());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
72
src/jrd/Coercion.h
Normal file
72
src/jrd/Coercion.h
Normal file
@ -0,0 +1,72 @@
|
||||
/*
|
||||
* PROGRAM: JRD access method
|
||||
* MODULE: Coercion.h
|
||||
* DESCRIPTION: Automatically coercing user datatypes
|
||||
*
|
||||
* The contents of this file are subject to the Initial
|
||||
* Developer's Public License Version 1.0 (the "License");
|
||||
* you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
* http://www.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl.
|
||||
*
|
||||
* Software distributed under the License is distributed AS IS,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing rights
|
||||
* and limitations under the License.
|
||||
*
|
||||
* The Original Code was created by Alex Peshkov
|
||||
* for the Firebird Open Source RDBMS project.
|
||||
*
|
||||
* Copyright (c) 2019 Alex Peshkov <peshkoff@mail.ru>
|
||||
* and all contributors signed below.
|
||||
*
|
||||
* All Rights Reserved.
|
||||
* Contributor(s): ______________________________________.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef JRD_COERCION_H
|
||||
#define JRD_COERCION_H
|
||||
|
||||
#include "firebird.h"
|
||||
|
||||
#include "../common/classes/array.h"
|
||||
#include "../common/dsc.h"
|
||||
|
||||
namespace Jrd
|
||||
{
|
||||
class thread_db;
|
||||
class TypeClause;
|
||||
|
||||
class CoercionRule
|
||||
{
|
||||
public:
|
||||
CoercionRule()
|
||||
: fromMask(0), toMask(0)
|
||||
{
|
||||
fromDsc.clear();
|
||||
toDsc.clear();
|
||||
}
|
||||
|
||||
void setRule(TypeClause* from, TypeClause *to);
|
||||
bool coerce(dsc* d) const;
|
||||
|
||||
private:
|
||||
dsc fromDsc, toDsc;
|
||||
USHORT fromMask, toMask;
|
||||
};
|
||||
|
||||
class CoercionArray : public Firebird::HalfStaticArray<CoercionRule, 4>
|
||||
{
|
||||
public:
|
||||
CoercionArray(MemoryPool& p)
|
||||
: Firebird::HalfStaticArray<CoercionRule, 4>(p)
|
||||
{
|
||||
}
|
||||
|
||||
bool coerce(dsc* d) const;
|
||||
};
|
||||
|
||||
} // namespace Jrd
|
||||
|
||||
#endif // JRD_COERCION_H
|
@ -922,7 +922,7 @@ namespace Jrd {
|
||||
UserId user;
|
||||
user.setUserName("Database Crypter");
|
||||
|
||||
Jrd::Attachment* const attachment = Jrd::Attachment::create(&dbb, nullptr);
|
||||
Jrd::Attachment* const attachment = Jrd::Attachment::create(&dbb);
|
||||
RefPtr<SysStableAttachment> sAtt(FB_NEW SysStableAttachment(attachment));
|
||||
attachment->setStable(sAtt);
|
||||
attachment->att_filename = dbb.dbb_filename;
|
||||
|
@ -61,6 +61,7 @@
|
||||
#include "../jrd/RuntimeStatistics.h"
|
||||
#include "../jrd/event_proto.h"
|
||||
#include "../jrd/ExtEngineManager.h"
|
||||
#include "../jrd/Coercion.h"
|
||||
#include "../lock/lock_proto.h"
|
||||
#include "../common/config/config.h"
|
||||
#include "../common/classes/SyncObject.h"
|
||||
@ -439,6 +440,7 @@ public:
|
||||
|
||||
FB_UINT64 dbb_repl_sequence; // replication sequence
|
||||
ReplicaMode dbb_replica_mode; // replica access mode
|
||||
CoercionArray dbb_bindings; // preconfigured datatype coercions
|
||||
|
||||
// returns true if primary file is located on raw device
|
||||
bool onRawDevice() const;
|
||||
@ -503,7 +505,8 @@ private:
|
||||
dbb_linger_end(0),
|
||||
dbb_plugin_config(pConf),
|
||||
dbb_repl_sequence(0),
|
||||
dbb_replica_mode(REPLICA_NONE)
|
||||
dbb_replica_mode(REPLICA_NONE),
|
||||
dbb_bindings(*p)
|
||||
{
|
||||
dbb_pools.add(p);
|
||||
}
|
||||
@ -541,6 +544,17 @@ public:
|
||||
FB_UINT64 getReplSequence(thread_db* tdbb);
|
||||
void setReplSequence(thread_db* tdbb, FB_UINT64 sequence);
|
||||
|
||||
CoercionArray *getBindings()
|
||||
{
|
||||
return &dbb_bindings;
|
||||
}
|
||||
|
||||
const CoercionArray *getBindings() const
|
||||
{
|
||||
return &dbb_bindings;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
//static int blockingAstSharedCounter(void*);
|
||||
static int blocking_ast_sweep(void* ast_object);
|
||||
|
@ -2959,7 +2959,7 @@ void BufferControl::cache_writer(BufferControl* bcb)
|
||||
UserId user;
|
||||
user.setUserName("Cache Writer");
|
||||
|
||||
Jrd::Attachment* const attachment = Jrd::Attachment::create(dbb, nullptr);
|
||||
Jrd::Attachment* const attachment = Jrd::Attachment::create(dbb);
|
||||
RefPtr<SysStableAttachment> sAtt(FB_NEW SysStableAttachment(attachment));
|
||||
attachment->setStable(sAtt);
|
||||
attachment->att_filename = dbb->dbb_filename;
|
||||
|
102
src/jrd/jrd.cpp
102
src/jrd/jrd.cpp
@ -127,6 +127,7 @@
|
||||
#include "../common/classes/fb_tls.h"
|
||||
#include "../common/classes/ClumpletWriter.h"
|
||||
#include "../common/classes/RefMutex.h"
|
||||
#include "../common/classes/ParsedList.h"
|
||||
#include "../common/utils_proto.h"
|
||||
#include "../jrd/DebugInterface.h"
|
||||
#include "../jrd/CryptoManager.h"
|
||||
@ -1016,11 +1017,9 @@ namespace Jrd
|
||||
PathName dpb_org_filename;
|
||||
string dpb_config;
|
||||
string dpb_session_tz;
|
||||
string dpb_time_zone_bind;
|
||||
string dpb_decfloat_bind;
|
||||
PathName dpb_set_bind;
|
||||
string dpb_decfloat_round;
|
||||
string dpb_decfloat_traps;
|
||||
string dpb_int128_bind;
|
||||
|
||||
public:
|
||||
static const ULONG DPB_FLAGS_MASK = DBB_damaged;
|
||||
@ -1063,63 +1062,40 @@ namespace Jrd
|
||||
}
|
||||
};
|
||||
|
||||
void Attachment::InitialOptions::setBinding(string option, NumericBinding& bind)
|
||||
void Attachment::setInitialOptions(thread_db* tdbb, DatabaseOptions& options, bool newDb)
|
||||
{
|
||||
option.lower();
|
||||
|
||||
if (option == "native")
|
||||
bind = NumericBinding::DEFAULT;
|
||||
else if (option == "char" || option == "character")
|
||||
bind = NumericBinding(NumericBinding::NUM_TEXT);
|
||||
else if (option == "double" || option == "double precision")
|
||||
bind = NumericBinding(NumericBinding::NUM_DOUBLE);
|
||||
else if (option == "bigint")
|
||||
bind = NumericBinding(NumericBinding::NUM_INT64);
|
||||
else if (option.substr(0, 7) == "bigint,")
|
||||
if (newDb)
|
||||
{
|
||||
const char* p = option.c_str() + 7;
|
||||
|
||||
while (*p == ' ')
|
||||
++p;
|
||||
|
||||
const char* start = p;
|
||||
int scale = 0;
|
||||
|
||||
while (*p >= '0' && *p <= '9')
|
||||
{
|
||||
scale = scale * 10 + (*p - '0');
|
||||
++p;
|
||||
}
|
||||
|
||||
if (*p != '\0' || p - start == 0 || p - start > 2 || scale > NumericBinding::MAX_SCALE)
|
||||
(Arg::Gds(isc_invalid_decfloat_bind) << option).raise();
|
||||
|
||||
bind = NumericBinding(NumericBinding::NUM_INT64, static_cast<SCHAR>(-scale));
|
||||
Database* dbb = tdbb->getDatabase();
|
||||
if (dbb->dbb_config->getBind())
|
||||
InitialOptions::setBind(tdbb, dbb->dbb_config->getBind(), dbb->getBindings());
|
||||
}
|
||||
else
|
||||
(Arg::Gds(isc_invalid_decfloat_bind) << option).raise();
|
||||
|
||||
att_initial_options.setInitialOptions(tdbb, options);
|
||||
att_initial_options.resetAttachment(this);
|
||||
}
|
||||
|
||||
Attachment::InitialOptions::InitialOptions(const DatabaseOptions& options)
|
||||
void Attachment::InitialOptions::setBind(thread_db* tdbb, const PathName& bind, CoercionArray* target)
|
||||
{
|
||||
if (options.dpb_time_zone_bind.hasData())
|
||||
if (bind.hasData())
|
||||
{
|
||||
auto option = options.dpb_time_zone_bind;
|
||||
option.lower();
|
||||
ParsedList rules(bind, ";,");
|
||||
Attachment* att = tdbb->getAttachment();
|
||||
AutoSetRestore<CoercionArray*> defSet(&att->att_dest_bind, target);
|
||||
|
||||
if (option == "legacy")
|
||||
timeZoneBind = TimeZoneUtil::BIND_LEGACY;
|
||||
else if (option == "native")
|
||||
timeZoneBind = TimeZoneUtil::BIND_NATIVE;
|
||||
else
|
||||
(Arg::Gds(isc_invalid_time_zone_bind) << option).raise();
|
||||
for (unsigned i = 0; i < rules.getCount(); ++i)
|
||||
{
|
||||
rules[i].insert(0, "SET BIND OF ");
|
||||
|
||||
AutoPreparedStatement ps(att->prepareStatement(tdbb, nullptr, rules[i].ToString()));
|
||||
ps->execute(tdbb, nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (options.dpb_decfloat_bind.hasData())
|
||||
setBinding(options.dpb_decfloat_bind, decFloatBinding);
|
||||
|
||||
if (options.dpb_int128_bind.hasData())
|
||||
setBinding(options.dpb_int128_bind, int128Binding);
|
||||
void Attachment::InitialOptions::setInitialOptions(thread_db* tdbb, const DatabaseOptions& options)
|
||||
{
|
||||
setBind(tdbb, options.dpb_set_bind, getBindings());
|
||||
|
||||
if (options.dpb_decfloat_round.hasData())
|
||||
{
|
||||
@ -1177,12 +1153,12 @@ namespace Jrd
|
||||
{
|
||||
// reset DecFloat options
|
||||
attachment->att_dec_status = decFloatStatus;
|
||||
attachment->att_dec_binding = decFloatBinding;
|
||||
attachment->att_i128_binding = int128Binding;
|
||||
|
||||
// reset time zone options
|
||||
attachment->att_timezone_bind = timeZoneBind;
|
||||
attachment->att_current_timezone = attachment->att_original_timezone = originalTimeZone;
|
||||
|
||||
// reset bindings
|
||||
attachment->att_bindings.clear();
|
||||
}
|
||||
} // namespace Jrd
|
||||
|
||||
@ -1682,9 +1658,11 @@ JAttachment* JProvider::internalAttach(CheckStatusWrapper* user_status, const ch
|
||||
|
||||
TRA_init(attachment);
|
||||
|
||||
bool newDb = false;
|
||||
if (dbb->dbb_flags & DBB_new)
|
||||
{
|
||||
// If we're a not a secondary attachment, initialize some stuff
|
||||
newDb = true;
|
||||
|
||||
// NS: Use alias as database ID only if accessing database using file name is not possible.
|
||||
//
|
||||
@ -2075,6 +2053,7 @@ JAttachment* JProvider::internalAttach(CheckStatusWrapper* user_status, const ch
|
||||
|
||||
CCH_init2(tdbb);
|
||||
VIO_init(tdbb);
|
||||
attachment->setInitialOptions(tdbb, options, newDb);
|
||||
|
||||
CCH_release_exclusive(tdbb);
|
||||
|
||||
@ -3008,6 +2987,8 @@ JAttachment* JProvider::createDatabase(CheckStatusWrapper* user_status, const ch
|
||||
|
||||
Monitoring::publishAttachment(tdbb);
|
||||
|
||||
attachment->setInitialOptions(tdbb, options, true);
|
||||
|
||||
CCH_release_exclusive(tdbb);
|
||||
|
||||
// Figure out what character set & collation this attachment prefers
|
||||
@ -6968,16 +6949,8 @@ void DatabaseOptions::get(const UCHAR* dpb, USHORT dpb_length, bool& invalid_cli
|
||||
dpb_replica_mode = (ReplicaMode) rdr.getInt();
|
||||
break;
|
||||
|
||||
case isc_dpb_time_zone_bind:
|
||||
rdr.getString(dpb_time_zone_bind);
|
||||
break;
|
||||
|
||||
case isc_dpb_decfloat_bind:
|
||||
rdr.getString(dpb_decfloat_bind);
|
||||
break;
|
||||
|
||||
case isc_dpb_int128_bind:
|
||||
rdr.getString(dpb_int128_bind);
|
||||
case isc_dpb_set_bind:
|
||||
rdr.getPath(dpb_set_bind);
|
||||
break;
|
||||
|
||||
case isc_dpb_decfloat_round:
|
||||
@ -7213,8 +7186,7 @@ static JAttachment* create_attachment(const PathName& alias_name,
|
||||
status_exception::raise(Arg::Gds(isc_att_shutdown));
|
||||
}
|
||||
|
||||
Attachment::InitialOptions initialOptions(options);
|
||||
attachment = Attachment::create(dbb, &initialOptions);
|
||||
attachment = Attachment::create(dbb);
|
||||
attachment->att_next = dbb->dbb_attachments;
|
||||
dbb->dbb_attachments = attachment;
|
||||
}
|
||||
|
@ -4737,7 +4737,7 @@ void Database::garbage_collector(Database* dbb)
|
||||
UserId user;
|
||||
user.setUserName("Garbage Collector");
|
||||
|
||||
Jrd::Attachment* const attachment = Jrd::Attachment::create(dbb, nullptr);
|
||||
Jrd::Attachment* const attachment = Jrd::Attachment::create(dbb);
|
||||
RefPtr<SysStableAttachment> sAtt(FB_NEW SysStableAttachment(attachment));
|
||||
attachment->setStable(sAtt);
|
||||
attachment->att_filename = dbb->dbb_filename;
|
||||
|
Loading…
Reference in New Issue
Block a user