mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-22 18:43:02 +01:00
Improvement #6788 - Extend EXTRACT to extract time zone strings.
This commit is contained in:
parent
8429c95795
commit
a02f0dea81
@ -372,6 +372,7 @@ Firebird 4.0
|
|||||||
SQL (1)
|
SQL (1)
|
||||||
SYSTEM (1)
|
SYSTEM (1)
|
||||||
TIES
|
TIES
|
||||||
|
TIMEZONE_NAME *
|
||||||
TOTALORDER *
|
TOTALORDER *
|
||||||
TRAPS *
|
TRAPS *
|
||||||
ZONE
|
ZONE
|
||||||
|
@ -296,6 +296,7 @@ select timestamp '2018-01-01 12:00 GMT' at local
|
|||||||
Two new `EXTRACT` expressions has been added:
|
Two new `EXTRACT` expressions has been added:
|
||||||
- `TIMEZONE_HOUR`: extracts the time zone hours displacement
|
- `TIMEZONE_HOUR`: extracts the time zone hours displacement
|
||||||
- `TIMEZONE_MINUTE`: extracts the time zone minutes displacement
|
- `TIMEZONE_MINUTE`: extracts the time zone minutes displacement
|
||||||
|
- `TIMEZONE_NAME`: extracts the time zone region or displacement string
|
||||||
|
|
||||||
#### Examples
|
#### Examples
|
||||||
|
|
||||||
@ -305,6 +306,9 @@ select extract(timezone_hour from current_time)
|
|||||||
|
|
||||||
select extract(timezone_minute from current_timestamp)
|
select extract(timezone_minute from current_timestamp)
|
||||||
from rdb$database;
|
from rdb$database;
|
||||||
|
|
||||||
|
select extract(timezone_name from current_timestamp)
|
||||||
|
from rdb$database;
|
||||||
```
|
```
|
||||||
|
|
||||||
### `LOCALTIME` expression
|
### `LOCALTIME` expression
|
||||||
|
@ -492,6 +492,7 @@ static const TOK tokens[] =
|
|||||||
{TOK_TIMEOUT, "TIMEOUT", true},
|
{TOK_TIMEOUT, "TIMEOUT", true},
|
||||||
{TOK_TIMEZONE_HOUR, "TIMEZONE_HOUR", false},
|
{TOK_TIMEZONE_HOUR, "TIMEZONE_HOUR", false},
|
||||||
{TOK_TIMEZONE_MINUTE, "TIMEZONE_MINUTE", false},
|
{TOK_TIMEZONE_MINUTE, "TIMEZONE_MINUTE", false},
|
||||||
|
{TOK_TIMEZONE_NAME, "TIMEZONE_NAME", true},
|
||||||
{TOK_TO, "TO", false},
|
{TOK_TO, "TO", false},
|
||||||
{TOK_TOTALORDER, "TOTALORDER", true},
|
{TOK_TOTALORDER, "TOTALORDER", true},
|
||||||
{TOK_TRAILING, "TRAILING", false},
|
{TOK_TRAILING, "TRAILING", false},
|
||||||
|
@ -5334,6 +5334,7 @@ ValueExprNode* ExtractNode::dsqlPass(DsqlCompilerScratch* dsqlScratch)
|
|||||||
|
|
||||||
case blr_extract_timezone_hour:
|
case blr_extract_timezone_hour:
|
||||||
case blr_extract_timezone_minute:
|
case blr_extract_timezone_minute:
|
||||||
|
case blr_extract_timezone_name:
|
||||||
if (!nodeIs<NullNode>(sub1) &&
|
if (!nodeIs<NullNode>(sub1) &&
|
||||||
!sub1->getDsqlDesc().isTime() &&
|
!sub1->getDsqlDesc().isTime() &&
|
||||||
!sub1->getDsqlDesc().isTimeStamp())
|
!sub1->getDsqlDesc().isTimeStamp())
|
||||||
@ -5385,6 +5386,10 @@ void ExtractNode::make(DsqlCompilerScratch* dsqlScratch, dsc* desc)
|
|||||||
desc->makeLong(ISC_TIME_SECONDS_PRECISION_SCALE + 3);
|
desc->makeLong(ISC_TIME_SECONDS_PRECISION_SCALE + 3);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case blr_extract_timezone_name:
|
||||||
|
desc->makeVarying(TimeZoneUtil::MAX_LEN, ttype_ascii);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
desc->makeShort(0);
|
desc->makeShort(0);
|
||||||
break;
|
break;
|
||||||
@ -5406,6 +5411,10 @@ void ExtractNode::getDesc(thread_db* /*tdbb*/, CompilerScratch* /*csb*/, dsc* de
|
|||||||
desc->makeLong(ISC_TIME_SECONDS_PRECISION_SCALE + 3);
|
desc->makeLong(ISC_TIME_SECONDS_PRECISION_SCALE + 3);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case blr_extract_timezone_name:
|
||||||
|
desc->makeVarying(TimeZoneUtil::MAX_LEN, ttype_ascii);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
desc->makeShort(0);
|
desc->makeShort(0);
|
||||||
break;
|
break;
|
||||||
@ -5484,6 +5493,7 @@ dsc* ExtractNode::execute(thread_db* tdbb, jrd_req* request) const
|
|||||||
|
|
||||||
case blr_extract_timezone_hour:
|
case blr_extract_timezone_hour:
|
||||||
case blr_extract_timezone_minute:
|
case blr_extract_timezone_minute:
|
||||||
|
case blr_extract_timezone_name:
|
||||||
{
|
{
|
||||||
ISC_TIME_TZ timeTz = TimeZoneUtil::timeToTimeTz(
|
ISC_TIME_TZ timeTz = TimeZoneUtil::timeToTimeTz(
|
||||||
*(ISC_TIME*) value->dsc_address, &EngineCallbacks::instance);
|
*(ISC_TIME*) value->dsc_address, &EngineCallbacks::instance);
|
||||||
@ -5512,6 +5522,7 @@ dsc* ExtractNode::execute(thread_db* tdbb, jrd_req* request) const
|
|||||||
|
|
||||||
case blr_extract_timezone_hour:
|
case blr_extract_timezone_hour:
|
||||||
case blr_extract_timezone_minute:
|
case blr_extract_timezone_minute:
|
||||||
|
case blr_extract_timezone_name:
|
||||||
timeStampTz.utc_timestamp.timestamp_date = TimeZoneUtil::TIME_TZ_BASE_DATE;
|
timeStampTz.utc_timestamp.timestamp_date = TimeZoneUtil::TIME_TZ_BASE_DATE;
|
||||||
timeStampTz.utc_timestamp.timestamp_time = ((ISC_TIME_TZ*) value->dsc_address)->utc_time;
|
timeStampTz.utc_timestamp.timestamp_time = ((ISC_TIME_TZ*) value->dsc_address)->utc_time;
|
||||||
timeStampTz.time_zone = ((ISC_TIME_TZ*) value->dsc_address)->time_zone;
|
timeStampTz.time_zone = ((ISC_TIME_TZ*) value->dsc_address)->time_zone;
|
||||||
@ -5532,6 +5543,7 @@ dsc* ExtractNode::execute(thread_db* tdbb, jrd_req* request) const
|
|||||||
case blr_extract_millisecond:
|
case blr_extract_millisecond:
|
||||||
case blr_extract_timezone_hour:
|
case blr_extract_timezone_hour:
|
||||||
case blr_extract_timezone_minute:
|
case blr_extract_timezone_minute:
|
||||||
|
case blr_extract_timezone_name:
|
||||||
ERR_post(Arg::Gds(isc_expression_eval_err) <<
|
ERR_post(Arg::Gds(isc_expression_eval_err) <<
|
||||||
Arg::Gds(isc_invalid_extractpart_date));
|
Arg::Gds(isc_invalid_extractpart_date));
|
||||||
break;
|
break;
|
||||||
@ -5546,6 +5558,7 @@ dsc* ExtractNode::execute(thread_db* tdbb, jrd_req* request) const
|
|||||||
{
|
{
|
||||||
case blr_extract_timezone_hour:
|
case blr_extract_timezone_hour:
|
||||||
case blr_extract_timezone_minute:
|
case blr_extract_timezone_minute:
|
||||||
|
case blr_extract_timezone_name:
|
||||||
{
|
{
|
||||||
dsc tempDsc;
|
dsc tempDsc;
|
||||||
tempDsc.makeTimestampTz(&timeStampTz);
|
tempDsc.makeTimestampTz(&timeStampTz);
|
||||||
@ -5563,6 +5576,7 @@ dsc* ExtractNode::execute(thread_db* tdbb, jrd_req* request) const
|
|||||||
{
|
{
|
||||||
case blr_extract_timezone_hour:
|
case blr_extract_timezone_hour:
|
||||||
case blr_extract_timezone_minute:
|
case blr_extract_timezone_minute:
|
||||||
|
case blr_extract_timezone_name:
|
||||||
timeStampTz = *(ISC_TIMESTAMP_TZ*) value->dsc_address;
|
timeStampTz = *(ISC_TIMESTAMP_TZ*) value->dsc_address;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -5578,28 +5592,41 @@ dsc* ExtractNode::execute(thread_db* tdbb, jrd_req* request) const
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (blrSubOp == blr_extract_timezone_hour || blrSubOp == blr_extract_timezone_minute)
|
|
||||||
{
|
|
||||||
int tzSign;
|
|
||||||
unsigned tzh, tzm;
|
|
||||||
TimeZoneUtil::extractOffset(timeStampTz, &tzSign, &tzh, &tzm);
|
|
||||||
|
|
||||||
switch (blrSubOp)
|
|
||||||
{
|
|
||||||
case blr_extract_timezone_hour:
|
|
||||||
*(SSHORT*) impure->vlu_desc.dsc_address = tzSign * int(tzh);
|
|
||||||
return &impure->vlu_desc;
|
|
||||||
|
|
||||||
case blr_extract_timezone_minute:
|
|
||||||
*(SSHORT*) impure->vlu_desc.dsc_address = tzSign * int(tzm);
|
|
||||||
return &impure->vlu_desc;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
USHORT part;
|
USHORT part;
|
||||||
|
|
||||||
switch (blrSubOp)
|
switch (blrSubOp)
|
||||||
{
|
{
|
||||||
|
case blr_extract_timezone_hour:
|
||||||
|
case blr_extract_timezone_minute:
|
||||||
|
{
|
||||||
|
int tzSign;
|
||||||
|
unsigned tzh, tzm;
|
||||||
|
TimeZoneUtil::extractOffset(timeStampTz, &tzSign, &tzh, &tzm);
|
||||||
|
|
||||||
|
switch (blrSubOp)
|
||||||
|
{
|
||||||
|
case blr_extract_timezone_hour:
|
||||||
|
*(SSHORT*) impure->vlu_desc.dsc_address = tzSign * int(tzh);
|
||||||
|
return &impure->vlu_desc;
|
||||||
|
|
||||||
|
case blr_extract_timezone_minute:
|
||||||
|
*(SSHORT*) impure->vlu_desc.dsc_address = tzSign * int(tzm);
|
||||||
|
return &impure->vlu_desc;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case blr_extract_timezone_name:
|
||||||
|
{
|
||||||
|
char timeZoneBuffer[TimeZoneUtil::MAX_SIZE];
|
||||||
|
const auto len = TimeZoneUtil::format(timeZoneBuffer, sizeof(timeZoneBuffer), timeStampTz.time_zone);
|
||||||
|
|
||||||
|
impure->vlu_desc.makeText(len, ttype_ascii, (UCHAR*) timeZoneBuffer);
|
||||||
|
EVL_make_value(tdbb, &impure->vlu_desc, impure);
|
||||||
|
return &impure->vlu_desc;
|
||||||
|
}
|
||||||
|
|
||||||
case blr_extract_year:
|
case blr_extract_year:
|
||||||
part = times.tm_year + 1900;
|
part = times.tm_year + 1900;
|
||||||
break;
|
break;
|
||||||
|
@ -8579,6 +8579,7 @@ timestamp_part
|
|||||||
| MILLISECOND { $$ = blr_extract_millisecond; }
|
| MILLISECOND { $$ = blr_extract_millisecond; }
|
||||||
| TIMEZONE_HOUR { $$ = blr_extract_timezone_hour; }
|
| TIMEZONE_HOUR { $$ = blr_extract_timezone_hour; }
|
||||||
| TIMEZONE_MINUTE { $$ = blr_extract_timezone_minute; }
|
| TIMEZONE_MINUTE { $$ = blr_extract_timezone_minute; }
|
||||||
|
| TIMEZONE_NAME { $$ = blr_extract_timezone_name; }
|
||||||
| WEEK { $$ = blr_extract_week; }
|
| WEEK { $$ = blr_extract_week; }
|
||||||
| WEEKDAY { $$ = blr_extract_weekday; }
|
| WEEKDAY { $$ = blr_extract_weekday; }
|
||||||
| YEARDAY { $$ = blr_extract_yearday; }
|
| YEARDAY { $$ = blr_extract_yearday; }
|
||||||
@ -9037,6 +9038,7 @@ non_reserved_word
|
|||||||
| SQL
|
| SQL
|
||||||
| SYSTEM
|
| SYSTEM
|
||||||
| TIES
|
| TIES
|
||||||
|
| TIMEZONE_NAME
|
||||||
| TOTALORDER
|
| TOTALORDER
|
||||||
| TRAPS
|
| TRAPS
|
||||||
| ZONE
|
| ZONE
|
||||||
|
@ -288,6 +288,7 @@
|
|||||||
#define blr_extract_week (unsigned char)9
|
#define blr_extract_week (unsigned char)9
|
||||||
#define blr_extract_timezone_hour (unsigned char)10
|
#define blr_extract_timezone_hour (unsigned char)10
|
||||||
#define blr_extract_timezone_minute (unsigned char)11
|
#define blr_extract_timezone_minute (unsigned char)11
|
||||||
|
#define blr_extract_timezone_name (unsigned char)12
|
||||||
|
|
||||||
#define blr_current_date (unsigned char)160
|
#define blr_current_date (unsigned char)160
|
||||||
#define blr_current_timestamp (unsigned char)161
|
#define blr_current_timestamp (unsigned char)161
|
||||||
|
Loading…
Reference in New Issue
Block a user