# Buggy code
def update(self, other: "DataFrame", join: str = "left", overwrite: bool = True):
    """
    Modify in place using non-NA values from another DataFrame.
    Aligns on indices. There is no return value.

    Parameters
    ----------
    other : DataFrame, or Series
    join : 'left', default 'left'
        Only left join is implemented, keeping the index and columns of the original object.
    overwrite : bool, default True
        How to handle non-NA values for overlapping keys:

        * True: overwrite original DataFrame's values with values from `other`.
        * False: only update values that are NA in the original DataFrame.

    Returns
    -------
    None : method directly changes calling object

    See Also
    --------
    DataFrame.merge : For column(s)-on-columns(s) operations.

    Examples
    --------
    >>> df = ks.DataFrame({'A': [1, 2, 3], 'B': [400, 500, 600]}, columns=['A', 'B'])
    >>> new_df = ks.DataFrame({'B': [4, 5, 6], 'C': [7, 8, 9]}, columns=['B', 'C'])
    >>> df.update(new_df)
    >>> df
       A  B
    0  1  4
    1  2  5
    2  3  6

    The DataFrame's length does not increase as a result of the update,
    only values at matching index/column labels are updated.

    >>> df = ks.DataFrame({'A': ['a', 'b', 'c'], 'B': ['x', 'y', 'z']}, columns=['A', 'B'])
    >>> new_df = ks.DataFrame({'B': ['d', 'e', 'f', 'g', 'h', 'i']}, columns=['B'])
    >>> df.update(new_df)
    >>> df
       A  B
    0  a  d
    1  b  e
    2  c  f

    For Series, it's name attribute must be set.

    >>> df = ks.DataFrame({'A': ['a', 'b', 'c'], 'B': ['x', 'y', 'z']}, columns=['A', 'B'])
    >>> new_column = ks.Series(['d', 'e'], name='B', index=[0, 2])
    >>> df.update(new_column)
    >>> df
       A  B
    0  a  d
    1  b  y
    2  c  e

    If `other` contains None the corresponding values are not updated in the original dataframe.

    >>> df = ks.DataFrame({'A': [1, 2, 3], 'B': [400, 500, 600]}, columns=['A', 'B'])
    >>> new_df = ks.DataFrame({'B': [4, None, 6]}, columns=['B'])
    >>> df.update(new_df)
    >>> df
       A      B
    0  1    4.0
    1  2  500.0
    2  3    6.0
    """
    if join != "left":
        raise NotImplementedError("Only left join is supported")

    if isinstance(other, ks.Series):
        other = DataFrame(other)

    update_columns = list(
        set(self._internal.data_columns).intersection(set(other._internal.data_columns))
    )
    update_sdf = self.join(other[update_columns], rsuffix="_new")._sdf

    for column_name in update_columns:
        old_col = update_sdf[column_name]
        new_col = update_sdf[column_name + "_new"]
        if overwrite:
            update_sdf = update_sdf.withColumn(
                column_name, F.when(new_col.isNull(), old_col).otherwise(new_col)
            )
        else:
            update_sdf = update_sdf.withColumn(
                column_name, F.when(old_col.isNull(), new_col).otherwise(old_col)
            )
    internal = self._internal.copy(sdf=update_sdf.select(self._internal.columns))
    self._internal = internal


# Traceback (KeyError)
df = ks.read_parquet("/mnt/ivan/sample.parquet")
df['a.b']

# KeyError: 'a.b'
# ---------------------------------------------------------------------------
# KeyError                                  Traceback (most recent call last)
# <command-3188040896828876> in <module>()
#       1 df = ks.read_parquet("/mnt/ivan/sample.parquet")
# ----> 2 df['a.b']
#
# /databricks/python/lib/python3.5/site-packages/databricks/koalas/frame.py in __getitem__(self, key)
#     448
#     449     def __getitem__(self, key):
# --> 450         return self._pd_getitem(key)
#     451
#     452     def __setitem__(self, key, value):
#
# /databricks/python/lib/python3.5/site-packages/databricks/koalas/frame.py in _pd_getitem(self, key)
#     427                 return Series(self._sdf.__getitem__(key), self, self._metadata.index_info)
#     428             except AnalysisException:
# --> 429                 raise KeyError(key)
#     430         if np.isscalar(key) or isinstance(key, (tuple, string_types)):
#     431             raise NotImplementedError(key)
#
# KeyError: 'a.b'

# Fixed code
def update(self, other: "DataFrame", join: str = "left", overwrite: bool = True):
    """
    Modify in place using non-NA values from another DataFrame.
    Aligns on indices. There is no return value.

    Parameters
    ----------
    other : DataFrame, or Series
    join : 'left', default 'left'
        Only left join is implemented, keeping the index and columns of the original object.
    overwrite : bool, default True
        How to handle non-NA values for overlapping keys:

        * True: overwrite original DataFrame's values with values from `other`.
        * False: only update values that are NA in the original DataFrame.

    Returns
    -------
    None : method directly changes calling object

    See Also
    --------
    DataFrame.merge : For column(s)-on-columns(s) operations.

    Examples
    --------
    >>> df = ks.DataFrame({'A': [1, 2, 3], 'B': [400, 500, 600]}, columns=['A', 'B'])
    >>> new_df = ks.DataFrame({'B': [4, 5, 6], 'C': [7, 8, 9]}, columns=['B', 'C'])
    >>> df.update(new_df)
    >>> df
       A  B
    0  1  4
    1  2  5
    2  3  6

    The DataFrame's length does not increase as a result of the update,
    only values at matching index/column labels are updated.

    >>> df = ks.DataFrame({'A': ['a', 'b', 'c'], 'B': ['x', 'y', 'z']}, columns=['A', 'B'])
    >>> new_df = ks.DataFrame({'B': ['d', 'e', 'f', 'g', 'h', 'i']}, columns=['B'])
    >>> df.update(new_df)
    >>> df
       A  B
    0  a  d
    1  b  e
    2  c  f

    For Series, it's name attribute must be set.

    >>> df = ks.DataFrame({'A': ['a', 'b', 'c'], 'B': ['x', 'y', 'z']}, columns=['A', 'B'])
    >>> new_column = ks.Series(['d', 'e'], name='B', index=[0, 2])
    >>> df.update(new_column)
    >>> df
       A  B
    0  a  d
    1  b  y
    2  c  e

    If `other` contains None the corresponding values are not updated in the original dataframe.

    >>> df = ks.DataFrame({'A': [1, 2, 3], 'B': [400, 500, 600]}, columns=['A', 'B'])
    >>> new_df = ks.DataFrame({'B': [4, None, 6]}, columns=['B'])
    >>> df.update(new_df)
    >>> df
       A      B
    0  1    4.0
    1  2  500.0
    2  3    6.0
    """
    if join != "left":
        raise NotImplementedError("Only left join is supported")

    if isinstance(other, ks.Series):
        other = DataFrame(other)

    update_columns = list(
        set(self._internal.data_columns).intersection(set(other._internal.data_columns))
    )
    update_sdf = self.join(other[update_columns], rsuffix="_new")._sdf

    for column_name in update_columns:
        old_col = scol_for(update_sdf, column_name)
        new_col = scol_for(update_sdf, column_name + "_new")
        if overwrite:
            update_sdf = update_sdf.withColumn(
                column_name, F.when(new_col.isNull(), old_col).otherwise(new_col)
            )
        else:
            update_sdf = update_sdf.withColumn(
                column_name, F.when(old_col.isNull(), new_col).otherwise(old_col)
            )
    internal = self._internal.copy(
        sdf=update_sdf.select(
            [scol_for(update_sdf, col) for col in self._internal.columns]
        )
    )
    self._internal = internal