Example #1
0
        public override Type EvaluateType()
        {
            // CASE WHEN's type depends on the most generous type from its branches
            // E.g.  CASE WHEN <num> ELSE <string> END gives a string type
            var hasElseExpression = (ElseExpression != null);
            var distinctTypes     = hasElseExpression ?
                                    CaseAlternatives.Select(n => n.EvaluateType())
                                    .Union(new List <Type> {
                ElseExpression.EvaluateType()
            })
                                    .Distinct() :
                                    CaseAlternatives.Select(n => n.EvaluateType())
                                    .Distinct();
            var anyNullable = distinctTypes.Any(t => TypeHelper.IsSystemNullableType(t))
                              // when Else statement is not provided resulting type becomes automatically nullable
                              || !hasElseExpression;
            var distinctUnboxedTypes = distinctTypes
                                       .Select(t => TypeHelper.GetUnderlyingTypeIfNullable(t)).Distinct();

            Type resultUnboxedType;

            if (distinctUnboxedTypes.Count() > 1)
            {
                resultUnboxedType = distinctUnboxedTypes.Aggregate((resType, nextType) =>
                {
                    Type resultedTypeRaw;
                    if (!TypeCoersionTables.CoersionTableForValueType.TryGetValue((BinaryOperator.Plus, resType, nextType), out resultedTypeRaw))
                    {
                        throw new TranspilerInternalErrorException($"Unexpected use of CASE WHEN operating between types {resType} and {nextType}");
                    }
                    if (resultedTypeRaw == default(Type))
                    {
                        throw new TranspilerNotSupportedException($"Case WHEN operating between types {resType} and {nextType}");
                    }
                    return(resultedTypeRaw);
                });
            }
            else
            {
                resultUnboxedType = distinctUnboxedTypes.First();
            }

            return(anyNullable ? TypeHelper.MakeNullableIfNotAlready(resultUnboxedType) : resultUnboxedType);
        }
Example #2
0
 public override string ToString()
 {
     return($"CaseExpr: Case {CaseAlternatives.ToString()} Else->{ElseExpression?.ToString() ?? "(None)"}");
 }