Invoked prior to getFinalisedQuery()

@param DataQuery $dataQuery
@param array $queriedColumns
@param SQLSelect $sqlSelect
338712
public function beforeGetFinalisedQuery(DataQuery $dataQuery, $queriedColumns = [], SQLSelect $sqlSelect)
    {
        // Get metadata and SQL from join table
        $hasManyRelation = $this->getParentRelationship($dataQuery);
        $joinTableSQLSelect = $hasManyRelation->dataQuery()->query();
        $joinTableSQL = $joinTableSQLSelect->sql($joinTableParameters);
        $joinTableColumns = array_keys($joinTableSQLSelect->getSelect()); // Get aliases (keys) only
        $joinTableAlias = $this->getJoinAlias();

        // Get fields to join on
        $localKey = $this->getLocalKey();
        $schema = DataObject::getSchema();
        $baseTable = $schema->baseDataClass($dataQuery->dataClass());
        $childField = $schema->sqlColumnForField($baseTable, 'ID');

        // Add select fields
        foreach ($joinTableColumns as $joinTableColumn) {
            $sqlSelect->selectField(
                "\"{$joinTableAlias}\".\"{$joinTableColumn}\"",
                "{$joinTableAlias}_{$joinTableColumn}"
            );
        }

        // Apply join and record sql for later insertion (at end of replacements)
        // By using a string placeholder $$_SUBQUERY_$$ we protect field/table rewrites from interfering twice
        // on the already-finalised inner list
        $sqlSelect->addInnerJoin(
            '(SELECT $$_SUBQUERY_$$)',
            "\"{$joinTableAlias}\".\"{$localKey}\" = {$childField}",
            $joinTableAlias,
            20,
            $joinTableParameters
        );
        $dataQuery->setQueryParam('Foreign.JoinTableSQL', $joinTableSQL);

        // After this join, and prior to afterGetFinalisedQuery, $sqlSelect will be populated with the
        // necessary sql rewrites (versioned, etc) that effect the base table.
        // By using a placeholder for the subquery we can protect the subquery (already rewritten)
        // from being re-written a second time. However we DO want the join predicate (above) to be rewritten.
        // See http://php.net/manual/en/function.str-replace.php#refsect1-function.str-replace-notes
        // for the reason we only add the final substitution at the end of getFinalisedQuery()
    }
360148
public function getRelationExistenceQueryForSelfRelation(Builder $query, Builder $parentQuery, $columns = ['*'])
    {
        $query->from($query->getModel()->getTable().' as '.$hash = $this->getRelationCountHash());

        $this->performJoin($query);

        $query->getModel()->setTable($hash);

        return $query->select($columns)->whereColumn(
            $parentQuery->getQuery()->from.'.'.$query->getModel()->getKeyName(), '=', $this->getQualifiedFirstKeyName()
        );
    }
459220
public function apply(DataQuery $query)
    {
        if ($this->aggregate) {
            throw new InvalidArgumentException(sprintf(
                'Aggregate functions can only be used with comparison filters. See %s',
                $this->fullName
            ));
        }

        return parent::apply($query);
    }
1048588
public function filterQuery(QueryBuilder &$query, &$selects = null)
    {
        //run the parent method
        parent::filterQuery($query, $selects);

        //get the values
        $value   = $this->getOption('value');
        $table   = $this->getOption('table');
        $column  = $this->getOption('column');
        $column2 = $this->getOption('column2');

        //if there is no value, return
        if (!$value) {
            return;
        }

        $model = $this->config->getDataModel();

        //if the table hasn't been joined yet, join it
        if (!$this->validator->isJoined($query, $table)) {
            $query->join($table, $model->getTable().'.'.$model->getKeyName(), '=', $column);
        }

        //add where clause
        $query->whereIn($column2, $value);

        //add having clauses
        $query->havingRaw('COUNT(DISTINCT '.$query->getConnection()->getTablePrefix().$column2.') = '.count($value));

        //add select field
        if ($selects && !in_array($column2, $selects)) {
            $selects[] = $column2;
        }
    }
401095
protected function applyOne(DataQuery $query)
    {
        $this->model = $query->applyRelation($this->relation);

        $predicate = sprintf("%s %s ?", $this->getDbName(), $this->getOperator());
        $clause = [$predicate => $this->getDbFormattedValue()];

        return $this->aggregate ?
            $this->applyAggregate($query, $clause) :
            $query->where($clause);
    }
525138
public function augmentSQL(SQLSelect $query, DataQuery $dataQuery = null)
    {
        if (Subsite::$disable_subsite_filter) {
            return;
        }
        if ($dataQuery && $dataQuery->getQueryParam('Subsite.filter') === false) {
            return;
        }

        // If you're querying by ID, ignore the sub-site - this is a bit ugly...
        // if(!$query->where
        // || (strpos($query->where[0], ".\"ID\" = ") === false
        // && strpos($query->where[0], ".`ID` = ") === false && strpos($query->where[0], ".ID = ") === false
        // && strpos($query->where[0], "ID = ") !== 0)) {
        if ($query->filtersOnID()) {
            return;
        }

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

        if ($subsiteID === null) {
            return;
        }

        // The foreach is an ugly way of getting the first key :-)
        foreach ($query->getFrom() as $tableName => $info) {
            // The tableName should be SiteTree or SiteTree_Live...
            $siteTreeTableName = SiteTree::getSchema()->tableName(SiteTree::class);
            if (strpos($tableName, $siteTreeTableName) === false) {
                break;
            }
            $query->addWhere("\"$tableName\".\"SubsiteID\" IN ($subsiteID)");
            break;
        }
    }
1204151
public function postSelect(StatementInterface $statement, ResultInterface $result, ResultSetInterface $resultSet)
    {
        if ($this->getDmsColumns())
            // We have used the query with presented Predefined DMS Columns
            // Nothing to do
            return;

        $storedValues = $this->getStoredValues();
        $pkColumn     = $storedValues['pk'];

        $totalResultSet = array();
        foreach($resultSet as $rc)
        {
            if (!$rc instanceof iDataSetConveyor)
                throw new \Exception(sprintf(
                    'ResultSet must instance of iDataSetConveyor to DmsFeature interact to. "%s" given.'
                    , get_class($rc)
                ));

            $rc = $rc->toArray();

            $pk = $rc[$pkColumn]; // get pk column value
            foreach ($rc as $c => $v) {
                // iterate trough result containing duplicated rows because of join over dms values
                if ($c == 'dms__content' || $c == 'dms__field')
                    // dms virtual columns avoided and set as field->content
                    continue;

                if ($c == $pkColumn
                    && (!in_array($pkColumn, $storedValues['columns'])
                        && !in_array('*', $storedValues['columns'])
                    )
                )
                    continue;


                $totalResultSet[$pk][$c] = $v;
            }

            if (isset($rc['dms__content']) && isset($rc['dms__field'])) {
                if (in_array($rc['dms__field'], $storedValues['columns'])
                    || in_array('*', $storedValues['columns'])
                )
                {
                    $column = $rc['dms__field'];
                    $value  = $rc['dms__content'];
                    $totalResultSet[$pk][$column] = $value;
                }

                unset($rc['dms__field']);
                unset($rc['dms__content']);
            }
        }

        $resultSet->initialize($totalResultSet);
    }
80553
public function setPaginationFromQuery(SQLSelect $query)
    {
        if ($limit = $query->getLimit()) {
            $this->setPageLength($limit['limit']);
            $this->setPageStart($limit['start']);
            $this->setTotalItems($query->unlimitedRowCount());
        }
        return $this;
    }
1370142
public function processQuery(Query $query, $knownTables): Query
    {
        foreach ($this->getTables($query) as $table) {
            $knownTables[] = $table;
        }

        return parent::processQuery($query, $knownTables);
    }
840842
protected function selectColumnsFromTable(SQLSelect &$query, $tableClass, $columns = null)
    {
        // Add SQL for multi-value fields
        $schema = DataObject::getSchema();
        $databaseFields = $schema->databaseFields($tableClass, false);
        $compositeFields = $schema->compositeFields($tableClass, false);
        unset($databaseFields['ID']);
        foreach ($databaseFields as $k => $v) {
            if ((is_null($columns) || in_array($k, $columns)) && !isset($compositeFields[$k])) {
                // Update $collidingFields if necessary
                $expressionForField = $query->expressionForField($k);
                $quotedField = $schema->sqlColumnForField($tableClass, $k);
                if ($expressionForField) {
                    if (!isset($this->collidingFields[$k])) {
                        $this->collidingFields[$k] = array($expressionForField);
                    }
                    $this->collidingFields[$k][] = $quotedField;
                } else {
                    $query->selectField($quotedField, $k);
                }
            }
        }
        foreach ($compositeFields as $k => $v) {
            if ((is_null($columns) || in_array($k, $columns)) && $v) {
                $tableName = $schema->tableName($tableClass);
                $dbO = Injector::inst()->create($v, $k);
                $dbO->setTable($tableName);
                $dbO->addToQuery($query);
            }
        }
    }
510893
private void proceedWithQuery
  (PreparedStatement queryStmt, DataSet ds) throws SQLException {
    if (queryArgs != null && queryArgs.length > 0) {
      for (int i=0; i < queryArgs.length; i++) {
        queryStmt.setObject(i + 1, queryArgs[i]);
      }
    }
    try(ResultSet rs = queryStmt.executeQuery()) {
      int colCount = metaData.getColumnCount();
      while (rs.next()) {
        Object[] data = new Object[colCount];
        for (int i = 0; i < colCount; i++) {  
          data[i] = rs.getObject(i+1);
        }
        ds.addRow(new Row(data));
      }
    }
  }
671914
private void validateSelectQuery(final String selectQuery) {
        final SimpleDBParser parser = new SimpleDBParser(selectQuery);
        try {
            parser.selectQuery();
        } catch (Exception e) {
            throw new InvalidSimpleDBQueryException("The following query is an invalid SimpleDB query: " + selectQuery,
                    e);
        }
    }
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}");
        }
    }
106995
protected static function multiQuery(string $queries): void
  {
    if (self::$logQueries)
    {
      $time0 = microtime(true);

      $tmp = self::$mysqli->multi_query($queries);
      if ($tmp===false)
      {
        throw new DataLayerException(self::$mysqli->errno, self::$mysqli->error, $queries);
      }

      self::$queryLog[] = ['query' => $queries, 'time' => microtime(true) - $time0];
    }
    else
    {
      $tmp = self::$mysqli->multi_query($queries);
      if ($tmp===false)
      {
        throw new DataLayerException(self::$mysqli->errno, self::$mysqli->error, $queries);
      }
    }
  }
310292
public function augmentLoadLazyFields(SQLSelect &$query, DataQuery &$dataQuery = null, $dataObject)
    {
        // The VersionedMode local variable ensures that this decorator only applies to
        // queries that have originated from the Versioned object, and have the Versioned
        // metadata set on the query object. This prevents regular queries from
        // accidentally querying the *_Versions tables.
        $versionedMode = $dataObject->getSourceQueryParam('Versioned.mode');
        $modesToAllowVersioning = ['all_versions', 'latest_versions', 'archive', 'version'];
        if (!empty($dataObject->Version) &&
            (!empty($versionedMode) && in_array($versionedMode, $modesToAllowVersioning))
        ) {
            // This will ensure that augmentSQL will select only the same version as the owner,
            // regardless of how this object was initially selected
            $versionColumn = $this->owner->getSchema()->sqlColumnForField($this->owner, 'Version');
            $dataQuery->where([
                $versionColumn => $dataObject->Version
            ]);
            $dataQuery->setQueryParam('Versioned.mode', 'all_versions');
        }
    }
500872
public function select( $query, $bindings = [] )
	{
		$query = $this->bind_params( $query, $bindings );

		$result = $this->db->get_results( $query );

		if ( $result === false || $this->db->last_error ) {
			throw new QueryException( $query, $bindings, new \Exception( $this->db->last_error ) );
		}

		return $result;
	}
1177637
protected function getDataQueryLocale(DataQuery $dataQuery = null)
    {
        if (!$dataQuery) {
            return null;
        }
        $localeCode = $dataQuery->getQueryParam('Fluent.Locale') ?: FluentState::singleton()->getLocale();
        if ($localeCode) {
            return Locale::getByLocale($localeCode);
        }
        return null;
    }