protected function explain()
	{
		if ($this->query_sql === null) {
			$this->compile();
		}

		$sql = "\n    EXPLAIN\n" . $this->interpolateQuery($this->query_sql, $this->query_params);

		$explain = $this->pdo->query($sql);

		$data = $explain->fetchAll(\PDO::FETCH_ASSOC);
		$col_len = array();
		$t = "\n";

		// Calculate column widths
		foreach ($data as $row) {
			foreach ($row as $k => $v) {
				$col_len[$k] = isset($col_len[$k]) ? max($col_len[$k], strlen($v)) : strlen($v);
			}
		}
		foreach ($col_len as $k => $len) {
			$col_len[$k] = max($len, strlen($k));
		}

		// Horizontal Line
		foreach ($col_len as $k => $len) {
			$t .= '+'.str_repeat('-', $len + 2);
		}
		$t .= "+\n";

		// Table header
		foreach ($col_len as $k => $len) {
			$t .= sprintf('| %-'.$len.'s ', $k);
		}
		$t .= "+\n";

		// Horizontal Line
		foreach ($col_len as $k => $len) {
			$t .= '+'.str_repeat('-', $len + 2);
		}
		$t .= "+\n";

		// Table body
		foreach ($data as $row) {
			foreach ($row as $k => $v) {
				$t .= sprintf('| %-'.$col_len[$k].'s ', $v);
			}
			$t .= "|\n";
		}

		// Horizontal Line
		foreach ($col_len as $k => $len) {
			$t .= '+'.str_repeat('-', $len + 2);
		}
		$t .= "+\n";

		// Log the table
		if (function_exists('debug_msg')) {
			debug_msg('Explain last query:%s', $t);
		}

		// Make sure EXPLAIN query is destroyed.
		$this->uncompile();
	}