vendor/doctrine/lib/Doctrine/ORM/Query/SqlWalker.php
author cavaliet
Wed, 11 Apr 2012 12:07:42 +0200
changeset 86 38ee151428dc
parent 0 7f95f8617b0b
permissions -rwxr-xr-x
remove original label column from all tags list
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
     1
<?php
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
     2
/*
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
     3
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
     4
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
     5
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
     6
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
     7
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
     8
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
     9
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    10
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    11
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    12
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    13
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    14
 *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    15
 * This software consists of voluntary contributions made by many individuals
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    16
 * and is licensed under the LGPL. For more information, see
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    17
 * <http://www.doctrine-project.org>.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    18
 */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    19
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    20
namespace Doctrine\ORM\Query;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    21
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    22
use Doctrine\DBAL\LockMode,
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    23
    Doctrine\ORM\Mapping\ClassMetadata,
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    24
    Doctrine\ORM\Query,
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    25
    Doctrine\ORM\Query\QueryException;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    26
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    27
/**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    28
 * The SqlWalker is a TreeWalker that walks over a DQL AST and constructs
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    29
 * the corresponding SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    30
 *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    31
 * @author Roman Borschel <roman@code-factory.org>
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    32
 * @author Benjamin Eberlei <kontakt@beberlei.de>
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    33
 * @since 2.0
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    34
 * @todo Rename: SQLWalker
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    35
 */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    36
class SqlWalker implements TreeWalker
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    37
{
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    38
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    39
     * @var ResultSetMapping
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    40
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    41
    private $_rsm;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    42
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    43
    /** Counters for generating unique column aliases, table aliases and parameter indexes. */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    44
    private $_aliasCounter = 0;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    45
    private $_tableAliasCounter = 0;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    46
    private $_scalarResultCounter = 1;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    47
    private $_sqlParamIndex = 0;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    48
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    49
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    50
     * @var ParserResult
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    51
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    52
    private $_parserResult;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    53
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    54
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    55
     * @var EntityManager
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    56
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    57
    private $_em;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    58
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    59
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    60
     * @var Doctrine\DBAL\Connection
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    61
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    62
    private $_conn;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    63
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    64
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    65
     * @var AbstractQuery
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    66
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    67
    private $_query;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    68
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    69
    private $_tableAliasMap = array();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    70
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    71
    /** Map from result variable names to their SQL column alias names. */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    72
    private $_scalarResultAliasMap = array();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    73
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    74
    /** Map of all components/classes that appear in the DQL query. */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    75
    private $_queryComponents;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    76
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    77
    /** A list of classes that appear in non-scalar SelectExpressions. */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    78
    private $_selectedClasses = array();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    79
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    80
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    81
     * The DQL alias of the root class of the currently traversed query.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    82
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    83
    private $_rootAliases = array();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    84
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    85
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    86
     * Flag that indicates whether to generate SQL table aliases in the SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    87
     * These should only be generated for SELECT queries, not for UPDATE/DELETE.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    88
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    89
    private $_useSqlTableAliases = true;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    90
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    91
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    92
     * The database platform abstraction.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    93
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    94
     * @var AbstractPlatform
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    95
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    96
    private $_platform;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    97
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    98
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    99
     * {@inheritDoc}
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   100
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   101
    public function __construct($query, $parserResult, array $queryComponents)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   102
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   103
        $this->_query = $query;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   104
        $this->_parserResult = $parserResult;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   105
        $this->_queryComponents = $queryComponents;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   106
        $this->_rsm = $parserResult->getResultSetMapping();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   107
        $this->_em = $query->getEntityManager();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   108
        $this->_conn = $this->_em->getConnection();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   109
        $this->_platform = $this->_conn->getDatabasePlatform();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   110
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   111
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   112
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   113
     * Gets the Query instance used by the walker.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   114
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   115
     * @return Query.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   116
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   117
    public function getQuery()
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   118
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   119
        return $this->_query;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   120
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   121
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   122
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   123
     * Gets the Connection used by the walker.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   124
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   125
     * @return Connection
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   126
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   127
    public function getConnection()
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   128
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   129
        return $this->_conn;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   130
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   131
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   132
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   133
     * Gets the EntityManager used by the walker.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   134
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   135
     * @return EntityManager
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   136
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   137
    public function getEntityManager()
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   138
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   139
        return $this->_em;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   140
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   141
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   142
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   143
     * Gets the information about a single query component.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   144
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   145
     * @param string $dqlAlias The DQL alias.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   146
     * @return array
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   147
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   148
    public function getQueryComponent($dqlAlias)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   149
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   150
        return $this->_queryComponents[$dqlAlias];
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   151
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   152
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   153
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   154
     * Gets an executor that can be used to execute the result of this walker.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   155
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   156
     * @return AbstractExecutor
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   157
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   158
    public function getExecutor($AST)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   159
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   160
        $isDeleteStatement = $AST instanceof AST\DeleteStatement;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   161
        $isUpdateStatement = $AST instanceof AST\UpdateStatement;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   162
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   163
        if ($isDeleteStatement) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   164
            $primaryClass = $this->_em->getClassMetadata(
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   165
                $AST->deleteClause->abstractSchemaName
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   166
            );
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   167
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   168
            if ($primaryClass->isInheritanceTypeJoined()) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   169
                return new Exec\MultiTableDeleteExecutor($AST, $this);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   170
            } else {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   171
                return new Exec\SingleTableDeleteUpdateExecutor($AST, $this);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   172
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   173
        } else if ($isUpdateStatement) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   174
            $primaryClass = $this->_em->getClassMetadata(
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   175
                $AST->updateClause->abstractSchemaName
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   176
            );
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   177
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   178
            if ($primaryClass->isInheritanceTypeJoined()) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   179
                return new Exec\MultiTableUpdateExecutor($AST, $this);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   180
            } else {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   181
                return new Exec\SingleTableDeleteUpdateExecutor($AST, $this);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   182
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   183
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   184
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   185
        return new Exec\SingleSelectExecutor($AST, $this);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   186
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   187
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   188
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   189
     * Generates a unique, short SQL table alias.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   190
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   191
     * @param string $tableName Table name
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   192
     * @param string $dqlAlias The DQL alias.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   193
     * @return string Generated table alias.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   194
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   195
    public function getSQLTableAlias($tableName, $dqlAlias = '')
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   196
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   197
        $tableName .= ($dqlAlias) ? '@[' . $dqlAlias . ']' : '';
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   198
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   199
        if ( ! isset($this->_tableAliasMap[$tableName])) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   200
            $this->_tableAliasMap[$tableName] = strtolower(substr($tableName, 0, 1)) . $this->_tableAliasCounter++ . '_';
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   201
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   202
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   203
        return $this->_tableAliasMap[$tableName];
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   204
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   205
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   206
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   207
     * Forces the SqlWalker to use a specific alias for a table name, rather than
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   208
     * generating an alias on its own.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   209
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   210
     * @param string $tableName
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   211
     * @param string $alias
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   212
     * @param string $dqlAlias
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   213
     * @return string
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   214
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   215
    public function setSQLTableAlias($tableName, $alias, $dqlAlias = '')
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   216
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   217
        $tableName .= ($dqlAlias) ? '@[' . $dqlAlias . ']' : '';
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   218
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   219
        $this->_tableAliasMap[$tableName] = $alias;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   220
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   221
        return $alias;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   222
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   223
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   224
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   225
     * Gets an SQL column alias for a column name.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   226
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   227
     * @param string $columnName
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   228
     * @return string
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   229
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   230
    public function getSQLColumnAlias($columnName)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   231
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   232
        return $columnName . $this->_aliasCounter++;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   233
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   234
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   235
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   236
     * Generates the SQL JOINs that are necessary for Class Table Inheritance
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   237
     * for the given class.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   238
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   239
     * @param ClassMetadata $class The class for which to generate the joins.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   240
     * @param string $dqlAlias The DQL alias of the class.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   241
     * @return string The SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   242
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   243
    private function _generateClassTableInheritanceJoins($class, $dqlAlias)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   244
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   245
        $sql = '';
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   246
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   247
        $baseTableAlias = $this->getSQLTableAlias($class->table['name'], $dqlAlias);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   248
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   249
        // INNER JOIN parent class tables
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   250
        foreach ($class->parentClasses as $parentClassName) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   251
            $parentClass = $this->_em->getClassMetadata($parentClassName);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   252
            $tableAlias = $this->getSQLTableAlias($parentClass->table['name'], $dqlAlias);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   253
            // If this is a joined association we must use left joins to preserve the correct result.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   254
            $sql .= isset($this->_queryComponents[$dqlAlias]['relation']) ? ' LEFT ' : ' INNER ';
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   255
            $sql .= 'JOIN ' . $parentClass->getQuotedTableName($this->_platform)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   256
                  . ' ' . $tableAlias . ' ON ';
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   257
            $first = true;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   258
            foreach ($class->identifier as $idField) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   259
                if ($first) $first = false; else $sql .= ' AND ';
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   260
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   261
                $columnName = $class->getQuotedColumnName($idField, $this->_platform);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   262
                $sql .= $baseTableAlias . '.' . $columnName
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   263
                      . ' = '
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   264
                      . $tableAlias . '.' . $columnName;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   265
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   266
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   267
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   268
        // LEFT JOIN subclass tables, if partial objects disallowed.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   269
        if ( ! $this->_query->getHint(Query::HINT_FORCE_PARTIAL_LOAD)) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   270
            foreach ($class->subClasses as $subClassName) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   271
                $subClass = $this->_em->getClassMetadata($subClassName);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   272
                $tableAlias = $this->getSQLTableAlias($subClass->table['name'], $dqlAlias);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   273
                $sql .= ' LEFT JOIN ' . $subClass->getQuotedTableName($this->_platform)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   274
                        . ' ' . $tableAlias . ' ON ';
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   275
                $first = true;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   276
                foreach ($class->identifier as $idField) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   277
                    if ($first) $first = false; else $sql .= ' AND ';
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   278
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   279
                    $columnName = $class->getQuotedColumnName($idField, $this->_platform);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   280
                    $sql .= $baseTableAlias . '.' . $columnName
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   281
                            . ' = '
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   282
                            . $tableAlias . '.' . $columnName;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   283
                }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   284
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   285
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   286
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   287
        return $sql;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   288
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   289
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   290
    private function _generateOrderedCollectionOrderByItems()
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   291
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   292
        $sql = '';
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   293
        foreach ($this->_selectedClasses AS $dqlAlias => $class) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   294
            $qComp = $this->_queryComponents[$dqlAlias];
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   295
            if (isset($qComp['relation']['orderBy'])) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   296
                foreach ($qComp['relation']['orderBy'] AS $fieldName => $orientation) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   297
                    if ($qComp['metadata']->isInheritanceTypeJoined()) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   298
                        $tableName = $this->_em->getUnitOfWork()->getEntityPersister($class->name)->getOwningTable($fieldName);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   299
                    } else {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   300
                        $tableName = $qComp['metadata']->table['name'];
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   301
                    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   302
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   303
                    if ($sql != '') {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   304
                        $sql .= ', ';
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   305
                    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   306
                    $sql .= $this->getSQLTableAlias($tableName, $dqlAlias) . '.' .
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   307
                            $qComp['metadata']->getQuotedColumnName($fieldName, $this->_platform) . " $orientation";
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   308
                }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   309
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   310
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   311
        return $sql;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   312
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   313
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   314
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   315
     * Generates a discriminator column SQL condition for the class with the given DQL alias.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   316
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   317
     * @param array $dqlAliases List of root DQL aliases to inspect for discriminator restrictions.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   318
     * @return string
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   319
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   320
    private function _generateDiscriminatorColumnConditionSQL(array $dqlAliases)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   321
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   322
        $encapsulate = false;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   323
        $sql = '';
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   324
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   325
        foreach ($dqlAliases as $dqlAlias) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   326
            $class = $this->_queryComponents[$dqlAlias]['metadata'];
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   327
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   328
            if ($class->isInheritanceTypeSingleTable()) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   329
                $conn = $this->_em->getConnection();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   330
                $values = array();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   331
                if ($class->discriminatorValue !== null) { // discrimnators can be 0
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   332
                    $values[] = $conn->quote($class->discriminatorValue);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   333
                }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   334
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   335
                foreach ($class->subClasses as $subclassName) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   336
                    $values[] = $conn->quote($this->_em->getClassMetadata($subclassName)->discriminatorValue);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   337
                }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   338
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   339
                if ($sql != '') {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   340
                    $sql .= ' AND ';
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   341
                    $encapsulate = true;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   342
                }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   343
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   344
                $sql .= ($sql != '' ? ' AND ' : '')
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   345
                      . (($this->_useSqlTableAliases) ? $this->getSQLTableAlias($class->table['name'], $dqlAlias) . '.' : '')
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   346
                      . $class->discriminatorColumn['name'] . ' IN (' . implode(', ', $values) . ')';
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   347
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   348
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   349
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   350
        return ($encapsulate) ? '(' . $sql . ')' : $sql;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   351
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   352
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   353
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   354
     * Walks down a SelectStatement AST node, thereby generating the appropriate SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   355
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   356
     * @return string The SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   357
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   358
    public function walkSelectStatement(AST\SelectStatement $AST)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   359
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   360
        $sql = $this->walkSelectClause($AST->selectClause);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   361
        $sql .= $this->walkFromClause($AST->fromClause);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   362
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   363
        if (($whereClause = $AST->whereClause) !== null) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   364
            $sql .= $this->walkWhereClause($whereClause);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   365
        } else if (($discSql = $this->_generateDiscriminatorColumnConditionSQL($this->_rootAliases)) !== '') {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   366
            $sql .= ' WHERE ' . $discSql;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   367
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   368
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   369
        $sql .= $AST->groupByClause ? $this->walkGroupByClause($AST->groupByClause) : '';
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   370
        $sql .= $AST->havingClause ? $this->walkHavingClause($AST->havingClause) : '';
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   371
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   372
        if (($orderByClause = $AST->orderByClause) !== null) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   373
            $sql .= $AST->orderByClause ? $this->walkOrderByClause($AST->orderByClause) : '';
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   374
        } else if (($orderBySql = $this->_generateOrderedCollectionOrderByItems()) !== '') {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   375
            $sql .= ' ORDER BY '.$orderBySql;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   376
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   377
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   378
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   379
        $sql = $this->_platform->modifyLimitQuery(
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   380
            $sql, $this->_query->getMaxResults(), $this->_query->getFirstResult()
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   381
        );
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   382
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   383
        if (($lockMode = $this->_query->getHint(Query::HINT_LOCK_MODE)) !== false) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   384
            if ($lockMode == LockMode::PESSIMISTIC_READ) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   385
                $sql .= " " . $this->_platform->getReadLockSQL();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   386
            } else if ($lockMode == LockMode::PESSIMISTIC_WRITE) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   387
                $sql .= " " . $this->_platform->getWriteLockSQL();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   388
            } else if ($lockMode == LockMode::OPTIMISTIC) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   389
                foreach ($this->_selectedClasses AS $class) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   390
                    if ( ! $class->isVersioned) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   391
                        throw \Doctrine\ORM\OptimisticLockException::lockFailed();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   392
                    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   393
                }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   394
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   395
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   396
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   397
        return $sql;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   398
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   399
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   400
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   401
     * Walks down an UpdateStatement AST node, thereby generating the appropriate SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   402
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   403
     * @param UpdateStatement
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   404
     * @return string The SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   405
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   406
    public function walkUpdateStatement(AST\UpdateStatement $AST)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   407
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   408
        $this->_useSqlTableAliases = false;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   409
        $sql = $this->walkUpdateClause($AST->updateClause);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   410
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   411
        if (($whereClause = $AST->whereClause) !== null) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   412
            $sql .= $this->walkWhereClause($whereClause);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   413
        } else if (($discSql = $this->_generateDiscriminatorColumnConditionSQL($this->_rootAliases)) !== '') {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   414
            $sql .= ' WHERE ' . $discSql;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   415
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   416
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   417
        return $sql;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   418
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   419
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   420
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   421
     * Walks down a DeleteStatement AST node, thereby generating the appropriate SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   422
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   423
     * @param DeleteStatement
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   424
     * @return string The SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   425
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   426
    public function walkDeleteStatement(AST\DeleteStatement $AST)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   427
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   428
        $this->_useSqlTableAliases = false;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   429
        $sql = $this->walkDeleteClause($AST->deleteClause);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   430
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   431
        if (($whereClause = $AST->whereClause) !== null) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   432
            $sql .= $this->walkWhereClause($whereClause);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   433
        } else if (($discSql = $this->_generateDiscriminatorColumnConditionSQL($this->_rootAliases)) !== '') {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   434
            $sql .= ' WHERE ' . $discSql;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   435
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   436
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   437
        return $sql;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   438
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   439
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   440
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   441
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   442
     * Walks down an IdentificationVariable (no AST node associated), thereby generating the SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   443
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   444
     * @param string $identificationVariable
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   445
     * @param string $fieldName
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   446
     * @return string The SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   447
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   448
    public function walkIdentificationVariable($identificationVariable, $fieldName = null)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   449
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   450
        $class = $this->_queryComponents[$identificationVariable]['metadata'];
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   451
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   452
        if (
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   453
            $fieldName !== null && $class->isInheritanceTypeJoined() &&
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   454
            isset($class->fieldMappings[$fieldName]['inherited'])
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   455
        ) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   456
            $class = $this->_em->getClassMetadata($class->fieldMappings[$fieldName]['inherited']);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   457
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   458
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   459
        return $this->getSQLTableAlias($class->table['name'], $identificationVariable);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   460
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   461
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   462
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   463
     * Walks down a PathExpression AST node, thereby generating the appropriate SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   464
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   465
     * @param mixed
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   466
     * @return string The SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   467
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   468
    public function walkPathExpression($pathExpr)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   469
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   470
        $sql = '';
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   471
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   472
        switch ($pathExpr->type) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   473
            case AST\PathExpression::TYPE_STATE_FIELD:
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   474
                $fieldName = $pathExpr->field;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   475
                $dqlAlias = $pathExpr->identificationVariable;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   476
                $class = $this->_queryComponents[$dqlAlias]['metadata'];
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   477
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   478
                if ($this->_useSqlTableAliases) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   479
                    $sql .= $this->walkIdentificationVariable($dqlAlias, $fieldName) . '.';
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   480
                }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   481
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   482
                $sql .= $class->getQuotedColumnName($fieldName, $this->_platform);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   483
                break;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   484
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   485
            case AST\PathExpression::TYPE_SINGLE_VALUED_ASSOCIATION:
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   486
                // 1- the owning side:
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   487
                //    Just use the foreign key, i.e. u.group_id
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   488
                $fieldName = $pathExpr->field;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   489
                $dqlAlias = $pathExpr->identificationVariable;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   490
                $class = $this->_queryComponents[$dqlAlias]['metadata'];
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   491
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   492
                if (isset($class->associationMappings[$fieldName]['inherited'])) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   493
                    $class = $this->_em->getClassMetadata($class->associationMappings[$fieldName]['inherited']);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   494
                }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   495
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   496
                $assoc = $class->associationMappings[$fieldName];
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   497
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   498
                if ($assoc['isOwningSide']) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   499
                    // COMPOSITE KEYS NOT (YET?) SUPPORTED
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   500
                    if (count($assoc['sourceToTargetKeyColumns']) > 1) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   501
                        throw QueryException::associationPathCompositeKeyNotSupported();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   502
                    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   503
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   504
                    if ($this->_useSqlTableAliases) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   505
                        $sql .= $this->getSQLTableAlias($class->table['name'], $dqlAlias) . '.';
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   506
                    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   507
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   508
                    $sql .= reset($assoc['targetToSourceKeyColumns']);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   509
                } else {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   510
                    throw QueryException::associationPathInverseSideNotSupported();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   511
                }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   512
                break;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   513
                
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   514
            default:
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   515
                throw QueryException::invalidPathExpression($pathExpr);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   516
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   517
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   518
        return $sql;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   519
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   520
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   521
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   522
     * Walks down a SelectClause AST node, thereby generating the appropriate SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   523
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   524
     * @param $selectClause
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   525
     * @return string The SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   526
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   527
    public function walkSelectClause($selectClause)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   528
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   529
        $sql = 'SELECT ' . (($selectClause->isDistinct) ? 'DISTINCT ' : '') . implode(
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   530
            ', ', array_filter(array_map(array($this, 'walkSelectExpression'), $selectClause->selectExpressions))
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   531
        );
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   532
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   533
        $addMetaColumns = ! $this->_query->getHint(Query::HINT_FORCE_PARTIAL_LOAD) &&
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   534
                $this->_query->getHydrationMode() == Query::HYDRATE_OBJECT
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   535
                ||
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   536
                $this->_query->getHydrationMode() != Query::HYDRATE_OBJECT &&
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   537
                $this->_query->getHint(Query::HINT_INCLUDE_META_COLUMNS);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   538
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   539
        foreach ($this->_selectedClasses as $dqlAlias => $class) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   540
            // Register as entity or joined entity result
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   541
            if ($this->_queryComponents[$dqlAlias]['relation'] === null) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   542
                $this->_rsm->addEntityResult($class->name, $dqlAlias);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   543
            } else {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   544
                $this->_rsm->addJoinedEntityResult(
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   545
                    $class->name, $dqlAlias,
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   546
                    $this->_queryComponents[$dqlAlias]['parent'],
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   547
                    $this->_queryComponents[$dqlAlias]['relation']['fieldName']
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   548
                );
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   549
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   550
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   551
            if ($class->isInheritanceTypeSingleTable() || $class->isInheritanceTypeJoined()) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   552
                // Add discriminator columns to SQL
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   553
                $rootClass = $this->_em->getClassMetadata($class->rootEntityName);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   554
                $tblAlias = $this->getSQLTableAlias($rootClass->table['name'], $dqlAlias);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   555
                $discrColumn = $rootClass->discriminatorColumn;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   556
                $columnAlias = $this->getSQLColumnAlias($discrColumn['name']);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   557
                $sql .= ", $tblAlias." . $discrColumn['name'] . ' AS ' . $columnAlias;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   558
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   559
                $columnAlias = $this->_platform->getSQLResultCasing($columnAlias);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   560
                $this->_rsm->setDiscriminatorColumn($dqlAlias, $columnAlias);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   561
                $this->_rsm->addMetaResult($dqlAlias, $columnAlias, $discrColumn['fieldName']);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   562
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   563
                // Add foreign key columns to SQL, if necessary
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   564
                if ($addMetaColumns) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   565
                    //FIXME: Include foreign key columns of child classes also!!??
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   566
                    foreach ($class->associationMappings as $assoc) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   567
                        if ($assoc['isOwningSide'] && $assoc['type'] & ClassMetadata::TO_ONE) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   568
                            if (isset($assoc['inherited'])) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   569
                                $owningClass = $this->_em->getClassMetadata($assoc['inherited']);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   570
                                $sqlTableAlias = $this->getSQLTableAlias($owningClass->table['name'], $dqlAlias);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   571
                            } else {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   572
                                $sqlTableAlias = $this->getSQLTableAlias($class->table['name'], $dqlAlias);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   573
                            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   574
                            
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   575
                            foreach ($assoc['targetToSourceKeyColumns'] as $srcColumn) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   576
                                $columnAlias = $this->getSQLColumnAlias($srcColumn);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   577
                                $sql .= ", $sqlTableAlias." . $srcColumn . ' AS ' . $columnAlias;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   578
                                $columnAlias = $this->_platform->getSQLResultCasing($columnAlias);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   579
                                $this->_rsm->addMetaResult($dqlAlias, $this->_platform->getSQLResultCasing($columnAlias), $srcColumn, (isset($assoc['id']) && $assoc['id'] === true));
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   580
                            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   581
                        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   582
                    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   583
                }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   584
            } else {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   585
                // Add foreign key columns to SQL, if necessary
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   586
                if ($addMetaColumns) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   587
                    $sqlTableAlias = $this->getSQLTableAlias($class->table['name'], $dqlAlias);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   588
                    foreach ($class->associationMappings as $assoc) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   589
                        if ($assoc['isOwningSide'] && $assoc['type'] & ClassMetadata::TO_ONE) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   590
                            foreach ($assoc['targetToSourceKeyColumns'] as $srcColumn) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   591
                                $columnAlias = $this->getSQLColumnAlias($srcColumn);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   592
                                $sql .= ', ' . $sqlTableAlias . '.' . $srcColumn . ' AS ' . $columnAlias;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   593
                                $columnAlias = $this->_platform->getSQLResultCasing($columnAlias);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   594
                                $this->_rsm->addMetaResult($dqlAlias, $this->_platform->getSQLResultCasing($columnAlias), $srcColumn, (isset($assoc['id']) && $assoc['id'] === true));
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   595
                            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   596
                        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   597
                    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   598
                }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   599
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   600
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   601
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   602
        return $sql;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   603
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   604
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   605
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   606
     * Walks down a FromClause AST node, thereby generating the appropriate SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   607
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   608
     * @return string The SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   609
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   610
    public function walkFromClause($fromClause)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   611
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   612
        $identificationVarDecls = $fromClause->identificationVariableDeclarations;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   613
        $sqlParts = array();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   614
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   615
        foreach ($identificationVarDecls as $identificationVariableDecl) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   616
            $sql = '';
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   617
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   618
            $rangeDecl = $identificationVariableDecl->rangeVariableDeclaration;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   619
            $dqlAlias = $rangeDecl->aliasIdentificationVariable;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   620
        
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   621
            $this->_rootAliases[] = $dqlAlias;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   622
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   623
            $class = $this->_em->getClassMetadata($rangeDecl->abstractSchemaName);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   624
            $sql .= $class->getQuotedTableName($this->_platform) . ' '
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   625
                  . $this->getSQLTableAlias($class->table['name'], $dqlAlias);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   626
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   627
            if ($class->isInheritanceTypeJoined()) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   628
                $sql .= $this->_generateClassTableInheritanceJoins($class, $dqlAlias);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   629
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   630
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   631
            foreach ($identificationVariableDecl->joinVariableDeclarations as $joinVarDecl) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   632
                $sql .= $this->walkJoinVariableDeclaration($joinVarDecl);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   633
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   634
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   635
            if ($identificationVariableDecl->indexBy) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   636
                $this->_rsm->addIndexBy(
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   637
                    $identificationVariableDecl->indexBy->simpleStateFieldPathExpression->identificationVariable,
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   638
                    $identificationVariableDecl->indexBy->simpleStateFieldPathExpression->field
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   639
                );
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   640
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   641
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   642
            $sqlParts[] = $this->_platform->appendLockHint($sql, $this->_query->getHint(Query::HINT_LOCK_MODE));
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   643
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   644
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   645
        return ' FROM ' . implode(', ', $sqlParts);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   646
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   647
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   648
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   649
     * Walks down a FunctionNode AST node, thereby generating the appropriate SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   650
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   651
     * @return string The SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   652
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   653
    public function walkFunction($function)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   654
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   655
        return $function->getSql($this);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   656
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   657
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   658
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   659
     * Walks down an OrderByClause AST node, thereby generating the appropriate SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   660
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   661
     * @param OrderByClause
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   662
     * @return string The SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   663
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   664
    public function walkOrderByClause($orderByClause)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   665
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   666
        $colSql = $this->_generateOrderedCollectionOrderByItems();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   667
        if ($colSql != '') {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   668
            $colSql = ", ".$colSql;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   669
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   670
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   671
        // OrderByClause ::= "ORDER" "BY" OrderByItem {"," OrderByItem}*
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   672
        return ' ORDER BY ' . implode(
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   673
            ', ', array_map(array($this, 'walkOrderByItem'), $orderByClause->orderByItems)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   674
        )  . $colSql;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   675
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   676
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   677
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   678
     * Walks down an OrderByItem AST node, thereby generating the appropriate SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   679
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   680
     * @param OrderByItem
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   681
     * @return string The SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   682
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   683
    public function walkOrderByItem($orderByItem)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   684
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   685
        $sql = '';
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   686
        $expr = $orderByItem->expression;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   687
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   688
        if ($expr instanceof AST\PathExpression) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   689
            $sql = $this->walkPathExpression($expr);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   690
        } else {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   691
            $columnName = $this->_queryComponents[$expr]['token']['value'];
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   692
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   693
            $sql = $this->_scalarResultAliasMap[$columnName];
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   694
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   695
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   696
        return $sql . ' ' . strtoupper($orderByItem->type);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   697
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   698
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   699
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   700
     * Walks down a HavingClause AST node, thereby generating the appropriate SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   701
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   702
     * @param HavingClause
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   703
     * @return string The SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   704
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   705
    public function walkHavingClause($havingClause)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   706
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   707
        return ' HAVING ' . $this->walkConditionalExpression($havingClause->conditionalExpression);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   708
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   709
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   710
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   711
     * Walks down a JoinVariableDeclaration AST node and creates the corresponding SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   712
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   713
     * @param JoinVariableDeclaration $joinVarDecl
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   714
     * @return string The SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   715
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   716
    public function walkJoinVariableDeclaration($joinVarDecl)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   717
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   718
        $join = $joinVarDecl->join;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   719
        $joinType = $join->joinType;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   720
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   721
        if ($joinVarDecl->indexBy) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   722
            // For Many-To-One or One-To-One associations this obviously makes no sense, but is ignored silently.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   723
            $this->_rsm->addIndexBy(
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   724
                $joinVarDecl->indexBy->simpleStateFieldPathExpression->identificationVariable,
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   725
                $joinVarDecl->indexBy->simpleStateFieldPathExpression->field
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   726
            );
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   727
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   728
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   729
        if ($joinType == AST\Join::JOIN_TYPE_LEFT || $joinType == AST\Join::JOIN_TYPE_LEFTOUTER) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   730
            $sql = ' LEFT JOIN ';
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   731
        } else {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   732
            $sql = ' INNER JOIN ';
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   733
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   734
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   735
        $joinAssocPathExpr = $join->joinAssociationPathExpression;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   736
        $joinedDqlAlias = $join->aliasIdentificationVariable;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   737
        $relation = $this->_queryComponents[$joinedDqlAlias]['relation'];
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   738
        $targetClass = $this->_em->getClassMetadata($relation['targetEntity']);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   739
        $sourceClass = $this->_em->getClassMetadata($relation['sourceEntity']);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   740
        $targetTableName = $targetClass->getQuotedTableName($this->_platform);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   741
        $targetTableAlias = $this->getSQLTableAlias($targetClass->table['name'], $joinedDqlAlias);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   742
        $sourceTableAlias = $this->getSQLTableAlias($sourceClass->table['name'], $joinAssocPathExpr->identificationVariable);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   743
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   744
        // Ensure we got the owning side, since it has all mapping info
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   745
        $assoc = ( ! $relation['isOwningSide']) ? $targetClass->associationMappings[$relation['mappedBy']] : $relation;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   746
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   747
        if ($this->_query->getHint(Query::HINT_INTERNAL_ITERATION) == true) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   748
            if ($relation['type'] == ClassMetadata::ONE_TO_MANY || $relation['type'] == ClassMetadata::MANY_TO_MANY) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   749
                throw QueryException::iterateWithFetchJoinNotAllowed($assoc);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   750
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   751
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   752
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   753
        if ($joinVarDecl->indexBy) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   754
            // For Many-To-One or One-To-One associations this obviously makes no sense, but is ignored silently.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   755
            $this->_rsm->addIndexBy(
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   756
                $joinVarDecl->indexBy->simpleStateFieldPathExpression->identificationVariable,
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   757
                $joinVarDecl->indexBy->simpleStateFieldPathExpression->field
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   758
            );
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   759
        } else if (isset($relation['indexBy'])) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   760
            $this->_rsm->addIndexBy($joinedDqlAlias, $relation['indexBy']);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   761
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   762
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   763
        // This condition is not checking ClassMetadata::MANY_TO_ONE, because by definition it cannot
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   764
        // be the owning side and previously we ensured that $assoc is always the owning side of the associations.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   765
        // The owning side is necessary at this point because only it contains the JoinColumn information.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   766
        if ($assoc['type'] & ClassMetadata::TO_ONE) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   767
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   768
            $sql .= $targetTableName . ' ' . $targetTableAlias . ' ON ';
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   769
            $first = true;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   770
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   771
            foreach ($assoc['sourceToTargetKeyColumns'] as $sourceColumn => $targetColumn) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   772
                if ( ! $first) $sql .= ' AND '; else $first = false;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   773
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   774
                if ($relation['isOwningSide']) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   775
                    if ($targetClass->containsForeignIdentifier && !isset($targetClass->fieldNames[$targetColumn])) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   776
                        $quotedTargetColumn = $targetColumn; // Join columns cannot be quoted.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   777
                    } else {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   778
                        $quotedTargetColumn = $targetClass->getQuotedColumnName($targetClass->fieldNames[$targetColumn], $this->_platform);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   779
                    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   780
                    $sql .= $sourceTableAlias . '.' . $sourceColumn . ' = ' . $targetTableAlias . '.' . $quotedTargetColumn;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   781
                } else {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   782
                    if ($sourceClass->containsForeignIdentifier && !isset($sourceClass->fieldNames[$targetColumn])) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   783
                        $quotedTargetColumn = $targetColumn; // Join columns cannot be quoted.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   784
                    } else {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   785
                        $quotedTargetColumn = $sourceClass->getQuotedColumnName($sourceClass->fieldNames[$targetColumn], $this->_platform);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   786
                    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   787
                    $sql .= $sourceTableAlias . '.' . $quotedTargetColumn . ' = ' . $targetTableAlias . '.' . $sourceColumn;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   788
                }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   789
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   790
        } else if ($assoc['type'] == ClassMetadata::MANY_TO_MANY) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   791
            // Join relation table
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   792
            $joinTable = $assoc['joinTable'];
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   793
            $joinTableAlias = $this->getSQLTableAlias($joinTable['name'], $joinedDqlAlias);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   794
            $sql .= $sourceClass->getQuotedJoinTableName($assoc, $this->_platform) . ' ' . $joinTableAlias . ' ON ';
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   795
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   796
            $first = true;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   797
            if ($relation['isOwningSide']) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   798
                foreach ($assoc['relationToSourceKeyColumns'] as $relationColumn => $sourceColumn) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   799
                    if ( ! $first) $sql .= ' AND '; else $first = false;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   800
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   801
                    if ($sourceClass->containsForeignIdentifier && !isset($sourceClass->fieldNames[$sourceColumn])) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   802
                        $quotedTargetColumn = $sourceColumn; // Join columns cannot be quoted.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   803
                    } else {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   804
                        $quotedTargetColumn = $sourceClass->getQuotedColumnName($sourceClass->fieldNames[$sourceColumn], $this->_platform);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   805
                    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   806
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   807
                    $sql .= $sourceTableAlias . '.' . $quotedTargetColumn . ' = ' . $joinTableAlias . '.' . $relationColumn;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   808
                }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   809
            } else {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   810
                foreach ($assoc['relationToTargetKeyColumns'] as $relationColumn => $targetColumn) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   811
                    if ( ! $first) $sql .= ' AND '; else $first = false;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   812
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   813
                    if ($sourceClass->containsForeignIdentifier && !isset($sourceClass->fieldNames[$targetColumn])) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   814
                        $quotedTargetColumn = $targetColumn; // Join columns cannot be quoted.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   815
                    } else {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   816
                        $quotedTargetColumn = $sourceClass->getQuotedColumnName($sourceClass->fieldNames[$targetColumn], $this->_platform);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   817
                    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   818
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   819
                    $sql .= $sourceTableAlias . '.' . $quotedTargetColumn . ' = ' . $joinTableAlias . '.' . $relationColumn;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   820
                }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   821
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   822
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   823
            // Join target table
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   824
            $sql .= ($joinType == AST\Join::JOIN_TYPE_LEFT || $joinType == AST\Join::JOIN_TYPE_LEFTOUTER)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   825
            	? ' LEFT JOIN ' : ' INNER JOIN ';
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   826
            $sql .= $targetTableName . ' ' . $targetTableAlias . ' ON ';
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   827
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   828
            $first = true;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   829
            if ($relation['isOwningSide']) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   830
                foreach ($assoc['relationToTargetKeyColumns'] as $relationColumn => $targetColumn) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   831
                    if ( ! $first) $sql .= ' AND '; else $first = false;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   832
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   833
                    if ($targetClass->containsForeignIdentifier && !isset($targetClass->fieldNames[$targetColumn])) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   834
                        $quotedTargetColumn = $targetColumn; // Join columns cannot be quoted.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   835
                    } else {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   836
                        $quotedTargetColumn = $targetClass->getQuotedColumnName($targetClass->fieldNames[$targetColumn], $this->_platform);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   837
                    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   838
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   839
                    $sql .= $targetTableAlias . '.' . $quotedTargetColumn . ' = ' . $joinTableAlias . '.' . $relationColumn;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   840
                }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   841
            } else {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   842
                foreach ($assoc['relationToSourceKeyColumns'] as $relationColumn => $sourceColumn) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   843
                    if ( ! $first) $sql .= ' AND '; else $first = false;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   844
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   845
                    if ($targetClass->containsForeignIdentifier && !isset($targetClass->fieldNames[$sourceColumn])) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   846
                        $quotedTargetColumn = $sourceColumn; // Join columns cannot be quoted.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   847
                    } else {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   848
                        $quotedTargetColumn = $targetClass->getQuotedColumnName($targetClass->fieldNames[$sourceColumn], $this->_platform);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   849
                    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   850
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   851
                    $sql .= $targetTableAlias . '.' . $quotedTargetColumn . ' = ' . $joinTableAlias . '.' . $relationColumn;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   852
                }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   853
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   854
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   855
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   856
        // Handle WITH clause
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   857
        if (($condExpr = $join->conditionalExpression) !== null) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   858
            // Phase 2 AST optimization: Skip processment of ConditionalExpression
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   859
            // if only one ConditionalTerm is defined
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   860
            $sql .= ' AND (' . $this->walkConditionalExpression($condExpr) . ')';
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   861
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   862
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   863
        $discrSql = $this->_generateDiscriminatorColumnConditionSQL(array($joinedDqlAlias));
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   864
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   865
        if ($discrSql) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   866
            $sql .= ' AND ' . $discrSql;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   867
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   868
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   869
        // FIXME: these should either be nested or all forced to be left joins (DDC-XXX)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   870
        if ($targetClass->isInheritanceTypeJoined()) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   871
            $sql .= $this->_generateClassTableInheritanceJoins($targetClass, $joinedDqlAlias);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   872
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   873
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   874
        return $sql;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   875
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   876
    
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   877
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   878
     * Walks down a CoalesceExpression AST node and generates the corresponding SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   879
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   880
     * @param CoalesceExpression $coalesceExpression
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   881
     * @return string The SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   882
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   883
    public function walkCoalesceExpression($coalesceExpression)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   884
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   885
        $sql = 'COALESCE(';
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   886
        
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   887
        $scalarExpressions = array();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   888
        
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   889
        foreach ($coalesceExpression->scalarExpressions as $scalarExpression) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   890
            $scalarExpressions[] = $this->walkSimpleArithmeticExpression($scalarExpression);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   891
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   892
        
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   893
        $sql .= implode(', ', $scalarExpressions) . ')';
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   894
        
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   895
        return $sql;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   896
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   897
    
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   898
    public function walkCaseExpression($expression)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   899
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   900
        switch (true) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   901
            case ($expression instanceof AST\CoalesceExpression):
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   902
                return $this->walkCoalesceExpression($expression);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   903
                
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   904
            case ($expression instanceof AST\NullIfExpression):
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   905
                return $this->walkNullIfExpression($expression);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   906
                
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   907
            default:
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   908
                return '';
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   909
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   910
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   911
    
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   912
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   913
     * Walks down a NullIfExpression AST node and generates the corresponding SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   914
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   915
     * @param NullIfExpression $nullIfExpression
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   916
     * @return string The SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   917
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   918
    public function walkNullIfExpression($nullIfExpression)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   919
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   920
        $firstExpression = is_string($nullIfExpression->firstExpression) 
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   921
            ? $this->_conn->quote($nullIfExpression->firstExpression)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   922
            : $this->walkSimpleArithmeticExpression($nullIfExpression->firstExpression);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   923
        
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   924
        $secondExpression = is_string($nullIfExpression->secondExpression) 
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   925
            ? $this->_conn->quote($nullIfExpression->secondExpression)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   926
            : $this->walkSimpleArithmeticExpression($nullIfExpression->secondExpression);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   927
        
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   928
        return 'NULLIF(' . $firstExpression . ', ' . $secondExpression . ')';
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   929
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   930
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   931
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   932
     * Walks down a SelectExpression AST node and generates the corresponding SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   933
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   934
     * @param SelectExpression $selectExpression
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   935
     * @return string The SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   936
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   937
    public function walkSelectExpression($selectExpression)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   938
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   939
        $sql = '';
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   940
        $expr = $selectExpression->expression;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   941
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   942
        if ($expr instanceof AST\PathExpression) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   943
            if ($expr->type == AST\PathExpression::TYPE_STATE_FIELD) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   944
                $fieldName = $expr->field;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   945
                $dqlAlias = $expr->identificationVariable;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   946
                $qComp = $this->_queryComponents[$dqlAlias];
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   947
                $class = $qComp['metadata'];
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   948
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   949
                if ( ! $selectExpression->fieldIdentificationVariable) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   950
                    $resultAlias = $fieldName;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   951
                } else {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   952
                    $resultAlias = $selectExpression->fieldIdentificationVariable;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   953
                }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   954
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   955
                if ($class->isInheritanceTypeJoined()) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   956
                    $tableName = $this->_em->getUnitOfWork()->getEntityPersister($class->name)->getOwningTable($fieldName);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   957
                } else {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   958
                    $tableName = $class->getTableName();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   959
                }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   960
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   961
                $sqlTableAlias = $this->getSQLTableAlias($tableName, $dqlAlias);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   962
                $columnName = $class->getQuotedColumnName($fieldName, $this->_platform);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   963
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   964
                $columnAlias = $this->getSQLColumnAlias($columnName);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   965
                $sql .= $sqlTableAlias . '.' . $columnName . ' AS ' . $columnAlias;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   966
                $columnAlias = $this->_platform->getSQLResultCasing($columnAlias);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   967
                $this->_rsm->addScalarResult($columnAlias, $resultAlias);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   968
            } else {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   969
                throw QueryException::invalidPathExpression($expr->type);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   970
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   971
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   972
        else if ($expr instanceof AST\AggregateExpression) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   973
            if ( ! $selectExpression->fieldIdentificationVariable) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   974
                $resultAlias = $this->_scalarResultCounter++;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   975
            } else {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   976
                $resultAlias = $selectExpression->fieldIdentificationVariable;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   977
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   978
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   979
            $columnAlias = 'sclr' . $this->_aliasCounter++;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   980
            $sql .= $this->walkAggregateExpression($expr) . ' AS ' . $columnAlias;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   981
            $this->_scalarResultAliasMap[$resultAlias] = $columnAlias;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   982
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   983
            $columnAlias = $this->_platform->getSQLResultCasing($columnAlias);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   984
            $this->_rsm->addScalarResult($columnAlias, $resultAlias);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   985
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   986
        else if ($expr instanceof AST\Subselect) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   987
            if ( ! $selectExpression->fieldIdentificationVariable) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   988
                $resultAlias = $this->_scalarResultCounter++;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   989
            } else {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   990
                $resultAlias = $selectExpression->fieldIdentificationVariable;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   991
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   992
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   993
            $columnAlias = 'sclr' . $this->_aliasCounter++;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   994
            $sql .= '(' . $this->walkSubselect($expr) . ') AS '.$columnAlias;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   995
            $this->_scalarResultAliasMap[$resultAlias] = $columnAlias;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   996
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   997
            $columnAlias = $this->_platform->getSQLResultCasing($columnAlias);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   998
            $this->_rsm->addScalarResult($columnAlias, $resultAlias);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   999
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1000
        else if ($expr instanceof AST\Functions\FunctionNode) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1001
            if ( ! $selectExpression->fieldIdentificationVariable) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1002
                $resultAlias = $this->_scalarResultCounter++;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1003
            } else {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1004
                $resultAlias = $selectExpression->fieldIdentificationVariable;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1005
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1006
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1007
            $columnAlias = 'sclr' . $this->_aliasCounter++;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1008
            $sql .= $this->walkFunction($expr) . ' AS ' . $columnAlias;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1009
            $this->_scalarResultAliasMap[$resultAlias] = $columnAlias;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1010
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1011
            $columnAlias = $this->_platform->getSQLResultCasing($columnAlias);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1012
            $this->_rsm->addScalarResult($columnAlias, $resultAlias);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1013
        } else if (
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1014
            $expr instanceof AST\SimpleArithmeticExpression ||
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1015
            $expr instanceof AST\ArithmeticTerm ||
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1016
            $expr instanceof AST\ArithmeticFactor ||
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1017
            $expr instanceof AST\ArithmeticPrimary ||
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1018
            $expr instanceof AST\Literal
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1019
        ) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1020
            if ( ! $selectExpression->fieldIdentificationVariable) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1021
                $resultAlias = $this->_scalarResultCounter++;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1022
            } else {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1023
                $resultAlias = $selectExpression->fieldIdentificationVariable;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1024
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1025
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1026
            $columnAlias = 'sclr' . $this->_aliasCounter++;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1027
            
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1028
            if ($expr instanceof AST\Literal) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1029
                $sql .= $this->walkLiteral($expr) . ' AS ' .$columnAlias;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1030
            } else {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1031
                $sql .= $this->walkSimpleArithmeticExpression($expr) . ' AS ' . $columnAlias;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1032
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1033
            
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1034
            $this->_scalarResultAliasMap[$resultAlias] = $columnAlias;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1035
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1036
            $columnAlias = $this->_platform->getSQLResultCasing($columnAlias);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1037
            $this->_rsm->addScalarResult($columnAlias, $resultAlias);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1038
        } else if (
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1039
            $expr instanceof AST\NullIfExpression ||
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1040
            $expr instanceof AST\CoalesceExpression ||
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1041
            $expr instanceof AST\CaseExpression
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1042
        ) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1043
            if ( ! $selectExpression->fieldIdentificationVariable) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1044
                $resultAlias = $this->_scalarResultCounter++;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1045
            } else {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1046
                $resultAlias = $selectExpression->fieldIdentificationVariable;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1047
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1048
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1049
            $columnAlias = 'sclr' . $this->_aliasCounter++;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1050
            
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1051
            $sql .= $this->walkCaseExpression($expr) . ' AS ' . $columnAlias;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1052
            
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1053
            $this->_scalarResultAliasMap[$resultAlias] = $columnAlias;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1054
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1055
            $columnAlias = $this->_platform->getSQLResultCasing($columnAlias);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1056
            $this->_rsm->addScalarResult($columnAlias, $resultAlias);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1057
        } else {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1058
            // IdentificationVariable or PartialObjectExpression
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1059
            if ($expr instanceof AST\PartialObjectExpression) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1060
                $dqlAlias = $expr->identificationVariable;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1061
                $partialFieldSet = $expr->partialFieldSet;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1062
            } else {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1063
                $dqlAlias = $expr;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1064
                $partialFieldSet = array();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1065
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1066
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1067
            $queryComp = $this->_queryComponents[$dqlAlias];
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1068
            $class = $queryComp['metadata'];
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1069
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1070
            if ( ! isset($this->_selectedClasses[$dqlAlias])) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1071
                $this->_selectedClasses[$dqlAlias] = $class;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1072
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1073
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1074
            $beginning = true;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1075
            // Select all fields from the queried class
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1076
            foreach ($class->fieldMappings as $fieldName => $mapping) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1077
                if ($partialFieldSet && !in_array($fieldName, $partialFieldSet)) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1078
                    continue;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1079
                }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1080
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1081
                if (isset($mapping['inherited'])) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1082
                    $tableName = $this->_em->getClassMetadata($mapping['inherited'])->table['name'];
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1083
                } else {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1084
                    $tableName = $class->table['name'];
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1085
                }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1086
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1087
                if ($beginning) $beginning = false; else $sql .= ', ';
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1088
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1089
                $sqlTableAlias = $this->getSQLTableAlias($tableName, $dqlAlias);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1090
                $columnAlias = $this->getSQLColumnAlias($mapping['columnName']);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1091
                $sql .= $sqlTableAlias . '.' . $class->getQuotedColumnName($fieldName, $this->_platform)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1092
                      . ' AS ' . $columnAlias;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1093
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1094
                $columnAlias = $this->_platform->getSQLResultCasing($columnAlias);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1095
                $this->_rsm->addFieldResult($dqlAlias, $columnAlias, $fieldName, $class->name);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1096
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1097
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1098
            // Add any additional fields of subclasses (excluding inherited fields)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1099
            // 1) on Single Table Inheritance: always, since its marginal overhead
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1100
            // 2) on Class Table Inheritance only if partial objects are disallowed,
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1101
            //    since it requires outer joining subtables.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1102
            if ($class->isInheritanceTypeSingleTable() || ! $this->_query->getHint(Query::HINT_FORCE_PARTIAL_LOAD)) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1103
                foreach ($class->subClasses as $subClassName) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1104
                    $subClass = $this->_em->getClassMetadata($subClassName);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1105
                    $sqlTableAlias = $this->getSQLTableAlias($subClass->table['name'], $dqlAlias);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1106
                    foreach ($subClass->fieldMappings as $fieldName => $mapping) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1107
                        if (isset($mapping['inherited']) || $partialFieldSet && !in_array($fieldName, $partialFieldSet)) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1108
                            continue;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1109
                        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1110
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1111
                        if ($beginning) $beginning = false; else $sql .= ', ';
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1112
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1113
                        $columnAlias = $this->getSQLColumnAlias($mapping['columnName']);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1114
                        $sql .= $sqlTableAlias . '.' . $subClass->getQuotedColumnName($fieldName, $this->_platform)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1115
                                . ' AS ' . $columnAlias;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1116
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1117
                        $columnAlias = $this->_platform->getSQLResultCasing($columnAlias);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1118
                        $this->_rsm->addFieldResult($dqlAlias, $columnAlias, $fieldName, $subClassName);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1119
                    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1120
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1121
                    // Add join columns (foreign keys) of the subclass
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1122
                    //TODO: Probably better do this in walkSelectClause to honor the INCLUDE_META_COLUMNS hint
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1123
                    foreach ($subClass->associationMappings as $fieldName => $assoc) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1124
                        if ($assoc['isOwningSide'] && $assoc['type'] & ClassMetadata::TO_ONE && ! isset($assoc['inherited'])) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1125
                            foreach ($assoc['targetToSourceKeyColumns'] as $srcColumn) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1126
                                if ($beginning) $beginning = false; else $sql .= ', ';
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1127
                                $columnAlias = $this->getSQLColumnAlias($srcColumn);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1128
                                $sql .= $sqlTableAlias . '.' . $srcColumn . ' AS ' . $columnAlias;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1129
                                $this->_rsm->addMetaResult($dqlAlias, $this->_platform->getSQLResultCasing($columnAlias), $srcColumn);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1130
                            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1131
                        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1132
                    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1133
                }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1134
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1135
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1136
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1137
        return $sql;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1138
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1139
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1140
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1141
     * Walks down a QuantifiedExpression AST node, thereby generating the appropriate SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1142
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1143
     * @param QuantifiedExpression
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1144
     * @return string The SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1145
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1146
    public function walkQuantifiedExpression($qExpr)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1147
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1148
        return ' ' . strtoupper($qExpr->type)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1149
             . '(' . $this->walkSubselect($qExpr->subselect) . ')';
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1150
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1151
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1152
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1153
     * Walks down a Subselect AST node, thereby generating the appropriate SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1154
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1155
     * @param Subselect
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1156
     * @return string The SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1157
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1158
    public function walkSubselect($subselect)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1159
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1160
        $useAliasesBefore = $this->_useSqlTableAliases;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1161
        $this->_useSqlTableAliases = true;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1162
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1163
        $sql = $this->walkSimpleSelectClause($subselect->simpleSelectClause);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1164
        $sql .= $this->walkSubselectFromClause($subselect->subselectFromClause);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1165
        $sql .= $subselect->whereClause ? $this->walkWhereClause($subselect->whereClause) : '';
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1166
        $sql .= $subselect->groupByClause ? $this->walkGroupByClause($subselect->groupByClause) : '';
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1167
        $sql .= $subselect->havingClause ? $this->walkHavingClause($subselect->havingClause) : '';
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1168
        $sql .= $subselect->orderByClause ? $this->walkOrderByClause($subselect->orderByClause) : '';
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1169
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1170
        $this->_useSqlTableAliases = $useAliasesBefore;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1171
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1172
        return $sql;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1173
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1174
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1175
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1176
     * Walks down a SubselectFromClause AST node, thereby generating the appropriate SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1177
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1178
     * @param SubselectFromClause
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1179
     * @return string The SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1180
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1181
    public function walkSubselectFromClause($subselectFromClause)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1182
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1183
        $identificationVarDecls = $subselectFromClause->identificationVariableDeclarations;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1184
        $sqlParts = array ();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1185
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1186
        foreach ($identificationVarDecls as $subselectIdVarDecl) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1187
            $sql = '';
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1188
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1189
            $rangeDecl = $subselectIdVarDecl->rangeVariableDeclaration;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1190
            $dqlAlias = $rangeDecl->aliasIdentificationVariable;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1191
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1192
            $class = $this->_em->getClassMetadata($rangeDecl->abstractSchemaName);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1193
            $sql .= $class->getQuotedTableName($this->_platform) . ' '
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1194
                  . $this->getSQLTableAlias($class->table['name'], $dqlAlias);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1195
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1196
            if ($class->isInheritanceTypeJoined()) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1197
                $sql .= $this->_generateClassTableInheritanceJoins($class, $dqlAlias);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1198
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1199
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1200
            foreach ($subselectIdVarDecl->joinVariableDeclarations as $joinVarDecl) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1201
                $sql .= $this->walkJoinVariableDeclaration($joinVarDecl);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1202
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1203
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1204
            $sqlParts[] = $this->_platform->appendLockHint($sql, $this->_query->getHint(Query::HINT_LOCK_MODE));
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1205
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1206
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1207
        return ' FROM ' . implode(', ', $sqlParts);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1208
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1209
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1210
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1211
     * Walks down a SimpleSelectClause AST node, thereby generating the appropriate SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1212
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1213
     * @param SimpleSelectClause
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1214
     * @return string The SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1215
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1216
    public function walkSimpleSelectClause($simpleSelectClause)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1217
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1218
        return 'SELECT' . ($simpleSelectClause->isDistinct ? ' DISTINCT' : '')
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1219
             . $this->walkSimpleSelectExpression($simpleSelectClause->simpleSelectExpression);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1220
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1221
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1222
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1223
     * Walks down a SimpleSelectExpression AST node, thereby generating the appropriate SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1224
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1225
     * @param SimpleSelectExpression
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1226
     * @return string The SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1227
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1228
    public function walkSimpleSelectExpression($simpleSelectExpression)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1229
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1230
        $sql = '';
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1231
        $expr = $simpleSelectExpression->expression;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1232
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1233
        if ($expr instanceof AST\PathExpression) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1234
            $sql .= $this->walkPathExpression($expr);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1235
        } else if ($expr instanceof AST\AggregateExpression) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1236
            if ( ! $simpleSelectExpression->fieldIdentificationVariable) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1237
                $alias = $this->_scalarResultCounter++;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1238
            } else {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1239
                $alias = $simpleSelectExpression->fieldIdentificationVariable;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1240
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1241
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1242
            $sql .= $this->walkAggregateExpression($expr) . ' AS dctrn__' . $alias;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1243
        } else if ($expr instanceof AST\Subselect) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1244
            if ( ! $simpleSelectExpression->fieldIdentificationVariable) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1245
                $alias = $this->_scalarResultCounter++;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1246
            } else {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1247
                $alias = $simpleSelectExpression->fieldIdentificationVariable;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1248
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1249
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1250
            $columnAlias = 'sclr' . $this->_aliasCounter++;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1251
            $sql .= '(' . $this->walkSubselect($expr) . ') AS ' . $columnAlias;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1252
            $this->_scalarResultAliasMap[$alias] = $columnAlias;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1253
        } else if ($expr instanceof AST\Functions\FunctionNode) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1254
            if ( ! $simpleSelectExpression->fieldIdentificationVariable) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1255
                $alias = $this->_scalarResultCounter++;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1256
            } else {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1257
                $alias = $simpleSelectExpression->fieldIdentificationVariable;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1258
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1259
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1260
            $columnAlias = 'sclr' . $this->_aliasCounter++;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1261
            $sql .= $this->walkFunction($expr) . ' AS ' . $columnAlias;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1262
            $this->_scalarResultAliasMap[$alias] = $columnAlias;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1263
        } else if (
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1264
            $expr instanceof AST\SimpleArithmeticExpression ||
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1265
            $expr instanceof AST\ArithmeticTerm ||
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1266
            $expr instanceof AST\ArithmeticFactor ||
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1267
            $expr instanceof AST\ArithmeticPrimary
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1268
        ) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1269
            if ( ! $simpleSelectExpression->fieldIdentificationVariable) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1270
                $alias = $this->_scalarResultCounter++;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1271
            } else {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1272
                $alias = $simpleSelectExpression->fieldIdentificationVariable;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1273
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1274
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1275
            $columnAlias = 'sclr' . $this->_aliasCounter++;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1276
            $sql .= $this->walkSimpleArithmeticExpression($expr) . ' AS ' . $columnAlias;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1277
            $this->_scalarResultAliasMap[$alias] = $columnAlias;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1278
        } else {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1279
            // IdentificationVariable
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1280
            $class = $this->_queryComponents[$expr]['metadata'];
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1281
            $tableAlias = $this->getSQLTableAlias($class->getTableName(), $expr);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1282
            $first = true;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1283
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1284
            foreach ($class->identifier as $identifier) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1285
                if ($first) $first = false; else $sql .= ', ';
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1286
                $sql .= $tableAlias . '.' . $class->getQuotedColumnName($identifier, $this->_platform);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1287
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1288
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1289
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1290
        return ' ' . $sql;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1291
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1292
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1293
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1294
     * Walks down an AggregateExpression AST node, thereby generating the appropriate SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1295
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1296
     * @param AggregateExpression
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1297
     * @return string The SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1298
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1299
    public function walkAggregateExpression($aggExpression)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1300
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1301
        return $aggExpression->functionName . '(' . ($aggExpression->isDistinct ? 'DISTINCT ' : '')
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1302
             . $this->walkSimpleArithmeticExpression($aggExpression->pathExpression) . ')';
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1303
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1304
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1305
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1306
     * Walks down a GroupByClause AST node, thereby generating the appropriate SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1307
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1308
     * @param GroupByClause
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1309
     * @return string The SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1310
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1311
    public function walkGroupByClause($groupByClause)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1312
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1313
        $sql = '';
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1314
        foreach ($groupByClause->groupByItems AS $groupByItem) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1315
            if (is_string($groupByItem)) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1316
                foreach ($this->_queryComponents[$groupByItem]['metadata']->identifier AS $idField) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1317
                    if ($sql != '') {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1318
                        $sql .= ', ';
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1319
                    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1320
                    $groupByItem = new AST\PathExpression(AST\PathExpression::TYPE_STATE_FIELD, $groupByItem, $idField);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1321
                    $groupByItem->type = AST\PathExpression::TYPE_STATE_FIELD;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1322
                    $sql .= $this->walkGroupByItem($groupByItem);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1323
                }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1324
            } else {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1325
                if ($sql != '') {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1326
                    $sql .= ', ';
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1327
                }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1328
                $sql .= $this->walkGroupByItem($groupByItem);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1329
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1330
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1331
        return ' GROUP BY ' . $sql;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1332
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1333
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1334
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1335
     * Walks down a GroupByItem AST node, thereby generating the appropriate SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1336
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1337
     * @param GroupByItem
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1338
     * @return string The SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1339
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1340
    public function walkGroupByItem(AST\PathExpression $pathExpr)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1341
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1342
        return $this->walkPathExpression($pathExpr);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1343
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1344
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1345
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1346
     * Walks down a DeleteClause AST node, thereby generating the appropriate SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1347
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1348
     * @param DeleteClause
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1349
     * @return string The SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1350
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1351
    public function walkDeleteClause(AST\DeleteClause $deleteClause)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1352
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1353
        $sql = 'DELETE FROM ';
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1354
        $class = $this->_em->getClassMetadata($deleteClause->abstractSchemaName);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1355
        $sql .= $class->getQuotedTableName($this->_platform);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1356
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1357
        $this->setSQLTableAlias($class->getTableName(), $class->getTableName(), $deleteClause->aliasIdentificationVariable);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1358
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1359
        $this->_rootAliases[] = $deleteClause->aliasIdentificationVariable;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1360
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1361
        return $sql;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1362
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1363
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1364
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1365
     * Walks down an UpdateClause AST node, thereby generating the appropriate SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1366
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1367
     * @param UpdateClause
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1368
     * @return string The SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1369
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1370
    public function walkUpdateClause($updateClause)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1371
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1372
        $sql = 'UPDATE ';
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1373
        $class = $this->_em->getClassMetadata($updateClause->abstractSchemaName);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1374
        $sql .= $class->getQuotedTableName($this->_platform);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1375
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1376
        $this->setSQLTableAlias($class->getTableName(), $class->getTableName(), $updateClause->aliasIdentificationVariable);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1377
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1378
        $this->_rootAliases[] = $updateClause->aliasIdentificationVariable;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1379
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1380
        $sql .= ' SET ' . implode(
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1381
            ', ', array_map(array($this, 'walkUpdateItem'), $updateClause->updateItems)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1382
        );
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1383
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1384
        return $sql;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1385
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1386
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1387
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1388
     * Walks down an UpdateItem AST node, thereby generating the appropriate SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1389
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1390
     * @param UpdateItem
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1391
     * @return string The SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1392
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1393
    public function walkUpdateItem($updateItem)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1394
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1395
        $useTableAliasesBefore = $this->_useSqlTableAliases;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1396
        $this->_useSqlTableAliases = false;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1397
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1398
        $sql = $this->walkPathExpression($updateItem->pathExpression) . ' = ';
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1399
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1400
        $newValue = $updateItem->newValue;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1401
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1402
        if ($newValue === null) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1403
            $sql .= 'NULL';
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1404
        } else if ($newValue instanceof AST\Node) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1405
            $sql .= $newValue->dispatch($this);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1406
        } else {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1407
            $sql .= $this->_conn->quote($newValue);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1408
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1409
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1410
        $this->_useSqlTableAliases = $useTableAliasesBefore;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1411
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1412
        return $sql;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1413
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1414
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1415
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1416
     * Walks down a WhereClause AST node, thereby generating the appropriate SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1417
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1418
     * @param WhereClause
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1419
     * @return string The SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1420
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1421
    public function walkWhereClause($whereClause)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1422
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1423
        $discrSql = $this->_generateDiscriminatorColumnConditionSql($this->_rootAliases);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1424
        $condSql = $this->walkConditionalExpression($whereClause->conditionalExpression);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1425
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1426
        return ' WHERE ' . (( ! $discrSql) ? $condSql : '(' . $condSql . ') AND ' . $discrSql);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1427
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1428
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1429
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1430
     * Walk down a ConditionalExpression AST node, thereby generating the appropriate SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1431
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1432
     * @param ConditionalExpression
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1433
     * @return string The SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1434
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1435
    public function walkConditionalExpression($condExpr)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1436
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1437
        // Phase 2 AST optimization: Skip processment of ConditionalExpression
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1438
        // if only one ConditionalTerm is defined
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1439
        return ( ! ($condExpr instanceof AST\ConditionalExpression))
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1440
            ? $this->walkConditionalTerm($condExpr)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1441
            : implode(
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1442
                ' OR ', array_map(array($this, 'walkConditionalTerm'), $condExpr->conditionalTerms)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1443
            );
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1444
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1445
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1446
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1447
     * Walks down a ConditionalTerm AST node, thereby generating the appropriate SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1448
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1449
     * @param ConditionalTerm
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1450
     * @return string The SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1451
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1452
    public function walkConditionalTerm($condTerm)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1453
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1454
        // Phase 2 AST optimization: Skip processment of ConditionalTerm
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1455
        // if only one ConditionalFactor is defined
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1456
        return ( ! ($condTerm instanceof AST\ConditionalTerm))
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1457
            ? $this->walkConditionalFactor($condTerm)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1458
            : implode(
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1459
                ' AND ', array_map(array($this, 'walkConditionalFactor'), $condTerm->conditionalFactors)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1460
            );
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1461
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1462
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1463
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1464
     * Walks down a ConditionalFactor AST node, thereby generating the appropriate SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1465
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1466
     * @param ConditionalFactor
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1467
     * @return string The SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1468
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1469
    public function walkConditionalFactor($factor)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1470
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1471
        // Phase 2 AST optimization: Skip processment of ConditionalFactor
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1472
        // if only one ConditionalPrimary is defined
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1473
        return ( ! ($factor instanceof AST\ConditionalFactor))
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1474
            ? $this->walkConditionalPrimary($factor)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1475
            : ($factor->not ? 'NOT ' : '') . $this->walkConditionalPrimary($factor->conditionalPrimary);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1476
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1477
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1478
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1479
     * Walks down a ConditionalPrimary AST node, thereby generating the appropriate SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1480
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1481
     * @param ConditionalPrimary
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1482
     * @return string The SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1483
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1484
    public function walkConditionalPrimary($primary)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1485
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1486
        if ($primary->isSimpleConditionalExpression()) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1487
            return $primary->simpleConditionalExpression->dispatch($this);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1488
        } else if ($primary->isConditionalExpression()) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1489
            $condExpr = $primary->conditionalExpression;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1490
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1491
            return '(' . $this->walkConditionalExpression($condExpr) . ')';
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1492
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1493
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1494
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1495
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1496
     * Walks down an ExistsExpression AST node, thereby generating the appropriate SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1497
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1498
     * @param ExistsExpression
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1499
     * @return string The SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1500
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1501
    public function walkExistsExpression($existsExpr)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1502
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1503
        $sql = ($existsExpr->not) ? 'NOT ' : '';
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1504
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1505
        $sql .= 'EXISTS (' . $this->walkSubselect($existsExpr->subselect) . ')';
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1506
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1507
        return $sql;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1508
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1509
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1510
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1511
     * Walks down a CollectionMemberExpression AST node, thereby generating the appropriate SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1512
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1513
     * @param CollectionMemberExpression
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1514
     * @return string The SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1515
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1516
    public function walkCollectionMemberExpression($collMemberExpr)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1517
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1518
        $sql = $collMemberExpr->not ? 'NOT ' : '';
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1519
        $sql .= 'EXISTS (SELECT 1 FROM ';
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1520
        $entityExpr = $collMemberExpr->entityExpression;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1521
        $collPathExpr = $collMemberExpr->collectionValuedPathExpression;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1522
        
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1523
        $fieldName = $collPathExpr->field;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1524
        $dqlAlias = $collPathExpr->identificationVariable;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1525
        
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1526
        $class = $this->_queryComponents[$dqlAlias]['metadata'];
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1527
        
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1528
        if ($entityExpr instanceof AST\InputParameter) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1529
            $dqlParamKey = $entityExpr->name;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1530
            $entity = $this->_query->getParameter($dqlParamKey);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1531
        } else {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1532
            //TODO
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1533
            throw new \BadMethodCallException("Not implemented");
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1534
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1535
        
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1536
        $assoc = $class->associationMappings[$fieldName];
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1537
        
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1538
        if ($assoc['type'] == ClassMetadata::ONE_TO_MANY) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1539
            $targetClass = $this->_em->getClassMetadata($assoc['targetEntity']);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1540
            $targetTableAlias = $this->getSQLTableAlias($targetClass->table['name']);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1541
            $sourceTableAlias = $this->getSQLTableAlias($class->table['name'], $dqlAlias);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1542
            
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1543
            $sql .= $targetClass->getQuotedTableName($this->_platform)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1544
                  . ' ' . $targetTableAlias . ' WHERE ';
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1545
                    
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1546
            $owningAssoc = $targetClass->associationMappings[$assoc['mappedBy']];
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1547
            
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1548
            $first = true;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1549
            
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1550
            foreach ($owningAssoc['targetToSourceKeyColumns'] as $targetColumn => $sourceColumn) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1551
                if ($first) $first = false; else $sql .= ' AND ';
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1552
                
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1553
                $sql .= $sourceTableAlias . '.' . $class->getQuotedColumnName($class->fieldNames[$targetColumn], $this->_platform) 
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1554
                      . ' = ' 
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1555
                      . $targetTableAlias . '.' . $sourceColumn;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1556
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1557
            
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1558
            $sql .= ' AND ';
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1559
            $first = true;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1560
            
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1561
            foreach ($targetClass->identifier as $idField) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1562
                if ($first) $first = false; else $sql .= ' AND ';
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1563
                
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1564
                $this->_parserResult->addParameterMapping($dqlParamKey, $this->_sqlParamIndex++);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1565
                $sql .= $targetTableAlias . '.' 
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1566
                      . $targetClass->getQuotedColumnName($idField, $this->_platform) . ' = ?';
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1567
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1568
        } else { // many-to-many
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1569
            $targetClass = $this->_em->getClassMetadata($assoc['targetEntity']);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1570
            
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1571
            $owningAssoc = $assoc['isOwningSide'] ? $assoc : $targetClass->associationMappings[$assoc['mappedBy']];
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1572
            $joinTable = $owningAssoc['joinTable'];
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1573
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1574
            // SQL table aliases
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1575
            $joinTableAlias = $this->getSQLTableAlias($joinTable['name']);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1576
            $targetTableAlias = $this->getSQLTableAlias($targetClass->table['name']);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1577
            $sourceTableAlias = $this->getSQLTableAlias($class->table['name'], $dqlAlias);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1578
            
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1579
            // join to target table
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1580
            $sql .= $targetClass->getQuotedJoinTableName($owningAssoc, $this->_platform)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1581
                  . ' ' . $joinTableAlias . ' INNER JOIN '
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1582
                  . $targetClass->getQuotedTableName($this->_platform)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1583
                  . ' ' . $targetTableAlias . ' ON ';
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1584
            
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1585
            // join conditions
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1586
            $joinColumns = $assoc['isOwningSide']
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1587
                ? $joinTable['inverseJoinColumns']
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1588
                : $joinTable['joinColumns'];
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1589
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1590
            $first = true;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1591
            foreach ($joinColumns as $joinColumn) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1592
                if ($first) $first = false; else $sql .= ' AND ';
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1593
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1594
                $sql .= $joinTableAlias . '.' . $joinColumn['name'] . ' = '
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1595
                        . $targetTableAlias . '.' . $targetClass->getQuotedColumnName(
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1596
                                $targetClass->fieldNames[$joinColumn['referencedColumnName']],
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1597
                                $this->_platform);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1598
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1599
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1600
            $sql .= ' WHERE ';
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1601
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1602
            $joinColumns = $assoc['isOwningSide']
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1603
                ? $joinTable['joinColumns']
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1604
                : $joinTable['inverseJoinColumns'];
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1605
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1606
            $first = true;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1607
            foreach ($joinColumns as $joinColumn) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1608
                if ($first) $first = false; else $sql .= ' AND ';
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1609
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1610
                $sql .= $joinTableAlias . '.' . $joinColumn['name'] . ' = ' 
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1611
                      . $sourceTableAlias . '.' . $class->getQuotedColumnName(
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1612
                              $class->fieldNames[$joinColumn['referencedColumnName']],
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1613
                              $this->_platform);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1614
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1615
            
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1616
            $sql .= ' AND ';
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1617
            $first = true;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1618
            
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1619
            foreach ($targetClass->identifier as $idField) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1620
                if ($first) $first = false; else $sql .= ' AND ';
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1621
                
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1622
                $this->_parserResult->addParameterMapping($dqlParamKey, $this->_sqlParamIndex++);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1623
                $sql .= $targetTableAlias . '.' 
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1624
                      . $targetClass->getQuotedColumnName($idField, $this->_platform) . ' = ?';
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1625
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1626
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1627
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1628
        return $sql . ')';
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1629
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1630
    
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1631
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1632
     * Walks down an EmptyCollectionComparisonExpression AST node, thereby generating the appropriate SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1633
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1634
     * @param EmptyCollectionComparisonExpression
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1635
     * @return string The SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1636
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1637
    public function walkEmptyCollectionComparisonExpression($emptyCollCompExpr)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1638
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1639
        $sizeFunc = new AST\Functions\SizeFunction('size');
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1640
        $sizeFunc->collectionPathExpression = $emptyCollCompExpr->expression;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1641
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1642
        return $sizeFunc->getSql($this) . ($emptyCollCompExpr->not ? ' > 0' : ' = 0');
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1643
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1644
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1645
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1646
     * Walks down a NullComparisonExpression AST node, thereby generating the appropriate SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1647
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1648
     * @param NullComparisonExpression
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1649
     * @return string The SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1650
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1651
    public function walkNullComparisonExpression($nullCompExpr)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1652
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1653
        $sql = '';
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1654
        $innerExpr = $nullCompExpr->expression;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1655
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1656
        if ($innerExpr instanceof AST\InputParameter) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1657
            $dqlParamKey = $innerExpr->name;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1658
            $this->_parserResult->addParameterMapping($dqlParamKey, $this->_sqlParamIndex++);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1659
            $sql .= ' ?';
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1660
        } else {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1661
            $sql .= $this->walkPathExpression($innerExpr);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1662
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1663
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1664
        $sql .= ' IS' . ($nullCompExpr->not ? ' NOT' : '') . ' NULL';
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1665
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1666
        return $sql;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1667
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1668
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1669
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1670
     * Walks down an InExpression AST node, thereby generating the appropriate SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1671
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1672
     * @param InExpression
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1673
     * @return string The SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1674
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1675
    public function walkInExpression($inExpr)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1676
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1677
        $sql = $this->walkPathExpression($inExpr->pathExpression)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1678
             . ($inExpr->not ? ' NOT' : '') . ' IN (';
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1679
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1680
        if ($inExpr->subselect) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1681
            $sql .= $this->walkSubselect($inExpr->subselect);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1682
        } else {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1683
            $sql .= implode(', ', array_map(array($this, 'walkInParameter'), $inExpr->literals));
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1684
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1685
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1686
        $sql .= ')';
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1687
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1688
        return $sql;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1689
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1690
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1691
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1692
     * Walks down an InstanceOfExpression AST node, thereby generating the appropriate SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1693
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1694
     * @param InstanceOfExpression
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1695
     * @return string The SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1696
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1697
    public function walkInstanceOfExpression($instanceOfExpr)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1698
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1699
        $sql = '';
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1700
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1701
        $dqlAlias = $instanceOfExpr->identificationVariable;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1702
        $discrClass = $class = $this->_queryComponents[$dqlAlias]['metadata'];
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1703
        $fieldName = null;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1704
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1705
        if ($class->discriminatorColumn) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1706
            $discrClass = $this->_em->getClassMetadata($class->rootEntityName);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1707
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1708
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1709
        if ($this->_useSqlTableAliases) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1710
            $sql .= $this->getSQLTableAlias($discrClass->table['name'], $dqlAlias) . '.';
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1711
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1712
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1713
        $sql .= $class->discriminatorColumn['name'] . ($instanceOfExpr->not ? ' <> ' : ' = ');
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1714
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1715
        if ($instanceOfExpr->value instanceof AST\InputParameter) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1716
            // We need to modify the parameter value to be its correspondent mapped value
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1717
            $dqlParamKey = $instanceOfExpr->value->name;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1718
            $paramValue  = $this->_query->getParameter($dqlParamKey);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1719
            
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1720
            if ( ! ($paramValue instanceof \Doctrine\ORM\Mapping\ClassMetadata)) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1721
                throw QueryException::invalidParameterType('ClassMetadata', get_class($paramValue));
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1722
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1723
            
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1724
            $entityClassName = $paramValue->name;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1725
        } else {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1726
            // Get name from ClassMetadata to resolve aliases.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1727
            $entityClassName = $this->_em->getClassMetadata($instanceOfExpr->value)->name;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1728
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1729
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1730
        if ($entityClassName == $class->name) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1731
            $sql .= $this->_conn->quote($class->discriminatorValue);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1732
        } else {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1733
            $discrMap = array_flip($class->discriminatorMap);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1734
            if (!isset($discrMap[$entityClassName])) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1735
                throw QueryException::instanceOfUnrelatedClass($entityClassName, $class->rootEntityName);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1736
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1737
            
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1738
            $sql .= $this->_conn->quote($discrMap[$entityClassName]);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1739
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1740
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1741
        return $sql;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1742
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1743
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1744
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1745
     * Walks down an InParameter AST node, thereby generating the appropriate SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1746
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1747
     * @param InParameter
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1748
     * @return string The SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1749
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1750
    public function walkInParameter($inParam)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1751
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1752
        return $inParam instanceof AST\InputParameter ?
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1753
                $this->walkInputParameter($inParam) :
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1754
                $this->walkLiteral($inParam);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1755
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1756
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1757
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1758
     * Walks down a literal that represents an AST node, thereby generating the appropriate SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1759
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1760
     * @param mixed
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1761
     * @return string The SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1762
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1763
    public function walkLiteral($literal)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1764
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1765
        switch ($literal->type) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1766
            case AST\Literal::STRING:
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1767
                return $this->_conn->quote($literal->value);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1768
            case AST\Literal::BOOLEAN:
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1769
                $bool = strtolower($literal->value) == 'true' ? true : false;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1770
                $boolVal = $this->_conn->getDatabasePlatform()->convertBooleans($bool);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1771
                return is_string($boolVal) ? $this->_conn->quote($boolVal) : $boolVal;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1772
            case AST\Literal::NUMERIC:
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1773
                return $literal->value;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1774
            default:
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1775
                throw QueryException::invalidLiteral($literal);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1776
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1777
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1778
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1779
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1780
     * Walks down a BetweenExpression AST node, thereby generating the appropriate SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1781
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1782
     * @param BetweenExpression
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1783
     * @return string The SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1784
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1785
    public function walkBetweenExpression($betweenExpr)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1786
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1787
        $sql = $this->walkArithmeticExpression($betweenExpr->expression);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1788
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1789
        if ($betweenExpr->not) $sql .= ' NOT';
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1790
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1791
        $sql .= ' BETWEEN ' . $this->walkArithmeticExpression($betweenExpr->leftBetweenExpression)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1792
              . ' AND ' . $this->walkArithmeticExpression($betweenExpr->rightBetweenExpression);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1793
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1794
        return $sql;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1795
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1796
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1797
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1798
     * Walks down a LikeExpression AST node, thereby generating the appropriate SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1799
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1800
     * @param LikeExpression
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1801
     * @return string The SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1802
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1803
    public function walkLikeExpression($likeExpr)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1804
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1805
        $stringExpr = $likeExpr->stringExpression;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1806
        $sql = $stringExpr->dispatch($this) . ($likeExpr->not ? ' NOT' : '') . ' LIKE ';
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1807
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1808
        if ($likeExpr->stringPattern instanceof AST\InputParameter) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1809
            $inputParam = $likeExpr->stringPattern;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1810
            $dqlParamKey = $inputParam->name;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1811
            $this->_parserResult->addParameterMapping($dqlParamKey, $this->_sqlParamIndex++);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1812
            $sql .= '?';
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1813
        } else {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1814
            $sql .= $this->_conn->quote($likeExpr->stringPattern);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1815
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1816
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1817
        if ($likeExpr->escapeChar) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1818
            $sql .= ' ESCAPE ' . $this->_conn->quote($likeExpr->escapeChar);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1819
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1820
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1821
        return $sql;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1822
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1823
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1824
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1825
     * Walks down a StateFieldPathExpression AST node, thereby generating the appropriate SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1826
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1827
     * @param StateFieldPathExpression
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1828
     * @return string The SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1829
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1830
    public function walkStateFieldPathExpression($stateFieldPathExpression)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1831
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1832
        return $this->walkPathExpression($stateFieldPathExpression);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1833
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1834
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1835
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1836
     * Walks down a ComparisonExpression AST node, thereby generating the appropriate SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1837
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1838
     * @param ComparisonExpression
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1839
     * @return string The SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1840
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1841
    public function walkComparisonExpression($compExpr)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1842
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1843
        $sql = '';
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1844
        $leftExpr = $compExpr->leftExpression;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1845
        $rightExpr = $compExpr->rightExpression;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1846
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1847
        if ($leftExpr instanceof AST\Node) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1848
            $sql .= $leftExpr->dispatch($this);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1849
        } else {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1850
            $sql .= is_numeric($leftExpr) ? $leftExpr : $this->_conn->quote($leftExpr);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1851
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1852
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1853
        $sql .= ' ' . $compExpr->operator . ' ';
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1854
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1855
        if ($rightExpr instanceof AST\Node) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1856
            $sql .= $rightExpr->dispatch($this);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1857
        } else {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1858
            $sql .= is_numeric($rightExpr) ? $rightExpr : $this->_conn->quote($rightExpr);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1859
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1860
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1861
        return $sql;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1862
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1863
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1864
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1865
     * Walks down an InputParameter AST node, thereby generating the appropriate SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1866
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1867
     * @param InputParameter
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1868
     * @return string The SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1869
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1870
    public function walkInputParameter($inputParam)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1871
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1872
        $this->_parserResult->addParameterMapping($inputParam->name, $this->_sqlParamIndex++);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1873
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1874
        return '?';
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1875
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1876
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1877
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1878
     * Walks down an ArithmeticExpression AST node, thereby generating the appropriate SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1879
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1880
     * @param ArithmeticExpression
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1881
     * @return string The SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1882
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1883
    public function walkArithmeticExpression($arithmeticExpr)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1884
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1885
        return ($arithmeticExpr->isSimpleArithmeticExpression())
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1886
        	? $this->walkSimpleArithmeticExpression($arithmeticExpr->simpleArithmeticExpression)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1887
        	: '(' . $this->walkSubselect($arithmeticExpr->subselect) . ')';
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1888
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1889
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1890
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1891
     * Walks down an SimpleArithmeticExpression AST node, thereby generating the appropriate SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1892
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1893
     * @param SimpleArithmeticExpression
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1894
     * @return string The SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1895
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1896
    public function walkSimpleArithmeticExpression($simpleArithmeticExpr)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1897
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1898
        return ( ! ($simpleArithmeticExpr instanceof AST\SimpleArithmeticExpression))
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1899
            ? $this->walkArithmeticTerm($simpleArithmeticExpr)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1900
            : implode(
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1901
                ' ', array_map(array($this, 'walkArithmeticTerm'), $simpleArithmeticExpr->arithmeticTerms)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1902
            );
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1903
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1904
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1905
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1906
     * Walks down an ArithmeticTerm AST node, thereby generating the appropriate SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1907
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1908
     * @param mixed
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1909
     * @return string The SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1910
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1911
    public function walkArithmeticTerm($term)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1912
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1913
        if (is_string($term)) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1914
            return $term;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1915
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1916
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1917
        // Phase 2 AST optimization: Skip processment of ArithmeticTerm
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1918
        // if only one ArithmeticFactor is defined
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1919
        return ( ! ($term instanceof AST\ArithmeticTerm))
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1920
            ? $this->walkArithmeticFactor($term)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1921
            : implode(
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1922
                ' ', array_map(array($this, 'walkArithmeticFactor'), $term->arithmeticFactors)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1923
            );
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1924
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1925
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1926
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1927
     * Walks down an ArithmeticFactor that represents an AST node, thereby generating the appropriate SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1928
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1929
     * @param mixed
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1930
     * @return string The SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1931
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1932
    public function walkArithmeticFactor($factor)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1933
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1934
        if (is_string($factor)) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1935
            return $factor;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1936
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1937
        
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1938
        // Phase 2 AST optimization: Skip processment of ArithmeticFactor
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1939
        // if only one ArithmeticPrimary is defined
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1940
        return ( ! ($factor instanceof AST\ArithmeticFactor))
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1941
            ? $this->walkArithmeticPrimary($factor)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1942
            : ($factor->isNegativeSigned() ? '-' : ($factor->isPositiveSigned() ? '+' : '')) 
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1943
                . $this->walkArithmeticPrimary($factor->arithmeticPrimary);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1944
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1945
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1946
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1947
     * Walks down an ArithmeticPrimary that represents an AST node, thereby generating the appropriate SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1948
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1949
     * @param mixed
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1950
     * @return string The SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1951
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1952
    public function walkArithmeticPrimary($primary)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1953
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1954
        if ($primary instanceof AST\SimpleArithmeticExpression) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1955
            return '(' . $this->walkSimpleArithmeticExpression($primary) . ')';
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1956
        } else if ($primary instanceof AST\Node) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1957
            return $primary->dispatch($this);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1958
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1959
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1960
        // TODO: We need to deal with IdentificationVariable here
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1961
        return '';
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1962
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1963
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1964
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1965
     * Walks down a StringPrimary that represents an AST node, thereby generating the appropriate SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1966
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1967
     * @param mixed
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1968
     * @return string The SQL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1969
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1970
    public function walkStringPrimary($stringPrimary)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1971
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1972
        return (is_string($stringPrimary))
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1973
            ? $this->_conn->quote($stringPrimary)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1974
            : $stringPrimary->dispatch($this);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1975
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
  1976
}