From a64b202dade1771ed50b90bb4f3e9bb7f3bc1687 Mon Sep 17 00:00:00 2001 From: Adriano dos Santos Fernandes Date: Tue, 26 Mar 2019 13:12:39 -0300 Subject: [PATCH] Fixed CORE-6034 - The original time zone should be set to the current time zone at routine invocation. --- doc/sql.extensions/README.time_zone.md | 2 ++ src/dsql/ExprNodes.cpp | 4 ++++ src/dsql/StmtNodes.cpp | 4 ++++ src/jrd/exe.cpp | 4 ++++ src/jrd/recsrc/ProcedureScan.cpp | 8 ++++++++ 5 files changed, 22 insertions(+) diff --git a/doc/sql.extensions/README.time_zone.md b/doc/sql.extensions/README.time_zone.md index cffea1a339..f3041a0c89 100644 --- a/doc/sql.extensions/README.time_zone.md +++ b/doc/sql.extensions/README.time_zone.md @@ -8,6 +8,8 @@ The session time zone, as the name implies, can be a different one for each data It can then be changed with `SET TIME ZONE` statement to a given time zone or reset to its original value with `SET TIME ZONE LOCAL`. +The original time zone value is initially defined equal to the current time zone in session initialization and cannot be changed manually. But the original time zone is internally changed when a routine (function, procedure or trigger) is called to the value of the current time zone and restored to its previous value at routine exit. That means that a routine that changes the current time zone and later run `SET TIME ZONE LOCAL` will restore the current time zone to its initially received value. + A time zone may be a string with a time zone region (for example, `America/Sao_Paulo`) or a hours:minutes displacement (for example, `-03:00`) from GMT. A time/timestamp with time zone is considered equal to another time/timestamp with time zone if their conversion to UTC are equal, for example, `time '10:00 -02' = time '09:00 -03'`, since both are the same as `time '12:00 GMT'`. This is also valid in the context of `UNIQUE` constraints and for sorting purposes. diff --git a/src/dsql/ExprNodes.cpp b/src/dsql/ExprNodes.cpp index f4944608c4..a32582e8a5 100644 --- a/src/dsql/ExprNodes.cpp +++ b/src/dsql/ExprNodes.cpp @@ -12712,6 +12712,10 @@ dsc* UdfCallNode::execute(thread_db* tdbb, jrd_req* request) const Arg::Gds(isc_modnotfound)); } + AutoSetRestore autoOriginalTimeZone( + &tdbb->getAttachment()->att_original_timezone, + tdbb->getAttachment()->att_current_timezone); + // Evaluate the function. if (function->fun_entrypoint) diff --git a/src/dsql/StmtNodes.cpp b/src/dsql/StmtNodes.cpp index cc412b0fc6..aaaedb00f8 100644 --- a/src/dsql/StmtNodes.cpp +++ b/src/dsql/StmtNodes.cpp @@ -3203,6 +3203,10 @@ void ExecProcedureNode::executeProcedure(thread_db* tdbb, jrd_req* request) cons try { + AutoSetRestore autoOriginalTimeZone( + &tdbb->getAttachment()->att_original_timezone, + tdbb->getAttachment()->att_current_timezone); + procRequest->req_gmt_timestamp = request->req_gmt_timestamp; EXE_start(tdbb, procRequest, transaction); diff --git a/src/jrd/exe.cpp b/src/jrd/exe.cpp index 787b183b8b..9acb33c11e 100644 --- a/src/jrd/exe.cpp +++ b/src/jrd/exe.cpp @@ -1163,6 +1163,10 @@ void EXE_execute_triggers(thread_db* tdbb, UserId* invoker = s->triggerInvoker ? s->triggerInvoker : tdbb->getAttachment()->att_ss_user; AutoSetRestore userIdHolder(&tdbb->getAttachment()->att_ss_user, invoker); + AutoSetRestore autoOriginalTimeZone( + &tdbb->getAttachment()->att_original_timezone, + tdbb->getAttachment()->att_current_timezone); + EXE_start(tdbb, trigger, transaction); } diff --git a/src/jrd/recsrc/ProcedureScan.cpp b/src/jrd/recsrc/ProcedureScan.cpp index 659b7a1028..ccf25402e1 100644 --- a/src/jrd/recsrc/ProcedureScan.cpp +++ b/src/jrd/recsrc/ProcedureScan.cpp @@ -110,6 +110,10 @@ void ProcedureScan::open(thread_db* tdbb) const TraceProcExecute trace(tdbb, proc_request, request, m_targetList); + AutoSetRestore autoOriginalTimeZone( + &tdbb->getAttachment()->att_original_timezone, + tdbb->getAttachment()->att_current_timezone); + EXE_start(tdbb, proc_request, request->req_transaction); if (iml) @@ -184,6 +188,10 @@ bool ProcedureScan::getRecord(thread_db* tdbb) const TraceProcFetch trace(tdbb, proc_request); + AutoSetRestore autoOriginalTimeZone( + &tdbb->getAttachment()->att_original_timezone, + tdbb->getAttachment()->att_current_timezone); + try { EXE_receive(tdbb, proc_request, 1, oml, om);