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

Add SET TIME ZONE BIND statement.

This commit is contained in:
Adriano dos Santos Fernandes 2018-07-03 12:58:37 -03:00
parent 873cd8090f
commit 94f377b8fb
10 changed files with 116 additions and 5 deletions

View File

@ -325,6 +325,7 @@ Firebird 4.0
IDLE *
INVOKER
LAST_DAY *
LEGACY *
MESSAGE *
NATIVE *
NORMALIZE_DECFLOAT *
@ -336,7 +337,7 @@ Firebird 4.0
PRIVILEGE *
QUANTIZE *
RANGE (1)
RESET *
RESET *
SECURITY
SESSION
SQL (1)

View File

@ -157,6 +157,30 @@ set time zone 'America/Sao_Paulo';
set time zone local;
```
### `SET TIME ZONE BIND` statement
Changes the session time zone bind for compatibility with old clients.
The default is NATIVE, which means that `TIME WITH TIME ZONE` and `TIMESTAMP WITH TIME ZONE` expressions are returned with they new data types to the client.
Old clients may not understand the new data types, so it's possible to define the bind to LEGACY and the expressions will be returned as `TIME WITHOUT TIME ZONE` and `TIMESTAMP WITHOUT TIME ZONE`, with appropriate conversion.
The bind configuration is also applicable to input parameters.
#### Syntax
```
SET TIME ZONE BIND { NATIVE | LEGACY }
```
#### Examples
```
set time zone bind native;
set time zone bind legacy;
```
### `AT` expression
Translates a time/timestamp value to its correspondent value in another time zone.

View File

@ -51,6 +51,13 @@ class NoThrowTimeStamp;
class TimeZoneUtil
{
public:
enum Bind
{
BIND_LEGACY,
BIND_NATIVE
};
public:
static const USHORT GMT_ZONE = 65535;

View File

@ -8407,6 +8407,17 @@ 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?

View File

@ -1807,6 +1807,32 @@ 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:

View File

@ -222,6 +222,26 @@ void GEN_port(DsqlCompilerScratch* dsqlScratch, dsql_msg* message)
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)
{

View File

@ -604,6 +604,7 @@ using namespace Firebird;
%token <metaNamePtr> IDLE
%token <metaNamePtr> INVOKER
%token <metaNamePtr> LAST_DAY
%token <metaNamePtr> LEGACY
%token <metaNamePtr> LOCAL
%token <metaNamePtr> LOCALTIME
%token <metaNamePtr> LOCALTIMESTAMP
@ -860,6 +861,7 @@ mng_statement
| set_role { $$ = $1; }
| session_reset { $$ = $1; }
| set_time_zone { $$ = $1; }
| set_time_zone_bind { $$ = $1; }
;
@ -5293,10 +5295,24 @@ timepart_ses_stmt_tout
%type <mngNode> set_time_zone
set_time_zone
: SET TIME ZONE sql_string
{ $$ = newNode<SetTimeZoneNode>($4->getString()); }
| SET TIME ZONE LOCAL
{ $$ = newNode<SetTimeZoneNode>(); }
: SET TIME ZONE set_time_zone_option { $$ = $4; }
;
%type <mngNode> set_time_zone_option
set_time_zone_option
: sql_string { $$ = newNode<SetTimeZoneNode>($1->getString()); }
| 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>)
@ -8642,6 +8658,7 @@ non_reserved_word
| IDLE
| INVOKER
| LAST_DAY
| LEGACY
| LIFETIME
| MESSAGE
| NATIVE

View File

@ -228,6 +228,7 @@ Jrd::Attachment::Attachment(MemoryPool* pool, Database* dbb)
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_original_timezone(TimeZoneUtil::getSystemTimeZone()),
att_current_timezone(att_original_timezone),
att_utility(UTIL_NONE),
@ -476,6 +477,7 @@ void Jrd::Attachment::resetSession(thread_db* tdbb, jrd_tra** traHandle)
att_dec_binding = DecimalBinding::DEFAULT;
// reset time zone
att_timezone_bind = TimeZoneUtil::BIND_NATIVE;
att_current_timezone = att_original_timezone;
// reset timeouts

View File

@ -40,6 +40,7 @@
#include "../common/classes/stack.h"
#include "../common/classes/timestamp.h"
#include "../common/ThreadStart.h"
#include "../common/TimeZoneUtil.h"
#include "../jrd/EngineInterface.h"
#include "../jrd/sbm.h"
@ -361,6 +362,7 @@ 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;
USHORT att_original_timezone;
USHORT att_current_timezone;

View File

@ -258,6 +258,7 @@ static const TOK tokens[] =
{TOK_LEADING, "LEADING", false},
{TOK_LEAVE, "LEAVE", true},
{TOK_LEFT, "LEFT", false},
{TOK_LEGACY, "LEGACY", true},
{TOK_LENGTH, "LENGTH", true},
{TOK_LEVEL, "LEVEL", true},
{TOK_LIFETIME, "LIFETIME", true},