Skip to content

Commit

Permalink
Let users select legacy datatype (CHAR, DOUBLE or BIGINT with scale) …
Browse files Browse the repository at this point in the history
…to be used instead DECFLOAT when talking to old client
  • Loading branch information
AlexPeshkoff committed Mar 21, 2017
1 parent b80e5f4 commit 84f435c
Show file tree
Hide file tree
Showing 7 changed files with 115 additions and 14 deletions.
12 changes: 12 additions & 0 deletions src/common/DecFloat.h
Expand Up @@ -51,6 +51,18 @@ struct DecimalStatus
USHORT decExtFlag, roundingMode;
};

struct DecimalBinding
{
DecimalBinding()
: bind(DEC_NATIVE), numScale(0)
{ }

enum Bind { DEC_NATIVE, DEC_TEXT, DEC_DOUBLE, DEC_NUMERIC };

Bind bind;
SCHAR numScale;
};

class Decimal64
{
friend class Decimal128;
Expand Down
11 changes: 11 additions & 0 deletions src/dsql/StmtNodes.cpp
Expand Up @@ -8072,6 +8072,17 @@ void SetTrapsNode::execute(thread_db* tdbb, dsql_req* /*request*/) const
//--------------------


void SetBindNode::execute(thread_db* tdbb, dsql_req* /*request*/) const
{
SET_TDBB(tdbb);
Attachment* const attachment = tdbb->getAttachment();
attachment->att_dec_binding = bind;
}


//--------------------


StmtNode* UpdateOrInsertNode::dsqlPass(DsqlCompilerScratch* dsqlScratch)
{
thread_db* tdbb = JRD_get_thread_data(); // necessary?
Expand Down
26 changes: 26 additions & 0 deletions src/dsql/StmtNodes.h
Expand Up @@ -1631,6 +1631,32 @@ class SetTrapsNode : public SessionManagementNode
};


class SetBindNode : public SessionManagementNode
{
public:
SetBindNode(MemoryPool& pool)
: SessionManagementNode(pool)
{
}

public:
virtual Firebird::string internalPrint(NodePrinter& printer) const
{
SessionManagementNode::internalPrint(printer);

NODE_PRINT(printer, bind.bind);
NODE_PRINT(printer, bind.numScale);

return "SetBindNode";
}

virtual void execute(thread_db* tdbb, dsql_req* request) const;

public:
Firebird::DecimalBinding bind;
};


class UpdateOrInsertNode : public TypedNode<DsqlOnlyStmtNode, StmtNode::TYPE_UPDATE_OR_INSERT>
{
public:
Expand Down
19 changes: 19 additions & 0 deletions src/dsql/gen.cpp
Expand Up @@ -201,6 +201,25 @@ void GEN_port(DsqlCompilerScratch* dsqlScratch, dsql_msg* message)
if (fromCharSet != toCharSet)
parameter->par_desc.setTextType(toCharSet);
}
else if (parameter->par_desc.isDecFloat())
{
const DecimalBinding& b = tdbb->getAttachment()->att_dec_binding;
switch (b.bind)
{
case DecimalBinding::DEC_NATIVE:
break;
case DecimalBinding::DEC_TEXT:
parameter->par_desc.makeText((parameter->par_desc.dsc_dtype == dtype_dec64 ?
DECDOUBLE_String : DECQUAD_String) - 1, ttype_ascii);
break;
case DecimalBinding::DEC_DOUBLE:
parameter->par_desc.makeDouble();
break;
case DecimalBinding::DEC_NUMERIC:
parameter->par_desc.makeInt64(b.numScale);
break;
}
}

if (parameter->par_desc.dsc_dtype == dtype_text && parameter->par_index != 0)
{
Expand Down
58 changes: 44 additions & 14 deletions src/dsql/parse.y
Expand Up @@ -591,6 +591,7 @@ using namespace Firebird;

// tokens added for Firebird 4.0
%token <metaNamePtr> BINARY
%token <metaNamePtr> BIND
%token <metaNamePtr> COMPARE_DECFLOAT
%token <metaNamePtr> CUME_DIST
%token <metaNamePtr> DECFLOAT
Expand All @@ -599,6 +600,7 @@ using namespace Firebird;
%token <metaNamePtr> FOLLOWING
%token <metaNamePtr> INVOKER
%token <metaNamePtr> MESSAGE
%token <metaNamePtr> NATIVE
%token <metaNamePtr> NORMALIZE_DECFLOAT
%token <metaNamePtr> NTILE
%token <metaNamePtr> OTHERS
Expand Down Expand Up @@ -763,6 +765,7 @@ using namespace Firebird;
Jrd::CreateAlterRoleNode* createAlterRoleNode;
Jrd::SetRoundNode* setRoundNode;
Jrd::SetTrapsNode* setTrapsNode;
Jrd::SetBindNode* setBindNode;
}

%include types.y
Expand Down Expand Up @@ -822,6 +825,7 @@ tra_statement
mng_statement
: set_round { $$ = $1; }
| set_traps { $$ = $1; }
| set_bind { $$ = $1; }
| set_role { $$ = $1; }
;

Expand Down Expand Up @@ -4075,7 +4079,6 @@ keyword_or_column
| VAR_POP
| UNBOUNDED // added in FB 4.0
| WINDOW
| DECFLOAT
;

col_opt
Expand Down Expand Up @@ -4720,14 +4723,7 @@ varbinary_character_keyword

%type <legacyField> decfloat_type
decfloat_type
: DECFLOAT
{
$$ = newNode<dsql_fld>();
$$->dtype = dtype_dec64;
$$->length = sizeof(Decimal64);
$$->precision = 16;
}
| DECFLOAT '(' signed_long_integer ')'
: DECFLOAT '(' signed_long_integer ')'
{
if ($3 != 16 && $3 != 34)
yyabandon(YYPOSNARG(3), -842, isc_decprecision_err); // DecFloat precision must be 16 or 34.
Expand Down Expand Up @@ -5037,6 +5033,14 @@ set_traps
{ $$ = $5; }
;

%type <setBindNode> set_bind
set_bind
: SET DECFLOAT BIND
{ $$ = newNode<SetBindNode>(); }
bind_clause($4)
{ $$ = $4; }
;

%type traps_list_opt(<setTrapsNode>)
traps_list_opt($setTrapsNode)
: // nothing
Expand All @@ -5055,6 +5059,29 @@ trap($setTrapsNode)
{ $setTrapsNode->trap($1); }
;

%type bind_clause(<setBindNode>)
bind_clause($setBindNode)
: NATIVE
// do nothing
| character_keyword
{ $setBindNode->bind.bind = DecimalBinding::DEC_TEXT; }
| DOUBLE PRECISION
{ $setBindNode->bind.bind = DecimalBinding::DEC_DOUBLE; }
| BIGINT scale_clause($setBindNode)
{ $setBindNode->bind.bind = DecimalBinding::DEC_NUMERIC; }
;

%type scale_clause(<setBindNode>)
scale_clause($setBindNode)
: // nothing
| ',' signed_long_integer
{
if ($2 > 18 || $2 < 0)
yyabandon(YYPOSNARG(2), -842, isc_scale_nogt); // Scale must be between 0 and precision
$setBindNode->bind.numScale = -$2;
}
;

%type tran_option_list_opt(<setTransactionNode>)
tran_option_list_opt($setTransactionNode)
: // nothing
Expand Down Expand Up @@ -8285,27 +8312,30 @@ non_reserved_word
| SERVERWIDE
| INCREMENT
| TRUSTED
| CUME_DIST // added in FB 4.0
| BIND // added in FB 4.0
| COMPARE_DECFLOAT
| CUME_DIST
| DECFLOAT
| DEFINER
| EXCLUDE
| FOLLOWING
| INVOKER
| MESSAGE
| NATIVE
| NORMALIZE_DECFLOAT
| NTILE
| OTHERS
| PERCENT_RANK
| PRECEDING
| PRIVILEGE
| QUANTIZE
| RANGE
| SECURITY
| SQL
| SYSTEM
| TIES
| TRAPS
| QUANTIZE
| TOTALORDER
| NORMALIZE_DECFLOAT
| COMPARE_DECFLOAT
| TRAPS
;

%%
1 change: 1 addition & 0 deletions src/jrd/Attachment.h
Expand Up @@ -337,6 +337,7 @@ class Attachment : public pool_alloc<type_att>
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::DecimalBinding att_dec_binding; // use legacy datatype for DecFloat in outer world

jrd_req* findSystemRequest(thread_db* tdbb, USHORT id, USHORT which);

Expand Down
2 changes: 2 additions & 0 deletions src/yvalve/keywords.cpp
Expand Up @@ -95,6 +95,7 @@ static const TOK tokens[] =
{TOK_BIN_SHR, "BIN_SHR", true},
{TOK_BIN_XOR, "BIN_XOR", true},
{TOK_BINARY, "BINARY", false},
{TOK_BIND, "BIND", true},
{TOK_BIT_LENGTH, "BIT_LENGTH", false},
{TOK_BLOB, "BLOB", false},
{TOK_BLOCK, "BLOCK", true},
Expand Down Expand Up @@ -283,6 +284,7 @@ static const TOK tokens[] =
{TOK_NAME, "NAME", true},
{TOK_NAMES, "NAMES", true},
{TOK_NATIONAL, "NATIONAL", false},
{TOK_NATIVE, "NATIVE", true},
{TOK_NATURAL, "NATURAL", false},
{TOK_NCHAR, "NCHAR", false},
{TOK_NEXT, "NEXT", true},
Expand Down

0 comments on commit 84f435c

Please sign in to comment.