private function tokenizeSQL($sql): array
    {
        $token = '\\(|\\)|\[|\]|[\']|"|\140|<>|<=|>=|:=|[*\/<>,+=-]';
        $terminal = $token.'|;| |\\n';
        $result = [];
        $string = $sql;
        $string = ltrim($string);
        $string = rtrim($string, ';').';'; // always ends with a terminal
        $string = preg_replace("/[\n\r]/s", ' ', $string);
        while (
            preg_match("/^($token)($terminal)/s", $string, $matches) ||
            preg_match("/^({$token})./s", $string, $matches) ||
            preg_match("/^(@?[a-zA-Z0-9_.]+?)($terminal)/s", $string, $matches)
        ) {
            $t = $matches[1];
            if ($t == '\'') {
                // it's a string
                $t = $this->tokSingleQuoteString($string);
                array_push($result, $t);
            }
            elseif ($t == "\140") {
                // it's a backtick string (a name)
                $t = $this->tokBackQuoteString($string);
                array_push($result, $t);
            }
            elseif ($t == '"') {
                // it's a double quoted string (a name in normal sql)
                $t = $this->tokDoubleQuoteString($string);
                array_push($result, $t);
            }
            else {
                array_push($result, $t);
            }
            $string = substr($string, strlen($t));
            $string = ltrim($string);
        }
        return $result;
    }