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); } }
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)); } }
/// <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 IASTNode ProcessEqualityExpression(object o) { IASTNode x = o as IASTNode; if (x == null) { log.Warn("processEqualityExpression() : No expression to process!"); return(null); } int type = x.Type; if (type == EQ || type == NE) { bool negated = type == NE; if (x.ChildCount == 2) { IASTNode a = x.GetChild(0); IASTNode b = x.GetChild(1); // (EQ NULL b) => (IS_NULL b) if (a.Type == NULL && b.Type != NULL) { return(CreateIsNullParent(b, negated)); } // (EQ a NULL) => (IS_NULL a) if (b.Type == NULL && a.Type != NULL) { return(CreateIsNullParent(a, negated)); } if (b.Type == EMPTY) { return(ProcessIsEmpty(a, negated)); } } } return(x); }
private void CreateSelectClauseFromFromClause(IASTNode qn) { // TODO - check this. Not *exactly* the same logic as the Java original qn.InsertChild(0, (IASTNode)adaptor.Create(SELECT_CLAUSE, "{derived select clause}")); _selectClause = ( SelectClause )qn.GetChild(0); _selectClause.InitializeDerivedSelectClause(_currentFromClause); if (log.IsDebugEnabled()) { log.Debug("Derived SELECT clause created."); } }
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> /// 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 string[] ExtractMutationTexts(IASTNode operand, int count) { if (operand is ParameterNode) { string[] rtn = new string[count]; for (int i = 0; i < count; i++) { rtn[i] = "?"; } return(rtn); } else if (operand.Type == HqlSqlWalker.VECTOR_EXPR) { string[] rtn = new string[operand.ChildCount]; for (int x = 0; x < operand.ChildCount; x++) { rtn[x++] = operand.GetChild(x).Text; } return(rtn); } else if (operand is SqlNode) { string nodeText = operand.Text; if (nodeText.StartsWith("(")) { nodeText = nodeText.Substring(1); } if (nodeText.EndsWith(")")) { nodeText = nodeText.Substring(0, nodeText.Length - 1); } String[] splits = StringHelper.Split(", ", nodeText); if (count != splits.Length) { throw new HibernateException("SqlNode's text did not reference expected number of columns"); } return(splits); } else { throw new HibernateException("dont know how to extract row value elements from node : " + operand); } }
/// <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); }
public virtual void Resolve(bool inSelect) { // Get the function name node. IASTNode name = GetChild(0); InitializeMethodNode(name, inSelect); IASTNode exprList = name.NextSibling; // If the expression list has exactly one expression, and the type of the expression is a collection // then this might be a collection function, such as index(c) or size(c). if ((exprList != null && exprList.ChildCount == 1) && IsCollectionPropertyMethod) { CollectionProperty(exprList.GetChild(0), name); } else { DialectFunction(exprList); } }
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; } }
private static string[] ExtractMutationTexts(IASTNode operand, int count) { if (operand is ParameterNode) { return(Enumerable.Repeat("?", count).ToArray()); } if (operand is SqlNode) { string nodeText = operand.Text; if (nodeText.StartsWith("(")) { nodeText = nodeText.Substring(1); } if (nodeText.EndsWith(")")) { nodeText = nodeText.Substring(0, nodeText.Length - 1); } string[] splits = nodeText.Split(new[] { ", " }, StringSplitOptions.None); if (count != splits.Length) { throw new HibernateException("SqlNode's text did not reference expected number of columns"); } return(splits); } if (operand.Type == HqlSqlWalker.VECTOR_EXPR) { var rtn = new string[operand.ChildCount]; for (int x = 0; x < operand.ChildCount; x++) { rtn[x] = operand.GetChild(x).Text; } return(rtn); } throw new HibernateException("dont know how to extract row value elements from node : " + operand); }
public override void Initialize() { IASTNode lhs = LeftHandOperand; if (lhs == null) { throw new SemanticException("left-hand operand of in operator was null"); } IASTNode inList = InList; if (inList == null) { throw new SemanticException("right-hand operand of in operator was null"); } // for expected parameter type injection, we expect that the lhs represents // some form of property ref and that the children of the in-list represent // one-or-more params. var lhsNode = lhs as SqlNode; if (lhsNode != null) { IType lhsType = lhsNode.DataType; IASTNode inListChild = inList.GetChild(0); while (inListChild != null) { var expectedTypeAwareNode = inListChild as IExpectedTypeAwareNode; if (expectedTypeAwareNode != null) { expectedTypeAwareNode.ExpectedType = lhsType; } inListChild = inListChild.NextSibling; } } }
private void HandleWithFragment(FromElement fromElement, IASTNode hqlWithNode) { try { ITreeNodeStream old = input; input = new CommonTreeNodeStream(adaptor, hqlWithNode); IASTNode hqlSqlWithNode = (IASTNode)withClause().Tree; input = old; if (log.IsDebugEnabled()) { log.Debug("handleWithFragment() : {0}", _printer.ShowAsString(hqlSqlWithNode, "-- with clause --")); } WithClauseVisitor visitor = new WithClauseVisitor(fromElement); NodeTraverser traverser = new NodeTraverser(visitor); traverser.TraverseDepthFirst(hqlSqlWithNode); FromElement referencedFromElement = visitor.GetReferencedFromElement(); if (referencedFromElement != fromElement) { throw new InvalidWithClauseException( "with-clause expressions did not reference from-clause element to which the with-clause was associated"); } SqlGenerator sql = new SqlGenerator(_sessionFactoryHelper.Factory, new CommonTreeNodeStream(adaptor, hqlSqlWithNode.GetChild(0))); sql.whereExpr(); var withClauseFragment = new SqlString("(", sql.GetSQL(), ")"); fromElement.SetWithClauseFragment(visitor.GetJoinAlias(), withClauseFragment); } catch (SemanticException) { throw; } catch (InvalidWithClauseException) { throw; } catch (Exception e) { throw new SemanticException(e.Message, e); } }
private void CreateSelectClauseFromFromClause(IASTNode qn) { // TODO - check this. Not *exactly* the same logic as the Java original qn.InsertChild(0, (IASTNode)adaptor.Create(SELECT_CLAUSE, "{derived select clause}")); _selectClause = ( SelectClause ) qn.GetChild(0); _selectClause.InitializeDerivedSelectClause( _currentFromClause ); if ( log.IsDebugEnabled ) { log.Debug( "Derived SELECT clause created." ); } }
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); } }
private void DialectFunction(IASTNode exprList) { _function = SessionFactoryHelper.FindSQLFunction(_methodName); if (_function != null) { IASTNode child = null; if (exprList != null) { child = _methodName == "iif" ? exprList.GetChild(1) : exprList.GetChild(0); } DataType = SessionFactoryHelper.FindFunctionReturnType(_methodName, child); } //TODO: /*else { methodName = (String) getWalker().getTokenReplacements().get( methodName ); }*/ }
/// <summary> /// Finds the first node of the specified type in the chain of children. /// </summary> /// <param name="parent">The parent</param> /// <param name="type">The type to find.</param> /// <returns>The first node of the specified type, or null if not found.</returns> public static IASTNode FindTypeInChildren(IASTNode parent, int type) { for (int i = 0; i < parent.ChildCount; i++) { var child = parent.GetChild(i); if (child.Type == type) { return child; } } return null; }
public IASTNode ProcessMemberOf(IToken n, IASTNode p, IASTNode root) { ASTFactory factory = new ASTFactory(adaptor); return factory.CreateNode(n == null ? IN : NOT_IN, n == null ? "in" : "not in", root.IsNil && root.ChildCount == 1 ? root.GetChild(0) : root, factory.CreateNode(IN_LIST, "inList", CreateSubquery(p))); }
/** * Mutate the subtree relating to a row-value-constructor to instead use * a series of ANDed predicates. This allows multi-column type comparisons * and explicit row-value-constructor syntax even on databases which do * not support row-value-constructor. * <p/> * For example, here we'd mutate "... where (col1, col2) = ('val1', 'val2) ..." to * "... where col1 = 'val1' and col2 = 'val2' ..." * * @param valueElements The number of elements in the row value constructor list. */ private void MutateRowValueConstructorSyntax(int valueElements) { // mutation depends on the types of nodes invloved... int comparisonType = Type; string comparisonText = Text; Type = HqlSqlWalker.AND; Text = "AND"; String[] lhsElementTexts = ExtractMutationTexts(LeftHandOperand, valueElements); String[] rhsElementTexts = ExtractMutationTexts(RightHandOperand, valueElements); IParameterSpecification lhsEmbeddedCompositeParameterSpecification = LeftHandOperand == null || (!(LeftHandOperand is ParameterNode)) ? null : (( ParameterNode )LeftHandOperand).HqlParameterSpecification; IParameterSpecification rhsEmbeddedCompositeParameterSpecification = RightHandOperand == null || (!(RightHandOperand is ParameterNode)) ? null : (( ParameterNode )RightHandOperand).HqlParameterSpecification; IASTNode container = this; for (int i = valueElements - 1; i > 0; i--) { if (i == 1) { container.ClearChildren(); container.AddChildren( ASTFactory.CreateNode( comparisonType, comparisonText, ASTFactory.CreateNode(HqlSqlWalker.SQL_TOKEN, lhsElementTexts[0]), ASTFactory.CreateNode(HqlSqlWalker.SQL_TOKEN, rhsElementTexts[0]) ), ASTFactory.CreateNode( comparisonType, comparisonText, ASTFactory.CreateNode(HqlSqlWalker.SQL_TOKEN, lhsElementTexts[1]), ASTFactory.CreateNode(HqlSqlWalker.SQL_TOKEN, rhsElementTexts[1]) )); // "pass along" our initial embedded parameter node(s) to the first generated // sql fragment so that it can be handled later for parameter binding... SqlFragment fragment = ( SqlFragment )container.GetChild(0).GetChild(0); if (lhsEmbeddedCompositeParameterSpecification != null) { fragment.AddEmbeddedParameter(lhsEmbeddedCompositeParameterSpecification); } if (rhsEmbeddedCompositeParameterSpecification != null) { fragment.AddEmbeddedParameter(rhsEmbeddedCompositeParameterSpecification); } } else { container.ClearChildren(); container.AddChildren( ASTFactory.CreateNode(HqlSqlWalker.AND, "AND"), ASTFactory.CreateNode( comparisonType, comparisonText, ASTFactory.CreateNode(HqlSqlWalker.SQL_TOKEN, lhsElementTexts[i]), ASTFactory.CreateNode(HqlSqlWalker.SQL_TOKEN, rhsElementTexts[i]) )); container = container.GetChild(0); } } }
public void Visit(IASTNode node) { if ((node.Type == HqlSqlWalker.PARAM) || (node.Type == HqlSqlWalker.COLON)) { string name = node.GetChild(0).Text; if (_parameterNames.Contains(name)) { _nodes.Add(node); } } }
/// <summary> /// Finds the first node of the specified type in the chain of children. /// </summary> /// <param name="parent">The parent</param> /// <param name="type">The type to find.</param> /// <returns>The first node of the specified type, or null if not found.</returns> public static IASTNode FindTypeInChildren(IASTNode parent, int type) { for (int i = 0; i < parent.ChildCount; i++) { if (parent.GetChild(i).Type == type) { return parent.GetChild(i); } } return null; }
private void HandleWithFragment(FromElement fromElement, IASTNode hqlWithNode) { try { ITreeNodeStream old = input; input = new CommonTreeNodeStream(adaptor, hqlWithNode); IASTNode hqlSqlWithNode = (IASTNode)withClause().Tree; input = old; if (log.IsDebugEnabled()) { log.Debug("handleWithFragment() : {0}", _printer.ShowAsString(hqlSqlWithNode, "-- with clause --")); } WithClauseVisitor visitor = new WithClauseVisitor(fromElement); NodeTraverser traverser = new NodeTraverser(visitor); traverser.TraverseDepthFirst(hqlSqlWithNode); SqlGenerator sql = new SqlGenerator(_sessionFactoryHelper.Factory, new CommonTreeNodeStream(adaptor, hqlSqlWithNode.GetChild(0))); sql.whereExpr(); fromElement.WithClauseFragment = new SqlString("(", sql.GetSQL(), ")"); } catch (SemanticException) { throw; } catch (InvalidWithClauseException) { throw; } catch (Exception e) { throw new SemanticException(e.Message, e); } }
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; } }
private static string[] ExtractMutationTexts(IASTNode operand, int count) { if ( operand is ParameterNode ) { string[] rtn = new string[count]; for ( int i = 0; i < count; i++ ) { rtn[i] = "?"; } return rtn; } else if ( operand.Type == HqlSqlWalker.VECTOR_EXPR ) { string[] rtn = new string[operand.ChildCount]; for (int x = 0; x < operand.ChildCount; x++) { rtn[ x++ ] = operand.GetChild(x).Text; } return rtn; } else if ( operand is SqlNode ) { string nodeText = operand.Text; if ( nodeText.StartsWith( "(" ) ) { nodeText = nodeText.Substring( 1 ); } if ( nodeText.EndsWith( ")" ) ) { nodeText = nodeText.Substring( 0, nodeText.Length - 1 ); } String[] splits = StringHelper.Split( ", ", nodeText ); if ( count != splits.Length ) { throw new HibernateException( "SqlNode's text did not reference expected number of columns" ); } return splits; } else { throw new HibernateException( "dont know how to extract row value elements from node : " + operand ); } }
public override void Initialize() { IASTNode lhs = LeftHandOperand; if (lhs == null) { throw new SemanticException("left-hand operand of in operator was null"); } IASTNode inList = InList; if (inList == null) { throw new SemanticException("right-hand operand of in operator was null"); } // for expected parameter type injection, we expect that the lhs represents // some form of property ref and that the children of the in-list represent // one-or-more params. var lhsNode = lhs as SqlNode; IType lhsType = null; if (lhsNode != null) { lhsType = lhsNode.DataType; IASTNode inListChild = inList.GetChild(0); while (inListChild != null) { var expectedTypeAwareNode = inListChild as IExpectedTypeAwareNode; if (expectedTypeAwareNode != null) { expectedTypeAwareNode.ExpectedType = lhsType; } inListChild = inListChild.NextSibling; } } var sessionFactory = SessionFactoryHelper.Factory; if (sessionFactory.Dialect.SupportsRowValueConstructorSyntaxInInList) { return; } lhsType = lhsType ?? ExtractDataType(lhs); if (lhsType == null) { return; } var rhsNode = inList.GetFirstChild(); if (rhsNode == null || !IsNodeAcceptable(rhsNode)) { return; } var lhsColumnSpan = lhsType.GetColumnSpan(sessionFactory); var rhsColumnSpan = rhsNode.Type == HqlSqlWalker.VECTOR_EXPR ? rhsNode.ChildCount : ExtractDataType(rhsNode)?.GetColumnSpan(sessionFactory) ?? 0; if (lhsColumnSpan > 1 && rhsColumnSpan > 1) { MutateRowValueConstructorSyntaxInInListSyntax(lhs, lhsColumnSpan, rhsNode, rhsColumnSpan); } }
private static string[] ExtractMutationTexts(IASTNode operand, int count) { if ( operand is ParameterNode ) { return Enumerable.Repeat("?", count).ToArray(); } if (operand is SqlNode) { string nodeText = operand.Text; if (nodeText.StartsWith("(")) { nodeText = nodeText.Substring(1); } if (nodeText.EndsWith(")")) { nodeText = nodeText.Substring(0, nodeText.Length - 1); } string[] splits = nodeText.Split(new[] { ", " }, StringSplitOptions.None); if (count != splits.Length) { throw new HibernateException("SqlNode's text did not reference expected number of columns"); } return splits; } if (operand.Type == HqlSqlWalker.VECTOR_EXPR) { var rtn = new string[operand.ChildCount]; for (int x = 0; x < operand.ChildCount; x++) { rtn[ x ] = operand.GetChild(x).Text; } return rtn; } throw new HibernateException( "dont know how to extract row value elements from node : " + operand ); }