Walks down a SelectStatement AST node, wrapping it in a SELECT DISTINCT.

@return string

@throws RuntimeException
8005
public function walkSelectStatement(SelectStatement $AST)
    {
        if ($this->platformSupportsRowNumber()) {
            return $this->walkSelectStatementWithRowNumber($AST);
        }

        return $this->walkSelectStatementWithoutRowNumber($AST);
    }
261384
public function end()
    {
        if (null === $this->ifPart) {
            throw new \RuntimeException('You must specify an if part.');
        }
        if (null === $this->thenPart) {
            throw new \RuntimeException('You must specify a then part.');
        }

        return $this->node;
    }
692741
public function SubselectFromClause()
    {
        $this->match(Lexer::T_FROM);

        $identificationVariables   = [];
        $identificationVariables[] = $this->SubselectIdentificationVariableDeclaration();

        while ($this->lexer->isNextToken(Lexer::T_COMMA)) {
            $this->match(Lexer::T_COMMA);

            $identificationVariables[] = $this->SubselectIdentificationVariableDeclaration();
        }

        return new AST\SubselectFromClause($identificationVariables);
    }
1042447
public function select(SQLStatement $select): string
    {
        $limit = $select->getLimit();

        if ($limit <= 0) {
            return parent::select($select);
        }

        $sql = $select->getDistinct() ? 'SELECT DISTINCT ' : 'SELECT ';
        $sql .= $this->handleColumns($select->getColumns());
        $sql .= ' FROM ';
        $sql .= $this->handleTables($select->getTables());
        $sql .= $this->handleJoins($select->getJoins());
        $sql .= $this->handleWheres($select->getWheres());
        $sql .= $this->handleGroupings($select->getGroupBy());
        $sql .= $this->handleOrderings($select->getOrder());
        $sql .= $this->handleHavings($select->getHaving());

        $offset = $select->getOffset();

        if ($offset < 0) {
            return 'SELECT * FROM (' . $sql . ') M1 WHERE ROWNUM <= ' . $limit;
        }

        $limit += $offset;
        $offset++;

        return 'SELECT * FROM (SELECT M1.*, ROWNUM AS OPIS_ROWNUM FROM (' . $sql . ') M1 WHERE ROWNUM <= ' . $limit . ') WHERE OPIS_ROWNUM >= ' . $offset;
    }
404498
public function getPayload()
    {
        if (!$this->token) {
            throw new \RuntimeException('Token is mandatory.');
        }

        $descriptionNode = $this->appendDescriptionNode();
        $this->appendTagNode($descriptionNode);
        $this->appendTokenNode($descriptionNode);
        $this->appendTemplateNode($descriptionNode);
        $this->appendAdditionalNode($descriptionNode);

        $this->dom->formatOutput = true;

        return $this->dom->saveXML();
    }
827918
public function get_field_select() : string {
        $fieldlist = $this->get_fieldlist();

        return implode(', ', array_map(function($fieldname, $fieldalias) {
            return "{$this->tablealias}.{$fieldname} AS {$fieldalias}";
        }, $fieldlist, array_keys($fieldlist)));
    }
1209517
public function walkSelectStatementWithRowNumber(SelectStatement $AST)
    {
        $hasOrderBy   = false;
        $outerOrderBy = ' ORDER BY dctrn_minrownum ASC';
        $orderGroupBy = '';

        if ($AST->orderByClause instanceof OrderByClause) {
            $hasOrderBy = true;

            $this->rebuildOrderByForRowNumber($AST);
        }

        $innerSql           = $this->getInnerSQL($AST);
        $sqlIdentifier      = $this->getSQLIdentifier($AST);
        $sqlAliasIdentifier = array_map(static function ($info) {
            return $info['alias'];
        }, $sqlIdentifier);

        if ($hasOrderBy) {
            $orderGroupBy = ' GROUP BY ' . implode(', ', $sqlAliasIdentifier);
            $sqlPiece     = 'MIN(' . $this->walkResultVariable('dctrn_rownum') . ') AS dctrn_minrownum';

            $sqlAliasIdentifier[] = $sqlPiece;
            $sqlIdentifier[]      = [
                'alias' => $sqlPiece,
                'type'  => Type::getType('integer'),
            ];
        }

        // Build the counter query
        $sql = sprintf('SELECT DISTINCT %s FROM (%s) dctrn_result', implode(', ', $sqlAliasIdentifier), $innerSql);

        if ($hasOrderBy) {
            $sql .= $orderGroupBy . $outerOrderBy;
        }

        // Apply the limit and offset.
        $sql = $this->platform->modifyLimitQuery($sql, $this->maxResults, $this->firstResult ?? 0);

        // Add the columns to the ResultSetMapping. It's not really nice but
        // it works. Preferably I'd clear the RSM or simply create a new one
        // but that is not possible from inside the output walker, so we dirty
        // up the one we have.
        foreach ($sqlIdentifier as $property => $propertyMapping) {
            $this->rsm->addScalarResult($propertyMapping['alias'], $property, $propertyMapping['type']);
        }

        return $sql;
    }
207389
protected function _getSelectFieldsAndTable()
    {
        $template = "SELECT %s FROM %s";
        if ($this->_sql->isDistinct()) {
            $template = "SELECT DISTINCT %s FROM %s";
        }
        $this->_statement = sprintf(
            $template,
            $this->_getFieldList(),
            $this->_sql->getTable()
        );
        return $this;
    }
881923
private function parseSelectField()
    {
        $expression = null;

        // IS SUBSELECT
        if($this->tokenizer->is(TokenType::LEFT_PAREN))
        {
            $this->tokenizer->readNextToken(); // "SELECT"

            $expression = new AST\Subquery($this->parseQuery());

            $this->tokenizer->expect(TokenType::RIGHT_PAREN);
        }

        // TYPEOF sobject WHEN ... THEN ... [ELSE]
        elseif($this->tokenizer->is(TokenType::KEYWORD))
        {
            $keyword = strtoupper($this->tokenizer->getTokenValue());

            switch($keyword)
            {
                case 'TYPEOF':

                    $this->tokenizer->readNextToken(); // ADVANCE TO "WHEN"

                    $expression = $this->parseSelectTypeofExpression();

                    // EXPECT "END", ADVANCE TO "FROM"-CLAUSE
                    $this->tokenizer->expectKeyword('end');
                break;
                default:
                    throw new ParseException(sprintf('Unexpected keyword "%s", expecting "TYPEOF", "LEFT_PAREN" or "FIELDNAME".', $keyword), $this->tokenizer->getLine(), $this->tokenizer->getLinePos(), $this->tokenizer->getInput());
            }
        }

        // "ORDINARY" FIELD OR FUNCTION
        elseif($this->tokenizer->isExpressionOrKeyword('from'))
        {
            $name = $this->tokenizer->getTokenValue();

            $this->tokenizer->readNextToken();

            // IS (AGGREGATE) FUNCTION
            if($this->tokenizer->is(TokenType::LEFT_PAREN))
            {
                $expression = new AST\SelectFunction($this->parseFunctionExpression($name, Functions\SoqlFunctionInterface::CONTEXT_SELECT));
            }
            else
            {
                $expression = new AST\SelectField($name);
            }
        }

        // IS THE NEXT TOKEN AN ALIAS?
        if($this->tokenizer->is(TokenType::EXPRESSION) && $expression instanceof AST\CanHazAliasInterface)
        {
            $expression->setAlias($this->parseAlias());
        }
        return $expression;
    }
202007
private function getSelectQuery()
	{
		$result = $this->getSelectClause();

		if ($join = $this->getJoinClause()) {
			$result .= ' ' . $join;
		}

		if ($where = $this->getWhereClause()) {
			$result .= ' ' . $where;
		}

		if ($groupBy = $this->getGroupByClause()) {
			$result .= ' ' . $groupBy;
		}

		if ($orderBy = $this->getOrderByClause()) {
			$result .= ' ' . $orderBy;
		}

		if ($limit = $this->getLimitClause()) {
			$result .= ' ' . $limit;
		}

		if ($offset = $this->getOffsetClause()) {
			$result .= ' ' . $offset;
		}

		return $result;
	}
607892
public function getAsManualSql()
    {
        $strOrderByArray = array();
        $intLength = count($this->objNodeArray);
        for ($intIndex = 0; $intIndex < $intLength; $intIndex++) {
            $strOrderByCommand = $this->objNodeArray[$intIndex]->getAsManualSqlColumn();

            // Check to see if they want a ASC/DESC declarator
            if ((($intIndex + 1) < $intLength) &&
                !($this->objNodeArray[$intIndex + 1] instanceof Node\NodeBase)
            ) {
                if ((!$this->objNodeArray[$intIndex + 1]) ||
                    (trim(strtolower($this->objNodeArray[$intIndex + 1])) == 'desc')
                ) {
                    $strOrderByCommand .= ' DESC';
                } else {
                    $strOrderByCommand .= ' ASC';
                }
                $intIndex++;
            }

            array_push($strOrderByArray, $strOrderByCommand);
        }

        return implode(',', $strOrderByArray);
    }
18317
protected function visitSirelNodeSelectStatement(Node\SelectStatement $select)
    {
        return join(" ", array_filter(array(
            "SELECT",

            ($select->distinct ? "DISTINCT" : null),

            ($select->projections
                ? join(", ", $this->visitEach($select->projections))
                : '*'),

            // FROM
            $this->visit($select->source),

            // WHERE
            ($select->restrictions 
                ? "WHERE " . join(" AND ", $this->visitEach($select->restrictions))
                : null
            ),

            // ORDER BY
            ($select->orders
                ? "ORDER BY " . join(", ", $this->visitEach($select->orders))
                : null),

            // GROUP BY
            ($select->groups
                ? "GROUP BY " . join(', ', $this->visitEach($select->groups))
                : null),

            // LIMIT
            ($select->limit ? $this->visit($select->limit) : null),

            // OFFSET 
            ($select->offset ? $this->visit($select->offset) : null)
        ))) . ';';
    }
161179
public function getQueryString()
    {
        $query = parent::getQueryString();
        if ($query) {
            $query .= '&';
        }

        if (!defined('REQUEST_TOKEN')) {
            throw new \RuntimeException('Request token not defined - can not append to query string.');
        }

        $query .= 'rt=' . REQUEST_TOKEN;

        return $query;
    }
716899
public function getSelectClause()
    {
        $select = [];
        foreach ($this->all() as $column) {
            $select[] = $column->getRawSelect();
        }

        return implode(', ', $select);
    }
684990
public function getDistinctString() {
    $distinct = array();
    if (is_array($s = $this->getDistinct()) && !empty($s)) {
      foreach ($s as $distinctAttribute) {
        $item = array();
        if ($distinctAttribute['dist_key'] != 'none_dist') {
          if (is_array($distinctAttribute) && !empty($distinctAttribute)) {
            foreach ($distinctAttribute as $k => $v) {
              $item[] = $k . ":" . $v;
            }
          }
          $distinct[] = implode(",", $item);
        } else {
          $distinct[] = $distinctAttribute['dist_key'];
        }
      }
    }
    return implode(";", $distinct);
  }
332517
private function selector():string{
		$selector = $this->hash(50);
		// Check if selector is unique.
		do{
			$isUnique = Input::$token->selectOneBySelector($selector);
		}while( $isUnique[0] !== null );
		return $selector;
	}
1166493
public function buildCountStatement()
	{
		if( !$this->keys )
			throw new RuntimeException( 'No Columns defined.' );
		if( !$this->tables )
			throw new RuntimeException( 'No Tables defined.' );

		$tables		= array();
		$tables		= "\nFROM\n\t".implode( ",\n\t", $this->tables );
		$conditions	= "";
		$groupings	= "";
		$havings	= "";
		if( $this->conditions )
			$conditions	= "\nWHERE\n\t".implode( " AND\n\t", $this->conditions );
		if( $this->groupings )
			$groupings	= "\nGROUP BY\n\t".implode( ",\n\t", $this->groupings );
		if( $this->havings )
			$havings	= "\nHAVING\n\t".implode( ",\n\t", $this->havings );
		$column	= preg_replace( '/(.+)( AS .+)/i', '\\1', $this->keys[0] );
		$statement = "SELECT COUNT(".$column.") as rowcount".$tables.$conditions.$groupings.$havings;
		return $statement;
	}