Skip to content

Commit

Permalink
Improvement CORE-5853 - Forward-compatible expressions LOCALTIME and …
Browse files Browse the repository at this point in the history
…LOCALTIMESTAMP.
  • Loading branch information
asfernandes committed Jul 11, 2018
1 parent 4bac379 commit 15e25b3
Show file tree
Hide file tree
Showing 7 changed files with 84 additions and 10 deletions.
13 changes: 13 additions & 0 deletions doc/README.time_zone_forward_compatibility.md
Original file line number Diff line number Diff line change
@@ -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.
28 changes: 20 additions & 8 deletions src/dsql/ExprNodes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand All @@ -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
{
Expand Down Expand Up @@ -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();

Expand All @@ -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
{
Expand Down
8 changes: 6 additions & 2 deletions src/dsql/ExprNodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
}

Expand All @@ -359,6 +360,7 @@ class CurrentTimeNode : public TypedNode<ValueExprNode, ExprNode::TYPE_CURRENT_T

public:
unsigned precision;
bool dsqlLocal;
};


Expand All @@ -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)
{
}

Expand All @@ -386,6 +389,7 @@ class CurrentTimeStampNode : public TypedNode<ValueExprNode, ExprNode::TYPE_CURR

public:
unsigned precision;
bool dsqlLocal;
};


Expand Down
33 changes: 33 additions & 0 deletions src/dsql/parse.y
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -3863,6 +3868,8 @@ keyword_or_column
| UPDATING
| VAR_SAMP
| VAR_POP
| LOCALTIME // added in FB 3.0.4
| LOCALTIMESTAMP
;

col_opt
Expand Down Expand Up @@ -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
Expand Down
5 changes: 5 additions & 0 deletions src/jrd/blp.h
Original file line number Diff line number Diff line change
Expand Up @@ -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}
};
5 changes: 5 additions & 0 deletions src/jrd/blr.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
2 changes: 2 additions & 0 deletions src/yvalve/keywords.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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},
Expand Down

0 comments on commit 15e25b3

Please sign in to comment.