public NativeSQLQuerySpecification(
			string queryString,
			INativeSQLQueryReturn[] sqlQueryReturns,
			ICollection<string> querySpaces)
		{
			this.queryString = queryString;
			this.sqlQueryReturns = sqlQueryReturns;

			if (querySpaces == null)
			{
                this.querySpaces = new IESI.HashedSet<string>();
			}
			else
			{
                var tmp = new IESI.HashedSet<string>();
				tmp.AddAll(querySpaces);
				// Can't use ImmutableSet here because it doesn't implement GetHashCode properly.
				this.querySpaces = tmp;
			}

			// pre-determine and cache the hashcode
			int hCode = queryString.GetHashCode();
			unchecked
			{
				hCode = 29 * hCode + CollectionHelper.GetHashCode(this.querySpaces);
				if (this.sqlQueryReturns != null)
				{
					hCode = 29 * hCode + CollectionHelper.GetHashCode(this.sqlQueryReturns);
				}
			}

			hashCode = hCode;
		}
		public IESI.ISet<string> GetQuerySpaces()
		{
			IESI.ISet<string> result = new IESI.HashedSet<string>();

			foreach (ICriteriaInfoProvider info in criteriaInfoMap.Values)
			{
				result.AddAll(info.Spaces);
			}

			foreach (ICollectionPersister collectionPersister in criteriaCollectionPersisters)
			{
				result.AddAll(collectionPersister.CollectionSpaces);
			}
			return result;
		}
		public AssignmentSpecification(IASTNode eq, IQueryable persister)
		{
			if (eq.Type != HqlSqlWalker.EQ)
			{
				throw new QueryException("assignment in set-clause not associated with equals");
			}

			_eq = eq;
			_factory = persister.Factory;

			// Needed to bump this up to DotNode, because that is the only thing which currently
			// knows about the property-ref path in the correct format; it is either this, or
			// recurse over the DotNodes constructing the property path just like DotNode does
			// internally
			DotNode lhs;
			try
			{
				lhs = (DotNode)eq.GetFirstChild();
			}
			catch (InvalidCastException e)
			{
				throw new QueryException(
					string.Format("Left side of assigment should be a case sensitive property or a field (depending on mapping); found '{0}'", eq.GetFirstChild()), e);
			}
			var rhs = (SqlNode)lhs.NextSibling;

			ValidateLhs(lhs);

			string propertyPath = lhs.PropertyPath;
			var temp = new IESI.HashedSet<string>();
			// yuck!
			var usep = persister as UnionSubclassEntityPersister;
			if (usep!=null)
			{
				temp.AddAll(persister.ConstraintOrderedTableNameClosure);
			}
			else
			{
				temp.Add(persister.GetSubclassTableName(persister.GetSubclassPropertyTableNumber(propertyPath)));
			}
			_tableNames = new IESI.ImmutableSet<string>(temp);

			if (rhs == null)
			{
				_hqlParameters = new IParameterSpecification[0];
			}
			else if (IsParam(rhs))
			{
				_hqlParameters = new[] { ((ParameterNode)rhs).HqlParameterSpecification };
			}
			else
			{
				var parameterList = ASTUtil.CollectChildren(rhs, IsParam);
				_hqlParameters = new IParameterSpecification[parameterList.Count];
				int i = 0;
				foreach (ParameterNode parameterNode in parameterList)
				{
					_hqlParameters[i++] = parameterNode.HqlParameterSpecification;
				}
			}
		}