@@ -514,6 +514,30 @@ is_tsql_binary_family_datatype(Oid oid)
514514 return false;
515515}
516516
517+ // /* Returns true if the oid belongs to sql_variant datatype */
518+ // static bool
519+ // is_sql_variant_type(Oid oid)
520+ // {
521+ // HeapTuple tuple;
522+ // bool result = false;
523+
524+ // tuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(oid));
525+ // if (HeapTupleIsValid(tuple))
526+ // {
527+ // Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tuple);
528+ // Oid type_nsoid = typtup->typnamespace;
529+ // char *type_name = NameStr(typtup->typname);
530+ // char *type_nsname = get_namespace_name(type_nsoid);
531+
532+ // if (strcmp(type_nsname, "sys") == 0 && strcmp(type_name, "sql_variant") == 0)
533+ // result = true;
534+
535+ // ReleaseSysCache(tuple);
536+ // }
537+
538+ // return result;
539+ // }
540+
517541static CoercionPathType
518542tsql_find_coercion_pathway (Oid sourceTypeId , Oid targetTypeId , CoercionContext ccontext , Oid * funcid )
519543{
@@ -3173,6 +3197,30 @@ select_common_type_setop(ParseState *pstate, List *exprs, Node **which_expr, con
31733197 ListCell * lc ;
31743198 bool is_case_expr = (strlen (context ) == 4 && strncmp (context , "CASE" , 4 ) == 0 );
31753199
3200+ /*
3201+ * For CASE expressions, if any branch is sql_variant, return sql_variant
3202+ * directly. sql_variant has the highest TSQL type precedence (0) and can
3203+ * hold any type, so it is always the correct common type when present.
3204+ * We must check this before the main loop because the loop bails out on
3205+ * non-char types, and the other branch (e.g. bit) would cause an early
3206+ * return of InvalidOid before sql_variant is ever seen.
3207+ */
3208+ if (is_case_expr )
3209+ {
3210+ foreach (lc , exprs )
3211+ {
3212+ Node * expr = (Node * ) lfirst (lc );
3213+ Oid type = exprType (expr );
3214+
3215+ if ((* common_utility_plugin_ptr -> is_tsql_sqlvariant_datatype )(type ))
3216+ {
3217+ if (which_expr )
3218+ * which_expr = expr ;
3219+ return type ;
3220+ }
3221+ }
3222+ }
3223+
31763224 /* Find a common type based on precedence. NULLs are ignored, and make
31773225 * string literals varchars. If a type besides CHAR, NCHAR, VARCHAR,
31783226 * or NVARCHAR is present, let engine handle finding the type.
@@ -3207,18 +3255,8 @@ select_common_type_setop(ParseState *pstate, List *exprs, Node **which_expr, con
32073255 continue ;
32083256 else if (is_tsql_str_const (expr ))
32093257 type = common_utility_plugin_ptr -> lookup_tsql_datatype_oid ("varchar" );
3210- else if ((!is_tsql_char_type_with_len (type , is_case_expr )))
3211- {
3212- if (is_case_expr && is_tsql_base_datatype (type ))
3213- {
3214- // Type exists in tsql_precedence_infos — allow through
3215- // to the precedence comparison below
3216- }
3217- else
3218- {
3219- return InvalidOid ;
3220- }
3221- }
3258+ else if ((!is_tsql_char_type_with_len (type , is_case_expr )))
3259+ return InvalidOid ;
32223260
32233261 if (tsql_has_higher_precedence (type , result_type ) || result_type == InvalidOid )
32243262 {
0 commit comments