prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  DB function to edit column names
  **Problem**
  <!-- Please provide a clear and concise description of the problem that this feature request is designed to solve.-->
  The user might want to edit column names.
  
  **Proposed solution**
  <!-- A clear and concise description of your proposed solution or feature. -->
  We need a `db` function to allow the user to edit the name of a column. We need to check and fix foreign keys and other references to the column.
  
  </issue>
  <code>
  [start of db/columns.py]
  1 from sqlalchemy import Column, Integer, ForeignKey
  2 from db import constants
  3 
  4 
  5 NULLABLE = "nullable"
  6 PRIMARY_KEY = "primary_key"
  7 TYPE = "type"
  8 
  9 ID_TYPE = Integer
  10 DEFAULT_COLUMNS = {
  11     constants.ID: {TYPE: ID_TYPE, PRIMARY_KEY: True, NULLABLE: False}
  12 }
  13 
  14 
  15 class MathesarColumn(Column):
  16     """
  17     This class constrains the possible arguments, enabling us to include
  18     a copy method (which has been deprecated in upstream SQLAlchemy since
  19     1.4).  The idea is that we can faithfully copy the subset of the
  20     column definition that we care about, and this class defines that
  21     subset.
  22     """
  23     def __init__(
  24             self,
  25             name,
  26             sa_type,
  27             foreign_keys=set(),
  28             primary_key=False,
  29             nullable=True,
  30     ):
  31         """
  32         Construct a new ``MathesarColumn`` object.
  33 
  34         Required arguments:
  35         name -- String giving the name of the column in the database.
  36         sa_type -- the SQLAlchemy type of the column.
  37 
  38         Optional keyword arguments:
  39         primary_key -- Boolean giving whether the column is a primary key.
  40         """
  41         super().__init__(
  42             *foreign_keys,
  43             name=name,
  44             type_=sa_type,
  45             primary_key=primary_key,
  46             nullable=nullable,
  47         )
  48 
  49     @classmethod
  50     def from_column(cls, column):
  51         """
  52         This alternate init method creates a new column (a copy) of the
  53         given column.  It respects only the properties in the __init__
  54         of the MathesarColumn.
  55         """
  56         fkeys = {ForeignKey(fk.target_fullname) for fk in column.foreign_keys}
  57         return cls(
  58             column.name,
  59             column.type,
  60             foreign_keys=fkeys,
  61             primary_key=column.primary_key,
  62             nullable=column.nullable,
  63         )
  64 
  65     @property
  66     def is_default(self):
  67         default_def = DEFAULT_COLUMNS.get(self.name, False)
  68         return (
  69             default_def
  70             and self.type.python_type == default_def[TYPE]().python_type
  71             and self.primary_key == default_def.get(PRIMARY_KEY, False)
  72             and self.nullable == default_def.get(NULLABLE, True)
  73         )
  74 
  75 
  76 def get_default_mathesar_column_list():
  77     return [
  78         MathesarColumn(
  79             c,
  80             DEFAULT_COLUMNS[c][TYPE],
  81             primary_key=DEFAULT_COLUMNS[c][PRIMARY_KEY]
  82         )
  83         for c in DEFAULT_COLUMNS
  84     ]
  85 
  86 
  87 def init_mathesar_table_column_list_with_defaults(column_list):
  88     default_columns = get_default_mathesar_column_list()
  89     given_columns = [MathesarColumn.from_column(c) for c in column_list]
  90     return default_columns + given_columns
  91
  [end of db/columns.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/db/columns.py b/db/columns.py
  --- a/db/columns.py
  +++ b/db/columns.py
  @@ -1,4 +1,4 @@
  -from sqlalchemy import Column, Integer, ForeignKey
  +from sqlalchemy import Column, Integer, ForeignKey, Table, DDL, MetaData
   from db import constants
   
   
  @@ -88,3 +88,19 @@
       default_columns = get_default_mathesar_column_list()
       given_columns = [MathesarColumn.from_column(c) for c in column_list]
       return default_columns + given_columns
  +
  +
  +def rename_column(schema, table_name, column_name, new_column_name, engine):
  +    _preparer = engine.dialect.identifier_preparer
  +    with engine.begin() as conn:
  +        metadata = MetaData(bind=engine, schema=schema)
  +        table = Table(table_name, metadata, schema=schema, autoload_with=engine)
  +        column = table.columns[column_name]
  +        prepared_table_name = _preparer.format_table(table)
  +        prepared_column_name = _preparer.format_column(column)
  +        prepared_new_column_name = _preparer.quote(new_column_name)
  +        alter_stmt = f"""
  +        ALTER TABLE {prepared_table_name}
  +        RENAME {prepared_column_name} TO {prepared_new_column_name}
  +        """
  +        conn.execute(DDL(alter_stmt))
  
verification_info: {"golden_diff": "diff --git a/db/columns.py b/db/columns.py\n--- a/db/columns.py\n+++ b/db/columns.py\n@@ -1,4 +1,4 @@\n-from sqlalchemy import Column, Integer, ForeignKey\n+from sqlalchemy import Column, Integer, ForeignKey, Table, DDL, MetaData\n from db import constants\n \n \n@@ -88,3 +88,19 @@\n     default_columns = get_default_mathesar_column_list()\n     given_columns = [MathesarColumn.from_column(c) for c in column_list]\n     return default_columns + given_columns\n+\n+\n+def rename_column(schema, table_name, column_name, new_column_name, engine):\n+    _preparer = engine.dialect.identifier_preparer\n+    with engine.begin() as conn:\n+        metadata = MetaData(bind=engine, schema=schema)\n+        table = Table(table_name, metadata, schema=schema, autoload_with=engine)\n+        column = table.columns[column_name]\n+        prepared_table_name = _preparer.format_table(table)\n+        prepared_column_name = _preparer.format_column(column)\n+        prepared_new_column_name = _preparer.quote(new_column_name)\n+        alter_stmt = f\"\"\"\n+        ALTER TABLE {prepared_table_name}\n+        RENAME {prepared_column_name} TO {prepared_new_column_name}\n+        \"\"\"\n+        conn.execute(DDL(alter_stmt))\n", "issue": "DB function to edit column names\n**Problem**\r\n<!-- Please provide a clear and concise description of the problem that this feature request is designed to solve.-->\r\nThe user might want to edit column names.\r\n\r\n**Proposed solution**\r\n<!-- A clear and concise description of your proposed solution or feature. -->\r\nWe need a `db` function to allow the user to edit the name of a column. We need to check and fix foreign keys and other references to the column.\n", "before_files": [{"content": "from sqlalchemy import Column, Integer, ForeignKey\nfrom db import constants\n\n\nNULLABLE = \"nullable\"\nPRIMARY_KEY = \"primary_key\"\nTYPE = \"type\"\n\nID_TYPE = Integer\nDEFAULT_COLUMNS = {\n    constants.ID: {TYPE: ID_TYPE, PRIMARY_KEY: True, NULLABLE: False}\n}\n\n\nclass MathesarColumn(Column):\n    \"\"\"\n    This class constrains the possible arguments, enabling us to include\n    a copy method (which has been deprecated in upstream SQLAlchemy since\n    1.4).  The idea is that we can faithfully copy the subset of the\n    column definition that we care about, and this class defines that\n    subset.\n    \"\"\"\n    def __init__(\n            self,\n            name,\n            sa_type,\n            foreign_keys=set(),\n            primary_key=False,\n            nullable=True,\n    ):\n        \"\"\"\n        Construct a new ``MathesarColumn`` object.\n\n        Required arguments:\n        name -- String giving the name of the column in the database.\n        sa_type -- the SQLAlchemy type of the column.\n\n        Optional keyword arguments:\n        primary_key -- Boolean giving whether the column is a primary key.\n        \"\"\"\n        super().__init__(\n            *foreign_keys,\n            name=name,\n            type_=sa_type,\n            primary_key=primary_key,\n            nullable=nullable,\n        )\n\n    @classmethod\n    def from_column(cls, column):\n        \"\"\"\n        This alternate init method creates a new column (a copy) of the\n        given column.  It respects only the properties in the __init__\n        of the MathesarColumn.\n        \"\"\"\n        fkeys = {ForeignKey(fk.target_fullname) for fk in column.foreign_keys}\n        return cls(\n            column.name,\n            column.type,\n            foreign_keys=fkeys,\n            primary_key=column.primary_key,\n            nullable=column.nullable,\n        )\n\n    @property\n    def is_default(self):\n        default_def = DEFAULT_COLUMNS.get(self.name, False)\n        return (\n            default_def\n            and self.type.python_type == default_def[TYPE]().python_type\n            and self.primary_key == default_def.get(PRIMARY_KEY, False)\n            and self.nullable == default_def.get(NULLABLE, True)\n        )\n\n\ndef get_default_mathesar_column_list():\n    return [\n        MathesarColumn(\n            c,\n            DEFAULT_COLUMNS[c][TYPE],\n            primary_key=DEFAULT_COLUMNS[c][PRIMARY_KEY]\n        )\n        for c in DEFAULT_COLUMNS\n    ]\n\n\ndef init_mathesar_table_column_list_with_defaults(column_list):\n    default_columns = get_default_mathesar_column_list()\n    given_columns = [MathesarColumn.from_column(c) for c in column_list]\n    return default_columns + given_columns\n", "path": "db/columns.py"}]}