[ 
https://issues.apache.org/jira/browse/CALCITE-5229?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17579354#comment-17579354
 ] 

Zhengqiang Duan commented on CALCITE-5229:
------------------------------------------

I found out that the type returned by the generated getElementType is based on 
the rowType in the RelNode . If it is RelRocordType, then a new Synthetic type 
is created.
{code:java}
@Override public Type getJavaClass(RelDataType type) {
  if (type instanceof JavaType) {
    JavaType javaType = (JavaType) type;
    return javaType.getJavaClass();
  }
  if (type instanceof BasicSqlType || type instanceof IntervalSqlType) {
    switch (type.getSqlTypeName()) {
    case VARCHAR:
    case CHAR:
      return String.class;
    case DATE:
    case TIME:
    case TIME_WITH_LOCAL_TIME_ZONE:
    case INTEGER:
    case INTERVAL_YEAR:
    case INTERVAL_YEAR_MONTH:
    case INTERVAL_MONTH:
      return type.isNullable() ? Integer.class : int.class;
    case TIMESTAMP:
    case TIMESTAMP_WITH_LOCAL_TIME_ZONE:
    case BIGINT:
    case INTERVAL_DAY:
    case INTERVAL_DAY_HOUR:
    case INTERVAL_DAY_MINUTE:
    case INTERVAL_DAY_SECOND:
    case INTERVAL_HOUR:
    case INTERVAL_HOUR_MINUTE:
    case INTERVAL_HOUR_SECOND:
    case INTERVAL_MINUTE:
    case INTERVAL_MINUTE_SECOND:
    case INTERVAL_SECOND:
      return type.isNullable() ? Long.class : long.class;
    case SMALLINT:
      return type.isNullable() ? Short.class : short.class;
    case TINYINT:
      return type.isNullable() ? Byte.class : byte.class;
    case DECIMAL:
      return BigDecimal.class;
    case BOOLEAN:
      return type.isNullable() ? Boolean.class : boolean.class;
    case DOUBLE:
    case FLOAT: // sic
      return type.isNullable() ? Double.class : double.class;
    case REAL:
      return type.isNullable() ? Float.class : float.class;
    case BINARY:
    case VARBINARY:
      return ByteString.class;
    case GEOMETRY:
      return Geometries.Geom.class;
    case SYMBOL:
      return Enum.class;
    case ANY:
      return Object.class;
    case NULL:
      return Void.class;
    default:
      break;
    }
  }
  switch (type.getSqlTypeName()) {
  case ROW:
    assert type instanceof RelRecordType;
    if (type instanceof JavaRecordType) {
      return ((JavaRecordType) type).clazz;
    } else {
      return createSyntheticType((RelRecordType) type);
    }
  case MAP:
    return Map.class;
  case ARRAY:
  case MULTISET:
    return List.class;
  default:
    break;
  }
  return Object.class;
}

/** Creates a synthetic Java class whose fields have the same names and
 * relational types. */
private Type createSyntheticType(RelRecordType type) {
  final String name =
      "Record" + type.getFieldCount() + "_" + syntheticTypes.size();
  final SyntheticRecordType syntheticType =
      new SyntheticRecordType(type, name);
  for (final RelDataTypeField recordField : type.getFieldList()) {
    final Type javaClass = getJavaClass(recordField.getType());
    syntheticType.fields.add(
        new RecordFieldImpl(
            syntheticType,
            recordField.getName(),
            javaClass,
            recordField.getType().isNullable()
                && !Primitive.is(javaClass),
            Modifier.PUBLIC));
  }
  return register(syntheticType);
} {code}
In addition, the code generation getElementType is based on the physType type 
of the parent node in the execution plan.
{code:java}
org/apache/calcite/adapter/enumerable/EnumerableRelImplementor.java:171
    memberDeclarations.add(
        Expressions.methodDecl(Modifier.PUBLIC, Class.class,
            BuiltInMethod.TYPED_GET_ELEMENT_TYPE.method.getName(),
            ImmutableList.of(),
            Blocks.toFunctionBlock(
                Expressions.return_(null,
                    Expressions.constant(result.physType.getJavaRowType()))))); 
{code}
So, we need to investigate why the rowType type in EnumerableLimit is not 
Employee type.

> JdbcTest#testDynamicParameterInLimitOffset throws IllegalArgumentException
> --------------------------------------------------------------------------
>
>                 Key: CALCITE-5229
>                 URL: https://issues.apache.org/jira/browse/CALCITE-5229
>             Project: Calcite
>          Issue Type: Bug
>          Components: core
>    Affects Versions: 1.31.0
>            Reporter: Benchao Li
>            Assignee: Zhengqiang Duan
>            Priority: Major
>
> After CALCITE-5201, this test will fail because we can transform more cases 
> to semi join, and the physical type for some {{EnumerableRel}}s is wrong, we 
> should fix them.
> See https://github.com/apache/calcite/pull/2848/files#r913566595
> {code:java}
> java.lang.IllegalArgumentException: Can not set int field Baz$Record5_1.empid 
> to null value
> java.sql.SQLException: java.lang.IllegalArgumentException: Can not set int 
> field Baz$Record5_1.empid to null value
>       at 
> org.apache.calcite.avatica.util.PositionedCursor$FieldGetter.getObject(PositionedCursor.java:132)
>       at 
> org.apache.calcite.avatica.util.AbstractCursor$AccessorImpl.getObject(AbstractCursor.java:357)
>       at 
> org.apache.calcite.avatica.util.AbstractCursor$AccessorImpl.getString(AbstractCursor.java:300)
>       at 
> org.apache.calcite.avatica.AvaticaResultSet.getString(AvaticaResultSet.java:241)
>       at 
> org.apache.calcite.test.CalciteAssert$ResultSetFormatter.rowToString(CalciteAssert.java:1986)
>       at 
> org.apache.calcite.test.CalciteAssert$ResultSetFormatter.resultSet(CalciteAssert.java:1972)
>       at 
> org.apache.calcite.test.CalciteAssert.lambda$checkResult$2(CalciteAssert.java:310)
>       at 
> org.apache.calcite.test.CalciteAssert.assertPrepare(CalciteAssert.java:631)
>       at 
> org.apache.calcite.test.CalciteAssert.access$700(CalciteAssert.java:149)
>       at 
> org.apache.calcite.test.CalciteAssert$AssertQuery.lambda$returns$1(CalciteAssert.java:1448)
>       at 
> org.apache.calcite.test.CalciteAssert$AssertQuery.withConnection(CalciteAssert.java:1384)
>       at 
> org.apache.calcite.test.CalciteAssert$AssertQuery.returns(CalciteAssert.java:1443)
>       at 
> org.apache.calcite.test.CalciteAssert$AssertQuery.returns(CalciteAssert.java:1433)
>       at 
> org.apache.calcite.test.CalciteAssert$AssertQuery.returns(CalciteAssert.java:1396)
>       at 
> org.apache.calcite.test.JdbcTest.testDynamicParameterInLimitOffset(JdbcTest.java:5448){code}



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to