protected function guess_id_field_from_sql(string $sql) : string {
        // We are not interested in any subquery/view/conditions for the purpose of this method, so
        // let's reduce the query to the interesting parts by recursively cleaning all
        // contents within parenthesis. If there are problems (null), we keep the text unmodified.
        // So just top-level sql will remain after the reduction.
        $recursiveregexp = '/\((([^()]*|(?R))*)\)/';
        $sql = (preg_replace($recursiveregexp, '', $sql) ?: $sql);
        // Get the list of relevant words from the SQL Query.
        // We explode the SQL by the space character, then trim any extra whitespace (e.g. newlines), before we filter
        // empty value, and finally we re-index the array.
        $sql = rtrim($sql, ';');
        $words = array_map('trim', preg_split('/\s+/', $sql));
        $words = array_filter($words, function($word) {
            return $word !== '';
        });
        $words = array_values($words);
        $uwords = array_map('strtoupper', $words); // Uppercase all them.

        // If the query has boolean operators (UNION, it is the only one we support cross-db)
        // then we cannot guarantee whats coming after the first query, it can be anything.
        if (array_search('UNION', $uwords)) {
            return '';
        }

        if ($firstfrom = array_search('FROM', $uwords)) {
            // Found a FROM keyword.
            // Select the previous word.
            $fieldname = $words[$firstfrom - 1];
            if (is_numeric($fieldname)) {
                return $fieldname;
            }

            if ($hasdot = strpos($fieldname, '.')) {
                // This field is against a table alias. Take off the alias.
                $fieldname = substr($fieldname, $hasdot + 1);
            }

            return $fieldname;

        } else if ((count($words) == 1) && (is_numeric($words[0]))) {
            // Not a real SQL, just a single numerical value - such as one returned by {@link self::add_system_context()}.
            return $words[0];

        } else if ((count($words) == 2) && (strtoupper($words[0]) === 'SELECT') && (is_numeric($words[1]))) {
            // SQL returning a constant numerical value.
            return $words[1];
        }

        return '';
    }
protected function guess_id_field_from_sql(string $sql) : string {
        // We are not interested in any subquery/view/conditions for the purpose of this method, so
        // let's reduce the query to the interesting parts by recursively cleaning all
        // contents within parenthesis. If there are problems (null), we keep the text unmodified.
        // So just top-level sql will remain after the reduction.
        $recursiveregexp = '/\((([^()]*|(?R))*)\)/';
        $sql = (preg_replace($recursiveregexp, '', $sql) ?: $sql);
        // Get the list of relevant words from the SQL Query.
        // We explode the SQL by the space character, then trim any extra whitespace (e.g. newlines), before we filter
        // empty value, and finally we re-index the array.
        $sql = rtrim($sql, ';');
        $words = array_map('trim', preg_split('/\s+/', $sql));
        $words = array_filter($words, function($word) {
            return $word !== '';
        });
        $words = array_values($words);
        $uwords = array_map('strtoupper', $words); // Uppercase all them.

        // If the query has boolean operators (UNION, it is the only one we support cross-db)
        // then we cannot guarantee whats coming after the first query, it can be anything.
        if (array_search('UNION', $uwords)) {
            return '';
        }

        if ($firstfrom = array_search('FROM', $uwords)) {
            // Found a FROM keyword.
            // Select the previous word.
            $fieldname = $words[$firstfrom - 1];
            if (is_numeric($fieldname)) {
                return $fieldname;
            }

            if ($hasdot = strpos($fieldname, '.')) {
                // This field is against a table alias. Take off the alias.
                $fieldname = substr($fieldname, $hasdot + 1);
            }

            return $fieldname;

        } else if ((count($words) == 1) && (is_numeric($words[0]))) {
            // Not a real SQL, just a single numerical value - such as one returned by {@link self::add_system_context()}.
            return $words[0];

        } else if ((count($words) == 2) && (strtoupper($words[0]) === 'SELECT') && (is_numeric($words[1]))) {
            // SQL returning a constant numerical value.
            return $words[1];
        }

        return '';
    }
protected function guess_id_field_from_sql ( string $ sql ) : string { // We are not interested in any subquery/view/conditions for the purpose of this method, so // let's reduce the query to the interesting parts by recursively cleaning all // contents within parenthesis. If there are problems (null), we keep the text unmodified. // So just top-level sql will remain after the reduction. $ recursiveregexp = '/\((([^()]*|(?R))*)\)/' ; $ sql = ( preg_replace ( $ recursiveregexp , '' , $ sql ) ? : $ sql ) ; // Get the list of relevant words from the SQL Query. // We explode the SQL by the space character, then trim any extra whitespace (e.g. newlines), before we filter // empty value, and finally we re-index the array. $ sql = rtrim ( $ sql , ';' ) ; $ words = array_map ( 'trim' , preg_split ( '/\s+/' , $ sql ) ) ; $ words = array_filter ( $ words , function ( $ word ) { return $ word !== '' ; } ) ; $ words = array_values ( $ words ) ; $ uwords = array_map ( 'strtoupper' , $ words ) ; // Uppercase all them. // If the query has boolean operators (UNION, it is the only one we support cross-db) // then we cannot guarantee whats coming after the first query, it can be anything. if ( array_search ( 'UNION' , $ uwords ) ) { return '' ; } if ( $ firstfrom = array_search ( 'FROM' , $ uwords ) ) { // Found a FROM keyword. // Select the previous word. $ fieldname = $ words [ $ firstfrom - 1 ] ; if ( is_numeric ( $ fieldname ) ) { return $ fieldname ; } if ( $ hasdot = strpos ( $ fieldname , '.' ) ) { // This field is against a table alias. Take off the alias. $ fieldname = substr ( $ fieldname , $ hasdot + 1 ) ; } return $ fieldname ; } else if ( ( count ( $ words ) == 1 ) && ( is_numeric ( $ words [ 0 ] ) ) ) { // Not a real SQL, just a single numerical value - such as one returned by {@link self::add_system_context()}. return $ words [ 0 ] ; } else if ( ( count ( $ words ) == 2 ) && ( strtoupper ( $ words [ 0 ] ) === 'SELECT' ) && ( is_numeric ( $ words [ 1 ] ) ) ) { // SQL returning a constant numerical value. return $ words [ 1 ] ; } return '' ; }
Guess the name of the contextid field from the supplied SQL.

@param   string  $sql The SQL to guess from
@return  string  The field name or a numeric value representing the context id
Guess the name of the contextid field from the supplied SQL .