[ 
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)

Reply via email to