Skip to content

Commit

Permalink
Feature #5959 - Add support for QUARTER to EXTRACT, FIRST_DAY and LAS…
Browse files Browse the repository at this point in the history
…T_DAY [CORE5693].
  • Loading branch information
asfernandes committed May 4, 2023
1 parent 39fb998 commit 3fdc100
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 6 deletions.
4 changes: 2 additions & 2 deletions doc/sql.extensions/README.builtin_functions.txt
Original file line number Diff line number Diff line change
Expand Up @@ -514,7 +514,7 @@ Function:
date/timestamp value.

Format:
FIRST_DAY( OF { YEAR | MONTH | WEEK } FROM <date_or_timestamp> )
FIRST_DAY( OF { YEAR | QUARTER | MONTH | WEEK } FROM <date_or_timestamp> )

Notes:
1) The first day of the week is considered as Sunday, per the same rules of EXTRACT with WEEKDAY.
Expand Down Expand Up @@ -615,7 +615,7 @@ Function:
date/timestamp value.

Format:
LAST_DAY( OF { YEAR | MONTH | WEEK } FROM <date_or_timestamp> )
LAST_DAY( OF { YEAR | QUARTER | MONTH | WEEK } FROM <date_or_timestamp> )

Notes:
1) The last day of the week is considered as Saturday, per the same rules of EXTRACT with WEEKDAY.
Expand Down
1 change: 1 addition & 0 deletions src/common/keywords.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,7 @@ static const TOK tokens[] =
{TOK_PROTECTED, "PROTECTED", true},
{TOK_PUBLICATION, "PUBLICATION", false},
{TOK_QUANTIZE, "QUANTIZE", true},
{TOK_QUARTER, "QUARTER", true},
{TOK_RAND, "RAND", true},
{TOK_RANGE, "RANGE", true},
{TOK_RANK, "RANK", true},
Expand Down
5 changes: 5 additions & 0 deletions src/dsql/ExprNodes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5276,6 +5276,7 @@ ValueExprNode* ExtractNode::dsqlPass(DsqlCompilerScratch* dsqlScratch)
switch (blrSubOp)
{
case blr_extract_year:
case blr_extract_quarter:
case blr_extract_month:
case blr_extract_day:
case blr_extract_weekday:
Expand Down Expand Up @@ -5602,6 +5603,10 @@ dsc* ExtractNode::execute(thread_db* tdbb, Request* request) const
part = times.tm_year + 1900;
break;

case blr_extract_quarter:
part = times.tm_mon / 3 + 1;
break;

case blr_extract_month:
part = times.tm_mon + 1;
break;
Expand Down
8 changes: 8 additions & 0 deletions src/dsql/parse.y
Original file line number Diff line number Diff line change
Expand Up @@ -694,6 +694,10 @@ using namespace Firebird;
%token <metaNamePtr> UNICODE_CHAR
%token <metaNamePtr> UNICODE_VAL

// tokens added for Firebird 6.0

%token <metaNamePtr> QUARTER

// precedence declarations for expression evaluation

%left OR
Expand Down Expand Up @@ -8457,6 +8461,7 @@ encrypt_decrypt
%type <blrOp> of_first_last_day_part
of_first_last_day_part
: OF YEAR { $$ = blr_extract_year; }
| OF QUARTER { $$ = blr_extract_quarter; }
| OF MONTH { $$ = blr_extract_month; }
| OF WEEK { $$ = blr_extract_week; }
;
Expand Down Expand Up @@ -8702,6 +8707,7 @@ next_value_expression
%type <blrOp> timestamp_part
timestamp_part
: YEAR { $$ = blr_extract_year; }
| QUARTER { $$ = blr_extract_quarter; }
| MONTH { $$ = blr_extract_month; }
| DAY { $$ = blr_extract_day; }
| HOUR { $$ = blr_extract_hour; }
Expand Down Expand Up @@ -9184,6 +9190,8 @@ non_reserved_word
| TIMEZONE_NAME
| UNICODE_CHAR
| UNICODE_VAL
// added in FB 6.0

This comment has been minimized.

Copy link
@dyemanov

dyemanov May 5, 2023

Member

I would not mind adding this to v5, unless someone else disagrees.

| QUARTER
;

%%
1 change: 1 addition & 0 deletions src/include/firebird/impl/blr.h
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,7 @@
#define blr_extract_timezone_hour (unsigned char)10
#define blr_extract_timezone_minute (unsigned char)11
#define blr_extract_timezone_name (unsigned char)12
#define blr_extract_quarter (unsigned char)13

#define blr_current_date (unsigned char)160
#define blr_current_timestamp (unsigned char)161
Expand Down
35 changes: 31 additions & 4 deletions src/jrd/SysFunction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2668,16 +2668,33 @@ dsc* evlCharToUuid(thread_db* tdbb, const SysFunction* function, const NestValue
#define blr_extract_yearday (unsigned char)7
#define blr_extract_millisecond (unsigned char)8
#define blr_extract_week (unsigned char)9
#define blr_extract_timezone_hour (unsigned char)10
#define blr_extract_timezone_minute (unsigned char)11
#define blr_extract_timezone_name (unsigned char)12
#define blr_extract_quarter (unsigned char)13
*/

const char* extractParts[10] =
{
"YEAR", "MONTH", "DAY", "HOUR", "MINUTE", "SECOND", "WEEKDAY", "YEARDAY", "MILLISECOND", "WEEK"
const char* extractParts[] =
{
"YEAR",
"MONTH",
"DAY",
"HOUR",
"MINUTE",
"SECOND",
"WEEKDAY",
"YEARDAY",
"MILLISECOND",
"WEEK",
nullptr,
nullptr,
nullptr,
"QUARTER"
};

const char* getPartName(int n)
{
if (n < 0 || n >= FB_NELEM(extractParts))
if (n < 0 || n >= FB_NELEM(extractParts) || !extractParts[n])
return "Unknown";

return extractParts[n];
Expand Down Expand Up @@ -4117,6 +4134,7 @@ dsc* evlDateDiff(thread_db* tdbb, const SysFunction* function, const NestValueAr
switch (part)
{
case blr_extract_year:
case blr_extract_quarter:
case blr_extract_month:
case blr_extract_day:
case blr_extract_week:
Expand Down Expand Up @@ -4322,6 +4340,11 @@ dsc* evlFirstLastDay(thread_db* tdbb, const SysFunction* function, const NestVal
times.tm_mday = 1;
break;

case blr_extract_quarter:
times.tm_mon = times.tm_mon / 3 * 3;
times.tm_mday = 1;
break;

case blr_extract_week:
break;

Expand All @@ -4345,6 +4368,10 @@ dsc* evlFirstLastDay(thread_db* tdbb, const SysFunction* function, const NestVal
adjust = -1;
break;

case blr_extract_quarter:
times.tm_mon += 2;
// fall through

case blr_extract_month:
if (++times.tm_mon == 12)
{
Expand Down

0 comments on commit 3fdc100

Please sign in to comment.