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); } }
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); } } } }
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); }
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); } }
internal void AddChild(HqlTreeNode child) { if (child is HqlExpressionSubTreeHolder) { AddChildren(child.Children); } else { _children.Add(child); _node.AddChild(child.AstNode); } }
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); }
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); }
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); } }
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); } }
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); } }
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); } }