Пример #1
0
        public override void  Resolve(bool generateJoin, bool implicitJoin, string classAlias, IASTNode parent)
        {
            if (IsResolved)
            {
                return;
            }

            FromReferenceNode collectionNode = ( FromReferenceNode )GetChild(0);
            SessionFactoryHelperExtensions sessionFactoryHelper = SessionFactoryHelper;

            collectionNode.ResolveIndex(this);                          // Fully resolve the map reference, create implicit joins.

            IType type = collectionNode.DataType;

            if (!type.IsCollectionType)
            {
                throw new SemanticException("The [] operator cannot be applied to type " + type);
            }

            string collectionRole = (( CollectionType )type).Role;
            IQueryableCollection queryableCollection = sessionFactoryHelper.RequireQueryableCollection(collectionRole);

            if (!queryableCollection.HasIndex)
            {
                throw new QueryException("unindexed fromElement before []: " + collectionNode.Path);
            }

            // Generate the inner join -- The elements need to be joined to the collection they are in.
            FromElement fromElement  = collectionNode.FromElement;
            String      elementTable = fromElement.TableAlias;
            FromClause  fromClause   = fromElement.FromClause;
            String      path         = collectionNode.Path;

            FromElement elem = fromClause.FindCollectionJoin(path);

            if (elem == null)
            {
                FromElementFactory factory = new FromElementFactory(fromClause, fromElement, path);
                elem = factory.CreateCollectionElementsJoin(queryableCollection, elementTable);
                if (Log.IsDebugEnabled)
                {
                    Log.Debug("No FROM element found for the elements of collection join path " + path
                              + ", created " + elem);
                }
            }
            else
            {
                if (Log.IsDebugEnabled)
                {
                    Log.Debug("FROM element found for collection join path " + path);
                }
            }

            // The 'from element' that represents the elements of the collection.
            FromElement = fromElement;

            // Add the condition to the join sequence that qualifies the indexed element.
            IASTNode selector = GetChild(1);

            if (selector == null)
            {
                throw new QueryException("No index value!");
            }

            // Sometimes use the element table alias, sometimes use the... umm... collection table alias (many to many)
            String collectionTableAlias = elementTable;

            if (elem.CollectionTableAlias != null)
            {
                collectionTableAlias = elem.CollectionTableAlias;
            }

            // TODO: get SQL rendering out of here, create an AST for the join expressions.
            // Use the SQL generator grammar to generate the SQL text for the index expression.
            JoinSequence joinSequence = fromElement.JoinSequence;

            string[] indexCols = queryableCollection.IndexColumnNames;
            if (indexCols.Length != 1)
            {
                throw new QueryException("composite-index appears in []: " + collectionNode.Path);
            }

            SqlGenerator gen = new SqlGenerator(SessionFactoryHelper.Factory, new CommonTreeNodeStream(selector));

            try
            {
                gen.simpleExpr();                 //TODO: used to be exprNoParens! was this needed?
            }
            catch (RecognitionException e)
            {
                throw new QueryException(e.Message, e);
            }

            string selectorExpression = gen.GetSQL().ToString();

            joinSequence.AddCondition(new SqlString(collectionTableAlias + '.' + indexCols[0] + " = " + selectorExpression));
            //joinSequence.AddCondition(collectionTableAlias, new string[] { indexCols[0] }, selectorExpression, false);

            IList <IParameterSpecification> paramSpecs = gen.GetCollectedParameters();

            if (paramSpecs != null)
            {
                switch (paramSpecs.Count)
                {
                case 0:
                    // nothing to do
                    break;

                case 1:
                    IParameterSpecification paramSpec = paramSpecs[0];
                    paramSpec.ExpectedType = queryableCollection.IndexType;
                    fromElement.SetIndexCollectionSelectorParamSpec(paramSpec);
                    break;

                default:
                    fromElement.SetIndexCollectionSelectorParamSpec(
                        new AggregatedIndexCollectionSelectorParameterSpecifications(paramSpecs)
                        );
                    break;
                }
            }

            // Now, set the text for this node.  It should be the element columns.
            String[] elementColumns = queryableCollection.GetElementColumnNames(elementTable);
            Text = elementColumns[0];

            IsResolved = true;
        }
Пример #2
0
		public override void  Resolve(bool generateJoin, bool implicitJoin, string classAlias, IASTNode parent)
		{
			if (IsResolved) 
			{
				return;
			}

			FromReferenceNode collectionNode = ( FromReferenceNode ) GetChild(0);
			SessionFactoryHelperExtensions sessionFactoryHelper = SessionFactoryHelper;
			collectionNode.ResolveIndex( this );		// Fully resolve the map reference, create implicit joins.

			IType type = collectionNode.DataType;
			if ( !type.IsCollectionType ) 
			{
				throw new SemanticException( "The [] operator cannot be applied to type " + type);
			}

			string collectionRole = ( ( CollectionType ) type ).Role;
			IQueryableCollection queryableCollection = sessionFactoryHelper.RequireQueryableCollection( collectionRole );
			if ( !queryableCollection.HasIndex ) 
			{
				throw new QueryException( "unindexed fromElement before []: " + collectionNode.Path );
			}

			// Generate the inner join -- The elements need to be joined to the collection they are in.
			FromElement fromElement = collectionNode.FromElement;
			String elementTable = fromElement.TableAlias;
			FromClause fromClause = fromElement.FromClause;
			String path = collectionNode.Path;

			FromElement elem = fromClause.FindCollectionJoin( path );
			if ( elem == null ) 
			{
				FromElementFactory factory = new FromElementFactory( fromClause, fromElement, path );
				elem = factory.CreateCollectionElementsJoin( queryableCollection, elementTable );
				if ( Log.IsDebugEnabled )
				{
					Log.Debug( "No FROM element found for the elements of collection join path " + path
							+ ", created " + elem );
				}
			}
			else 
			{
				if ( Log.IsDebugEnabled ) 
				{
					Log.Debug( "FROM element found for collection join path " + path );
				}
			}

			// The 'from element' that represents the elements of the collection.
			FromElement = fromElement;

			// Add the condition to the join sequence that qualifies the indexed element.
			IASTNode selector = GetChild(1);
			if ( selector == null ) 
			{
				throw new QueryException( "No index value!" );
			}

			// Sometimes use the element table alias, sometimes use the... umm... collection table alias (many to many)
			String collectionTableAlias = elementTable;
			if ( elem.CollectionTableAlias != null ) 
			{
				collectionTableAlias = elem.CollectionTableAlias;
			}

			// TODO: get SQL rendering out of here, create an AST for the join expressions.
			// Use the SQL generator grammar to generate the SQL text for the index expression.
			JoinSequence joinSequence = fromElement.JoinSequence;
			string[] indexCols = queryableCollection.IndexColumnNames;
			if ( indexCols.Length != 1 ) 
			{
				throw new QueryException( "composite-index appears in []: " + collectionNode.Path );
			}

			SqlGenerator gen = new SqlGenerator(SessionFactoryHelper.Factory, new CommonTreeNodeStream(selector));

			try 
			{
				gen.simpleExpr(); //TODO: used to be exprNoParens! was this needed?
			}
			catch ( RecognitionException e ) 
			{
				throw new QueryException( e.Message, e );
			}

			string selectorExpression = gen.GetSQL().ToString();

			joinSequence.AddCondition(new SqlString(collectionTableAlias + '.' + indexCols[0] + " = " + selectorExpression ));
			//joinSequence.AddCondition(collectionTableAlias, new string[] { indexCols[0] }, selectorExpression, false);

			IList<IParameterSpecification> paramSpecs = gen.GetCollectedParameters();
			if ( paramSpecs != null ) 
			{
				switch ( paramSpecs.Count ) 
				{
					case 0 :
						// nothing to do
						break;
					case 1 :
						IParameterSpecification paramSpec = paramSpecs[0];
						paramSpec.ExpectedType = queryableCollection.IndexType;
						fromElement.SetIndexCollectionSelectorParamSpec( paramSpec );
						break;
					default:
						fromElement.SetIndexCollectionSelectorParamSpec(
								new AggregatedIndexCollectionSelectorParameterSpecifications( paramSpecs )
						);
						break;
				}
			}

			// Now, set the text for this node.  It should be the element columns.
			String[] elementColumns = queryableCollection.GetElementColumnNames( elementTable );
			Text = elementColumns[0];

		    IsResolved = true;
		}