All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.hive.beeline.BeeLine Maven / Gradle / Ivy

The newest version!
/**
 * 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.
 */

/*
 * This source file is based on code taken from SQLLine 1.0.2
 * See SQLLine notice in LICENSE
 */
package org.apache.hive.beeline;

import java.io.ByteArrayInputStream;
import java.io.Closeable;
import java.io.EOFException;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.io.SequenceInputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.net.JarURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.SQLWarning;
import java.sql.Statement;
import java.text.ChoiceFormat;
import java.text.MessageFormat;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Properties;
import java.util.ResourceBundle;
import java.util.Set;
import java.util.SortedSet;
import java.util.StringTokenizer;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.jar.Attributes;
import java.util.jar.Manifest;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

import jline.console.completer.Completer;
import jline.console.completer.StringsCompleter;
import jline.console.completer.FileNameCompleter;
import jline.console.ConsoleReader;
import jline.console.history.FileHistory;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.GnuParser;
import org.apache.commons.cli.OptionBuilder;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.hive.conf.HiveConf;
import org.apache.hadoop.io.IOUtils;
import org.apache.hive.beeline.cli.CliOptionsProcessor;
import org.apache.hive.common.util.ShutdownHookManager;
import org.apache.hive.beeline.hs2connection.BeelineHS2ConnectionFileParseException;
import org.apache.hive.beeline.hs2connection.HS2ConnectionFileUtils;
import org.apache.hive.beeline.hs2connection.UserHS2ConnectionFileParser;
import org.apache.hive.beeline.hs2connection.HS2ConnectionFileParser;
import org.apache.hive.beeline.hs2connection.HiveSiteHS2ConnectionFileParser;
import org.apache.thrift.transport.TTransportException;

import com.google.common.annotations.VisibleForTesting;

import org.apache.hive.jdbc.Utils;
import org.apache.hive.jdbc.Utils.JdbcConnectionParams;

/**
 * A console SQL shell with command completion.
 * 

* TODO: *

    *
  • User-friendly connection prompts
  • *
  • Page results
  • *
  • Handle binary data (blob fields)
  • *
  • Implement command aliases
  • *
  • Stored procedure execution
  • *
  • Binding parameters to prepared statements
  • *
  • Scripting language
  • *
  • XA transactions
  • *
* */ @SuppressWarnings("static-access") public class BeeLine implements Closeable { private static final ResourceBundle resourceBundle = ResourceBundle.getBundle(BeeLine.class.getSimpleName()); private final BeeLineSignalHandler signalHandler; private final Runnable shutdownHook; private static final String separator = System.getProperty("line.separator"); private boolean exit = false; private final DatabaseConnections connections = new DatabaseConnections(); public static final String COMMAND_PREFIX = "!"; private Collection drivers = null; private final BeeLineOpts opts = new BeeLineOpts(this, System.getProperties()); private String lastProgress = null; private final Map seenWarnings = new HashMap(); private final Commands commands = new Commands(this); private OutputFile scriptOutputFile = null; private OutputFile recordOutputFile = null; private PrintStream outputStream = new PrintStream(System.out, true); private PrintStream errorStream = new PrintStream(System.err, true); private ConsoleReader consoleReader; private List batch = null; private final Reflector reflector = new Reflector(this); private String dbName = null; private String currentDatabase = null; private FileHistory history; // Indicates if this instance of beeline is running in compatibility mode, or beeline mode private boolean isBeeLine = true; private static final Options options = new Options(); public static final String BEELINE_DEFAULT_JDBC_DRIVER = "org.apache.hive.jdbc.HiveDriver"; public static final String DEFAULT_DATABASE_NAME = "default"; private static final String SCRIPT_OUTPUT_PREFIX = ">>>"; private static final int SCRIPT_OUTPUT_PAD_SIZE = 5; private static final int ERRNO_OK = 0; private static final int ERRNO_ARGS = 1; private static final int ERRNO_OTHER = 2; private static final String HIVE_VAR_PREFIX = "--hivevar"; private static final String HIVE_CONF_PREFIX = "--hiveconf"; private static final String PROP_FILE_PREFIX = "--property-file"; static final String PASSWD_MASK = "[passwd stripped]"; private final Map formats = map(new Object[] { "vertical", new VerticalOutputFormat(this), "table", new TableOutputFormat(this), "csv2", new SeparatedValuesOutputFormat(this, ','), "tsv2", new SeparatedValuesOutputFormat(this, '\t'), "dsv", new SeparatedValuesOutputFormat(this, BeeLineOpts.DEFAULT_DELIMITER_FOR_DSV), "csv", new DeprecatedSeparatedValuesOutputFormat(this, ','), "tsv", new DeprecatedSeparatedValuesOutputFormat(this, '\t'), "xmlattr", new XMLAttributeOutputFormat(this), "xmlelements", new XMLElementOutputFormat(this), }); private List supportedLocalDriver = new ArrayList(Arrays.asList("com.mysql.jdbc.Driver", "org.postgresql.Driver")); final CommandHandler[] commandHandlers = new CommandHandler[] { new ReflectiveCommandHandler(this, new String[] {"quit", "done", "exit"}, null), new ReflectiveCommandHandler(this, new String[] {"connect", "open"}, new Completer[] {new StringsCompleter(getConnectionURLExamples())}), new ReflectiveCommandHandler(this, new String[] {"describe"}, new Completer[] {new TableNameCompletor(this)}), new ReflectiveCommandHandler(this, new String[] {"indexes"}, new Completer[] {new TableNameCompletor(this)}), new ReflectiveCommandHandler(this, new String[] {"primarykeys"}, new Completer[] {new TableNameCompletor(this)}), new ReflectiveCommandHandler(this, new String[] {"exportedkeys"}, new Completer[] {new TableNameCompletor(this)}), new ReflectiveCommandHandler(this, new String[] {"manual"}, null), new ReflectiveCommandHandler(this, new String[] {"importedkeys"}, new Completer[] {new TableNameCompletor(this)}), new ReflectiveCommandHandler(this, new String[] {"procedures"}, null), new ReflectiveCommandHandler(this, new String[] {"tables"}, null), new ReflectiveCommandHandler(this, new String[] {"typeinfo"}, null), new ReflectiveCommandHandler(this, new String[] {"columns"}, new Completer[] {new TableNameCompletor(this)}), new ReflectiveCommandHandler(this, new String[] {"reconnect"}, null), new ReflectiveCommandHandler(this, new String[] {"dropall"}, new Completer[] {new TableNameCompletor(this)}), new ReflectiveCommandHandler(this, new String[] {"history"}, null), new ReflectiveCommandHandler(this, new String[] {"metadata"}, new Completer[] { new StringsCompleter(getMetadataMethodNames())}), new ReflectiveCommandHandler(this, new String[] {"nativesql"}, null), new ReflectiveCommandHandler(this, new String[] {"dbinfo"}, null), new ReflectiveCommandHandler(this, new String[] {"rehash"}, null), new ReflectiveCommandHandler(this, new String[] {"verbose"}, null), new ReflectiveCommandHandler(this, new String[] {"run"}, new Completer[] {new FileNameCompleter()}), new ReflectiveCommandHandler(this, new String[] {"batch"}, null), new ReflectiveCommandHandler(this, new String[] {"list"}, null), new ReflectiveCommandHandler(this, new String[] {"all"}, null), new ReflectiveCommandHandler(this, new String[] {"go", "#"}, null), new ReflectiveCommandHandler(this, new String[] {"script"}, new Completer[] {new FileNameCompleter()}), new ReflectiveCommandHandler(this, new String[] {"record"}, new Completer[] {new FileNameCompleter()}), new ReflectiveCommandHandler(this, new String[] {"brief"}, null), new ReflectiveCommandHandler(this, new String[] {"close"}, null), new ReflectiveCommandHandler(this, new String[] {"closeall"}, null), new ReflectiveCommandHandler(this, new String[] {"isolation"}, new Completer[] {new StringsCompleter(getIsolationLevels())}), new ReflectiveCommandHandler(this, new String[] {"outputformat"}, new Completer[] {new StringsCompleter( formats.keySet().toArray(new String[0]))}), new ReflectiveCommandHandler(this, new String[] {"autocommit"}, null), new ReflectiveCommandHandler(this, new String[] {"commit"}, null), new ReflectiveCommandHandler(this, new String[] {"properties"}, new Completer[] {new FileNameCompleter()}), new ReflectiveCommandHandler(this, new String[] {"rollback"}, null), new ReflectiveCommandHandler(this, new String[] {"help", "?"}, null), new ReflectiveCommandHandler(this, new String[] {"set"}, getOpts().optionCompleters()), new ReflectiveCommandHandler(this, new String[] {"save"}, null), new ReflectiveCommandHandler(this, new String[] {"scan"}, null), new ReflectiveCommandHandler(this, new String[] {"sql"}, null), new ReflectiveCommandHandler(this, new String[] {"sh"}, null), new ReflectiveCommandHandler(this, new String[] {"call"}, null), new ReflectiveCommandHandler(this, new String[] {"nullemptystring"}, new Completer[] {new BooleanCompleter()}), new ReflectiveCommandHandler(this, new String[]{"addlocaldriverjar"}, null), new ReflectiveCommandHandler(this, new String[]{"addlocaldrivername"}, null) }; private final Completer beeLineCommandCompleter = new BeeLineCommandCompleter(Arrays.asList(commandHandlers)); static final SortedSet KNOWN_DRIVERS = new TreeSet(Arrays.asList( new String[] { "org.apache.hive.jdbc.HiveDriver", "org.apache.hadoop.hive.jdbc.HiveDriver", })); static { try { Class.forName("jline.console.ConsoleReader"); } catch (Throwable t) { throw new ExceptionInInitializerError("jline-missing"); } } static { // -d options.addOption(OptionBuilder .hasArg() .withArgName("driver class") .withDescription("the driver class to use") .create('d')); // -u options.addOption(OptionBuilder .hasArg() .withArgName("database url") .withDescription("the JDBC URL to connect to") .create('u')); // -r options.addOption(OptionBuilder .withLongOpt("reconnect") .withDescription("Reconnect to last saved connect url (in conjunction with !save)") .create('r')); // -n options.addOption(OptionBuilder .hasArg() .withArgName("username") .withDescription("the username to connect as") .create('n')); // -p options.addOption(OptionBuilder .hasArg() .withArgName("password") .withDescription("the password to connect as") .hasOptionalArg() .create('p')); // -w (or) --password-file options.addOption(OptionBuilder .hasArg() .withArgName("password-file") .withDescription("the password file to read password from") .withLongOpt("password-file") .create('w')); // -a options.addOption(OptionBuilder .hasArg() .withArgName("authType") .withDescription("the authentication type") .create('a')); // -i options.addOption(OptionBuilder .hasArg() .withArgName("init") .withDescription("script file for initialization") .create('i')); // -e options.addOption(OptionBuilder .hasArgs() .withArgName("query") .withDescription("query that should be executed") .create('e')); // -f