Наследование: NHibernate.Hql.Ast.ANTLR.Tree.FromReferenceNode, ISelectExpression
Пример #1
0
		public void LookupConstant(DotNode node)
		{
			string text = ASTUtil.GetPathText(node);
			IQueryable persister = _walker.SessionFactoryHelper.FindQueryableUsingImports(text);
			if (persister != null)
			{
				// the name of an entity class
				string discrim = persister.DiscriminatorSQLValue;
				node.DataType = persister.DiscriminatorType;

				if (InFragment.Null == discrim || InFragment.NotNull == discrim)
				{
					throw new InvalidPathException("subclass test not allowed for null or not null discriminator: '" + text + "'");
				}
				else
				{
					SetSQLValue(node, text, discrim); //the class discriminator value
				}
			}
			else
			{
				Object value = ReflectHelper.GetConstantValue(text);
				if (value == null)
				{
					throw new InvalidPathException("Invalid path: '" + text + "'");
				}
				else
				{
					SetConstantValue(node, text, value);
				}
			}
		}
Пример #2
0
        private bool ResolveAsNakedComponentPropertyRefLhs(DotNode parent)
        {
            FromElement fromElement = LocateSingleFromElement();

            if (fromElement == null)
            {
                return(false);
            }

            IType componentType = GetNakedPropertyType(fromElement);

            if (componentType == null)
            {
                throw new QueryException("Unable to resolve path [" + parent.Path + "], unexpected token [" + OriginalText + "]");
            }
            if (!componentType.IsComponentType)
            {
                throw new QueryException("Property '" + OriginalText + "' is not a component.  Use an alias to reference associations or collections.");
            }

            IType  propertyType;              // used to set the type of the parent dot node
            string propertyPath = Text + "." + NextSibling.Text;

            try
            {
                // check to see if our "propPath" actually
                // represents a property on the persister
                propertyType = fromElement.GetPropertyType(Text, propertyPath);
            }
            catch (Exception)
            {
                // assume we do *not* refer to a property on the given persister
                return(false);
            }

            FromElement         = fromElement;
            parent.PropertyPath = propertyPath;
            parent.DataType     = propertyType;

            return(true);
        }
Пример #3
0
        private void DereferenceEntityIdentifier(string propertyName, DotNode dotParent)
        {
            // special shortcut for id properties, skip the join!
            // this must only occur at the _end_ of a path expression
            if (Log.IsDebugEnabled)
            {
                Log.Debug("dereferenceShortcut() : property " +
                          propertyName + " in " + FromElement.ClassName +
                          " does not require a join.");
            }

            InitText();
            SetPropertyNameAndPath(dotParent);             // Set the unresolved path in this node and the parent.
            // Set the text for the parent.
            if (dotParent != null)
            {
                dotParent._dereferenceType = DerefIdentifier;
                dotParent.Text             = Text;
                dotParent._columns         = GetColumns();
            }
        }
Пример #4
0
        private void SetPropertyNameAndPath(IASTNode parent)
        {
            if (IsDotNode(parent))
            {
                DotNode dotNode = (DotNode)parent;

                IASTNode rhs = dotNode.GetChild(1);
                _propertyName         = rhs.Text;
                _propertyPath         = _propertyPath + "." + _propertyName;         // Append the new property name onto the unresolved path.
                dotNode._propertyPath = _propertyPath;
                if (Log.IsDebugEnabled)
                {
                    Log.Debug("Unresolved property path is now '" + dotNode._propertyPath + "'");
                }
            }
            else
            {
                if (Log.IsDebugEnabled)
                {
                    Log.Debug("terminal propertyPath = [" + _propertyPath + "]");
                }
            }
        }
Пример #5
0
		private void SetConstantValue(DotNode node, string text, object value)
		{
			if (log.IsDebugEnabled)
			{
				log.Debug("setConstantValue() " + text + " -> " + value + " " + value.GetType().Name);
			}

			node.ClearChildren();	// Chop off the rest of the tree.

			if (value is string)
			{
				node.Type = HqlSqlWalker.QUOTED_String;
			}
			else if (value is char)
			{
				node.Type = HqlSqlWalker.QUOTED_String;
			}
			else if (value is byte)
			{
				node.Type = HqlSqlWalker.NUM_INT;
			}
			else if (value is short)
			{
				node.Type = HqlSqlWalker.NUM_INT;
			}
			else if (value is int)
			{
				node.Type = HqlSqlWalker.NUM_INT;
			}
			else if (value is long)
			{
				node.Type = HqlSqlWalker.NUM_LONG;
			}
			else if (value is double)
			{
				node.Type = HqlSqlWalker.NUM_DOUBLE;
			}
			else if (value is decimal)
			{
				node.Type = HqlSqlWalker.NUM_DECIMAL;
			}
			else if (value is float)
			{
				node.Type = HqlSqlWalker.NUM_FLOAT;
			}
			else
			{
				node.Type = HqlSqlWalker.CONSTANT;
			}

			IType type;
			try
			{
				type = TypeFactory.HeuristicType(value.GetType().Name);
			}
			catch (MappingException me)
			{
				throw new QueryException(me);
			}

			if (type == null)
			{
				throw new QueryException(LiteralProcessor.ErrorCannotDetermineType + node.Text);
			}
			try
			{
				ILiteralType literalType = (ILiteralType)type;
				NHibernate.Dialect.Dialect dialect = _walker.SessionFactoryHelper.Factory.Dialect;
				node.Text = literalType.ObjectToSQLString(value, dialect);
			}
			catch (Exception e)
			{
				throw new QueryException(LiteralProcessor.ErrorCannotFormatLiteral + node.Text, e);
			}

			node.DataType = type;
			node.SetResolvedConstant(text);
		}
Пример #6
0
		private static void SetSQLValue(DotNode node, string text, string value)
		{
			if (log.IsDebugEnabled)
			{
				log.Debug("setSQLValue() " + text + " -> " + value);
			}
			node.ClearChildren(); // Chop off the rest of the tree.
			node.Type = HqlSqlWalker.SQL_TOKEN;
			node.Text = value;
			node.SetResolvedConstant(text);
		}
Пример #7
0
        private void DereferenceEntity(EntityType entityType, bool implicitJoin, string classAlias, bool generateJoin, IASTNode parent)
        {
            CheckForCorrelatedSubquery("dereferenceEntity");

            // three general cases we check here as to whether to render a physical SQL join:
            // 1) is our parent a DotNode as well?  If so, our property reference is
            //      being further de-referenced...
            // 2) is this a DML statement
            // 3) we were asked to generate any needed joins (generateJoins==true) *OR*
            //		we are currently processing a select or from clause
            // (an additional check is the REGRESSION_STYLE_JOIN_SUPPRESSION check solely intended for the test suite)
            //
            // The REGRESSION_STYLE_JOIN_SUPPRESSION is an additional check
            // intended solely for use within the test suite.  This forces the
            // implicit join resolution to behave more like the classic parser.
            // The underlying issue is that classic translator is simply wrong
            // about its decisions on whether or not to render an implicit join
            // into a physical SQL join in a lot of cases.  The piece it generally
            // tends to miss is that INNER joins effect the results by further
            // restricting the data set!  A particular manifestation of this is
            // the fact that the classic translator will skip the physical join
            // for ToOne implicit joins *if the query is shallow*; the result
            // being that Query.list() and Query.iterate() could return
            // different number of results!

            DotNode parentAsDotNode = null;
            string  property        = _propertyName;
            bool    joinIsNeeded;

            if (IsDotNode(parent))
            {
                // our parent is another dot node, meaning we are being further dereferenced.
                // thus we need to generate a join unless the parent refers to the associated
                // entity's PK (because 'our' table would know the FK).
                parentAsDotNode = ( DotNode )parent;
                property        = parentAsDotNode._propertyName;
                joinIsNeeded    = generateJoin && !IsReferenceToPrimaryKey(parentAsDotNode._propertyName, entityType);
            }
            else if (!Walker.IsSelectStatement)
            {
                // in non-select queries, the only time we should need to join is if we are in a subquery from clause
                joinIsNeeded = Walker.CurrentStatementType == HqlSqlWalker.SELECT && Walker.IsInFrom;
            }
            else if (REGRESSION_STYLE_JOIN_SUPPRESSION)
            {
                // this is the regression style determination which matches the logic of the classic translator
                joinIsNeeded = generateJoin && (!Walker.IsInSelect || !Walker.IsShallowQuery);
            }
            else
            {
                joinIsNeeded = generateJoin || (Walker.IsInSelect || Walker.IsInFrom);
            }

            if (joinIsNeeded)
            {
                DereferenceEntityJoin(classAlias, entityType, implicitJoin, parent);
            }
            else
            {
                DereferenceEntityIdentifier(property, parentAsDotNode);
            }
        }
		public override object Create(IToken payload)
		{
			if (payload == null)
			{
				return base.Create(payload);
			}

			object ret;

			switch (payload.Type)
			{
				case HqlSqlWalker.SELECT:
				case HqlSqlWalker.QUERY:
					ret = new QueryNode(payload);
					break;
				case HqlSqlWalker.UPDATE:
					ret = new UpdateStatement(payload);
					break;
				case HqlSqlWalker.DELETE:
					ret = new DeleteStatement(payload);
					break;
				case HqlSqlWalker.INSERT:
					ret = new InsertStatement(payload);
					break;
				case HqlSqlWalker.INTO:
					ret = new IntoClause(payload);
					break;
				case HqlSqlWalker.FROM:
					ret = new FromClause(payload);
					break;
				case HqlSqlWalker.FROM_FRAGMENT:
					ret = new FromElement(payload);
					break;
				case HqlSqlWalker.IMPLIED_FROM:
					ret = new ImpliedFromElement(payload);
					break;
				case HqlSqlWalker.DOT:
					ret = new DotNode(payload);
					break;
				case HqlSqlWalker.INDEX_OP:
					ret = new IndexNode(payload);
					break;
					// Alias references and identifiers use the same node class.
				case HqlSqlWalker.ALIAS_REF:
				case HqlSqlWalker.IDENT:
					ret = new IdentNode(payload);
					break;
				case HqlSqlWalker.SQL_TOKEN:
					ret = new SqlFragment(payload);
					break;
				case HqlSqlWalker.METHOD_CALL:
					ret = new MethodNode(payload);
					break;
				case HqlSqlWalker.ELEMENTS:
				case HqlSqlWalker.INDICES:
					ret = new CollectionFunction(payload);
					break;
				case HqlSqlWalker.SELECT_CLAUSE:
					ret = new SelectClause(payload);
					break;
				case HqlSqlWalker.SELECT_EXPR:
					ret = new SelectExpressionImpl(payload);
					break;
				case HqlSqlWalker.AGGREGATE:
					ret = new AggregateNode(payload);
					break;
				case HqlSqlWalker.COUNT:
					ret = new CountNode(payload);
					break;
				case HqlSqlWalker.CONSTRUCTOR:
					ret = new ConstructorNode(payload);
					break;
				case HqlSqlWalker.NUM_INT:
				case HqlSqlWalker.NUM_FLOAT:
				case HqlSqlWalker.NUM_LONG:
				case HqlSqlWalker.NUM_DOUBLE:
                case HqlSqlWalker.NUM_DECIMAL:
                case HqlSqlWalker.QUOTED_String:
					ret = new LiteralNode(payload);
					break;
				case HqlSqlWalker.TRUE:
				case HqlSqlWalker.FALSE:
					ret = new BooleanLiteralNode(payload);
					break;
				case HqlSqlWalker.JAVA_CONSTANT:
					ret = new JavaConstantNode(payload);
					break;
				case HqlSqlWalker.ORDER:
					ret = new OrderByClause(payload);
					break;
				case HqlSqlWalker.PLUS:
				case HqlSqlWalker.MINUS:
				case HqlSqlWalker.STAR:
				case HqlSqlWalker.DIV:
				case HqlSqlWalker.BAND:
				case HqlSqlWalker.BOR:
				case HqlSqlWalker.BXOR:
					ret = new BinaryArithmeticOperatorNode(payload);
					break;
				case HqlSqlWalker.UNARY_MINUS:
				case HqlSqlWalker.UNARY_PLUS:
				case HqlSqlWalker.BNOT:
					ret = new UnaryArithmeticNode(payload);
					break;
				case HqlSqlWalker.CASE2:
					ret = new Case2Node(payload);
					break;
				case HqlSqlWalker.CASE:
					ret = new CaseNode(payload);
					break;
				case HqlSqlWalker.PARAM:
				case HqlSqlWalker.NAMED_PARAM:
					ret = new ParameterNode(payload);
					break;
				case HqlSqlWalker.EQ:
				case HqlSqlWalker.NE:
				case HqlSqlWalker.LT:
				case HqlSqlWalker.GT:
				case HqlSqlWalker.LE:
				case HqlSqlWalker.GE:
				case HqlSqlWalker.LIKE:
				case HqlSqlWalker.NOT_LIKE:
					ret = new BinaryLogicOperatorNode(payload);
					break;
				case HqlSqlWalker.IN:
				case HqlSqlWalker.NOT_IN:
					ret = new InLogicOperatorNode(payload);
					break;
				case HqlSqlWalker.BETWEEN:
				case HqlSqlWalker.NOT_BETWEEN:
					ret = new BetweenOperatorNode(payload);
					break;
				case HqlSqlWalker.IS_NULL:
					ret = new IsNullLogicOperatorNode(payload);
					break;
				case HqlSqlWalker.IS_NOT_NULL:
					ret = new IsNotNullLogicOperatorNode(payload);
					break;
				case HqlSqlWalker.EXISTS:
					ret = new UnaryLogicOperatorNode(payload);
					break;
				default:
					ret = new SqlNode(payload);
					break;
			}

			Initialise(ret);
			return ret;
		}
Пример #9
0
		private void DereferenceEntityIdentifier(string propertyName, DotNode dotParent)
		{
			// special shortcut for id properties, skip the join!
			// this must only occur at the _end_ of a path expression
			if (Log.IsDebugEnabled)
			{
				Log.Debug("dereferenceShortcut() : property " +
					propertyName + " in " + FromElement.ClassName +
					" does not require a join.");
			}

			InitText();
			SetPropertyNameAndPath(dotParent); // Set the unresolved path in this node and the parent.
			// Set the text for the parent.
			if (dotParent != null)
			{
				dotParent._dereferenceType = DerefIdentifier;
				dotParent.Text = Text;
				dotParent._columns = GetColumns();
			}
		}
Пример #10
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...
                    }
                }
            }
        }
        public override object Create(IToken payload)
        {
            if (payload == null)
            {
                return(base.Create(payload));
            }

            object ret;

            switch (payload.Type)
            {
            case HqlSqlWalker.SELECT:
            case HqlSqlWalker.QUERY:
                ret = new QueryNode(payload);
                break;

            case HqlSqlWalker.UPDATE:
                ret = new UpdateStatement(payload);
                break;

            case HqlSqlWalker.DELETE:
                ret = new DeleteStatement(payload);
                break;

            case HqlSqlWalker.INSERT:
                ret = new InsertStatement(payload);
                break;

            case HqlSqlWalker.INTO:
                ret = new IntoClause(payload);
                break;

            case HqlSqlWalker.FROM:
                ret = new FromClause(payload);
                break;

            case HqlSqlWalker.FROM_FRAGMENT:
                ret = new FromElement(payload);
                break;

            case HqlSqlWalker.IMPLIED_FROM:
                ret = new ImpliedFromElement(payload);
                break;

            case HqlSqlWalker.DOT:
                ret = new DotNode(payload);
                break;

            case HqlSqlWalker.INDEX_OP:
                ret = new IndexNode(payload);
                break;

            // Alias references and identifiers use the same node class.
            case HqlSqlWalker.ALIAS_REF:
            case HqlSqlWalker.IDENT:
                ret = new IdentNode(payload);
                break;

            case HqlSqlWalker.SQL_TOKEN:
                ret = new SqlFragment(payload);
                break;

            case HqlSqlWalker.METHOD_CALL:
                ret = new MethodNode(payload);
                break;

            case HqlSqlWalker.ELEMENTS:
            case HqlSqlWalker.INDICES:
                ret = new CollectionFunction(payload);
                break;

            case HqlSqlWalker.SELECT_CLAUSE:
                ret = new SelectClause(payload);
                break;

            case HqlSqlWalker.SELECT_EXPR:
                ret = new SelectExpressionImpl(payload);
                break;

            case HqlSqlWalker.AGGREGATE:
                ret = new AggregateNode(payload);
                break;

            case HqlSqlWalker.COUNT:
                ret = new CountNode(payload);
                break;

            case HqlSqlWalker.CONSTRUCTOR:
                ret = new ConstructorNode(payload);
                break;

            case HqlSqlWalker.NUM_INT:
            case HqlSqlWalker.NUM_FLOAT:
            case HqlSqlWalker.NUM_LONG:
            case HqlSqlWalker.NUM_DOUBLE:
            case HqlSqlWalker.QUOTED_String:
                ret = new LiteralNode(payload);
                break;

            case HqlSqlWalker.TRUE:
            case HqlSqlWalker.FALSE:
                ret = new BooleanLiteralNode(payload);
                break;

            case HqlSqlWalker.JAVA_CONSTANT:
                ret = new JavaConstantNode(payload);
                break;

            case HqlSqlWalker.ORDER:
                ret = new OrderByClause(payload);
                break;

            case HqlSqlWalker.PLUS:
            case HqlSqlWalker.MINUS:
            case HqlSqlWalker.STAR:
            case HqlSqlWalker.DIV:
            case HqlSqlWalker.BAND:
            case HqlSqlWalker.BOR:
            case HqlSqlWalker.BXOR:
                ret = new BinaryArithmeticOperatorNode(payload);
                break;

            case HqlSqlWalker.UNARY_MINUS:
            case HqlSqlWalker.UNARY_PLUS:
            case HqlSqlWalker.BNOT:
                ret = new UnaryArithmeticNode(payload);
                break;

            case HqlSqlWalker.CASE2:
                ret = new Case2Node(payload);
                break;

            case HqlSqlWalker.CASE:
                ret = new CaseNode(payload);
                break;

            case HqlSqlWalker.PARAM:
            case HqlSqlWalker.NAMED_PARAM:
                ret = new ParameterNode(payload);
                break;

            case HqlSqlWalker.EQ:
            case HqlSqlWalker.NE:
            case HqlSqlWalker.LT:
            case HqlSqlWalker.GT:
            case HqlSqlWalker.LE:
            case HqlSqlWalker.GE:
            case HqlSqlWalker.LIKE:
            case HqlSqlWalker.NOT_LIKE:
                ret = new BinaryLogicOperatorNode(payload);
                break;

            case HqlSqlWalker.IN:
            case HqlSqlWalker.NOT_IN:
                ret = new InLogicOperatorNode(payload);
                break;

            case HqlSqlWalker.BETWEEN:
            case HqlSqlWalker.NOT_BETWEEN:
                ret = new BetweenOperatorNode(payload);
                break;

            case HqlSqlWalker.IS_NULL:
                ret = new IsNullLogicOperatorNode(payload);
                break;

            case HqlSqlWalker.IS_NOT_NULL:
                ret = new IsNotNullLogicOperatorNode(payload);
                break;

            case HqlSqlWalker.EXISTS:
                ret = new UnaryLogicOperatorNode(payload);
                break;

            default:
                ret = new SqlNode(payload);
                break;
            }

            Initialise(ret);
            return(ret);
        }
Пример #12
0
		private static void PrepareAnyImplicitJoins(DotNode dotNode) 
		{
			if ( dotNode.GetLhs() is DotNode )
			{
				DotNode lhs = ( DotNode ) dotNode.GetLhs();
				FromElement lhsOrigin = lhs.FromElement;
				if ( lhsOrigin != null && "" == lhsOrigin.Text )
				{
					String lhsOriginText = lhsOrigin.Queryable.TableName +
							" " + lhsOrigin.TableAlias;
					lhsOrigin.Text = lhsOriginText;
				}
				PrepareAnyImplicitJoins( lhs );
			}
		}
Пример #13
0
		private bool ResolveAsNakedComponentPropertyRefRhs(DotNode parent)
		{
			FromElement fromElement = LocateSingleFromElement();
			if (fromElement == null)
			{
				return false;
			}

			IType propertyType;
			string propertyPath = parent.GetLhs().Text + "." + Text;
			try
			{
				// check to see if our "propPath" actually
				// represents a property on the persister
				propertyType = fromElement.GetPropertyType(Text, propertyPath);
			}
			catch (Exception)
			{
				// assume we do *not* refer to a property on the given persister
				return false;
			}

			FromElement = fromElement;
			// this piece is needed for usage in select clause
			DataType = propertyType;

			_nakedPropertyRef = true;

			return true;
		}
Пример #14
0
		private bool ResolveAsNakedComponentPropertyRefLhs(DotNode parent)
		{
			FromElement fromElement = LocateSingleFromElement();
			if (fromElement == null)
			{
				return false;
			}

			IType componentType = GetNakedPropertyType(fromElement);

			if (componentType == null)
			{
				throw new QueryException("Unable to resolve path [" + parent.Path + "], unexpected token [" + OriginalText + "]");
			}
			if (!componentType.IsComponentType)
			{
				throw new QueryException("Property '" + OriginalText + "' is not a component.  Use an alias to reference associations or collections.");
			}

			IType propertyType ;  // used to set the type of the parent dot node
			string propertyPath = Text + "." + NextSibling.Text;
			try
			{
				// check to see if our "propPath" actually
				// represents a property on the persister
				propertyType = fromElement.GetPropertyType(Text, propertyPath);
			}
			catch (Exception)
			{
				// assume we do *not* refer to a property on the given persister
				return false;
			}

			FromElement = fromElement;
			parent.PropertyPath = propertyPath;
			parent.DataType = propertyType;

			return true;
		}