public string[] ToColumns(string tableAlias, string path, bool inSelect, bool forceAlias)
        {
            CheckInitialized();
            IPropertyMapping propertyMapping = GetPropertyMapping(path);

            // If this from element is a collection and the path is a collection property (maxIndex, etc.) then
            // generate a sub-query.
            if (!inSelect && _queryableCollection != null && CollectionProperties.IsCollectionProperty(path))
            {
                IDictionary <string, IFilter> enabledFilters = _fromElement.Walker.EnabledFilters;

                string subquery = CollectionSubqueryFactory.CreateCollectionSubquery(
                    _joinSequence,
                    enabledFilters,
                    propertyMapping.ToColumns(tableAlias, path)
                    );
                if (Log.IsDebugEnabled())
                {
                    Log.Debug("toColumns({0},{1}) : subquery = {2}", tableAlias, path, subquery);
                }
                return(new [] { "(" + subquery + ")" });
            }
            else
            {
                if (forceAlias)
                {
                    return(propertyMapping.ToColumns(tableAlias, path));
                }
                else if (_fromElement.Walker.StatementType == HqlSqlWalker.SELECT)
                {
                    return(propertyMapping.ToColumns(tableAlias, path));
                }
                else if (_fromElement.Walker.CurrentClauseType == HqlSqlWalker.SELECT)
                {
                    return(propertyMapping.ToColumns(tableAlias, path));
                }
                else if (_fromElement.Walker.IsSubQuery)
                {
                    // We already know it's subqery for DML query.
                    // If this FROM_ELEMENT represents a correlation to the outer-most query we must use real table name
                    // for UPDATE(typically in a SET clause)/DELETE queries unless it's multi-table reference inside top level where clause
                    // (as this subquery will actually be used in the "id select" phase of that multi-table executor)
                    var useAlias = _fromElement.Walker.StatementType == HqlSqlWalker.INSERT ||
                                   (IsMultiTable && _fromElement.Walker.CurrentTopLevelClauseType == HqlSqlWalker.WHERE);

                    if (!useAlias && IsCorrelation)
                    {
                        return(propertyMapping.ToColumns(ExtractTableName(), path));
                    }

                    return(propertyMapping.ToColumns(tableAlias, path));
                }
                else
                {
                    string[] columns = propertyMapping.ToColumns(path);
                    Log.Info("Using non-qualified column reference [{0} -> ({1})]", path, ArrayHelper.ToString(columns));
                    return(columns);
                }
            }
        }
Пример #2
0
        public void HandlePropertyBeingDereferenced(IType propertySource, string propertyName)
        {
            if (QueryableCollection != null && CollectionProperties.IsCollectionProperty(propertyName))
            {
                // propertyName refers to something like collection.size...
                return;
            }
            if (propertySource.IsComponentType)
            {
                // property name is a sub-path of a component...
                return;
            }

            IQueryable persister = Queryable;

            if (persister != null)
            {
                try
                {
                    Declarer propertyDeclarer = persister.GetSubclassPropertyDeclarer(propertyName);

                    if (Log.IsInfoEnabled())
                    {
                        Log.Info("handling property dereference [{0} ({1}) -> {2} ({3})]", persister.EntityName, ClassAlias, propertyName, propertyDeclarer);
                    }
                    if (propertyDeclarer == Declarer.SubClass)
                    {
                        _dereferencedBySubclassProperty = true;
                        _includeSubclasses = true;
                    }
                    else if (propertyDeclarer == Declarer.SuperClass)
                    {
                        _dereferencedBySuperclassProperty = true;
                    }
                }
                catch (QueryException ex)
                {
                    // ignore it; the incoming property could not be found so we
                    // cannot be sure what to do here.  At the very least, the
                    // safest is to simply not apply any dereference toggling...
                    Log.Debug(ex, "Unable to find property {0}, no dereference will be handled for it.", propertyName);
                }
            }
        }
Пример #3
0
        public IPropertyMapping GetPropertyMapping(string propertyName)
        {
            CheckInitialized();

            if (_queryableCollection == null)
            {
                // Not a collection?
                return((IPropertyMapping)_persister);                   // Return the entity property mapping.
            }

            // If the property is a special collection property name, return a CollectionPropertyMapping.
            if (CollectionProperties.IsCollectionProperty(propertyName))
            {
                if (_collectionPropertyMapping == null)
                {
                    _collectionPropertyMapping = new CollectionPropertyMapping(_queryableCollection);
                }
                return(_collectionPropertyMapping);
            }
            if (_queryableCollection.ElementType.IsAnyType)
            {
                // collection of <many-to-any/> mappings...
                // used to circumvent the component-collection check below...
                return(_queryableCollection);
            }

            if (_queryableCollection.ElementType.IsComponentType)
            {
                // Collection of components.
                if (propertyName == Persister.Entity.EntityPersister.EntityID)
                {
                    return((IPropertyMapping)_queryableCollection.OwnerEntityPersister);
                }
            }

            return(_queryableCollection);
        }
Пример #4
0
        public string[] ToColumns(string tableAlias, string path, bool inSelect, bool forceAlias)
        {
            CheckInitialized();
            IPropertyMapping propertyMapping = GetPropertyMapping(path);

            // If this from element is a collection and the path is a collection property (maxIndex, etc.) then
            // generate a sub-query.
            if (!inSelect && _queryableCollection != null && CollectionProperties.IsCollectionProperty(path))
            {
                IDictionary <string, IFilter> enabledFilters = _fromElement.Walker.EnabledFilters;

                string subquery = CollectionSubqueryFactory.CreateCollectionSubquery(
                    _joinSequence,
                    enabledFilters,
                    propertyMapping.ToColumns(tableAlias, path)
                    );
                if (Log.IsDebugEnabled)
                {
                    Log.Debug("toColumns(" + tableAlias + "," + path + ") : subquery = " + subquery);
                }
                return(new [] { "(" + subquery + ")" });
            }
            else
            {
                if (forceAlias)
                {
                    return(propertyMapping.ToColumns(tableAlias, path));
                }
                else if (_fromElement.Walker.StatementType == HqlSqlWalker.SELECT)
                {
                    return(propertyMapping.ToColumns(tableAlias, path));
                }
                else if (_fromElement.Walker.CurrentClauseType == HqlSqlWalker.SELECT)
                {
                    return(propertyMapping.ToColumns(tableAlias, path));
                }
                else if (_fromElement.Walker.IsSubQuery)
                {
                    // for a subquery, the alias to use depends on a few things (we
                    // already know this is not an overall SELECT):
                    //      1) if this FROM_ELEMENT represents a correlation to the
                    //          outer-most query
                    //              A) if the outer query represents a multi-table
                    //                  persister, we need to use the given alias
                    //                  in anticipation of one of the multi-table
                    //                  executors being used (as this subquery will
                    //                  actually be used in the "id select" phase
                    //                  of that multi-table executor)
                    //              B) otherwise, we need to use the persister's
                    //                  table name as the column qualification
                    //      2) otherwise (not correlated), use the given alias
                    if (IsCorrelation)
                    {
                        if (IsMultiTable)
                        {
                            return(propertyMapping.ToColumns(tableAlias, path));
                        }
                        else
                        {
                            return(propertyMapping.ToColumns(ExtractTableName(), path));
                        }
                    }
                    else
                    {
                        return(propertyMapping.ToColumns(tableAlias, path));
                    }
                }
                else
                {
                    string[] columns = propertyMapping.ToColumns(path);
                    Log.Info("Using non-qualified column reference [" + path + " -> (" + ArrayHelper.ToString(columns) + ")]");
                    return(columns);
                }
            }
        }