2015-04-07 09:35:12 +01:00
|
|
|
//---------------------------------------------------------------------
|
|
|
|
// <copyright file="Constant.cs" company="Microsoft">
|
|
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
|
|
// </copyright>
|
|
|
|
//
|
|
|
|
// @owner [....]
|
|
|
|
// @backupOwner [....]
|
|
|
|
//---------------------------------------------------------------------
|
|
|
|
|
|
|
|
namespace System.Data.Mapping.ViewGeneration.Structures
|
|
|
|
{
|
|
|
|
using System.Collections.Generic;
|
|
|
|
using System.Data.Common.CommandTrees;
|
|
|
|
using System.Data.Common.CommandTrees.ExpressionBuilder;
|
|
|
|
using System.Data.Common.Utils;
|
|
|
|
using System.Data.Mapping.ViewGeneration.CqlGeneration;
|
|
|
|
using System.Data.Metadata.Edm;
|
|
|
|
using System.Diagnostics;
|
|
|
|
using System.Text;
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// This class denotes a constant that can be stored in multiconstants or projected in fields.
|
|
|
|
/// </summary>
|
|
|
|
internal abstract class Constant : InternalBase
|
|
|
|
{
|
|
|
|
#region Fields
|
|
|
|
internal static readonly IEqualityComparer<Constant> EqualityComparer = new CellConstantComparer();
|
|
|
|
internal static readonly Constant Null = NullConstant.Instance;
|
|
|
|
internal static readonly Constant NotNull = new NegatedConstant( new Constant[] { NullConstant.Instance });
|
|
|
|
internal static readonly Constant Undefined = UndefinedConstant.Instance;
|
|
|
|
/// <summary>
|
|
|
|
/// Represents scalar constants within a finite set that are not specified explicitly in the domain.
|
|
|
|
/// Currently only used as a Sentinel node to prevent expression optimization
|
|
|
|
/// </summary>
|
|
|
|
internal static readonly Constant AllOtherConstants = AllOtherConstantsConstant.Instance;
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region Methods
|
|
|
|
internal abstract bool IsNull();
|
|
|
|
|
|
|
|
internal abstract bool IsNotNull();
|
|
|
|
|
|
|
|
internal abstract bool IsUndefined();
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Returns true if this constant contains not null.
|
|
|
|
/// Implemented in <see cref="NegatedConstant"/> class, all other implementations return false.
|
|
|
|
/// </summary>
|
|
|
|
internal abstract bool HasNotNull();
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Generates eSQL for the constant expression.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="outputMember">The member to which this constant is directed</param>
|
|
|
|
internal abstract StringBuilder AsEsql(StringBuilder builder, MemberPath outputMember, string blockAlias);
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Generates CQT for the constant expression.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="row">The input row.</param>
|
|
|
|
/// <param name="outputMember">The member to which this constant is directed</param>
|
|
|
|
internal abstract DbExpression AsCqt(DbExpression row, MemberPath outputMember);
|
|
|
|
|
|
|
|
public override bool Equals(object obj)
|
|
|
|
{
|
|
|
|
Constant cellConst = obj as Constant;
|
|
|
|
if (cellConst == null)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return IsEqualTo(cellConst);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public override int GetHashCode()
|
|
|
|
{
|
|
|
|
return base.GetHashCode();
|
|
|
|
}
|
|
|
|
|
|
|
|
protected abstract bool IsEqualTo(Constant right);
|
|
|
|
|
|
|
|
internal abstract string ToUserString();
|
|
|
|
|
|
|
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
|
|
|
internal static void ConstantsToUserString(StringBuilder builder, Set<Constant> constants)
|
|
|
|
{
|
|
|
|
bool isFirst = true;
|
|
|
|
foreach (Constant constant in constants)
|
|
|
|
{
|
|
|
|
if (isFirst == false)
|
|
|
|
{
|
|
|
|
builder.Append(System.Data.Entity.Strings.ViewGen_CommaBlank);
|
|
|
|
}
|
|
|
|
isFirst = false;
|
|
|
|
string constrStr = constant.ToUserString();
|
|
|
|
builder.Append(constrStr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region Comparer class
|
|
|
|
private class CellConstantComparer : IEqualityComparer<Constant>
|
|
|
|
{
|
|
|
|
public bool Equals(Constant left, Constant right)
|
|
|
|
{
|
|
|
|
// Quick check with references
|
|
|
|
if (object.ReferenceEquals(left, right))
|
|
|
|
{
|
|
|
|
// Gets the Null and Undefined case as well
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
// One of them is non-null at least. So if the other one is
|
|
|
|
// null, we cannot be equal
|
|
|
|
if (left == null || right == null)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
// Both are non-null at this point
|
|
|
|
return left.IsEqualTo(right);
|
|
|
|
}
|
|
|
|
|
|
|
|
public int GetHashCode(Constant key)
|
|
|
|
{
|
|
|
|
EntityUtil.CheckArgumentNull(key, "key");
|
|
|
|
return key.GetHashCode();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region Special constant classes (NullConstant, UndefinedConstant, AllOtherConstants)
|
|
|
|
private sealed class NullConstant : Constant
|
|
|
|
{
|
|
|
|
internal static readonly Constant Instance = new NullConstant();
|
|
|
|
|
|
|
|
private NullConstant() { }
|
|
|
|
|
|
|
|
#region Methods
|
|
|
|
internal override bool IsNull()
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
internal override bool IsNotNull()
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
internal override bool IsUndefined()
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
internal override bool HasNotNull()
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
internal override StringBuilder AsEsql(StringBuilder builder, MemberPath outputMember, string blockAlias)
|
|
|
|
{
|
|
|
|
Debug.Assert(outputMember.LeafEdmMember != null, "Constant can't correspond to an empty member path.");
|
|
|
|
EdmType constType = Helper.GetModelTypeUsage(outputMember.LeafEdmMember).EdmType;
|
|
|
|
|
|
|
|
builder.Append("CAST(NULL AS ");
|
|
|
|
CqlWriter.AppendEscapedTypeName(builder, constType);
|
|
|
|
builder.Append(')');
|
|
|
|
return builder;
|
|
|
|
}
|
|
|
|
|
|
|
|
internal override DbExpression AsCqt(DbExpression row, MemberPath outputMember)
|
|
|
|
{
|
|
|
|
Debug.Assert(outputMember.LeafEdmMember != null, "Constant can't correspond to an empty path.");
|
|
|
|
EdmType constType = Helper.GetModelTypeUsage(outputMember.LeafEdmMember).EdmType;
|
|
|
|
|
|
|
|
return TypeUsage.Create(constType).Null();
|
|
|
|
}
|
|
|
|
|
|
|
|
public override int GetHashCode()
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected override bool IsEqualTo(Constant right)
|
|
|
|
{
|
|
|
|
Debug.Assert(Object.ReferenceEquals(this, Instance), "this must be == Instance for NullConstant");
|
|
|
|
return Object.ReferenceEquals(this, right);
|
|
|
|
}
|
|
|
|
|
|
|
|
internal override string ToUserString()
|
|
|
|
{
|
|
|
|
return System.Data.Entity.Strings.ViewGen_Null;
|
|
|
|
}
|
|
|
|
|
|
|
|
internal override void ToCompactString(StringBuilder builder)
|
|
|
|
{
|
|
|
|
builder.Append("NULL");
|
|
|
|
}
|
|
|
|
#endregion
|
|
|
|
}
|
|
|
|
private sealed class UndefinedConstant : Constant
|
|
|
|
{
|
|
|
|
internal static readonly Constant Instance = new UndefinedConstant();
|
|
|
|
|
|
|
|
private UndefinedConstant() { }
|
|
|
|
|
|
|
|
#region Methods
|
|
|
|
internal override bool IsNull()
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
internal override bool IsNotNull()
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
internal override bool IsUndefined()
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
internal override bool HasNotNull()
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Not supported in this class.
|
|
|
|
/// </summary>
|
|
|
|
internal override StringBuilder AsEsql(StringBuilder builder, MemberPath outputMember, string blockAlias)
|
|
|
|
{
|
|
|
|
Debug.Fail("Should not be called.");
|
|
|
|
return null; // To keep the compiler happy
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Not supported in this class.
|
|
|
|
/// </summary>
|
|
|
|
internal override DbExpression AsCqt(DbExpression row, MemberPath outputMember)
|
|
|
|
{
|
|
|
|
Debug.Fail("Should not be called.");
|
|
|
|
return null; // To keep the compiler happy
|
|
|
|
}
|
|
|
|
|
|
|
|
public override int GetHashCode()
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected override bool IsEqualTo(Constant right)
|
|
|
|
{
|
|
|
|
Debug.Assert(Object.ReferenceEquals(this, Instance), "this must be == Instance for NullConstant");
|
|
|
|
return Object.ReferenceEquals(this, right);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Not supported in this class.
|
|
|
|
/// </summary>
|
|
|
|
internal override string ToUserString()
|
|
|
|
{
|
|
|
|
Debug.Fail("We should not emit a message about Undefined constants to the user.");
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
internal override void ToCompactString(StringBuilder builder)
|
|
|
|
{
|
|
|
|
builder.Append("?");
|
|
|
|
}
|
|
|
|
#endregion
|
|
|
|
}
|
|
|
|
private sealed class AllOtherConstantsConstant : Constant
|
|
|
|
{
|
|
|
|
internal static readonly Constant Instance = new AllOtherConstantsConstant();
|
|
|
|
|
|
|
|
private AllOtherConstantsConstant() { }
|
|
|
|
|
|
|
|
#region Methods
|
|
|
|
internal override bool IsNull()
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
internal override bool IsNotNull()
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
internal override bool IsUndefined()
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
internal override bool HasNotNull()
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Not supported in this class.
|
|
|
|
/// </summary>
|
|
|
|
internal override StringBuilder AsEsql(StringBuilder builder, MemberPath outputMember, string blockAlias)
|
|
|
|
{
|
|
|
|
Debug.Fail("Should not be called.");
|
|
|
|
return null; // To keep the compiler happy
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Not supported in this class.
|
|
|
|
/// </summary>
|
|
|
|
internal override DbExpression AsCqt(DbExpression row, MemberPath outputMember)
|
|
|
|
{
|
|
|
|
Debug.Fail("Should not be called.");
|
|
|
|
return null; // To keep the compiler happy
|
|
|
|
}
|
|
|
|
|
|
|
|
public override int GetHashCode()
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected override bool IsEqualTo(Constant right)
|
|
|
|
{
|
|
|
|
Debug.Assert(Object.ReferenceEquals(this, Instance), "this must be == Instance for NullConstant");
|
|
|
|
return Object.ReferenceEquals(this, right);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Not supported in this class.
|
|
|
|
/// </summary>
|
|
|
|
internal override string ToUserString()
|
|
|
|
{
|
|
|
|
Debug.Fail("We should not emit a message about Undefined constants to the user.");
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
internal override void ToCompactString(StringBuilder builder)
|
|
|
|
{
|
|
|
|
builder.Append("AllOtherConstants");
|
|
|
|
}
|
|
|
|
#endregion
|
|
|
|
}
|
|
|
|
#endregion
|
|
|
|
}
|
|
|
|
}
|