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

Pavel Pereslegin edited comment on IGNITE-20651 at 2/5/25 10:42 AM:
--------------------------------------------------------------------

This issue is still actual at the moment of release AI 3.0.

It is definitely a case when we are using single column table.
Looks like record view is not supposed to work with SimpleMarshaller.
Check {{RecordMarshallerImpl}} constructor and how it is uses 
{{Marshaller.createMarshaller}} and {{Marshaller.csimpleMarshaller}}. Naive 
approach simpleMarshaller should not throw exception (if 
{{allowUnmappedFields}} specified) must return {{NoOpMarshaller}} if column was 
not found.

Possible test cases (for {{RecordMarshallerTest}}).
{code:java}
    @ParameterizedTest
    @MethodSource("marshallerFactoryProvider")
    public void singleColumnSchemaMapping(MarshallerFactory factory) throws 
MarshallerException {
        SchemaDescriptor schema = new 
SchemaDescriptor(schemaVersion.incrementAndGet(),
                new Column[]{new Column("key".toUpperCase(), INT64, false)},
                new Column[]{}
        );

        Consumer<Mapper<Long>> testCase = mapper -> {
            RecordMarshaller<Long> marshaller = factory.create(schema, mapper);

            long rec = TestObject.randomObject(rnd).id;

            BinaryRow row = marshaller.marshal(rec);

            Object restoredRec = marshaller.unmarshal(Row.wrapBinaryRow(schema, 
row));

            assertThat(restoredRec, instanceOf(Long.class));

            assertEquals(rec, restoredRec);
        };

        // Mapper without column name.
        testCase.accept(Mapper.of(Long.class));

        // Mapper with column name.
        testCase.accept(Mapper.of(Long.class, "id"));
    }

    @ParameterizedTest
    @MethodSource("marshallerFactoryProvider")
    public void mappingSingleColumn(MarshallerFactory factory) throws 
MarshallerException {
        SchemaDescriptor schema = new 
SchemaDescriptor(schemaVersion.incrementAndGet(),
                new Column[]{new Column("key".toUpperCase(), INT64, false)},
                new Column[]{
                        new Column("col1".toUpperCase(), INT32, false),
                        new Column("col2".toUpperCase(), INT64, true),
                        new Column("col3".toUpperCase(), STRING, false)
                });

        // split into separate test cases for different columns
        Mapper<Long> mapper = Mapper.of(Long.class, "id");

        RecordMarshaller<Long> marshaller = factory.create(schema, mapper);

        long rec = TestObject.randomObject(rnd).id;

        BinaryRow row = marshaller.marshal(rec);

        Object restoredRec = marshaller.unmarshal(Row.wrapBinaryRow(schema, 
row));

        assertThat(restoredRec, instanceOf(Long.class));

        assertEquals(rec, restoredRec);
    }

{code}



was (Author: xtern):
This issue is actual at the moment of release AI 3.0.

It is definitely a case when we using single column table.
Looks like record view is not supposed to work with SimpleMarshaller.
Check {{RecordMarshallerImpl}} constructor and how it is uses 
{{Marshaller.createMarshaller}} and {{Marshaller.csimpleMarshaller}}. Naive 
approach - simpleMarshaller should not throw exception (if 
{{allowUnmappedFields}} specified) must return {{NoOpMarshaller}} in this case.

Possible test cases (for {{RecordMarshallerTest}}).
{code:java}
    @ParameterizedTest
    @MethodSource("marshallerFactoryProvider")
    public void singleColumnSchemaMapping(MarshallerFactory factory) throws 
MarshallerException {
        SchemaDescriptor schema = new 
SchemaDescriptor(schemaVersion.incrementAndGet(),
                new Column[]{new Column("key".toUpperCase(), INT64, false)},
                new Column[]{}
        );

        Consumer<Mapper<Long>> testCase = mapper -> {
            RecordMarshaller<Long> marshaller = factory.create(schema, mapper);

            long rec = TestObject.randomObject(rnd).id;

            BinaryRow row = marshaller.marshal(rec);

            Object restoredRec = marshaller.unmarshal(Row.wrapBinaryRow(schema, 
row));

            assertThat(restoredRec, instanceOf(Long.class));

            assertEquals(rec, restoredRec);
        };

        // Mapper without column name.
        testCase.accept(Mapper.of(Long.class));

        // Mapper with column name.
        testCase.accept(Mapper.of(Long.class, "id"));
    }

    @ParameterizedTest
    @MethodSource("marshallerFactoryProvider")
    public void mappingSingleColumn(MarshallerFactory factory) throws 
MarshallerException {
        SchemaDescriptor schema = new 
SchemaDescriptor(schemaVersion.incrementAndGet(),
                new Column[]{new Column("key".toUpperCase(), INT64, false)},
                new Column[]{
                        new Column("col1".toUpperCase(), INT32, false),
                        new Column("col2".toUpperCase(), INT64, true),
                        new Column("col3".toUpperCase(), STRING, false)
                });

        // split into separate test cases for different columns
        Mapper<Long> mapper = Mapper.of(Long.class, "id");

        RecordMarshaller<Long> marshaller = factory.create(schema, mapper);

        long rec = TestObject.randomObject(rnd).id;

        BinaryRow row = marshaller.marshal(rec);

        Object restoredRec = marshaller.unmarshal(Row.wrapBinaryRow(schema, 
row));

        assertThat(restoredRec, instanceOf(Long.class));

        assertEquals(rec, restoredRec);
    }

{code}


> Table API. It is not possible to create a single column RecordView
> ------------------------------------------------------------------
>
>                 Key: IGNITE-20651
>                 URL: https://issues.apache.org/jira/browse/IGNITE-20651
>             Project: Ignite
>          Issue Type: Bug
>          Components: sql
>            Reporter: Maksim Zhuravkov
>            Assignee: Pavel Pereslegin
>            Priority: Major
>              Labels: ignite-3
>             Fix For: 3.1
>
>
> It is not possible to create a single column RecordView:
> {code:java}
>     @Test
>     public void singleColumnMapper() {
>         Ignite ignite = CLUSTER_NODES.get(0);
>         IgniteTables tables = ignite.tables();
>         sql("CREATE TABLE vals (id INTEGER PRIMARY KEY, val VARCHAR)");
>         sql("INSERT INTO vals VALUES(1, '1')");
>         RecordView<Integer> idView = 
> tables.table("vals").recordView(Mapper.of(Integer.class, "id"));
>         assertNotNull(idView.get(null, 1));
>     }
> {code}
> Error:
> {noformat}
> org.apache.ignite.lang.IgniteException: IGN-CMN-65535 
> TraceId:30b4df56-49ff-4e79-8035-f13f9acd2bc1
>       at 
> java.base/java.lang.invoke.MethodHandle.invokeWithArguments(MethodHandle.java:710)
>       at 
> org.apache.ignite.internal.util.ExceptionUtils$1.copy(ExceptionUtils.java:789)
>       at 
> org.apache.ignite.internal.util.ExceptionUtils$ExceptionFactory.createCopy(ExceptionUtils.java:723)
>       at 
> org.apache.ignite.internal.util.ExceptionUtils.copyExceptionWithCause(ExceptionUtils.java:525)
>       at 
> org.apache.ignite.internal.util.ViewUtils.copyExceptionWithCauseIfPossible(ViewUtils.java:91)
>       at 
> org.apache.ignite.internal.util.ViewUtils.ensurePublicException(ViewUtils.java:71)
>       at org.apache.ignite.internal.util.ViewUtils.sync(ViewUtils.java:54)
>       at 
> org.apache.ignite.internal.table.RecordViewImpl.get(RecordViewImpl.java:106)
>       at 
> org.apache.ignite.internal.table.PublicApiThreadingRecordView.lambda$get$0(PublicApiThreadingRecordView.java:56)
>       at 
> org.apache.ignite.internal.thread.PublicApiThreading.executeWithRole(PublicApiThreading.java:144)
>       at 
> org.apache.ignite.internal.thread.PublicApiThreading.execUserSyncOperation(PublicApiThreading.java:102)
>       at 
> org.apache.ignite.internal.table.PublicApiThreadingViewBase.executeSyncOp(PublicApiThreadingViewBase.java:107)
>       at 
> org.apache.ignite.internal.table.PublicApiThreadingRecordView.get(PublicApiThreadingRecordView.java:56)
>       at 
> org.apache.ignite.internal.restart.RestartProofRecordView.lambda$get$0(RestartProofRecordView.java:54)
>       at 
> org.apache.ignite.internal.restart.RestartProofApiObject.lambda$attached$0(RestartProofApiObject.java:46)
>       at 
> org.apache.ignite.internal.restart.IgniteAttachmentLock.attached(IgniteAttachmentLock.java:59)
>       at 
> org.apache.ignite.internal.restart.RestartProofApiObject.attached(RestartProofApiObject.java:46)
>       at 
> org.apache.ignite.internal.restart.RestartProofRecordView.get(RestartProofRecordView.java:54)
>       at 
> org.apache.ignite.internal.sql.engine.ItDynamicParameterTest.singleColumnMapper(ItDynamicParameterTest.java:87)
>       at java.base/java.lang.reflect.Method.invoke(Method.java:566)
>       at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
>       at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
> Caused by: org.apache.ignite.lang.IgniteException: IGN-CMN-65535 
> TraceId:30b4df56-49ff-4e79-8035-f13f9acd2bc1
>       at 
> org.apache.ignite.internal.lang.IgniteExceptionMapperUtil.lambda$mapToPublicException$2(IgniteExceptionMapperUtil.java:88)
>       at 
> org.apache.ignite.internal.lang.IgniteExceptionMapperUtil.mapCheckingResultIsPublic(IgniteExceptionMapperUtil.java:141)
>       at 
> org.apache.ignite.internal.lang.IgniteExceptionMapperUtil.mapToPublicException(IgniteExceptionMapperUtil.java:110)
>       at 
> org.apache.ignite.internal.lang.IgniteExceptionMapperUtil.mapToPublicException(IgniteExceptionMapperUtil.java:88)
>       at 
> org.apache.ignite.internal.lang.IgniteExceptionMapperUtil.lambda$convertToPublicFuture$3(IgniteExceptionMapperUtil.java:178)
>       at 
> java.base/java.util.concurrent.CompletableFuture.uniHandle(CompletableFuture.java:930)
>       at 
> java.base/java.util.concurrent.CompletableFuture.uniHandleStage(CompletableFuture.java:946)
>       at 
> java.base/java.util.concurrent.CompletableFuture.handle(CompletableFuture.java:2266)
>       at 
> org.apache.ignite.internal.lang.IgniteExceptionMapperUtil.convertToPublicFuture(IgniteExceptionMapperUtil.java:176)
>       at 
> org.apache.ignite.internal.table.AbstractTableView.doOperation(AbstractTableView.java:111)
>       at 
> org.apache.ignite.internal.table.RecordViewImpl.getAsync(RecordViewImpl.java:114)
>       ... 15 more
> Caused by: java.lang.AssertionError
>       at 
> org.apache.ignite.internal.schema.marshaller.reflection.RecordMarshallerImpl.<init>(RecordMarshallerImpl.java:66)
>       at 
> org.apache.ignite.internal.table.RecordViewImpl.lambda$new$0(RecordViewImpl.java:100)
>       at 
> org.apache.ignite.internal.table.RecordViewImpl.marshaller(RecordViewImpl.java:436)
>       at 
> org.apache.ignite.internal.table.RecordViewImpl.marshalKey(RecordViewImpl.java:504)
>       at 
> org.apache.ignite.internal.table.RecordViewImpl.lambda$getAsync$2(RecordViewImpl.java:115)
>       at 
> org.apache.ignite.internal.table.AbstractTableView.lambda$withSchemaSync$1(AbstractTableView.java:142)
>       at 
> java.base/java.util.concurrent.CompletableFuture.uniComposeStage(CompletableFuture.java:1106)
>       at 
> java.base/java.util.concurrent.CompletableFuture.thenCompose(CompletableFuture.java:2235)
>       at 
> org.apache.ignite.internal.table.AbstractTableView.withSchemaSync(AbstractTableView.java:142)
>       at 
> org.apache.ignite.internal.table.AbstractTableView.withSchemaSync(AbstractTableView.java:133)
>       ... 17 more
> {noformat}



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

Reply via email to