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
[CALCITE-6313] Add POWER function for PostgreSQL #3762
Conversation
normanj-bitquill
commented
Apr 16, 2024
- The existing power function is moved to all non PostgreSQL libraries
- The new power function is only for PostgreSQL
- The new function returns a decimal if any argument is a decimal
In order to separate the POWER function for PostgreSQL and non-PostgreSQL dialects, the POWER function was moved to the Is there a more clean way to separate the POWER function so that the PostgreSQL implementation is able to return Decimal values in some cases? |
core/src/main/java/org/apache/calcite/sql/fun/SqlLibraryOperators.java
Outdated
Show resolved
Hide resolved
core/src/main/java/org/apache/calcite/sql/type/ReturnTypes.java
Outdated
Show resolved
Hide resolved
@@ -559,15 +558,6 @@ static SqlOperatorTable operatorTableFor(SqlLibrary library) { | |||
} | |||
|
|||
@Test void testArithmeticOperatorsFails() { | |||
expr("^power(2,'abc')^") |
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 delete these tests? What happens to them? They look like good tests.
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 POWER
function is no longer available in SqlStdOperatorTable
. The implementation to use depends on which library is active since PostgreSQL can use a different return type.
This test fails as it was since POWER
is not in StdOperatorTable
. Is there a way to specify the library to use for the test?
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.
Yes, see the operatorTableFor() function.
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.
Updated.
core/src/test/resources/sql/misc.iq
Outdated
@@ -2301,17 +2301,6 @@ where false; | |||
|
|||
!ok | |||
|
|||
# [CALCITE-2447] POWER, ATAN2 functions fail with NoSuchMethodException |
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 delete this test?
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 POWER
function is no longer available in SqlStdOperatorTable
. Is there any way of specifying a library to use here?
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 don't think there is, but the question is whether there should be a standard power function.
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 found where the ChainedSqlOperatorTable
is created and was able to give the library operator table precedence over the standard operator table.
@@ -2006,7 +2006,7 @@ void checkPeriodPredicate(Checker checker) { | |||
expr("1-2+3*4/5/6-7") | |||
.ok("(((1 - 2) + (((3 * 4) / 5) / 6)) - 7)"); | |||
expr("power(2,3)") | |||
.ok("POWER(2, 3)"); | |||
.ok("`POWER`(2, 3)"); |
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.
these quotes look suspicious
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.
This will end up going through here:
https://github.com/apache/calcite/blob/main/core/src/main/java/org/apache/calcite/sql/SqlUtil.java#L393
and only look in SqlStdOperatorTable
for the function.
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.
Then it's related to my previous question: should there be a variant of this function in the standard operator table?
If not, I guess this is fine.
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 it possible to have a power function in the standard operator table and still have an override for PostgreSQL that is able to return a decimal in some cases?
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 don't know the answer to this question. But I know that Calcite can load multiple libraries, and I believe a function will be resolved by trying the libraries in order. I also am assuming that there is nothing special about the standard operator table. So if you load the postgres operator table first, perhaps the right POWER will be used?
A quick experiment should be able answer this question.
If this works, we should probably document that the right way to implement a dialect is to load the dialect specific operator table first.
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 found where the ChainedSqlOperatorTable
is created and was able to give the library operator table precedence over the standard operator table.
With this change, no changes are needed to existing tests.
857f16d
to
d2cdb89
Compare
In general, until the changes are approved I would recommend adding new commits instead of force-pushing. It makes it easier for reviewers to see what's new. Then you can squash when the PR is approved. |
@@ -117,8 +117,7 @@ private SqlOperatorTable create(ImmutableSet<SqlLibrary> librarySet) { | |||
SqlOperatorTable operatorTable = SqlOperatorTables.of(list); | |||
if (standard) { | |||
operatorTable = | |||
SqlOperatorTables.chain(SqlStdOperatorTable.instance(), | |||
operatorTable); | |||
SqlOperatorTables.chain(operatorTable, SqlStdOperatorTable.instance()); |
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.
This may cause problems for other people. Ideally you want to do this just for your tests.
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.
Understood. I'll take a look.
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.
This has been fixed. The only changes needed now are in the unit test itself. I setup the operator table there such that PostgreSQL is first.
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 second commit should have a descriptive name, e.g., "only update loading library order for tests." But that is moot now, since I think this is ready for merging, so the next step is to squash the commits. We can't merge this until 1.37 is released, though.
bd25b70
to
a0fff43
Compare
* The existing power function is moved to all non PostgreSQL libraries * The new power function is only for PostgreSQL * The new function returns a decimal if any argument is a decimal
a0fff43
to
db336c2
Compare
Quality Gate passedIssues Measures |