Got exception when write custom udaf with @workspace VarcharHolder filed

Caused by: java.lang.IllegalStateException: Workspace variable ‘acc’ in aggregation function ‘concat_col’ is not allowed to have variable length type.
at com.google.common.base.Preconditions.checkState(Preconditions.java:824)
at com.dremio.exec.expr.fn.AggrFunctionHolder.declareWorkspaceVectors(AggrFunctionHolder.java:160)

I find the reason is that VarcharHolder isn’t VariableWidthScalar, is there any suggestions on how to write a udaf which return varchar type?

Probably faced the same problem.
We wrote a function analogous to string_agg.
On a request, it is executed correctly, and on a complex one, it fails with the same simple error.

In the plan of the request, the difference is visible:
successful requests go through the step StreamAgg,
unsuccessful equests go through the step .

This error is a consequence of one of the checks in HashAgg.

An error is thrown in the method:

com.dremio.exec.expr.fn.AggrFunctionHolder - declareWorkspaceVectors.

Call line:

Preconditions.checkState(workspaceVars[i].completeType.isFixedWidthScalar(), <…>

Сheck method (if it returns false, then there will be an error):

com.dremio.common.expression.CompleteType

public boolean isFixedWidthScalar() {
switch(type.getTypeID()){
case List:
case Struct:
case Union:
case Binary:
case Utf8:
return false;
default:
return true;
}
}

Dremio has a deprecated class - Object Holder. You can use it (it is used in similar functions). It’s a bit crazy, but in our case it worked, we just wrapped the forbidden NullableVarcharHolder in it. Here’s an example of a piece of code:

@Param
NullableVarCharHolder in;

@Param(constant = true)
VarCharHolder delimiter;

@Workspace
ObjectHolder inter;

@Output
NullableVarCharHolder out;

@Inject
ArrowBuf buffer;

@Workspace
private BitHolder firstAdd;

public void setup() {
  ObjectHolder objectHolder = new ObjectHolder();
  objectHolder.obj = new NullableVarCharHolder();
  inter = objectHolder;
  ((NullableVarCharHolder)inter.obj).buffer = buffer;
  ((NullableVarCharHolder)inter.obj).end = ((NullableVarCharHolder)inter.obj).start = 0;
  ((NullableVarCharHolder)inter.obj).isSet = 1;
  firstAdd.value = 1;
}