You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@calcite.apache.org by "Dmitry Sysolyatin (Jira)" <ji...@apache.org> on 2022/12/31 15:08:00 UTC
[jira] [Comment Edited] (CALCITE-5460) Types.className should not replace '$' to '.' if name of class contains $
[ https://issues.apache.org/jira/browse/CALCITE-5460?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17653321#comment-17653321 ]
Dmitry Sysolyatin edited comment on CALCITE-5460 at 12/31/22 3:07 PM:
----------------------------------------------------------------------
[~julianhyde] In my understanding the purpose of Types.className is to return correct java classname that can be used inside `Expression` to generate correct java code.
I found this issue when was trying to implement UDF function using scala object method and calcite generated me wrong java code.
For example:
{code:java}
import org.apache.calcite.linq4j.tree.Expressions
import org.scalatest.funsuite.AnyFunSuite
object FunctionImpls {
def testFunc(): Boolean = true
}
// JAVA REPRESENTATION OF FunctionImpls object
// public final class FunctionImpls$ {
// public static final FunctionImpls$ MODULE$ = new FunctionImpls$();
//
// public boolean testFunc(final String arg) {
// return true;
// }
//
// private FunctionImpls$() {
// }
//}
class CalciteFuncTest extends AnyFunSuite {
test("Get object instance expression") {
val objectExpr = Expressions.field(null, FunctionImpls.getClass, "MODULE$")
assert(objectExpr.toString == "FunctionImpls$.MODULE$") // without fix it will generate FunctionImpls..MODULE$ instead of FunctionImpls$.MODULE$
}
{code}
Calcite generates `FunctionImpls..MODULE$` instead of FunctionImpls$.MODULE$ without PR's fix.
From git history I found that `return className.replace('$', '.');` was added in order to generate correct class name for inner classes, but it does not take into account that class can contain `$` inside name. Instead of using className.replace('$', '.'); would be better to use clazz.getCanonicalName() (it returns proper name, how it should be by Java Language Specification)
was (Author: dmsysolyatin):
[~julianhyde] In my understanding the purpose of Types.className is to return correct java classname that can be used inside `Expression` to generate correct java code.
I found this issue when was trying to implement UDF function using scala object method and calcite generated me wrong java code.
For example:
{code:java}
import org.apache.calcite.linq4j.tree.Expressions
import org.scalatest.funsuite.AnyFunSuite
object FunctionImpls {
def testFunc(): Boolean = true
}
// JAVA REPRESENTATION OF FunctionImpls object
// public final class FunctionImpls$ {
// public static final FunctionImpls$ MODULE$ = new FunctionImpls$();
//
// public boolean testFunc(final String arg) {
// return true;
// }
//
// private FunctionImpls$() {
// }
//}
class CalciteFuncTest extends AnyFunSuite {
test("Get object instance expression") {
val objectExpr = Expressions.field(null, FunctionImpls.getClass, "MODULE$")
assert(objectExpr.toString == "FunctionImpls$.MODULE$") // without fix it will generate FunctionImpls..MODULE$ instead of FunctionImpls$.MODULE$
}
{code}
Calcite generates `FunctionImpls..MODULE$` instead of FunctionImpls$.MODULE$ without PR's fix.
From git history I found that `return className.replace('$', '.');` was added in order to generate correct class name for inner classes, but it does not handle all cases how you can see from example above. Instead of using className.replace('$', '.'); would be better to use clazz.getCanonicalName() (it returns proper name, how it should be by Java Language Specification)
> Types.className should not replace '$' to '.' if name of class contains $
> -------------------------------------------------------------------------
>
> Key: CALCITE-5460
> URL: https://issues.apache.org/jira/browse/CALCITE-5460
> Project: Calcite
> Issue Type: Bug
> Components: linq4j
> Affects Versions: 1.32.0
> Reporter: Dmitry Sysolyatin
> Assignee: Dmitry Sysolyatin
> Priority: Major
> Labels: pull-request-available
>
> I faced with this problem when I was trying to use Types.className with scala object.
> Internally, scala object is instance of class "<full_object_name>$". If Types.className is applied to this class then $ will be replaced by '.'. But it is wrong behaviour
> The same behaviour will be for any class names which contain symbol $.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)