Esempio n. 1
0
        IASTNode CreateFromFilterElement(IASTNode filterEntity, IASTNode alias)
        {
            var fromElementFound = true;

            var fromElement = _currentFromClause.GetFromElement(alias.Text) ??
                              _currentFromClause.GetFromElementByClassName(filterEntity.Text);

            if (fromElement == null)
            {
                fromElementFound = false;
                fromElement      = _currentFromClause.AddFromElement(filterEntity.Text, alias);
            }

            FromClause           fromClause = fromElement.FromClause;
            IQueryableCollection persister  = _sessionFactoryHelper.GetCollectionPersister(_collectionFilterRole);

            // Get the names of the columns used to link between the collection
            // owner and the collection elements.
            String[] keyColumnNames = persister.KeyColumnNames;
            String   fkTableAlias   = persister.IsOneToMany
                                        ? fromElement.TableAlias
                                        : fromClause.AliasGenerator.CreateName(_collectionFilterRole);

            JoinSequence join = _sessionFactoryHelper.CreateJoinSequence();

            join.SetRoot(persister, fkTableAlias);

            if (!persister.IsOneToMany)
            {
                join.AddJoin((IAssociationType)persister.ElementType,
                             fromElement.TableAlias,
                             JoinType.InnerJoin,
                             persister.GetElementColumnNames(fkTableAlias));
            }

            join.AddCondition(fkTableAlias, keyColumnNames, " = ", true);
            fromElement.JoinSequence = join;
            fromElement.Filter       = true;

            if (log.IsDebugEnabled())
            {
                log.Debug("createFromFilterElement() : processed filter FROM element.");
            }

            if (fromElementFound)
            {
                return((IASTNode)adaptor.Nil());
            }

            return(fromElement);
        }
Esempio n. 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;
        }
Esempio n. 3
0
        public void Token(string token, QueryTranslator q)
        {
            if (token != null)
            {
                path.Append(token);
            }

            string alias = q.GetPathAlias(path.ToString());

            if (alias != null)
            {
                Reset(q);                       //reset the dotcount (but not the path)
                currentName            = alias; //after reset!
                currentPropertyMapping = q.GetPropertyMapping(currentName);
                if (!ignoreInitialJoin)
                {
                    JoinSequence ojf = q.GetPathJoin(path.ToString());
                    try
                    {
                        joinSequence.AddCondition(ojf.ToJoinFragment(q.EnabledFilters, true).ToWhereFragmentString);                         //after reset!
                    }
                    catch (MappingException me)
                    {
                        throw new QueryException(me);
                    }
                    // we don't need to worry about any condition in the ON clause
                    // here (toFromFragmentString), since anything in the ON condition
                    // is already applied to the whole query
                }
            }
            else if (".".Equals(token))
            {
                dotcount++;
            }
            else
            {
                if (dotcount == 0)
                {
                    if (!continuation)
                    {
                        if (!q.IsName(token))
                        {
                            throw new QueryException("undefined alias or unknown mapping: " + token);
                        }
                        currentName            = token;
                        currentPropertyMapping = q.GetPropertyMapping(currentName);
                    }
                }
                else if (dotcount == 1)
                {
                    if (currentName != null)
                    {
                        currentProperty = token;
                    }
                    else if (collectionName != null)
                    {
                        //IQueryableCollection p = q.GetCollectionPersister( collectionRole );
                        //DoCollectionProperty( token, p, collectionName );
                        continuation = false;
                    }
                    else
                    {
                        throw new QueryException("unexpected");
                    }
                }
                else
                {
                    // dotcount>=2

                    // Do the corresponding RHS
                    IType propertyType = PropertyType;

                    if (propertyType == null)
                    {
                        throw new QueryException("unresolved property: " + currentProperty);
                    }

                    if (propertyType.IsComponentType)
                    {
                        DereferenceComponent(token);
                    }
                    else if (propertyType.IsEntityType)
                    {
                        DereferenceEntity(token, (EntityType)propertyType, q);
                    }
                    else if (propertyType.IsCollectionType)
                    {
                        DereferenceCollection(token, ((CollectionType)propertyType).Role, q);
                    }
                    else if (token != null)
                    {
                        throw new QueryException("dereferenced: " + currentProperty);
                    }
                }
            }
        }