Repository: mathesar-foundation/mathesar

Issue:
Installation creates nonsensical cast functions
## Description
<!-- A clear and concise description of what the bug is. -->

The installation of cast functions currently creates many such functions which make no sense, and can only fail. For example, we create a function that attempts to cast a `bigint` to a `mathesar_types.email`. However, such a conversion is impossible. There's no such thing as a value which is both a valid integer and a valid email address.

## Expected behavior
<!-- A clear and concise description of what you expected to happen. -->

Only cast functions which make sense should be installed.

<!-- Add any other context about the problem or screenshots here. -->

The main issue seems to be the constant `db.types.categories.STRING_LIKE_TYPES`. We use this to construct a bunch of textual cast functions in the `db.types.operations.cast.create_textual_casts` function. However, we consider _many_ types (e.g., `mathesar_types.email` to be `STRING_LIKE_TYPES`, and most don't make sense as the target of arbitrary casts from other arbitrary types.



Discussion:
This was discovered while putting together DB-layer logic for determining the `valid_target_types` array for some types. Many (many) types consider `mathesar_types.uri` to be a `valid_target_type` (taking whether we have a custom cast function with that pair as the definition). We need to make sure only the correct target types are ... targeted ... by our custom casting functions for a given source type.

Resolving patch:
diff --git a/db/records/operations/relevance.py b/db/records/operations/relevance.py
--- a/db/records/operations/relevance.py
+++ b/db/records/operations/relevance.py
@@ -1,5 +1,6 @@
 from sqlalchemy import case, select, desc
 from db.types import categories
+from db.types.base import MathesarCustomType
 from db.types.operations.convert import get_db_type_enum_from_class
 
 WEIGHT_4 = 4
@@ -37,8 +38,8 @@ def _get_scored_selectable(relation, parameters_dict):
 
 def _get_col_score_expr(col, param_val):
     col_type = get_db_type_enum_from_class(col.type.__class__)
-
-    if col_type in categories.STRING_LIKE_TYPES:
+    searchable_string_types = categories.STRING_LIKE_TYPES | frozenset([MathesarCustomType.URI, MathesarCustomType.EMAIL])
+    if col_type in searchable_string_types:
         score_expr = case(
             (col.ilike(param_val), WEIGHT_4),
             (col.ilike(param_val + '%'), WEIGHT_3),
diff --git a/db/types/categories.py b/db/types/categories.py
--- a/db/types/categories.py
+++ b/db/types/categories.py
@@ -10,8 +10,6 @@
     *STRING_TYPES,
     PostgresType.CHAR,
     PostgresType.NAME,
-    MathesarCustomType.URI,
-    MathesarCustomType.EMAIL,
 })
 
 INTEGER_TYPES = frozenset({
diff --git a/db/types/operations/cast.py b/db/types/operations/cast.py
--- a/db/types/operations/cast.py
+++ b/db/types/operations/cast.py
@@ -44,7 +44,6 @@ def get_column_cast_expression(column, target_type, engine, type_options=None):
 
 def install_all_casts(engine):
     create_boolean_casts(engine)
-    create_date_casts(engine)
     create_decimal_number_casts(engine)
     create_email_casts(engine)
     create_integer_casts(engine)
@@ -64,11 +63,6 @@ def create_boolean_casts(engine):
     create_cast_functions(PostgresType.BOOLEAN, type_body_map, engine)
 
 
-def create_date_casts(engine):
-    type_body_map = _get_date_type_body_map()
-    create_cast_functions(PostgresType.DATE, type_body_map, engine)
-
-
 def create_json_casts(engine):
     json_types = categories.JSON_TYPES
     for db_type in json_types:


Test patch: