prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  1.0 is not a boolean
  ## Description
  The software detects `1.0` as a boolean instead of a numeric, which makes the system fail.
  
  UI: `When making an XHR request, the server responded with an error, but the response body was not valid JSON.`
  Database: `ERROR:  1.0 is not a boolean`
  
  ## Expected behavior
  
  The software should cast `1.0` to numeric.
  If the auto-casting mechanism fails, an informative error should be shown.
  
  ## To Reproduce
  
  Create a test CSV file and import it.
  ```column
  1.0
  ```
  
  --- 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/columns/operations/infer_types.py`
  Content:
  ```
  1 import logging
  2 
  3 from sqlalchemy import VARCHAR, TEXT, Text
  4 from sqlalchemy.exc import DatabaseError
  5 
  6 from db.columns.exceptions import DagCycleError
  7 from db.columns.operations.alter import alter_column_type
  8 from db.tables.operations.select import get_oid_from_table, reflect_table
  9 from db.types.base import PostgresType, MathesarCustomType, get_available_known_db_types
  10 from db.metadata import get_empty_metadata
  11 
  12 
  13 logger = logging.getLogger(__name__)
  14 
  15 MAX_INFERENCE_DAG_DEPTH = 100
  16 
  17 TYPE_INFERENCE_DAG = {
  18     PostgresType.BOOLEAN: [],
  19     MathesarCustomType.EMAIL: [],
  20     PostgresType.INTERVAL: [],
  21     PostgresType.NUMERIC: [
  22         PostgresType.BOOLEAN,
  23     ],
  24     PostgresType.TEXT: [
  25         PostgresType.BOOLEAN,
  26         PostgresType.DATE,
  27         PostgresType.NUMERIC,
  28         MathesarCustomType.MATHESAR_MONEY,
  29         PostgresType.TIMESTAMP_WITHOUT_TIME_ZONE,
  30         PostgresType.TIMESTAMP_WITH_TIME_ZONE,
  31         # We only infer to TIME_WITHOUT_TIME_ZONE as time zones don't make much sense
  32         # without additional date information. See postgres documentation for further
  33         # details: https://www.postgresql.org/docs/13/datatype-datetime.html
  34         PostgresType.TIME_WITHOUT_TIME_ZONE,
  35         PostgresType.INTERVAL,
  36         MathesarCustomType.EMAIL,
  37         MathesarCustomType.URI,
  38         MathesarCustomType.MATHESAR_JSON_ARRAY,
  39         MathesarCustomType.MATHESAR_JSON_OBJECT,
  40     ],
  41 }
  42 
  43 
  44 def infer_column_type(schema, table_name, column_name, engine, depth=0, type_inference_dag=None, metadata=None, columns_might_have_defaults=True):
  45     """
  46     Attempts to cast the column to the best type for it, given the mappings defined in TYPE_INFERENCE_DAG
  47     and _get_type_classes_mapped_to_dag_nodes. Returns the resulting column type's class.
  48 
  49     Algorithm:
  50         1. reflect the column's type class;
  51         2. use _get_type_classes_mapped_to_dag_nodes to map it to a TYPE_INFERENCE_DAG key;
  52         3. look up the sequence of types referred to by that key on the TYPE_INFERENCE_DAG;
  53             - if there's no such key on the TYPE_INFERENCE_DAG dict, or if its value is an empty
  54             list, return the current column type's class;
  55         4. iterate through that sequence of types trying to alter the column's type to them;
  56             - if the column's type is altered successfully, break iteration and return the output
  57             of running infer_column_type again (trigger tail recursion);
  58             - if none of the column type alterations succeed, return the current column type's
  59             class.
  60     """
  61     if type_inference_dag is None:
  62         type_inference_dag = TYPE_INFERENCE_DAG
  63     metadata = metadata if metadata else get_empty_metadata()
  64     if depth > MAX_INFERENCE_DAG_DEPTH:
  65         raise DagCycleError("The type_inference_dag likely has a cycle")
  66     type_classes_to_dag_nodes = _get_type_classes_mapped_to_dag_nodes(engine)
  67     column_type_class = _get_column_class(
  68         engine=engine,
  69         schema=schema,
  70         table_name=table_name,
  71         column_name=column_name,
  72         metadata=metadata,
  73     )
  74     # a DAG node will be a DatabaseType Enum
  75     dag_node = type_classes_to_dag_nodes.get(column_type_class)
  76     logger.debug(f"dag_node: {dag_node}")
  77     types_to_cast_to = type_inference_dag.get(dag_node, [])
  78     table_oid = get_oid_from_table(table_name, schema, engine)
  79     for db_type in types_to_cast_to:
  80         try:
  81             with engine.begin() as conn:
  82                 alter_column_type(
  83                     table_oid,
  84                     column_name,
  85                     engine,
  86                     conn,
  87                     db_type,
  88                     metadata=metadata,
  89                     columns_might_have_defaults=columns_might_have_defaults,
  90                 )
  91             logger.info(f"Column {column_name} altered to type {db_type.id}")
  92             column_type_class = infer_column_type(
  93                 schema,
  94                 table_name,
  95                 column_name,
  96                 engine,
  97                 depth=depth + 1,
  98                 type_inference_dag=type_inference_dag,
  99                 metadata=metadata
  100             )
  101             break
  102         # It's expected we catch this error when the test to see whether
  103         # a type is appropriate for a column fails.
  104         except DatabaseError:
  105             logger.info(
  106                 f"Cannot alter column {column_name} to type {db_type.id}"
  107             )
  108     return column_type_class
  109 
  110 
  111 def _get_column_class(engine, schema, table_name, column_name, metadata):
  112     # Metadata can be reused because reflect_table fetches the table details again
  113     table = reflect_table(table_name, schema, engine, metadata=metadata)
  114     column_type_class = table.columns[column_name].type.__class__
  115     return column_type_class
  116 
  117 
  118 def _get_type_classes_mapped_to_dag_nodes(engine):
  119     """
  120     Returns SA type classes mapped to TYPE_INFERENCE_DAG nodes.
  121 
  122     Purpose of this mapping is to find the wanted position on the TYPE_INFERENCE_DAG, given a
  123     column's SA type class.
  124     """
  125     type_classes_to_enums = {
  126         db_type.get_sa_class(engine): db_type
  127         for db_type
  128         in get_available_known_db_types(engine)
  129     }
  130     # NOTE: below dict merge sets some keys to PostgresType.TEXT, which, in infer_column_type,
  131     # maps these classes to the types grouped under TYPE_INFERENCE_DAG[PostgresType.TEXT].
  132     type_classes_to_dag_nodes = (
  133         type_classes_to_enums | {
  134             Text: PostgresType.TEXT,
  135             TEXT: PostgresType.TEXT,
  136             VARCHAR: PostgresType.TEXT,
  137         }
  138     )
  139     return type_classes_to_dag_nodes
  140
  ```
  --- 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/columns/operations/infer_types.py b/db/columns/operations/infer_types.py
  --- a/db/columns/operations/infer_types.py
  +++ b/db/columns/operations/infer_types.py
  @@ -18,9 +18,7 @@
       PostgresType.BOOLEAN: [],
       MathesarCustomType.EMAIL: [],
       PostgresType.INTERVAL: [],
  -    PostgresType.NUMERIC: [
  -        PostgresType.BOOLEAN,
  -    ],
  +    PostgresType.NUMERIC: [],
       PostgresType.TEXT: [
           PostgresType.BOOLEAN,
           PostgresType.DATE,
  
verification_info: {"golden_diff": "diff --git a/db/columns/operations/infer_types.py b/db/columns/operations/infer_types.py\n--- a/db/columns/operations/infer_types.py\n+++ b/db/columns/operations/infer_types.py\n@@ -18,9 +18,7 @@\n     PostgresType.BOOLEAN: [],\n     MathesarCustomType.EMAIL: [],\n     PostgresType.INTERVAL: [],\n-    PostgresType.NUMERIC: [\n-        PostgresType.BOOLEAN,\n-    ],\n+    PostgresType.NUMERIC: [],\n     PostgresType.TEXT: [\n         PostgresType.BOOLEAN,\n         PostgresType.DATE,\n", "issue": "1.0 is not a boolean\n## Description\r\nThe software detects `1.0` as a boolean instead of a numeric, which makes the system fail.\r\n\r\nUI: `When making an XHR request, the server responded with an error, but the response body was not valid JSON.`\r\nDatabase: `ERROR:  1.0 is not a boolean`\r\n\r\n## Expected behavior\r\n\r\nThe software should cast `1.0` to numeric.\r\nIf the auto-casting mechanism fails, an informative error should be shown.\r\n\r\n## To Reproduce\r\n\r\nCreate a test CSV file and import it.\r\n```column\r\n1.0\r\n```\n", "before_files": [{"content": "import logging\n\nfrom sqlalchemy import VARCHAR, TEXT, Text\nfrom sqlalchemy.exc import DatabaseError\n\nfrom db.columns.exceptions import DagCycleError\nfrom db.columns.operations.alter import alter_column_type\nfrom db.tables.operations.select import get_oid_from_table, reflect_table\nfrom db.types.base import PostgresType, MathesarCustomType, get_available_known_db_types\nfrom db.metadata import get_empty_metadata\n\n\nlogger = logging.getLogger(__name__)\n\nMAX_INFERENCE_DAG_DEPTH = 100\n\nTYPE_INFERENCE_DAG = {\n    PostgresType.BOOLEAN: [],\n    MathesarCustomType.EMAIL: [],\n    PostgresType.INTERVAL: [],\n    PostgresType.NUMERIC: [\n        PostgresType.BOOLEAN,\n    ],\n    PostgresType.TEXT: [\n        PostgresType.BOOLEAN,\n        PostgresType.DATE,\n        PostgresType.NUMERIC,\n        MathesarCustomType.MATHESAR_MONEY,\n        PostgresType.TIMESTAMP_WITHOUT_TIME_ZONE,\n        PostgresType.TIMESTAMP_WITH_TIME_ZONE,\n        # We only infer to TIME_WITHOUT_TIME_ZONE as time zones don't make much sense\n        # without additional date information. See postgres documentation for further\n        # details: https://www.postgresql.org/docs/13/datatype-datetime.html\n        PostgresType.TIME_WITHOUT_TIME_ZONE,\n        PostgresType.INTERVAL,\n        MathesarCustomType.EMAIL,\n        MathesarCustomType.URI,\n        MathesarCustomType.MATHESAR_JSON_ARRAY,\n        MathesarCustomType.MATHESAR_JSON_OBJECT,\n    ],\n}\n\n\ndef infer_column_type(schema, table_name, column_name, engine, depth=0, type_inference_dag=None, metadata=None, columns_might_have_defaults=True):\n    \"\"\"\n    Attempts to cast the column to the best type for it, given the mappings defined in TYPE_INFERENCE_DAG\n    and _get_type_classes_mapped_to_dag_nodes. Returns the resulting column type's class.\n\n    Algorithm:\n        1. reflect the column's type class;\n        2. use _get_type_classes_mapped_to_dag_nodes to map it to a TYPE_INFERENCE_DAG key;\n        3. look up the sequence of types referred to by that key on the TYPE_INFERENCE_DAG;\n            - if there's no such key on the TYPE_INFERENCE_DAG dict, or if its value is an empty\n            list, return the current column type's class;\n        4. iterate through that sequence of types trying to alter the column's type to them;\n            - if the column's type is altered successfully, break iteration and return the output\n            of running infer_column_type again (trigger tail recursion);\n            - if none of the column type alterations succeed, return the current column type's\n            class.\n    \"\"\"\n    if type_inference_dag is None:\n        type_inference_dag = TYPE_INFERENCE_DAG\n    metadata = metadata if metadata else get_empty_metadata()\n    if depth > MAX_INFERENCE_DAG_DEPTH:\n        raise DagCycleError(\"The type_inference_dag likely has a cycle\")\n    type_classes_to_dag_nodes = _get_type_classes_mapped_to_dag_nodes(engine)\n    column_type_class = _get_column_class(\n        engine=engine,\n        schema=schema,\n        table_name=table_name,\n        column_name=column_name,\n        metadata=metadata,\n    )\n    # a DAG node will be a DatabaseType Enum\n    dag_node = type_classes_to_dag_nodes.get(column_type_class)\n    logger.debug(f\"dag_node: {dag_node}\")\n    types_to_cast_to = type_inference_dag.get(dag_node, [])\n    table_oid = get_oid_from_table(table_name, schema, engine)\n    for db_type in types_to_cast_to:\n        try:\n            with engine.begin() as conn:\n                alter_column_type(\n                    table_oid,\n                    column_name,\n                    engine,\n                    conn,\n                    db_type,\n                    metadata=metadata,\n                    columns_might_have_defaults=columns_might_have_defaults,\n                )\n            logger.info(f\"Column {column_name} altered to type {db_type.id}\")\n            column_type_class = infer_column_type(\n                schema,\n                table_name,\n                column_name,\n                engine,\n                depth=depth + 1,\n                type_inference_dag=type_inference_dag,\n                metadata=metadata\n            )\n            break\n        # It's expected we catch this error when the test to see whether\n        # a type is appropriate for a column fails.\n        except DatabaseError:\n            logger.info(\n                f\"Cannot alter column {column_name} to type {db_type.id}\"\n            )\n    return column_type_class\n\n\ndef _get_column_class(engine, schema, table_name, column_name, metadata):\n    # Metadata can be reused because reflect_table fetches the table details again\n    table = reflect_table(table_name, schema, engine, metadata=metadata)\n    column_type_class = table.columns[column_name].type.__class__\n    return column_type_class\n\n\ndef _get_type_classes_mapped_to_dag_nodes(engine):\n    \"\"\"\n    Returns SA type classes mapped to TYPE_INFERENCE_DAG nodes.\n\n    Purpose of this mapping is to find the wanted position on the TYPE_INFERENCE_DAG, given a\n    column's SA type class.\n    \"\"\"\n    type_classes_to_enums = {\n        db_type.get_sa_class(engine): db_type\n        for db_type\n        in get_available_known_db_types(engine)\n    }\n    # NOTE: below dict merge sets some keys to PostgresType.TEXT, which, in infer_column_type,\n    # maps these classes to the types grouped under TYPE_INFERENCE_DAG[PostgresType.TEXT].\n    type_classes_to_dag_nodes = (\n        type_classes_to_enums | {\n            Text: PostgresType.TEXT,\n            TEXT: PostgresType.TEXT,\n            VARCHAR: PostgresType.TEXT,\n        }\n    )\n    return type_classes_to_dag_nodes\n", "path": "db/columns/operations/infer_types.py"}], "after_files": [{"content": "import logging\n\nfrom sqlalchemy import VARCHAR, TEXT, Text\nfrom sqlalchemy.exc import DatabaseError\n\nfrom db.columns.exceptions import DagCycleError\nfrom db.columns.operations.alter import alter_column_type\nfrom db.tables.operations.select import get_oid_from_table, reflect_table\nfrom db.types.base import PostgresType, MathesarCustomType, get_available_known_db_types\nfrom db.metadata import get_empty_metadata\n\n\nlogger = logging.getLogger(__name__)\n\nMAX_INFERENCE_DAG_DEPTH = 100\n\nTYPE_INFERENCE_DAG = {\n    PostgresType.BOOLEAN: [],\n    MathesarCustomType.EMAIL: [],\n    PostgresType.INTERVAL: [],\n    PostgresType.NUMERIC: [],\n    PostgresType.TEXT: [\n        PostgresType.BOOLEAN,\n        PostgresType.DATE,\n        PostgresType.NUMERIC,\n        MathesarCustomType.MATHESAR_MONEY,\n        PostgresType.TIMESTAMP_WITHOUT_TIME_ZONE,\n        PostgresType.TIMESTAMP_WITH_TIME_ZONE,\n        # We only infer to TIME_WITHOUT_TIME_ZONE as time zones don't make much sense\n        # without additional date information. See postgres documentation for further\n        # details: https://www.postgresql.org/docs/13/datatype-datetime.html\n        PostgresType.TIME_WITHOUT_TIME_ZONE,\n        PostgresType.INTERVAL,\n        MathesarCustomType.EMAIL,\n        MathesarCustomType.URI,\n        MathesarCustomType.MATHESAR_JSON_ARRAY,\n        MathesarCustomType.MATHESAR_JSON_OBJECT,\n    ],\n}\n\n\ndef infer_column_type(schema, table_name, column_name, engine, depth=0, type_inference_dag=None, metadata=None, columns_might_have_defaults=True):\n    \"\"\"\n    Attempts to cast the column to the best type for it, given the mappings defined in TYPE_INFERENCE_DAG\n    and _get_type_classes_mapped_to_dag_nodes. Returns the resulting column type's class.\n\n    Algorithm:\n        1. reflect the column's type class;\n        2. use _get_type_classes_mapped_to_dag_nodes to map it to a TYPE_INFERENCE_DAG key;\n        3. look up the sequence of types referred to by that key on the TYPE_INFERENCE_DAG;\n            - if there's no such key on the TYPE_INFERENCE_DAG dict, or if its value is an empty\n            list, return the current column type's class;\n        4. iterate through that sequence of types trying to alter the column's type to them;\n            - if the column's type is altered successfully, break iteration and return the output\n            of running infer_column_type again (trigger tail recursion);\n            - if none of the column type alterations succeed, return the current column type's\n            class.\n    \"\"\"\n    if type_inference_dag is None:\n        type_inference_dag = TYPE_INFERENCE_DAG\n    metadata = metadata if metadata else get_empty_metadata()\n    if depth > MAX_INFERENCE_DAG_DEPTH:\n        raise DagCycleError(\"The type_inference_dag likely has a cycle\")\n    type_classes_to_dag_nodes = _get_type_classes_mapped_to_dag_nodes(engine)\n    column_type_class = _get_column_class(\n        engine=engine,\n        schema=schema,\n        table_name=table_name,\n        column_name=column_name,\n        metadata=metadata,\n    )\n    # a DAG node will be a DatabaseType Enum\n    dag_node = type_classes_to_dag_nodes.get(column_type_class)\n    logger.debug(f\"dag_node: {dag_node}\")\n    types_to_cast_to = type_inference_dag.get(dag_node, [])\n    table_oid = get_oid_from_table(table_name, schema, engine)\n    for db_type in types_to_cast_to:\n        try:\n            with engine.begin() as conn:\n                alter_column_type(\n                    table_oid,\n                    column_name,\n                    engine,\n                    conn,\n                    db_type,\n                    metadata=metadata,\n                    columns_might_have_defaults=columns_might_have_defaults,\n                )\n            logger.info(f\"Column {column_name} altered to type {db_type.id}\")\n            column_type_class = infer_column_type(\n                schema,\n                table_name,\n                column_name,\n                engine,\n                depth=depth + 1,\n                type_inference_dag=type_inference_dag,\n                metadata=metadata\n            )\n            break\n        # It's expected we catch this error when the test to see whether\n        # a type is appropriate for a column fails.\n        except DatabaseError:\n            logger.info(\n                f\"Cannot alter column {column_name} to type {db_type.id}\"\n            )\n    return column_type_class\n\n\ndef _get_column_class(engine, schema, table_name, column_name, metadata):\n    # Metadata can be reused because reflect_table fetches the table details again\n    table = reflect_table(table_name, schema, engine, metadata=metadata)\n    column_type_class = table.columns[column_name].type.__class__\n    return column_type_class\n\n\ndef _get_type_classes_mapped_to_dag_nodes(engine):\n    \"\"\"\n    Returns SA type classes mapped to TYPE_INFERENCE_DAG nodes.\n\n    Purpose of this mapping is to find the wanted position on the TYPE_INFERENCE_DAG, given a\n    column's SA type class.\n    \"\"\"\n    type_classes_to_enums = {\n        db_type.get_sa_class(engine): db_type\n        for db_type\n        in get_available_known_db_types(engine)\n    }\n    # NOTE: below dict merge sets some keys to PostgresType.TEXT, which, in infer_column_type,\n    # maps these classes to the types grouped under TYPE_INFERENCE_DAG[PostgresType.TEXT].\n    type_classes_to_dag_nodes = (\n        type_classes_to_enums | {\n            Text: PostgresType.TEXT,\n            TEXT: PostgresType.TEXT,\n            VARCHAR: PostgresType.TEXT,\n        }\n    )\n    return type_classes_to_dag_nodes\n", "path": "db/columns/operations/infer_types.py"}]}