[jira] [Created] (CALCITE-6245) Permute operands of SqlCall everywhere when validating and Converting to Rel
Feng Jin created CALCITE-6245: - Summary: Permute operands of SqlCall everywhere when validating and Converting to Rel Key: CALCITE-6245 URL: https://issues.apache.org/jira/browse/CALCITE-6245 Project: Calcite Issue Type: Bug Reporter: Feng Jin Currently, when using named parameters, there may be some issues due to the incorrect expansion of named parameters during validation. Specifically, several unit tests can be added to reproduce this. add a test case org.apache.calcite.test.UdfTest#testScalarFunctionWithParameter {code:java} @Test void testScalarFunctionWithParameter() { final String sql = "select \"adhoc\".my_det_plus(X => \"deptno\", Y => 100) as p\n" + "from \"adhoc\".EMPLOYEES"; final AtomicInteger c = Smalls.MyDeterministicPlusFunction.INSTANCE_COUNT.get(); final int before = c.get(); withUdf().query(sql).returnsUnordered("P=110", "P=120", "P=110", "P=110"); final int after = c.get(); assertThat(after, is(before + 1)); } {code} And we will get the following error: {code:shell} java.sql.SQLException: Error while executing SQL "select "adhoc".my_det_plus(x => "deptno", y => 100) as p from "adhoc".EMPLOYEES": At line 1, column 28: Column 'X' not found in any table 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:164) at org.apache.calcite.avatica.AvaticaStatement.executeQuery(AvaticaStatement.java:228) at org.apache.calcite.test.CalciteAssert.assertQuery(CalciteAssert.java:543) at org.apache.calcite.test.CalciteAssert$AssertQuery.lambda$returns$1(CalciteAssert.java:1455) at org.apache.calcite.test.CalciteAssert$AssertQuery.withConnection(CalciteAssert.java:1394) at org.apache.calcite.test.CalciteAssert$AssertQuery.returns(CalciteAssert.java:1453) at org.apache.calcite.test.CalciteAssert$AssertQuery.returns(CalciteAssert.java:1443) at org.apache.calcite.test.CalciteAssert$AssertQuery.returnsUnordered(CalciteAssert.java:1465) at org.apache.calcite.test.UdfTest.testScalarFunctionWithParameter(UdfTest.java:227) {code} another test case: org.apache.calcite.test.UdfTest#testAggFunctionWithParameter {code:java} @Test void testAggFunctionWithParameter() { final String empDept = JdbcTest.EmpDeptTableFactory.class.getName(); final String sum = Smalls.MyStaticSumFunction.class.getName(); final String sum2 = Smalls.MySumFunction.class.getName(); final CalciteAssert.AssertThat with = CalciteAssert.model("{\n" + " version: '1.0',\n" + " schemas: [\n" + " {\n" + " name: 'adhoc',\n" + " tables: [\n" + " {\n" + " name: 'EMPLOYEES',\n" + " type: 'custom',\n" + " factory: '" + empDept + "',\n" + " operand: {'foo': true, 'bar': 345}\n" + " }\n" + " ],\n" + " functions: [\n" + " {\n" + " name: 'MY_SUM',\n" + " className: '" + sum + "'\n" + " },\n" + " {\n" + " name: 'MY_SUM2',\n" + " className: '" + sum2 + "'\n" + " }\n" + " ]\n" + " }\n" + " ]\n" + "}") .withDefaultSchema("adhoc") .with("caseSensitive", false); with.withDefaultSchema(null) .query( "select \"adhoc\".my_sum(arg1 => \"deptno\") as p from \"adhoc\".EMPLOYEES\n") .returns("P=50\n"); } {code} And we will get the following error: {code:shell} // Some comments here Caused by: org.apache.calcite.runtime.CalciteContextException: From line 1, column 23 to line 1, column 26: Column 'ARG1' not found in any table at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:423) at org.apache.calcite.runtime.Resources$ExInstWithCause.ex(Resources.java:505) at org.apache.calcite.sql.SqlUtil.newContextException(SqlUtil.java:945) at org.apache.calcite.sql.SqlUtil.newContextException(SqlUtil.java:930) at org.apache.calcite.sql.validate.SqlValidatorImpl.newValidationError(SqlValidatorImpl.java:5470) at
[jira] [Updated] (CALCITE-6238) Exception while evaluating ROUND function
[ https://issues.apache.org/jira/browse/CALCITE-6238?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ] ASF GitHub Bot updated CALCITE-6238: Labels: pull-request-available (was: ) > Exception while evaluating ROUND function > - > > Key: CALCITE-6238 > URL: https://issues.apache.org/jira/browse/CALCITE-6238 > Project: Calcite > Issue Type: Bug > Components: core >Affects Versions: 1.36.0 >Reporter: Mihai Budiu >Priority: Minor > Labels: pull-request-available > > The following test in CalciteSqlOperatorTest: > {code:java} > @Test void testRoundFunc() { > final SqlOperatorFixture f = fixture(); > f.checkScalar("round(42, CAST(2 as BIGINT))", 42, "INTEGER NOT NULL"); > } > {code} > causes an exception; here is the relevant part of the stack trace: > {code} > java.sql.SQLException: Error while executing SQL "values (round(42, CAST(2 as > BIGINT)))": Unable to implement EnumerableCalc(expr#0=[{inputs}], > expr#1=[42], expr#2=[2:BIGINT], expr#3=[ROUND($t1, $t2)], EXPR$0=[$t3]): > rowcount = 1.0, cumulative cost = {2.0 rows, 6.0 cpu, 0.0 io}, id = 20 > EnumerableValues(tuples=[[{ 0 }]]): rowcount = 1.0, cumulative cost = {1.0 > rows, 1.0 cpu, 0.0 io}, id = 13 > ... > Suppressed: java.lang.RuntimeException: while resolving method > 'sround[int, long]' in class class org.apache.calcite.runtime.SqlFunctions > at > org.apache.calcite.adapter.enumerable.EnumUtils.call(EnumUtils.java:679) > at > org.apache.calcite.adapter.enumerable.RexImpTable$MethodImplementor.call(RexImpTable.java:2818) > at > org.apache.calcite.adapter.enumerable.RexImpTable$MethodImplementor.implementSafe(RexImpTable.java:2799) > at > org.apache.calcite.adapter.enumerable.RexImpTable$AbstractRexCallImplementor.genValueStatement(RexImpTable.java:3857) > at > org.apache.calcite.adapter.enumerable.RexImpTable$AbstractRexCallImplementor.implement(RexImpTable.java:3819) > {code} > And indeed, SqlFunctions does not have a function sround with this signature. > There are several possible fixes: > - reject calls to ROUND that have a BIGINT second argument > - have the validator insert an implicit cast for the second argument to > INTEGER > - implement more Java versions of the SROUND function in SqlFunctions. > Probably many more. > Which one of these is the right one? I suspect this problem applies to other > SQL functions as well. -- This message was sent by Atlassian Jira (v8.20.10#820010)
[jira] [Commented] (CALCITE-6240) Remove ROW_NUMBER if OVER PARTITION BY unique key
[ https://issues.apache.org/jira/browse/CALCITE-6240?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=17814506#comment-17814506 ] Julian Hyde commented on CALCITE-6240: -- Also related to CALCITE-5406, because {code:java} SELECT DISTINCT ON (x) x, y, z FROM t{code} is equivalent to {code:java} SELECT x, y, z FROM ( SELECT x, y, z, ROW_NUMBER() OVER (PARTITION BY x) AS r FROM t) WHERE r = 1{code} > Remove ROW_NUMBER if OVER PARTITION BY unique key > - > > Key: CALCITE-6240 > URL: https://issues.apache.org/jira/browse/CALCITE-6240 > Project: Calcite > Issue Type: Improvement > Components: core >Reporter: Jiajun Xie >Assignee: Jiajun Xie >Priority: Minor > > The SQL Only have ROW_NUMBER function. > {code:java} > SELECT empno, ename FROM ( > SELECT ROW_NUMBER() OVER (PARTITION BY empno) rn, empno, ename > FROM emp > ) WHERE rn <= 5{code} > to > {code:java} > SELECT empno, ename FROM emp{code} > > If we know every partition count is less than filter count, we can optimize > {code:java} > SELECT deptno, ename FROM ( > SELECT ROW_NUMBER() OVER (PARTITION BY deptno) rn, deptno, ename > FROM emp > ) WHERE rn <= N > -- Statistic let we know every department count is less than N{code} > to > {code:java} > SELECT empno, ename FROM emp {code} -- This message was sent by Atlassian Jira (v8.20.10#820010)
[jira] [Commented] (CALCITE-6237) Using fractions in LOG function does not return correct results
[ https://issues.apache.org/jira/browse/CALCITE-6237?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=17814503#comment-17814503 ] Julian Hyde commented on CALCITE-6237: -- +1 [~asolimando] [~caicancai], Often the hardest problem is to describe the problem correctly. This is why we do a lot of our work in jira (and why creating a PR too early can create confusion). You will notice that I asked a question above, "Do you understand why I closed CALCITE-6232 as invalid?", and also "Why would you expect fractions to have a special behavior in Log functions?" in CALCITE-6232. Those questions are my invitation to start a discussion. The main thing I think you can do better is to engage in discussion. > Using fractions in LOG function does not return correct results > --- > > Key: CALCITE-6237 > URL: https://issues.apache.org/jira/browse/CALCITE-6237 > Project: Calcite > Issue Type: Bug > Components: core >Affects Versions: 1.36.0 >Reporter: Caican Cai >Priority: Major > Fix For: 1.37.0 > > > {code:java} > mysql> SELECT LOG10(2/3) AS result; > +-+ > | result | > +-+ > | -0.1760912594899757 | > +-+ > 1 row in set (0.00 sec) > mysql> SELECT LOG2(0) AS result; > ++ > | result | > ++ > | NULL | > ++ > 1 row in set, 1 warning (0.01 sec) > mysql> SELECT LOG2(2/3) AS result; > +-+ > | result | > +-+ > | -0.5849625021638512 | > +-+ > 1 row in set (0.00 sec) > {code} > When using Calcite's Log2 and Log10 functions, if the parameter is a > fraction, the integer digits will be retained by default. I think this is > wrong. Several decimal places (such as tens) should be retained by default. -- This message was sent by Atlassian Jira (v8.20.10#820010)
[jira] [Comment Edited] (CALCITE-6240) Remove ROW_NUMBER if OVER PARTITION BY unique key
[ https://issues.apache.org/jira/browse/CALCITE-6240?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=17814498#comment-17814498 ] Julian Hyde edited comment on CALCITE-6240 at 2/5/24 8:02 PM: -- Regarding the first rewrite - converting ROW_NUMBER on a unique key to 1. Can this behavior be described by an algebraic property? E.g. ROW_NUMBER applied to one row always returns 1? The second rewrite is also desirable, but I think it will require a different mechanism. (It is related to CALCITE-3181, CALCITE-4687.) Maybe this case should focus only on the first rewrite. Related: {{ROW_NUMBER() OVER (PARTITION BY w, x ORDER BY x, y)}} can be simplified to {{ROW_NUMBER() OVER (PARTITION BY w, x ORDER BY y)}} because {{x}} has a unique value within any group. This could be applied to any aggregate function that sorts, e.g. {{LISTAGG()}}. was (Author: julianhyde): Can this behavior be described by an algebraic property? E.g. ROW_NUMBER applied to one row always returns 1? Related: {{ROW_NUMBER() OVER (PARTITION BY w, x ORDER BY x, y)}} can be simplified to {{ROW_NUMBER() OVER (PARTITION BY w, x ORDER BY y)}} because {{x}} has a unique value within any group. This could be applied to any aggregate function that sorts, e.g. {{LISTAGG()}}. > Remove ROW_NUMBER if OVER PARTITION BY unique key > - > > Key: CALCITE-6240 > URL: https://issues.apache.org/jira/browse/CALCITE-6240 > Project: Calcite > Issue Type: Improvement > Components: core >Reporter: Jiajun Xie >Assignee: Jiajun Xie >Priority: Minor > > The SQL Only have ROW_NUMBER function. > {code:java} > SELECT empno, ename FROM ( > SELECT ROW_NUMBER() OVER (PARTITION BY empno) rn, empno, ename > FROM emp > ) WHERE rn <= 5{code} > to > {code:java} > SELECT empno, ename FROM emp{code} > > If we know every partition count is less than filter count, we can optimize > {code:java} > SELECT deptno, ename FROM ( > SELECT ROW_NUMBER() OVER (PARTITION BY deptno) rn, deptno, ename > FROM emp > ) WHERE rn <= N > -- Statistic let we know every department count is less than N{code} > to > {code:java} > SELECT empno, ename FROM emp {code} -- This message was sent by Atlassian Jira (v8.20.10#820010)
[jira] [Commented] (CALCITE-6240) Remove ROW_NUMBER if OVER PARTITION BY unique key
[ https://issues.apache.org/jira/browse/CALCITE-6240?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=17814498#comment-17814498 ] Julian Hyde commented on CALCITE-6240: -- Can this behavior be described by an algebraic property? E.g. ROW_NUMBER applied to one row always returns 1? Related: {{ROW_NUMBER() OVER (PARTITION BY w, x ORDER BY x, y)}} can be simplified to {{ROW_NUMBER() OVER (PARTITION BY w, x ORDER BY y)}} because {{x}} has a unique value within any group. This could be applied to any aggregate function that sorts, e.g. {{LISTAGG()}}. > Remove ROW_NUMBER if OVER PARTITION BY unique key > - > > Key: CALCITE-6240 > URL: https://issues.apache.org/jira/browse/CALCITE-6240 > Project: Calcite > Issue Type: Improvement > Components: core >Reporter: Jiajun Xie >Assignee: Jiajun Xie >Priority: Minor > > The SQL Only have ROW_NUMBER function. > {code:java} > SELECT empno, ename FROM ( > SELECT ROW_NUMBER() OVER (PARTITION BY empno) rn, empno, ename > FROM emp > ) WHERE rn <= 5{code} > to > {code:java} > SELECT empno, ename FROM emp{code} > > If we know every partition count is less than filter count, we can optimize > {code:java} > SELECT deptno, ename FROM ( > SELECT ROW_NUMBER() OVER (PARTITION BY deptno) rn, deptno, ename > FROM emp > ) WHERE rn <= N > -- Statistic let we know every department count is less than N{code} > to > {code:java} > SELECT empno, ename FROM emp {code} -- This message was sent by Atlassian Jira (v8.20.10#820010)
[jira] [Commented] (CALCITE-6244) Improve `Expressions#constant` to allow passing models with non-public fields
[ https://issues.apache.org/jira/browse/CALCITE-6244?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=17814429#comment-17814429 ] Julian Hyde commented on CALCITE-6244: -- Do you propose to allow any class with public fields? I’d be happier if you supported some particular models, such as records, that we can verify are immutable. And add tests for each model. You say “use reflection”, and using reflection when building the AST is fine, but maybe not fine if the generated code uses reflection. I want the generated code to be such that Javac can do constant reduction. > Improve `Expressions#constant` to allow passing models with non-public fields > - > > Key: CALCITE-6244 > URL: https://issues.apache.org/jira/browse/CALCITE-6244 > Project: Calcite > Issue Type: Improvement > Components: linq4j >Reporter: Wegdan Ghazi >Assignee: Wegdan Ghazi >Priority: Minor > > To use > [Expressions#constant|https://github.com/apache/calcite/blob/e17098d47f3c31e4d90cc17e6e1da1175bf49ae4/linq4j/src/main/java/org/apache/calcite/linq4j/tree/Expressions.java#L540] > with complex models, it's required to pass a model with public fields, as > can be seen in this > [test|https://github.com/apache/calcite/blob/e17098d47f3c31e4d90cc17e6e1da1175bf49ae4/linq4j/src/test/java/org/apache/calcite/linq4j/test/ExpressionTest.java#L865]. > i.e. to successfully pass an instance of `{{{}Employee{}}}`, it must be > defined as follows: > {code:java} > public static class Employee { > public final int empno; > public final String name; > public final int deptno; public Employee(int empno, String name, int > deptno) { > this.empno = empno; > this.name = name; > this.deptno = deptno; > } public String toString() { > return "Employee(name: " + name + ", deptno:" + deptno + ")"; > } @Override public int hashCode() { > final int prime = 31; > int result = 1; > result = prime * result + deptno; > result = prime * result + empno; > result = prime * result + ((name == null) ? 0 : name.hashCode()); > return result; > } @Override public boolean equals(Object obj) { > if (this == obj) { > return true; > } > if (obj == null) { > return false; > } > if (getClass() != obj.getClass()) { > return false; > } > Employee other = (Employee) obj; > if (deptno != other.deptno) { > return false; > } > if (empno != other.empno) { > return false; > } > if (name == null) { > if (other.name != null) { > return false; > } > } else if (!name.equals(other.name)) { > return false; > } > return true; > } > } {code} > This makes it difficult to use generated classes e.g. Java records or > immutables, or even encapsulated POJOs to pass through Linq4j. > This is caused by the logic to > [explore|https://github.com/apache/calcite/blob/e17098d47f3c31e4d90cc17e6e1da1175bf49ae4/linq4j/src/main/java/org/apache/calcite/linq4j/tree/ConstantExpression.java#L299] > and > [create|https://github.com/apache/calcite/blob/e17098d47f3c31e4d90cc17e6e1da1175bf49ae4/linq4j/src/main/java/org/apache/calcite/linq4j/tree/ConstantExpression.java#L216] > the model constructor; which depends on: > {code:java} > value.getClass().getFields() {code} > which only accesses public fields. > {*}Proposed solution{*}: Access fields using reflection, by accessing their > getter methods. -- This message was sent by Atlassian Jira (v8.20.10#820010)
[jira] [Updated] (CALCITE-6244) Improve `Expressions#constant` to allow passing models with non-public fields
[ https://issues.apache.org/jira/browse/CALCITE-6244?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ] Julian Hyde updated CALCITE-6244: - Component/s: linq4j (was: avatica) > Improve `Expressions#constant` to allow passing models with non-public fields > - > > Key: CALCITE-6244 > URL: https://issues.apache.org/jira/browse/CALCITE-6244 > Project: Calcite > Issue Type: Improvement > Components: linq4j >Reporter: Wegdan Ghazi >Assignee: Wegdan Ghazi >Priority: Minor > > To use > [Expressions#constant|https://github.com/apache/calcite/blob/e17098d47f3c31e4d90cc17e6e1da1175bf49ae4/linq4j/src/main/java/org/apache/calcite/linq4j/tree/Expressions.java#L540] > with complex models, it's required to pass a model with public fields, as > can be seen in this > [test|https://github.com/apache/calcite/blob/e17098d47f3c31e4d90cc17e6e1da1175bf49ae4/linq4j/src/test/java/org/apache/calcite/linq4j/test/ExpressionTest.java#L865]. > i.e. to successfully pass an instance of `{{{}Employee{}}}`, it must be > defined as follows: > {code:java} > public static class Employee { > public final int empno; > public final String name; > public final int deptno; public Employee(int empno, String name, int > deptno) { > this.empno = empno; > this.name = name; > this.deptno = deptno; > } public String toString() { > return "Employee(name: " + name + ", deptno:" + deptno + ")"; > } @Override public int hashCode() { > final int prime = 31; > int result = 1; > result = prime * result + deptno; > result = prime * result + empno; > result = prime * result + ((name == null) ? 0 : name.hashCode()); > return result; > } @Override public boolean equals(Object obj) { > if (this == obj) { > return true; > } > if (obj == null) { > return false; > } > if (getClass() != obj.getClass()) { > return false; > } > Employee other = (Employee) obj; > if (deptno != other.deptno) { > return false; > } > if (empno != other.empno) { > return false; > } > if (name == null) { > if (other.name != null) { > return false; > } > } else if (!name.equals(other.name)) { > return false; > } > return true; > } > } {code} > This makes it difficult to use generated classes e.g. Java records or > immutables, or even encapsulated POJOs to pass through Linq4j. > This is caused by the logic to > [explore|https://github.com/apache/calcite/blob/e17098d47f3c31e4d90cc17e6e1da1175bf49ae4/linq4j/src/main/java/org/apache/calcite/linq4j/tree/ConstantExpression.java#L299] > and > [create|https://github.com/apache/calcite/blob/e17098d47f3c31e4d90cc17e6e1da1175bf49ae4/linq4j/src/main/java/org/apache/calcite/linq4j/tree/ConstantExpression.java#L216] > the model constructor; which depends on: > {code:java} > value.getClass().getFields() {code} > which only accesses public fields. > {*}Proposed solution{*}: Access fields using reflection, by accessing their > getter methods. -- This message was sent by Atlassian Jira (v8.20.10#820010)
[jira] [Created] (CALCITE-6244) Improve `Expressions#constant` to allow passing models with non-public fields
Wegdan Ghazi created CALCITE-6244: - Summary: Improve `Expressions#constant` to allow passing models with non-public fields Key: CALCITE-6244 URL: https://issues.apache.org/jira/browse/CALCITE-6244 Project: Calcite Issue Type: Improvement Components: avatica Reporter: Wegdan Ghazi Assignee: Wegdan Ghazi To use [Expressions#constant|https://github.com/apache/calcite/blob/e17098d47f3c31e4d90cc17e6e1da1175bf49ae4/linq4j/src/main/java/org/apache/calcite/linq4j/tree/Expressions.java#L540] with complex models, it's required to pass a model with public fields, as can be seen in this [test|https://github.com/apache/calcite/blob/e17098d47f3c31e4d90cc17e6e1da1175bf49ae4/linq4j/src/test/java/org/apache/calcite/linq4j/test/ExpressionTest.java#L865]. i.e. to successfully pass an instance of `Employee`, it must be defined as follows: {code:java} public static class Employee { public final int empno; public final String name; public final int deptno; public Employee(int empno, String name, int deptno) { this.empno = empno; this.name = name; this.deptno = deptno; } public String toString() { return "Employee(name: " + name + ", deptno:" + deptno + ")"; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + deptno; result = prime * result + empno; result = prime * result + ((name == null) ? 0 : name.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } Employee other = (Employee) obj; if (deptno != other.deptno) { return false; } if (empno != other.empno) { return false; } if (name == null) { if (other.name != null) { return false; } } else if (!name.equals(other.name)) { return false; } return true; } } {code} This makes it difficult to use generated classes e.g. Java records or immutables, or even encapsulated POJOs to pass through Linq4j. This is caused by the logic to [explore|https://github.com/apache/calcite/blob/e17098d47f3c31e4d90cc17e6e1da1175bf49ae4/linq4j/src/main/java/org/apache/calcite/linq4j/tree/ConstantExpression.java#L299] and [create|https://github.com/apache/calcite/blob/e17098d47f3c31e4d90cc17e6e1da1175bf49ae4/linq4j/src/main/java/org/apache/calcite/linq4j/tree/ConstantExpression.java#L216] the model constructor; which depends on: {code:java} value.getClass().getFields() {code} which only accesses public fields. {*}Proposed solution{*}: Access fields using reflection, by accessing their getter methods. -- This message was sent by Atlassian Jira (v8.20.10#820010)
[jira] [Updated] (CALCITE-6244) Improve `Expressions#constant` to allow passing models with non-public fields
[ https://issues.apache.org/jira/browse/CALCITE-6244?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ] Wegdan Ghazi updated CALCITE-6244: -- Description: To use [Expressions#constant|https://github.com/apache/calcite/blob/e17098d47f3c31e4d90cc17e6e1da1175bf49ae4/linq4j/src/main/java/org/apache/calcite/linq4j/tree/Expressions.java#L540] with complex models, it's required to pass a model with public fields, as can be seen in this [test|https://github.com/apache/calcite/blob/e17098d47f3c31e4d90cc17e6e1da1175bf49ae4/linq4j/src/test/java/org/apache/calcite/linq4j/test/ExpressionTest.java#L865]. i.e. to successfully pass an instance of `{{{}Employee{}}}`, it must be defined as follows: {code:java} public static class Employee { public final int empno; public final String name; public final int deptno; public Employee(int empno, String name, int deptno) { this.empno = empno; this.name = name; this.deptno = deptno; } public String toString() { return "Employee(name: " + name + ", deptno:" + deptno + ")"; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + deptno; result = prime * result + empno; result = prime * result + ((name == null) ? 0 : name.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } Employee other = (Employee) obj; if (deptno != other.deptno) { return false; } if (empno != other.empno) { return false; } if (name == null) { if (other.name != null) { return false; } } else if (!name.equals(other.name)) { return false; } return true; } } {code} This makes it difficult to use generated classes e.g. Java records or immutables, or even encapsulated POJOs to pass through Linq4j. This is caused by the logic to [explore|https://github.com/apache/calcite/blob/e17098d47f3c31e4d90cc17e6e1da1175bf49ae4/linq4j/src/main/java/org/apache/calcite/linq4j/tree/ConstantExpression.java#L299] and [create|https://github.com/apache/calcite/blob/e17098d47f3c31e4d90cc17e6e1da1175bf49ae4/linq4j/src/main/java/org/apache/calcite/linq4j/tree/ConstantExpression.java#L216] the model constructor; which depends on: {code:java} value.getClass().getFields() {code} which only accesses public fields. {*}Proposed solution{*}: Access fields using reflection, by accessing their getter methods. was: To use [Expressions#constant|https://github.com/apache/calcite/blob/e17098d47f3c31e4d90cc17e6e1da1175bf49ae4/linq4j/src/main/java/org/apache/calcite/linq4j/tree/Expressions.java#L540] with complex models, it's required to pass a model with public fields, as can be seen in this [test|https://github.com/apache/calcite/blob/e17098d47f3c31e4d90cc17e6e1da1175bf49ae4/linq4j/src/test/java/org/apache/calcite/linq4j/test/ExpressionTest.java#L865]. i.e. to successfully pass an instance of `Employee`, it must be defined as follows: {code:java} public static class Employee { public final int empno; public final String name; public final int deptno; public Employee(int empno, String name, int deptno) { this.empno = empno; this.name = name; this.deptno = deptno; } public String toString() { return "Employee(name: " + name + ", deptno:" + deptno + ")"; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + deptno; result = prime * result + empno; result = prime * result + ((name == null) ? 0 : name.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } Employee other = (Employee) obj; if (deptno != other.deptno) { return false; } if (empno != other.empno) { return false; } if (name == null) { if (other.name != null) { return false; } } else if (!name.equals(other.name)) { return false; } return true; } } {code} This makes it difficult to use generated classes e.g. Java records or immutables, or even encapsulated POJOs to pass through Linq4j. This is caused by the logic to [explore|https://github.com/apache/calcite/blob/e17098d47f3c31e4d90cc17e6e1da1175bf49ae4/linq4j/src/main/java/org/apache/calcite/linq4j/tree/ConstantExpression.java#L299] and
[jira] [Commented] (CALCITE-5647) RelMdPopulationSize should use mq.getRowCount(rel) instead of rel.estimateRowCount(mq)
[ https://issues.apache.org/jira/browse/CALCITE-5647?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=17814239#comment-17814239 ] Ruben Q L commented on CALCITE-5647: [~jduong] done. > RelMdPopulationSize should use mq.getRowCount(rel) instead of > rel.estimateRowCount(mq) > -- > > Key: CALCITE-5647 > URL: https://issues.apache.org/jira/browse/CALCITE-5647 > Project: Calcite > Issue Type: Bug > Components: core >Affects Versions: 1.34.0 >Reporter: Adam Kennedy >Assignee: Adam Kennedy >Priority: Minor > Labels: pull-request-available > Original Estimate: 1h > Time Spent: 20m > Remaining Estimate: 40m > > A few locations in Calcite call rel.estimateRowCount(mq) when they should > instead call mq.getRowCount(red). > We detected this because we implemented row count estimation entirely within > an alternative handle instead of RelMdRowCount, and then override > estimateRowCount to ensure the custom handler is user, by throwing an > unreachable code exception. > A few places in Calcite trigger these unreachable exceptions because they do > not use mq.getRowCount. > The most easily triggered on is in RelMdPopulationSize for the Values > parameter. -- This message was sent by Atlassian Jira (v8.20.10#820010)
[jira] [Updated] (CALCITE-5647) RelMdPopulationSize should use mq.getRowCount(rel) instead of rel.estimateRowCount(mq)
[ https://issues.apache.org/jira/browse/CALCITE-5647?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ] Ruben Q L updated CALCITE-5647: --- Summary: RelMdPopulationSize should use mq.getRowCount(rel) instead of rel.estimateRowCount(mq) (was: RelMdPopulationSize calls rel.estimateRowCount instead of mq.getRowCount) > RelMdPopulationSize should use mq.getRowCount(rel) instead of > rel.estimateRowCount(mq) > -- > > Key: CALCITE-5647 > URL: https://issues.apache.org/jira/browse/CALCITE-5647 > Project: Calcite > Issue Type: Bug > Components: core >Affects Versions: 1.34.0 >Reporter: Adam Kennedy >Assignee: Adam Kennedy >Priority: Minor > Labels: pull-request-available > Original Estimate: 1h > Time Spent: 20m > Remaining Estimate: 40m > > A few locations in Calcite call rel.estimateRowCount(mq) when they should > instead call mq.getRowCount(red). > We detected this because we implemented row count estimation entirely within > an alternative handle instead of RelMdRowCount, and then override > estimateRowCount to ensure the custom handler is user, by throwing an > unreachable code exception. > A few places in Calcite trigger these unreachable exceptions because they do > not use mq.getRowCount. > The most easily triggered on is in RelMdPopulationSize for the Values > parameter. -- This message was sent by Atlassian Jira (v8.20.10#820010)