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...");
			}
		}
        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...");
            }
        }
        private IASTNode Expand()
        {
            var parameters  = ParameterDetector.LocateParameters(_tree, new HashSet <string>(_map.Keys));
            var nodeMapping = new Dictionary <IASTNode, IEnumerable <IASTNode> >();

            foreach (IASTNode param in parameters)
            {
                var paramName  = param.GetChild(0);
                var aliases    = _map[paramName.Text];
                var astAliases = new List <IASTNode>();

                foreach (string alias in aliases)
                {
                    IASTNode astAlias     = param.DupNode();
                    IASTNode astAliasName = paramName.DupNode();
                    astAliasName.Text = alias;
                    astAlias.AddChild(astAliasName);

                    astAliases.Add(astAlias);
                }

                nodeMapping.Add(param, astAliases);
            }

            return(DuplicateTree(_tree, nodeMapping));
        }
        /// <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);
            }
        }
		/// <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);
			}
		}
示例#6
0
 private void AddChildren(IEnumerable <HqlTreeNode> children)
 {
     foreach (var child in children)
     {
         if (child != null)
         {
             if (child is HqlDistinctHolder)
             {
                 AddChildren(child.Children);
             }
             else
             {
                 _children.Add(child);
                 _node.AddChild(child.AstNode);
             }
         }
     }
 }
示例#7
0
        public IASTNode Append(int type, String text, bool appendIfEmpty)
        {
            if (text != null && (appendIfEmpty || text.Length > 0))
            {
                return(parent.AddChild(factory.CreateNode(type, text)));
            }

            return(null);
        }
示例#8
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);
            }
        }
示例#9
0
 internal void AddChild(HqlTreeNode child)
 {
     if (child is HqlExpressionSubTreeHolder)
     {
         AddChildren(child.Children);
     }
     else
     {
         _children.Add(child);
         _node.AddChild(child.AstNode);
     }
 }
示例#10
0
        void PrepareVersioned(IASTNode updateNode, IASTNode versioned)
        {
            var        updateStatement = (UpdateStatement)updateNode;
            FromClause fromClause      = updateStatement.FromClause;

            if (versioned != null)
            {
                // Make sure that the persister is versioned
                IQueryable persister = fromClause.GetFromElement().Queryable;
                if (!persister.IsVersioned)
                {
                    throw new SemanticException("increment option specified for update of non-versioned entity");
                }

                IVersionType versionType = persister.VersionType;
                if (versionType is IUserVersionType)
                {
                    throw new SemanticException("user-defined version types not supported for increment option");
                }

                IASTNode eq = ASTFactory.CreateNode(EQ, "=");
                IASTNode versionPropertyNode = GenerateVersionPropertyNode(persister);

                eq.SetFirstChild(versionPropertyNode);

                IASTNode versionIncrementNode;
                if (typeof(DateTime).IsAssignableFrom(versionType.ReturnedClass))
                {
                    versionIncrementNode = ASTFactory.CreateNode(PARAM, "?");
                    IParameterSpecification paramSpec = new VersionTypeSeedParameterSpecification(versionType);
                    ((ParameterNode)versionIncrementNode).HqlParameterSpecification = paramSpec;
                    Parameters.Insert(0, paramSpec);
                }
                else
                {
                    // Not possible to simply re-use the versionPropertyNode here as it causes
                    // OOM errors due to circularity :(
                    versionIncrementNode = ASTFactory.CreateNode(PLUS, "+");
                    versionIncrementNode.SetFirstChild(GenerateVersionPropertyNode(persister));
                    versionIncrementNode.AddChild(ASTFactory.CreateNode(IDENT, "1"));
                }

                eq.AddChild(versionIncrementNode);

                EvaluateAssignment(eq, persister, 0);

                IASTNode setClause = updateStatement.SetClause;
                IASTNode currentFirstSetElement = setClause.GetFirstChild();
                setClause.SetFirstChild(eq);
                eq.NextSibling = currentFirstSetElement;
            }
        }
        private static IASTNode DuplicateTree(IASTNode ast, IDictionary <IASTNode, IEnumerable <IASTNode> > nodeMapping)
        {
            IASTNode thisNode = ast.DupNode();

            foreach (IASTNode child in ast)
            {
                IEnumerable <IASTNode> candidate;

                if (nodeMapping.TryGetValue(child, out candidate))
                {
                    foreach (IASTNode replacement in candidate)
                    {
                        thisNode.AddChild(replacement);
                    }
                }
                else
                {
                    thisNode.AddChild(DuplicateTree(child, nodeMapping));
                }
            }

            return(thisNode);
        }
示例#12
0
        IASTNode GenerateSyntheticDotNodeForNonQualifiedPropertyRef(IASTNode property, FromElement fromElement)
        {
            IASTNode dot = (IASTNode)adaptor.Create(DOT, "{non-qualified-property-ref}");

            // TODO : better way?!?
            ((DotNode)dot).PropertyPath = ((FromReferenceNode)property).Path;

            IdentNode syntheticAlias = (IdentNode)adaptor.Create(IDENT, "{synthetic-alias}");

            syntheticAlias.FromElement = fromElement;
            syntheticAlias.IsResolved  = true;

            dot.SetFirstChild(syntheticAlias);
            dot.AddChild(property);

            return(dot);
        }
示例#13
0
        public virtual void AddDiscriminatorWhereFragment(IRestrictableStatement statement, IQueryable persister, IDictionary <string, IFilter> enabledFilters, string alias)
        {
            string whereFragment = persister.FilterFragment(alias, enabledFilters).Trim();

            if (string.Empty.Equals(whereFragment))
            {
                return;
            }
            if (whereFragment.StartsWith("and"))
            {
                whereFragment = whereFragment.Substring(4);
            }

            // Need to parse off the column qualifiers; this is assuming (which is true as of now)
            // that this is only used from update and delete HQL statement parsing
            whereFragment = StringHelper.Replace(whereFragment, persister.GenerateFilterConditionAlias(alias) + ".", "");

            // Note: this simply constructs a "raw" SQL_TOKEN representing the
            // where fragment and injects this into the tree.  This "works";
            // however it is probably not the best long-term solution.
            //
            // At some point we probably want to apply an additional grammar to
            // properly tokenize this where fragment into constituent parts
            // focused on the operators embedded within the fragment.
            IASTNode discrimNode = Create(HqlSqlWalker.SQL_TOKEN, whereFragment);

            if (statement.WhereClause.ChildCount == 0)
            {
                statement.WhereClause.SetFirstChild(discrimNode);
            }
            else
            {
                IASTNode and = Create(HqlSqlWalker.AND, "{and}");
                IASTNode currentFirstChild = statement.WhereClause.GetFirstChild();
                and.SetFirstChild(discrimNode);
                and.AddChild(currentFirstChild);
                statement.WhereClause.SetFirstChild(and);
            }
        }
示例#14
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 [" + 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.ToString().IndexOf("?") >= 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 [" + 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);
            }
        }
示例#15
0
        public IASTNode NegateNode(IASTNode node)
        {
            // TODO - copy code from HqlParser.java
            switch (node.Type)
            {
            case OR:
                node.Type = AND;
                node.Text = "{and}";
                NegateNode(node.GetChild(0));
                NegateNode(node.GetChild(1));
                return(node);

            case AND:
                node.Type = OR;
                node.Text = "{or}";
                NegateNode(node.GetChild(0));
                NegateNode(node.GetChild(1));
                return(node);

            case EQ:
                node.Type = NE;
                node.Text = "{not}" + node.Text;
                return(node);                           // (NOT (EQ a b) ) => (NE a b)

            case NE:
                node.Type = EQ;
                node.Text = "{not}" + node.Text;
                return(node);                           // (NOT (NE a b) ) => (EQ a b)

            case GT:
                node.Type = LE;
                node.Text = "{not}" + node.Text;
                return(node);                           // (NOT (GT a b) ) => (LE a b)

            case LT:
                node.Type = GE;
                node.Text = "{not}" + node.Text;
                return(node);                           // (NOT (LT a b) ) => (GE a b)

            case GE:
                node.Type = LT;
                node.Text = "{not}" + node.Text;
                return(node);                           // (NOT (GE a b) ) => (LT a b)

            case LE:
                node.Type = GT;
                node.Text = "{not}" + node.Text;
                return(node);                           // (NOT (LE a b) ) => (GT a b)

            case LIKE:
                node.Type = NOT_LIKE;
                node.Text = "{not}" + node.Text;
                return(node);                           // (NOT (LIKE a b) ) => (NOT_LIKE a b)

            case NOT_LIKE:
                node.Type = LIKE;
                node.Text = "{not}" + node.Text;
                return(node);                           // (NOT (NOT_LIKE a b) ) => (LIKE a b)

            case IN:
                node.Type = NOT_IN;
                node.Text = "{not}" + node.Text;
                return(node);

            case NOT_IN:
                node.Type = IN;
                node.Text = "{not}" + node.Text;
                return(node);

            case IS_NULL:
                node.Type = IS_NOT_NULL;
                node.Text = "{not}" + node.Text;
                return(node);                           // (NOT (IS_NULL a b) ) => (IS_NOT_NULL a b)

            case IS_NOT_NULL:
                node.Type = IS_NULL;
                node.Text = "{not}" + node.Text;
                return(node);                           // (NOT (IS_NOT_NULL a b) ) => (IS_NULL a b)

            case BETWEEN:
                node.Type = NOT_BETWEEN;
                node.Text = "{not}" + node.Text;
                return(node);                           // (NOT (BETWEEN a b) ) => (NOT_BETWEEN a b)

            case NOT_BETWEEN:
                node.Type = BETWEEN;
                node.Text = "{not}" + node.Text;
                return(node);                           // (NOT (NOT_BETWEEN a b) ) => (BETWEEN a b)

            /* This can never happen because this rule will always eliminate the child NOT.
             *                      case NOT:
             *                              return x.getFirstChild();			// (NOT (NOT x) ) => (x)
             */
            default:
                IASTNode not = (IASTNode)TreeAdaptor.Create(NOT, "not");
                not.AddChild(node);
                return(not);
            }
        }
示例#16
0
		void PrepareFromClauseInputTree(IASTNode fromClauseInput, ITreeNodeStream input)
		{
			if (IsFilter())
			{
				// Handle collection-fiter compilation.
				// IMPORTANT NOTE: This is modifying the INPUT (HQL) tree, not the output tree!
				IQueryableCollection persister = _sessionFactoryHelper.GetCollectionPersister(_collectionFilterRole);
				IType collectionElementType = persister.ElementType;
				if (!collectionElementType.IsEntityType)
				{
					throw new QueryException("collection of values in filter: this");
				}

				string collectionElementEntityName = persister.ElementPersister.EntityName;

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

				fromClauseInput.AddChild(fromElement);
				fromClauseInput.AddChild(alias);

				// Show the modified AST.
				if (log.IsDebugEnabled)
				{
					log.Debug("prepareFromClauseInputTree() : Filter - Added 'this' as a from element...");
				}
				
				// Create a parameter specification for the collection filter...
				IType collectionFilterKeyType = _sessionFactoryHelper.RequireQueryableCollection(_collectionFilterRole).KeyType;
				ParameterNode collectionFilterKeyParameter = (ParameterNode)adaptor.Create(PARAM, "?");
				CollectionFilterKeyParameterSpecification collectionFilterKeyParameterSpec = new CollectionFilterKeyParameterSpecification(
						_collectionFilterRole, collectionFilterKeyType, _positionalParameterCount++
				);
				collectionFilterKeyParameter.HqlParameterSpecification = collectionFilterKeyParameterSpec;
				_parameters.Add(collectionFilterKeyParameterSpec);
			}
		}