SystemError - "value" is neither a method, a field, nor a member class of "org.apache.arrow.vector.holders.NullableDecimalHolder"

Hello There,

We are getting this below error while executing a query, can you help us on understanding the RCA behind this.

------------------------------------ Error Below -------------------------------

 SYSTEM ERROR: CompileException: Line 66, Column 50: "value" is neither a method, a field, nor a member class of "org.apache.arrow.vector.holders.NullableDecimalHolder"

SqlOperatorImpl NESTED_LOOP_JOIN
Location 0:0:7
Fragment 0:0

[Error Id: ac1f0347-f0cf-4c59-ba57-beb7aeb3c6cb on dremio-executor-1.dremio-cluster-pod.default.svc.cluster.local:0]

  (com.google.common.util.concurrent.UncheckedExecutionException) com.dremio.exec.exception.ClassTransformationException: Failure generating transformation classes for value: 
 
package com.dremio.s;

import com.dremio.exec.exception.SchemaChangeException;
import com.dremio.exec.expr.VectorResolver;
import com.dremio.exec.expr.fn.FunctionErrorContext;
import com.dremio.exec.record.VectorAccessible;
import com.dremio.sabot.exec.context.FunctionContext;
import com.dremio.sabot.op.join.nlje.MatchGenerator;
import org.apache.arrow.memory.ArrowBuf;
import org.apache.arrow.vector.BigIntVector;
import org.apache.arrow.vector.DecimalVector;
import org.apache.arrow.vector.holders.NullableBigIntHolder;
import org.apache.arrow.vector.holders.NullableBitHolder;
import org.apache.arrow.vector.holders.NullableDecimalHolder;

public class MatchGeneratorGen14407370
    extends MatchGenerator
{

    BigIntVector[] vv0;
    DecimalVector vv2;
    ArrowBuf work6;
    FunctionErrorContext work7;
    ArrowBuf work8;
    FunctionErrorContext work9;
    NullableBigIntHolder constant11;
    NullableBigIntHolder constant13;

    public MatchGeneratorGen14407370() {
        __INIT__();
    }

    public boolean doEval(int probeIndex, int buildIndex)
        throws SchemaChangeException
    {
        {
            NullableBigIntHolder out1 = new NullableBigIntHolder();
            {
                out1 .isSet = vv0 [((buildIndex)>>> 16)].isSet(((buildIndex)& 65535));
                if (out1 .isSet == 1) {
                    out1 .value = vv0 [((buildIndex)>>> 16)].get(((buildIndex)& 65535));
                }
            }
            NullableDecimalHolder out3 = new NullableDecimalHolder();
            {
                out3 .isSet = vv2 .isSet((probeIndex));
                if (out3 .isSet == 1) {
                    out3 .scale = 1;
                    out3 .precision = 22;
                    out3 .start = (16 *(probeIndex));
                    out3 .buffer = vv2 .getDataBuffer();
                }
            }
            NullableBitHolder out4 = new NullableBitHolder();
            AndOP0:
            {
                NullableBitHolder out5 = new NullableBitHolder();
                AndOP1:
                {
                    if ((out1 .isSet == 1)&&(out1 .value!= 1)) {
                        out5 .isSet = 1;
                        out5 .value = 0;
                        break AndOP1;
                    }
                    if ((out3 .isSet == 1)&&(out3 .value!= 1)) {
                        out5 .isSet = 1;
                        out5 .value = 0;
                        break AndOP1;
                    }
                    if ((out1 .isSet*out3 .isSet) == 0) {
                        out5 .isSet = 0;
                    } else {
                        out5 .isSet = 1;
                        out5 .value = 1;
                    }
                }
                if ((out5 .isSet == 1)&&(out5 .value!= 1)) {
                    out4 .isSet = 1;
                    out4 .value = 0;
                    break AndOP0;
                }
                //---- start of eval portion of castDECIMAL function. ----//
                NullableDecimalHolder out14 = new NullableDecimalHolder();
                {
                    if (((out1 .isSet*constant11 .isSet)*constant13 .isSet) == 0) {
                        out14 .isSet = 0;
                    } else {
                        final NullableDecimalHolder out = new NullableDecimalHolder();
                        NullableBigIntHolder in = out1;
                        NullableBigIntHolder precision = constant11;
                        NullableBigIntHolder scale = constant13;
                        ArrowBuf buffer = work8;
                        FunctionErrorContext errorContext = work9;
                         
DecimalFunctions$CastBigIntDecimal_eval: {
    java.math.BigDecimal bd = java.math.BigDecimal.valueOf(in.value).setScale((int) scale.value, java.math.RoundingMode.HALF_UP);

    try {
        org.apache.arrow.vector.util.DecimalUtility.writeBigDecimalToArrowBuf(bd, buffer, 0);
    } catch (RuntimeException e) {
        throw errorContext.error(e).build();
    }
    out.buffer = buffer;
    out.precision = (int) precision.value;
    out.scale = (int) scale.value;
}
 
                        work8 = buffer;
                        work9 = errorContext;
                        out.isSet = 1;
                        out14 = out;
                    }
                }
                //---- end of eval portion of castDECIMAL function. ----//
                //---- start of eval portion of divide function. ----//
                NullableDecimalHolder out15 = new NullableDecimalHolder();
                {
                    if ((out14 .isSet*out3 .isSet) == 0) {
                        out15 .isSet = 0;
                    } else {
                        final NullableDecimalHolder resultHolder = new NullableDecimalHolder();
                        NullableDecimalHolder leftHolder = out14;
                        NullableDecimalHolder rightHolder = out3;
                        ArrowBuf buffer = work6;
                        FunctionErrorContext functionErrorContext = work7;
                         
DecimalFunctions$DivideDecimals_eval: {
    int index = (leftHolder.start / (org.apache.arrow.vector.util.DecimalUtility.DECIMAL_BYTE_LENGTH));
    java.math.BigDecimal left = org.apache.arrow.vector.util.DecimalUtility.getBigDecimalFromArrowBuf(leftHolder.buffer, index, leftHolder.scale);

    index = (rightHolder.start / (org.apache.arrow.vector.util.DecimalUtility.DECIMAL_BYTE_LENGTH));

    java.math.BigDecimal right = org.apache.arrow.vector.util.DecimalUtility.getBigDecimalFromArrowBuf(rightHolder.buffer, index, rightHolder.scale);
    org.apache.arrow.vector.types.pojo.ArrowType.Decimal resultTypeForOperation = org.apache.arrow.gandiva.evaluator.DecimalTypeUtil.getResultTypeForOperation(org.apache.arrow.gandiva.evaluator.DecimalTypeUtil.OperationType.DIVIDE, new org.apache.arrow.vector.types.pojo.ArrowType.Decimal(leftHolder.precision, leftHolder.scale), new org.apache.arrow.vector.types.pojo.ArrowType.Decimal(rightHolder.precision, rightHolder.scale));

    resultHolder.precision = resultTypeForOperation.getPrecision();
    resultHolder.scale = resultTypeForOperation.getScale();
    if (resultHolder.scale > leftHolder.scale - rightHolder.scale) {
        left = left.setScale(resultHolder.scale + rightHolder.scale, java.math.BigDecimal.ROUND_UNNECESSARY);
    }

    java.math.BigInteger leftUnscaled = left.unscaledValue();
    java.math.BigInteger rightUnscaled = right.unscaledValue();
    java.math.BigInteger[] quotientAndRemainder = leftUnscaled.divideAndRemainder(rightUnscaled);
    java.math.BigInteger resultUnscaled = quotientAndRemainder[0];

    if (quotientAndRemainder[1].abs().multiply(java.math.BigInteger.valueOf(2)).compareTo(rightUnscaled.abs()) >= 0) {
        resultUnscaled = resultUnscaled.add(java.math.BigInteger.valueOf((leftUnscaled.signum() ^ rightUnscaled.signum()) + 1));
    }

    java.math.BigDecimal result = new java.math.BigDecimal(resultUnscaled, resultHolder.scale);

    result = com.dremio.exec.expr.fn.impl.DecimalFunctions.checkOverflow(result);
    try {
        org.apache.arrow.vector.util.DecimalUtility.writeBigDecimalToArrowBuf(result, buffer, 0);
    } catch (RuntimeException e) {
        throw functionErrorContext.error(e).build();
    }
    resultHolder.buffer = buffer;
}
 
                        work6 = buffer;
                        work7 = functionErrorContext;
                        resultHolder.isSet = 1;
                        out15 = resultHolder;
                    }
                }
                //---- end of eval portion of divide function. ----//
                //---- start of eval portion of isnotnull function. ----//
                NullableBitHolder out16 = new NullableBitHolder();
                {
                    final NullableBitHolder out = new NullableBitHolder();
                    NullableDecimalHolder input = out15;
                     
GNullOpNullableDecimalHolder$IsNotNull_eval: {
    out.isSet = 1;
    out.value = (input.isSet == 0 ? 0 : 1);
}
 
                    out16 = out;
                }
                //---- end of eval portion of isnotnull function. ----//
                if ((out16 .isSet == 1)&&(out16 .value!= 1)) {
                    out4 .isSet = 1;
                    out4 .value = 0;
                    break AndOP0;
                }
                if ((out5 .isSet*out16 .isSet) == 0) {
                    out4 .isSet = 0;
                } else {
                    out4 .isSet = 1;
                    out4 .value = 1;
                }
            }
            if ((out4 .isSet == 1)&&(out4 .value == 1)) {
                return true;
            }
            return false;
        }
    }

    public void doSetup(FunctionContext context, VectorAccessible probeVectorAccessible, VectorAccessible buildVectorAccessible)
        throws SchemaChangeException
    {
        {
            vv0 = ((BigIntVector[]) VectorResolver.hyper((buildVectorAccessible), BigIntVector.class, 0));
            vv2 = ((DecimalVector) VectorResolver.simple((probeVectorAccessible), DecimalVector.class, 3));
            work6 = (context).getManagedBuffer();
            work7 = (context).getFunctionErrorContext(0);
            work8 = (context).getManagedBuffer();
            work9 = (context).getFunctionErrorContext(1);
            NullableBigIntHolder out10 = new NullableBigIntHolder();
            out10 .value = 19L;
            out10 .isSet = 1;
            constant11 = out10;
            NullableBigIntHolder out12 = new NullableBigIntHolder();
            out12 .value = 0L;
            out12 .isSet = 1;
            constant13 = out12;
            /** start SETUP for function castDECIMAL **/ 
            {
                NullableBigIntHolder precision = constant11;
                NullableBigIntHolder scale = constant13;
                ArrowBuf buffer = work8;
                FunctionErrorContext errorContext = work9;
                 
DecimalFunctions$CastBigIntDecimal_setup: {
    buffer = buffer.reallocIfNeeded(16);
}
 
                work8 = buffer;
                work9 = errorContext;
            }
            /** end SETUP for function castDECIMAL **/ 
            /** start SETUP for function divide **/ 
            {
                ArrowBuf buffer = work6;
                FunctionErrorContext functionErrorContext = work7;
                 
DecimalFunctions$DivideDecimals_setup: {
    buffer = buffer.reallocIfNeeded(16);
}
 
                work6 = buffer;
                work7 = functionErrorContext;
            }
            /** end SETUP for function divide **/ 
            /** start SETUP for function isnotnull **/ 
            {
                 {}
            }
            /** end SETUP for function isnotnull **/ 
        }
    }

    public void __INIT__()
        throws SchemaChangeException
    {
    }

}

    com.google.common.cache.LocalCache$Segment.get():2051
    com.google.common.cache.LocalCache.get():3953
    com.google.common.cache.LocalCache.getOrLoad():3976
    com.google.common.cache.LocalCache$LocalLoadingCache.get():4960
    com.dremio.exec.compile.CodeCompiler.getImplementationClass():57
    com.dremio.exec.compile.CodeCompiler.getImplementationClass():50
    com.dremio.exec.expr.CodeGenerator.getImplementationClass():168
    com.dremio.sabot.op.join.nlje.MatchGenerator.generate():228
    com.dremio.sabot.op.join.nlje.EvaluatingJoinMatcher.setup():175
    com.dremio.sabot.op.join.nlje.NLJEOperator.noMoreToConsumeRight():230
    com.dremio.sabot.driver.SmartOp$SmartDualInput.noMoreToConsumeRight():443
    com.dremio.sabot.driver.WyePipe.pump():83
    com.dremio.sabot.driver.Pipeline.doPump():109
    com.dremio.sabot.driver.Pipeline.pumpOnce():99
    com.dremio.sabot.exec.fragment.FragmentExecutor$DoAsPumper.run():336
    com.dremio.sabot.exec.fragment.FragmentExecutor.run():285
    com.dremio.sabot.exec.fragment.FragmentExecutor.access$1200():92
    com.dremio.sabot.exec.fragment.FragmentExecutor$AsyncTaskImpl.run():679
    com.dremio.sabot.task.AsyncTaskWrapper.run():112
    com.dremio.sabot.task.slicing.SlicingThread.mainExecutionLoop():226
    com.dremio.sabot.task.slicing.SlicingThread.run():156
  Caused By (com.dremio.exec.exception.ClassTransformationException) Failure generating transformation classes for value: 
 
package com.dremio.s;

import com.dremio.exec.exception.SchemaChangeException;
import com.dremio.exec.expr.VectorResolver;
import com.dremio.exec.expr.fn.FunctionErrorContext;
import com.dremio.exec.record.VectorAccessible;
import com.dremio.sabot.exec.context.FunctionContext;
import com.dremio.sabot.op.join.nlje.MatchGenerator;
import org.apache.arrow.memory.ArrowBuf;
import org.apache.arrow.vector.BigIntVector;
import org.apache.arrow.vector.DecimalVector;
import org.apache.arrow.vector.holders.NullableBigIntHolder;
import org.apache.arrow.vector.holders.NullableBitHolder;
import org.apache.arrow.vector.holders.NullableDecimalHolder;

public class MatchGeneratorGen14407370
    extends MatchGenerator
{

    BigIntVector[] vv0;
    DecimalVector vv2;
    ArrowBuf work6;
    FunctionErrorContext work7;
    ArrowBuf work8;
    FunctionErrorContext work9;
    NullableBigIntHolder constant11;
    NullableBigIntHolder constant13;

    public MatchGeneratorGen14407370() {
        __INIT__();
    }

    public boolean doEval(int probeIndex, int buildIndex)
        throws SchemaChangeException
    {
        {
            NullableBigIntHolder out1 = new NullableBigIntHolder();
            {
                out1 .isSet = vv0 [((buildIndex)>>> 16)].isSet(((buildIndex)& 65535));
                if (out1 .isSet == 1) {
                    out1 .value = vv0 [((buildIndex)>>> 16)].get(((buildIndex)& 65535));
                }
            }
            NullableDecimalHolder out3 = new NullableDecimalHolder();
            {
                out3 .isSet = vv2 .isSet((probeIndex));
                if (out3 .isSet == 1) {
                    out3 .scale = 1;
                    out3 .precision = 22;
                    out3 .start = (16 *(probeIndex));
                    out3 .buffer = vv2 .getDataBuffer();
                }
            }
            NullableBitHolder out4 = new NullableBitHolder();
            AndOP0:
            {
                NullableBitHolder out5 = new NullableBitHolder();
                AndOP1:
                {
                    if ((out1 .isSet == 1)&&(out1 .value!= 1)) {
                        out5 .isSet = 1;
                        out5 .value = 0;
                        break AndOP1;
                    }
                    if ((out3 .isSet == 1)&&(out3 .value!= 1)) {
                        out5 .isSet = 1;
                        out5 .value = 0;
                        break AndOP1;
                    }
                    if ((out1 .isSet*out3 .isSet) == 0) {
                        out5 .isSet = 0;
                    } else {
                        out5 .isSet = 1;
                        out5 .value = 1;
                    }
                }
                if ((out5 .isSet == 1)&&(out5 .value!= 1)) {
                    out4 .isSet = 1;
                    out4 .value = 0;
                    break AndOP0;
                }
                //---- start of eval portion of castDECIMAL function. ----//
                NullableDecimalHolder out14 = new NullableDecimalHolder();
                {
                    if (((out1 .isSet*constant11 .isSet)*constant13 .isSet) == 0) {
                        out14 .isSet = 0;
                    } else {
                        final NullableDecimalHolder out = new NullableDecimalHolder();
                        NullableBigIntHolder in = out1;
                        NullableBigIntHolder precision = constant11;
                        NullableBigIntHolder scale = constant13;
                        ArrowBuf buffer = work8;
                        FunctionErrorContext errorContext = work9;
                         
DecimalFunctions$CastBigIntDecimal_eval: {
    java.math.BigDecimal bd = java.math.BigDecimal.valueOf(in.value).setScale((int) scale.value, java.math.RoundingMode.HALF_UP);

    try {
        org.apache.arrow.vector.util.DecimalUtility.writeBigDecimalToArrowBuf(bd, buffer, 0);
    } catch (RuntimeException e) {
        throw errorContext.error(e).build();
    }
    out.buffer = buffer;
    out.precision = (int) precision.value;
    out.scale = (int) scale.value;
}
 
                        work8 = buffer;
                        work9 = errorContext;
                        out.isSet = 1;
                        out14 = out;
                    }
                }
                //---- end of eval portion of castDECIMAL function. ----//
                //---- start of eval portion of divide function. ----//
                NullableDecimalHolder out15 = new NullableDecimalHolder();
                {
                    if ((out14 .isSet*out3 .isSet) == 0) {
                        out15 .isSet = 0;
                    } else {
                        final NullableDecimalHolder resultHolder = new NullableDecimalHolder();
                        NullableDecimalHolder leftHolder = out14;
                        NullableDecimalHolder rightHolder = out3;
                        ArrowBuf buffer = work6;
                        FunctionErrorContext functionErrorContext = work7;
                         
DecimalFunctions$DivideDecimals_eval: {
    int index = (leftHolder.start / (org.apache.arrow.vector.util.DecimalUtility.DECIMAL_BYTE_LENGTH));
    java.math.BigDecimal left = org.apache.arrow.vector.util.DecimalUtility.getBigDecimalFromArrowBuf(leftHolder.buffer, index, leftHolder.scale);

    index = (rightHolder.start / (org.apache.arrow.vector.util.DecimalUtility.DECIMAL_BYTE_LENGTH));

    java.math.BigDecimal right = org.apache.arrow.vector.util.DecimalUtility.getBigDecimalFromArrowBuf(rightHolder.buffer, index, rightHolder.scale);
    org.apache.arrow.vector.types.pojo.ArrowType.Decimal resultTypeForOperation = org.apache.arrow.gandiva.evaluator.DecimalTypeUtil.getResultTypeForOperation(org.apache.arrow.gandiva.evaluator.DecimalTypeUtil.OperationType.DIVIDE, new org.apache.arrow.vector.types.pojo.ArrowType.Decimal(leftHolder.precision, leftHolder.scale), new org.apache.arrow.vector.types.pojo.ArrowType.Decimal(rightHolder.precision, rightHolder.scale));

    resultHolder.precision = resultTypeForOperation.getPrecision();
    resultHolder.scale = resultTypeForOperation.getScale();
    if (resultHolder.scale > leftHolder.scale - rightHolder.scale) {
        left = left.setScale(resultHolder.scale + rightHolder.scale, java.math.BigDecimal.ROUND_UNNECESSARY);
    }

    java.math.BigInteger leftUnscaled = left.unscaledValue();
    java.math.BigInteger rightUnscaled = right.unscaledValue();
    java.math.BigInteger[] quotientAndRemainder = leftUnscaled.divideAndRemainder(rightUnscaled);
    java.math.BigInteger resultUnscaled = quotientAndRemainder[0];

    if (quotientAndRemainder[1].abs().multiply(java.math.BigInteger.valueOf(2)).compareTo(rightUnscaled.abs()) >= 0) {
        resultUnscaled = resultUnscaled.add(java.math.BigInteger.valueOf((leftUnscaled.signum() ^ rightUnscaled.signum()) + 1));
    }

    java.math.BigDecimal result = new java.math.BigDecimal(resultUnscaled, resultHolder.scale);

    result = com.dremio.exec.expr.fn.impl.DecimalFunctions.checkOverflow(result);
    try {
        org.apache.arrow.vector.util.DecimalUtility.writeBigDecimalToArrowBuf(result, buffer, 0);
    } catch (RuntimeException e) {
        throw functionErrorContext.error(e).build();
    }
    resultHolder.buffer = buffer;
}
 
                        work6 = buffer;
                        work7 = functionErrorContext;
                        resultHolder.isSet = 1;
                        out15 = resultHolder;
                    }
                }
                //---- end of eval portion of divide function. ----//
                //---- start of eval portion of isnotnull function. ----//
                NullableBitHolder out16 = new NullableBitHolder();
                {
                    final NullableBitHolder out = new NullableBitHolder();
                    NullableDecimalHolder input = out15;
                     
GNullOpNullableDecimalHolder$IsNotNull_eval: {
    out.isSet = 1;
    out.value = (input.isSet == 0 ? 0 : 1);
}
 
                    out16 = out;
                }
                //---- end of eval portion of isnotnull function. ----//
                if ((out16 .isSet == 1)&&(out16 .value!= 1)) {
                    out4 .isSet = 1;
                    out4 .value = 0;
                    break AndOP0;
                }
                if ((out5 .isSet*out16 .isSet) == 0) {
                    out4 .isSet = 0;
                } else {
                    out4 .isSet = 1;
                    out4 .value = 1;
                }
            }
            if ((out4 .isSet == 1)&&(out4 .value == 1)) {
                return true;
            }
            return false;
        }
    }

    public void doSetup(FunctionContext context, VectorAccessible probeVectorAccessible, VectorAccessible buildVectorAccessible)
        throws SchemaChangeException
    {
        {
            vv0 = ((BigIntVector[]) VectorResolver.hyper((buildVectorAccessible), BigIntVector.class, 0));
            vv2 = ((DecimalVector) VectorResolver.simple((probeVectorAccessible), DecimalVector.class, 3));
            work6 = (context).getManagedBuffer();
            work7 = (context).getFunctionErrorContext(0);
            work8 = (context).getManagedBuffer();
            work9 = (context).getFunctionErrorContext(1);
            NullableBigIntHolder out10 = new NullableBigIntHolder();
            out10 .value = 19L;
            out10 .isSet = 1;
            constant11 = out10;
            NullableBigIntHolder out12 = new NullableBigIntHolder();
            out12 .value = 0L;
            out12 .isSet = 1;
            constant13 = out12;
            /** start SETUP for function castDECIMAL **/ 
            {
                NullableBigIntHolder precision = constant11;
                NullableBigIntHolder scale = constant13;
                ArrowBuf buffer = work8;
                FunctionErrorContext errorContext = work9;
                 
DecimalFunctions$CastBigIntDecimal_setup: {
    buffer = buffer.reallocIfNeeded(16);
}
 
                work8 = buffer;
                work9 = errorContext;
            }
            /** end SETUP for function castDECIMAL **/ 
            /** start SETUP for function divide **/ 
            {
                ArrowBuf buffer = work6;
                FunctionErrorContext functionErrorContext = work7;
                 
DecimalFunctions$DivideDecimals_setup: {
    buffer = buffer.reallocIfNeeded(16);
}
 
                work6 = buffer;
                work7 = functionErrorContext;
            }
            /** end SETUP for function divide **/ 
            /** start SETUP for function isnotnull **/ 
            {
                 {}
            }
            /** end SETUP for function isnotnull **/ 
        }
    }

    public void __INIT__()
        throws SchemaChangeException
    {
    }

}

hi @balaji.ramaswamy can you help here.

@ashish.sharma2

This looks like an issue we fixed in 12.0 and above. What versions of Dremio is this? Can you please share the query profile? Also if there is a decimal column, can you try to CAST to FLOAT, save as VDS and try the same query on the VDS?

Thanks for the advice mate, will try and get back to you.