示例#1
0
        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);
        }
示例#2
0
        private void Initialize(SelectClause selectClause)
        {
            IList <FromElement> fromElementList = selectClause.FromElementsForLoad;

            _hasScalars        = selectClause.IsScalarSelect;
            _scalarColumnNames = selectClause.ColumnNames;
            //sqlResultTypes = selectClause.getSqlResultTypes();
            _queryReturnTypes = selectClause.QueryReturnTypes;

            _selectNewTransformer = HolderInstantiator.CreateSelectNewTransformer(selectClause.Constructor, selectClause.IsMap, selectClause.IsList);
            _queryReturnAliases   = selectClause.QueryReturnAliases;

            IList <FromElement> collectionFromElements = selectClause.CollectionFromElements;

            if (collectionFromElements != null && collectionFromElements.Count != 0)
            {
                int length = collectionFromElements.Count;
                _collectionPersisters = new IQueryableCollection[length];
                _collectionOwners     = new int[length];
                _collectionSuffixes   = new string[length];

                for (int i = 0; i < length; i++)
                {
                    FromElement collectionFromElement = collectionFromElements[i];
                    _collectionPersisters[i] = collectionFromElement.QueryableCollection;
                    _collectionOwners[i]     = fromElementList.IndexOf(collectionFromElement.Origin);
                    //				collectionSuffixes[i] = collectionFromElement.getColumnAliasSuffix();
                    //				collectionSuffixes[i] = Integer.toString( i ) + "_";
                    _collectionSuffixes[i] = collectionFromElement.CollectionSuffix;
                }
            }

            int size = fromElementList.Count;

            _entityPersisters           = new IQueryable[size];
            _entityEagerPropertyFetches = new bool[size];
            _entityAliases         = new String[size];
            _sqlAliases            = new String[size];
            _sqlAliasSuffixes      = new String[size];
            _includeInSelect       = new bool[size];
            _owners                = new int[size];
            _ownerAssociationTypes = new EntityType[size];

            for (int i = 0; i < size; i++)
            {
                FromElement element = fromElementList[i];
                _entityPersisters[i] = (IQueryable)element.EntityPersister;

                if (_entityPersisters[i] == null)
                {
                    throw new InvalidOperationException("No entity persister for " + element);
                }

                _entityEagerPropertyFetches[i] = element.IsAllPropertyFetch;
                _sqlAliases[i]    = element.TableAlias;
                _entityAliases[i] = element.ClassAlias;
                _sqlAliasByEntityAlias.Add(_entityAliases[i], _sqlAliases[i]);
                // TODO should we just collect these like with the collections above?
                _sqlAliasSuffixes[i] = (size == 1) ? "" : i + "_";
                //			sqlAliasSuffixes[i] = element.getColumnAliasSuffix();
                _includeInSelect[i] = !element.IsFetch;
                if (_includeInSelect[i])
                {
                    _selectLength++;
                }

                _owners[i] = -1;                 //by default
                if (element.IsFetch)
                {
                    if (element.IsCollectionJoin || element.QueryableCollection != null)
                    {
                        // This is now handled earlier in this method.
                    }
                    else if (element.DataType.IsEntityType)
                    {
                        var entityType = (EntityType)element.DataType;
                        if (entityType.IsOneToOne)
                        {
                            _owners[i] = fromElementList.IndexOf(element.Origin);
                        }
                        _ownerAssociationTypes[i] = entityType;
                    }
                }
            }

            //NONE, because its the requested lock mode, not the actual!
            _defaultLockModes = ArrayHelper.FillArray(LockMode.None, size);
        }
示例#3
0
 public WithClauseVisitor(FromElement fromElement)
 {
     _joinFragment = fromElement;
 }
示例#4
0
 public JoinSequence AddJoin(FromElement fromElement)
 {
     joins.AddRange(fromElement.JoinSequence.joins);
     return(this);
 }
示例#5
0
 internal JoinSequenceSelector(HqlSqlWalker walker, FromClause fromClause, FromElement fromElement)
 {
     _walker      = walker;
     _fromClause  = fromClause;
     _fromElement = fromElement;
 }
示例#6
0
 public WithClauseVisitor(FromElement fromElement)
 {
     _joinFragment = fromElement;
     _multiTable   = (fromElement.EntityPersister as IQueryable)?.IsMultiTable == true;
 }
示例#7
0
        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 [{0}]", 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.IndexOfOrdinal("?") >= 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 [{0}]", 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);
            }
        }
示例#8
0
        private void Initialize(SelectClause selectClause)
        {
            IList <FromElement> fromElementList = selectClause.FromElementsForLoad;

            _hasScalars        = selectClause.IsScalarSelect;
            _scalarColumnNames = selectClause.ColumnNames;
            //sqlResultTypes = selectClause.getSqlResultTypes();
            ResultTypes = selectClause.QueryReturnTypes;

            _selectNewTransformer = GetSelectNewTransformer(selectClause);
            _queryReturnAliases   = selectClause.QueryReturnAliases;

            IList <FromElement> collectionFromElements = selectClause.CollectionFromElements;

            if (collectionFromElements != null && collectionFromElements.Count != 0)
            {
                int length = collectionFromElements.Count;
                _collectionPersisters = new IQueryableCollection[length];
                _collectionOwners     = new int[length];
                _collectionSuffixes   = new string[length];
                CollectionFetches     = new bool[length];
                if (collectionFromElements.Any(qc => qc.QueryableCollection.IsManyToMany))
                {
                    _collectionUserProvidedAliases = new Dictionary <string, string[]> [length];
                }

                for (int i = 0; i < length; i++)
                {
                    FromElement collectionFromElement = collectionFromElements[i];
                    _collectionPersisters[i] = collectionFromElement.QueryableCollection;
                    _collectionOwners[i]     = fromElementList.IndexOf(collectionFromElement.Origin);
                    //				collectionSuffixes[i] = collectionFromElement.getColumnAliasSuffix();
                    //				collectionSuffixes[i] = Integer.toString( i ) + "_";
                    _collectionSuffixes[i] = collectionFromElement.CollectionSuffix;
                    CollectionFetches[i]   = collectionFromElement.IsFetch;
                }
            }

            int size = fromElementList.Count;

            _entityPersisters           = new IQueryable[size];
            _entityEagerPropertyFetches = new bool[size];
            _entityFetchLazyProperties  = new HashSet <string> [size];
            _entityAliases         = new String[size];
            _sqlAliases            = new String[size];
            _sqlAliasSuffixes      = new String[size];
            _includeInSelect       = new bool[size];
            _owners                = new int[size];
            _ownerAssociationTypes = new EntityType[size];
            EntityFetches          = new bool[size];
            var cacheTypes = new List <IType>(ResultTypes);

            for (int i = 0; i < size; i++)
            {
                FromElement element = fromElementList[i];
                _entityPersisters[i] = (IQueryable)element.EntityPersister;

                if (_entityPersisters[i] == null)
                {
                    throw new InvalidOperationException("No entity persister for " + element);
                }

                _entityEagerPropertyFetches[i] = element.IsAllPropertyFetch;
                _entityFetchLazyProperties[i]  = element.FetchLazyProperties != null
                                        ? new HashSet <string>(element.FetchLazyProperties)
                                        : null;
                _sqlAliases[i]    = element.TableAlias;
                _entityAliases[i] = element.ClassAlias;
                _sqlAliasByEntityAlias.Add(_entityAliases[i], _sqlAliases[i]);
                // TODO should we just collect these like with the collections above?
                _sqlAliasSuffixes[i] = (size == 1) ? "" : i + "_";
                //			sqlAliasSuffixes[i] = element.getColumnAliasSuffix();
                _includeInSelect[i] = !element.IsFetch;
                EntityFetches[i]    = element.IsFetch;
                if (element.IsFetch)
                {
                    cacheTypes.Add(_entityPersisters[i].Type);
                }
                if (_includeInSelect[i])
                {
                    _selectLength++;
                }

                if (collectionFromElements != null && element.IsFetch && element.QueryableCollection?.IsManyToMany == true &&
                    element.QueryableCollection.IsManyToManyFiltered(_queryTranslator.EnabledFilters))
                {
                    var collectionIndex = collectionFromElements.IndexOf(element);

                    if (collectionIndex >= 0)
                    {
                        // When many-to-many is filtered we need to populate collection from element persister and not from bridge table.
                        // As bridge table will contain not-null values for filtered elements
                        // So do alias substitution for collection persister with element persister
                        // See test TestFilteredLinqQuery for details
                        _collectionUserProvidedAliases[collectionIndex] = new Dictionary <string, string[]>
                        {
                            { CollectionPersister.PropElement, _entityPersisters[i].GetIdentifierAliases(Suffixes[i]) }
                        };
                    }
                }

                _owners[i] = -1;                 //by default
                if (element.IsFetch)
                {
                    if (element.IsCollectionJoin || element.QueryableCollection != null)
                    {
                        // This is now handled earlier in this method.
                    }
                    else if (element.DataType.IsEntityType)
                    {
                        _owners[i] = fromElementList.IndexOf(element.Origin);
                        _ownerAssociationTypes[i] = (EntityType)element.DataType;
                    }
                }
            }

            if (_collectionPersisters != null)
            {
                cacheTypes.AddRange(_collectionPersisters.Where((t, i) => CollectionFetches[i]).Select(t => t.CollectionType));
            }

            _cacheTypes = cacheTypes.ToArray();

            //NONE, because its the requested lock mode, not the actual!
            _defaultLockModes = ArrayHelper.Fill(LockMode.None, size);
            _uncacheableCollectionPersisters = _queryTranslator.UncacheableCollectionPersisters;
        }