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

Abhishek Singh Chouhan commented on CALCITE-5690:
-------------------------------------------------

> Does {{RelDataTypeHolder}} claim to be thread-safe? Is its implementation 
>actually thread-safe? Does the code using it need to be thread-safe, and if 
>so, did it make a mistake using a non-thread-safe class?

RelDataTypeHolder is not thread safe. None of the associated documentation 
suggests/claims thread-safety as well. 

I believe RelDataTypeFactoryImpl assumes that the type is immutable 
([here|[https://github.com/apache/calcite/blob/main/core/src/main/java/org/apache/calcite/rel/type/RelDataTypeFactoryImpl.java#L402]]
 and 
[here|[https://github.com/apache/calcite/blob/main/core/src/main/java/org/apache/calcite/rel/type/RelDataTypeFactoryImpl.java#L421]).]
  The datatype cache is interning the type assuming immutable objects, however 
the DynamicRecordTypeImpl is mutable. Maybe we should skip interning 
DynamicRecordTypeImpl?

> ConcurrentModificationException during validation of table with 
> DynamicRecordType
> ---------------------------------------------------------------------------------
>
>                 Key: CALCITE-5690
>                 URL: https://issues.apache.org/jira/browse/CALCITE-5690
>             Project: Calcite
>          Issue Type: Bug
>    Affects Versions: 1.32.0
>            Reporter: Abhishek Singh Chouhan
>            Priority: Major
>
> When multiple threads are doing validation on a Table with 
> DynamicRecordTypeImpl, we run into a ConcurrentModificationException. One of 
> the instances where this happens is when two validations are happening in 
> parallel 
> Thread1 - 
> SELECT DS_GET_QUANTILE(DS_QUANTILES_SKETCH(COL1), 0.9) FROM TABLE1 GROUP BY 
> COL1, COL2, COL3
> Thread2 - SELECT DS_GET_QUANTILE(DS_QUANTILES_SKETCH(COL1), 0.9) FROM TABLE1 
> GROUP BY COL1, COL2
> While expanding the groupby in thread1 we intern the type at multiple places, 
> eg. DelegatingScope#fullyQualify -> SqlValidatorScope#rowType -> 
> RelDataTypeFactoryImpl#createTypeWithNullability -> canonize
> During the validation in thread1 we cache DynamicRecordTypeImpl with Col1 and 
> Col2 as the fields.
> The race condition happens when thread2 gets a hold of this(abovementioned) 
> cached DynamicRecordTypeImpl during its validation and is iterating over the 
> fields eg during SqlValidatorImpl.validateGroupItem and thread 1 then goes 
> and inserts Col3 field in the holder.
> {code:java}
> java.util.ConcurrentModificationException
>     at 
> java.base/java.util.ArrayList$Itr.checkForComodification(ArrayList.java:1043)
>     at java.base/java.util.ArrayList$Itr.next(ArrayList.java:997)
>     at 
> org.apache.calcite.rel.type.RelDataTypeHolder.getFieldOrInsert(RelDataTypeHolder.java:56)
>     at 
> org.apache.calcite.rel.type.DynamicRecordTypeImpl.getField(DynamicRecordTypeImpl.java:59)
>     at 
> org.apache.calcite.sql.validate.SqlNameMatchers$BaseMatcher.field(SqlNameMatchers.java:126)
>     at 
> org.apache.calcite.sql.validate.SqlValidatorImpl$DeriveTypeVisitor.visit(SqlValidatorImpl.java:6455)
>     at 
> org.apache.calcite.sql.validate.SqlValidatorImpl$DeriveTypeVisitor.visit(SqlValidatorImpl.java:6360)
>     at org.apache.calcite.sql.SqlIdentifier.accept(SqlIdentifier.java:324)
>     at 
> org.apache.calcite.sql.validate.SqlValidatorImpl.deriveTypeImpl(SqlValidatorImpl.java:1869)
>     at 
> org.apache.calcite.sql.validate.SqlValidatorImpl.deriveType(SqlValidatorImpl.java:1854)
>     at 
> org.apache.calcite.sql.validate.SqlValidatorImpl.validateGroupItem(SqlValidatorImpl.java:4393)
>     at 
> org.apache.calcite.sql.validate.SqlValidatorImpl.validateGroupClause(SqlValidatorImpl.java:4366)
>     at 
> org.apache.calcite.sql.validate.SqlValidatorImpl.validateSelect(SqlValidatorImpl.java:3701)
>     at 
> org.apache.calcite.sql.validate.SelectNamespace.validateImpl(SelectNamespace.java:64)
>     at 
> org.apache.calcite.sql.validate.AbstractNamespace.validate(AbstractNamespace.java:89)
>     at 
> org.apache.calcite.sql.validate.SqlValidatorImpl.validateNamespace(SqlValidatorImpl.java:1107)
>     at 
> org.apache.calcite.sql.validate.SqlValidatorImpl.validateQuery(SqlValidatorImpl.java:1078)
>     at org.apache.calcite.sql.SqlSelect.validate(SqlSelect.java:248)
>     at 
> org.apache.calcite.sql.validate.SqlValidatorImpl.validateScopedExpression(SqlValidatorImpl.java:1053)
>     at 
> org.apache.calcite.sql.validate.SqlValidatorImpl.validate(SqlValidatorImpl.java:759)
>  {code}
>  



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

Reply via email to