public ISyntaxNode Visit(TSqlFragment node, TSqlFragment parent, string sourceProperty, ISyntaxNode result)
        {
            ColumnReferenceExpression columnReference = node as ColumnReferenceExpression;

            if (columnReference == null)
            {
                return(result);
            }

            StatementNode statement = result as StatementNode;

            if (statement == null)
            {
                return(result);
            }
            if (columnReference.ColumnType != ColumnType.Regular)
            {
                return(result);
            }
            if (statement.Tables == null || statement.Tables.Count == 0)
            {
                return(result);
            }

            Identifier     identifier        = null;
            string         propertyFieldName = null;
            IList <string> identifiers       = new List <string>();

            for (int i = 0; i < columnReference.MultiPartIdentifier.Identifiers.Count; i++)
            {
                identifiers.Add(columnReference.MultiPartIdentifier.Identifiers[i].Value);
            }

            if (identifiers.Count == 1) // no table alias - just column name
            {
                identifier = columnReference.MultiPartIdentifier.Identifiers[0];
            }
            else if (columnReference.MultiPartIdentifier.Identifiers.Count == 2)
            {
                if (IsSpecialField(identifiers[1])) // no table alias - just column name
                {
                    propertyFieldName = identifiers[1];
                    identifier        = columnReference.MultiPartIdentifier.Identifiers[0];
                }
                else
                {
                    identifier = columnReference.MultiPartIdentifier.Identifiers[1];
                }
            }
            else // columnReference.MultiPartIdentifier.Identifiers.Count == 3
            {
                propertyFieldName = identifiers[2];
                identifier        = columnReference.MultiPartIdentifier.Identifiers[1];
            }

            MetaProperty property = GetProperty(identifiers, statement);

            if (property == null)
            {
                return(result);
            }
            if (property.Fields.Count == 0)
            {
                return(result);
            }

            if (property.IsReferenceType)
            {
                if (propertyFieldName == null) // Т.Ссылка | Т.Владелец
                {
                    VisitReferenceTypeColumn(columnReference, parent, sourceProperty, identifier, property);
                }
                else // uuid | type | TYPE
                {
                    VisitReferenceTypeColumn(columnReference, parent, sourceProperty, columnReference.MultiPartIdentifier.Identifiers, identifier, property, propertyFieldName);
                }
            }
            else // Т.Наименование
            {
                VisitValueTypeColumn(identifier, property);
            }

            return(result);
        }
        private MetaProperty GetPropertyWithoutTableAlias(IList <string> identifiers, StatementNode statement)
        {
            TableNode    table        = null;
            MetaProperty property     = null;
            string       propertyName = identifiers[0];

            foreach (ISyntaxNode tableNode in statement.Tables.Values)
            {
                if (tableNode is TableNode)
                {
                    table = (TableNode)tableNode;
                    if (table.Alias == null)
                    {
                        if (table.MetaObject != null)
                        {
                            property = table.MetaObject.Properties.Where(p => p.Name == propertyName).FirstOrDefault();
                            if (property != null)
                            {
                                return(property); //TODO: check if property name is unique for all tables having no alias
                            }
                        }
                    }
                }
                else if (tableNode is StatementNode)
                {
                    return(property); // TODO: query derived table ... tunneling ... value type inference ... !?
                }
            }
            return(property);
        }