docs: @Override
      public Optional<Type> coerceTypeBase(Type sourceType, String resultTypeBase)
      {
          String sourceTypeName = sourceType.getTypeSignature().getBase();
          if (sourceTypeName.equals(resultTypeBase)) {
              return Optional.of(sourceType);
          }
  
          switch (sourceTypeName) {
              case UnknownType.NAME: {
                  switch (resultTypeBase) {
                      case StandardTypes.BOOLEAN:
                      case StandardTypes.BIGINT:
                      case StandardTypes.INTEGER:
                      case StandardTypes.DOUBLE:
                      case StandardTypes.REAL:
                      case StandardTypes.VARBINARY:
                      case StandardTypes.DATE:
                      case StandardTypes.TIME:
                      case StandardTypes.TIME_WITH_TIME_ZONE:
                      case StandardTypes.TIMESTAMP:
                      case StandardTypes.TIMESTAMP_WITH_TIME_ZONE:
                      case StandardTypes.HYPER_LOG_LOG:
                      case SetDigestType.NAME:
                      case StandardTypes.P4_HYPER_LOG_LOG:
                      case StandardTypes.JSON:
                      case StandardTypes.INTERVAL_YEAR_TO_MONTH:
                      case StandardTypes.INTERVAL_DAY_TO_SECOND:
                      case JoniRegexpType.NAME:
                      case LikePatternType.NAME:
                      case JsonPathType.NAME:
                      case ColorType.NAME:
                      case CodePointsType.NAME:
                          return Optional.of(getType(new TypeSignature(resultTypeBase)));
                      case StandardTypes.VARCHAR:
                          return Optional.of(createVarcharType(0));
                      case StandardTypes.CHAR:
                          return Optional.of(createCharType(0));
                      case StandardTypes.DECIMAL:
                          return Optional.of(createDecimalType(1, 0));
                      default:
                          return Optional.empty();
                  }
              }
              case StandardTypes.TINYINT: {
                  switch (resultTypeBase) {
                      case StandardTypes.SMALLINT:
                          return Optional.of(SMALLINT);
                      case StandardTypes.INTEGER:
                          return Optional.of(INTEGER);
                      case StandardTypes.BIGINT:
                          return Optional.of(BIGINT);
                      case StandardTypes.REAL:
                          return Optional.of(REAL);
                      case StandardTypes.DOUBLE:
                          return Optional.of(DOUBLE);
                      case StandardTypes.DECIMAL:
                          return Optional.of(createDecimalType(3, 0));
                      default:
                          return Optional.empty();
                  }
              }
              case StandardTypes.SMALLINT: {
                  switch (resultTypeBase) {
                      case StandardTypes.INTEGER:
                          return Optional.of(INTEGER);
                      case StandardTypes.BIGINT:
                          return Optional.of(BIGINT);
                      case StandardTypes.REAL:
                          return Optional.of(REAL);
                      case StandardTypes.DOUBLE:
                          return Optional.of(DOUBLE);
                      case StandardTypes.DECIMAL:
                          return Optional.of(createDecimalType(5, 0));
                      default:
                          return Optional.empty();
                  }
              }
              case StandardTypes.INTEGER: {
                  switch (resultTypeBase) {
                      case StandardTypes.BIGINT:
                          return Optional.of(BIGINT);
                      case StandardTypes.REAL:
                          return Optional.of(REAL);
                      case StandardTypes.DOUBLE:
                          return Optional.of(DOUBLE);
                      case StandardTypes.DECIMAL:
                          return Optional.of(createDecimalType(10, 0));
                      default:
                          return Optional.empty();
                  }
              }
              case StandardTypes.BIGINT: {
                  switch (resultTypeBase) {
                      case StandardTypes.REAL:
                          return Optional.of(REAL);
                      case StandardTypes.DOUBLE:
                          return Optional.of(DOUBLE);
                      case StandardTypes.DECIMAL:
                          return Optional.of(createDecimalType(19, 0));
                      default:
                          return Optional.empty();
                  }
              }
              case StandardTypes.DECIMAL: {
                  switch (resultTypeBase) {
                      case StandardTypes.REAL:
                          return Optional.of(REAL);
                      case StandardTypes.DOUBLE:
                          return Optional.of(DOUBLE);
                      default:
                          return Optional.empty();
                  }
              }
              case StandardTypes.REAL: {
                  switch (resultTypeBase) {
                      case StandardTypes.DOUBLE:
                          return Optional.of(DOUBLE);
                      default:
                          return Optional.empty();
                  }
              }
              case StandardTypes.DATE: {
                  switch (resultTypeBase) {
                      case StandardTypes.TIMESTAMP:
                          return Optional.of(TIMESTAMP);
                      case StandardTypes.TIMESTAMP_WITH_TIME_ZONE:
                          return Optional.of(TIMESTAMP_WITH_TIME_ZONE);
                      default:
                          return Optional.empty();
                  }
              }
              case StandardTypes.TIME: {
                  switch (resultTypeBase) {
                      case StandardTypes.TIME_WITH_TIME_ZONE:
                          return Optional.of(TIME_WITH_TIME_ZONE);
                      default:
                          return Optional.empty();
                  }
              }
              case StandardTypes.TIMESTAMP: {
                  switch (resultTypeBase) {
                      case StandardTypes.TIMESTAMP_WITH_TIME_ZONE:
                          return Optional.of(TIMESTAMP_WITH_TIME_ZONE);
                      default:
                          return Optional.empty();
                  }
              }
              case StandardTypes.VARCHAR: {
                  switch (resultTypeBase) {
                      case StandardTypes.CHAR:
                          if (featuresConfig.isLegacyCharToVarcharCoercion()) {
                              return Optional.empty();
                          }
  
                          VarcharType varcharType = (VarcharType) sourceType;
                          if (varcharType.isUnbounded()) {
                              return Optional.of(CharType.createCharType(CharType.MAX_LENGTH));
                          }
  
                          return Optional.of(createCharType(Math.min(CharType.MAX_LENGTH, varcharType.getLengthSafe())));
                      case JoniRegexpType.NAME:
                          return Optional.of(JONI_REGEXP);
                      case Re2JRegexpType.NAME:
                          return Optional.of(RE2J_REGEXP);
                      case LikePatternType.NAME:
                          return Optional.of(LIKE_PATTERN);
                      case JsonPathType.NAME:
                          return Optional.of(JSON_PATH);
                      case CodePointsType.NAME:
                          return Optional.of(CODE_POINTS);
                      default:
                          return Optional.empty();
                  }
              }
              case StandardTypes.CHAR: {
                  switch (resultTypeBase) {
                      case StandardTypes.VARCHAR:
                          if (!featuresConfig.isLegacyCharToVarcharCoercion()) {
                              return Optional.empty();
                          }
  
                          CharType charType = (CharType) sourceType;
                          return Optional.of(createVarcharType(charType.getLength()));
                      case JoniRegexpType.NAME:
                          return Optional.of(JONI_REGEXP);
                      case Re2JRegexpType.NAME:
                          return Optional.of(RE2J_REGEXP);
                      case LikePatternType.NAME:
                          return Optional.of(LIKE_PATTERN);
                      case JsonPathType.NAME:
                          return Optional.of(JSON_PATH);
                      case CodePointsType.NAME:
                          return Optional.of(CODE_POINTS);
                      default:
                          return Optional.empty();
                  }
              }
              case StandardTypes.P4_HYPER_LOG_LOG: {
                  switch (resultTypeBase) {
                      case StandardTypes.HYPER_LOG_LOG:
                          return Optional.of(HYPER_LOG_LOG);
                      default:
                          return Optional.empty();
                  }
              }
              default:
                  return Optional.empty();
          }
      }