prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Type Inference 1:  Check column against a type
  **Problem**
  <!-- Please provide a clear and concise description of the problem that this feature request is designed to solve.-->
  
  Different types in Mathesar will enable different operations; for example, strings could be aggregated by concatenating, but numeric types could be aggregated by summing or multiplying.  So far, while we can reflect different types, we have no way to determine the type most appropriate for a column.
  
  **Proposed solution**
  <!-- A clear and concise description of your proposed solution or feature. -->
  
  Given a `schema`, `table_name`, `column_name`, and `type`, we need to be able to return a boolean giving whether the column can be cast to that type.
  
  **Additional context**
  <!-- Add any other context or screenshots about the feature request here.-->
  
  We may need to take an optional sample size parameter to do this for large data.  Performance testing will be necessary.
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `db/types/base.py`
  Content:
  ```
  1 from sqlalchemy import create_engine
  2 from db import constants
  3 
  4 SCHEMA = f"{constants.MATHESAR_PREFIX}types"
  5 # Since we want to have our identifiers quoted appropriately for use in
  6 # PostgreSQL, we want to use the postgres dialect preparer to set this up.
  7 preparer = create_engine("postgresql://").dialect.identifier_preparer
  8 
  9 
  10 def get_qualified_name(name):
  11     return ".".join([preparer.quote_schema(SCHEMA), name])
  12
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/db/types/base.py b/db/types/base.py
  --- a/db/types/base.py
  +++ b/db/types/base.py
  @@ -1,5 +1,6 @@
  -from sqlalchemy import create_engine
  +from sqlalchemy import create_engine, MetaData, Table, DDL
   from db import constants
  +from db.types import email
   
   SCHEMA = f"{constants.MATHESAR_PREFIX}types"
   # Since we want to have our identifiers quoted appropriately for use in
  @@ -9,3 +10,41 @@
   
   def get_qualified_name(name):
       return ".".join([preparer.quote_schema(SCHEMA), name])
  +
  +
  +def get_supported_alter_column_types(engine):
  +    dialect_types = engine.dialect.ischema_names
  +    type_map = {
  +        # Default Postgres types
  +        "boolean": dialect_types.get("boolean"),
  +        "interval": dialect_types.get("interval"),
  +        "numeric": dialect_types.get("numeric"),
  +        "string": dialect_types.get("name"),
  +        # Custom Mathesar types
  +        "email": dialect_types.get(email.QUALIFIED_EMAIL)
  +    }
  +    return {k: v for k, v in type_map.items() if v is not None}
  +
  +
  +def alter_column_type(
  +        schema, table_name, column_name, target_type_str, engine
  +):
  +    _preparer = engine.dialect.identifier_preparer
  +    supported_types = get_supported_alter_column_types(engine)
  +    target_type = supported_types.get(target_type_str.lower())
  +    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_type_name = target_type().compile(dialect=engine.dialect)
  +        alter_stmt = f"""
  +        ALTER TABLE {prepared_table_name}
  +          ALTER COLUMN {prepared_column_name}
  +          TYPE {prepared_type_name}
  +          USING {prepared_column_name}::{prepared_type_name};
  +        """
  +        conn.execute(DDL(alter_stmt))
  
verification_info: {"golden_diff": "diff --git a/db/types/base.py b/db/types/base.py\n--- a/db/types/base.py\n+++ b/db/types/base.py\n@@ -1,5 +1,6 @@\n-from sqlalchemy import create_engine\n+from sqlalchemy import create_engine, MetaData, Table, DDL\n from db import constants\n+from db.types import email\n \n SCHEMA = f\"{constants.MATHESAR_PREFIX}types\"\n # Since we want to have our identifiers quoted appropriately for use in\n@@ -9,3 +10,41 @@\n \n def get_qualified_name(name):\n     return \".\".join([preparer.quote_schema(SCHEMA), name])\n+\n+\n+def get_supported_alter_column_types(engine):\n+    dialect_types = engine.dialect.ischema_names\n+    type_map = {\n+        # Default Postgres types\n+        \"boolean\": dialect_types.get(\"boolean\"),\n+        \"interval\": dialect_types.get(\"interval\"),\n+        \"numeric\": dialect_types.get(\"numeric\"),\n+        \"string\": dialect_types.get(\"name\"),\n+        # Custom Mathesar types\n+        \"email\": dialect_types.get(email.QUALIFIED_EMAIL)\n+    }\n+    return {k: v for k, v in type_map.items() if v is not None}\n+\n+\n+def alter_column_type(\n+        schema, table_name, column_name, target_type_str, engine\n+):\n+    _preparer = engine.dialect.identifier_preparer\n+    supported_types = get_supported_alter_column_types(engine)\n+    target_type = supported_types.get(target_type_str.lower())\n+    with engine.begin() as conn:\n+        metadata = MetaData(bind=engine, schema=schema)\n+        table = Table(\n+            table_name, metadata, schema=schema, autoload_with=engine\n+        )\n+        column = table.columns[column_name]\n+        prepared_table_name = _preparer.format_table(table)\n+        prepared_column_name = _preparer.format_column(column)\n+        prepared_type_name = target_type().compile(dialect=engine.dialect)\n+        alter_stmt = f\"\"\"\n+        ALTER TABLE {prepared_table_name}\n+          ALTER COLUMN {prepared_column_name}\n+          TYPE {prepared_type_name}\n+          USING {prepared_column_name}::{prepared_type_name};\n+        \"\"\"\n+        conn.execute(DDL(alter_stmt))\n", "issue": "Type Inference 1:  Check column against a type\n**Problem**\r\n<!-- Please provide a clear and concise description of the problem that this feature request is designed to solve.-->\r\n\r\nDifferent types in Mathesar will enable different operations; for example, strings could be aggregated by concatenating, but numeric types could be aggregated by summing or multiplying.  So far, while we can reflect different types, we have no way to determine the type most appropriate for a column.\r\n\r\n**Proposed solution**\r\n<!-- A clear and concise description of your proposed solution or feature. -->\r\n\r\nGiven a `schema`, `table_name`, `column_name`, and `type`, we need to be able to return a boolean giving whether the column can be cast to that type.\r\n\r\n**Additional context**\r\n<!-- Add any other context or screenshots about the feature request here.-->\r\n\r\nWe may need to take an optional sample size parameter to do this for large data.  Performance testing will be necessary.\r\n\n", "before_files": [{"content": "from sqlalchemy import create_engine\nfrom db import constants\n\nSCHEMA = f\"{constants.MATHESAR_PREFIX}types\"\n# Since we want to have our identifiers quoted appropriately for use in\n# PostgreSQL, we want to use the postgres dialect preparer to set this up.\npreparer = create_engine(\"postgresql://\").dialect.identifier_preparer\n\n\ndef get_qualified_name(name):\n    return \".\".join([preparer.quote_schema(SCHEMA), name])\n", "path": "db/types/base.py"}], "after_files": [{"content": "from sqlalchemy import create_engine, MetaData, Table, DDL\nfrom db import constants\nfrom db.types import email\n\nSCHEMA = f\"{constants.MATHESAR_PREFIX}types\"\n# Since we want to have our identifiers quoted appropriately for use in\n# PostgreSQL, we want to use the postgres dialect preparer to set this up.\npreparer = create_engine(\"postgresql://\").dialect.identifier_preparer\n\n\ndef get_qualified_name(name):\n    return \".\".join([preparer.quote_schema(SCHEMA), name])\n\n\ndef get_supported_alter_column_types(engine):\n    dialect_types = engine.dialect.ischema_names\n    type_map = {\n        # Default Postgres types\n        \"boolean\": dialect_types.get(\"boolean\"),\n        \"interval\": dialect_types.get(\"interval\"),\n        \"numeric\": dialect_types.get(\"numeric\"),\n        \"string\": dialect_types.get(\"name\"),\n        # Custom Mathesar types\n        \"email\": dialect_types.get(email.QUALIFIED_EMAIL)\n    }\n    return {k: v for k, v in type_map.items() if v is not None}\n\n\ndef alter_column_type(\n        schema, table_name, column_name, target_type_str, engine\n):\n    _preparer = engine.dialect.identifier_preparer\n    supported_types = get_supported_alter_column_types(engine)\n    target_type = supported_types.get(target_type_str.lower())\n    with engine.begin() as conn:\n        metadata = MetaData(bind=engine, schema=schema)\n        table = Table(\n            table_name, metadata, schema=schema, autoload_with=engine\n        )\n        column = table.columns[column_name]\n        prepared_table_name = _preparer.format_table(table)\n        prepared_column_name = _preparer.format_column(column)\n        prepared_type_name = target_type().compile(dialect=engine.dialect)\n        alter_stmt = f\"\"\"\n        ALTER TABLE {prepared_table_name}\n          ALTER COLUMN {prepared_column_name}\n          TYPE {prepared_type_name}\n          USING {prepared_column_name}::{prepared_type_name};\n        \"\"\"\n        conn.execute(DDL(alter_stmt))\n", "path": "db/types/base.py"}]}