#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
#
# Impala's shell
from __future__ import print_function, unicode_literals
from compatibility import _xrange as xrange

import cmd
import errno
import getpass
import os
import prettytable
import random
import re
import shlex
import signal
import socket
import sqlparse
import subprocess
import sys
import textwrap
import time
import traceback

from impala_client import ImpalaHS2Client, ImpalaBeeswaxClient, QueryOptionLevels
from impala_shell_config_defaults import impala_shell_defaults
from option_parser import get_option_parser, get_config_from_file
from shell_output import (DelimitedOutputFormatter, OutputStream, PrettyOutputFormatter,
                          OverwritingStdErrOutputStream)
from subprocess import call
from shell_exceptions import (RPCException, DisconnectedException, QueryStateException,
    QueryCancelledByShellException, MissingThriftMethodException)


VERSION_FORMAT = "Impala Shell v%(version)s (%(git_hash)s) built on %(build_date)s"
VERSION_STRING = "impala shell build version not available"
READLINE_UNAVAILABLE_ERROR = "The readline module was either not found or disabled. " \
                             "Command history will not be collected."

# Tarball / packaging build makes impala_build_version available
try:
  from impala_build_version import get_git_hash, get_build_date, get_version
  VERSION_STRING = VERSION_FORMAT % {'version': get_version(),
                                     'git_hash': get_git_hash()[:7],
                                     'build_date': get_build_date()}
except Exception:
  pass

DEFAULT_BEESWAX_PORT = 21000
DEFAULT_HS2_PORT = 21050
DEFAULT_HS2_HTTP_PORT = 28000


def strip_comments(sql):
  """sqlparse default implementation of strip comments has a bad performance when parsing
  very large SQL due to the grouping. This is because the default implementation tries to
  format the SQL for pretty-printing. Impala shell use of strip comments is mostly for
  checking and not for altering the actual SQL, so having a pretty-formatted SQL is
  irrelevant in Impala shell. Removing the grouping gives a significant performance boost.
  """
  stack = sqlparse.engine.FilterStack()
  stack.stmtprocess.append(sqlparse.filters.StripCommentsFilter())
  stack.postprocess.append(sqlparse.filters.SerializerUnicode())
  return ''.join(stack.run(sql, 'utf-8')).strip()


class CmdStatus:
  """Values indicate the execution status of a command to the cmd shell driver module
  SUCCESS and ERROR continue running the shell and ABORT exits the shell
  Since SUCCESS == None, successful commands do not need to explicitly return
  anything on completion
  """
  SUCCESS = None
  ABORT = True
  ERROR = False


class FatalShellException(Exception):
  """Thrown if a fatal error occurs that requires terminating the shell. The cause of the
  error should be logged to stderr before raising this exception."""
  pass


class QueryOptionDisplayModes:
  REGULAR_OPTIONS_ONLY = 1
  ALL_OPTIONS = 2


# Py3 method resolution order requires 'object' to be last w/ multiple inheritance
class ImpalaShell(cmd.Cmd, object):
  """ Simple Impala Shell.

  Implements the context manager interface to ensure client connections and sessions
  are cleanly torn down. ImpalaShell instances should be used within a "with" statement
  to ensure correct teardown.

  Basic usage: type connect <host:port> to connect to an impalad
  Then issue queries or other commands. Tab-completion should show the set of
  available commands.
  Methods that implement shell commands return a boolean tuple (stop, status)
  stop is a flag the command loop uses to continue/discontinue the prompt.
  Status tells the caller that the command completed successfully.
  """

  # If not connected to an impalad, the server version is unknown.
  UNKNOWN_SERVER_VERSION = "Not Connected"
  PROMPT_FORMAT = "[{host}:{port}] {db}> "
  DISCONNECTED_PROMPT = "[Not connected] > "
  # Message to display in shell when cancelling a query
  CANCELLATION_MESSAGE = ' Cancelling Query'
  # Number of times to attempt cancellation before giving up.
  CANCELLATION_TRIES = 3
  # Commands are terminated with the following delimiter.
  CMD_DELIM = ';'
  # Valid variable name pattern
  VALID_VAR_NAME_PATTERN = r'[A-Za-z][A-Za-z0-9_]*'
  # Pattern for removal of comments preceding SET commands
  COMMENTS_BEFORE_SET_PATTERN = r'^(\s*/\*(.|\n)*?\*/|\s*--.*\n)*\s*((un)?set)'
  COMMENTS_BEFORE_SET_REPLACEMENT = r'\3'
  # Variable names are prefixed with the following string
  VAR_PREFIXES = [ 'VAR', 'HIVEVAR' ]
  DEFAULT_DB = 'default'
  # Regex applied to all tokens of a query to detect DML statements.
  DML_REGEX = re.compile("^(insert|upsert|update|delete)$", re.I)
  # Seperator for queries in the history file.
  HISTORY_FILE_QUERY_DELIM = '_IMP_DELIM_'
  # Strings that are interpreted as True for some shell options.
  TRUE_STRINGS = ("true", "TRUE", "True", "1")
  # List of quit commands
  QUIT_COMMANDS = ("quit", "exit")

  VALID_SHELL_OPTIONS = {
    'LIVE_PROGRESS': (lambda x: x in ImpalaShell.TRUE_STRINGS, "live_progress"),
    'LIVE_SUMMARY': (lambda x: x in ImpalaShell.TRUE_STRINGS, "live_summary"),
    'WRITE_DELIMITED' : (lambda x: x in ImpalaShell.TRUE_STRINGS, "write_delimited"),
    'VERBOSE' : (lambda x: x in ImpalaShell.TRUE_STRINGS, "verbose"),
    'DELIMITER' : (lambda x: " " if x == '\\s' else x, "output_delimiter"),
    'OUTPUT_FILE' : (lambda x: None if x == '' else x, "output_file"),
  }

  # Minimum time in seconds between two calls to get the exec summary.
  PROGRESS_UPDATE_INTERVAL = 1.0
  # Environment variable used to source a global config file
  GLOBAL_CONFIG_FILE = "IMPALA_SHELL_GLOBAL_CONFIG_FILE"

  def __init__(self, options, query_options):
    cmd.Cmd.__init__(self)
    self.is_alive = True

    self.impalad = None
    self.kerberos_host_fqdn = options.kerberos_host_fqdn
    self.use_kerberos = options.use_kerberos
    self.kerberos_service_name = options.kerberos_service_name
    self.use_ssl = options.ssl
    self.ca_cert = options.ca_cert
    self.user = options.user
    self.ldap_password = options.ldap_password
    self.ldap_password_cmd = options.ldap_password_cmd
    self.use_ldap = options.use_ldap
    self.client_connect_timeout_ms = options.client_connect_timeout_ms
    self.verbose = options.verbose
    self.prompt = ImpalaShell.DISCONNECTED_PROMPT
    self.server_version = ImpalaShell.UNKNOWN_SERVER_VERSION
    self.webserver_address = None

    self.current_db = options.default_db
    self.history_file = os.path.expanduser(options.history_file)
    # Stores the state of user input until a delimiter is seen.
    self.partial_cmd = str()
    # Stores the old prompt while the user input is incomplete.
    self.cached_prompt = str()

    self.show_profiles = options.show_profiles

    # Output formatting flags/options
    self.output_file = options.output_file
    self.output_delimiter = " " if options.output_delimiter == "\\s" \
        else options.output_delimiter
    self.write_delimited = options.write_delimited
    self.print_header = options.print_header

    self.progress_stream = OverwritingStdErrOutputStream()

    self.set_query_options = query_options
    self.set_variables = options.variables

    self._populate_command_list()

    self.imp_client = None

    # Used to pass the original unmodified command into do_*() methods.
    self.orig_cmd = None

    # Tracks query handle of the last query executed. Used by the 'profile' command.
    self.last_query_handle = None;

    self.live_summary = options.live_summary
    self.live_progress = options.live_progress

    self.ignore_query_failure = options.ignore_query_failure

    self.http_path = options.http_path
    self.fetch_size = options.fetch_size

    # Due to a readline bug in centos/rhel7, importing it causes control characters to be
    # printed. This breaks any scripting against the shell in non-interactive mode. Since
    # the non-interactive mode does not need readline - do not import it.
    if options.query or options.query_file:
      self.interactive = False
      self._disable_readline()
    else:
      self.interactive = True
      try:
        self.readline = __import__('readline')
        try:
          self.readline.set_history_length(int(options.history_max))
          # The history file is created when the Impala shell is invoked and commands are
          # issued. In case it does not exist do not read the history file.
          if os.path.exists(self.history_file):
            self.readline.read_history_file(self.history_file)
            self._replace_history_delimiters(ImpalaShell.HISTORY_FILE_QUERY_DELIM, '\n')
        except ValueError:
          warning = "WARNING: history_max option malformed %s\n" % options.history_max
          print(warning, file=sys.stderr)
          self.readline.set_history_length(1000)
        except IOError as i:
          warning = "WARNING: Unable to load command history (disabling impala-shell " \
              "command history): %s" % i
          print(warning, file=sys.stderr)
          # This history file exists but is not readable, disable readline.
          self._disable_readline()
      except ImportError as i:
        warning = "WARNING: Unable to import readline module (disabling impala-shell " \
            "command history): %s" % i
        print(warning, file=sys.stderr)
        self._disable_readline()

    if options.impalad is not None:
      self.do_connect(options.impalad)
      # Check if the database in shell option exists
      self._validate_database(immediately=True)

    # We handle Ctrl-C ourselves, using an Event object to signal cancellation
    # requests between the handler and the main shell thread.
    signal.signal(signal.SIGINT, self._signal_handler)

  def __enter__(self):
    return self

  def __exit__(self, type, value, traceback):
    self.close_connection()

  def _populate_command_list(self):
    """Populate a list of commands in the shell.

    Each command has its own method of the form do_<command>, and can be extracted by
    introspecting the class directory.
    """
    # Slice the command method name to get the name of the command.
    self.commands = [cmd[3:] for cmd in dir(self.__class__) if cmd.startswith('do_')]

  def _disable_readline(self):
    """Disables the readline module.

    The readline module is responsible for keeping track of command history.
    """
    self.readline = None

  def _print_options(self, print_mode):
    """Prints the current query options with default values distinguished from set values
    by brackets [], followed by shell-local options.
    The options are displayed in groups based on option levels received in parameter.
    Input parameter decides whether all groups or just the 'Regular' and 'Advanced'
    options are displayed."""
    print("Query options (defaults shown in []):")
    if not self.imp_client.default_query_options and not self.set_query_options:
      print('\tNo options available.')
    else:
      (regular_options, advanced_options, development_options, deprecated_options,
          removed_options) = self._get_query_option_grouping()
      self._print_option_group(regular_options)
      # If the shell is connected to an Impala that predates IMPALA-2181 then
      # the advanced_options would be empty and only the regular options would
      # be displayed.
      if advanced_options:
        print('\nAdvanced Query Options:')
        self._print_option_group(advanced_options)
      if print_mode == QueryOptionDisplayModes.ALL_OPTIONS:
        if development_options:
          print('\nDevelopment Query Options:')
          self._print_option_group(development_options)
        if deprecated_options:
          print('\nDeprecated Query Options:')
          self._print_option_group(deprecated_options)
    self._print_shell_options()

  def _get_query_option_grouping(self):
    """For all the query options received through rpc this function determines the
    query option level for display purposes using the received query_option_levels
    parameters.
    If the option level can't be determined then it defaults to 'REGULAR'"""
    (regular_options, advanced_options, development_options, deprecated_options,
        removed_options) = {}, {}, {}, {}, {}
    if sys.version_info.major < 3:
      client_default_query_opts = self.imp_client.default_query_options.iteritems()
    else:
      client_default_query_opts = self.imp_client.default_query_options.items()
    for option_name, option_value in client_default_query_opts:
      level = self.imp_client.query_option_levels.get(option_name,
                                                      QueryOptionLevels.REGULAR)
      if level == QueryOptionLevels.REGULAR:
        regular_options[option_name] = option_value
      elif level == QueryOptionLevels.DEVELOPMENT:
        development_options[option_name] = option_value
      elif level == QueryOptionLevels.DEPRECATED:
        deprecated_options[option_name] = option_value
      elif level == QueryOptionLevels.REMOVED:
        removed_options[option_name] = option_value
      else:
        advanced_options[option_name] = option_value
    return (regular_options, advanced_options, development_options, deprecated_options,
            removed_options)

  def _print_option_group(self, query_options):
    """Gets query options and prints them. Value is inside [] for the ones having
    default values.
    query_options parameter is a subset of the default_query_options map"""
    for option in sorted(query_options):
      if (option in self.set_query_options and
          self.set_query_options[option] != query_options[option]):  # noqa
        print('\n'.join(["\t%s: %s" % (option, self.set_query_options[option])]))
      else:
        print('\n'.join(["\t%s: [%s]" % (option, query_options[option])]))

  def _print_variables(self):
    # Prints the currently defined variables.
    if not self.set_variables:
      print('\tNo variables defined.')
    else:
      for k in sorted(self.set_variables):
        print('\n'.join(["\t%s: %s" % (k, self.set_variables[k])]))

  def _print_shell_options(self):
    """Prints shell options, which are local and independent of query options."""
    print("\nShell Options")
    for x in self.VALID_SHELL_OPTIONS:
      print("\t%s: %s" % (x, self.__dict__[self.VALID_SHELL_OPTIONS[x][1]]))

  def _build_query_string(self, leading_comment, cmd, args):
    """Called to build a query string based on the parts output by parseline():
    the leading comment, the command name and the arguments to the command."""
    # In order to deduce the correct cmd, parseline stripped the leading comment.
    # To preserve the original query, the leading comment (if exists) will be
    # prepended when constructing the query sent to the Impala front-end.
    return "{0}{1} {2}".format(leading_comment or '', cmd or '', args)

  def do_shell(self, args):
    """Run a command on the shell
    Usage: shell <cmd>
           ! <cmd>

    """
    try:
      start_time = time.time()
      os.system(args)
      self._print_if_verbose("--------\nExecuted in %2.2fs" % (time.time() - start_time))
    except Exception as e:
      print('Error running command : %s' % e, file=sys.stderr)
      return CmdStatus.ERROR

  def _remove_comments_before_set(self, line):
    """SET commands preceded by a comment become a SET query, which are not processed
       locally. SET VAR:* commands must be processed locally, since they are not known
       to the frontend. Thus, we remove comments that precede SET commands to enforce the
       local processing."""
    regexp = re.compile(ImpalaShell.COMMENTS_BEFORE_SET_PATTERN, re.IGNORECASE)
    return regexp.sub(ImpalaShell.COMMENTS_BEFORE_SET_REPLACEMENT, line, 1)

  def sanitise_input(self, args):
    # A command terminated by a semi-colon is legal. Check for the trailing
    # semi-colons and strip them from the end of the command.
    if not self.interactive:
      # Strip all the non-interactive commands of the delimiter.
      args = self._remove_comments_before_set(args)
      tokens = args.strip().split(' ')
      return ' '.join(tokens).rstrip(ImpalaShell.CMD_DELIM)
    # Handle EOF if input is interactive
    tokens = args.strip().split(' ')
    if tokens[0].lower() == 'eof':
      if not self.partial_cmd:
        # The first token is the command.
        # If it's EOF, call do_quit()
        return 'quit'
      else:
        # If a command is in progress and the user hits a Ctrl-D, clear its state
        # and reset the prompt.
        self.prompt = self.cached_prompt
        self.partial_cmd = str()
        # The print statement makes the new prompt appear in a new line.
        # Also print an extra newline to indicate that the current command has
        # been cancelled.
        print('\n')
        return str()
    args = self._check_for_command_completion(args)
    args = self._remove_comments_before_set(args)
    tokens = args.strip().split(' ')
    args = ' '.join(tokens).strip()
    return args.rstrip(ImpalaShell.CMD_DELIM)

  def _shlex_split(self, line):
    """Reimplement shlex.split() so that escaped single quotes
    are actually escaped. shlex.split() only escapes double quotes
    by default. This method will throw a ValueError if an open
    quotation (either single or double) is found.
    """
    my_split = shlex.shlex(line, posix=True)
    my_split.escapedquotes = '"\''
    my_split.whitespace_split = True
    my_split.commenters = ''
    return list(my_split)

  def _cmd_ends_with_delim(self, line):
    """Check if the input command ends with a command delimiter.

    A command ending with the delimiter and containing an open quotation character is
    not considered terminated. If no open quotation is found, it's considered
    terminated.
    """
    # Strip any comments to make a statement such as the following be considered as
    # ending with a delimiter:
    # select 1 + 1; -- this is a comment
    line = strip_comments(line).rstrip()
    if line.endswith(ImpalaShell.CMD_DELIM):
      try:
        # Look for an open quotation in the entire command, and not just the
        # current line.
        if self.partial_cmd:
          line = strip_comments('%s %s' % (self.partial_cmd, line))
        self._shlex_split(line)
        return True
      # If the command ends with a delimiter, check if it has an open quotation.
      # shlex in self._split() throws a ValueError iff an open quotation is found.
      # A quotation can either be a single quote or a double quote.
      except ValueError:
        pass

    # This checks to see if there are any backslashed quotes
    # outside of quotes, since backslashed quotes
    # outside of single or double quotes should not be escaped.
    # Ex. 'abc\'xyz' -> closed because \' is escaped
    #     \'abcxyz   -> open because \' is not escaped
    #     \'abcxyz'  -> closed
    # Iterate through the line and switch the state if a single or double quote is found
    # and ignore escaped single and double quotes if the line is considered open (meaning
    # a previous single or double quote has not been closed yet)
      state_closed = True
      opener = None
      for i, char in enumerate(line):
        if state_closed and (char in ['\'', '\"']):
          state_closed = False
          opener = char
        elif not state_closed and opener == char:
          if line[i - 1] != '\\':
            state_closed = True
            opener = None

      return state_closed

    return False

  def _check_for_command_completion(self, cmd):
    """Check for a delimiter at the end of user input.

    The end of the user input is scanned for a legal delimiter.
    If a delimiter is not found:
      - Input is not send to onecmd()
        - onecmd() is a method in Cmd which routes the user input to the
          appropriate method. An empty string results in a no-op.
      - Input is removed from history.
      - Input is appended to partial_cmd
    If a delimiter is found:
      - The contents of partial_cmd are put in history, as they represent
        a completed command.
      - The contents are passed to the appropriate method for execution.
      - partial_cmd is reset to an empty string.
    """
    if self.readline: current_history_len = self.readline.get_current_history_length()
    # Input is incomplete, store the contents and do nothing.
    if not self._cmd_ends_with_delim(cmd):
      # The user input is incomplete, change the prompt to reflect this.
      if not self.partial_cmd and cmd:
        self.cached_prompt = self.prompt
        self.prompt = '> '.rjust(len(self.cached_prompt))

      # partial_cmd is already populated, add the current input after a newline.
      if self.partial_cmd and cmd:
        self.partial_cmd = "{0}\n{1}".format(self.partial_cmd, cmd)
      else:
        # If the input string is empty or partial_cmd is empty.
        self.partial_cmd = "{0}{1}".format(self.partial_cmd, cmd)
      # Remove the most recent item from history if:
      #   -- The current state of user input in incomplete.
      #   -- The most recent user input is not an empty string
      if self.readline and current_history_len > 0 and cmd:
        self.readline.remove_history_item(current_history_len - 1)
      # An empty string results in a no-op. Look at emptyline()
      return str()
    elif self.partial_cmd:  # input ends with a delimiter and partial_cmd is not empty
      if cmd != ImpalaShell.CMD_DELIM:
        completed_cmd = "{0}\n{1}".format(self.partial_cmd, cmd)
      else:
        completed_cmd = "{0}{1}".format(self.partial_cmd, cmd)
      # Reset partial_cmd to an empty string
      self.partial_cmd = str()
      # Replace the most recent history item with the completed command.
      completed_cmd = sqlparse.format(completed_cmd)
      if self.readline and current_history_len > 0:
        if sys.version_info.major == 2:
          completed_cmd = completed_cmd.encode('utf-8')
        self.readline.replace_history_item(current_history_len - 1, completed_cmd)
      # Revert the prompt to its earlier state
      self.prompt = self.cached_prompt
    else:  # Input has a delimiter and partial_cmd is empty
      completed_cmd = sqlparse.format(cmd)
    return completed_cmd

  def _new_impala_client(self):
    protocol = options.protocol.lower()
    if protocol == 'hs2':
      return ImpalaHS2Client(self.impalad, self.fetch_size, self.kerberos_host_fqdn,
                          self.use_kerberos, self.kerberos_service_name, self.use_ssl,
                          self.ca_cert, self.user, self.ldap_password, self.use_ldap,
                          self.client_connect_timeout_ms, self.verbose,
                          use_http_base_transport=False, http_path=self.http_path)
    elif protocol == 'hs2-http':
      return ImpalaHS2Client(self.impalad, self.fetch_size, self.kerberos_host_fqdn,
                          self.use_kerberos, self.kerberos_service_name, self.use_ssl,
                          self.ca_cert, self.user, self.ldap_password, self.use_ldap,
                          self.client_connect_timeout_ms, self.verbose,
                          use_http_base_transport=True, http_path=self.http_path)
    elif protocol == 'beeswax':
      return ImpalaBeeswaxClient(self.impalad, self.fetch_size, self.kerberos_host_fqdn,
                          self.use_kerberos, self.kerberos_service_name, self.use_ssl,
                          self.ca_cert, self.user, self.ldap_password, self.use_ldap,
                          self.client_connect_timeout_ms, self.verbose)
    else:
      err_msg = "Invalid --protocol value {0}, must be beeswax, hs2 or hs2-http."
      print(err_msg.format(protocol), file=sys.stderr)
      raise FatalShellException()

  def close_connection(self):
    """Closes the current Impala connection."""
    if self.imp_client:
      self.imp_client.close_connection()

  def _signal_handler(self, signal, frame):
    """Handles query cancellation on a Ctrl+C event"""
    if self.last_query_handle is None or self.last_query_handle.is_closed:
      if self.partial_cmd:
        # Revert the prompt to its earlier state
        self.prompt = self.cached_prompt
        # Reset the already given commands
        self.partial_cmd = str()
      raise KeyboardInterrupt()
    # Create a new connection to the impalad and cancel the query.
    # TODO: this isn't thread-safe with respect to the main thread executing the
    # query. This probably contributes to glitchiness when cancelling query in
    # the shell.
    for cancel_try in xrange(ImpalaShell.CANCELLATION_TRIES):
      try:
        self.imp_client.is_query_cancelled = True
        print(ImpalaShell.CANCELLATION_MESSAGE, file=sys.stderr)
        new_imp_client = self._new_impala_client()
        new_imp_client.connect()
        try:
          new_imp_client.cancel_query(self.last_query_handle)
          new_imp_client.close_query(self.last_query_handle)
        finally:
          new_imp_client.close_connection()
        break
      except Exception as e:
        # Suppress harmless errors.
        err_msg = str(e).strip()
        if err_msg in ['ERROR: Cancelled', 'ERROR: Invalid or unknown query handle']:
          break
        err_details = "Failed to reconnect and close (try %i/%i): %s"
        print(err_details % (cancel_try + 1, ImpalaShell.CANCELLATION_TRIES, err_msg),
              file=sys.stderr)

  def _is_quit_command(self, command):
    # Do a case insensitive check
    return command.lower() in ImpalaShell.QUIT_COMMANDS

  def set_prompt(self, db):
    self.prompt = ImpalaShell.PROMPT_FORMAT.format(
        host=self.impalad[0], port=self.impalad[1], db=db)

  def precmd(self, args):
    if sys.version_info.major == 2:
      args = self.sanitise_input(args.decode('utf-8'))  # python2
    else:
      args = self.sanitise_input(args)  # python3
    if not args: return args
    # Split args using sqlparse. If there are multiple queries present in user input,
    # the length of the returned query list will be greater than one.
    parsed_cmds = sqlparse.split(args)
    if len(parsed_cmds) > 1:
      # The last command needs a delimiter to be successfully executed.
      parsed_cmds[-1] += ImpalaShell.CMD_DELIM
      self.cmdqueue.extend(parsed_cmds)
      # If cmdqueue is populated, then commands are executed from the cmdqueue, and user
      # input is ignored. Send an empty string as the user input just to be safe.
      return str()
    # There is no need to reconnect if we are quitting.
    if not self.imp_client.is_connected() and not self._is_quit_command(args):
      print("Connection lost, reconnecting...", file=sys.stderr)
      self._connect()
      self._validate_database(immediately=True)
    return args

  def onecmd(self, line):
    """Overridden to ensure the variable replacement is processed in interactive
       as well as non-interactive mode, since the precmd method would only work for
       the interactive case, when cmdloop is called.
    """
    # Replace variables in the statement before it's executed
    line = replace_variables(self.set_variables, line)
    # Cmd is an old-style class, hence we need to call the method directly
    # instead of using super()
    # TODO: This may have to be changed to a super() call once we move to Python 3
    if line == None:
      return CmdStatus.ERROR
    else:
      # This code is based on the code from the standard Python library package cmd.py:
      # https://github.com/python/cpython/blob/master/Lib/cmd.py#L192
      # One change is lowering command before getting a function. The lowering
      # is necessary to find a proper function and here is a right place
      # because the lowering command in front of the finding can avoid a
      # side effect.
      command, arg, line, leading_comment = self.parseline(line)
      if not line:
        return self.emptyline()
      # orig_cmd and last_leading_comment are passed into do_*() functions
      # via this side mechanism because the cmd module limits us to passing
      # in the argument list only.
      self.orig_cmd = command
      self.last_leading_comment = leading_comment
      self.lastcmd = line
      if not command:
        return self.default(line)
      elif line == 'EOF':
        self.lastcmd = ''
      else:
        try:
          func = getattr(self, 'do_' + command.lower())
        except AttributeError:
          return self.default(line)
        return func(arg)

  def postcmd(self, status, args):
    # status conveys to shell how the shell should continue execution
    # should always be a CmdStatus
    return status

  def do_summary(self, args):
    if not self.last_query_handle:
      print("Could not retrieve summary: no previous query.", file=sys.stderr)
      return CmdStatus.ERROR

    summary = None
    try:
      summary = self.imp_client.get_summary(self.last_query_handle)
    except RPCException as e:
      import re
      error_pattern = re.compile("ERROR: Query id \d+:\d+ not found.")
      if error_pattern.match(e.value):
        print("Could not retrieve summary for query.", file=sys.stderr)
      else:
        print(e, file=sys.stderr)
      return CmdStatus.ERROR
    if summary.nodes is None:
      print("Summary not available", file=sys.stderr)
      return CmdStatus.SUCCESS
    output = []
    table = self._default_summary_table()
    self.imp_client.build_summary_table(summary, 0, False, 0, False, output)
    formatter = PrettyOutputFormatter(table)
    self.output_stream = OutputStream(formatter, filename=self.output_file)
    self.output_stream.write(output)

  def _handle_shell_options(self, token, value):
    try:
      handle = self.VALID_SHELL_OPTIONS[token]
      self.__dict__[handle[1]] = handle[0](value)
      return True
    except KeyError:
      return False

  def _handle_unset_shell_options(self, token):
    try:
      handle = self.VALID_SHELL_OPTIONS[token]
      self.__dict__[handle[1]] = impala_shell_defaults[handle[1]]
      return True
    except KeyError:
      return False

  def _print_with_set(self, print_level):
    self._print_options(print_level)
    print("\nVariables:")
    self._print_variables()

  def do_set(self, args):
    """Set or display query options.

    Display query options:
    Usage: SET (to display the Regular options) or
           SET ALL (to display all the options)
    Set query options:
    Usage: SET <option>=<value>
           OR
           SET VAR:<variable>=<value>

    """
    # TODO: Expand set to allow for setting more than just query options.
    if len(args) == 0:
      self._print_with_set(QueryOptionDisplayModes.REGULAR_OPTIONS_ONLY)
      return CmdStatus.SUCCESS

    # Remove any extra spaces surrounding the tokens.
    # Allows queries that have spaces around the = sign.
    tokens = [arg.strip() for arg in args.split("=")]
    if len(tokens) != 2:
      if len(tokens) == 1 and tokens[0].upper() == "ALL":
        self._print_with_set(QueryOptionDisplayModes.ALL_OPTIONS)
        return CmdStatus.SUCCESS
      else:
        set_err_msg = ("Error: SET <option>=<value>\n"
                       "       OR\n"
                       "       SET VAR:<variable>=<value>")
        print(set_err_msg, file=sys.stderr)
        return CmdStatus.ERROR
    option_upper = tokens[0].upper()
    # Check if it's a variable
    var_name = get_var_name(option_upper)
    if var_name is not None:
      # Set the variable
      self.set_variables[var_name] = tokens[1]
      self._print_if_verbose('Variable %s set to %s' % (var_name, tokens[1]))
    elif not self._handle_shell_options(option_upper, tokens[1]):
      if option_upper not in self.imp_client.default_query_options.keys():
        print("Unknown query option: %s" % (tokens[0]))
        print("Available query options, with their values (defaults shown in []):")
        self._print_options(QueryOptionDisplayModes.REGULAR_OPTIONS_ONLY)
        return CmdStatus.ERROR
      if self.imp_client.query_option_levels[option_upper] == QueryOptionLevels.REMOVED:
        self._print_if_verbose("Ignoring removed query option: '{0}'".format(tokens[0]))
        return CmdStatus.SUCCESS
      self.set_query_options[option_upper] = tokens[1]
      self._print_if_verbose('%s set to %s' % (option_upper, tokens[1]))

  def do_unset(self, args):
    """Unset a query option"""
    if len(args.split()) != 1:
      print('Usage: unset <option>')
      return CmdStatus.ERROR
    option = args.upper()
    # Check if it's a variable
    var_name = get_var_name(option)
    if var_name is not None:
      if self.set_variables.get(var_name):
        print('Unsetting variable %s' % var_name)
        del self.set_variables[var_name]
      else:
        print("No variable called %s is set" % var_name)
    elif self.set_query_options.get(option):
      print('Unsetting option %s' % option)
      del self.set_query_options[option]
    elif self._handle_unset_shell_options(option):
      print('Unsetting shell option %s' % option)
    else:
      print("No option called %s is set" % option)

  def do_quit(self, args):
    """Quit the Impala shell"""
    self._print_if_verbose("Goodbye " + self.user)
    self.is_alive = False
    return CmdStatus.ABORT

  def do_exit(self, args):
    """Exit the impala shell"""
    return self.do_quit(args)

  def do_connect(self, args):
    """Connect to an Impalad instance:
    Usage: connect, defaults to the fqdn of the localhost and the protocol's default port
           connect <hostname:port>
           connect <hostname>, defaults to the protocol's default port

    """
    # Assume the user wants to connect to the local impalad if no connection string is
    # specified. Connecting to a kerberized impalad requires an fqdn as the host name.
    if self.use_ldap and self.ldap_password is None:
      self.ldap_password = getpass.getpass("LDAP password for %s: " % self.user)

    if not args: args = socket.getfqdn()
    tokens = args.split(" ")
    # validate the connection string.
    host_port = [val for val in tokens[0].split(':') if val.strip()]
    protocol = options.protocol.lower()
    if (':' in tokens[0] and len(host_port) != 2):
      print("Connection string must either be empty, or of the form "
            "<hostname[:port]>", file=sys.stderr)
      return CmdStatus.ERROR
    elif len(host_port) == 1:
      if protocol == 'hs2':
        port = str(DEFAULT_HS2_PORT)
      elif protocol == 'hs2-http':
        port = str(DEFAULT_HS2_HTTP_PORT)
      elif protocol == 'beeswax':
        port = str(DEFAULT_BEESWAX_PORT)
      else:
        print("Invalid protocol specified: %s" % protocol, file=sys.stderr)
        raise FatalShellException()
      host_port.append(port)
    self.impalad = tuple(host_port)
    self.close_connection()
    self.imp_client = self._new_impala_client()
    self._connect()
    # If the connection fails and the Kerberos has not been enabled,
    # check for a valid kerberos ticket and retry the connection
    # with kerberos enabled.
    # IMPALA-8932: Kerberos is not yet supported for hs2-http, so don't retry.
    if not self.imp_client.connected and not self.use_kerberos and protocol != 'hs2-http':
      try:
        if call(["klist", "-s"]) == 0:
          print("Kerberos ticket found in the credentials cache, retrying "
                "the connection with a secure transport.", file=sys.stderr)
          self.use_kerberos = True
          self.use_ldap = False
          self.ldap_password = None
          self.imp_client = self._new_impala_client()
          self._connect()
      except OSError:
        pass

    if self.imp_client.connected:
      self._print_if_verbose('Connected to %s:%s' % self.impalad)
      self._print_if_verbose('Server version: %s' % self.server_version)
      self.set_prompt(ImpalaShell.DEFAULT_DB)
      self._validate_database()
    # In the case that we lost connection while a command was being entered,
    # we may have a dangling command, clear partial_cmd
    self.partial_cmd = str()
    # Check if any of query options set by the user are inconsistent
    # with the impalad being connected to

    # Use a temporary to avoid changing set_query_options during iteration.
    new_query_options = {}
    default_query_option_keys = set(self.imp_client.default_query_options)
    if sys.version_info.major < 3:
      query_options_to_set = self.set_query_options.iteritems()
    else:
      query_options_to_set = self.set_query_options.items()

    for set_option, value in query_options_to_set:
      if set_option not in default_query_option_keys:
        print('%s is not supported for the impalad being '
              'connected to, ignoring.' % set_option)
      else:
        new_query_options[set_option] = value

    if "CLIENT_IDENTIFIER" not in new_query_options \
        and "CLIENT_IDENTIFIER" in default_query_option_keys:
      # Programmatically set default CLIENT_IDENTIFIER to our version string,
      # if the Impala version supports this option.
      new_query_options["CLIENT_IDENTIFIER"] = VERSION_STRING

    self.set_query_options = new_query_options

  def _connect(self):
    try:
      self.server_version, self.webserver_address = self.imp_client.connect()
    except MissingThriftMethodException as e:
      if options.protocol.lower() == 'beeswax':
        port_flag = "-beeswax_port"
        addtl_suggestion = ""
      else:
        assert options.protocol.lower() == 'hs2'
        port_flag = "-hs2_port"
        addtl_suggestion = (" Also check that the Impala daemon connected to has version "
                            "3.3 or greater. impala-shell only supports connecting to "
                            "the HS2 interface of Impala version 3.3 or greater. For "
                            "older Impala versions you must use the (deprecated) beeswax "
                            "protocol with the --protocol=beeswax.")
      # We get a TApplicationException if the transport is valid,
      # but the RPC does not exist.
      print("\n".join(textwrap.wrap(
        "Error: Unable to communicate with impalad service because of the error "
        "reported below. The service does not implement a required Thrift method. "
        "The service may not be an Impala Daemon or you may have specified the wrong "
        "port to connect to. Check host:port to ensure that the port matches the "
        "{port_flag} flag on the Impala Daemon and try again.{addtl_suggestion}".format(
          port_flag=port_flag, addtl_suggestion=addtl_suggestion))), file=sys.stderr)
      print(str(e), file=sys.stderr)
      self.close_connection()
      raise
    except ImportError:
      print("Unable to import the python 'ssl' module. It is"
            " required for an SSL-secured connection.", file=sys.stderr)
      raise FatalShellException()
    except socket.error as e:
      # if the socket was interrupted, reconnect the connection with the client
      if e.errno == errno.EINTR:
        self._reconnect_cancellation()
      else:
        print("Socket error %s: %s" % (e.errno, e), file=sys.stderr)
        self.close_connection()
        self.prompt = self.DISCONNECTED_PROMPT
    except Exception as e:
      if self.ldap_password_cmd and \
          self.ldap_password and \
          self.ldap_password.endswith('\n'):
        print("Warning: LDAP password contains a trailing newline. "
              "Did you use 'echo' instead of 'echo -n'?", file=sys.stderr)
      if self.use_ssl and sys.version_info < (2,7,9) \
          and "EOF occurred in violation of protocol" in str(e):
        print("Warning: TLSv1.2 is not supported for Python < 2.7.9", file=sys.stderr)
      print("Error connecting: %s, %s" % (type(e).__name__, e), file=sys.stderr)
      # A secure connection may still be open. So we explicitly close it.
      self.close_connection()
      # If a connection to another impalad failed while already connected
      # reset the prompt to disconnected.
      self.server_version = self.UNKNOWN_SERVER_VERSION
      self.prompt = self.DISCONNECTED_PROMPT

  def _reconnect_cancellation(self):
    self._connect()
    self._validate_database()

  def _validate_database(self, immediately=False):
    """ Issues a "USE <db>" command where <db> is the current database.
    It is typically needed after the connection is (re-)established to the Impala daemon.

    If immediately is False, it appends the USE command to self.cmdqueue.
    If immediately is True, it executes the USE command right away.
    """
    if not self.imp_client.connected:
      return
    # Should only check if successfully connected.
    if self.current_db:
      self.current_db = self.current_db.strip('`')
      use_current_db = ('use `%s`' % self.current_db)
      if immediately:
        self.onecmd(use_current_db)
      else:
        self.cmdqueue.append(use_current_db + ImpalaShell.CMD_DELIM)

  def _print_if_verbose(self, message, file_descriptor=sys.stderr, flush=True):
    if self.verbose:
      print(message, file=file_descriptor)

    # print() takes a flush keyword argument in python3, but not in python2,
    # so we do it as a second step
    if flush:
      file_descriptor.flush()

  def print_runtime_profile(self, profile, status=False):
    if self.show_profiles or status:
      if profile is not None:
        print("Query Runtime Profile:\n" + profile)

  def _parse_table_name_arg(self, arg):
    """ Parses an argument string and returns the result as a db name, table name combo.

    If the table name was not fully qualified, the current database is returned as the db.
    Otherwise, the table is split into db/table name parts and returned.
    If an invalid format is provided, None is returned.
    """
    if not arg: return
    # If a multi-line argument, the name might be split across lines
    arg = arg.replace('\n', '')
    # Get the database and table name, using the current database if the table name
    # wasn't fully qualified.
    db_name, tbl_name = self.current_db, arg
    if db_name is None:
      db_name = ImpalaShell.DEFAULT_DB
    db_table_name = arg.split('.')
    if len(db_table_name) == 1:
      return db_name, db_table_name[0]
    if len(db_table_name) == 2:
      return db_table_name

  def do_alter(self, args):
    return self._execute_stmt(
        self._build_query_string(self.last_leading_comment, self.orig_cmd, args))

  def do_create(self, args):
    # We want to print the webserver link only for CTAS queries.
    print_web_link = "select" in args
    query = self._build_query_string(self.last_leading_comment, self.orig_cmd, args)
    return self._execute_stmt(query, print_web_link=print_web_link)

  def do_drop(self, args):
    return self._execute_stmt(
        self._build_query_string(self.last_leading_comment, self.orig_cmd, args))

  def do_load(self, args):
    return self._execute_stmt(
        self._build_query_string(self.last_leading_comment, self.orig_cmd, args))

  def do_profile(self, args):
    """Prints the runtime profile of the last DML statement or SELECT query executed."""
    if len(args) > 0:
      print("'profile' does not accept any arguments", file=sys.stderr)
      return CmdStatus.ERROR
    elif self.last_query_handle is None:
      print('No previous query available to profile', file=sys.stderr)
      return CmdStatus.ERROR
    profile = self.imp_client.get_runtime_profile(self.last_query_handle)
    return self.print_runtime_profile(profile, True)

  def do_select(self, args):
    """Executes a SELECT... query, fetching all rows"""
    query_str = self._build_query_string(self.last_leading_comment, self.orig_cmd, args)
    return self._execute_stmt(query_str, print_web_link=True)

  def do_compute(self, args):
    """Executes a COMPUTE STATS query.
    Impala shell cannot get child query handle so it cannot
    query live progress for COMPUTE STATS query. Disable live
    progress/summary callback for COMPUTE STATS query."""

    query = self._build_query_string(self.last_leading_comment, self.orig_cmd, args)
    (prev_live_progress, prev_live_summary) = self.live_progress, self.live_summary
    (self.live_progress, self.live_summary) = False, False
    try:
      ret = self._execute_stmt(query)
    finally:
      (self.live_progress, self.live_summary) = prev_live_progress, prev_live_summary
    return ret

  def _format_outputstream(self):
    column_names = self.imp_client.get_column_names(self.last_query_handle)
    if self.write_delimited:
      formatter = DelimitedOutputFormatter(field_delim=self.output_delimiter)
      self.output_stream = OutputStream(formatter, filename=self.output_file)
      # print the column names
      if self.print_header:
        self.output_stream.write([column_names])
    else:
      prettytable = self.construct_table_with_header(column_names)
      formatter = PrettyOutputFormatter(prettytable)
      self.output_stream = OutputStream(formatter, filename=self.output_file)

  def _periodic_wait_callback(self):
    """If enough time elapsed since the last call to the periodic callback,
    execute the RPC to get the query exec summary and depending on the set options
    print either the progress or the summary or both to stderr.
    """
    if not self.live_progress and not self.live_summary: return

    checkpoint = time.time()
    if checkpoint - self.last_summary > self.PROGRESS_UPDATE_INTERVAL:
      summary = self.imp_client.get_summary(self.last_query_handle)
      if not summary:
        return

      if summary.is_queued:
        queued_msg = "Query queued. Latest queuing reason: %s\n" % summary.queued_reason
        self.progress_stream.write(queued_msg)
        self.last_summary = time.time()
        return

      data = ""
      if summary.error_logs:
        for error_line in summary.error_logs:
          data += error_line + "\n"
          query_id_search = re.search("Retrying query using query id: (.*)",
                                      error_line)
          if query_id_search and len(query_id_search.groups()) == 1:
            retried_query_id = query_id_search.group(1)
            data += "Retried query link: %s\n"\
                    % self.imp_client.get_query_link(retried_query_id)

      if summary.progress:
        progress = summary.progress

        # If the data is not complete return and wait for a good result.
        if not progress.total_scan_ranges and not progress.num_completed_scan_ranges:
          self.last_summary = time.time()
          return

        if self.live_progress and progress.total_scan_ranges > 0:
          val = ((summary.progress.num_completed_scan_ranges * 100) /
                 summary.progress.total_scan_ranges)
          fragment_text = "[%s%s] %s%%\n" % ("#" * val, " " * (100 - val), val)
          data += fragment_text

        if self.live_summary:
          table = self._default_summary_table()
          output = []
          self.imp_client.build_summary_table(summary, 0, False, 0, False, output)
          formatter = PrettyOutputFormatter(table)
          data += formatter.format(output) + "\n"

      self.progress_stream.write(data)
      self.last_summary = time.time()

  def _default_summary_table(self):
    return self.construct_table_with_header(["Operator", "#Hosts", "#Inst",
                                             "Avg Time", "Max Time", "#Rows",
                                             "Est. #Rows", "Peak Mem",
                                             "Est. Peak Mem", "Detail"])

  def _execute_stmt(self, query_str, is_dml=False, print_web_link=False):
    """Executes 'query_str' with options self.set_query_options on the Impala server.
    The query is run to completion and close with any results, warnings, errors or
    other output that we want to display to users printed to the output.
    Results for queries are streamed from the server and displayed as they become
    available.
    is_dml: True iff the caller detects that 'query_str' is a DML statement, false
            otherwise.
    print_web_link: if True, a link to the query on the Impala debug webserver is printed.
    """
    self._print_if_verbose("Query: %s" % query_str)
    # TODO: Clean up this try block and refactor it (IMPALA-3814)
    try:
      if not self.webserver_address:
        print_web_link = False
      if print_web_link:
        self._print_if_verbose("Query submitted at: %s (Coordinator: %s)" %
            (time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()),
            self.webserver_address))

      start_time = time.time()
      self.last_query_handle = None
      self.last_query_handle = self.imp_client.execute_query(
          query_str, self.set_query_options)
      self.last_summary = time.time()
      if print_web_link:
        self._print_if_verbose(
            "Query progress can be monitored at: %s" % self.imp_client.get_query_link(
             self.imp_client.get_query_id_str(self.last_query_handle)))

      wait_to_finish = self.imp_client.wait_to_finish(self.last_query_handle,
          self._periodic_wait_callback)
      # Reset the progress stream.
      self.progress_stream.clear()

      if is_dml:
        # retrieve the error log
        warning_log = self.imp_client.get_warning_log(self.last_query_handle)
        (num_rows, num_row_errors) = self.imp_client.close_dml(self.last_query_handle)
      else:
        # impalad does not support the fetching of metadata for certain types of queries.
        if not self.imp_client.expect_result_metadata(query_str, self.last_query_handle):
          # Close the query
          self.imp_client.close_query(self.last_query_handle)
          return CmdStatus.SUCCESS

        self._format_outputstream()
        # fetch returns a generator
        rows_fetched = self.imp_client.fetch(self.last_query_handle)
        num_rows = 0

        for rows in rows_fetched:
          # IMPALA-4418: Break out of the loop to prevent printing an unnecessary empty line.
          if len(rows) == 0:
            continue
          self.output_stream.write(rows)
          num_rows += len(rows)

        # retrieve the error log
        warning_log = self.imp_client.get_warning_log(self.last_query_handle)

      end_time = time.time()

      if warning_log:
        self._print_if_verbose(warning_log)
      # print 'Modified' when is_dml is true (i.e. 1), or 'Fetched' otherwise.
      verb = ["Fetched", "Modified"][is_dml]
      time_elapsed = end_time - start_time

      # Add the number of row errors if this DML and the operation supports it.
      # num_row_errors is None if the DML operation doesn't return it.
      if is_dml and num_row_errors is not None:
        error_report = ", %d row error(s)" % (num_row_errors)
      else:
        error_report = ""

      self._print_if_verbose("%s %d row(s)%s in %2.2fs" %\
          (verb, num_rows, error_report, time_elapsed))

      if not is_dml:
        self.imp_client.close_query(self.last_query_handle)
      try:
        profile = self.imp_client.get_runtime_profile(self.last_query_handle)
        self.print_runtime_profile(profile)
      except RPCException as e:
        if self.show_profiles: raise e
      return CmdStatus.SUCCESS
    except QueryCancelledByShellException as e:
      return CmdStatus.SUCCESS
    except RPCException as e:
      # could not complete the rpc successfully
      print(e, file=sys.stderr)
    except UnicodeDecodeError as e:
      # An error occoured possibly during the fetching.
      # Depending of which protocol is at use it can come from different places.
      # Possibly occours because we try to display binary data which contains
      # undecodable elements.
      if self.last_query_handle is not None:
        self.imp_client.close_query(self.last_query_handle)
      print('UnicodeDecodeError : %s \nPlease check for columns containing binary data '
          'to find the possible source of the error.' % (e,), file=sys.stderr)
    except QueryStateException as e:
      # an exception occurred while executing the query
      if self.last_query_handle is not None:
        self.imp_client.close_query(self.last_query_handle)
      print(e, file=sys.stderr)
    except DisconnectedException as e:
      # the client has lost the connection
      print(e, file=sys.stderr)
      self.imp_client.connected = False
      self.prompt = ImpalaShell.DISCONNECTED_PROMPT
    except socket.error as e:
      # if the socket was interrupted, reconnect the connection with the client
      if e.errno == errno.EINTR:
        print(ImpalaShell.CANCELLATION_MESSAGE)
        self._reconnect_cancellation()
      else:
        print("Socket error %s: %s" % (e.errno, e), file=sys.stderr)
        self.prompt = self.DISCONNECTED_PROMPT
        self.imp_client.connected = False
    except Exception as e:
      # if the exception is unknown, there was possibly an issue with the connection
      # set the shell as disconnected
      print('Unknown Exception : %s' % (e,), file=sys.stderr)
      # Print the stack trace for the exception.
      traceback.print_exc()
      self.close_connection()
      self.prompt = ImpalaShell.DISCONNECTED_PROMPT
    return CmdStatus.ERROR


  def construct_table_with_header(self, column_names):
    """ Constructs the table header for a given query handle.

    Should be called after the query has finished and before data is fetched.
    All data is left aligned.
    """
    table = prettytable.PrettyTable()
    for column in column_names:
      table.add_column(column, [])
    table.align = "l"
    return table

  def do_values(self, args):
    """Executes a VALUES(...) query, fetching all rows"""
    return self._execute_stmt(
        self._build_query_string(self.last_leading_comment, self.orig_cmd, args))

  def do_with(self, args):
    """Executes a query with a WITH clause, fetching all rows"""
    query = self._build_query_string(self.last_leading_comment, self.orig_cmd, args)
    # Use shlex to deal with escape quotes in string literals.
    # Set posix=False to preserve the quotes.
    tokens = shlex.split(strip_comments(query.lstrip()), posix=False)
    try:
      # Because the WITH clause may precede DML or SELECT queries,
      # just checking the first token is insufficient.
      is_dml = False
      if any(self.DML_REGEX.match(t) for t in tokens):
        is_dml = True
      return self._execute_stmt(query, is_dml=is_dml, print_web_link=True)
    except ValueError:
      return self._execute_stmt(query, print_web_link=True)

  def do_use(self, args):
    """Executes a USE... query"""
    cmd_status = self._execute_stmt(
        self._build_query_string(self.last_leading_comment, self.orig_cmd, args))
    if cmd_status is CmdStatus.SUCCESS:
      self.current_db = args.strip('`').strip()
      self.set_prompt(self.current_db)
    elif args.strip('`') == self.current_db:
      # args == current_db means -d option was passed but the "use [db]" operation failed.
      # We need to set the current_db to None so that it does not show a database, which
      # may not exist.
      self.current_db = None
      return CmdStatus.ERROR
    else:
      return CmdStatus.ERROR

  def do_show(self, args):
    """Executes a SHOW... query, fetching all rows"""
    return self._execute_stmt(
        self._build_query_string(self.last_leading_comment, self.orig_cmd, args))

  def do_describe(self, args):
    return self.__do_describe(self.orig_cmd, args)

  def do_desc(self, args):
    return self.__do_describe("describe", args)

  def __do_describe(self, cmd, args):
    """Executes a DESCRIBE... query, fetching all rows"""
    # original command should be overridden because the server cannot
    # recognize "desc" as a keyword. Thus, given command should be
    # replaced with "describe" here.
    return self._execute_stmt(
        self._build_query_string(self.last_leading_comment, cmd, args))

  def __do_dml(self, orig_cmd, args):
    """Executes a DML query"""
    query = self._build_query_string(self.last_leading_comment, orig_cmd, args)
    return self._execute_stmt(query, is_dml=True, print_web_link=True)

  def do_upsert(self, args):
    return self.__do_dml(self.orig_cmd, args)

  def do_update(self, args):
    return self.__do_dml(self.orig_cmd, args)

  def do_delete(self, args):
    return self.__do_dml(self.orig_cmd, args)

  def do_insert(self, args):
    return self.__do_dml(self.orig_cmd, args)

  def do_explain(self, args):
    """Explain the query execution plan"""
    return self._execute_stmt(
        self._build_query_string(self.last_leading_comment, self.orig_cmd, args))

  def do_history(self, args):
    """Display command history"""
    # Deal with readline peculiarity. When history does not exist,
    # readline returns 1 as the history length and stores 'None' at index 0.
    if self.readline and self.readline.get_current_history_length() > 0:
      for index in xrange(1, self.readline.get_current_history_length() + 1):
        cmd = self.readline.get_history_item(index)
        print('[%d]: %s' % (index, cmd.decode('utf-8', 'replace')), file=sys.stderr)
    else:
      print(READLINE_UNAVAILABLE_ERROR, file=sys.stderr)

  def do_rerun(self, args):
    """Rerun a command with an command index in history
    Example: @1;
    """
    history_len = self.readline.get_current_history_length()
    # Rerun command shouldn't appear in history
    self.readline.remove_history_item(history_len - 1)
    history_len -= 1
    if not self.readline:
      print(READLINE_UNAVAILABLE_ERROR, file=sys.stderr)
      return CmdStatus.ERROR
    try:
      cmd_idx = int(args)
    except ValueError:
      print("Command index to be rerun must be an integer.", file=sys.stderr)
      return CmdStatus.ERROR
    if not (0 < cmd_idx <= history_len or -history_len <= cmd_idx < 0):
      print("Command index out of range. Valid range: [1, {0}] and [-{0}, -1]"
                      .format(history_len), file=sys.stderr)
      return CmdStatus.ERROR
    if cmd_idx < 0:
      cmd_idx += history_len + 1
    cmd = self.readline.get_history_item(cmd_idx)
    print("Rerunning " + cmd, file=sys.stderr)
    return self.onecmd(cmd.rstrip(";"))

  def do_tip(self, args):
    """Print a random tip"""
    print(random.choice(TIPS), file=sys.stderr)

  def do_src(self, args):
    return self.do_source(args)

  def do_source(self, args):
    try:
      cmd_file = open(args, "r")
    except Exception as e:
      print("Error opening file '%s': %s" % (args, e), file=sys.stderr)
      return CmdStatus.ERROR
    if self.execute_query_list(parse_query_text(cmd_file.read())):
      return CmdStatus.SUCCESS
    else:
      return CmdStatus.ERROR

  def postloop(self):
    """Save session commands in history."""
    if self.readline:
      try:
        self._replace_history_delimiters('\n', ImpalaShell.HISTORY_FILE_QUERY_DELIM)
        self.readline.write_history_file(self.history_file)
      except IOError as i:
        msg = "Unable to save command history (disabling history collection): %s" % i
        print(msg, file=sys.stderr)
        # The history file is not writable, disable readline.
        self._disable_readline()

  def parseline(self, line):
    """Parse the line into a command name and a string containing
    the arguments.  Returns a tuple containing (command, args, line, leading comment).
    'command' and 'args' may be None if the line couldn't be parsed.
    'line' in return tuple is the rewritten original line, with leading
    and trailing space removed and special characters transformed into
    their aliases. If the line contains a leading comment, the leading
    comment will be removed in order to deduce a 'command' correctly.
    The 'command' is used to determine which 'do_<command>' function to invoke.
    The 'do_<command>' implementation can decide whether to retain or ignore the
    leading comment.

    Examples:

    > /*comment*/ help connect;
    line: help connect
    args: connect
    command: help
    leading comment: /*comment*/

    > /*comment*/ ? connect;
    line: help connect
    args: connect
    command: help
    leading comment: /*comment*/

    > /*first comment*/ select /*second comment*/ 1;
    line: select /*second comment*/ 1
    args: /*second comment*/ 1
    command: select
    leading comment: /*first comment*/
    """
    if ImpalaShell._has_leading_comment(line):
      leading_comment, line = ImpalaShell.strip_leading_comment(line.strip())
    else:
      leading_comment, line = None, line.strip()

    if line and line[0] == '@':
      line = 'rerun ' + line[1:]
    return super(ImpalaShell, self).parseline(line) + (leading_comment,)

  @staticmethod
  def _has_leading_comment(raw_line):
    """
    Helper function that returns Boolean true if a query starts with a comment.
    This saves us from relying on sqlparse filtering, which can be slow.
    """
    line = raw_line.lstrip()
    if line and (line.startswith('--') or line.startswith('/*')):
      return True
    else:
      return False

  @staticmethod
  def strip_leading_comment(sql):
    """
    Filter a leading comment in the SQL statement. This function returns a tuple
    containing (leading comment, line without the leading comment).
    """
    class StripLeadingCommentFilter(object):
      def __init__(self):
        self.comment = None

      def _process(self, tlist):
        """
        Iterate through the list of tokens, appending each leading commment
        to self.comment, and then popping that element off the list. When we
        hit the first non-comment and non-whitespace token, then we're done --
        the remainder after that point is the SQL statement.
        """
        token = tlist.token_first()
        while token:
          if self._is_comment(token) or self._is_whitespace(token):
            if self.comment is None:
              self.comment = token.value
            else:
              self.comment += token.value
            tlist.tokens.pop(0)

            # skip_ws=False treats white space characters as tokens also
            token = tlist.token_first(skip_ws=False)
          else:
            break

      def _is_comment(self, token):
        return isinstance(token, sqlparse.sql.Comment) or \
               token.ttype == sqlparse.tokens.Comment.Single or \
               token.ttype == sqlparse.tokens.Comment.Multiline

      def _is_whitespace(self, token):
        return token.ttype == sqlparse.tokens.Whitespace or \
               token.ttype == sqlparse.tokens.Newline

      def process(self, stmt):
        [self.process(sgroup) for sgroup in stmt.get_sublists()]
        self._process(stmt)

    stack = sqlparse.engine.FilterStack()
    strip_leading_comment_filter = StripLeadingCommentFilter()
    stack.stmtprocess.append(strip_leading_comment_filter)
    stack.postprocess.append(sqlparse.filters.SerializerUnicode())
    stripped_line = ''.join(stack.run(sql, 'utf-8'))
    return strip_leading_comment_filter.comment, stripped_line

  def _replace_history_delimiters(self, src_delim, tgt_delim):
    """Replaces source_delim with target_delim for all items in history.

    Read all the items from history into a local list. Clear the history and copy them
    back after doing the transformation.
    """
    history_len = self.readline.get_current_history_length()
    # load the history and replace the shell's delimiter with EOL
    history_items = map(self.readline.get_history_item, xrange(1, history_len + 1))
    if sys.version_info.major == 2:
      src_delim = src_delim.encode('utf-8')
      tgt_delim = tgt_delim.encode('utf-8')
    history_items = [item.replace(src_delim, tgt_delim) for item in history_items]
    # Clear the original history and replace it with the mutated history.
    self.readline.clear_history()
    for history_item in history_items:
      self.readline.add_history(history_item)

  def default(self, line):
    """Called for any command that doesn't have a do_*() method. Sends the command
    with any arguments and trailing comment to the server."""
    return self._execute_stmt(line, print_web_link=True)

  def emptyline(self):
    """If an empty line is entered, do nothing"""

  def do_version(self, args):
    """Prints the Impala build version"""
    print("Shell version: %s" % VERSION_STRING, file=sys.stderr)
    print("Server version: %s" % self.server_version, file=sys.stderr)

  def completenames(self, text, *ignored):
    """Make tab completion of commands case agnostic

    Override the superclass's completenames() method to support tab completion for
    upper case and mixed case commands.
    """
    cmd_names = [cmd for cmd in self.commands if cmd.startswith(text.lower())]
    # If the user input is upper case, return commands in upper case.
    if text.isupper(): return [cmd_names.upper() for cmd_names in cmd_names]
    # If the user input is lower case or mixed case, return lower case commands.
    return cmd_names

  def execute_query_list(self, queries):
    if not self.imp_client.connected:
      print('Not connected to Impala, could not execute queries.', file=sys.stderr)
      return False
    queries = [self.sanitise_input(q) for q in queries]
    for q in queries:
      if self.onecmd(q) is CmdStatus.ERROR:
        print('Could not execute command: %s' % q, file=sys.stderr)
        if not self.ignore_query_failure: return False
    return True


TIPS = [
  "Press TAB twice to see a list of available commands.",
  "After running a query, type SUMMARY to see a summary of where time was spent.",
  "The SET command shows the current value of all shell and query options.",
  "To see live updates on a query's progress, run 'set LIVE_SUMMARY=1;'.",
  "To see a summary of a query's progress that updates in real-time, run 'set \
LIVE_PROGRESS=1;'.",
  "The HISTORY command lists all shell commands in chronological order.",
  "The '-B' command line flag turns off pretty-printing for query results. Use this flag \
to remove formatting from results you want to save for later, or to benchmark Impala.",
  "You can run a single query from the command line using the '-q' option.",
  "When pretty-printing is disabled, you can use the '--output_delimiter' flag to set \
the delimiter for fields in the same row. The default is '\\t'.",
  "Run the PROFILE command after a query has finished to see a comprehensive summary of \
all the performance and diagnostic information that Impala gathered for that query. Be \
warned, it can be very long!",
  "To see more tips, run the TIP command.",
  "Every command must be terminated by a ';'.",
  "Want to know what version of Impala you're connected to? Run the VERSION command to \
find out!",
  "You can change the Impala daemon that you're connected to by using the CONNECT \
command."
  "To see how Impala will plan to run your query without actually executing it, use the \
EXPLAIN command. You can change the level of detail in the EXPLAIN output by setting the \
EXPLAIN_LEVEL query option.",
  "When you set a query option it lasts for the duration of the Impala shell session."
]

HEADER_DIVIDER =\
  "***********************************************************************************"


def _format_tip(tip):
  """Takes a tip string and splits it on word boundaries so that it fits neatly inside the
  shell header."""
  return '\n'.join([l for l in textwrap.wrap(tip, len(HEADER_DIVIDER))])


WELCOME_STRING = """\
***********************************************************************************
Welcome to the Impala shell.
(%s)

%s
***********************************************************************************\
""" \
  % (VERSION_STRING, _format_tip(random.choice(TIPS)))


def parse_query_text(query_text):
  """Parse query file text to extract queries"""
  query_list = sqlparse.split(query_text)
  # Remove trailing comments in the input, if any. We do this because sqlparse splits the
  # input at query boundaries and associates the query only with preceding comments
  # (following comments are associated with the next query). This is a problem with
  # trailing comments. For example, consider the following input:
  # -------------
  # -- comment1
  # select 1;
  # -- comment2
  # -------------
  # When sqlparse splits the query, "comment1" is associated with the query "select 1" and
  # "--comment2" is sent as is. Impala's parser however doesn't consider it a valid SQL
  # and throws an exception. We identify such trailing comments and ignore them (do not
  # send them to Impala).
  if query_list and not strip_comments(query_list[-1]).strip("\n"):
    query_list.pop()
  return query_list


def parse_variables(keyvals):
  """Parse variable assignments passed as arguments in the command line"""
  kv_pattern = r'(%s)=(.*)$' % (ImpalaShell.VALID_VAR_NAME_PATTERN,)
  vars = {}
  if keyvals:
    for keyval in keyvals:
      match = re.match(kv_pattern, keyval)
      if not match:
        print('Error: Could not parse key-value "%s". ' % (keyval,) +
              'It must follow the pattern "KEY=VALUE".', file=sys.stderr)
        parser.print_help()
        raise FatalShellException()
      else:
        vars[match.groups()[0].upper()] = replace_variables(vars, match.groups()[1])
  return vars


def replace_variables(set_variables, input_string):
  """
  Replaces variable within the input_string with their corresponding values
  from the given set_variables.
  """
  errors = False

  # In the case of a byte sequence, re.findall() will choke under python 3
  if sys.version_info.major > 2:
    if not isinstance(input_string, str):
      input_string = input_string.decode('utf-8')

  matches = set([v.upper() for v in re.findall(r'(?<!\\)\${([^}]+)}', input_string)])
  for name in matches:
    value = None
    # Check if syntax is correct
    var_name = get_var_name(name)
    if var_name is None:
      print('Error: Unknown substitution syntax (%s). ' % (name,) +
            'Use ${VAR:var_name}.', file=sys.stderr)
      errors = True
    else:
      # Replaces variable value
      if set_variables and var_name in set_variables:
        value = set_variables[var_name]
        if value is None:
          errors = True
        else:
          regexp = re.compile(r'(?<!\\)\${%s}' % (name,), re.IGNORECASE)
          input_string = regexp.sub(value, input_string)
      else:
        print('Error: Unknown variable %s' % (var_name), file=sys.stderr)
        errors = True
  if errors:
    return None
  else:
    return input_string


def get_var_name(name):
  """Looks for a namespace:var_name pattern in an option name.
     Returns the variable name if it's a match or None otherwise.
  """
  ns_match = re.match(r'^([^:]*):(.*)', name)
  if ns_match is not None:
    ns = ns_match.group(1)
    var_name = ns_match.group(2)
    if ns in ImpalaShell.VAR_PREFIXES:
      return var_name
  return None


def execute_queries_non_interactive_mode(options, query_options):
  """Run queries in non-interactive mode. Return True on success. Logs the
  error and returns False otherwise."""
  if options.query_file:
    # "-" here signifies input from STDIN
    if options.query_file == "-":
      query_text = sys.stdin.read()
    else:
      try:
        with open(options.query_file, 'r') as query_file_handle:
          query_text = query_file_handle.read()
      except Exception as e:
        print("Could not open file '%s': %s" % (options.query_file, e), file=sys.stderr)
        return False
  elif options.query:
    query_text = options.query
  else:
    return True

  queries = parse_query_text(query_text)
  with ImpalaShell(options, query_options) as shell:
    return (shell.execute_query_list(shell.cmdqueue) and
            shell.execute_query_list(queries))


def get_intro(options):
  """Get introduction message for start-up. The last character should not be a return."""
  if not options.verbose:
    return ""

  intro = WELCOME_STRING

  if not options.ssl and options.creds_ok_in_clear and options.use_ldap:
    intro += ("\n\nLDAP authentication is enabled, but the connection to Impala is "
              "not secured by TLS.\nALL PASSWORDS WILL BE SENT IN THE CLEAR TO IMPALA.")
  return intro


def impala_shell_main():
  """
  There are two types of options: shell options and query_options. Both can be set on the
  command line, which override default options. Specifically, if there exists a global
  config file (default path: /etc/impalarc) then options are loaded from that file. If
  there exists a user config file (~/.impalarc), then options are loaded in from that
  file and override any options already loaded from the global impalarc. The default shell
  options come from impala_shell_config_defaults.py. Query options have no defaults within
  the impala-shell, but they do have defaults on the server. Query options can be also
  changed in impala-shell with the 'set' command.
  """
  # pass defaults into option parser
  global options, parser
  parser = get_option_parser(impala_shell_defaults)
  options, args = parser.parse_args()

  # by default, use the impalarc in the user's home directory
  # and superimpose it on the global impalarc config
  global_config = os.path.expanduser(
    os.environ.get(ImpalaShell.GLOBAL_CONFIG_FILE,
                   impala_shell_defaults['global_config_default_path']))
  if os.path.isfile(global_config):
    # Always output the source of the global config if verbose
    if options.verbose:
      print(
        "Loading in options from global config file: %s \n" % global_config,
        file=sys.stderr)
  elif global_config != impala_shell_defaults['global_config_default_path']:
    print('%s not found.\n' % global_config, file=sys.stderr)
    raise FatalShellException()
  # Override the default user config by a custom config if necessary
  user_config = impala_shell_defaults.get("config_file")
  input_config = os.path.expanduser(options.config_file)
  # verify input_config, if found
  if input_config != user_config:
    if os.path.isfile(input_config):
      if options.verbose:
        print("Loading in options from config file: %s \n" % input_config,
              file=sys.stderr)
      # command line overrides loading ~/.impalarc
      user_config = input_config
    else:
      print('%s not found.\n' % input_config, file=sys.stderr)
      raise FatalShellException()
  configs_to_load = [global_config, user_config]

  # load shell and query options from the list of config files
  # in ascending order of precedence
  try:
    loaded_shell_options = {}
    query_options = {}
    for config_file in configs_to_load:
      s_options, q_options = get_config_from_file(config_file,
                                                  parser.option_list)
      loaded_shell_options.update(s_options)
      query_options.update(q_options)

    impala_shell_defaults.update(loaded_shell_options)
  except Exception as e:
    print(e, file=sys.stderr)
    raise FatalShellException()

  parser = get_option_parser(impala_shell_defaults)
  options, args = parser.parse_args()

  # Arguments that could not be parsed are stored in args. Print an error and exit.
  if len(args) > 0:
    print('Error, could not parse arguments "%s"' % (' ').join(args), file=sys.stderr)
    parser.print_help()
    raise FatalShellException()

  if options.version:
    print(VERSION_STRING)
    return

  if options.write_delimited:
    if isinstance(options.output_delimiter, str):
      delim_sequence = bytearray(options.output_delimiter, 'utf-8')
    else:
      delim_sequence = options.output_delimiter
    delim = delim_sequence.decode('unicode_escape')
    if len(delim) != 1:
      print("Illegal delimiter %s, the delimiter "
            "must be a 1-character string." % delim, file=sys.stderr)
      raise FatalShellException()

  if options.use_kerberos and options.use_ldap:
    print("Please specify at most one authentication mechanism (-k or -l)",
          file=sys.stderr)
    raise FatalShellException()

  if not options.ssl and not options.creds_ok_in_clear and options.use_ldap:
    print("LDAP credentials may not be sent over insecure " +
          "connections. Enable SSL or set --auth_creds_ok_in_clear",
          file=sys.stderr)
    raise FatalShellException()

  if not options.use_ldap and options.ldap_password_cmd:
    print("Option --ldap_password_cmd requires using LDAP authentication " +
          "mechanism (-l)", file=sys.stderr)
    raise FatalShellException()

  start_msg = "Starting Impala Shell"

  py_version_msg = "using Python {0}.{1}.{2}".format(
    sys.version_info.major, sys.version_info.minor, sys.version_info.micro)

  if options.use_kerberos:
    if options.verbose:
      kerb_msg = "with Kerberos authentication"
      print("{0} {1} {2}".format(start_msg, kerb_msg, py_version_msg), file=sys.stderr)
      print("Using service name '%s'" % options.kerberos_service_name, file=sys.stderr)
    # Check if the user has a ticket in the credentials cache
    try:
      if call(['klist', '-s']) != 0:
        print(("-k requires a valid kerberos ticket but no valid kerberos "
               "ticket found."), file=sys.stderr)
        raise FatalShellException()
    except OSError as e:
      print('klist not found on the system, install kerberos clients', file=sys.stderr)
      raise FatalShellException()
  elif options.use_ldap:
    if options.verbose:
      ldap_msg = "with LDAP-based authentication"
      print("{0} {1} {2}".format(start_msg, ldap_msg, py_version_msg), file=sys.stderr)
  else:
    if options.verbose:
      no_auth_msg = "with no authentication"
      print("{0} {1} {2}".format(start_msg, no_auth_msg, py_version_msg), file=sys.stderr)

  options.ldap_password = None
  if options.use_ldap and options.ldap_password_cmd:
    try:
      p = subprocess.Popen(shlex.split(options.ldap_password_cmd), stdout=subprocess.PIPE,
                           stderr=subprocess.PIPE)
      options.ldap_password, stderr = p.communicate()
      if p.returncode != 0:
        print("Error retrieving LDAP password (command was '%s', error was: "
              "'%s')" % (options.ldap_password_cmd, stderr.strip()), file=sys.stderr)
        raise FatalShellException()
    except Exception as e:
      print("Error retrieving LDAP password (command was: '%s', exception "
            "was: '%s')" % (options.ldap_password_cmd, e), file=sys.stderr)
      raise FatalShellException()

  if options.ssl:
    if options.ca_cert is None:
      if options.verbose:
        print("SSL is enabled. Impala server certificates will NOT be verified "
              "(set --ca_cert to change)", file=sys.stderr)
    else:
      if options.verbose:
        print("SSL is enabled", file=sys.stderr)

  if options.output_file:
    try:
      # Make sure the given file can be opened for writing. This will also clear the file
      # if successful.
      open(options.output_file, 'wb')
    except IOError as e:
      print('Error opening output file for writing: %s' % e, file=sys.stderr)
      raise FatalShellException()

  options.variables = parse_variables(options.keyval)

  # Override query_options from config file with those specified on the command line.
  query_options.update(
     [(k.upper(), v) for k, v in parse_variables(options.query_options).items()])

  # Non-interactive mode
  if options.query or options.query_file:
    # Impala shell will disable live_progress if non-interactive mode is detected.
    options.live_progress = False
    print("Warning: live_progress only applies to interactive shell sessions, "
          "and is being skipped for now.", file=sys.stderr)
    if options.live_summary:
      print("Error: live_summary is available for interactive mode only.",
            file=sys.stderr)
      raise FatalShellException()

    if execute_queries_non_interactive_mode(options, query_options):
      return
    else:
      raise FatalShellException()

  intro = get_intro(options)

  with ImpalaShell(options, query_options) as shell:
    while shell.is_alive:
      try:
        try:
          shell.cmdloop(intro)
        except KeyboardInterrupt:
          print('^C', file=sys.stderr)
        # A last measure against any exceptions thrown by an rpc
        # not caught in the shell
        except socket.error as e:
          # if the socket was interrupted, reconnect the connection with the client
          if e.errno == errno.EINTR:
            print(shell.CANCELLATION_MESSAGE)
            shell._reconnect_cancellation()
          else:
            print("Socket error %s: %s" % (e.errno, e), file=sys.stderr)
            shell.imp_client.connected = False
            shell.prompt = shell.DISCONNECTED_PROMPT
        except DisconnectedException as e:
          # the client has lost the connection
          print(e, file=sys.stderr)
          shell.imp_client.connected = False
          shell.prompt = shell.DISCONNECTED_PROMPT
        except QueryStateException as e:
          # an exception occurred while executing the query
          shell.imp_client.close_query(shell.last_query_handle)
          print(e, file=sys.stderr)
        except RPCException as e:
          # could not complete the rpc successfully
          print(e, file=sys.stderr)
        except IOError as e:
          # Interrupted system calls (e.g. because of cancellation) should be ignored.
          if e.errno != errno.EINTR: raise
      finally:
        intro = ''


if __name__ == "__main__":
  try:
    impala_shell_main()
  except FatalShellException:
    # Ensure that fatal errors cause a clean exit with error.
    sys.exit(1)
