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)