예제 #1
0
		private static void RenderNonScalarProperties(ASTAppender appender, FromElement fromElement, int nonscalarSize, int k)
		{
			string text = fromElement.RenderPropertySelect(nonscalarSize, k);
			appender.Append(HqlSqlWalker.SQL_TOKEN, text, false);

			if (fromElement.QueryableCollection != null && fromElement.IsFetch)
			{
				text = fromElement.RenderCollectionSelectFragment(nonscalarSize, k);
				appender.Append(HqlSqlWalker.SQL_TOKEN, text, false);
			}

			// Look through the FromElement's children to find any collections of values that should be fetched...
			ASTIterator iter = new ASTIterator(fromElement);
			foreach (FromElement child in iter)
			{
				if (child.IsCollectionOfValuesOrComponents && child.IsFetch)
				{
					// Need a better way to define the suffixes here...
					text = child.RenderValueCollectionSelectFragment(nonscalarSize, nonscalarSize + k);
					appender.Append(HqlSqlWalker.SQL_TOKEN, text, false);
				}
			}
		}
예제 #2
0
		private void RenderNonScalarIdentifiers(FromElement fromElement, int nonscalarSize, int j, ISelectExpression expr, ASTAppender appender)
		{
			string text = fromElement.RenderIdentifierSelect(nonscalarSize, j);

			if (!fromElement.FromClause.IsSubQuery)
			{
				if (!_scalarSelect && !Walker.IsShallowQuery)
				{
					//TODO: is this a bit ugly?
					expr.Text = text;
				}
				else
				{
					appender.Append(HqlSqlWalker.SQL_TOKEN, text, false);
				}
			}
		}
예제 #3
0
		/// <summary>
		/// Prepares a derived (i.e., not explicitly defined in the query) select clause.
		/// </summary>
		/// <param name="fromClause">The from clause to which this select clause is linked.</param>
		public void InitializeDerivedSelectClause(FromClause fromClause)
		{
			if (_prepared)
			{
				throw new InvalidOperationException("SelectClause was already prepared!");
			}

			//Used to be tested by the TCK but the test is no longer here
			//		if ( getSessionFactoryHelper().isStrictJPAQLComplianceEnabled() && !getWalker().isSubQuery() ) {
			//			// NOTE : the isSubQuery() bit is a temporary hack...
			//			throw new QuerySyntaxException( "JPA-QL compliance requires select clause" );
			//		}
			IList<IASTNode> fromElements = fromClause.GetProjectionList();

			ASTAppender appender = new ASTAppender(ASTFactory, this);	// Get ready to start adding nodes.
			int size = fromElements.Count;
			List<IType> sqlResultTypeList = new List<IType>(size);
			List<IType> queryReturnTypeList = new List<IType>(size);

			int k = 0;
			foreach (FromElement fromElement in fromElements)
			{
				IType type = fromElement.SelectType;

				AddCollectionFromElement(fromElement);

				if (type != null)
				{
					bool collectionOfElements = fromElement.IsCollectionOfValuesOrComponents;
					if (!collectionOfElements)
					{
						if (!fromElement.IsFetch)
						{
							// Add the type to the list of returned sqlResultTypes.
							queryReturnTypeList.Add(type);
						}

						_fromElementsForLoad.Add(fromElement);
						sqlResultTypeList.Add(type);

						// Generate the select expression.
						string text = fromElement.RenderIdentifierSelect(size, k);

						SelectExpressionImpl generatedExpr = (SelectExpressionImpl)appender.Append(HqlSqlWalker.SELECT_EXPR, text, false);
						if (generatedExpr != null)
						{
							generatedExpr.FromElement = fromElement;
						}
					}
				}
				k++;
			}

			// Get all the select expressions (that we just generated) and render the select.
			ISelectExpression[] selectExpressions = CollectSelectExpressions();

			if (Walker.IsShallowQuery)
			{
				RenderScalarSelects(selectExpressions, fromClause);
			}
			else
			{
				RenderNonScalarSelects(selectExpressions, fromClause);
			}

			FinishInitialization( /*sqlResultTypeList,*/ queryReturnTypeList);
		}
예제 #4
0
		private void RenderNonScalarSelects(ISelectExpression[] selectExpressions, FromClause currentFromClause)
		{
			ASTAppender appender = new ASTAppender(ASTFactory, this);
			int size = selectExpressions.Length;
			int nonscalarSize = 0;

			for (int i = 0; i < size; i++)
			{
				if (!selectExpressions[i].IsScalar)
				{
					nonscalarSize++;
				}
			}

			int j = 0;
			for (int i = 0; i < size; i++)
			{
				if (!selectExpressions[i].IsScalar)
				{
					ISelectExpression expr = selectExpressions[i];
					FromElement fromElement = expr.FromElement;
					if (fromElement != null)
					{
						RenderNonScalarIdentifiers(fromElement, nonscalarSize, j, expr, appender);
						j++;
					}
				}
			}

			if (!currentFromClause.IsSubQuery)
			{
				// Generate the property select tokens.
				int k = 0;
				for (int i = 0; i < size; i++)
				{
					if (!selectExpressions[i].IsScalar)
					{
						FromElement fromElement = selectExpressions[i].FromElement;
						if (fromElement != null)
						{
							RenderNonScalarProperties(appender, fromElement, nonscalarSize, k);
							k++;
						}
					}
				}
			}
		}
예제 #5
0
		/// <summary>
		/// Prepares an explicitly defined select clause.
		/// </summary>
		/// <param name="fromClause">The from clause linked to this select clause.</param>
		/// <exception cref="SemanticException"></exception>
		public void InitializeExplicitSelectClause(FromClause fromClause)
		{
			if (_prepared)
			{
				throw new InvalidOperationException("SelectClause was already prepared!");
			}

			//explicit = true;	// This is an explict Select.
			//ArrayList sqlResultTypeList = new ArrayList();
			List<IType> queryReturnTypeList = new List<IType>();

			// First, collect all of the select expressions.
			// NOTE: This must be done *before* invoking setScalarColumnText() because setScalarColumnText()
			// changes the AST!!!
			ISelectExpression[] selectExpressions = CollectSelectExpressions();

			for (int i = 0; i < selectExpressions.Length; i++)
			{
				ISelectExpression expr = selectExpressions[i];

				if (expr.IsConstructor)
				{
					_constructorNode = (ConstructorNode)expr;
					IList<IType> constructorArgumentTypeList = _constructorNode.ConstructorArgumentTypeList;
					//sqlResultTypeList.addAll( constructorArgumentTypeList );
					queryReturnTypeList.AddRange(constructorArgumentTypeList);
					_scalarSelect = true;

					for (int j = 1; j < _constructorNode.ChildCount; j++)
					{
						ISelectExpression se = _constructorNode.GetChild(j) as ISelectExpression;

						if (se != null && IsReturnableEntity(se))
						{
							_fromElementsForLoad.Add(se.FromElement);
						}
					}
				}
				else
				{
					IType type = expr.DataType;
					if (type == null && !(expr is ParameterNode))
					{
						throw new QueryException("No data type for node: " + expr.GetType().Name + " " + new ASTPrinter().ShowAsString((IASTNode)expr, ""));
					}
					//sqlResultTypeList.add( type );

					// If the data type is not an association type, it could not have been in the FROM clause.
					if (expr.IsScalar)
					{
						_scalarSelect = true;
					}

					if (IsReturnableEntity(expr))
					{
						_fromElementsForLoad.Add(expr.FromElement);
					}

					// Always add the type to the return type list.
					queryReturnTypeList.Add(type);
				}
			}

			//init the aliases, after initing the constructornode
			InitAliases(selectExpressions);

			if (!Walker.IsShallowQuery)
			{
				// add the fetched entities
				IList<IASTNode> fromElements = fromClause.GetProjectionList();

				ASTAppender appender = new ASTAppender(ASTFactory, this);	// Get ready to start adding nodes.
				int size = fromElements.Count;
				int k = 0;

				foreach (FromElement fromElement in fromElements)
				{
					if (fromElement.IsFetch)
					{
						FromElement origin;
						if (fromElement.RealOrigin == null)
						{
							// work around that crazy issue where the tree contains
							// "empty" FromElements (no text); afaict, this is caused
							// by FromElementFactory.createCollectionJoin()
							if (fromElement.Origin == null)
							{
								throw new QueryException("Unable to determine origin of join fetch [" + fromElement.GetDisplayText() + "]");
							}

							origin = fromElement.Origin;
						}
						else
						{
							origin = fromElement.RealOrigin;
						}

						// Only perform the fetch if its owner is included in the select 
						if (!_fromElementsForLoad.Contains(origin))
						{
							// NH-2846: Before 2012-01-18, we threw this exception. However, some
							// components using LINQ (e.g. paging) like to automatically append e.g. Count(). It
							// can then be difficult to avoid having a bogus fetch statement, so just ignore those.
							// An alternative solution may be to have the linq provider filter out the fetch instead.
							// throw new QueryException(string.Format(JoinFetchWithoutOwnerExceptionMsg, fromElement.GetDisplayText()));

							//throw away the fromElement. It's clearly redundant.
							fromElement.Parent.RemoveChild(fromElement);
						}
						else
						{

							IType type = fromElement.SelectType;
							AddCollectionFromElement(fromElement);

							if (type != null)
							{
								bool collectionOfElements = fromElement.IsCollectionOfValuesOrComponents;
								if (!collectionOfElements)
								{
									// Add the type to the list of returned sqlResultTypes.
									fromElement.IncludeSubclasses = true;
									_fromElementsForLoad.Add(fromElement);
									//sqlResultTypeList.add( type );
									// Generate the select expression.
									String text = fromElement.RenderIdentifierSelect(size, k);
									SelectExpressionImpl generatedExpr = (SelectExpressionImpl)appender.Append(HqlSqlWalker.SELECT_EXPR, text, false);
									if (generatedExpr != null)
									{
										generatedExpr.FromElement = fromElement;
									}
								}
							}
						}
					}

					k++;
				}

				// generate id select fragment and then property select fragment for
				// each expression, just like generateSelectFragments().
				RenderNonScalarSelects(CollectSelectExpressions(true), fromClause);
			}

			if (_scalarSelect || Walker.IsShallowQuery)
			{
				// If there are any scalars (non-entities) selected, render the select column aliases.
				RenderScalarSelects(selectExpressions, fromClause);
			}

			FinishInitialization( /*sqlResultTypeList,*/ queryReturnTypeList);
		}
예제 #6
0
		private void RenderNonScalarSelects(ISelectExpression[] selectExpressions, FromClause currentFromClause)
		{
			var appender = new ASTAppender(ASTFactory, this);
			var nonscalarSize = selectExpressions.Count(e => !e.IsScalar);

			int j = 0;
			foreach (var e in selectExpressions)
			{
				if (!e.IsScalar)
				{
					FromElement fromElement = e.FromElement;
					if (fromElement != null)
					{
						RenderNonScalarIdentifiers(fromElement, nonscalarSize, j, e, appender);
						j++;
					}
				}
			}

			if (!currentFromClause.IsSubQuery)
			{
				// Generate the property select tokens.
				int k = 0;
				foreach (var e in selectExpressions)
				{
					if (!e.IsScalar)
					{
						FromElement fromElement = e.FromElement;
						if (fromElement != null)
						{
							RenderNonScalarProperties(appender, fromElement, nonscalarSize, k);
							k++;
						}
					}
				}
			}
		}