Add a subselect expression to the query.

@param  \Closure|static|string $query
@param  string  $as

@return \Illuminate\Database\Query\Builder
490251
public function selectSub($query, $as)
    {
        $this->handler->setBuilder($query)
            ->collectSubQueryTags();

        return parent::selectSub($query, $as);
    }
321017
protected function getVisibleOnlySubQuery(SelectQuery $query)
    {
        // TODO: The following query requires optimization
        $subSelect = $query->subSelect();
        $subSelect
            ->selectDistinct('ezurl_object_link.url_id')
            ->from('ezurl_object_link')
            ->innerJoin(
                'ezcontentobject_attribute',
                $query->expr->lAnd(
                    $query->expr->eq('ezurl_object_link.contentobject_attribute_id', 'ezcontentobject_attribute.id'),
                    $query->expr->eq('ezurl_object_link.contentobject_attribute_version', 'ezcontentobject_attribute.version')
                )
            )
            ->innerJoin(
                'ezcontentobject_tree',
                $query->expr->lAnd(
                    $query->expr->eq('ezcontentobject_tree.contentobject_id', 'ezcontentobject_attribute.contentobject_id'),
                    $query->expr->eq('ezcontentobject_tree.contentobject_version', 'ezcontentobject_attribute.version')
                )
            )
            ->where(
                $query->expr->eq(
                    'ezcontentobject_tree.is_invisible',
                    $query->bindValue(0, null, PDO::PARAM_INT)
                )
            );

        return $subSelect;
    }
846828
public function columnSelect(self $query, ?string $alias = null)
    {
        if ($alias) {
            $alias = $this->dialect()->quoteName($alias);
        }

        $this->addColumn($query, $alias);

        return $this;
    }
795417
protected function _selectQueryTranslator($query)
    {
        $limit = $query->clause('limit');
        $offset = $query->clause('offset');

        if ($limit && $offset === null) {
            $query->modifier(['_auto_top_' => sprintf('TOP %d', $limit)]);
        }

        if ($offset !== null && !$query->clause('order')) {
            $query->order($query->newExpr()->add('(SELECT NULL)'));
        }

        if ($this->_version() < 11 && $offset !== null) {
            return $this->_pagingSubquery($query, $limit, $offset);
        }

        return $this->_transformDistinct($query);
    }
816172
protected function subselect_query($name)
    {
        if (isset($this->subselect_query[$name]))
        {
            $sql = $this->subselect_query[$name];
        }
        else
        {
            $sql = preg_replace_callback('/\{(.+)\}/Uu', array($this, 'subselect_callback'), $this->subselect[$name]);
            $this->subselect_query[$name] = $sql;
        }
        return "({$sql}) AS `{$name}`";
    }
1308894
protected function selectQuerySource(&$query)
    {
        foreach ($query['trace'] as $i => &$trace) {
            $isSource = true;
            foreach ($this->getNamespacesCutoff() as $namespace) {
                $namespace = trim($namespace, '/\\').'\\';
                if (isset($trace['class']) && strpos($trace['class'], $namespace) !== false) {
                    $isSource = false;
                }
            }
            if ($isSource) {
                $query['trace'][$i - 1]['query_source'] = true;
                break;
            }
        }
    }
1055633
protected function augmentSQLVersioned(SQLSelect $query)
    {
        $baseTable = $this->baseTable();
        foreach ($query->getFrom() as $alias => $join) {
            if (!$this->isTableVersioned($alias)) {
                continue;
            }

            if ($alias != $baseTable) {
                // Make sure join includes version as well
                $query->setJoinFilter(
                    $alias,
                    "\"{$alias}_Versions\".\"RecordID\" = \"{$baseTable}_Versions\".\"RecordID\""
                    . " AND \"{$alias}_Versions\".\"Version\" = \"{$baseTable}_Versions\".\"Version\""
                );
            }

            // Rewrite all usages of `Table` to `Table_Versions`
            $query->renameTable($alias, $alias . '_Versions');
            // However, add an alias back to the base table in case this must later be joined.
            // See ApplyVersionFilters for example which joins _Versions back onto draft table.
            $query->renameTable($alias . '_Draft', $alias);
        }

        // Add all <basetable>_Versions columns
        foreach (Config::inst()->get(static::class, 'db_for_versions_table') as $name => $type) {
            $query->selectField(sprintf('"%s_Versions"."%s"', $baseTable, $name), $name);
        }

        // Alias the record ID as the row ID, and ensure ID filters are aliased correctly
        $query->selectField("\"{$baseTable}_Versions\".\"RecordID\"", "ID");
        $query->replaceText("\"{$baseTable}_Versions\".\"ID\"", "\"{$baseTable}_Versions\".\"RecordID\"");

        // However, if doing count, undo rewrite of "ID" column
        $query->replaceText(
            "count(DISTINCT \"{$baseTable}_Versions\".\"RecordID\")",
            "count(DISTINCT \"{$baseTable}_Versions\".\"ID\")"
        );

        // Filter deleted versions, which are all unqueryable
        $query->addWhere(["\"{$baseTable}_Versions\".\"WasDeleted\"" => 0]);
    }
1093274
protected function buildSelectQuery(SQLSelect $query, array &$parameters)
    {
        $sql  = $this->buildSelectFragment($query, $parameters);
        $sql .= $this->buildFromFragment($query, $parameters);
        $sql .= $this->buildWhereFragment($query, $parameters);
        $sql .= $this->buildGroupByFragment($query, $parameters);
        $sql .= $this->buildHavingFragment($query, $parameters);
        $sql .= $this->buildOrderByFragment($query, $parameters);
        $sql .= $this->buildLimitFragment($query, $parameters);
        return $sql;
    }
1054662
public function select($field, string $as = null, bool $reset = true): self
    {
        $reset && $this->reset();

        // handle trivial selects
        if ($field === 1 || $field === '1') {
            return $this->push('select', '1');
        } elseif ($field === true) {
            return $this->push('select', 'TRUE');
        }

        // handle other query object
        if ($field instanceof Builder || $field instanceof Sql) {
            if ($as == null) {
                throw new BuilderException('Alias required!');
            }
            return $this->push('select', '('. $field->toString() .') AS '. $this->agent->quoteField($as));
        }

        $field = $this->prepareField($field);
        if ($as != null) {
            $field = $field .' AS '. $this->agent->quoteField($as);
        }

        return $this->push('select', $field);
    }
732978
protected function buildQuery(Builder $query, $name)
    {
        $op = $this->getOperator();
        $value = $this->getValue();

        switch ($op) {
            case 'in':
                $query->whereIn($name, (array) $value);
                break;
            case 'between':
                $query->whereBetween($name, (array) $value);
                break;
            case 'like':
                $value .= '%';
                $query->where($name, $op, $value);
                break;
            default:
                $query->where($name, $op, $value);
        }
    }
108157
public function compileSelect(Builder $query)
    {
        $original = $query->columns;

        if (is_null($query->columns)) {
            $query->columns = ['*'];
        }

        $sql = trim($this->concatenate($this->compileComponents($query)));

        $query->columns = $original;

        return $sql;
    }
1282439
public function mergeBindings(Builder $query)
	{
		$this->bindings = array_values(array_merge($this->bindings, $query->bindings));

		return $this;
	}
655301
protected function setOperation($query, string $operation)
	{
		if(($query instanceof Subquery) === false)
		{
			$query = new Subquery($query);
		}

		$this->setOperations[] =
		[
			'query'     => $query,
			'operation' => $operation,
		];

		return $this;
	}
1042739
protected function addSelectsToQuery(Builder $query, array $selects)
    {
        if (!empty($selects)) {
            $query->selectRaw('max(' . implode(' + ', $selects) . ') as relevance', $this->searchBindings);
        }
    }
15531
protected function functions(&$query)
    {

        switch ($this->mode) {

            case "mysql":
            case "odbc":
            case "sqlite":
                $query = preg_replace("/\bISNULL\(/", "IFNULL(", $query);
                break;

            case "postgres":
            case "redshift":
                $query = preg_replace("/\bI[FS]NULL\(/", "COALESCE(", $query);
                break;

            case "mssql":
            case "mssqlsrv":
                $query = preg_replace("/\bIFNULL\(/", "ISNULL(", $query);
                break;
        }

        switch ($this->mode) {

            case "mysql":
            case "postgres":
            case "redshift":
            case "odbc":
            case "mssql":
            case "mssqlsrv":
                $query = preg_replace("/\bSUBSTR\(/", "SUBSTRING(", $query);
                break;

            case "sqlite":
                $query = preg_replace("/\bSUBSTRING\(/", "SUBSTR(", $query);
                break;
        }

        switch ($this->mode) {

            case "postgres":
            case "redshift":
                $query = preg_replace("/\FROM_UNIXTIME\(([^,\)]+),(\s*)([^\)]+)\)/", "TO_CHAR(ABSTIME($1), $3)", $query);
                break;
        }
    }
617017
public function augmentSQL(SQLSelect $query, DataQuery $dataQuery = null)
    {
        /** @var Locale|null $locale */
        $locale = $this->getDataQueryLocale($dataQuery);
        if (!$locale) {
            return;
        }

        // Rewrite query un-versioned
        parent::augmentSQL($query, $dataQuery);

        // Rewrite based on versioned rules
        if (!$dataQuery->getQueryParam('Versioned.mode')) {
            return;
        }

        $tables = $this->getLocalisedTables();
        $versionedMode = $dataQuery->getQueryParam('Versioned.mode');
        switch ($versionedMode) {
            // Reading a specific stage (Stage or Live)
            case 'stage':
            case 'stage_unique':
                // Rename all localised tables (note: alias remains unchanged). This is only done outside of draft.
                $stage = $dataQuery->getQueryParam('Versioned.stage');
                if ($stage !== Versioned::DRAFT) {
                    $this->renameLocalisedTables($query, $tables);
                }
                break;
            // Return all version instances
            case 'archive':
            case 'all_versions':
            case 'latest_versions':
            case 'latest_version_single':
            case 'version':
                $this->rewriteVersionedTables($query, $tables, $locale);
                break;
            default:
                throw new InvalidArgumentException("Bad value for query parameter Versioned.mode: {$versionedMode}");
        }
    }
363373
public function augmentSQL(SQLSelect $query, DataQuery $dataQuery = null)
    {
        if (!class_exists(Subsite::class)) {
            return;
        }

        if (Subsite::$disable_subsite_filter) {
            return;
        }

        if ($dataQuery && $dataQuery->getQueryParam('Subsite.filter') === false) {
            return;
        }

        if ($query->filtersOnID()) {
            return;
        }

        if (Subsite::$force_subsite) {
            $subsiteID = Subsite::$force_subsite;
        } else {
            $subsiteID = (int) SubsiteState::singleton()->getSubsiteId();
        }

        // Get the base table name
        $elementTableName = DataObject::getSchema()->baseDataTable(BaseElement::class);

        // The foreach is an ugly way of getting the first key :-)
        foreach ($query->getFrom() as $tableName => $info) {
            // The tableName should be Element or Element_Live...
            if (substr($tableName, 0, strlen($elementTableName)) === $elementTableName) {
                $query->addWhere("\"$tableName\".\"SubsiteID\" IN ($subsiteID)");
                break;
            }
        }
    }