[
https://issues.apache.org/jira/browse/CALCITE-1467?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15606453#comment-15606453
]
Julian Hyde edited comment on CALCITE-1467 at 10/25/16 8:59 PM:
----------------------------------------------------------------
Ah, DECIMAL. If I recall correctly, we haven't finished our support for the
{{DECIMAL}} data type. (I have just logged CALCITE-1468 to track.)
Note that {{SqlOperatorBaseTest}} has
{code}
/**
* Whether DECIMAL type is implemented.
*/
public static final boolean DECIMAL = false;
{code}
and 9 occurrences of
{code}
if (!DECIMAL) {
return;
}
{code}
There are two obvious ways to represent {{DECIMAL}} in the runtime: as a
{{BigDecimal}} value, and as a shifted integer. For the latter, if you wanted
to represent 1234.56 as a {{DECIMAL(6, 2)}}, you would use the value 123456 and
remember to divide by 100 on the way out. Shifted integers are more complicated
but more efficient (because we can operate in terms of primitive values rather
than Java objects).
Suppose we wanted to implement the {{POWER}} function for {{DECIMAL}} values.
We could implement it in terms of {{power(long, long)}}, with some extra
operations to adding and multiply by constants. So we would not need a
{{power(BigDecimal, BigDecimal)}}. Other built-in operators could be handled
similarly. For user-defined functions we would use BigDecimal for parameters
and return values (and, yes, pay a performance penalty).
was (Author: julianhyde):
Ah, DECIMAL. If I recall correctly, we haven't finished our support for the
DECIMAL data type.
Note that {{SqlOperatorBaseTest}} has
{code}
/**
* Whether DECIMAL type is implemented.
*/
public static final boolean DECIMAL = false;
{code}
and 9 occurrences of
{code}
if (!DECIMAL) {
return;
}
{code}
There are two obvious ways to represent {{DECIMAL}} in the runtime: as a
{{BigDecimal}} value, and as a shifted integer. For the latter, if you wanted
to represent 1234.56 as a {{DECIMAL(6, 2)}}, you would use the value 123456 and
remember to divide by 100 on the way out. Shifted integers are more complicated
but more efficient (because we can operate in terms of primitive values rather
than Java objects).
Suppose we wanted to implement the {{POWER}} function for {{DECIMAL}} values.
We could implement it in terms of {{power(long, long)}}, with some extra
operations to adding and multiply by constants. So we would not need a
{{power(BigDecimal, BigDecimal)}}. Other built-in operators could be handled
similarly. For user-defined functions we would use BigDecimal for parameters
and return values (and, yes, pay a performance penalty).
> SqlFunctions power
> ------------------
>
> Key: CALCITE-1467
> URL: https://issues.apache.org/jira/browse/CALCITE-1467
> Project: Calcite
> Issue Type: Bug
> Reporter: Anton Solovev
> Assignee: Julian Hyde
>
> there are only 3 power methods:
> double power(double b0, double b1)
> double power(long b0, long b1)
> double power(long b0, BigDecimal b1)
> in org.apache.calcite.runtime.SqlFunctions
> but methods are unsuitable with double power(double b0, BigDecimal b1)
> {code}
> @Test public void testPowerFuncWithDec() {
> tester.setFor(SqlStdOperatorTable.POWER);
> tester.checkScalarApprox("power(cast(10 as double), cast(2 as
> decimal))", "DOUBLE NOT NULL", 100d, 0);
> }
> {code}
> got exception:
> {noformat}
> java.lang.RuntimeException: java.sql.SQLException: Error while executing SQL
> "values (power(cast(10 as double), cast(2 as decimal)))": while resolving
> method 'power[double, class java.math.BigDecimal]' in class class
> org.apache.calcite.runtime.SqlFunctions
> at com.google.common.base.Throwables.propagate(Throwables.java:160)
> at
> org.apache.calcite.sql.test.SqlOperatorBaseTest$TesterImpl.check(SqlOperatorBaseTest.java:6091)
> at
> org.apache.calcite.sql.test.SqlTesterImpl.check(SqlTesterImpl.java:434)
> at
> org.apache.calcite.sql.test.SqlTesterImpl.checkScalarApprox(SqlTesterImpl.java:388)
> at
> org.apache.calcite.sql.test.SqlOperatorBaseTest.testPowerFuncWithDec(SqlOperatorBaseTest.java:3686)
> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> at
> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
> at
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
> at java.lang.reflect.Method.invoke(Method.java:498)
> at
> org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
> at
> org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
> at
> org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
> at
> org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
> at
> org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
> at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
> at
> org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
> at
> org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
> at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
> at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
> at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
> at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
> at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
> at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
> at org.junit.runners.Suite.runChild(Suite.java:128)
> at org.junit.runners.Suite.runChild(Suite.java:27)
> at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
> at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
> at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
> at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
> at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
> at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
> at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
> at
> com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:117)
> at
> com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:42)
> at
> com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:262)
> at
> com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:84)
> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> at
> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
> at
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
> at java.lang.reflect.Method.invoke(Method.java:498)
> at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
> Caused by: java.sql.SQLException: Error while executing SQL "values
> (power(cast(10 as double), cast(2 as decimal)))": while resolving method
> 'power[double, class java.math.BigDecimal]' in class class
> org.apache.calcite.runtime.SqlFunctions
> at org.apache.calcite.avatica.Helper.createException(Helper.java:56)
> at org.apache.calcite.avatica.Helper.createException(Helper.java:41)
> at
> org.apache.calcite.avatica.AvaticaStatement.executeInternal(AvaticaStatement.java:147)
> at
> org.apache.calcite.avatica.AvaticaStatement.executeQuery(AvaticaStatement.java:208)
> at
> org.apache.calcite.sql.test.SqlOperatorBaseTest$TesterImpl.check(SqlOperatorBaseTest.java:6088)
> ... 39 more
> Caused by: java.lang.RuntimeException: while resolving method 'power[double,
> class java.math.BigDecimal]' in class class
> org.apache.calcite.runtime.SqlFunctions
> at org.apache.calcite.linq4j.tree.Types.lookupMethod(Types.java:346)
> at org.apache.calcite.linq4j.tree.Expressions.call(Expressions.java:442)
> at
> org.apache.calcite.adapter.enumerable.RexImpTable$MethodNameImplementor.implement(RexImpTable.java:1612)
> at
> org.apache.calcite.adapter.enumerable.RexImpTable.implementCall(RexImpTable.java:855)
> at
> org.apache.calcite.adapter.enumerable.RexImpTable.implementNullSemantics(RexImpTable.java:843)
> at
> org.apache.calcite.adapter.enumerable.RexImpTable.implementNullSemantics0(RexImpTable.java:756)
> at
> org.apache.calcite.adapter.enumerable.RexImpTable.access$900(RexImpTable.java:181)
> at
> org.apache.calcite.adapter.enumerable.RexImpTable$3.implement(RexImpTable.java:411)
> at
> org.apache.calcite.adapter.enumerable.RexToLixTranslator.translateCall(RexToLixTranslator.java:565)
> at
> org.apache.calcite.adapter.enumerable.RexToLixTranslator.translate0(RexToLixTranslator.java:537)
> at
> org.apache.calcite.adapter.enumerable.RexToLixTranslator.translate(RexToLixTranslator.java:222)
> at
> org.apache.calcite.adapter.enumerable.RexToLixTranslator.translate0(RexToLixTranslator.java:502)
> at
> org.apache.calcite.adapter.enumerable.RexToLixTranslator.translate(RexToLixTranslator.java:222)
> at
> org.apache.calcite.adapter.enumerable.RexToLixTranslator.translate(RexToLixTranslator.java:217)
> at
> org.apache.calcite.adapter.enumerable.RexToLixTranslator.translateList(RexToLixTranslator.java:741)
> at
> org.apache.calcite.adapter.enumerable.RexToLixTranslator.translateProjects(RexToLixTranslator.java:194)
> at
> org.apache.calcite.adapter.enumerable.EnumerableCalc.implement(EnumerableCalc.java:189)
> at
> org.apache.calcite.adapter.enumerable.EnumerableRelImplementor.implementRoot(EnumerableRelImplementor.java:102)
> at
> org.apache.calcite.adapter.enumerable.EnumerableInterpretable.toBindable(EnumerableInterpretable.java:92)
> at
> org.apache.calcite.prepare.CalcitePrepareImpl$CalcitePreparingStmt.implement(CalcitePrepareImpl.java:1200)
> at org.apache.calcite.prepare.Prepare.prepareSql(Prepare.java:297)
> at org.apache.calcite.prepare.Prepare.prepareSql(Prepare.java:194)
> at
> org.apache.calcite.prepare.CalcitePrepareImpl.prepare2_(CalcitePrepareImpl.java:735)
> at
> org.apache.calcite.prepare.CalcitePrepareImpl.prepare_(CalcitePrepareImpl.java:598)
> at
> org.apache.calcite.prepare.CalcitePrepareImpl.prepareSql(CalcitePrepareImpl.java:568)
> at
> org.apache.calcite.jdbc.CalciteConnectionImpl.parseQuery(CalciteConnectionImpl.java:215)
> at
> org.apache.calcite.jdbc.CalciteMetaImpl.prepareAndExecute(CalciteMetaImpl.java:594)
> at
> org.apache.calcite.avatica.AvaticaConnection.prepareAndExecuteInternal(AvaticaConnection.java:613)
> at
> org.apache.calcite.avatica.AvaticaStatement.executeInternal(AvaticaStatement.java:139)
> ... 41 more
> Caused by: java.lang.NoSuchMethodException:
> org.apache.calcite.runtime.SqlFunctions.power(double, java.math.BigDecimal)
> at java.lang.Class.getMethod(Class.java:1786)
> at org.apache.calcite.linq4j.tree.Types.lookupMethod(Types.java:337)
> ... 69 more
> {noformat}
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)