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:
parent
873cd8090f
commit
94f377b8fb
@ -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)
|
||||
|
@ -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.
|
||||
|
@ -51,6 +51,13 @@ class NoThrowTimeStamp;
|
||||
|
||||
class TimeZoneUtil
|
||||
{
|
||||
public:
|
||||
enum Bind
|
||||
{
|
||||
BIND_LEGACY,
|
||||
BIND_NATIVE
|
||||
};
|
||||
|
||||
public:
|
||||
static const USHORT GMT_ZONE = 65535;
|
||||
|
||||
|
@ -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?
|
||||
|
@ -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:
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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},
|
||||
|
Loading…
Reference in New Issue
Block a user