Alessandro Solimando created CALCITE-7917:
---------------------------------------------

             Summary: RelMdSize returns a negative size for VARCHAR and 
VARBINARY without precision
                 Key: CALCITE-7917
                 URL: https://issues.apache.org/jira/browse/CALCITE-7917
             Project: Calcite
          Issue Type: Bug
          Components: core
    Affects Versions: 1.42.0
            Reporter: Alessandro Solimando
            Assignee: Alessandro Solimando
             Fix For: 1.43.0


_RelMdSize#averageTypeValueSize_ uses the precision of a string or binary type 
as its length 
([here|https://github.com/apache/calcite/blob/a7f3290b7fe2660fb9386a4fcdf2e624ae52ed63/core/src/main/java/org/apache/calcite/rel/metadata/RelMdSize.java#L347-L355]):
{code:java}
case BINARY:
  return (double) type.getPrecision();
case VARBINARY:
  return Math.min((double) type.getPrecision(), 100d);
case CHAR:
  return (double) type.getPrecision() * BYTES_PER_CHARACTER;
case VARCHAR:
  // Even in large (say VARCHAR(2000)) columns most strings are small
  return Math.min((double) type.getPrecision() * BYTES_PER_CHARACTER, 100d);
{code}
Since CALCITE-1684, the default precision of VARCHAR and VARBINARY is 
{_}RelDataType.PRECISION_NOT_SPECIFIED{_}, which is -1 
([here|https://github.com/apache/calcite/blob/a7f3290b7fe2660fb9386a4fcdf2e624ae52ed63/core/src/main/java/org/apache/calcite/rel/type/RelDataTypeSystemImpl.java#L109-L111]).
 The estimated size is then -2 bytes for VARCHAR and -1 byte for VARBINARY. 
CHAR and BINARY have the same problem with a type system whose default 
precision for them is {_}PRECISION_NOT_SPECIFIED{_}.

These negative estimates can propagate into _getAverageColumnSizes_ and 
_getAverageRowSize_.

Reproducer (for {_}RelMetadataTest{_}):
{code:java}
@Test void testSizeWithoutPrecision() {
  checkSize("SELECT CAST(empno AS VARCHAR) FROM emp", 100d);
}
{code}
The test currently fails as follows:
{noformat}
Expected: is <100.0>
     but: was <-2.0>
{noformat}
Proposed fix: when the precision of a CHARACTER or BINARY family type is 
{_}PRECISION_NOT_SPECIFIED{_}, use a default estimate of 100 bytes. This 
matches the existing estimates for VARCHAR and VARBINARY with large precisions 
([here|https://github.com/apache/calcite/blob/a7f3290b7fe2660fb9386a4fcdf2e624ae52ed63/core/src/main/java/org/apache/calcite/rel/metadata/RelMdSize.java#L349-L355]).
 It is a fallback estimate when the length is unspecified, not an average size 
derived from the type.




--
This message was sent by Atlassian Jira
(v10.3.26#10030026)

Reply via email to