private static IASTNode MakeIdent(IASTNode source, string text)
 {
     var ident = source.DupNode();
     ident.Type = HqlSqlWalker.IDENT;
     ident.Text = text;
     return ident;
 }
		private static void AddImpliedFromToFromNode(IASTNode fromClause, string collectionRole, ISessionFactoryImplementor factory)
		{
			SessionFactoryHelperExtensions _sessionFactoryHelper = new SessionFactoryHelperExtensions(factory);
			IQueryableCollection persister = _sessionFactoryHelper.GetCollectionPersister(collectionRole);
			IType collectionElementType = persister.ElementType;
			if (!collectionElementType.IsEntityType)
			{
				throw new QueryException("collection of values in filter: this");
			}

			string collectionElementEntityName = persister.ElementPersister.EntityName;

			ITreeAdaptor adaptor = new ASTTreeAdaptor();

			IASTNode fromElement = (IASTNode)adaptor.Create(HqlParser.FILTER_ENTITY, collectionElementEntityName);
			IASTNode alias = (IASTNode)adaptor.Create(HqlParser.ALIAS, "this");

			fromClause.AddChild(fromElement);
			fromClause.AddChild(alias);

			// Show the modified AST.
			if (log.IsDebugEnabled)
			{
				log.Debug("AddImpliedFormToFromNode() : Filter - Added 'this' as a from element...");
			}
		}
		public void Visit(IASTNode node)
		{
			if (predicate == null || predicate(node))
			{
				collectedNodes.Add(node);
			}
		}
		/// <summary>
		/// Insert a new node into both the Tree and the Node Array. Add DOWN and UP nodes if needed.
		/// </summary>
		/// <param name="parent">The parent node</param>
		/// <param name="child">The child node</param>
		public void InsertChild(IASTNode parent, IASTNode child)
		{
			if (child.ChildCount > 0)
			{
				throw new InvalidOperationException("Currently do not support adding nodes with children");
			}

			int parentIndex = nodes.IndexOf(parent);
			int numberOfChildNodes = NumberOfChildNodes(parentIndex);
			int insertPoint;
			
			if (numberOfChildNodes == 0)
			{
				insertPoint = parentIndex + 1;  // We want to insert immediately after the parent
				nodes.Insert(insertPoint, down);
				insertPoint++;  // We've just added a new node
			}
			else
			{
				insertPoint = parentIndex + numberOfChildNodes;
			}

			parent.AddChild(child);
			nodes.Insert(insertPoint, child);
			insertPoint++;

			if (numberOfChildNodes == 0)
			{
				nodes.Insert(insertPoint, up);
			}
		}
 public void Visit(IASTNode node)
 {
     if (node.Type == HqlSqlWalker.FROM)
     {
         _nodes.AddRange(node.Where(child => child.Type == HqlSqlWalker.RANGE).Select(range => range.GetChild(0)));
     }
 }
		protected SqlString GenerateIdInsertSelect(IQueryable persister, string tableAlias, IASTNode whereClause)
		{
			var select = new SqlSelectBuilder(Factory);
			SelectFragment selectFragment = new SelectFragment(Factory.Dialect)
				.AddColumns(tableAlias, persister.IdentifierColumnNames, persister.IdentifierColumnNames);
			select.SetSelectClause(selectFragment.ToFragmentString().Substring(2));

			string rootTableName = persister.TableName;
			SqlString fromJoinFragment = persister.FromJoinFragment(tableAlias, true, false);
			SqlString whereJoinFragment = persister.WhereJoinFragment(tableAlias, true, false);

			select.SetFromClause(rootTableName + ' ' + tableAlias + fromJoinFragment);

			if (whereJoinFragment == null)
			{
				whereJoinFragment = SqlString.Empty;
			}
			else
			{
				whereJoinFragment = whereJoinFragment.Trim();
				if (whereJoinFragment.StartsWithCaseInsensitive("and "))
				{
					whereJoinFragment = whereJoinFragment.Substring(4);
				}
			}

			SqlString userWhereClause = SqlString.Empty;
			if (whereClause.ChildCount != 0)
			{
				// If a where clause was specified in the update/delete query, use it to limit the
				// returned ids here...
				try
				{
					var nodes = new CommonTreeNodeStream(whereClause);
					var gen = new SqlGenerator(Factory, nodes);
					gen.whereClause();
					userWhereClause = gen.GetSQL().Substring(7);
				}
				catch (RecognitionException e)
				{
					throw new HibernateException("Unable to generate id select for DML operation", e);
				}
				if (whereJoinFragment.Length > 0)
				{
					whereJoinFragment.Append(" and ");
				}
			}

			select.SetWhereClause(whereJoinFragment + userWhereClause);

			var insert = new InsertSelect();
			if (Factory.Settings.IsCommentsEnabled)
			{
				insert.SetComment("insert-select for " + persister.EntityName + " ids");
			}
			insert.SetTableName(persister.TemporaryIdTableName);
			insert.SetSelect(select);
			return insert.ToSqlString();
		}
		protected HqlTreeNode(int type, string text, IASTFactory factory, IEnumerable<HqlTreeNode> children)
		{
			Factory = factory;
			_node = factory.CreateNode(type, text);
			_children = new List<HqlTreeNode>();

			AddChildren(children);
		}
Beispiel #8
0
		/// <summary>
		/// Returns the 'list' representation with some brackets around it for debugging.
		/// </summary>
		/// <param name="n">The tree.</param>
		/// <returns>The list representation of the tree.</returns>
		public static string GetDebugstring(IASTNode n)
		{
			StringBuilder buf = new StringBuilder();
			buf.Append("[ ");
			buf.Append((n == null) ? "{null}" : n.ToStringTree());
			buf.Append(" ]");
			return buf.ToString();
		}
Beispiel #9
0
		public virtual void ReplaceBy(IASTNode node)
		{
			if (Parent != null)
			{
				throw new ApplicationException("Couldn't find a parent node to delegate");
			}

			Parent.ReplaceChild(this, node);
		}
Beispiel #10
0
        protected HqlTreeNode(int type, string text, IASTFactory factory, params HqlTreeNode[] children)
        {
            _node = factory.CreateNode(type, text);
            _children = new List<HqlTreeNode>();

            foreach (var child in children)
            {
                _children.Add(child);
                _node.AddChild(child.AstNode);
            }
        }
				private void AddImplementorsToMap(IASTNode querySource, string className, string[] implementors)
				{
					if (implementors.Length == 1 && implementors[0] == className)
					{
						// No need to change things
						return;
					}

					_map.Add(querySource,
					         implementors.Select(implementor => MakeIdent(querySource, implementor)).ToArray());
				}
				public Dictionary<IASTNode, IASTNode[]> Process(IASTNode tree)
				{
					foreach (var querySource in new QuerySourceDetector(tree).LocateQuerySources())
					{
						var className = GetClassName(querySource);
						string[] implementors = _sfi.GetImplementors(className);
						AddImplementorsToMap(querySource, className, implementors);
					}

					return _map;
				}
		/// <summary>
		/// Traverse the AST tree depth first. Note that the AST passed in is not visited itself.  Visitation starts
		/// with its children.
		/// </summary>
		/// <param name="ast">ast</param>
		public void TraverseDepthFirst(IASTNode ast)
		{
			if (ast == null)
			{
				throw new ArgumentNullException("ast");
			}

			for (int i = 0; i < ast.ChildCount; i++)
			{
				VisitDepthFirst(ast.GetChild(i));
			}
		}
        public Dictionary<IASTNode, IASTNode[]> Process(IASTNode tree)
        {
            foreach (var querySource in new QuerySourceDetector(tree).LocateQuerySources())
            {
                var className = GetClassName(querySource);
                var classType = _sessionFactoryHelper.GetImportedClass(className);

                AddImplementorsToMap(querySource, classType == null ? className : classType.FullName);
            }

            return _map;
        }
    	private static string GetClassName(IASTNode querySource)
        {
            switch (querySource.Type)
            {
                case HqlSqlWalker.IDENT:
                    return querySource.Text;
                case HqlSqlWalker.DOT:
                    return BuildPath(querySource);
            }

            // TODO
            throw new NotSupportedException();
        }
		/// <summary>
		/// Creates a new AST-based query translator.
		/// </summary>
		/// <param name="queryIdentifier">The query-identifier (used in stats collection)</param>
        /// <param name="parsedQuery">The hql query to translate</param>
		/// <param name="enabledFilters">Currently enabled filters</param>
		/// <param name="factory">The session factory constructing this translator instance.</param>
		public QueryTranslatorImpl(
				string queryIdentifier,
				IASTNode parsedQuery,
				IDictionary<string, IFilter> enabledFilters,
				ISessionFactoryImplementor factory)
		{
			_queryIdentifier = queryIdentifier;
            _stageOneAst = parsedQuery;
			_compiled = false;
			_shallowQuery = false;
			_enabledFilters = enabledFilters;
			_factory = factory;
		}
        private IEnumerable<IASTNode> DuplicateTree()
        {
            var replacements = CrossJoinDictionaryArrays.PerformCrossJoin(_nodeMapping);

            var dups = new IASTNode[replacements.Count()];

            for (var i = 0; i < replacements.Count(); i++)
            {
                dups[i] = DuplicateTree(_ast, replacements[i]);
            }

            return dups;
        }
		private void VisitDepthFirst(IASTNode ast)
		{
			if (ast == null)
			{
				return;
			}

			_visitor.Visit(ast);

			for (int i = 0; i < ast.ChildCount; i++)
			{
				VisitDepthFirst(ast.GetChild(i));
			}
		}
		/// <summary>
		/// Handles HQL AST transformation for collection filters (which are created with <see cref="ISession.CreateFilter"/>).
		/// 
		/// Adds FROM elements to implicit FROM clause.
		/// E.g., 
		/// <code>
		/// ( query ( SELECT_FROM {filter-implied FROM} ) ( where ( = X 10 ) ) )
		/// </code>
		/// gets converted to 
		/// <code>
		/// ( query ( SELECT_FROM ( FROM NHibernate.DomainModel.Many this ) ) ( where ( = X 10 ) ) )
		/// </code>
		/// </summary>
		/// <param name="ast">The root node of HQL query</param>
		/// <param name="collectionRole">Collection that is being filtered</param>
		/// <param name="factory">Session factory</param>
		internal static void AddImpliedFromToQuery(IASTNode ast, string collectionRole, ISessionFactoryImplementor factory)
		{
			if (ast.Type != HqlParser.QUERY)
			{
				var msg = string.Format(CultureInfo.InvariantCulture,
					"invalid query type for collection filtering: expected {0}, got {1}", HqlParser.tokenNames[HqlParser.QUERY], HqlParser.tokenNames[ast.Type]);
				throw new QueryException(msg);
			}
			var selectFromClause = ast.Where(x => x.Type == HqlParser.SELECT_FROM).Single();
			var fromClause = selectFromClause.Where(x => x.Type == HqlParser.FROM).Single();
			
			fromClause.Text = "FROM"; // Just for prettier debug output
			AddImpliedFromToFromNode(fromClause, collectionRole, factory);
		}
        private static void BuildPath(IASTNode node, StringBuilder sb)
        {
            if (node.Type == HqlSqlWalker.DOT)
            {
                BuildPath(node.GetChild(0), sb);

                sb.Append('.');
                sb.Append(node.GetChild(1).Text);
            }
            else
            {
                sb.Append(node.Text);
            }
        }
		public void RecursiveResolve(int level, bool impliedAtRoot, string classAlias, IASTNode parent)
		{
			IASTNode lhs = GetFirstChild();
			int nextLevel = level + 1;
			if ( lhs != null ) 
			{
				FromReferenceNode n = ( FromReferenceNode ) lhs;
				n.RecursiveResolve( nextLevel, impliedAtRoot, null, this );
			}

			ResolveFirstChild();
			bool impliedJoin = !(level == RootLevel && !impliedAtRoot);

			Resolve( true, impliedJoin, classAlias, parent );
		}
		private static void Check(IASTNode check, IASTNode first, IASTNode second)
		{
			if (typeof(IExpectedTypeAwareNode).IsAssignableFrom(check.GetType()))
			{
				IType expectedType = null;
				if (typeof(SqlNode).IsAssignableFrom(first.GetType()))
				{
					expectedType = ((SqlNode)first).DataType;
				}
				if (expectedType == null && typeof(SqlNode).IsAssignableFrom(second.GetType()))
				{
					expectedType = ((SqlNode)second).DataType;
				}
				((IExpectedTypeAwareNode)check).ExpectedType = expectedType;
			}
		}
Beispiel #23
0
		/// <summary>
		/// Determine if a given node (test) is contained anywhere in the subtree
		/// of another given node (fixture).
		/// </summary>
		/// <param name="fixture">The node against which to be checked for children.</param>
		/// <param name="test">The node to be tested as being a subtree child of the parent.</param>
		/// <returns>True if child is contained in the parent's collection of children.</returns>
		public static bool IsSubtreeChild(IASTNode fixture, IASTNode test)
		{
			for (int i = 0; i < fixture.ChildCount; i++)
			{
				IASTNode n = fixture.GetChild(i);

				if (n == test)
				{
					return true;
				}
				if (n.ChildCount > 0 && IsSubtreeChild(n, test))
				{
					return true;
				}
			}
			return false;
		}
        private static IASTNode DuplicateTree(IASTNode ast, IDictionary<IASTNode, IASTNode> nodeMapping)
        {
            IASTNode candidate;

            if (nodeMapping.TryGetValue(ast, out candidate))
            {
                return candidate;
            }

            var dup = ast.DupNode();

            foreach (var child in ast)
            {
                dup.AddChild(DuplicateTree(child, nodeMapping));
            }

            return dup;
        }
Beispiel #25
0
		private static void GetPathText(StringBuilder buf, IASTNode n)
		{
			IASTNode firstChild = n.GetChild(0);

			// If the node has a first child, recurse into the first child.
			if (firstChild != null)
			{
				GetPathText(buf, firstChild);
			}

			// Append the text of the current node.
			buf.Append(n.Text);

			// If there is a second child (RHS), recurse into that child.
			if (firstChild != null && n.ChildCount > 1)
			{
				GetPathText(buf, n.GetChild(1));
			}
		}
	    public IASTNode Translate(ISessionFactory sessionFactory)
		{
            //if (_astNode == null)
            {
                var requiredHqlParameters = new List<NamedParameterDescriptor>();

                // TODO - can we cache any of this? 
                var queryModel = NhRelinqQueryParser.Parse(_expression);

                ExpressionToHqlTranslationResults = QueryModelVisitor.GenerateHqlQuery(queryModel,
                                                                                       _constantToParameterMap,
                                                                                       requiredHqlParameters);

                ParameterDescriptors = requiredHqlParameters.AsReadOnly();
                _astNode = ExpressionToHqlTranslationResults.Statement.AstNode;
            }

	        return _astNode;
		}
		public override void ResolveIndex(IASTNode parent)
		{
			// An ident node can represent an index expression if the ident
			// represents a naked property ref
			//      *Note: this makes the assumption (which is currently the case
			//      in the hql-sql grammar) that the ident is first resolved
			//      itself (addrExpr -> resolve()).  The other option, if that
			//      changes, is to call resolve from here; but it is
			//      currently un-needed overhead.
			if (!(IsResolved && _nakedPropertyRef)) 
			{
				throw new InvalidOperationException();
			}

			string propertyName = OriginalText;
			if (!DataType.IsCollectionType) 
			{
				throw new SemanticException("Collection expected; [" + propertyName + "] does not refer to a collection property");
			}

			// TODO : most of below was taken verbatim from DotNode; should either delegate this logic or super-type it
			CollectionType type = (CollectionType) DataType;
			string role = type.Role;
			IQueryableCollection queryableCollection = SessionFactoryHelper.RequireQueryableCollection(role);

			string columnTableAlias = FromElement.TableAlias;

			FromElementFactory factory = new FromElementFactory(
				  	Walker.CurrentFromClause,
					FromElement,
					propertyName,
					null,
					FromElement.ToColumns(columnTableAlias, propertyName, false),
					true
			);

			FromElement elem = factory.CreateCollection(queryableCollection, role, JoinType.InnerJoin, false, true);
			FromElement = elem;
			Walker.AddQuerySpaces(queryableCollection.CollectionSpaces);	// Always add the collection's query spaces.
		}
		private static void Check(IASTNode check, IASTNode first, IASTNode second)
		{
			var expectedTypeAwareNode = check as IExpectedTypeAwareNode;
			if (expectedTypeAwareNode != null)
			{
				IType expectedType = null;
				var firstNode = first as SqlNode;
				if (firstNode != null)
				{
					expectedType = firstNode.DataType;
				}
				if (expectedType == null)
				{
					var secondNode = second as SqlNode;
					if (secondNode != null)
					{
						expectedType = secondNode.DataType;
					}
				}
				expectedTypeAwareNode.ExpectedType = expectedType;
			}
		}
		/// <summary>
		/// Generates the scalar column AST nodes for a given array of SQL columns
		/// </summary>
		public static void GenerateScalarColumns(IASTFactory factory, IASTNode node, string[] sqlColumns, int i)
		{
			if (sqlColumns.Length == 1)
			{
				GenerateSingleScalarColumn(factory, node, i);
			}
			else
			{
				node.Text = sqlColumns[0]; // Use the DOT node to emit the first column name.

				// Create the column names, folled by the column aliases.
				for (int j = 0; j < sqlColumns.Length; j++)
				{
					if (j > 0)
					{
						node = node.AddSibling(factory.CreateNode(HqlSqlWalker.SQL_TOKEN, sqlColumns[j]));
					}

					node = node.AddSibling(factory.CreateNode(HqlSqlWalker.SELECT_COLUMNS, " as " + NameGenerator.ScalarName(i, j)));
				}
			}
		}
		static IQueryTranslator[] CreateQueryTranslators(IASTNode ast, string queryIdentifier, string collectionRole, bool shallow, IDictionary<string, IFilter> filters, ISessionFactoryImplementor factory)
		{
			var polymorphicParsers = AstPolymorphicProcessor.Process(ast, factory);

			var translators = polymorphicParsers
							.Select(hql => new QueryTranslatorImpl(queryIdentifier, hql, filters, factory))
							.ToArray();

			foreach (var translator in translators)
			{
				if (collectionRole == null)
				{
					translator.Compile(factory.Settings.QuerySubstitutions, shallow);
				}
				else
				{
					translator.Compile(collectionRole, factory.Settings.QuerySubstitutions, shallow);
				}
			}

			return translators;
			
		}
Beispiel #31
0
 void ProcessBool(IASTNode constant)
 {
     _literalProcessor.ProcessBoolean(constant);             // Use the delegate.
 }
        void CreateFromJoinElement(
            IASTNode path,
            IASTNode alias,
            int joinType,
            IASTNode fetchNode,
            IASTNode propertyFetch,
            IASTNode with)
        {
            bool fetch = fetchNode != null;

            if (fetch && IsSubQuery)
            {
                throw new QueryException("fetch not allowed in subquery from-elements");
            }
            // The path AST should be a DotNode, and it should have been evaluated already.
            if (path.Type != DOT)
            {
                throw new SemanticException("Path expected for join!");
            }

            DotNode dot = ( DotNode )path;
            //JoinType hibernateJoinType = JoinProcessor.ToHibernateJoinType( joinType );
            JoinType hibernateJoinType = _impliedJoinType;

            dot.JoinType = hibernateJoinType;                   // Tell the dot node about the join type.
            dot.Fetch    = fetch;

            // Generate an explicit join for the root dot node.   The implied joins will be collected and passed up
            // to the root dot node.
            dot.Resolve(true, false, alias == null ? null : alias.Text);

            FromElement fromElement;

            if (dot.DataType != null && dot.DataType.IsComponentType)
            {
                var factory = new FromElementFactory(CurrentFromClause, dot.GetLhs().FromElement, dot.PropertyPath, alias == null ? null : alias.Text, null, false);
                fromElement = factory.CreateComponentJoin((ComponentType)dot.DataType);
            }
            else
            {
                fromElement = dot.GetImpliedJoin();
                if (fromElement == null)
                {
                    throw new InvalidPathException("Invalid join: " + dot.Path);
                }
                fromElement.SetAllPropertyFetch(propertyFetch != null);

                if (with != null)
                {
                    if (fetch)
                    {
                        throw new SemanticException("with-clause not allowed on fetched associations; use filters");
                    }

                    HandleWithFragment(fromElement, with);
                }
            }

            if (log.IsDebugEnabled)
            {
                log.Debug("createFromJoinElement() : " + _printer.ShowAsString(fromElement, "-- join tree --"));
            }
        }
Beispiel #33
0
        public void RecursiveResolve(int level, bool impliedAtRoot, string classAlias, IASTNode parent)
        {
            IASTNode lhs       = GetFirstChild();
            int      nextLevel = level + 1;

            if (lhs != null)
            {
                FromReferenceNode n = ( FromReferenceNode )lhs;
                n.RecursiveResolve(nextLevel, impliedAtRoot, null, this);
            }

            ResolveFirstChild();
            bool impliedJoin = !(level == RootLevel && !impliedAtRoot);

            Resolve(true, impliedJoin, classAlias, parent);
        }
Beispiel #34
0
 public static IList <IASTNode> CollectChildren(IASTNode root, FilterPredicate predicate)
 {
     return(new CollectingNodeVisitor(predicate).Collect(root));
 }
Beispiel #35
0
        public void AddWhereFragment(
            JoinFragment joinFragment,
            SqlString whereFragment,
            QueryNode query,
            FromElement fromElement,
            HqlSqlWalker hqlSqlWalker)
        {
            if (whereFragment == null)
            {
                return;
            }

            if (!fromElement.UseWhereFragment && !joinFragment.HasThetaJoins)
            {
                return;
            }

            whereFragment = whereFragment.Trim();
            if (StringHelper.IsEmpty(whereFragment.ToString()))
            {
                return;
            }

            // Forcefully remove leading ands from where fragments; the grammar will
            // handle adding them
            if (whereFragment.StartsWithCaseInsensitive("and"))
            {
                whereFragment = whereFragment.Substring(4);
            }

            log.Debug("Using unprocessed WHERE-fragment [{0}]", whereFragment);

            SqlFragment fragment = (SqlFragment)Create(HqlSqlWalker.SQL_TOKEN, whereFragment.ToString());

            fragment.SetJoinFragment(joinFragment);
            fragment.FromElement = fromElement;

            if (fromElement.IndexCollectionSelectorParamSpec != null)
            {
                fragment.AddEmbeddedParameter(fromElement.IndexCollectionSelectorParamSpec);
                fromElement.IndexCollectionSelectorParamSpec = null;
            }

            if (hqlSqlWalker.IsFilter())
            {
                //if (whereFragment.IndexOfCaseInsensitive("?") >= 0)
                if (whereFragment.IndexOfOrdinal("?") >= 0)
                {
                    IType collectionFilterKeyType = hqlSqlWalker.SessionFactoryHelper
                                                    .RequireQueryableCollection(hqlSqlWalker.CollectionFilterRole)
                                                    .KeyType;
                    CollectionFilterKeyParameterSpecification paramSpec = new CollectionFilterKeyParameterSpecification(
                        hqlSqlWalker.CollectionFilterRole,
                        collectionFilterKeyType,
                        0
                        );
                    fragment.AddEmbeddedParameter(paramSpec);
                }
            }

            JoinProcessor.ProcessDynamicFilterParameters(
                whereFragment,
                fragment,
                hqlSqlWalker
                );

            log.Debug("Using processed WHERE-fragment [{0}]", fragment.Text);

            // Filter conditions need to be inserted before the HQL where condition and the
            // theta join node.  This is because org.hibernate.loader.Loader binds the filter parameters first,
            // then it binds all the HQL query parameters, see org.hibernate.loader.Loader.processFilterParameters().
            if (fragment.FromElement.IsFilter || fragment.HasFilterCondition)
            {
                if (_filters == null)
                {
                    // Find or create the WHERE clause
                    IASTNode where = (IASTNode)query.WhereClause;
                    // Create a new FILTERS node as a parent of all filters
                    _filters = Create(HqlSqlWalker.FILTERS, "{filter conditions}");
                    // Put the FILTERS node before the HQL condition and theta joins
                    where.InsertChild(0, _filters);
                }

                // add the current fragment to the FILTERS node
                _filters.AddChild(fragment);
            }
            else
            {
                if (_thetaJoins == null)
                {
                    // Find or create the WHERE clause
                    IASTNode where = (IASTNode)query.WhereClause;

                    // Create a new THETA_JOINS node as a parent of all filters
                    _thetaJoins = Create(HqlSqlWalker.THETA_JOINS, "{theta joins}");

                    // Put the THETA_JOINS node before the HQL condition, after the filters.
                    if (_filters == null)
                    {
                        where.InsertChild(0, _thetaJoins);
                    }
                    else
                    {
                        _filters.AddSibling(_thetaJoins);
                    }
                }

                // add the current fragment to the THETA_JOINS node
                _thetaJoins.AddChild(fragment);
            }
        }
 private static bool IsParam(IASTNode node)
 {
     return(node.Type == HqlSqlWalker.PARAM || node.Type == HqlSqlWalker.NAMED_PARAM);
 }
Beispiel #37
0
        public override void Resolve(bool generateJoin, bool implicitJoin, string classAlias, IASTNode parent)
        {
            if (!IsResolved)
            {
                if (Walker.CurrentFromClause.IsFromElementAlias(Text))
                {
                    if (ResolveAsAlias())
                    {
                        IsResolved = true;
                        // We represent a from-clause alias
                    }
                }
                else if (parent != null && parent.Type == HqlSqlWalker.DOT)
                {
                    DotNode dot = (DotNode)parent;
                    if (parent.GetFirstChild() == this)
                    {
                        if (ResolveAsNakedComponentPropertyRefLhs(dot))
                        {
                            // we are the LHS of the DOT representing a naked comp-prop-ref
                            IsResolved = true;
                        }
                    }
                    else
                    {
                        if (ResolveAsNakedComponentPropertyRefRhs(dot))
                        {
                            // we are the RHS of the DOT representing a naked comp-prop-ref
                            IsResolved = true;
                        }
                    }
                }
                else
                {
                    int result = ResolveAsNakedPropertyRef();
                    if (result == PropertyRef)
                    {
                        // we represent a naked (simple) prop-ref
                        IsResolved = true;
                    }
                    else if (result == ComponentRef)
                    {
                        // EARLY EXIT!!!  return so the resolve call explicitly coming from DotNode can
                        // resolve this...
                        return;
                    }
                }

                // if we are still not resolved, we might represent a constant.
                //      needed to add this here because the allowance of
                //      naked-prop-refs in the grammar collides with the
                //      definition of literals/constants ("nondeterminism").
                //      TODO: cleanup the grammar so that "processConstants" is always just handled from here
                if (!IsResolved)
                {
                    try
                    {
                        Walker.LiteralProcessor.ProcessConstant(this, false);
                    }
                    catch (Exception)
                    {
                        // just ignore it for now, it'll get resolved later...
                    }
                }
            }
        }
Beispiel #38
0
 public override T VisitDefault(IASTNode node) => d;
 static void SetAlias(IASTNode selectExpr, IASTNode ident)
 {
     ((ISelectExpression)selectExpr).Alias = ident.Text;
 }
Beispiel #40
0
        void PostProcessUpdate(IASTNode update)
        {
            var updateStatement = (UpdateStatement)update;

            PostProcessDML(updateStatement);
        }
Beispiel #41
0
 void PostProcessDelete(IASTNode delete)
 {
     PostProcessDML((DeleteStatement)delete);
 }
Beispiel #42
0
 private static String ExtractAppliedAlias(IASTNode dotNode)
 {
     return(dotNode.Text.Substring(0, dotNode.Text.IndexOf('.')));
 }
Beispiel #43
0
        static void ProcessIndex(IASTNode indexOp)
        {
            IndexNode indexNode = (IndexNode)indexOp;

            indexNode.Resolve(true, true);
        }
Beispiel #44
0
 protected void AddFunction(ASTNodeList newNodes, string functionName, IASTNode functionParameter)
 {
     AddFunction(newNodes, functionName, new List <IASTNode> {
         functionParameter
     });
 }
Beispiel #45
0
 static void PrepareLogicOperator(IASTNode operatorNode)
 {
     (( IOperatorNode )operatorNode).Initialize();
 }
Beispiel #46
0
 private void UseSelectClause(IASTNode select)
 {
     _selectClause = (SelectClause)select;
     _selectClause.InitializeExplicitSelectClause(_currentFromClause);
 }
Beispiel #47
0
 public HqlSqlGenerator(IStatement ast, ISessionFactoryImplementor sfi)
 {
     _ast = (IASTNode)ast;
     _sfi = sfi;
 }
Beispiel #48
0
        static void ProcessConstructor(IASTNode constructor)
        {
            ConstructorNode constructorNode = (ConstructorNode)constructor;

            constructorNode.Prepare();
        }
        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 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 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;
                }
            }
        }
Beispiel #50
0
        void CreateFromJoinElement(
            IASTNode path,
            IASTNode alias,
            int joinType,
            IASTNode fetchNode,
            IASTNode propertyFetch,
            IASTNode with)
        {
            bool fetch = fetchNode != null;

            if (fetch && IsSubQuery)
            {
                throw new QueryException("fetch not allowed in subquery from-elements");
            }

            // the incoming "path" can be either:
            //		1) an implicit join path (join p.address.city)
            //      2) an entity-join (join com.acme.User)
            //
            // so make the proper interpretation here...
            var entityJoinReferencedPersister = ResolveEntityJoinReferencedPersister(path);

            if (entityJoinReferencedPersister != null)
            {
                var entityJoin = CreateEntityJoin(entityJoinReferencedPersister, alias, joinType, with);
                ((FromReferenceNode)path).FromElement = entityJoin;
                SetPropertyFetch(entityJoin, propertyFetch, alias);
                return;
            }
            // The path AST should be a DotNode, and it should have been evaluated already.
            if (path.Type != DOT)
            {
                throw new SemanticException("Path expected for join!");
            }

            DotNode dot = ( DotNode )path;
            //JoinType hibernateJoinType = JoinProcessor.ToHibernateJoinType( joinType );
            JoinType hibernateJoinType = _impliedJoinType;

            dot.JoinType = hibernateJoinType;                   // Tell the dot node about the join type.
            dot.Fetch    = fetch;

            // Generate an explicit join for the root dot node.   The implied joins will be collected and passed up
            // to the root dot node.
            dot.Resolve(true, false, alias == null ? null : alias.Text);

            FromElement fromElement;

            if (dot.DataType != null && dot.DataType.IsComponentType)
            {
                var factory = new FromElementFactory(CurrentFromClause, dot.GetLhs().FromElement, dot.PropertyPath, alias == null ? null : alias.Text, null, false);
                fromElement = factory.CreateComponentJoin((ComponentType)dot.DataType);
            }
            else
            {
                fromElement = dot.GetImpliedJoin();
                if (fromElement == null)
                {
                    throw new InvalidPathException("Invalid join: " + dot.Path);
                }
                SetPropertyFetch(fromElement, propertyFetch, alias);

                if (with != null)
                {
                    if (fetch)
                    {
                        throw new SemanticException("with-clause not allowed on fetched associations; use filters");
                    }

                    HandleWithFragment(fromElement, with);
                }

                if (fromElement.Parent == null)
                {
                    fromElement.FromClause.AddChild(fromElement);
                }
            }

            if (log.IsDebugEnabled())
            {
                log.Debug("createFromJoinElement() : {0}", _printer.ShowAsString(fromElement, "-- join tree --"));
            }
        }
        protected SqlString GenerateIdInsertSelect(IQueryable persister, string tableAlias, IASTNode whereClause)
        {
            var            select         = new SqlSelectBuilder(Factory);
            SelectFragment selectFragment = new SelectFragment(Factory.Dialect)
                                            .AddColumns(tableAlias, persister.IdentifierColumnNames, persister.IdentifierColumnNames);

            select.SetSelectClause(selectFragment.ToFragmentString().Substring(2));

            string    rootTableName    = persister.TableName;
            SqlString fromJoinFragment = persister.FromJoinFragment(tableAlias, true, false);

            select.SetFromClause(rootTableName + " " + tableAlias + fromJoinFragment);

            var whereJoinFragment = GetWhereJoinFragment(persister, tableAlias);

            SqlString userWhereClause = SqlString.Empty;

            if (whereClause.ChildCount != 0)
            {
                // If a where clause was specified in the update/delete query, use it to limit the
                // returned ids here...
                try
                {
                    var nodes = new CommonTreeNodeStream(whereClause);
                    var gen   = new SqlGenerator(Factory, nodes);
                    gen.whereClause();
                    userWhereClause = gen.GetSQL().Substring(7);
                }
                catch (RecognitionException e)
                {
                    throw new HibernateException("Unable to generate id select for DML operation", e);
                }
                if (whereJoinFragment.Length > 0)
                {
                    whereJoinFragment = whereJoinFragment.Append(" and ");
                }
            }

            select.SetWhereClause(whereJoinFragment + userWhereClause);

            var insert = new InsertSelect();

            if (Factory.Settings.IsCommentsEnabled)
            {
                insert.SetComment("insert-select for " + persister.EntityName + " ids");
            }
            insert.SetTableName(persister.TemporaryIdTableName);
            insert.SetSelect(select);
            return(insert.ToSqlString());
        }
Beispiel #52
0
        static void SetPropertyFetch(FromElement fromElement, IASTNode propertyFetch, IASTNode alias)
        {
            if (propertyFetch == null)
            {
                return;
            }

            if (propertyFetch.ChildCount == 0)
            {
                fromElement.SetAllPropertyFetch(true);
            }
            else
            {
                var propertyPaths = new string[propertyFetch.ChildCount / 2];
                for (var i = 1; i < propertyFetch.ChildCount; i = i + 2)
                {
                    string propertyPath;
                    var    child = propertyFetch.GetChild(i);

                    // o.PropName
                    if (child is DotNode dotNode)
                    {
                        dotNode.JoinType     = JoinType.None;
                        dotNode.PropertyPath = GetPropertyPath(dotNode, alias);
                        propertyPath         = dotNode.PropertyPath;
                    }
                    else if (child is IdentNode identNode)
                    {
                        propertyPath = identNode.OriginalText;
                    }
                    else
                    {
                        throw new InvalidOperationException($"Unable to determine property path for AST node: {child.ToStringTree()}");
                    }

                    propertyPaths[(i - 1) / 2] = propertyPath;
                }

                fromElement.FetchLazyProperties = propertyPaths;
            }
        }
Beispiel #53
0
 public static void MakeSiblingOfParent(IASTNode parent, IASTNode child)
 {
     parent.RemoveChild(child);
     parent.AddSibling(child);
 }
Beispiel #54
0
 static void PrepareArithmeticOperator(IASTNode op)
 {
     ((IOperatorNode)op).Initialize();
 }
 void ProcessNumericLiteral(IASTNode literal)
 {
     _literalProcessor.ProcessNumericLiteral((SqlNode)literal);
 }
Beispiel #56
0
        static void ProcessFunction(IASTNode functionCall, bool inSelect)
        {
            MethodNode methodNode = (MethodNode)functionCall;

            methodNode.Resolve(inSelect);
        }
Beispiel #57
0
        void PostProcessInsert(IASTNode insert)
        {
            var insertStatement = (InsertStatement)insert;

            insertStatement.Validate();

            SelectClause selectClause = insertStatement.SelectClause;
            var          persister    = insertStatement.IntoClause.Queryable;

            if (!insertStatement.IntoClause.IsExplicitIdInsertion)
            {
                // We need to generate ids as part of this bulk insert.
                //
                // Note that this is only supported for sequence-style generators and
                // post-insert-style generators; basically, only in-db generators
                IIdentifierGenerator generator = persister.IdentifierGenerator;
                if (!SupportsIdGenWithBulkInsertion(generator))
                {
                    throw new QueryException("can only generate ids as part of bulk insert with either sequence or post-insert style generators");
                }

                IASTNode idSelectExprNode = null;

                var seqGenerator = generator as SequenceGenerator;
                if (seqGenerator != null)
                {
                    string seqName = seqGenerator.GeneratorKey();
                    string nextval = SessionFactoryHelper.Factory.Dialect.GetSelectSequenceNextValString(seqName);
                    idSelectExprNode = ASTFactory.CreateNode(SQL_TOKEN, nextval);
                }
                else
                {
                    //Don't need this, because we should never ever be selecting no columns in an insert ... select...
                    //and because it causes a bug on DB2

                    /*String idInsertString = sessionFactoryHelper.getFactory().getDialect().getIdentityInsertString();
                     * if ( idInsertString != null ) {
                     * idSelectExprNode = getASTFactory().create( HqlSqlTokenTypes.SQL_TOKEN, idInsertString );
                     * }*/
                }

                if (idSelectExprNode != null)
                {
                    selectClause.InsertChild(0, idSelectExprNode);

                    insertStatement.IntoClause.PrependIdColumnSpec();
                }
            }

            bool includeVersionProperty = persister.IsVersioned && !insertStatement.IntoClause.IsExplicitVersionInsertion && persister.VersionPropertyInsertable;

            if (includeVersionProperty)
            {
                // We need to seed the version value as part of this bulk insert
                IVersionType versionType = persister.VersionType;
                IASTNode     versionValueNode;

                if (SessionFactoryHelper.Factory.Dialect.SupportsParametersInInsertSelect)
                {
                    versionValueNode = ASTFactory.CreateNode(PARAM, "?");
                    IParameterSpecification paramSpec = new VersionTypeSeedParameterSpecification(versionType);
                    ((ParameterNode)versionValueNode).HqlParameterSpecification = paramSpec;
                    _parameters.Insert(0, paramSpec);
                }
                else
                {
                    if (IsIntegral(versionType))
                    {
                        try
                        {
                            object seedValue = versionType.Seed(null);
                            versionValueNode = ASTFactory.CreateNode(SQL_TOKEN, seedValue.ToString());
                        }
                        catch (Exception t)
                        {
                            throw new QueryException("could not determine seed value for version on bulk insert [" + versionType + "]", t);
                        }
                    }
                    else if (IsDatabaseGeneratedTimestamp(versionType))
                    {
                        var functionName = IsUtcDatabaseGeneratedTimestamp(versionType)
                                                        ? SessionFactoryHelper.Factory.Dialect.CurrentUtcTimestampSQLFunctionName
                                                        : SessionFactoryHelper.Factory.Dialect.CurrentTimestampSQLFunctionName;
                        versionValueNode = ASTFactory.CreateNode(SQL_TOKEN, functionName);
                    }
                    else
                    {
                        throw new QueryException("cannot handle version type [" + versionType + "] on bulk inserts with dialects not supporting parameters in insert-select statements");
                    }
                }

                selectClause.InsertChild(0, versionValueNode);

                insertStatement.IntoClause.PrependVersionColumnSpec();
            }

            if (insertStatement.IntoClause.IsDiscriminated)
            {
                string   sqlValue     = insertStatement.IntoClause.Queryable.DiscriminatorSQLValue;
                IASTNode discrimValue = ASTFactory.CreateNode(SQL_TOKEN, sqlValue);
                insertStatement.SelectClause.AddChild(discrimValue);
            }
        }
Beispiel #58
0
 public abstract void Resolve(bool generateJoin, bool implicitJoin, string classAlias, IASTNode parent);
Beispiel #59
0
 public abstract void ResolveIndex(IASTNode parent);
Beispiel #60
0
        void ProcessQuery(IASTNode select, IASTNode query)
        {
            if (log.IsDebugEnabled())
            {
                log.Debug("processQuery() : {0}", query.ToStringTree());
            }

            try {
                QueryNode qn = ( QueryNode )query;

                // Was there an explicit select expression?
                bool explicitSelect = select != null && select.ChildCount > 0;

                if (!explicitSelect)
                {
                    // No explicit select expression; render the id and properties
                    // projection lists for every persister in the from clause into
                    // a single 'token node'.
                    //TODO: the only reason we need this stuff now is collection filters,
                    //      we should get rid of derived select clause completely!
                    CreateSelectClauseFromFromClause(qn);
                }
                else
                {
                    // Use the explicitly declared select expression; determine the
                    // return types indicated by each select token
                    UseSelectClause(select);
                }

                // After that, process the JOINs.
                // Invoke a delegate to do the work, as this is farily complex.
                JoinProcessor          joinProcessor = new JoinProcessor(this);
                IRestrictableStatement rs            = qn;
                joinProcessor.ProcessJoins(rs);

                // Attach any mapping-defined "ORDER BY" fragments
                foreach (FromElement fromElement in qn.FromClause.GetProjectionListTyped())
                {
                    if (fromElement.IsFetch && fromElement.QueryableCollection != null)
                    {
                        // Does the collection referenced by this FromElement
                        // specify an order-by attribute?  If so, attach it to
                        // the query's order-by
                        if (fromElement.QueryableCollection.HasOrdering)
                        {
                            string orderByFragment = fromElement
                                                     .QueryableCollection
                                                     .GetSQLOrderByString(fromElement.TableAlias);
                            qn.GetOrderByClause().AddOrderFragment(orderByFragment);
                        }
                        if (fromElement.QueryableCollection.HasManyToManyOrdering)
                        {
                            string orderByFragment = fromElement.QueryableCollection
                                                     .GetManyToManyOrderByString(fromElement.TableAlias);
                            qn.GetOrderByClause().AddOrderFragment(orderByFragment);
                        }
                    }
                }
            }
            finally
            {
                PopFromClause();
            }
        }