-
Notifications
You must be signed in to change notification settings - Fork 92
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Reimplement datediff and dateadd in c to improve performance #1998
Reimplement datediff and dateadd in c to improve performance #1998
Conversation
Signed-off-by: Jake Owen <[email protected]>
Signed-off-by: Jake Owen <[email protected]>
Signed-off-by: Jake Owen <[email protected]>
Signed-off-by: Jake Owen <[email protected]>
Signed-off-by: Jake Owen <[email protected]>
Signed-off-by: Jake Owen <[email protected]>
Signed-off-by: Jake Owen <[email protected]>
Signed-off-by: Jake Owen <[email protected]>
AS | ||
$body$ | ||
BEGIN | ||
return sys.datediff_internal(datepart, startdate::TIMESTAMP, enddate::TIMESTAMP); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does a explicit type change happen in here ?
Signed-off-by: Jake Owen <[email protected]>
DECLARE | ||
timezone INTEGER; | ||
BEGIN | ||
timezone = sys.babelfish_get_datetimeoffset_tzoffset(startdate)::INTEGER * 2; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why this part is not moved into c impl ?
break; | ||
} | ||
} else { | ||
elog(ERROR, "the datepart %s is not supported by function dateadd for datatype datetimeoffset", lowunits); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The original msg on the script impl is :
RAISE EXCEPTION '"%" is not a recognized dateadd option.', datepart;
Signed-off-by: Jake Owen <[email protected]>
interval = (Interval *) DirectFunctionCall7(make_interval, 0, 0, 0, 0, 0, 0, Float8GetDatum((float) num * 0.000000001)); | ||
break; | ||
default: | ||
elog(ERROR, "the datepart %s is not supported by function dateadd for datatype datetimeoffset", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as the error msg is different
and could you combine too err out places together
AS | ||
$body$ | ||
BEGIN | ||
return sys.datediff_internal(datepart, startdate::TIMESTAMP, enddate::TIMESTAMP); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The original impl, the datediff internal script version , it's passing startdate and enddate as PG_CATALOG.date into datediff_internal.
This implement, just did an extra explicit type conversion in here, and I don't understand why it should do that.
case DTK_YEAR: | ||
if(dttype == TIME) { | ||
elog(ERROR, "the datepart %s is not supported by date function dateadd for data type time", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The original err msg should be :
The datepart % is not supported by date function dateadd for data type date.{datepart}
slight different from this implement
} | ||
} else { | ||
elog(ERROR, "the datepart %s is not supported by date function dateadd for data type %s", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And can we make the errmsg in the same code appear place , not repeat so many times
ereport(ERROR, | ||
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE), | ||
errmsg("data out of range for %s"), datetypeName(dttype))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The original sql script the err msg should be :
RAISE EXCEPTION '''%'' is not a recognized dateadd option.', datepart;
|
||
~~ERROR (Message: integer out of range)~~ | ||
~~ERROR (Message: The datediff function resulted in an overflow. The number of dateparts separating two date/time instances is too large. Try to use datediff with a less precise datepart)~~ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is that expected ?
Would you also mention how much percentage performance gain we have for this c impl ? |
break; | ||
default: | ||
elog(ERROR, "the datepart \"%s\" is not supported by function datediff for datatype date", lowunits); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pls also make sure this error msg is the same as previous
|
||
if(overflow) { | ||
elog(ERROR, "The datediff function resulted in an overflow. The number of dateparts separating two date/time instances is too large. Try to use datediff with a less precise datepart"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where is the error msg comes from ?
bool overflow = false; | ||
|
||
ok1 = timestamp2tm(timestamp1, NULL, tm1, &fsec1, NULL, NULL); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we make a better name for ok1, ok2 ?
int32 microsecdiff; | ||
struct pg_tm tt1, | ||
*tm1 = &tt1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To define a tt1, and make a pointer to tt1, looks weired, do we have a better way to define those ? And also, pls give a meaningful names instead of tm1, tm2 .
Signed-off-by: Jake Owen <[email protected]>
Signed-off-by: Jake Owen <[email protected]>
Signed-off-by: Jake Owen <[email protected]>
Signed-off-by: Jake Owen <[email protected]>
Signed-off-by: Jake Owen <[email protected]>
Signed-off-by: Jake Owen <[email protected]>
Signed-off-by: Jake Owen <[email protected]>
Signed-off-by: Jake Owen <[email protected]>
Signed-off-by: Jake Owen <[email protected]>
Signed-off-by: Jake Owen <[email protected]>
Signed-off-by: Jake Owen <[email protected]>
} | ||
|
||
if(!validDateDiff) { | ||
elog(ERROR, "The datepart %s is not a recognized datediff option.", lowunits); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the original error didn't have 'The'
RAISE EXCEPTION '"%" is not a recognized datediff option.', datepart;
} | ||
if(overflow) { | ||
elog(ERROR, "The datediff function resulted in an overflow. The number of dateparts separating two date/time instances is too large. Try to use datediff with a less precise datepart"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And also , we should use ereport to error out in c impl, and to make sure the transaction behavior is the same compare to sql server for this error msg
|
||
if(!validDateDiff) { | ||
elog(ERROR, "The datepart %s is not a recognized datediff option.", lowunits); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should add test cases for each error out and make sure transaction behavior is the same as sql server ( when error out, shouldn't abort the current transaction )
case DTK_MICROSEC: | ||
if(dttype == SMALLDATETIME || dttype == DATETIME || dttype == DATE) { | ||
elog(ERROR, "The datepart %s is not supported by date function dateadd for data type %s.", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would you reformat this part of code, to make sure all this error out in the same place and the err msg is also not the same cause it has an additional 'The' in the msg body.
Signed-off-by: Jake Owen <[email protected]>
Signed-off-by: Jake Owen <[email protected]>
Signed-off-by: Jake Owen <[email protected]>
Signed-off-by: Jake Owen <[email protected]>
ereport(ERROR, | ||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE), | ||
errmsg("The datepart %s is not supported by date function %s for data type %s.", lowunits, "dateadd", "date"))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Those are all very similar err msg :
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("The datepart %s is not supported by date function %s for data type %s.", lowunits, "dateadd", "date")));
}
please make sure we don't repeat this code everywhere
@@ -371,13 +371,6 @@ datetime | |||
2016-12-27 00:25:29.0 | |||
~~END~~ | |||
|
|||
-- out of range | |||
select dateadd(year, 150, cast('9900-12-26 23:29:29' as datetime)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why we delete this test case ?
Signed-off-by: Jake Owen <[email protected]>
Signed-off-by: Jake Owen <[email protected]>
Signed-off-by: Jake Owen <[email protected]>
d5d1d05
into
babelfish-for-postgresql:BABEL_3_X_DEV
…sh-for-postgresql#1998) This change reimplements the datediff, datediff_big, and dateadd functions in C to improve performance by 65% compared to the original implementation. Task: BABEL-4496 Signed-off-by: Jake Owen <[email protected]>
…sh-for-postgresql#1998) This change reimplements the datediff, datediff_big, and dateadd functions in C to improve performance by 65% compared to the original implementation. Task: BABEL-4496 Signed-off-by: Jake Owen <[email protected]>
Description
This change reimplements the datediff, datediff_big, and dateadd functions in C to improve performance by 65% compared to the original implementation.
Issues Resolved
Task: Babel-4496
Test Scenarios Covered
Minor version upgrade tests -
Major version upgrade tests -
Performance tests -
Tooling impact -
None
Client tests -
None
Check List
By submitting this pull request, I confirm that my contribution is under the terms of the Apache 2.0 and PostgreSQL licenses, and grant any person obtaining a copy of the contribution permission to relicense all or a portion of my contribution to the PostgreSQL License solely to contribute all or a portion of my contribution to the PostgreSQL open source project.
For more information on following Developer Certificate of Origin and signing off your commits, please check here.