mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-02-02 10:00:38 +01:00
Improvement CORE-5853 - Forward-compatible expressions LOCALTIME and LOCALTIMESTAMP.
This commit is contained in:
parent
4bac379c1a
commit
15e25b3c35
13
doc/README.time_zone_forward_compatibility.md
Normal file
13
doc/README.time_zone_forward_compatibility.md
Normal file
@ -0,0 +1,13 @@
|
||||
# Time Zone support forward compatibility
|
||||
|
||||
In version 4.0, Firebird will support time zones.
|
||||
|
||||
Within this support will come an incompatibility with previous versions' `CURRENT_TIME` and `CURRENT_TIMESTAMP` expressions.
|
||||
|
||||
In v4, `CURRENT_TIME` and `CURRENT_TIMESTAMP` will respectively return expressions of data type `TIME WITH TIME ZONE` and `TIMESTAMP WITH TIME ZONE`.
|
||||
|
||||
To make your queries and database code compatible with future versions, from v3.0.4 you can instead use `LOCALTIME` and `LOCALTIMESTAMP`. In v3, these `LOCAL*` expressions will work indenticaly to their correspondents `CURRENT_*` expressions.
|
||||
|
||||
In v4, `LOCAL*` expressions will continue to work identically as now, but the `CURRENT_*` expressions will change.
|
||||
|
||||
You should not start using `LOCALTIME` and `LOCALTIMESTAMP` if your database may be downgraded to v3.0.3 or another version, as the old versions will not recognize the new expressions.
|
@ -3460,14 +3460,15 @@ dsc* CurrentDateNode::execute(thread_db* /*tdbb*/, jrd_req* request) const
|
||||
|
||||
static RegisterNode<CurrentTimeNode> regCurrentTimeNode(blr_current_time);
|
||||
static RegisterNode<CurrentTimeNode> regCurrentTimeNode2(blr_current_time2);
|
||||
static RegisterNode<CurrentTimeNode> regCurrentTimeNode3(blr_local_time);
|
||||
|
||||
DmlNode* CurrentTimeNode::parse(thread_db* /*tdbb*/, MemoryPool& pool, CompilerScratch* csb, const UCHAR blrOp)
|
||||
{
|
||||
unsigned precision = DEFAULT_TIME_PRECISION;
|
||||
|
||||
fb_assert(blrOp == blr_current_time || blrOp == blr_current_time2);
|
||||
fb_assert(blrOp == blr_current_time || blrOp == blr_current_time2 || blrOp == blr_local_time);
|
||||
|
||||
if (blrOp == blr_current_time2)
|
||||
if (blrOp == blr_current_time2 || blrOp == blr_local_time)
|
||||
{
|
||||
precision = csb->csb_blr_reader.getByte();
|
||||
|
||||
@ -3489,12 +3490,17 @@ string CurrentTimeNode::internalPrint(NodePrinter& printer) const
|
||||
|
||||
void CurrentTimeNode::setParameterName(dsql_par* parameter) const
|
||||
{
|
||||
parameter->par_name = parameter->par_alias = "CURRENT_TIME";
|
||||
parameter->par_name = parameter->par_alias = dsqlLocal ? "LOCALTIME" : "CURRENT_TIME";
|
||||
}
|
||||
|
||||
void CurrentTimeNode::genBlr(DsqlCompilerScratch* dsqlScratch)
|
||||
{
|
||||
if (precision == DEFAULT_TIME_PRECISION)
|
||||
if (dsqlLocal)
|
||||
{
|
||||
dsqlScratch->appendUChar(blr_local_time);
|
||||
dsqlScratch->appendUChar(precision);
|
||||
}
|
||||
else if (precision == DEFAULT_TIME_PRECISION)
|
||||
dsqlScratch->appendUChar(blr_current_time);
|
||||
else
|
||||
{
|
||||
@ -3572,15 +3578,16 @@ dsc* CurrentTimeNode::execute(thread_db* /*tdbb*/, jrd_req* request) const
|
||||
|
||||
static RegisterNode<CurrentTimeStampNode> regCurrentTimeStampNode(blr_current_timestamp);
|
||||
static RegisterNode<CurrentTimeStampNode> regCurrentTimeStampNode2(blr_current_timestamp2);
|
||||
static RegisterNode<CurrentTimeStampNode> regCurrentTimeStampNode3(blr_local_timestamp);
|
||||
|
||||
DmlNode* CurrentTimeStampNode::parse(thread_db* /*tdbb*/, MemoryPool& pool, CompilerScratch* csb,
|
||||
const UCHAR blrOp)
|
||||
{
|
||||
unsigned precision = DEFAULT_TIMESTAMP_PRECISION;
|
||||
|
||||
fb_assert(blrOp == blr_current_timestamp || blrOp == blr_current_timestamp2);
|
||||
fb_assert(blrOp == blr_current_timestamp || blrOp == blr_current_timestamp2 || blrOp == blr_local_timestamp);
|
||||
|
||||
if (blrOp == blr_current_timestamp2)
|
||||
if (blrOp == blr_current_timestamp2 || blrOp == blr_local_timestamp)
|
||||
{
|
||||
precision = csb->csb_blr_reader.getByte();
|
||||
|
||||
@ -3602,12 +3609,17 @@ string CurrentTimeStampNode::internalPrint(NodePrinter& printer) const
|
||||
|
||||
void CurrentTimeStampNode::setParameterName(dsql_par* parameter) const
|
||||
{
|
||||
parameter->par_name = parameter->par_alias = "CURRENT_TIMESTAMP";
|
||||
parameter->par_name = parameter->par_alias = dsqlLocal ? "LOCALTIMESTAMP" : "CURRENT_TIMESTAMP";
|
||||
}
|
||||
|
||||
void CurrentTimeStampNode::genBlr(DsqlCompilerScratch* dsqlScratch)
|
||||
{
|
||||
if (precision == DEFAULT_TIMESTAMP_PRECISION)
|
||||
if (dsqlLocal)
|
||||
{
|
||||
dsqlScratch->appendUChar(blr_local_timestamp);
|
||||
dsqlScratch->appendUChar(precision);
|
||||
}
|
||||
else if (precision == DEFAULT_TIMESTAMP_PRECISION)
|
||||
dsqlScratch->appendUChar(blr_current_timestamp);
|
||||
else
|
||||
{
|
||||
|
@ -340,7 +340,8 @@ class CurrentTimeNode : public TypedNode<ValueExprNode, ExprNode::TYPE_CURRENT_T
|
||||
public:
|
||||
CurrentTimeNode(MemoryPool& pool, unsigned aPrecision)
|
||||
: TypedNode<ValueExprNode, ExprNode::TYPE_CURRENT_TIME>(pool),
|
||||
precision(aPrecision)
|
||||
precision(aPrecision),
|
||||
dsqlLocal(false)
|
||||
{
|
||||
}
|
||||
|
||||
@ -359,6 +360,7 @@ public:
|
||||
|
||||
public:
|
||||
unsigned precision;
|
||||
bool dsqlLocal;
|
||||
};
|
||||
|
||||
|
||||
@ -367,7 +369,8 @@ class CurrentTimeStampNode : public TypedNode<ValueExprNode, ExprNode::TYPE_CURR
|
||||
public:
|
||||
CurrentTimeStampNode(MemoryPool& pool, unsigned aPrecision)
|
||||
: TypedNode<ValueExprNode, ExprNode::TYPE_CURRENT_TIMESTAMP>(pool),
|
||||
precision(aPrecision)
|
||||
precision(aPrecision),
|
||||
dsqlLocal(false)
|
||||
{
|
||||
}
|
||||
|
||||
@ -386,6 +389,7 @@ public:
|
||||
|
||||
public:
|
||||
unsigned precision;
|
||||
bool dsqlLocal;
|
||||
};
|
||||
|
||||
|
||||
|
@ -589,6 +589,11 @@ using namespace Firebird;
|
||||
%token <metaNamePtr> REGR_SXY
|
||||
%token <metaNamePtr> REGR_SYY
|
||||
|
||||
// tokens added for Firebird 3.0.4
|
||||
|
||||
%token <metaNamePtr> LOCALTIME
|
||||
%token <metaNamePtr> LOCALTIMESTAMP
|
||||
|
||||
// precedence declarations for expression evaluation
|
||||
|
||||
%left OR
|
||||
@ -3863,6 +3868,8 @@ keyword_or_column
|
||||
| UPDATING
|
||||
| VAR_SAMP
|
||||
| VAR_POP
|
||||
| LOCALTIME // added in FB 3.0.4
|
||||
| LOCALTIMESTAMP
|
||||
;
|
||||
|
||||
col_opt
|
||||
@ -6575,8 +6582,34 @@ datetime_value_expression
|
||||
|
||||
$$ = newNode<CurrentTimeNode>($2);
|
||||
}
|
||||
| LOCALTIME time_precision_opt
|
||||
{
|
||||
if (client_dialect < SQL_DIALECT_V6_TRANSITION)
|
||||
{
|
||||
ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-104) <<
|
||||
Arg::Gds(isc_sql_dialect_datatype_unsupport) << Arg::Num(client_dialect) <<
|
||||
Arg::Str("TIME"));
|
||||
}
|
||||
|
||||
if (db_dialect < SQL_DIALECT_V6_TRANSITION)
|
||||
{
|
||||
ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-104) <<
|
||||
Arg::Gds(isc_sql_db_dialect_dtype_unsupport) << Arg::Num(db_dialect) <<
|
||||
Arg::Str("TIME"));
|
||||
}
|
||||
|
||||
CurrentTimeNode* node = newNode<CurrentTimeNode>($2);
|
||||
node->dsqlLocal = true;
|
||||
$$ = node;
|
||||
}
|
||||
| CURRENT_TIMESTAMP timestamp_precision_opt
|
||||
{ $$ = newNode<CurrentTimeStampNode>($2); }
|
||||
| LOCALTIMESTAMP timestamp_precision_opt
|
||||
{
|
||||
CurrentTimeStampNode* node = newNode<CurrentTimeStampNode>($2);
|
||||
node->dsqlLocal = true;
|
||||
$$ = node;
|
||||
}
|
||||
;
|
||||
|
||||
%type <uintVal> time_precision_opt
|
||||
|
@ -241,5 +241,10 @@ static const struct
|
||||
{"subfunc", function},
|
||||
{"record_version2", byte_line},
|
||||
{"gen_id2", gen_id2}, // 210
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{"local_timestamp", byte_line},
|
||||
{"local_time", byte_line},
|
||||
{0, 0}
|
||||
};
|
||||
|
@ -407,4 +407,9 @@
|
||||
#define blr_record_version2 (unsigned char) 209
|
||||
#define blr_gen_id2 (unsigned char) 210 // NEXT VALUE FOR generator
|
||||
|
||||
// FB 3.0.4 specific BLR
|
||||
|
||||
#define blr_local_timestamp (unsigned char) 214
|
||||
#define blr_local_time (unsigned char) 215
|
||||
|
||||
#endif // JRD_BLR_H
|
||||
|
@ -250,6 +250,8 @@ static const TOK tokens[] =
|
||||
{LINGER, "LINGER", 2, true},
|
||||
{LIST, "LIST", 2, false},
|
||||
{LN, "LN", 2, false},
|
||||
{LOCALTIME, "LOCALTIME", 2, true},
|
||||
{LOCALTIMESTAMP, "LOCALTIMESTAMP", 2, true},
|
||||
{LOCK, "LOCK", 2, true},
|
||||
{LOG, "LOG", 2, false},
|
||||
{LOG10, "LOG10", 2, false},
|
||||
|
Loading…
Reference in New Issue
Block a user