You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@calcite.apache.org by "Julian Hyde (JIRA)" <ji...@apache.org> on 2016/10/25 20:59:58 UTC

[jira] [Comment Edited] (CALCITE-1467) SqlFunctions power

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