├── Gemfile ├── .travis.yml ├── lib ├── impala │ ├── version.rb │ ├── protocol.rb │ ├── protocol │ │ ├── status_constants.rb │ │ ├── impala_service_constants.rb │ │ ├── fb303_constants.rb │ │ ├── beeswax_constants.rb │ │ ├── fb303_types.rb │ │ ├── impala_hive_server2_service.rb │ │ ├── hive_metastore_constants.rb │ │ ├── cli_service_constants.rb │ │ ├── status_types.rb │ │ ├── impala_service_types.rb │ │ ├── beeswax_types.rb │ │ ├── impala_service.rb │ │ ├── facebook_service.rb │ │ ├── hive_metastore_types.rb │ │ └── beeswax_service.rb │ ├── sasl_transport.rb │ ├── cursor.rb │ └── connection.rb └── impala.rb ├── .gitignore ├── Rakefile ├── README.md ├── thrift ├── Status.thrift ├── fb303.thrift ├── beeswax.thrift ├── ImpalaService.thrift ├── hive_metastore.thrift └── cli_service.thrift ├── LICENSE.txt ├── impala.gemspec └── test ├── test_impala.rb └── test_impala_connected.rb /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | gemspec 3 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: ruby 3 | rvm: 4 | - 2.2 5 | -------------------------------------------------------------------------------- /lib/impala/version.rb: -------------------------------------------------------------------------------- 1 | module Impala 2 | VERSION = "0.5.1" 3 | end 4 | -------------------------------------------------------------------------------- /lib/impala/protocol.rb: -------------------------------------------------------------------------------- 1 | require 'impala/protocol/impala_service' 2 | 3 | module Impala 4 | # Taken as a whole, this module contains all the thrift-generated stuff that 5 | # defines the Impala protocol. 6 | module Protocol 7 | end 8 | end -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.gem 2 | *.rbc 3 | .bundle 4 | .config 5 | .yardoc 6 | .yardopts 7 | Gemfile.lock 8 | InstalledFiles 9 | _yardoc 10 | coverage 11 | doc/ 12 | lib/bundler/man 13 | pkg 14 | rdoc 15 | spec/reports 16 | test/tmp 17 | test/version_tmp 18 | tmp 19 | -------------------------------------------------------------------------------- /lib/impala/protocol/status_constants.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Autogenerated by Thrift Compiler (0.9.1) 3 | # 4 | # DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 5 | # 6 | 7 | require 'thrift' 8 | require 'status_types' 9 | 10 | module Impala 11 | module Protocol 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /lib/impala/protocol/impala_service_constants.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Autogenerated by Thrift Compiler (0.9.1) 3 | # 4 | # DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 5 | # 6 | 7 | require 'thrift' 8 | require 'impala_service_types' 9 | 10 | module Impala 11 | module Protocol 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /lib/impala/protocol/fb303_constants.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Autogenerated by Thrift Compiler (0.9.1) 3 | # 4 | # DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 5 | # 6 | 7 | require 'thrift' 8 | require 'fb303_types' 9 | 10 | module Impala 11 | module Protocol 12 | module Fb303 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /lib/impala/protocol/beeswax_constants.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Autogenerated by Thrift Compiler (0.9.1) 3 | # 4 | # DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 5 | # 6 | 7 | require 'thrift' 8 | require 'beeswax_types' 9 | 10 | module Impala 11 | module Protocol 12 | module Beeswax 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require "bundler/gem_tasks" 2 | require "rake/testtask" 3 | 4 | task :default => [:test] 5 | 6 | Rake::TestTask.new do |t| 7 | t.libs.push "lib" 8 | t.test_files = FileList['test/test_*.rb'] 9 | t.verbose = true 10 | end 11 | 12 | THRIFT_FILES = FileList['./thrift/*.thrift'] 13 | GENNED_FILES = FileList['./lib/impala/protocol/*'] 14 | 15 | task :gen do 16 | THRIFT_FILES.each do |f| 17 | sh "thrift -out lib/impala/protocol --gen rb #{f}" 18 | end 19 | end 20 | 21 | task :clean do 22 | GENNED_FILES.each { |f| rm f } 23 | end 24 | -------------------------------------------------------------------------------- /lib/impala/protocol/fb303_types.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Autogenerated by Thrift Compiler (0.9.1) 3 | # 4 | # DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 5 | # 6 | 7 | require 'thrift' 8 | 9 | module Impala 10 | module Protocol 11 | module Fb303 12 | module Fb_status 13 | DEAD = 0 14 | STARTING = 1 15 | ALIVE = 2 16 | STOPPING = 3 17 | STOPPED = 4 18 | WARNING = 5 19 | VALUE_MAP = {0 => "DEAD", 1 => "STARTING", 2 => "ALIVE", 3 => "STOPPING", 4 => "STOPPED", 5 => "WARNING"} 20 | VALID_VALUES = Set.new([DEAD, STARTING, ALIVE, STOPPING, STOPPED, WARNING]).freeze 21 | end 22 | 23 | end 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /lib/impala/protocol/impala_hive_server2_service.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Autogenerated by Thrift Compiler (0.9.1) 3 | # 4 | # DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 5 | # 6 | 7 | require 'thrift' 8 | require 't_c_l_i_service' 9 | require 'impala_service_types' 10 | 11 | module Impala 12 | module Protocol 13 | module ImpalaHiveServer2Service 14 | class Client < ::Impala::Protocol::Hive::TCLIService::Client 15 | include ::Thrift::Client 16 | 17 | end 18 | 19 | class Processor < ::Impala::Protocol::Hive::TCLIService::Processor 20 | include ::Thrift::Processor 21 | 22 | end 23 | 24 | # HELPER FUNCTIONS AND STRUCTURES 25 | 26 | end 27 | 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # impala-ruby 2 | 3 | [![build](https://travis-ci.org/colinmarc/impala-ruby.svg?branch=master)](https://travis-ci.org/colinmarc/impala-ruby)   [![rubygems](https://badge.fury.io/rb/impala.svg)](http://rubygems.org/gems/impala) 4 | 5 | This is a ruby client for [Cloudera Impala][1]. You use it like this: 6 | 7 | ```ruby 8 | require 'impala' 9 | 10 | Impala.connect('host', 21000) do |conn| 11 | conn.query('SELECT zip, income FROM zipcode_incomes LIMIT 5') 12 | end 13 | # => [{:zip=>'02446', :income=>89597}, ...] 14 | ``` 15 | 16 | You can also use cursors to avoid loading the entire result set into memory: 17 | 18 | ```ruby 19 | conn = Impala.connect('host', 21000) 20 | cursor = conn.execute('SELECT zip, income FROM zipcode_incomes ORDER BY income DESC') 21 | 22 | one_row = cursor.fetch_row 23 | cursor.each do |row| 24 | # etc 25 | end 26 | 27 | conn.close 28 | ``` 29 | 30 | [1]: https://ccp.cloudera.com/display/IMPALA10BETADOC/Introducing+Cloudera+Impala 31 | -------------------------------------------------------------------------------- /thrift/Status.thrift: -------------------------------------------------------------------------------- 1 | // Copyright 2012 Cloudera Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | namespace cpp impala 16 | namespace java com.cloudera.impala.thrift 17 | namespace rb impala.protocol 18 | 19 | enum TStatusCode { 20 | OK, 21 | CANCELLED, 22 | ANALYSIS_ERROR, 23 | NOT_IMPLEMENTED_ERROR, 24 | RUNTIME_ERROR, 25 | MEM_LIMIT_EXCEEDED, 26 | INTERNAL_ERROR 27 | } 28 | 29 | struct TStatus { 30 | 1: required TStatusCode status_code 31 | 2: list error_msgs 32 | } 33 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013 Colin Marc 2 | 3 | MIT License 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | "Software"), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /impala.gemspec: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | lib = File.expand_path('../lib', __FILE__) 3 | $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) 4 | require 'impala/version' 5 | 6 | Gem::Specification.new do |gem| 7 | gem.name = "impala" 8 | gem.version = Impala::VERSION 9 | gem.authors = ["Colin Marc"] 10 | gem.email = ["colinmarc@gmail.com"] 11 | gem.description = %q{A ruby client for Cloudera's Impala} 12 | gem.summary = %q{A ruby client for Cloudera's Impala} 13 | gem.homepage = "https://github.com/colinmarc/impala-ruby" 14 | gem.license = 'MIT' 15 | 16 | gem.add_dependency('thrift', '~> 0.9') 17 | gem.add_dependency('gssapi', '~> 1.2') 18 | 19 | gem.add_development_dependency('rake') 20 | gem.add_development_dependency('pry') 21 | 22 | gem.add_development_dependency('minitest') 23 | gem.add_development_dependency('mocha') 24 | 25 | gem.add_development_dependency('yard') 26 | gem.add_development_dependency('redcarpet') 27 | gem.add_development_dependency('github-markup') 28 | 29 | gem.files = `git ls-files`.split($/) 30 | gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) } 31 | gem.test_files = gem.files.grep(%r{^(test|spec|features)/}) 32 | gem.require_paths = ["lib"] 33 | end 34 | -------------------------------------------------------------------------------- /lib/impala/protocol/hive_metastore_constants.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Autogenerated by Thrift Compiler (0.9.1) 3 | # 4 | # DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 5 | # 6 | 7 | require 'thrift' 8 | require 'hive_metastore_types' 9 | 10 | module Impala 11 | module Protocol 12 | module HiveMetastore 13 | DDL_TIME = %q"transient_lastDdlTime" 14 | 15 | HIVE_FILTER_FIELD_OWNER = %q"hive_filter_field_owner__" 16 | 17 | HIVE_FILTER_FIELD_PARAMS = %q"hive_filter_field_params__" 18 | 19 | HIVE_FILTER_FIELD_LAST_ACCESS = %q"hive_filter_field_last_access__" 20 | 21 | IS_ARCHIVED = %q"is_archived" 22 | 23 | ORIGINAL_LOCATION = %q"original_location" 24 | 25 | META_TABLE_COLUMNS = %q"columns" 26 | 27 | META_TABLE_COLUMN_TYPES = %q"columns.types" 28 | 29 | BUCKET_FIELD_NAME = %q"bucket_field_name" 30 | 31 | BUCKET_COUNT = %q"bucket_count" 32 | 33 | FIELD_TO_DIMENSION = %q"field_to_dimension" 34 | 35 | META_TABLE_NAME = %q"name" 36 | 37 | META_TABLE_DB = %q"db" 38 | 39 | META_TABLE_LOCATION = %q"location" 40 | 41 | META_TABLE_SERDE = %q"serde" 42 | 43 | META_TABLE_PARTITION_COLUMNS = %q"partition_columns" 44 | 45 | FILE_INPUT_FORMAT = %q"file.inputformat" 46 | 47 | FILE_OUTPUT_FORMAT = %q"file.outputformat" 48 | 49 | META_TABLE_STORAGE = %q"storage_handler" 50 | 51 | end 52 | end 53 | end 54 | -------------------------------------------------------------------------------- /lib/impala/protocol/cli_service_constants.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Autogenerated by Thrift Compiler (0.9.1) 3 | # 4 | # DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 5 | # 6 | 7 | require 'thrift' 8 | require 'cli_service_types' 9 | 10 | module Impala 11 | module Protocol 12 | module Hive 13 | PRIMITIVE_TYPES = Set.new([ 14 | 0, 15 | 1, 16 | 2, 17 | 3, 18 | 4, 19 | 5, 20 | 6, 21 | 7, 22 | 8, 23 | 9, 24 | 15, 25 | ]) 26 | 27 | COMPLEX_TYPES = Set.new([ 28 | 10, 29 | 11, 30 | 12, 31 | 13, 32 | 14, 33 | ]) 34 | 35 | COLLECTION_TYPES = Set.new([ 36 | 10, 37 | 11, 38 | ]) 39 | 40 | TYPE_NAMES = { 41 | 0 => %q"BOOLEAN", 42 | 1 => %q"TINYINT", 43 | 2 => %q"SMALLINT", 44 | 3 => %q"INT", 45 | 4 => %q"BIGINT", 46 | 5 => %q"FLOAT", 47 | 6 => %q"DOUBLE", 48 | 7 => %q"STRING", 49 | 8 => %q"TIMESTAMP", 50 | 9 => %q"BINARY", 51 | 10 => %q"ARRAY", 52 | 11 => %q"MAP", 53 | 12 => %q"STRUCT", 54 | 13 => %q"UNIONTYPE", 55 | 15 => %q"DECIMAL", 56 | } 57 | 58 | end 59 | end 60 | end 61 | -------------------------------------------------------------------------------- /lib/impala/protocol/status_types.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Autogenerated by Thrift Compiler (0.9.1) 3 | # 4 | # DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 5 | # 6 | 7 | require 'thrift' 8 | 9 | module Impala 10 | module Protocol 11 | module TStatusCode 12 | OK = 0 13 | CANCELLED = 1 14 | ANALYSIS_ERROR = 2 15 | NOT_IMPLEMENTED_ERROR = 3 16 | RUNTIME_ERROR = 4 17 | MEM_LIMIT_EXCEEDED = 5 18 | INTERNAL_ERROR = 6 19 | VALUE_MAP = {0 => "OK", 1 => "CANCELLED", 2 => "ANALYSIS_ERROR", 3 => "NOT_IMPLEMENTED_ERROR", 4 => "RUNTIME_ERROR", 5 => "MEM_LIMIT_EXCEEDED", 6 => "INTERNAL_ERROR"} 20 | VALID_VALUES = Set.new([OK, CANCELLED, ANALYSIS_ERROR, NOT_IMPLEMENTED_ERROR, RUNTIME_ERROR, MEM_LIMIT_EXCEEDED, INTERNAL_ERROR]).freeze 21 | end 22 | 23 | class TStatus 24 | include ::Thrift::Struct, ::Thrift::Struct_Union 25 | STATUS_CODE = 1 26 | ERROR_MSGS = 2 27 | 28 | FIELDS = { 29 | STATUS_CODE => {:type => ::Thrift::Types::I32, :name => 'status_code', :enum_class => ::Impala::Protocol::TStatusCode}, 30 | ERROR_MSGS => {:type => ::Thrift::Types::LIST, :name => 'error_msgs', :element => {:type => ::Thrift::Types::STRING}} 31 | } 32 | 33 | def struct_fields; FIELDS; end 34 | 35 | def validate 36 | raise ::Thrift::ProtocolException.new(::Thrift::ProtocolException::UNKNOWN, 'Required field status_code is unset!') unless @status_code 37 | unless @status_code.nil? || ::Impala::Protocol::TStatusCode::VALID_VALUES.include?(@status_code) 38 | raise ::Thrift::ProtocolException.new(::Thrift::ProtocolException::UNKNOWN, 'Invalid value of field status_code!') 39 | end 40 | end 41 | 42 | ::Thrift::Struct.generate_accessors self 43 | end 44 | 45 | end 46 | end 47 | -------------------------------------------------------------------------------- /lib/impala.rb: -------------------------------------------------------------------------------- 1 | 2 | # the generated ruby files use a relative require, so we need to add the 3 | # generated directory to $LOAD_PATH 4 | this_dir = File.expand_path(File.dirname(__FILE__)) 5 | gen_dir = File.join(this_dir, 'impala/protocol') 6 | $LOAD_PATH.push(gen_dir) unless $LOAD_PATH.include?(gen_dir) 7 | 8 | require 'impala/version' 9 | 10 | require 'thrift' 11 | require 'time' 12 | require 'impala/protocol' 13 | require 'impala/sasl_transport' 14 | require 'impala/cursor' 15 | require 'impala/connection' 16 | 17 | module Impala 18 | DEFAULT_HOST = 'localhost' 19 | DEFAULT_PORT = 21000 20 | class InvalidQueryError < StandardError; end 21 | class ConnectionError < StandardError; end 22 | class CursorError < StandardError; end 23 | class ParsingError < StandardError; end 24 | 25 | # Connect to an Impala server. If a block is given, it will close the 26 | # connection after yielding the connection to the block. 27 | # @param [String] host the hostname or IP address of the Impala server 28 | # @param [int] port the port that the Impala server is listening on 29 | # @param [Hash] options connection options 30 | # @option options [int] :timeout the timeout in seconds to use when connecting 31 | # @option options [Hash] :sasl if present, used to connect with SASL PLAIN 32 | # authentication. Should have two properties: 33 | # - *:username* (String) 34 | # - *:password* (String) 35 | # @option options [Hash] :kerberos if present, used to connect with SASL 36 | # GSSAPI authentication using whatever context is available. Should have two 37 | # properties: 38 | # - *:host* (String) 39 | # - *:provider* (String) 40 | # @yieldparam [Connection] conn the open connection. Will be closed once the block 41 | # finishes 42 | # @return [Connection] the open connection, or, if a block is 43 | # passed, the return value of the block 44 | def self.connect(host=DEFAULT_HOST, port=DEFAULT_PORT, options={}) 45 | connection = Connection.new(host, port, options) 46 | 47 | if block_given? 48 | begin 49 | ret = yield connection 50 | ensure 51 | connection.close 52 | end 53 | else 54 | ret = connection 55 | end 56 | 57 | ret 58 | end 59 | end 60 | -------------------------------------------------------------------------------- /thrift/fb303.thrift: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | /** 21 | * fb303.thrift 22 | */ 23 | 24 | namespace java com.facebook.fb303 25 | namespace cpp facebook.fb303 26 | namespace rb Impala.Protocol.fb303 27 | 28 | /** 29 | * Common status reporting mechanism across all services 30 | */ 31 | enum fb_status { 32 | DEAD = 0, 33 | STARTING = 1, 34 | ALIVE = 2, 35 | STOPPING = 3, 36 | STOPPED = 4, 37 | WARNING = 5, 38 | } 39 | 40 | /** 41 | * Standard base service 42 | */ 43 | service FacebookService { 44 | 45 | /** 46 | * Returns a descriptive name of the service 47 | */ 48 | string getName(), 49 | 50 | /** 51 | * Returns the version of the service 52 | */ 53 | string getVersion(), 54 | 55 | /** 56 | * Gets the status of this service 57 | */ 58 | fb_status getStatus(), 59 | 60 | /** 61 | * User friendly description of status, such as why the service is in 62 | * the dead or warning state, or what is being started or stopped. 63 | */ 64 | string getStatusDetails(), 65 | 66 | /** 67 | * Gets the counters for this service 68 | */ 69 | map getCounters(), 70 | 71 | /** 72 | * Gets the value of a single counter 73 | */ 74 | i64 getCounter(1: string key), 75 | 76 | /** 77 | * Sets an option 78 | */ 79 | void setOption(1: string key, 2: string value), 80 | 81 | /** 82 | * Gets an option 83 | */ 84 | string getOption(1: string key), 85 | 86 | /** 87 | * Gets all options 88 | */ 89 | map getOptions(), 90 | 91 | /** 92 | * Returns a CPU profile over the given time interval (client and server 93 | * must agree on the profile format). 94 | */ 95 | string getCpuProfile(1: i32 profileDurationInSec), 96 | 97 | /** 98 | * Returns the unix time that the server has been running since 99 | */ 100 | i64 aliveSince(), 101 | 102 | /** 103 | * Tell the server to reload its configuration, reopen log files, etc 104 | */ 105 | oneway void reinitialize(), 106 | 107 | /** 108 | * Suggest a shutdown to the server 109 | */ 110 | oneway void shutdown(), 111 | 112 | } 113 | -------------------------------------------------------------------------------- /test/test_impala.rb: -------------------------------------------------------------------------------- 1 | require 'impala' 2 | require 'minitest/autorun' 3 | require 'mocha/setup' 4 | 5 | describe 'Impala.connect' do 6 | before do 7 | Thrift::Socket.expects(:new).with('host', 12345, nil) 8 | Thrift::BufferedTransport.expects(:new).once.returns(stub(:open => nil)) 9 | Thrift::BinaryProtocol.expects(:new).once 10 | Impala::Protocol::ImpalaService::Client.expects(:new).once 11 | end 12 | 13 | it 'should return an open connection when passed a block' do 14 | connection = Impala.connect('host', 12345) 15 | assert_equal(Impala::Connection, connection.class) 16 | assert_equal(true, connection.open?) 17 | end 18 | 19 | it 'should return the results of the query when given a block with a query, and then close tho connection' do 20 | Impala::Connection.any_instance.stubs(:query => 'result') 21 | Impala::Connection.any_instance.expects(:close).once 22 | 23 | ret = Impala.connect('host', 12345) do |conn| 24 | conn.query('query') 25 | end 26 | 27 | assert_equal('result', ret) 28 | end 29 | end 30 | 31 | describe Impala::Connection do 32 | describe '#check_result' do 33 | before do 34 | Impala::Connection.any_instance.stubs(:open) 35 | @connection = Impala::Connection.new('test', 1234) 36 | @service = stub(:get_state => nil) 37 | @connection.instance_variable_set('@service', @service) 38 | end 39 | 40 | it 'should close the handle if an exception is raised, and then re-raise' do 41 | handle = stub() 42 | @service.expects(:close).with(handle).once 43 | @service.expects(:get_state).raises(StandardError) 44 | assert_raises(StandardError) { @connection.send(:check_result, handle) } 45 | end 46 | end 47 | 48 | describe '#execute' do 49 | before do 50 | Impala::Connection.any_instance.stubs(:open) 51 | Impala::Cursor.stubs(:new) 52 | @connection = Impala::Connection.new('test', 1234) 53 | @connection.stubs(:open? => true, :check_result => nil) 54 | end 55 | 56 | it 'should call Protocol::ImpalaService::Client#executeAndWait with the query' do 57 | query = Impala::Protocol::Beeswax::Query.new 58 | query.query = 'query' 59 | query.configuration = [] 60 | 61 | @service = stub() 62 | @service.expects(:executeAndWait).with(query, Impala::Connection::LOG_CONTEXT_ID).once 63 | @connection.instance_variable_set('@service', @service) 64 | 65 | @connection.execute('query') 66 | end 67 | 68 | it 'should call Protocol::ImpalaService::Client#executeAndWait with the hadoop_user and configuration if passed as parameter' do 69 | query = Impala::Protocol::Beeswax::Query.new 70 | query.query = 'query' 71 | query.hadoop_user = 'impala' 72 | query.configuration = %w|NUM_SCANNER_THREADS=8 MEM_LIMIT=3221225472| 73 | 74 | @service = stub() 75 | @service.expects(:executeAndWait).with(query, Impala::Connection::LOG_CONTEXT_ID).once 76 | @connection.instance_variable_set('@service', @service) 77 | 78 | opt = { 79 | :user => 'impala', 80 | :num_scanner_threads => 8, 81 | :mem_limit => 3221225472 82 | } 83 | @connection.execute('query', opt) 84 | end 85 | end 86 | end 87 | -------------------------------------------------------------------------------- /lib/impala/protocol/impala_service_types.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Autogenerated by Thrift Compiler (0.9.1) 3 | # 4 | # DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 5 | # 6 | 7 | require 'thrift' 8 | require 'status_types' 9 | require 'beeswax_types' 10 | require 'cli_service_types' 11 | 12 | 13 | module Impala 14 | module Protocol 15 | module TImpalaQueryOptions 16 | ABORT_ON_ERROR = 0 17 | MAX_ERRORS = 1 18 | DISABLE_CODEGEN = 2 19 | BATCH_SIZE = 3 20 | MEM_LIMIT = 4 21 | NUM_NODES = 5 22 | MAX_SCAN_RANGE_LENGTH = 6 23 | MAX_IO_BUFFERS = 7 24 | NUM_SCANNER_THREADS = 8 25 | ALLOW_UNSUPPORTED_FORMATS = 9 26 | DEFAULT_ORDER_BY_LIMIT = 10 27 | DEBUG_ACTION = 11 28 | ABORT_ON_DEFAULT_LIMIT_EXCEEDED = 12 29 | PARQUET_COMPRESSION_CODEC = 13 30 | HBASE_CACHING = 14 31 | HBASE_CACHE_BLOCKS = 15 32 | VALUE_MAP = {0 => "ABORT_ON_ERROR", 1 => "MAX_ERRORS", 2 => "DISABLE_CODEGEN", 3 => "BATCH_SIZE", 4 => "MEM_LIMIT", 5 => "NUM_NODES", 6 => "MAX_SCAN_RANGE_LENGTH", 7 => "MAX_IO_BUFFERS", 8 => "NUM_SCANNER_THREADS", 9 => "ALLOW_UNSUPPORTED_FORMATS", 10 => "DEFAULT_ORDER_BY_LIMIT", 11 => "DEBUG_ACTION", 12 => "ABORT_ON_DEFAULT_LIMIT_EXCEEDED", 13 => "PARQUET_COMPRESSION_CODEC", 14 => "HBASE_CACHING", 15 => "HBASE_CACHE_BLOCKS"} 33 | VALID_VALUES = Set.new([ABORT_ON_ERROR, MAX_ERRORS, DISABLE_CODEGEN, BATCH_SIZE, MEM_LIMIT, NUM_NODES, MAX_SCAN_RANGE_LENGTH, MAX_IO_BUFFERS, NUM_SCANNER_THREADS, ALLOW_UNSUPPORTED_FORMATS, DEFAULT_ORDER_BY_LIMIT, DEBUG_ACTION, ABORT_ON_DEFAULT_LIMIT_EXCEEDED, PARQUET_COMPRESSION_CODEC, HBASE_CACHING, HBASE_CACHE_BLOCKS]).freeze 34 | end 35 | 36 | class TInsertResult 37 | include ::Thrift::Struct, ::Thrift::Struct_Union 38 | ROWS_APPENDED = 1 39 | 40 | FIELDS = { 41 | ROWS_APPENDED => {:type => ::Thrift::Types::MAP, :name => 'rows_appended', :key => {:type => ::Thrift::Types::STRING}, :value => {:type => ::Thrift::Types::I64}} 42 | } 43 | 44 | def struct_fields; FIELDS; end 45 | 46 | def validate 47 | raise ::Thrift::ProtocolException.new(::Thrift::ProtocolException::UNKNOWN, 'Required field rows_appended is unset!') unless @rows_appended 48 | end 49 | 50 | ::Thrift::Struct.generate_accessors self 51 | end 52 | 53 | class TPingImpalaServiceResp 54 | include ::Thrift::Struct, ::Thrift::Struct_Union 55 | VERSION = 1 56 | 57 | FIELDS = { 58 | VERSION => {:type => ::Thrift::Types::STRING, :name => 'version'} 59 | } 60 | 61 | def struct_fields; FIELDS; end 62 | 63 | def validate 64 | end 65 | 66 | ::Thrift::Struct.generate_accessors self 67 | end 68 | 69 | class TResetTableReq 70 | include ::Thrift::Struct, ::Thrift::Struct_Union 71 | DB_NAME = 1 72 | TABLE_NAME = 2 73 | 74 | FIELDS = { 75 | DB_NAME => {:type => ::Thrift::Types::STRING, :name => 'db_name'}, 76 | TABLE_NAME => {:type => ::Thrift::Types::STRING, :name => 'table_name'} 77 | } 78 | 79 | def struct_fields; FIELDS; end 80 | 81 | def validate 82 | raise ::Thrift::ProtocolException.new(::Thrift::ProtocolException::UNKNOWN, 'Required field db_name is unset!') unless @db_name 83 | raise ::Thrift::ProtocolException.new(::Thrift::ProtocolException::UNKNOWN, 'Required field table_name is unset!') unless @table_name 84 | end 85 | 86 | ::Thrift::Struct.generate_accessors self 87 | end 88 | 89 | end 90 | end 91 | -------------------------------------------------------------------------------- /lib/impala/sasl_transport.rb: -------------------------------------------------------------------------------- 1 | require 'gssapi' 2 | 3 | module Impala 4 | class SASLTransport < Thrift::FramedTransport 5 | STATUS_BYTES = 1 6 | PAYLOAD_LENGTH_BYTES = 4 7 | NEGOTIATION_STATUS = { 8 | START: 0x01, 9 | OK: 0x02, 10 | BAD: 0x03, 11 | ERROR: 0x04, 12 | COMPLETE: 0x05 13 | } 14 | 15 | def initialize(transport, mechanism, options={}) 16 | super(transport) 17 | @mechanism = mechanism.to_sym 18 | @options = options 19 | 20 | unless [:PLAIN, :GSSAPI].include? @mechanism 21 | raise "Unknown SASL mechanism: #{@mechanism}" 22 | end 23 | 24 | if @mechanism == :GSSAPI 25 | @gsscli = GSSAPI::Simple.new(@options[:host], @options[:principal]) 26 | end 27 | end 28 | 29 | def open 30 | super 31 | 32 | case @mechanism 33 | when :PLAIN 34 | handshake_plain! 35 | when :GSSAPI 36 | handshake_gssapi! 37 | end 38 | end 39 | 40 | private 41 | 42 | def handshake_plain! 43 | username = @options.fetch(:username, 'anonymous') 44 | password = @options.fetch(:password, 'anonymous') 45 | 46 | token = "[PLAIN]\u0000#{username}\u0000#{password}" 47 | write_handshake_message(NEGOTIATION_STATUS[:START], 'PLAIN') 48 | write_handshake_message(NEGOTIATION_STATUS[:OK], token) 49 | 50 | status, _ = read_handshake_message 51 | case status 52 | when NEGOTIATION_STATUS[:COMPLETE] 53 | @open = true 54 | when NEGOTIATION_STATUS[:OK] 55 | raise "Failed to complete challenge exchange: only NONE supported currently" 56 | end 57 | end 58 | 59 | def handshake_gssapi! 60 | token = @gsscli.init_context 61 | write_handshake_message(NEGOTIATION_STATUS[:START], 'GSSAPI') 62 | write_handshake_message(NEGOTIATION_STATUS[:OK], token) 63 | 64 | status, msg = read_handshake_message 65 | case status 66 | when NEGOTIATION_STATUS[:COMPLETE] 67 | raise "Unexpected COMPLETE from server" 68 | when NEGOTIATION_STATUS[:OK] 69 | unless @gsscli.init_context(msg) 70 | raise "GSSAPI: challenge provided by server could not be verified" 71 | end 72 | 73 | write_handshake_message(NEGOTIATION_STATUS[:OK], "") 74 | 75 | status, msg = read_handshake_message 76 | case status 77 | when NEGOTIATION_STATUS[:COMPLETE] 78 | raise "Unexpected COMPLETE from server" 79 | when NEGOTIATION_STATUS[:OK] 80 | unwrapped = @gsscli.unwrap_message(msg) 81 | rewrapped = @gsscli.wrap_message(unwrapped) 82 | 83 | write_handshake_message(NEGOTIATION_STATUS[:COMPLETE], rewrapped) 84 | 85 | status, msg = read_handshake_message 86 | case status 87 | when NEGOTIATION_STATUS[:COMPLETE] 88 | @open = true 89 | when NEGOTIATION_STATUS[:OK] 90 | raise "Failed to complete GSS challenge exchange" 91 | end 92 | end 93 | end 94 | end 95 | 96 | def read_handshake_message 97 | status, len = @transport.read(STATUS_BYTES + PAYLOAD_LENGTH_BYTES).unpack('cl>') 98 | body = @transport.to_io.read(len) 99 | if [NEGOTIATION_STATUS[:BAD], NEGOTIATION_STATUS[:ERROR]].include?(status) 100 | raise "Exception from server: #{body}" 101 | end 102 | 103 | [status, body] 104 | end 105 | 106 | def write_handshake_message(status, message) 107 | header = [status, message.length].pack('cl>') 108 | @transport.write(header + message) 109 | end 110 | end 111 | 112 | class SASLTransportFactory < Thrift::BaseTransportFactory 113 | def get_transport(transport) 114 | return SASLTransport.new(transport) 115 | end 116 | end 117 | end 118 | -------------------------------------------------------------------------------- /lib/impala/cursor.rb: -------------------------------------------------------------------------------- 1 | module Impala 2 | # Cursors are used to iterate over result sets without loading them all 3 | # into memory at once. This can be useful if you're dealing with lots of 4 | # rows. It implements Enumerable, so you can use each/select/map/etc. 5 | class Cursor 6 | BUFFER_SIZE = 1024 7 | include Enumerable 8 | 9 | def initialize(handle, service) 10 | @handle = handle 11 | @service = service 12 | 13 | 14 | @row_buffer = [] 15 | @done = false 16 | @open = true 17 | 18 | fetch_more 19 | end 20 | 21 | def inspect 22 | "#<#{self.class}#{open? ? '' : ' (CLOSED)'}>" 23 | end 24 | 25 | def each 26 | while row = fetch_row 27 | yield row 28 | end 29 | end 30 | 31 | # Returns the next available row as a hash, or nil if there are none left. 32 | # @return [Hash, nil] the next available row, or nil if there are none 33 | # left 34 | # @see #fetch_all 35 | def fetch_row 36 | if @row_buffer.empty? 37 | if @done 38 | return nil 39 | else 40 | fetch_more 41 | end 42 | end 43 | 44 | @row_buffer.shift 45 | end 46 | 47 | # Returns all the remaining rows in the result set. 48 | # @return [Array] the remaining rows in the result set 49 | # @see #fetch_one 50 | def fetch_all 51 | self.to_a 52 | end 53 | 54 | # Close the cursor on the remote server. Once a cursor is closed, you 55 | # can no longer fetch any rows from it. 56 | def close 57 | @open = false 58 | @service.close(@handle) 59 | end 60 | 61 | # Returns true if the cursor is still open. 62 | def open? 63 | @open 64 | end 65 | 66 | # Returns true if there are any more rows to fetch. 67 | def has_more? 68 | !@done || !@row_buffer.empty? 69 | end 70 | 71 | def runtime_profile 72 | @service.GetRuntimeProfile(@handle) 73 | end 74 | 75 | private 76 | 77 | def metadata 78 | @metadata ||= @service.get_results_metadata(@handle) 79 | end 80 | 81 | def fetch_more 82 | fetch_batch until @done || @row_buffer.count >= BUFFER_SIZE 83 | end 84 | 85 | def fetch_batch 86 | raise CursorError.new("Cursor has expired or been closed") unless @open 87 | 88 | begin 89 | res = @service.fetch(@handle, false, BUFFER_SIZE) 90 | rescue Protocol::Beeswax::BeeswaxException 91 | @open = false 92 | raise CursorError.new("Cursor has expired or been closed") 93 | end 94 | 95 | rows = res.data.map { |raw| parse_row(raw) } 96 | @row_buffer.concat(rows) 97 | 98 | unless res.has_more 99 | @done = true 100 | close 101 | end 102 | end 103 | 104 | def parse_row(raw) 105 | row = {} 106 | fields = raw.split(metadata.delim) 107 | 108 | metadata.schema.fieldSchemas.zip(fields).each do |schema, raw_value| 109 | value = convert_raw_value(raw_value, schema) 110 | row[schema.name.to_sym] = value 111 | end 112 | 113 | row 114 | end 115 | 116 | def convert_raw_value(value, schema) 117 | return nil if value == 'NULL' 118 | 119 | case schema.type 120 | when 'string' 121 | value 122 | when 'boolean' 123 | if value == 'true' 124 | true 125 | elsif value == 'false' 126 | false 127 | else 128 | raise ParsingError.new("Invalid value for boolean: #{value}") 129 | end 130 | when 'tinyint', 'smallint', 'int', 'bigint' 131 | value.to_i 132 | when 'double', 'float', 'decimal' 133 | value.to_f 134 | when "timestamp" 135 | Time.parse(value) 136 | else 137 | raise ParsingError.new("Unknown type: #{schema.type}") 138 | end 139 | end 140 | end 141 | end 142 | -------------------------------------------------------------------------------- /lib/impala/connection.rb: -------------------------------------------------------------------------------- 1 | module Impala 2 | # This object represents a connection to an Impala server. It can be used to 3 | # perform queries on the database. 4 | class Connection 5 | LOG_CONTEXT_ID = "impala-ruby" 6 | 7 | # Don't instantiate Connections directly; instead, use {Impala.connect}. 8 | def initialize(host, port, options={}) 9 | @host = host 10 | @port = port 11 | @options = options 12 | @connected = false 13 | open 14 | end 15 | 16 | def inspect 17 | "#<#{self.class} #{@host}:#{@port}#{open? ? '' : ' (DISCONNECTED)'}>" 18 | end 19 | 20 | # Open the connection if it's currently closed. 21 | def open 22 | return if @connected 23 | 24 | socket = Thrift::Socket.new(@host, @port, @options[:timeout]) 25 | 26 | if @options[:kerberos] 27 | @transport = SASLTransport.new(socket, :GSSAPI, @options[:kerberos]) 28 | elsif @options[:sasl] 29 | @transport = SASLTransport.new(socket, :PLAIN, @options[:sasl]) 30 | else 31 | @transport = Thrift::BufferedTransport.new(socket) 32 | end 33 | 34 | @transport.open 35 | 36 | proto = Thrift::BinaryProtocol.new(@transport) 37 | @service = Protocol::ImpalaService::Client.new(proto) 38 | @connected = true 39 | end 40 | 41 | # Close this connection. It can still be reopened with {#open}. 42 | def close 43 | return unless @connected 44 | 45 | @transport.close 46 | @connected = false 47 | end 48 | 49 | # Returns true if the connection is currently open. 50 | def open? 51 | @connected 52 | end 53 | 54 | # Refresh the metadata store. 55 | def refresh 56 | raise ConnectionError.new("Connection closed") unless open? 57 | @service.ResetCatalog 58 | end 59 | 60 | # Perform a query and return all the results. This will 61 | # load the entire result set into memory, so if you're dealing with lots 62 | # of rows, {#execute} may work better. 63 | # @param [String] query the query you want to run 64 | # @param [Hash] query_options the options to set user and configuration 65 | # except for :user, see TImpalaQueryOptions in ImpalaService.thrift 66 | # @option query_options [String] :user the user runs the query 67 | # @return [Array] an array of hashes, one for each row. 68 | def query(query, query_options = {}) 69 | execute(query, query_options).fetch_all 70 | end 71 | 72 | # Perform a query and return a cursor for iterating over the results. 73 | # @param [String] query the query you want to run 74 | # @param [Hash] query_options the options to set user and configuration 75 | # except for :user, see TImpalaQueryOptions in ImpalaService.thrift 76 | # @option query_options [String] :user the user runs the query 77 | # @return [Cursor] a cursor for the result rows 78 | def execute(query, query_options = {}) 79 | raise ConnectionError.new("Connection closed") unless open? 80 | 81 | handle = send_query(query, query_options) 82 | check_result(handle) 83 | Cursor.new(handle, @service) 84 | end 85 | 86 | private 87 | 88 | def send_query(query_text, query_options) 89 | query = Protocol::Beeswax::Query.new 90 | query.query = query_text 91 | 92 | query.hadoop_user = query_options.delete(:user) if query_options[:user] 93 | query.configuration = query_options.map do |key, value| 94 | "#{key.upcase}=#{value}" 95 | end 96 | 97 | @service.executeAndWait(query, LOG_CONTEXT_ID) 98 | end 99 | 100 | def check_result(handle) 101 | state = @service.get_state(handle) 102 | if state == Protocol::Beeswax::QueryState::EXCEPTION 103 | close_handle(handle) 104 | raise ConnectionError.new("The query was aborted") 105 | end 106 | rescue 107 | close_handle(handle) 108 | raise 109 | end 110 | 111 | def close_handle(handle) 112 | @service.close(handle) 113 | end 114 | end 115 | end 116 | -------------------------------------------------------------------------------- /thrift/beeswax.thrift: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to Cloudera, Inc. under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. Cloudera, Inc. licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | * 18 | * Interface for interacting with Beeswax Server 19 | */ 20 | 21 | namespace java com.cloudera.beeswax.api 22 | namespace py beeswaxd 23 | namespace cpp beeswax 24 | namespace rb impala.protocol.beeswax 25 | 26 | include "hive_metastore.thrift" 27 | 28 | // A Query 29 | struct Query { 30 | 1: string query; 31 | // A list of HQL commands to execute before the query. 32 | // This is typically defining UDFs, setting settings, and loading resources. 33 | 3: list configuration; 34 | 35 | // User and groups to "act as" for purposes of Hadoop. 36 | 4: string hadoop_user; 37 | } 38 | 39 | typedef string LogContextId 40 | 41 | enum QueryState { 42 | CREATED, 43 | INITIALIZED, 44 | COMPILED, 45 | RUNNING, 46 | FINISHED, 47 | EXCEPTION 48 | } 49 | 50 | struct QueryHandle { 51 | 1: string id; 52 | 2: LogContextId log_context; 53 | } 54 | 55 | struct QueryExplanation { 56 | 1: string textual 57 | } 58 | 59 | struct Results { 60 | // If set, data is valid. Otherwise, results aren't ready yet. 61 | 1: bool ready, 62 | // Columns for the results 63 | 2: list columns, 64 | // A set of results 65 | 3: list data, 66 | // The starting row of the results 67 | 4: i64 start_row, 68 | // Whether there are more results to fetch 69 | 5: bool has_more 70 | } 71 | 72 | /** 73 | * Metadata information about the results. 74 | * Applicable only for SELECT. 75 | */ 76 | struct ResultsMetadata { 77 | /** The schema of the results */ 78 | 1: hive_metastore.Schema schema, 79 | /** The directory containing the results. Not applicable for partition table. */ 80 | 2: string table_dir, 81 | /** If the results are straight from an existing table, the table name. */ 82 | 3: string in_tablename, 83 | /** Field delimiter */ 84 | 4: string delim, 85 | } 86 | 87 | exception BeeswaxException { 88 | 1: string message, 89 | // Use get_log(log_context) to retrieve any log related to this exception 90 | 2: LogContextId log_context, 91 | // (Optional) The QueryHandle that caused this exception 92 | 3: QueryHandle handle, 93 | 4: optional i32 errorCode = 0, 94 | 5: optional string SQLState = " " 95 | } 96 | 97 | exception QueryNotFoundException { 98 | } 99 | 100 | /** Represents a Hadoop-style configuration variable. */ 101 | struct ConfigVariable { 102 | 1: string key, 103 | 2: string value, 104 | 3: string description 105 | } 106 | 107 | service BeeswaxService { 108 | /** 109 | * Submit a query and return a handle (QueryHandle). The query runs asynchronously. 110 | */ 111 | QueryHandle query(1:Query query) throws(1:BeeswaxException error), 112 | 113 | /** 114 | * run a query synchronously and return a handle (QueryHandle). 115 | */ 116 | QueryHandle executeAndWait(1:Query query, 2:LogContextId clientCtx) 117 | throws(1:BeeswaxException error), 118 | 119 | /** 120 | * Get the query plan for a query. 121 | */ 122 | QueryExplanation explain(1:Query query) 123 | throws(1:BeeswaxException error), 124 | 125 | /** 126 | * Get the results of a query. This is non-blocking. Caller should check 127 | * Results.ready to determine if the results are in yet. The call requests 128 | * the batch size of fetch. 129 | */ 130 | Results fetch(1:QueryHandle query_id, 2:bool start_over, 3:i32 fetch_size=-1) 131 | throws(1:QueryNotFoundException error, 2:BeeswaxException error2), 132 | 133 | /** 134 | * Get the state of the query 135 | */ 136 | QueryState get_state(1:QueryHandle handle) throws(1:QueryNotFoundException error), 137 | 138 | /** 139 | * Get the result metadata 140 | */ 141 | ResultsMetadata get_results_metadata(1:QueryHandle handle) 142 | throws(1:QueryNotFoundException error), 143 | 144 | /** 145 | * Used to test connection to server. A "noop" command. 146 | */ 147 | string echo(1:string s) 148 | 149 | /** 150 | * Returns a string representation of the configuration object being used. 151 | * Handy for debugging. 152 | */ 153 | string dump_config() 154 | 155 | /** 156 | * Get the log messages related to the given context. 157 | */ 158 | string get_log(1:LogContextId context) throws(1:QueryNotFoundException error) 159 | 160 | /* 161 | * Returns "default" configuration. 162 | */ 163 | list get_default_configuration(1:bool include_hadoop) 164 | 165 | /* 166 | * closes the query with given handle 167 | */ 168 | void close(1:QueryHandle handle) throws(1:QueryNotFoundException error, 169 | 2:BeeswaxException error2) 170 | 171 | /* 172 | * clean the log context for given id 173 | */ 174 | void clean(1:LogContextId log_context) 175 | } 176 | -------------------------------------------------------------------------------- /lib/impala/protocol/beeswax_types.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Autogenerated by Thrift Compiler (0.9.1) 3 | # 4 | # DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 5 | # 6 | 7 | require 'thrift' 8 | require 'hive_metastore_types' 9 | 10 | 11 | module Impala 12 | module Protocol 13 | module Beeswax 14 | module QueryState 15 | CREATED = 0 16 | INITIALIZED = 1 17 | COMPILED = 2 18 | RUNNING = 3 19 | FINISHED = 4 20 | EXCEPTION = 5 21 | VALUE_MAP = {0 => "CREATED", 1 => "INITIALIZED", 2 => "COMPILED", 3 => "RUNNING", 4 => "FINISHED", 5 => "EXCEPTION"} 22 | VALID_VALUES = Set.new([CREATED, INITIALIZED, COMPILED, RUNNING, FINISHED, EXCEPTION]).freeze 23 | end 24 | 25 | class Query 26 | include ::Thrift::Struct, ::Thrift::Struct_Union 27 | QUERY = 1 28 | CONFIGURATION = 3 29 | HADOOP_USER = 4 30 | 31 | FIELDS = { 32 | QUERY => {:type => ::Thrift::Types::STRING, :name => 'query'}, 33 | CONFIGURATION => {:type => ::Thrift::Types::LIST, :name => 'configuration', :element => {:type => ::Thrift::Types::STRING}}, 34 | HADOOP_USER => {:type => ::Thrift::Types::STRING, :name => 'hadoop_user'} 35 | } 36 | 37 | def struct_fields; FIELDS; end 38 | 39 | def validate 40 | end 41 | 42 | ::Thrift::Struct.generate_accessors self 43 | end 44 | 45 | class QueryHandle 46 | include ::Thrift::Struct, ::Thrift::Struct_Union 47 | ID = 1 48 | LOG_CONTEXT = 2 49 | 50 | FIELDS = { 51 | ID => {:type => ::Thrift::Types::STRING, :name => 'id'}, 52 | LOG_CONTEXT => {:type => ::Thrift::Types::STRING, :name => 'log_context'} 53 | } 54 | 55 | def struct_fields; FIELDS; end 56 | 57 | def validate 58 | end 59 | 60 | ::Thrift::Struct.generate_accessors self 61 | end 62 | 63 | class QueryExplanation 64 | include ::Thrift::Struct, ::Thrift::Struct_Union 65 | TEXTUAL = 1 66 | 67 | FIELDS = { 68 | TEXTUAL => {:type => ::Thrift::Types::STRING, :name => 'textual'} 69 | } 70 | 71 | def struct_fields; FIELDS; end 72 | 73 | def validate 74 | end 75 | 76 | ::Thrift::Struct.generate_accessors self 77 | end 78 | 79 | class Results 80 | include ::Thrift::Struct, ::Thrift::Struct_Union 81 | READY = 1 82 | COLUMNS = 2 83 | DATA = 3 84 | START_ROW = 4 85 | HAS_MORE = 5 86 | 87 | FIELDS = { 88 | READY => {:type => ::Thrift::Types::BOOL, :name => 'ready'}, 89 | COLUMNS => {:type => ::Thrift::Types::LIST, :name => 'columns', :element => {:type => ::Thrift::Types::STRING}}, 90 | DATA => {:type => ::Thrift::Types::LIST, :name => 'data', :element => {:type => ::Thrift::Types::STRING}}, 91 | START_ROW => {:type => ::Thrift::Types::I64, :name => 'start_row'}, 92 | HAS_MORE => {:type => ::Thrift::Types::BOOL, :name => 'has_more'} 93 | } 94 | 95 | def struct_fields; FIELDS; end 96 | 97 | def validate 98 | end 99 | 100 | ::Thrift::Struct.generate_accessors self 101 | end 102 | 103 | # Metadata information about the results. 104 | # Applicable only for SELECT. 105 | class ResultsMetadata 106 | include ::Thrift::Struct, ::Thrift::Struct_Union 107 | SCHEMA = 1 108 | TABLE_DIR = 2 109 | IN_TABLENAME = 3 110 | DELIM = 4 111 | 112 | FIELDS = { 113 | # The schema of the results 114 | SCHEMA => {:type => ::Thrift::Types::STRUCT, :name => 'schema', :class => ::Impala::Protocol::HiveMetastore::Schema}, 115 | # The directory containing the results. Not applicable for partition table. 116 | TABLE_DIR => {:type => ::Thrift::Types::STRING, :name => 'table_dir'}, 117 | # If the results are straight from an existing table, the table name. 118 | IN_TABLENAME => {:type => ::Thrift::Types::STRING, :name => 'in_tablename'}, 119 | # Field delimiter 120 | DELIM => {:type => ::Thrift::Types::STRING, :name => 'delim'} 121 | } 122 | 123 | def struct_fields; FIELDS; end 124 | 125 | def validate 126 | end 127 | 128 | ::Thrift::Struct.generate_accessors self 129 | end 130 | 131 | class BeeswaxException < ::Thrift::Exception 132 | include ::Thrift::Struct, ::Thrift::Struct_Union 133 | MESSAGE = 1 134 | LOG_CONTEXT = 2 135 | HANDLE = 3 136 | ERRORCODE = 4 137 | SQLSTATE = 5 138 | 139 | FIELDS = { 140 | MESSAGE => {:type => ::Thrift::Types::STRING, :name => 'message'}, 141 | LOG_CONTEXT => {:type => ::Thrift::Types::STRING, :name => 'log_context'}, 142 | HANDLE => {:type => ::Thrift::Types::STRUCT, :name => 'handle', :class => ::Impala::Protocol::Beeswax::QueryHandle}, 143 | ERRORCODE => {:type => ::Thrift::Types::I32, :name => 'errorCode', :default => 0, :optional => true}, 144 | SQLSTATE => {:type => ::Thrift::Types::STRING, :name => 'SQLState', :default => %q" ", :optional => true} 145 | } 146 | 147 | def struct_fields; FIELDS; end 148 | 149 | def validate 150 | end 151 | 152 | ::Thrift::Struct.generate_accessors self 153 | end 154 | 155 | class QueryNotFoundException < ::Thrift::Exception 156 | include ::Thrift::Struct, ::Thrift::Struct_Union 157 | 158 | FIELDS = { 159 | 160 | } 161 | 162 | def struct_fields; FIELDS; end 163 | 164 | def validate 165 | end 166 | 167 | ::Thrift::Struct.generate_accessors self 168 | end 169 | 170 | # Represents a Hadoop-style configuration variable. 171 | class ConfigVariable 172 | include ::Thrift::Struct, ::Thrift::Struct_Union 173 | KEY = 1 174 | VALUE = 2 175 | DESCRIPTION = 3 176 | 177 | FIELDS = { 178 | KEY => {:type => ::Thrift::Types::STRING, :name => 'key'}, 179 | VALUE => {:type => ::Thrift::Types::STRING, :name => 'value'}, 180 | DESCRIPTION => {:type => ::Thrift::Types::STRING, :name => 'description'} 181 | } 182 | 183 | def struct_fields; FIELDS; end 184 | 185 | def validate 186 | end 187 | 188 | ::Thrift::Struct.generate_accessors self 189 | end 190 | 191 | end 192 | end 193 | end 194 | -------------------------------------------------------------------------------- /thrift/ImpalaService.thrift: -------------------------------------------------------------------------------- 1 | // Copyright 2012 Cloudera Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | namespace cpp impala 16 | namespace java com.cloudera.impala.thrift 17 | namespace rb impala.protocol 18 | 19 | include "Status.thrift" 20 | include "beeswax.thrift" 21 | include "cli_service.thrift" 22 | 23 | // ImpalaService accepts query execution options through beeswax.Query.configuration in 24 | // key:value form. For example, the list of strings could be: 25 | // "num_nodes:1", "abort_on_error:false" 26 | // The valid keys are listed in this enum. They map to TQueryOptions. 27 | // Note: If you add an option or change the default, you also need to update: 28 | // - ImpalaInternalService.thrift: TQueryOptions 29 | // - ImpaladClientExecutor.getBeeswaxQueryConfigurations() 30 | // - ImpalaServer::SetQueryOptions() 31 | // - ImpalaServer::TQueryOptionsToMap() 32 | enum TImpalaQueryOptions { 33 | // if true, abort execution on the first error 34 | ABORT_ON_ERROR, 35 | 36 | // maximum # of errors to be reported; Unspecified or 0 indicates backend default 37 | MAX_ERRORS, 38 | 39 | // if true, disable llvm codegen 40 | DISABLE_CODEGEN, 41 | 42 | // batch size to be used by backend; Unspecified or a size of 0 indicates backend 43 | // default 44 | BATCH_SIZE, 45 | 46 | // a per-machine approximate limit on the memory consumption of this query; 47 | // unspecified or a limit of 0 means no limit; 48 | // otherwise specified either as: 49 | // a) an int (= number of bytes); 50 | // b) a float followed by "M" (MB) or "G" (GB) 51 | MEM_LIMIT, 52 | 53 | // specifies the degree of parallelism with which to execute the query; 54 | // 1: single-node execution 55 | // NUM_NODES_ALL: executes on all nodes that contain relevant data 56 | // NUM_NODES_ALL_RACKS: executes on one node per rack that holds relevant data 57 | // > 1: executes on at most that many nodes at any point in time (ie, there can be 58 | // more nodes than numNodes with plan fragments for this query, but at most 59 | // numNodes would be active at any point in time) 60 | // Constants (NUM_NODES_ALL, NUM_NODES_ALL_RACKS) are defined in JavaConstants.thrift. 61 | NUM_NODES, 62 | 63 | // maximum length of the scan range; only applicable to HDFS scan range; Unspecified or 64 | // a length of 0 indicates backend default; 65 | MAX_SCAN_RANGE_LENGTH, 66 | 67 | // Maximum number of io buffers (per disk) 68 | MAX_IO_BUFFERS, 69 | 70 | // Number of scanner threads. 71 | NUM_SCANNER_THREADS, 72 | 73 | // If true, Impala will try to execute on file formats that are not fully supported yet 74 | ALLOW_UNSUPPORTED_FORMATS, 75 | 76 | // if set and > -1, specifies the default limit applied to a top-level SELECT statement 77 | // with an ORDER BY but without a LIMIT clause (ie, if the SELECT statement also has 78 | // a LIMIT clause, this default is ignored) 79 | DEFAULT_ORDER_BY_LIMIT, 80 | 81 | // DEBUG ONLY: 82 | // If set to 83 | // "[:]::", 84 | // the exec node with the given id will perform the specified action in the given 85 | // phase. If the optional backend number (starting from 0) is specified, only that 86 | // backend instance will perform the debug action, otherwise all backends will behave 87 | // in that way. 88 | // If the string doesn't have the required format or if any of its components is 89 | // invalid, the option is ignored. 90 | DEBUG_ACTION, 91 | 92 | // If true, raise an error when the DEFAULT_ORDER_BY_LIMIT has been reached. 93 | ABORT_ON_DEFAULT_LIMIT_EXCEEDED, 94 | 95 | // Compression codec for parquet when inserting into parquet tables. 96 | // Valid values are "snappy", "gzip" and "none" 97 | // Leave blank to use default. 98 | PARQUET_COMPRESSION_CODEC, 99 | 100 | // HBase scan query option. If set and > 0, HBASE_CACHING is the value for 101 | // "hbase.client.Scan.setCaching()" when querying HBase table. Otherwise, use backend 102 | // default. 103 | // If the value is too high, then the hbase region server will have a hard time (GC 104 | // pressure and long response times). If the value is too small, then there will be 105 | // extra trips to the hbase region server. 106 | HBASE_CACHING, 107 | 108 | // HBase scan query option. If set, HBase scan will always set 109 | // "hbase.client.setCacheBlocks" to CACHE_BLOCKS. Default is false. 110 | // If the table is large and the query is doing big scan, set it to false to 111 | // avoid polluting the cache in the hbase region server. 112 | // If the table is small and the table is used several time, set it to true to improve 113 | // performance. 114 | HBASE_CACHE_BLOCKS, 115 | } 116 | 117 | // The summary of an insert. 118 | struct TInsertResult { 119 | // Number of appended rows per modified partition. Only applies to HDFS tables. 120 | // The keys represent partitions to create, coded as k1=v1/k2=v2/k3=v3..., with the 121 | // root in an unpartitioned table being the empty string. 122 | 1: required map rows_appended 123 | } 124 | 125 | // Response from a call to PingImpalaService 126 | struct TPingImpalaServiceResp { 127 | // The Impala service's version string. 128 | 1: string version 129 | } 130 | 131 | // Parameters for a ResetTable request which will invalidate a table's metadata. 132 | // DEPRECATED. 133 | struct TResetTableReq { 134 | // Name of the table's parent database. 135 | 1: required string db_name 136 | 137 | // Name of the table. 138 | 2: required string table_name 139 | } 140 | 141 | // For all rpc that return a TStatus as part of their result type, 142 | // if the status_code field is set to anything other than OK, the contents 143 | // of the remainder of the result type is undefined (typically not set) 144 | service ImpalaService extends beeswax.BeeswaxService { 145 | // Cancel execution of query. Returns RUNTIME_ERROR if query_id 146 | // unknown. 147 | // This terminates all threads running on behalf of this query at 148 | // all nodes that were involved in the execution. 149 | // Throws BeeswaxException if the query handle is invalid (this doesn't 150 | // necessarily indicate an error: the query might have finished). 151 | Status.TStatus Cancel(1:beeswax.QueryHandle query_id) 152 | throws(1:beeswax.BeeswaxException error); 153 | 154 | // Invalidates all catalog metadata, forcing a reload 155 | // DEPRECATED; execute query "invalidate metadata" to refresh metadata 156 | Status.TStatus ResetCatalog(); 157 | 158 | // Invalidates a specific table's catalog metadata, forcing a reload on the next access 159 | // DEPRECATED; execute query "refresh " to refresh metadata 160 | Status.TStatus ResetTable(1:TResetTableReq request) 161 | 162 | // Returns the runtime profile string for the given query handle. 163 | string GetRuntimeProfile(1:beeswax.QueryHandle query_id) 164 | throws(1:beeswax.BeeswaxException error); 165 | 166 | // Closes the query handle and return the result summary of the insert. 167 | TInsertResult CloseInsert(1:beeswax.QueryHandle handle) 168 | throws(1:beeswax.QueryNotFoundException error, 2:beeswax.BeeswaxException error2); 169 | 170 | // Client calls this RPC to verify that the server is an ImpalaService. Returns the 171 | // server version. 172 | TPingImpalaServiceResp PingImpalaService(); 173 | } 174 | 175 | // Impala HiveServer2 service 176 | service ImpalaHiveServer2Service extends cli_service.TCLIService { 177 | } 178 | -------------------------------------------------------------------------------- /test/test_impala_connected.rb: -------------------------------------------------------------------------------- 1 | require 'impala' 2 | require 'minitest/autorun' 3 | require 'mocha' 4 | 5 | # these are tests that require an available Impala server. To run them, 6 | # declare a IMPALA_SERVER env var, e.g. `IMPALA_SERVER=localhost:21000 rake` 7 | IMPALA_SERVER = ENV['IMPALA_SERVER'] 8 | 9 | def connect 10 | parts = IMPALA_SERVER.split(':') 11 | if parts.length != 2 || parts.any? { |p| p.empty? } 12 | raise "Invalid IMPALA_SERVER: #{IMPALA_SERVER}" 13 | end 14 | 15 | host, port = parts 16 | Impala.connect(host, port) 17 | end 18 | 19 | describe 'connected tests' do 20 | before do 21 | skip unless IMPALA_SERVER 22 | @connection = connect 23 | end 24 | 25 | describe 'basic tests' do 26 | it 'can connect' do 27 | assert_instance_of(Impala::Connection, @connection) 28 | assert(@connection.open?, "the connection should be open") 29 | end 30 | 31 | it 'can refresh the catalog' do 32 | @connection.refresh 33 | end 34 | 35 | it 'can refresh metadata' do 36 | @connection.query('invalidate metadata') 37 | end 38 | 39 | it 'can run a basic query' do 40 | ret = @connection.query('SELECT "foo" AS foo') 41 | assert_equal([{:foo=>'foo'}], ret, "the result should be a list of hashes") 42 | end 43 | 44 | it 'can run a basic query with some query options as specified user' do 45 | ret = @connection.query('SELECT "foo" AS foo', 46 | :user => 'someoneelse', 47 | :mem_limit => 1234567890, 48 | :max_scan_range_length => 1024 * 1024 * 1024) 49 | assert_equal([{:foo=>'foo'}], ret, "the result should be a list of hashes") 50 | end 51 | 52 | it 'can handle boolean values' do 53 | ret = @connection.query('SELECT TRUE AS foo') 54 | assert_equal([{:foo=>true}], ret, "the result should be a bool") 55 | end 56 | 57 | it 'can handle double values' do 58 | ret = @connection.query('SELECT CAST(1.23 AS double) AS foo') 59 | assert_equal([{:foo=>1.23}], ret, "the result should be a float") 60 | end 61 | 62 | it 'can handle smallint values' do 63 | ret = @connection.query('SELECT CAST(123 AS smallint) AS foo') 64 | assert_equal([{:foo=>123}], ret, "the result should be an integer") 65 | end 66 | 67 | it 'can handle float values' do 68 | ret = @connection.query('SELECT CAST(1.23 AS float) as foo') 69 | assert_instance_of(Float, ret.first[:foo], "the result should be a float") 70 | end 71 | 72 | it 'can handle decimal values' do 73 | ret = @connection.query('SELECT CAST(1.5 AS decimal(9,4)) as foo') 74 | assert_instance_of(Float, ret.first[:foo], "the result should be a float") 75 | end 76 | 77 | it 'can handle timestamp values' do 78 | ret = @connection.query('SELECT NOW() AS foo') 79 | assert_instance_of(Time, ret.first[:foo], "the result should be a timestamp") 80 | end 81 | 82 | it 'can handle null values' do 83 | ret = @connection.query('SELECT NULL AS nothing') 84 | assert_equal(nil, ret.first[:nothing], "the result should be nil") 85 | end 86 | 87 | it 'can successfully refresh the metadata store' do 88 | ret = @connection.refresh 89 | end 90 | 91 | it 'can get the runtime profile from a cursor' do 92 | cursor = @connection.execute('SELECT NOW() as foo') 93 | ret = cursor.runtime_profile 94 | assert_instance_of(String, ret, "the result should be a string") 95 | end 96 | end 97 | 98 | describe 'with a test database' do 99 | before do 100 | @database = '_impala_ruby_test' 101 | @connection.query("CREATE DATABASE IF NOT EXISTS #{@database}") 102 | end 103 | 104 | after do 105 | @connection.query("DROP DATABASE IF EXISTS #{@database}") if @connection 106 | end 107 | 108 | it 'can use the database' do 109 | @connection.query("USE #{@database}") 110 | @connection.query("USE default") 111 | end 112 | 113 | describe 'and a test table' do 114 | before do 115 | @table = "#{@database}.foobar" 116 | @connection.query("DROP TABLE IF EXISTS #{@table}") 117 | @connection.query("CREATE TABLE #{@table} (i INT)") 118 | end 119 | 120 | after do 121 | @connection.query("DROP TABLE #{@table}") if @connection 122 | end 123 | 124 | it 'deals with empty tables correctly when using #query' do 125 | res = @connection.query("SELECT * FROM #{@table}") 126 | assert_equal([], res, "the result set should be empty") 127 | end 128 | 129 | it 'deals with empty tables correctly when using a cursor' do 130 | cursor = @connection.execute("SELECT * FROM #{@table}") 131 | assert_equal(false, cursor.has_more?, "has_more? should be false") 132 | assert_nil(cursor.fetch_row, "calls to fetch_row should be nil") 133 | end 134 | 135 | describe 'with data' do 136 | before do 137 | @connection.query("INSERT INTO #{@table} (i) SELECT 1") 138 | @connection.query("INSERT INTO #{@table} (i) SELECT 1") 139 | @connection.query("INSERT INTO #{@table} (i) SELECT 1") 140 | end 141 | 142 | it 'can handle the keywoard "with"' do 143 | res = @connection.query("with bar as (select * from #{@table}) select * from bar") 144 | assert_equal([{:i => 1}, {:i => 1}, {:i => 1}], res) 145 | end 146 | 147 | it 'can insert into the table' do 148 | @connection.query("INSERT INTO #{@table} (i) SELECT 2") 149 | end 150 | 151 | it 'can select from the table using #query' do 152 | res = @connection.query("SELECT * FROM #{@table}") 153 | assert_equal([{:i => 1}, {:i => 1}, {:i => 1}], res) 154 | end 155 | 156 | it 'can create a cursor and fetch one row at a time' do 157 | cursor = @connection.execute("SELECT * FROM #{@table}") 158 | assert_instance_of(Impala::Cursor, cursor, "the result should be a cursor") 159 | 160 | 3.times do 161 | row = cursor.fetch_row 162 | assert_equal({:i=>1}, row, "the row should be a hash with the correct result") 163 | end 164 | 165 | assert_equal(false, cursor.has_more?, "has_more? should be false") 166 | assert_nil(cursor.fetch_row, "subsequent calls to fetch_row should be nil") 167 | assert_equal(false, cursor.open?, "the cursor should be closed once it has returned all the rows") 168 | end 169 | 170 | it 'can use a cursor to deal with lots of data' do 171 | 10.times { @connection.query("INSERT INTO #{@table} SELECT * FROM #{@table}") } 172 | @connection.query("INSERT INTO #{@table} (i) SELECT 1") 173 | count = @connection.query("SELECT COUNT(*) as n from #{@table}")[0][:n] 174 | assert(count > Impala::Cursor::BUFFER_SIZE) # otherwise the test is pointless 175 | 176 | cursor = @connection.execute("SELECT * FROM #{@table}") 177 | assert_instance_of(Impala::Cursor, cursor, "the result should be a cursor") 178 | 179 | # fetch one to fill the buffer 180 | row = cursor.fetch_row 181 | assert_equal({:i=>1}, row, "the row should be a hash with the correct result") 182 | 183 | buffer_size = cursor.instance_variable_get('@row_buffer').size 184 | assert_equal(Impala::Cursor::BUFFER_SIZE - 1, buffer_size, "it should only buffer #{Impala::Cursor::BUFFER_SIZE} rows into memory") 185 | 186 | (count - 1).times do 187 | row = cursor.fetch_row 188 | assert_equal({:i=>1}, row, "the row should be a hash with the correct result") 189 | end 190 | 191 | assert_equal(false, cursor.has_more?, "has_more? should be false") 192 | assert_nil(cursor.fetch_row, "subsequent calls to fetch_row should be nil") 193 | assert_equal(false, cursor.open?, "the cursor should be closed once it has returned all the rows") 194 | end 195 | 196 | it 'can handle interspersed NULL values' do 197 | @connection.query("INSERT INTO #{@table} (i) SELECT NULL") 198 | res = @connection.query("SELECT * FROM #{@table} ORDER BY i DESC LIMIT 4") 199 | assert_equal([{:i => nil}, {:i => 1}, {:i => 1}, {:i => 1}], res) 200 | end 201 | 202 | it 'can alter table add column' do 203 | @connection.query("ALTER TABLE #{@table} ADD COLUMNS (new INT)") 204 | end 205 | end 206 | 207 | end 208 | end 209 | end 210 | -------------------------------------------------------------------------------- /lib/impala/protocol/impala_service.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Autogenerated by Thrift Compiler (0.9.1) 3 | # 4 | # DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 5 | # 6 | 7 | require 'thrift' 8 | require 'beeswax_service' 9 | require 'impala_service_types' 10 | 11 | module Impala 12 | module Protocol 13 | module ImpalaService 14 | class Client < ::Impala::Protocol::Beeswax::BeeswaxService::Client 15 | include ::Thrift::Client 16 | 17 | def Cancel(query_id) 18 | send_Cancel(query_id) 19 | return recv_Cancel() 20 | end 21 | 22 | def send_Cancel(query_id) 23 | send_message('Cancel', Cancel_args, :query_id => query_id) 24 | end 25 | 26 | def recv_Cancel() 27 | result = receive_message(Cancel_result) 28 | return result.success unless result.success.nil? 29 | raise result.error unless result.error.nil? 30 | raise ::Thrift::ApplicationException.new(::Thrift::ApplicationException::MISSING_RESULT, 'Cancel failed: unknown result') 31 | end 32 | 33 | def ResetCatalog() 34 | send_ResetCatalog() 35 | return recv_ResetCatalog() 36 | end 37 | 38 | def send_ResetCatalog() 39 | send_message('ResetCatalog', ResetCatalog_args) 40 | end 41 | 42 | def recv_ResetCatalog() 43 | result = receive_message(ResetCatalog_result) 44 | return result.success unless result.success.nil? 45 | raise ::Thrift::ApplicationException.new(::Thrift::ApplicationException::MISSING_RESULT, 'ResetCatalog failed: unknown result') 46 | end 47 | 48 | def ResetTable(request) 49 | send_ResetTable(request) 50 | return recv_ResetTable() 51 | end 52 | 53 | def send_ResetTable(request) 54 | send_message('ResetTable', ResetTable_args, :request => request) 55 | end 56 | 57 | def recv_ResetTable() 58 | result = receive_message(ResetTable_result) 59 | return result.success unless result.success.nil? 60 | raise ::Thrift::ApplicationException.new(::Thrift::ApplicationException::MISSING_RESULT, 'ResetTable failed: unknown result') 61 | end 62 | 63 | def GetRuntimeProfile(query_id) 64 | send_GetRuntimeProfile(query_id) 65 | return recv_GetRuntimeProfile() 66 | end 67 | 68 | def send_GetRuntimeProfile(query_id) 69 | send_message('GetRuntimeProfile', GetRuntimeProfile_args, :query_id => query_id) 70 | end 71 | 72 | def recv_GetRuntimeProfile() 73 | result = receive_message(GetRuntimeProfile_result) 74 | return result.success unless result.success.nil? 75 | raise result.error unless result.error.nil? 76 | raise ::Thrift::ApplicationException.new(::Thrift::ApplicationException::MISSING_RESULT, 'GetRuntimeProfile failed: unknown result') 77 | end 78 | 79 | def CloseInsert(handle) 80 | send_CloseInsert(handle) 81 | return recv_CloseInsert() 82 | end 83 | 84 | def send_CloseInsert(handle) 85 | send_message('CloseInsert', CloseInsert_args, :handle => handle) 86 | end 87 | 88 | def recv_CloseInsert() 89 | result = receive_message(CloseInsert_result) 90 | return result.success unless result.success.nil? 91 | raise result.error unless result.error.nil? 92 | raise result.error2 unless result.error2.nil? 93 | raise ::Thrift::ApplicationException.new(::Thrift::ApplicationException::MISSING_RESULT, 'CloseInsert failed: unknown result') 94 | end 95 | 96 | def PingImpalaService() 97 | send_PingImpalaService() 98 | return recv_PingImpalaService() 99 | end 100 | 101 | def send_PingImpalaService() 102 | send_message('PingImpalaService', PingImpalaService_args) 103 | end 104 | 105 | def recv_PingImpalaService() 106 | result = receive_message(PingImpalaService_result) 107 | return result.success unless result.success.nil? 108 | raise ::Thrift::ApplicationException.new(::Thrift::ApplicationException::MISSING_RESULT, 'PingImpalaService failed: unknown result') 109 | end 110 | 111 | end 112 | 113 | class Processor < ::Impala::Protocol::Beeswax::BeeswaxService::Processor 114 | include ::Thrift::Processor 115 | 116 | def process_Cancel(seqid, iprot, oprot) 117 | args = read_args(iprot, Cancel_args) 118 | result = Cancel_result.new() 119 | begin 120 | result.success = @handler.Cancel(args.query_id) 121 | rescue ::Impala::Protocol::Beeswax::BeeswaxException => error 122 | result.error = error 123 | end 124 | write_result(result, oprot, 'Cancel', seqid) 125 | end 126 | 127 | def process_ResetCatalog(seqid, iprot, oprot) 128 | args = read_args(iprot, ResetCatalog_args) 129 | result = ResetCatalog_result.new() 130 | result.success = @handler.ResetCatalog() 131 | write_result(result, oprot, 'ResetCatalog', seqid) 132 | end 133 | 134 | def process_ResetTable(seqid, iprot, oprot) 135 | args = read_args(iprot, ResetTable_args) 136 | result = ResetTable_result.new() 137 | result.success = @handler.ResetTable(args.request) 138 | write_result(result, oprot, 'ResetTable', seqid) 139 | end 140 | 141 | def process_GetRuntimeProfile(seqid, iprot, oprot) 142 | args = read_args(iprot, GetRuntimeProfile_args) 143 | result = GetRuntimeProfile_result.new() 144 | begin 145 | result.success = @handler.GetRuntimeProfile(args.query_id) 146 | rescue ::Impala::Protocol::Beeswax::BeeswaxException => error 147 | result.error = error 148 | end 149 | write_result(result, oprot, 'GetRuntimeProfile', seqid) 150 | end 151 | 152 | def process_CloseInsert(seqid, iprot, oprot) 153 | args = read_args(iprot, CloseInsert_args) 154 | result = CloseInsert_result.new() 155 | begin 156 | result.success = @handler.CloseInsert(args.handle) 157 | rescue ::Impala::Protocol::Beeswax::QueryNotFoundException => error 158 | result.error = error 159 | rescue ::Impala::Protocol::Beeswax::BeeswaxException => error2 160 | result.error2 = error2 161 | end 162 | write_result(result, oprot, 'CloseInsert', seqid) 163 | end 164 | 165 | def process_PingImpalaService(seqid, iprot, oprot) 166 | args = read_args(iprot, PingImpalaService_args) 167 | result = PingImpalaService_result.new() 168 | result.success = @handler.PingImpalaService() 169 | write_result(result, oprot, 'PingImpalaService', seqid) 170 | end 171 | 172 | end 173 | 174 | # HELPER FUNCTIONS AND STRUCTURES 175 | 176 | class Cancel_args 177 | include ::Thrift::Struct, ::Thrift::Struct_Union 178 | QUERY_ID = 1 179 | 180 | FIELDS = { 181 | QUERY_ID => {:type => ::Thrift::Types::STRUCT, :name => 'query_id', :class => ::Impala::Protocol::Beeswax::QueryHandle} 182 | } 183 | 184 | def struct_fields; FIELDS; end 185 | 186 | def validate 187 | end 188 | 189 | ::Thrift::Struct.generate_accessors self 190 | end 191 | 192 | class Cancel_result 193 | include ::Thrift::Struct, ::Thrift::Struct_Union 194 | SUCCESS = 0 195 | ERROR = 1 196 | 197 | FIELDS = { 198 | SUCCESS => {:type => ::Thrift::Types::STRUCT, :name => 'success', :class => ::Impala::Protocol::TStatus}, 199 | ERROR => {:type => ::Thrift::Types::STRUCT, :name => 'error', :class => ::Impala::Protocol::Beeswax::BeeswaxException} 200 | } 201 | 202 | def struct_fields; FIELDS; end 203 | 204 | def validate 205 | end 206 | 207 | ::Thrift::Struct.generate_accessors self 208 | end 209 | 210 | class ResetCatalog_args 211 | include ::Thrift::Struct, ::Thrift::Struct_Union 212 | 213 | FIELDS = { 214 | 215 | } 216 | 217 | def struct_fields; FIELDS; end 218 | 219 | def validate 220 | end 221 | 222 | ::Thrift::Struct.generate_accessors self 223 | end 224 | 225 | class ResetCatalog_result 226 | include ::Thrift::Struct, ::Thrift::Struct_Union 227 | SUCCESS = 0 228 | 229 | FIELDS = { 230 | SUCCESS => {:type => ::Thrift::Types::STRUCT, :name => 'success', :class => ::Impala::Protocol::TStatus} 231 | } 232 | 233 | def struct_fields; FIELDS; end 234 | 235 | def validate 236 | end 237 | 238 | ::Thrift::Struct.generate_accessors self 239 | end 240 | 241 | class ResetTable_args 242 | include ::Thrift::Struct, ::Thrift::Struct_Union 243 | REQUEST = 1 244 | 245 | FIELDS = { 246 | REQUEST => {:type => ::Thrift::Types::STRUCT, :name => 'request', :class => ::Impala::Protocol::TResetTableReq} 247 | } 248 | 249 | def struct_fields; FIELDS; end 250 | 251 | def validate 252 | end 253 | 254 | ::Thrift::Struct.generate_accessors self 255 | end 256 | 257 | class ResetTable_result 258 | include ::Thrift::Struct, ::Thrift::Struct_Union 259 | SUCCESS = 0 260 | 261 | FIELDS = { 262 | SUCCESS => {:type => ::Thrift::Types::STRUCT, :name => 'success', :class => ::Impala::Protocol::TStatus} 263 | } 264 | 265 | def struct_fields; FIELDS; end 266 | 267 | def validate 268 | end 269 | 270 | ::Thrift::Struct.generate_accessors self 271 | end 272 | 273 | class GetRuntimeProfile_args 274 | include ::Thrift::Struct, ::Thrift::Struct_Union 275 | QUERY_ID = 1 276 | 277 | FIELDS = { 278 | QUERY_ID => {:type => ::Thrift::Types::STRUCT, :name => 'query_id', :class => ::Impala::Protocol::Beeswax::QueryHandle} 279 | } 280 | 281 | def struct_fields; FIELDS; end 282 | 283 | def validate 284 | end 285 | 286 | ::Thrift::Struct.generate_accessors self 287 | end 288 | 289 | class GetRuntimeProfile_result 290 | include ::Thrift::Struct, ::Thrift::Struct_Union 291 | SUCCESS = 0 292 | ERROR = 1 293 | 294 | FIELDS = { 295 | SUCCESS => {:type => ::Thrift::Types::STRING, :name => 'success'}, 296 | ERROR => {:type => ::Thrift::Types::STRUCT, :name => 'error', :class => ::Impala::Protocol::Beeswax::BeeswaxException} 297 | } 298 | 299 | def struct_fields; FIELDS; end 300 | 301 | def validate 302 | end 303 | 304 | ::Thrift::Struct.generate_accessors self 305 | end 306 | 307 | class CloseInsert_args 308 | include ::Thrift::Struct, ::Thrift::Struct_Union 309 | HANDLE = 1 310 | 311 | FIELDS = { 312 | HANDLE => {:type => ::Thrift::Types::STRUCT, :name => 'handle', :class => ::Impala::Protocol::Beeswax::QueryHandle} 313 | } 314 | 315 | def struct_fields; FIELDS; end 316 | 317 | def validate 318 | end 319 | 320 | ::Thrift::Struct.generate_accessors self 321 | end 322 | 323 | class CloseInsert_result 324 | include ::Thrift::Struct, ::Thrift::Struct_Union 325 | SUCCESS = 0 326 | ERROR = 1 327 | ERROR2 = 2 328 | 329 | FIELDS = { 330 | SUCCESS => {:type => ::Thrift::Types::STRUCT, :name => 'success', :class => ::Impala::Protocol::TInsertResult}, 331 | ERROR => {:type => ::Thrift::Types::STRUCT, :name => 'error', :class => ::Impala::Protocol::Beeswax::QueryNotFoundException}, 332 | ERROR2 => {:type => ::Thrift::Types::STRUCT, :name => 'error2', :class => ::Impala::Protocol::Beeswax::BeeswaxException} 333 | } 334 | 335 | def struct_fields; FIELDS; end 336 | 337 | def validate 338 | end 339 | 340 | ::Thrift::Struct.generate_accessors self 341 | end 342 | 343 | class PingImpalaService_args 344 | include ::Thrift::Struct, ::Thrift::Struct_Union 345 | 346 | FIELDS = { 347 | 348 | } 349 | 350 | def struct_fields; FIELDS; end 351 | 352 | def validate 353 | end 354 | 355 | ::Thrift::Struct.generate_accessors self 356 | end 357 | 358 | class PingImpalaService_result 359 | include ::Thrift::Struct, ::Thrift::Struct_Union 360 | SUCCESS = 0 361 | 362 | FIELDS = { 363 | SUCCESS => {:type => ::Thrift::Types::STRUCT, :name => 'success', :class => ::Impala::Protocol::TPingImpalaServiceResp} 364 | } 365 | 366 | def struct_fields; FIELDS; end 367 | 368 | def validate 369 | end 370 | 371 | ::Thrift::Struct.generate_accessors self 372 | end 373 | 374 | end 375 | 376 | end 377 | end 378 | -------------------------------------------------------------------------------- /lib/impala/protocol/facebook_service.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Autogenerated by Thrift Compiler (0.9.1) 3 | # 4 | # DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 5 | # 6 | 7 | require 'thrift' 8 | require 'fb303_types' 9 | 10 | module Impala 11 | module Protocol 12 | module Fb303 13 | module FacebookService 14 | class Client 15 | include ::Thrift::Client 16 | 17 | def getName() 18 | send_getName() 19 | return recv_getName() 20 | end 21 | 22 | def send_getName() 23 | send_message('getName', GetName_args) 24 | end 25 | 26 | def recv_getName() 27 | result = receive_message(GetName_result) 28 | return result.success unless result.success.nil? 29 | raise ::Thrift::ApplicationException.new(::Thrift::ApplicationException::MISSING_RESULT, 'getName failed: unknown result') 30 | end 31 | 32 | def getVersion() 33 | send_getVersion() 34 | return recv_getVersion() 35 | end 36 | 37 | def send_getVersion() 38 | send_message('getVersion', GetVersion_args) 39 | end 40 | 41 | def recv_getVersion() 42 | result = receive_message(GetVersion_result) 43 | return result.success unless result.success.nil? 44 | raise ::Thrift::ApplicationException.new(::Thrift::ApplicationException::MISSING_RESULT, 'getVersion failed: unknown result') 45 | end 46 | 47 | def getStatus() 48 | send_getStatus() 49 | return recv_getStatus() 50 | end 51 | 52 | def send_getStatus() 53 | send_message('getStatus', GetStatus_args) 54 | end 55 | 56 | def recv_getStatus() 57 | result = receive_message(GetStatus_result) 58 | return result.success unless result.success.nil? 59 | raise ::Thrift::ApplicationException.new(::Thrift::ApplicationException::MISSING_RESULT, 'getStatus failed: unknown result') 60 | end 61 | 62 | def getStatusDetails() 63 | send_getStatusDetails() 64 | return recv_getStatusDetails() 65 | end 66 | 67 | def send_getStatusDetails() 68 | send_message('getStatusDetails', GetStatusDetails_args) 69 | end 70 | 71 | def recv_getStatusDetails() 72 | result = receive_message(GetStatusDetails_result) 73 | return result.success unless result.success.nil? 74 | raise ::Thrift::ApplicationException.new(::Thrift::ApplicationException::MISSING_RESULT, 'getStatusDetails failed: unknown result') 75 | end 76 | 77 | def getCounters() 78 | send_getCounters() 79 | return recv_getCounters() 80 | end 81 | 82 | def send_getCounters() 83 | send_message('getCounters', GetCounters_args) 84 | end 85 | 86 | def recv_getCounters() 87 | result = receive_message(GetCounters_result) 88 | return result.success unless result.success.nil? 89 | raise ::Thrift::ApplicationException.new(::Thrift::ApplicationException::MISSING_RESULT, 'getCounters failed: unknown result') 90 | end 91 | 92 | def getCounter(key) 93 | send_getCounter(key) 94 | return recv_getCounter() 95 | end 96 | 97 | def send_getCounter(key) 98 | send_message('getCounter', GetCounter_args, :key => key) 99 | end 100 | 101 | def recv_getCounter() 102 | result = receive_message(GetCounter_result) 103 | return result.success unless result.success.nil? 104 | raise ::Thrift::ApplicationException.new(::Thrift::ApplicationException::MISSING_RESULT, 'getCounter failed: unknown result') 105 | end 106 | 107 | def setOption(key, value) 108 | send_setOption(key, value) 109 | recv_setOption() 110 | end 111 | 112 | def send_setOption(key, value) 113 | send_message('setOption', SetOption_args, :key => key, :value => value) 114 | end 115 | 116 | def recv_setOption() 117 | result = receive_message(SetOption_result) 118 | return 119 | end 120 | 121 | def getOption(key) 122 | send_getOption(key) 123 | return recv_getOption() 124 | end 125 | 126 | def send_getOption(key) 127 | send_message('getOption', GetOption_args, :key => key) 128 | end 129 | 130 | def recv_getOption() 131 | result = receive_message(GetOption_result) 132 | return result.success unless result.success.nil? 133 | raise ::Thrift::ApplicationException.new(::Thrift::ApplicationException::MISSING_RESULT, 'getOption failed: unknown result') 134 | end 135 | 136 | def getOptions() 137 | send_getOptions() 138 | return recv_getOptions() 139 | end 140 | 141 | def send_getOptions() 142 | send_message('getOptions', GetOptions_args) 143 | end 144 | 145 | def recv_getOptions() 146 | result = receive_message(GetOptions_result) 147 | return result.success unless result.success.nil? 148 | raise ::Thrift::ApplicationException.new(::Thrift::ApplicationException::MISSING_RESULT, 'getOptions failed: unknown result') 149 | end 150 | 151 | def getCpuProfile(profileDurationInSec) 152 | send_getCpuProfile(profileDurationInSec) 153 | return recv_getCpuProfile() 154 | end 155 | 156 | def send_getCpuProfile(profileDurationInSec) 157 | send_message('getCpuProfile', GetCpuProfile_args, :profileDurationInSec => profileDurationInSec) 158 | end 159 | 160 | def recv_getCpuProfile() 161 | result = receive_message(GetCpuProfile_result) 162 | return result.success unless result.success.nil? 163 | raise ::Thrift::ApplicationException.new(::Thrift::ApplicationException::MISSING_RESULT, 'getCpuProfile failed: unknown result') 164 | end 165 | 166 | def aliveSince() 167 | send_aliveSince() 168 | return recv_aliveSince() 169 | end 170 | 171 | def send_aliveSince() 172 | send_message('aliveSince', AliveSince_args) 173 | end 174 | 175 | def recv_aliveSince() 176 | result = receive_message(AliveSince_result) 177 | return result.success unless result.success.nil? 178 | raise ::Thrift::ApplicationException.new(::Thrift::ApplicationException::MISSING_RESULT, 'aliveSince failed: unknown result') 179 | end 180 | 181 | def reinitialize() 182 | send_reinitialize() 183 | end 184 | 185 | def send_reinitialize() 186 | send_message('reinitialize', Reinitialize_args) 187 | end 188 | def shutdown() 189 | send_shutdown() 190 | end 191 | 192 | def send_shutdown() 193 | send_message('shutdown', Shutdown_args) 194 | end 195 | end 196 | 197 | class Processor 198 | include ::Thrift::Processor 199 | 200 | def process_getName(seqid, iprot, oprot) 201 | args = read_args(iprot, GetName_args) 202 | result = GetName_result.new() 203 | result.success = @handler.getName() 204 | write_result(result, oprot, 'getName', seqid) 205 | end 206 | 207 | def process_getVersion(seqid, iprot, oprot) 208 | args = read_args(iprot, GetVersion_args) 209 | result = GetVersion_result.new() 210 | result.success = @handler.getVersion() 211 | write_result(result, oprot, 'getVersion', seqid) 212 | end 213 | 214 | def process_getStatus(seqid, iprot, oprot) 215 | args = read_args(iprot, GetStatus_args) 216 | result = GetStatus_result.new() 217 | result.success = @handler.getStatus() 218 | write_result(result, oprot, 'getStatus', seqid) 219 | end 220 | 221 | def process_getStatusDetails(seqid, iprot, oprot) 222 | args = read_args(iprot, GetStatusDetails_args) 223 | result = GetStatusDetails_result.new() 224 | result.success = @handler.getStatusDetails() 225 | write_result(result, oprot, 'getStatusDetails', seqid) 226 | end 227 | 228 | def process_getCounters(seqid, iprot, oprot) 229 | args = read_args(iprot, GetCounters_args) 230 | result = GetCounters_result.new() 231 | result.success = @handler.getCounters() 232 | write_result(result, oprot, 'getCounters', seqid) 233 | end 234 | 235 | def process_getCounter(seqid, iprot, oprot) 236 | args = read_args(iprot, GetCounter_args) 237 | result = GetCounter_result.new() 238 | result.success = @handler.getCounter(args.key) 239 | write_result(result, oprot, 'getCounter', seqid) 240 | end 241 | 242 | def process_setOption(seqid, iprot, oprot) 243 | args = read_args(iprot, SetOption_args) 244 | result = SetOption_result.new() 245 | @handler.setOption(args.key, args.value) 246 | write_result(result, oprot, 'setOption', seqid) 247 | end 248 | 249 | def process_getOption(seqid, iprot, oprot) 250 | args = read_args(iprot, GetOption_args) 251 | result = GetOption_result.new() 252 | result.success = @handler.getOption(args.key) 253 | write_result(result, oprot, 'getOption', seqid) 254 | end 255 | 256 | def process_getOptions(seqid, iprot, oprot) 257 | args = read_args(iprot, GetOptions_args) 258 | result = GetOptions_result.new() 259 | result.success = @handler.getOptions() 260 | write_result(result, oprot, 'getOptions', seqid) 261 | end 262 | 263 | def process_getCpuProfile(seqid, iprot, oprot) 264 | args = read_args(iprot, GetCpuProfile_args) 265 | result = GetCpuProfile_result.new() 266 | result.success = @handler.getCpuProfile(args.profileDurationInSec) 267 | write_result(result, oprot, 'getCpuProfile', seqid) 268 | end 269 | 270 | def process_aliveSince(seqid, iprot, oprot) 271 | args = read_args(iprot, AliveSince_args) 272 | result = AliveSince_result.new() 273 | result.success = @handler.aliveSince() 274 | write_result(result, oprot, 'aliveSince', seqid) 275 | end 276 | 277 | def process_reinitialize(seqid, iprot, oprot) 278 | args = read_args(iprot, Reinitialize_args) 279 | @handler.reinitialize() 280 | return 281 | end 282 | 283 | def process_shutdown(seqid, iprot, oprot) 284 | args = read_args(iprot, Shutdown_args) 285 | @handler.shutdown() 286 | return 287 | end 288 | 289 | end 290 | 291 | # HELPER FUNCTIONS AND STRUCTURES 292 | 293 | class GetName_args 294 | include ::Thrift::Struct, ::Thrift::Struct_Union 295 | 296 | FIELDS = { 297 | 298 | } 299 | 300 | def struct_fields; FIELDS; end 301 | 302 | def validate 303 | end 304 | 305 | ::Thrift::Struct.generate_accessors self 306 | end 307 | 308 | class GetName_result 309 | include ::Thrift::Struct, ::Thrift::Struct_Union 310 | SUCCESS = 0 311 | 312 | FIELDS = { 313 | SUCCESS => {:type => ::Thrift::Types::STRING, :name => 'success'} 314 | } 315 | 316 | def struct_fields; FIELDS; end 317 | 318 | def validate 319 | end 320 | 321 | ::Thrift::Struct.generate_accessors self 322 | end 323 | 324 | class GetVersion_args 325 | include ::Thrift::Struct, ::Thrift::Struct_Union 326 | 327 | FIELDS = { 328 | 329 | } 330 | 331 | def struct_fields; FIELDS; end 332 | 333 | def validate 334 | end 335 | 336 | ::Thrift::Struct.generate_accessors self 337 | end 338 | 339 | class GetVersion_result 340 | include ::Thrift::Struct, ::Thrift::Struct_Union 341 | SUCCESS = 0 342 | 343 | FIELDS = { 344 | SUCCESS => {:type => ::Thrift::Types::STRING, :name => 'success'} 345 | } 346 | 347 | def struct_fields; FIELDS; end 348 | 349 | def validate 350 | end 351 | 352 | ::Thrift::Struct.generate_accessors self 353 | end 354 | 355 | class GetStatus_args 356 | include ::Thrift::Struct, ::Thrift::Struct_Union 357 | 358 | FIELDS = { 359 | 360 | } 361 | 362 | def struct_fields; FIELDS; end 363 | 364 | def validate 365 | end 366 | 367 | ::Thrift::Struct.generate_accessors self 368 | end 369 | 370 | class GetStatus_result 371 | include ::Thrift::Struct, ::Thrift::Struct_Union 372 | SUCCESS = 0 373 | 374 | FIELDS = { 375 | SUCCESS => {:type => ::Thrift::Types::I32, :name => 'success', :enum_class => ::Impala::Protocol::Fb303::Fb_status} 376 | } 377 | 378 | def struct_fields; FIELDS; end 379 | 380 | def validate 381 | unless @success.nil? || ::Impala::Protocol::Fb303::Fb_status::VALID_VALUES.include?(@success) 382 | raise ::Thrift::ProtocolException.new(::Thrift::ProtocolException::UNKNOWN, 'Invalid value of field success!') 383 | end 384 | end 385 | 386 | ::Thrift::Struct.generate_accessors self 387 | end 388 | 389 | class GetStatusDetails_args 390 | include ::Thrift::Struct, ::Thrift::Struct_Union 391 | 392 | FIELDS = { 393 | 394 | } 395 | 396 | def struct_fields; FIELDS; end 397 | 398 | def validate 399 | end 400 | 401 | ::Thrift::Struct.generate_accessors self 402 | end 403 | 404 | class GetStatusDetails_result 405 | include ::Thrift::Struct, ::Thrift::Struct_Union 406 | SUCCESS = 0 407 | 408 | FIELDS = { 409 | SUCCESS => {:type => ::Thrift::Types::STRING, :name => 'success'} 410 | } 411 | 412 | def struct_fields; FIELDS; end 413 | 414 | def validate 415 | end 416 | 417 | ::Thrift::Struct.generate_accessors self 418 | end 419 | 420 | class GetCounters_args 421 | include ::Thrift::Struct, ::Thrift::Struct_Union 422 | 423 | FIELDS = { 424 | 425 | } 426 | 427 | def struct_fields; FIELDS; end 428 | 429 | def validate 430 | end 431 | 432 | ::Thrift::Struct.generate_accessors self 433 | end 434 | 435 | class GetCounters_result 436 | include ::Thrift::Struct, ::Thrift::Struct_Union 437 | SUCCESS = 0 438 | 439 | FIELDS = { 440 | SUCCESS => {:type => ::Thrift::Types::MAP, :name => 'success', :key => {:type => ::Thrift::Types::STRING}, :value => {:type => ::Thrift::Types::I64}} 441 | } 442 | 443 | def struct_fields; FIELDS; end 444 | 445 | def validate 446 | end 447 | 448 | ::Thrift::Struct.generate_accessors self 449 | end 450 | 451 | class GetCounter_args 452 | include ::Thrift::Struct, ::Thrift::Struct_Union 453 | KEY = 1 454 | 455 | FIELDS = { 456 | KEY => {:type => ::Thrift::Types::STRING, :name => 'key'} 457 | } 458 | 459 | def struct_fields; FIELDS; end 460 | 461 | def validate 462 | end 463 | 464 | ::Thrift::Struct.generate_accessors self 465 | end 466 | 467 | class GetCounter_result 468 | include ::Thrift::Struct, ::Thrift::Struct_Union 469 | SUCCESS = 0 470 | 471 | FIELDS = { 472 | SUCCESS => {:type => ::Thrift::Types::I64, :name => 'success'} 473 | } 474 | 475 | def struct_fields; FIELDS; end 476 | 477 | def validate 478 | end 479 | 480 | ::Thrift::Struct.generate_accessors self 481 | end 482 | 483 | class SetOption_args 484 | include ::Thrift::Struct, ::Thrift::Struct_Union 485 | KEY = 1 486 | VALUE = 2 487 | 488 | FIELDS = { 489 | KEY => {:type => ::Thrift::Types::STRING, :name => 'key'}, 490 | VALUE => {:type => ::Thrift::Types::STRING, :name => 'value'} 491 | } 492 | 493 | def struct_fields; FIELDS; end 494 | 495 | def validate 496 | end 497 | 498 | ::Thrift::Struct.generate_accessors self 499 | end 500 | 501 | class SetOption_result 502 | include ::Thrift::Struct, ::Thrift::Struct_Union 503 | 504 | FIELDS = { 505 | 506 | } 507 | 508 | def struct_fields; FIELDS; end 509 | 510 | def validate 511 | end 512 | 513 | ::Thrift::Struct.generate_accessors self 514 | end 515 | 516 | class GetOption_args 517 | include ::Thrift::Struct, ::Thrift::Struct_Union 518 | KEY = 1 519 | 520 | FIELDS = { 521 | KEY => {:type => ::Thrift::Types::STRING, :name => 'key'} 522 | } 523 | 524 | def struct_fields; FIELDS; end 525 | 526 | def validate 527 | end 528 | 529 | ::Thrift::Struct.generate_accessors self 530 | end 531 | 532 | class GetOption_result 533 | include ::Thrift::Struct, ::Thrift::Struct_Union 534 | SUCCESS = 0 535 | 536 | FIELDS = { 537 | SUCCESS => {:type => ::Thrift::Types::STRING, :name => 'success'} 538 | } 539 | 540 | def struct_fields; FIELDS; end 541 | 542 | def validate 543 | end 544 | 545 | ::Thrift::Struct.generate_accessors self 546 | end 547 | 548 | class GetOptions_args 549 | include ::Thrift::Struct, ::Thrift::Struct_Union 550 | 551 | FIELDS = { 552 | 553 | } 554 | 555 | def struct_fields; FIELDS; end 556 | 557 | def validate 558 | end 559 | 560 | ::Thrift::Struct.generate_accessors self 561 | end 562 | 563 | class GetOptions_result 564 | include ::Thrift::Struct, ::Thrift::Struct_Union 565 | SUCCESS = 0 566 | 567 | FIELDS = { 568 | SUCCESS => {:type => ::Thrift::Types::MAP, :name => 'success', :key => {:type => ::Thrift::Types::STRING}, :value => {:type => ::Thrift::Types::STRING}} 569 | } 570 | 571 | def struct_fields; FIELDS; end 572 | 573 | def validate 574 | end 575 | 576 | ::Thrift::Struct.generate_accessors self 577 | end 578 | 579 | class GetCpuProfile_args 580 | include ::Thrift::Struct, ::Thrift::Struct_Union 581 | PROFILEDURATIONINSEC = 1 582 | 583 | FIELDS = { 584 | PROFILEDURATIONINSEC => {:type => ::Thrift::Types::I32, :name => 'profileDurationInSec'} 585 | } 586 | 587 | def struct_fields; FIELDS; end 588 | 589 | def validate 590 | end 591 | 592 | ::Thrift::Struct.generate_accessors self 593 | end 594 | 595 | class GetCpuProfile_result 596 | include ::Thrift::Struct, ::Thrift::Struct_Union 597 | SUCCESS = 0 598 | 599 | FIELDS = { 600 | SUCCESS => {:type => ::Thrift::Types::STRING, :name => 'success'} 601 | } 602 | 603 | def struct_fields; FIELDS; end 604 | 605 | def validate 606 | end 607 | 608 | ::Thrift::Struct.generate_accessors self 609 | end 610 | 611 | class AliveSince_args 612 | include ::Thrift::Struct, ::Thrift::Struct_Union 613 | 614 | FIELDS = { 615 | 616 | } 617 | 618 | def struct_fields; FIELDS; end 619 | 620 | def validate 621 | end 622 | 623 | ::Thrift::Struct.generate_accessors self 624 | end 625 | 626 | class AliveSince_result 627 | include ::Thrift::Struct, ::Thrift::Struct_Union 628 | SUCCESS = 0 629 | 630 | FIELDS = { 631 | SUCCESS => {:type => ::Thrift::Types::I64, :name => 'success'} 632 | } 633 | 634 | def struct_fields; FIELDS; end 635 | 636 | def validate 637 | end 638 | 639 | ::Thrift::Struct.generate_accessors self 640 | end 641 | 642 | class Reinitialize_args 643 | include ::Thrift::Struct, ::Thrift::Struct_Union 644 | 645 | FIELDS = { 646 | 647 | } 648 | 649 | def struct_fields; FIELDS; end 650 | 651 | def validate 652 | end 653 | 654 | ::Thrift::Struct.generate_accessors self 655 | end 656 | 657 | class Reinitialize_result 658 | include ::Thrift::Struct, ::Thrift::Struct_Union 659 | 660 | FIELDS = { 661 | 662 | } 663 | 664 | def struct_fields; FIELDS; end 665 | 666 | def validate 667 | end 668 | 669 | ::Thrift::Struct.generate_accessors self 670 | end 671 | 672 | class Shutdown_args 673 | include ::Thrift::Struct, ::Thrift::Struct_Union 674 | 675 | FIELDS = { 676 | 677 | } 678 | 679 | def struct_fields; FIELDS; end 680 | 681 | def validate 682 | end 683 | 684 | ::Thrift::Struct.generate_accessors self 685 | end 686 | 687 | class Shutdown_result 688 | include ::Thrift::Struct, ::Thrift::Struct_Union 689 | 690 | FIELDS = { 691 | 692 | } 693 | 694 | def struct_fields; FIELDS; end 695 | 696 | def validate 697 | end 698 | 699 | ::Thrift::Struct.generate_accessors self 700 | end 701 | 702 | end 703 | 704 | end 705 | end 706 | end 707 | -------------------------------------------------------------------------------- /lib/impala/protocol/hive_metastore_types.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Autogenerated by Thrift Compiler (0.9.1) 3 | # 4 | # DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 5 | # 6 | 7 | require 'thrift' 8 | require 'fb303_types' 9 | 10 | 11 | module Impala 12 | module Protocol 13 | module HiveMetastore 14 | module HiveObjectType 15 | GLOBAL = 1 16 | DATABASE = 2 17 | TABLE = 3 18 | PARTITION = 4 19 | COLUMN = 5 20 | VALUE_MAP = {1 => "GLOBAL", 2 => "DATABASE", 3 => "TABLE", 4 => "PARTITION", 5 => "COLUMN"} 21 | VALID_VALUES = Set.new([GLOBAL, DATABASE, TABLE, PARTITION, COLUMN]).freeze 22 | end 23 | 24 | module PrincipalType 25 | USER = 1 26 | ROLE = 2 27 | GROUP = 3 28 | VALUE_MAP = {1 => "USER", 2 => "ROLE", 3 => "GROUP"} 29 | VALID_VALUES = Set.new([USER, ROLE, GROUP]).freeze 30 | end 31 | 32 | module PartitionEventType 33 | LOAD_DONE = 1 34 | VALUE_MAP = {1 => "LOAD_DONE"} 35 | VALID_VALUES = Set.new([LOAD_DONE]).freeze 36 | end 37 | 38 | class Version 39 | include ::Thrift::Struct, ::Thrift::Struct_Union 40 | VERSION = 1 41 | COMMENTS = 2 42 | 43 | FIELDS = { 44 | VERSION => {:type => ::Thrift::Types::STRING, :name => 'version'}, 45 | COMMENTS => {:type => ::Thrift::Types::STRING, :name => 'comments'} 46 | } 47 | 48 | def struct_fields; FIELDS; end 49 | 50 | def validate 51 | end 52 | 53 | ::Thrift::Struct.generate_accessors self 54 | end 55 | 56 | class FieldSchema 57 | include ::Thrift::Struct, ::Thrift::Struct_Union 58 | NAME = 1 59 | TYPE = 2 60 | COMMENT = 3 61 | 62 | FIELDS = { 63 | NAME => {:type => ::Thrift::Types::STRING, :name => 'name'}, 64 | TYPE => {:type => ::Thrift::Types::STRING, :name => 'type'}, 65 | COMMENT => {:type => ::Thrift::Types::STRING, :name => 'comment'} 66 | } 67 | 68 | def struct_fields; FIELDS; end 69 | 70 | def validate 71 | end 72 | 73 | ::Thrift::Struct.generate_accessors self 74 | end 75 | 76 | class Type 77 | include ::Thrift::Struct, ::Thrift::Struct_Union 78 | NAME = 1 79 | TYPE1 = 2 80 | TYPE2 = 3 81 | 82 | FIELDS = { 83 | NAME => {:type => ::Thrift::Types::STRING, :name => 'name'}, 84 | TYPE1 => {:type => ::Thrift::Types::STRING, :name => 'type1', :optional => true}, 85 | TYPE2 => {:type => ::Thrift::Types::STRING, :name => 'type2', :optional => true} 86 | } 87 | 88 | def struct_fields; FIELDS; end 89 | 90 | def validate 91 | end 92 | 93 | ::Thrift::Struct.generate_accessors self 94 | end 95 | 96 | class HiveObjectRef 97 | include ::Thrift::Struct, ::Thrift::Struct_Union 98 | OBJECTTYPE = 1 99 | DBNAME = 2 100 | OBJECTNAME = 3 101 | PARTVALUES = 4 102 | COLUMNNAME = 5 103 | 104 | FIELDS = { 105 | OBJECTTYPE => {:type => ::Thrift::Types::I32, :name => 'objectType', :enum_class => ::Impala::Protocol::HiveMetastore::HiveObjectType}, 106 | DBNAME => {:type => ::Thrift::Types::STRING, :name => 'dbName'}, 107 | OBJECTNAME => {:type => ::Thrift::Types::STRING, :name => 'objectName'}, 108 | PARTVALUES => {:type => ::Thrift::Types::LIST, :name => 'partValues', :element => {:type => ::Thrift::Types::STRING}}, 109 | COLUMNNAME => {:type => ::Thrift::Types::STRING, :name => 'columnName'} 110 | } 111 | 112 | def struct_fields; FIELDS; end 113 | 114 | def validate 115 | unless @objectType.nil? || ::Impala::Protocol::HiveMetastore::HiveObjectType::VALID_VALUES.include?(@objectType) 116 | raise ::Thrift::ProtocolException.new(::Thrift::ProtocolException::UNKNOWN, 'Invalid value of field objectType!') 117 | end 118 | end 119 | 120 | ::Thrift::Struct.generate_accessors self 121 | end 122 | 123 | class PrivilegeGrantInfo 124 | include ::Thrift::Struct, ::Thrift::Struct_Union 125 | PRIVILEGE = 1 126 | CREATETIME = 2 127 | GRANTOR = 3 128 | GRANTORTYPE = 4 129 | GRANTOPTION = 5 130 | 131 | FIELDS = { 132 | PRIVILEGE => {:type => ::Thrift::Types::STRING, :name => 'privilege'}, 133 | CREATETIME => {:type => ::Thrift::Types::I32, :name => 'createTime'}, 134 | GRANTOR => {:type => ::Thrift::Types::STRING, :name => 'grantor'}, 135 | GRANTORTYPE => {:type => ::Thrift::Types::I32, :name => 'grantorType', :enum_class => ::Impala::Protocol::HiveMetastore::PrincipalType}, 136 | GRANTOPTION => {:type => ::Thrift::Types::BOOL, :name => 'grantOption'} 137 | } 138 | 139 | def struct_fields; FIELDS; end 140 | 141 | def validate 142 | unless @grantorType.nil? || ::Impala::Protocol::HiveMetastore::PrincipalType::VALID_VALUES.include?(@grantorType) 143 | raise ::Thrift::ProtocolException.new(::Thrift::ProtocolException::UNKNOWN, 'Invalid value of field grantorType!') 144 | end 145 | end 146 | 147 | ::Thrift::Struct.generate_accessors self 148 | end 149 | 150 | class HiveObjectPrivilege 151 | include ::Thrift::Struct, ::Thrift::Struct_Union 152 | HIVEOBJECT = 1 153 | PRINCIPALNAME = 2 154 | PRINCIPALTYPE = 3 155 | GRANTINFO = 4 156 | 157 | FIELDS = { 158 | HIVEOBJECT => {:type => ::Thrift::Types::STRUCT, :name => 'hiveObject', :class => ::Impala::Protocol::HiveMetastore::HiveObjectRef}, 159 | PRINCIPALNAME => {:type => ::Thrift::Types::STRING, :name => 'principalName'}, 160 | PRINCIPALTYPE => {:type => ::Thrift::Types::I32, :name => 'principalType', :enum_class => ::Impala::Protocol::HiveMetastore::PrincipalType}, 161 | GRANTINFO => {:type => ::Thrift::Types::STRUCT, :name => 'grantInfo', :class => ::Impala::Protocol::HiveMetastore::PrivilegeGrantInfo} 162 | } 163 | 164 | def struct_fields; FIELDS; end 165 | 166 | def validate 167 | unless @principalType.nil? || ::Impala::Protocol::HiveMetastore::PrincipalType::VALID_VALUES.include?(@principalType) 168 | raise ::Thrift::ProtocolException.new(::Thrift::ProtocolException::UNKNOWN, 'Invalid value of field principalType!') 169 | end 170 | end 171 | 172 | ::Thrift::Struct.generate_accessors self 173 | end 174 | 175 | class PrivilegeBag 176 | include ::Thrift::Struct, ::Thrift::Struct_Union 177 | PRIVILEGES = 1 178 | 179 | FIELDS = { 180 | PRIVILEGES => {:type => ::Thrift::Types::LIST, :name => 'privileges', :element => {:type => ::Thrift::Types::STRUCT, :class => ::Impala::Protocol::HiveMetastore::HiveObjectPrivilege}} 181 | } 182 | 183 | def struct_fields; FIELDS; end 184 | 185 | def validate 186 | end 187 | 188 | ::Thrift::Struct.generate_accessors self 189 | end 190 | 191 | class PrincipalPrivilegeSet 192 | include ::Thrift::Struct, ::Thrift::Struct_Union 193 | USERPRIVILEGES = 1 194 | GROUPPRIVILEGES = 2 195 | ROLEPRIVILEGES = 3 196 | 197 | FIELDS = { 198 | USERPRIVILEGES => {:type => ::Thrift::Types::MAP, :name => 'userPrivileges', :key => {:type => ::Thrift::Types::STRING}, :value => {:type => ::Thrift::Types::LIST, :element => {:type => ::Thrift::Types::STRUCT, :class => ::Impala::Protocol::HiveMetastore::PrivilegeGrantInfo}}}, 199 | GROUPPRIVILEGES => {:type => ::Thrift::Types::MAP, :name => 'groupPrivileges', :key => {:type => ::Thrift::Types::STRING}, :value => {:type => ::Thrift::Types::LIST, :element => {:type => ::Thrift::Types::STRUCT, :class => ::Impala::Protocol::HiveMetastore::PrivilegeGrantInfo}}}, 200 | ROLEPRIVILEGES => {:type => ::Thrift::Types::MAP, :name => 'rolePrivileges', :key => {:type => ::Thrift::Types::STRING}, :value => {:type => ::Thrift::Types::LIST, :element => {:type => ::Thrift::Types::STRUCT, :class => ::Impala::Protocol::HiveMetastore::PrivilegeGrantInfo}}} 201 | } 202 | 203 | def struct_fields; FIELDS; end 204 | 205 | def validate 206 | end 207 | 208 | ::Thrift::Struct.generate_accessors self 209 | end 210 | 211 | class Role 212 | include ::Thrift::Struct, ::Thrift::Struct_Union 213 | ROLENAME = 1 214 | CREATETIME = 2 215 | OWNERNAME = 3 216 | 217 | FIELDS = { 218 | ROLENAME => {:type => ::Thrift::Types::STRING, :name => 'roleName'}, 219 | CREATETIME => {:type => ::Thrift::Types::I32, :name => 'createTime'}, 220 | OWNERNAME => {:type => ::Thrift::Types::STRING, :name => 'ownerName'} 221 | } 222 | 223 | def struct_fields; FIELDS; end 224 | 225 | def validate 226 | end 227 | 228 | ::Thrift::Struct.generate_accessors self 229 | end 230 | 231 | class Database 232 | include ::Thrift::Struct, ::Thrift::Struct_Union 233 | NAME = 1 234 | DESCRIPTION = 2 235 | LOCATIONURI = 3 236 | PARAMETERS = 4 237 | PRIVILEGES = 5 238 | 239 | FIELDS = { 240 | NAME => {:type => ::Thrift::Types::STRING, :name => 'name'}, 241 | DESCRIPTION => {:type => ::Thrift::Types::STRING, :name => 'description'}, 242 | LOCATIONURI => {:type => ::Thrift::Types::STRING, :name => 'locationUri'}, 243 | PARAMETERS => {:type => ::Thrift::Types::MAP, :name => 'parameters', :key => {:type => ::Thrift::Types::STRING}, :value => {:type => ::Thrift::Types::STRING}}, 244 | PRIVILEGES => {:type => ::Thrift::Types::STRUCT, :name => 'privileges', :class => ::Impala::Protocol::HiveMetastore::PrincipalPrivilegeSet, :optional => true} 245 | } 246 | 247 | def struct_fields; FIELDS; end 248 | 249 | def validate 250 | end 251 | 252 | ::Thrift::Struct.generate_accessors self 253 | end 254 | 255 | class SerDeInfo 256 | include ::Thrift::Struct, ::Thrift::Struct_Union 257 | NAME = 1 258 | SERIALIZATIONLIB = 2 259 | PARAMETERS = 3 260 | 261 | FIELDS = { 262 | NAME => {:type => ::Thrift::Types::STRING, :name => 'name'}, 263 | SERIALIZATIONLIB => {:type => ::Thrift::Types::STRING, :name => 'serializationLib'}, 264 | PARAMETERS => {:type => ::Thrift::Types::MAP, :name => 'parameters', :key => {:type => ::Thrift::Types::STRING}, :value => {:type => ::Thrift::Types::STRING}} 265 | } 266 | 267 | def struct_fields; FIELDS; end 268 | 269 | def validate 270 | end 271 | 272 | ::Thrift::Struct.generate_accessors self 273 | end 274 | 275 | class Order 276 | include ::Thrift::Struct, ::Thrift::Struct_Union 277 | COL = 1 278 | ORDER = 2 279 | 280 | FIELDS = { 281 | COL => {:type => ::Thrift::Types::STRING, :name => 'col'}, 282 | ORDER => {:type => ::Thrift::Types::I32, :name => 'order'} 283 | } 284 | 285 | def struct_fields; FIELDS; end 286 | 287 | def validate 288 | end 289 | 290 | ::Thrift::Struct.generate_accessors self 291 | end 292 | 293 | class StorageDescriptor 294 | include ::Thrift::Struct, ::Thrift::Struct_Union 295 | COLS = 1 296 | LOCATION = 2 297 | INPUTFORMAT = 3 298 | OUTPUTFORMAT = 4 299 | COMPRESSED = 5 300 | NUMBUCKETS = 6 301 | SERDEINFO = 7 302 | BUCKETCOLS = 8 303 | SORTCOLS = 9 304 | PARAMETERS = 10 305 | 306 | FIELDS = { 307 | COLS => {:type => ::Thrift::Types::LIST, :name => 'cols', :element => {:type => ::Thrift::Types::STRUCT, :class => ::Impala::Protocol::HiveMetastore::FieldSchema}}, 308 | LOCATION => {:type => ::Thrift::Types::STRING, :name => 'location'}, 309 | INPUTFORMAT => {:type => ::Thrift::Types::STRING, :name => 'inputFormat'}, 310 | OUTPUTFORMAT => {:type => ::Thrift::Types::STRING, :name => 'outputFormat'}, 311 | COMPRESSED => {:type => ::Thrift::Types::BOOL, :name => 'compressed'}, 312 | NUMBUCKETS => {:type => ::Thrift::Types::I32, :name => 'numBuckets'}, 313 | SERDEINFO => {:type => ::Thrift::Types::STRUCT, :name => 'serdeInfo', :class => ::Impala::Protocol::HiveMetastore::SerDeInfo}, 314 | BUCKETCOLS => {:type => ::Thrift::Types::LIST, :name => 'bucketCols', :element => {:type => ::Thrift::Types::STRING}}, 315 | SORTCOLS => {:type => ::Thrift::Types::LIST, :name => 'sortCols', :element => {:type => ::Thrift::Types::STRUCT, :class => ::Impala::Protocol::HiveMetastore::Order}}, 316 | PARAMETERS => {:type => ::Thrift::Types::MAP, :name => 'parameters', :key => {:type => ::Thrift::Types::STRING}, :value => {:type => ::Thrift::Types::STRING}} 317 | } 318 | 319 | def struct_fields; FIELDS; end 320 | 321 | def validate 322 | end 323 | 324 | ::Thrift::Struct.generate_accessors self 325 | end 326 | 327 | class Table 328 | include ::Thrift::Struct, ::Thrift::Struct_Union 329 | TABLENAME = 1 330 | DBNAME = 2 331 | OWNER = 3 332 | CREATETIME = 4 333 | LASTACCESSTIME = 5 334 | RETENTION = 6 335 | SD = 7 336 | PARTITIONKEYS = 8 337 | PARAMETERS = 9 338 | VIEWORIGINALTEXT = 10 339 | VIEWEXPANDEDTEXT = 11 340 | TABLETYPE = 12 341 | PRIVILEGES = 13 342 | 343 | FIELDS = { 344 | TABLENAME => {:type => ::Thrift::Types::STRING, :name => 'tableName'}, 345 | DBNAME => {:type => ::Thrift::Types::STRING, :name => 'dbName'}, 346 | OWNER => {:type => ::Thrift::Types::STRING, :name => 'owner'}, 347 | CREATETIME => {:type => ::Thrift::Types::I32, :name => 'createTime'}, 348 | LASTACCESSTIME => {:type => ::Thrift::Types::I32, :name => 'lastAccessTime'}, 349 | RETENTION => {:type => ::Thrift::Types::I32, :name => 'retention'}, 350 | SD => {:type => ::Thrift::Types::STRUCT, :name => 'sd', :class => ::Impala::Protocol::HiveMetastore::StorageDescriptor}, 351 | PARTITIONKEYS => {:type => ::Thrift::Types::LIST, :name => 'partitionKeys', :element => {:type => ::Thrift::Types::STRUCT, :class => ::Impala::Protocol::HiveMetastore::FieldSchema}}, 352 | PARAMETERS => {:type => ::Thrift::Types::MAP, :name => 'parameters', :key => {:type => ::Thrift::Types::STRING}, :value => {:type => ::Thrift::Types::STRING}}, 353 | VIEWORIGINALTEXT => {:type => ::Thrift::Types::STRING, :name => 'viewOriginalText'}, 354 | VIEWEXPANDEDTEXT => {:type => ::Thrift::Types::STRING, :name => 'viewExpandedText'}, 355 | TABLETYPE => {:type => ::Thrift::Types::STRING, :name => 'tableType'}, 356 | PRIVILEGES => {:type => ::Thrift::Types::STRUCT, :name => 'privileges', :class => ::Impala::Protocol::HiveMetastore::PrincipalPrivilegeSet, :optional => true} 357 | } 358 | 359 | def struct_fields; FIELDS; end 360 | 361 | def validate 362 | end 363 | 364 | ::Thrift::Struct.generate_accessors self 365 | end 366 | 367 | class Partition 368 | include ::Thrift::Struct, ::Thrift::Struct_Union 369 | VALUES = 1 370 | DBNAME = 2 371 | TABLENAME = 3 372 | CREATETIME = 4 373 | LASTACCESSTIME = 5 374 | SD = 6 375 | PARAMETERS = 7 376 | PRIVILEGES = 8 377 | 378 | FIELDS = { 379 | VALUES => {:type => ::Thrift::Types::LIST, :name => 'values', :element => {:type => ::Thrift::Types::STRING}}, 380 | DBNAME => {:type => ::Thrift::Types::STRING, :name => 'dbName'}, 381 | TABLENAME => {:type => ::Thrift::Types::STRING, :name => 'tableName'}, 382 | CREATETIME => {:type => ::Thrift::Types::I32, :name => 'createTime'}, 383 | LASTACCESSTIME => {:type => ::Thrift::Types::I32, :name => 'lastAccessTime'}, 384 | SD => {:type => ::Thrift::Types::STRUCT, :name => 'sd', :class => ::Impala::Protocol::HiveMetastore::StorageDescriptor}, 385 | PARAMETERS => {:type => ::Thrift::Types::MAP, :name => 'parameters', :key => {:type => ::Thrift::Types::STRING}, :value => {:type => ::Thrift::Types::STRING}}, 386 | PRIVILEGES => {:type => ::Thrift::Types::STRUCT, :name => 'privileges', :class => ::Impala::Protocol::HiveMetastore::PrincipalPrivilegeSet, :optional => true} 387 | } 388 | 389 | def struct_fields; FIELDS; end 390 | 391 | def validate 392 | end 393 | 394 | ::Thrift::Struct.generate_accessors self 395 | end 396 | 397 | class Index 398 | include ::Thrift::Struct, ::Thrift::Struct_Union 399 | INDEXNAME = 1 400 | INDEXHANDLERCLASS = 2 401 | DBNAME = 3 402 | ORIGTABLENAME = 4 403 | CREATETIME = 5 404 | LASTACCESSTIME = 6 405 | INDEXTABLENAME = 7 406 | SD = 8 407 | PARAMETERS = 9 408 | DEFERREDREBUILD = 10 409 | 410 | FIELDS = { 411 | INDEXNAME => {:type => ::Thrift::Types::STRING, :name => 'indexName'}, 412 | INDEXHANDLERCLASS => {:type => ::Thrift::Types::STRING, :name => 'indexHandlerClass'}, 413 | DBNAME => {:type => ::Thrift::Types::STRING, :name => 'dbName'}, 414 | ORIGTABLENAME => {:type => ::Thrift::Types::STRING, :name => 'origTableName'}, 415 | CREATETIME => {:type => ::Thrift::Types::I32, :name => 'createTime'}, 416 | LASTACCESSTIME => {:type => ::Thrift::Types::I32, :name => 'lastAccessTime'}, 417 | INDEXTABLENAME => {:type => ::Thrift::Types::STRING, :name => 'indexTableName'}, 418 | SD => {:type => ::Thrift::Types::STRUCT, :name => 'sd', :class => ::Impala::Protocol::HiveMetastore::StorageDescriptor}, 419 | PARAMETERS => {:type => ::Thrift::Types::MAP, :name => 'parameters', :key => {:type => ::Thrift::Types::STRING}, :value => {:type => ::Thrift::Types::STRING}}, 420 | DEFERREDREBUILD => {:type => ::Thrift::Types::BOOL, :name => 'deferredRebuild'} 421 | } 422 | 423 | def struct_fields; FIELDS; end 424 | 425 | def validate 426 | end 427 | 428 | ::Thrift::Struct.generate_accessors self 429 | end 430 | 431 | class Schema 432 | include ::Thrift::Struct, ::Thrift::Struct_Union 433 | FIELDSCHEMAS = 1 434 | PROPERTIES = 2 435 | 436 | FIELDS = { 437 | FIELDSCHEMAS => {:type => ::Thrift::Types::LIST, :name => 'fieldSchemas', :element => {:type => ::Thrift::Types::STRUCT, :class => ::Impala::Protocol::HiveMetastore::FieldSchema}}, 438 | PROPERTIES => {:type => ::Thrift::Types::MAP, :name => 'properties', :key => {:type => ::Thrift::Types::STRING}, :value => {:type => ::Thrift::Types::STRING}} 439 | } 440 | 441 | def struct_fields; FIELDS; end 442 | 443 | def validate 444 | end 445 | 446 | ::Thrift::Struct.generate_accessors self 447 | end 448 | 449 | class EnvironmentContext 450 | include ::Thrift::Struct, ::Thrift::Struct_Union 451 | PROPERTIES = 1 452 | 453 | FIELDS = { 454 | PROPERTIES => {:type => ::Thrift::Types::MAP, :name => 'properties', :key => {:type => ::Thrift::Types::STRING}, :value => {:type => ::Thrift::Types::STRING}} 455 | } 456 | 457 | def struct_fields; FIELDS; end 458 | 459 | def validate 460 | end 461 | 462 | ::Thrift::Struct.generate_accessors self 463 | end 464 | 465 | class MetaException < ::Thrift::Exception 466 | include ::Thrift::Struct, ::Thrift::Struct_Union 467 | def initialize(message=nil) 468 | super() 469 | self.message = message 470 | end 471 | 472 | MESSAGE = 1 473 | 474 | FIELDS = { 475 | MESSAGE => {:type => ::Thrift::Types::STRING, :name => 'message'} 476 | } 477 | 478 | def struct_fields; FIELDS; end 479 | 480 | def validate 481 | end 482 | 483 | ::Thrift::Struct.generate_accessors self 484 | end 485 | 486 | class UnknownTableException < ::Thrift::Exception 487 | include ::Thrift::Struct, ::Thrift::Struct_Union 488 | def initialize(message=nil) 489 | super() 490 | self.message = message 491 | end 492 | 493 | MESSAGE = 1 494 | 495 | FIELDS = { 496 | MESSAGE => {:type => ::Thrift::Types::STRING, :name => 'message'} 497 | } 498 | 499 | def struct_fields; FIELDS; end 500 | 501 | def validate 502 | end 503 | 504 | ::Thrift::Struct.generate_accessors self 505 | end 506 | 507 | class UnknownDBException < ::Thrift::Exception 508 | include ::Thrift::Struct, ::Thrift::Struct_Union 509 | def initialize(message=nil) 510 | super() 511 | self.message = message 512 | end 513 | 514 | MESSAGE = 1 515 | 516 | FIELDS = { 517 | MESSAGE => {:type => ::Thrift::Types::STRING, :name => 'message'} 518 | } 519 | 520 | def struct_fields; FIELDS; end 521 | 522 | def validate 523 | end 524 | 525 | ::Thrift::Struct.generate_accessors self 526 | end 527 | 528 | class AlreadyExistsException < ::Thrift::Exception 529 | include ::Thrift::Struct, ::Thrift::Struct_Union 530 | def initialize(message=nil) 531 | super() 532 | self.message = message 533 | end 534 | 535 | MESSAGE = 1 536 | 537 | FIELDS = { 538 | MESSAGE => {:type => ::Thrift::Types::STRING, :name => 'message'} 539 | } 540 | 541 | def struct_fields; FIELDS; end 542 | 543 | def validate 544 | end 545 | 546 | ::Thrift::Struct.generate_accessors self 547 | end 548 | 549 | class InvalidPartitionException < ::Thrift::Exception 550 | include ::Thrift::Struct, ::Thrift::Struct_Union 551 | def initialize(message=nil) 552 | super() 553 | self.message = message 554 | end 555 | 556 | MESSAGE = 1 557 | 558 | FIELDS = { 559 | MESSAGE => {:type => ::Thrift::Types::STRING, :name => 'message'} 560 | } 561 | 562 | def struct_fields; FIELDS; end 563 | 564 | def validate 565 | end 566 | 567 | ::Thrift::Struct.generate_accessors self 568 | end 569 | 570 | class UnknownPartitionException < ::Thrift::Exception 571 | include ::Thrift::Struct, ::Thrift::Struct_Union 572 | def initialize(message=nil) 573 | super() 574 | self.message = message 575 | end 576 | 577 | MESSAGE = 1 578 | 579 | FIELDS = { 580 | MESSAGE => {:type => ::Thrift::Types::STRING, :name => 'message'} 581 | } 582 | 583 | def struct_fields; FIELDS; end 584 | 585 | def validate 586 | end 587 | 588 | ::Thrift::Struct.generate_accessors self 589 | end 590 | 591 | class InvalidObjectException < ::Thrift::Exception 592 | include ::Thrift::Struct, ::Thrift::Struct_Union 593 | def initialize(message=nil) 594 | super() 595 | self.message = message 596 | end 597 | 598 | MESSAGE = 1 599 | 600 | FIELDS = { 601 | MESSAGE => {:type => ::Thrift::Types::STRING, :name => 'message'} 602 | } 603 | 604 | def struct_fields; FIELDS; end 605 | 606 | def validate 607 | end 608 | 609 | ::Thrift::Struct.generate_accessors self 610 | end 611 | 612 | class NoSuchObjectException < ::Thrift::Exception 613 | include ::Thrift::Struct, ::Thrift::Struct_Union 614 | def initialize(message=nil) 615 | super() 616 | self.message = message 617 | end 618 | 619 | MESSAGE = 1 620 | 621 | FIELDS = { 622 | MESSAGE => {:type => ::Thrift::Types::STRING, :name => 'message'} 623 | } 624 | 625 | def struct_fields; FIELDS; end 626 | 627 | def validate 628 | end 629 | 630 | ::Thrift::Struct.generate_accessors self 631 | end 632 | 633 | class IndexAlreadyExistsException < ::Thrift::Exception 634 | include ::Thrift::Struct, ::Thrift::Struct_Union 635 | def initialize(message=nil) 636 | super() 637 | self.message = message 638 | end 639 | 640 | MESSAGE = 1 641 | 642 | FIELDS = { 643 | MESSAGE => {:type => ::Thrift::Types::STRING, :name => 'message'} 644 | } 645 | 646 | def struct_fields; FIELDS; end 647 | 648 | def validate 649 | end 650 | 651 | ::Thrift::Struct.generate_accessors self 652 | end 653 | 654 | class InvalidOperationException < ::Thrift::Exception 655 | include ::Thrift::Struct, ::Thrift::Struct_Union 656 | def initialize(message=nil) 657 | super() 658 | self.message = message 659 | end 660 | 661 | MESSAGE = 1 662 | 663 | FIELDS = { 664 | MESSAGE => {:type => ::Thrift::Types::STRING, :name => 'message'} 665 | } 666 | 667 | def struct_fields; FIELDS; end 668 | 669 | def validate 670 | end 671 | 672 | ::Thrift::Struct.generate_accessors self 673 | end 674 | 675 | class ConfigValSecurityException < ::Thrift::Exception 676 | include ::Thrift::Struct, ::Thrift::Struct_Union 677 | def initialize(message=nil) 678 | super() 679 | self.message = message 680 | end 681 | 682 | MESSAGE = 1 683 | 684 | FIELDS = { 685 | MESSAGE => {:type => ::Thrift::Types::STRING, :name => 'message'} 686 | } 687 | 688 | def struct_fields; FIELDS; end 689 | 690 | def validate 691 | end 692 | 693 | ::Thrift::Struct.generate_accessors self 694 | end 695 | 696 | end 697 | end 698 | end 699 | -------------------------------------------------------------------------------- /thrift/hive_metastore.thrift: -------------------------------------------------------------------------------- 1 | #!/usr/local/bin/thrift -java 2 | 3 | /** 4 | * Licensed to the Apache Software Foundation (ASF) under one 5 | * or more contributor license agreements. See the NOTICE file 6 | * distributed with this work for additional information 7 | * regarding copyright ownership. The ASF licenses this file 8 | * to you under the Apache License, Version 2.0 (the 9 | * "License"); you may not use this file except in compliance 10 | * with the License. You may obtain a copy of the License at 11 | * 12 | * http://www.apache.org/licenses/LICENSE-2.0 13 | * 14 | * Unless required by applicable law or agreed to in writing, software 15 | * distributed under the License is distributed on an "AS IS" BASIS, 16 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | * See the License for the specific language governing permissions and 18 | * limitations under the License. 19 | */ 20 | 21 | # 22 | # Thrift Service that the MetaStore is built on 23 | # 24 | 25 | include "fb303.thrift" 26 | 27 | namespace java org.apache.hadoop.hive.metastore.api 28 | namespace php metastore 29 | namespace cpp Apache.Hadoop.Hive 30 | namespace rb Impala.Protocol.HiveMetastore 31 | 32 | const string DDL_TIME = "transient_lastDdlTime" 33 | 34 | struct Version { 35 | 1: string version, 36 | 2: string comments 37 | } 38 | 39 | struct FieldSchema { 40 | 1: string name, // name of the field 41 | 2: string type, // type of the field. primitive types defined above, specify list, map for lists & maps 42 | 3: string comment 43 | } 44 | 45 | struct Type { 46 | 1: string name, // one of the types in PrimitiveTypes or CollectionTypes or User defined types 47 | 2: optional string type1, // object type if the name is 'list' (LIST_TYPE), key type if the name is 'map' (MAP_TYPE) 48 | 3: optional string type2, // val type if the name is 'map' (MAP_TYPE) 49 | //4: optional list fields // if the name is one of the user defined types 50 | } 51 | 52 | enum HiveObjectType { 53 | GLOBAL = 1, 54 | DATABASE = 2, 55 | TABLE = 3, 56 | PARTITION = 4, 57 | COLUMN = 5, 58 | } 59 | 60 | enum PrincipalType { 61 | USER = 1, 62 | ROLE = 2, 63 | GROUP = 3, 64 | } 65 | 66 | const string HIVE_FILTER_FIELD_OWNER = "hive_filter_field_owner__" 67 | const string HIVE_FILTER_FIELD_PARAMS = "hive_filter_field_params__" 68 | const string HIVE_FILTER_FIELD_LAST_ACCESS = "hive_filter_field_last_access__" 69 | 70 | enum PartitionEventType { 71 | LOAD_DONE = 1, 72 | } 73 | 74 | struct HiveObjectRef{ 75 | 1: HiveObjectType objectType, 76 | 2: string dbName, 77 | 3: string objectName, 78 | 4: list partValues, 79 | 5: string columnName, 80 | } 81 | 82 | struct PrivilegeGrantInfo { 83 | 1: string privilege, 84 | 2: i32 createTime, 85 | 3: string grantor, 86 | 4: PrincipalType grantorType, 87 | 5: bool grantOption, 88 | } 89 | 90 | struct HiveObjectPrivilege { 91 | 1: HiveObjectRef hiveObject, 92 | 2: string principalName, 93 | 3: PrincipalType principalType, 94 | 4: PrivilegeGrantInfo grantInfo, 95 | } 96 | 97 | struct PrivilegeBag { 98 | 1: list privileges, 99 | } 100 | 101 | struct PrincipalPrivilegeSet { 102 | 1: map> userPrivileges, // user name -> privilege grant info 103 | 2: map> groupPrivileges, // group name -> privilege grant info 104 | 3: map> rolePrivileges, //role name -> privilege grant info 105 | } 106 | 107 | struct Role { 108 | 1: string roleName, 109 | 2: i32 createTime, 110 | 3: string ownerName, 111 | } 112 | 113 | // namespace for tables 114 | struct Database { 115 | 1: string name, 116 | 2: string description, 117 | 3: string locationUri, 118 | 4: map parameters, // properties associated with the database 119 | 5: optional PrincipalPrivilegeSet privileges 120 | } 121 | 122 | // This object holds the information needed by SerDes 123 | struct SerDeInfo { 124 | 1: string name, // name of the serde, table name by default 125 | 2: string serializationLib, // usually the class that implements the extractor & loader 126 | 3: map parameters // initialization parameters 127 | } 128 | 129 | // sort order of a column (column name along with asc(1)/desc(0)) 130 | struct Order { 131 | 1: string col, // sort column name 132 | 2: i32 order // asc(1) or desc(0) 133 | } 134 | 135 | // this object holds all the information about physical storage of the data belonging to a table 136 | struct StorageDescriptor { 137 | 1: list cols, // required (refer to types defined above) 138 | 2: string location, // defaults to //tablename 139 | 3: string inputFormat, // SequenceFileInputFormat (binary) or TextInputFormat` or custom format 140 | 4: string outputFormat, // SequenceFileOutputFormat (binary) or IgnoreKeyTextOutputFormat or custom format 141 | 5: bool compressed, // compressed or not 142 | 6: i32 numBuckets, // this must be specified if there are any dimension columns 143 | 7: SerDeInfo serdeInfo, // serialization and deserialization information 144 | 8: list bucketCols, // reducer grouping columns and clustering columns and bucketing columns` 145 | 9: list sortCols, // sort order of the data in each bucket 146 | 10: map parameters // any user supplied key value hash 147 | } 148 | 149 | // table information 150 | struct Table { 151 | 1: string tableName, // name of the table 152 | 2: string dbName, // database name ('default') 153 | 3: string owner, // owner of this table 154 | 4: i32 createTime, // creation time of the table 155 | 5: i32 lastAccessTime, // last access time (usually this will be filled from HDFS and shouldn't be relied on) 156 | 6: i32 retention, // retention time 157 | 7: StorageDescriptor sd, // storage descriptor of the table 158 | 8: list partitionKeys, // partition keys of the table. only primitive types are supported 159 | 9: map parameters, // to store comments or any other user level parameters 160 | 10: string viewOriginalText, // original view text, null for non-view 161 | 11: string viewExpandedText, // expanded view text, null for non-view 162 | 12: string tableType, // table type enum, e.g. EXTERNAL_TABLE 163 | 13: optional PrincipalPrivilegeSet privileges, 164 | } 165 | 166 | struct Partition { 167 | 1: list values // string value is converted to appropriate partition key type 168 | 2: string dbName, 169 | 3: string tableName, 170 | 4: i32 createTime, 171 | 5: i32 lastAccessTime, 172 | 6: StorageDescriptor sd, 173 | 7: map parameters, 174 | 8: optional PrincipalPrivilegeSet privileges 175 | } 176 | 177 | struct Index { 178 | 1: string indexName, // unique with in the whole database namespace 179 | 2: string indexHandlerClass, // reserved 180 | 3: string dbName, 181 | 4: string origTableName, 182 | 5: i32 createTime, 183 | 6: i32 lastAccessTime, 184 | 7: string indexTableName, 185 | 8: StorageDescriptor sd, 186 | 9: map parameters, 187 | 10: bool deferredRebuild 188 | } 189 | 190 | // schema of the table/query results etc. 191 | struct Schema { 192 | // column names, types, comments 193 | 1: list fieldSchemas, // delimiters etc 194 | 2: map properties 195 | } 196 | 197 | // Key-value store to be used with selected 198 | // Metastore APIs (create, alter methods). 199 | // The client can pass environment properties / configs that can be 200 | // accessed in hooks. 201 | struct EnvironmentContext { 202 | 1: map properties 203 | } 204 | 205 | exception MetaException { 206 | 1: string message 207 | } 208 | 209 | exception UnknownTableException { 210 | 1: string message 211 | } 212 | 213 | exception UnknownDBException { 214 | 1: string message 215 | } 216 | 217 | exception AlreadyExistsException { 218 | 1: string message 219 | } 220 | 221 | exception InvalidPartitionException { 222 | 1: string message 223 | } 224 | 225 | exception UnknownPartitionException { 226 | 1: string message 227 | } 228 | 229 | exception InvalidObjectException { 230 | 1: string message 231 | } 232 | 233 | exception NoSuchObjectException { 234 | 1: string message 235 | } 236 | 237 | exception IndexAlreadyExistsException { 238 | 1: string message 239 | } 240 | 241 | exception InvalidOperationException { 242 | 1: string message 243 | } 244 | 245 | exception ConfigValSecurityException { 246 | 1: string message 247 | } 248 | 249 | /** 250 | * This interface is live. 251 | */ 252 | service ThriftHiveMetastore extends fb303.FacebookService 253 | { 254 | void create_database(1:Database database) throws(1:AlreadyExistsException o1, 2:InvalidObjectException o2, 3:MetaException o3) 255 | Database get_database(1:string name) throws(1:NoSuchObjectException o1, 2:MetaException o2) 256 | void drop_database(1:string name, 2:bool deleteData, 3:bool cascade) throws(1:NoSuchObjectException o1, 2:InvalidOperationException o2, 3:MetaException o3) 257 | list get_databases(1:string pattern) throws(1:MetaException o1) 258 | list get_all_databases() throws(1:MetaException o1) 259 | void alter_database(1:string dbname, 2:Database db) throws(1:MetaException o1, 2:NoSuchObjectException o2) 260 | 261 | // returns the type with given name (make seperate calls for the dependent types if needed) 262 | Type get_type(1:string name) throws(1:MetaException o1, 2:NoSuchObjectException o2) 263 | bool create_type(1:Type type) throws(1:AlreadyExistsException o1, 2:InvalidObjectException o2, 3:MetaException o3) 264 | bool drop_type(1:string type) throws(1:MetaException o1, 2:NoSuchObjectException o2) 265 | map get_type_all(1:string name) 266 | throws(1:MetaException o2) 267 | 268 | // Gets a list of FieldSchemas describing the columns of a particular table 269 | list get_fields(1: string db_name, 2: string table_name) throws (1: MetaException o1, 2: UnknownTableException o2, 3: UnknownDBException o3), 270 | 271 | // Gets a list of FieldSchemas describing both the columns and the partition keys of a particular table 272 | list get_schema(1: string db_name, 2: string table_name) throws (1: MetaException o1, 2: UnknownTableException o2, 3: UnknownDBException o3) 273 | 274 | // create a Hive table. Following fields must be set 275 | // tableName 276 | // database (only 'default' for now until Hive QL supports databases) 277 | // owner (not needed, but good to have for tracking purposes) 278 | // sd.cols (list of field schemas) 279 | // sd.inputFormat (SequenceFileInputFormat (binary like falcon tables or u_full) or TextInputFormat) 280 | // sd.outputFormat (SequenceFileInputFormat (binary) or TextInputFormat) 281 | // sd.serdeInfo.serializationLib (SerDe class name eg org.apache.hadoop.hive.serde.simple_meta.MetadataTypedColumnsetSerDe 282 | // * See notes on DDL_TIME 283 | void create_table(1:Table tbl) throws(1:AlreadyExistsException o1, 2:InvalidObjectException o2, 3:MetaException o3, 4:NoSuchObjectException o4) 284 | void create_table_with_environment_context(1:Table tbl, 285 | 2:EnvironmentContext environment_context) 286 | throws (1:AlreadyExistsException o1, 287 | 2:InvalidObjectException o2, 3:MetaException o3, 288 | 4:NoSuchObjectException o4) 289 | // drops the table and all the partitions associated with it if the table has partitions 290 | // delete data (including partitions) if deleteData is set to true 291 | void drop_table(1:string dbname, 2:string name, 3:bool deleteData) 292 | throws(1:NoSuchObjectException o1, 2:MetaException o3) 293 | list get_tables(1: string db_name, 2: string pattern) throws (1: MetaException o1) 294 | list get_all_tables(1: string db_name) throws (1: MetaException o1) 295 | 296 | Table get_table(1:string dbname, 2:string tbl_name) 297 | throws (1:MetaException o1, 2:NoSuchObjectException o2) 298 | list
get_table_objects_by_name(1:string dbname, 2:list tbl_names) 299 | throws (1:MetaException o1, 2:InvalidOperationException o2, 3:UnknownDBException o3) 300 | 301 | // Get a list of table names that match a filter. 302 | // The filter operators are LIKE, <, <=, >, >=, =, <> 303 | // 304 | // In the filter statement, values interpreted as strings must be enclosed in quotes, 305 | // while values interpreted as integers should not be. Strings and integers are the only 306 | // supported value types. 307 | // 308 | // The currently supported key names in the filter are: 309 | // Constants.HIVE_FILTER_FIELD_OWNER, which filters on the tables' owner's name 310 | // and supports all filter operators 311 | // Constants.HIVE_FILTER_FIELD_LAST_ACCESS, which filters on the last access times 312 | // and supports all filter operators except LIKE 313 | // Constants.HIVE_FILTER_FIELD_PARAMS, which filters on the tables' parameter keys and values 314 | // and only supports the filter operators = and <>. 315 | // Append the parameter key name to HIVE_FILTER_FIELD_PARAMS in the filter statement. 316 | // For example, to filter on parameter keys called "retention", the key name in the filter 317 | // statement should be Constants.HIVE_FILTER_FIELD_PARAMS + "retention" 318 | // Also, = and <> only work for keys that exist 319 | // in the tables. E.g., if you are looking for tables where key1 <> value, it will only 320 | // look at tables that have a value for the parameter key1. 321 | // Some example filter statements include: 322 | // filter = Constants.HIVE_FILTER_FIELD_OWNER + " like \".*test.*\" and " + 323 | // Constants.HIVE_FILTER_FIELD_LAST_ACCESS + " = 0"; 324 | // filter = Constants.HIVE_FILTER_FIELD_PARAMS + "retention = \"30\" or " + 325 | // Constants.HIVE_FILTER_FIELD_PARAMS + "retention = \"90\"" 326 | // @param dbName 327 | // The name of the database from which you will retrieve the table names 328 | // @param filterType 329 | // The type of filter 330 | // @param filter 331 | // The filter string 332 | // @param max_tables 333 | // The maximum number of tables returned 334 | // @return A list of table names that match the desired filter 335 | list get_table_names_by_filter(1:string dbname, 2:string filter, 3:i16 max_tables=-1) 336 | throws (1:MetaException o1, 2:InvalidOperationException o2, 3:UnknownDBException o3) 337 | 338 | // alter table applies to only future partitions not for existing partitions 339 | // * See notes on DDL_TIME 340 | void alter_table(1:string dbname, 2:string tbl_name, 3:Table new_tbl) 341 | throws (1:InvalidOperationException o1, 2:MetaException o2) 342 | void alter_table_with_environment_context(1:string dbname, 2:string tbl_name, 343 | 3:Table new_tbl, 4:EnvironmentContext environment_context) 344 | throws (1:InvalidOperationException o1, 2:MetaException o2) 345 | // the following applies to only tables that have partitions 346 | // * See notes on DDL_TIME 347 | Partition add_partition(1:Partition new_part) 348 | throws(1:InvalidObjectException o1, 2:AlreadyExistsException o2, 3:MetaException o3) 349 | Partition add_partition_with_environment_context(1:Partition new_part, 350 | 2:EnvironmentContext environment_context) 351 | throws (1:InvalidObjectException o1, 2:AlreadyExistsException o2, 352 | 3:MetaException o3) 353 | i32 add_partitions(1:list new_parts) 354 | throws(1:InvalidObjectException o1, 2:AlreadyExistsException o2, 3:MetaException o3) 355 | Partition append_partition(1:string db_name, 2:string tbl_name, 3:list part_vals) 356 | throws (1:InvalidObjectException o1, 2:AlreadyExistsException o2, 3:MetaException o3) 357 | Partition append_partition_by_name(1:string db_name, 2:string tbl_name, 3:string part_name) 358 | throws (1:InvalidObjectException o1, 2:AlreadyExistsException o2, 3:MetaException o3) 359 | bool drop_partition(1:string db_name, 2:string tbl_name, 3:list part_vals, 4:bool deleteData) 360 | throws(1:NoSuchObjectException o1, 2:MetaException o2) 361 | bool drop_partition_by_name(1:string db_name, 2:string tbl_name, 3:string part_name, 4:bool deleteData) 362 | throws(1:NoSuchObjectException o1, 2:MetaException o2) 363 | Partition get_partition(1:string db_name, 2:string tbl_name, 3:list part_vals) 364 | throws(1:MetaException o1, 2:NoSuchObjectException o2) 365 | 366 | Partition get_partition_with_auth(1:string db_name, 2:string tbl_name, 3:list part_vals, 367 | 4: string user_name, 5: list group_names) throws(1:MetaException o1, 2:NoSuchObjectException o2) 368 | 369 | Partition get_partition_by_name(1:string db_name 2:string tbl_name, 3:string part_name) 370 | throws(1:MetaException o1, 2:NoSuchObjectException o2) 371 | 372 | // returns all the partitions for this table in reverse chronological order. 373 | // If max parts is given then it will return only that many. 374 | list get_partitions(1:string db_name, 2:string tbl_name, 3:i16 max_parts=-1) 375 | throws(1:NoSuchObjectException o1, 2:MetaException o2) 376 | list get_partitions_with_auth(1:string db_name, 2:string tbl_name, 3:i16 max_parts=-1, 377 | 4: string user_name, 5: list group_names) throws(1:NoSuchObjectException o1, 2:MetaException o2) 378 | 379 | list get_partition_names(1:string db_name, 2:string tbl_name, 3:i16 max_parts=-1) 380 | throws(1:MetaException o2) 381 | 382 | // get_partition*_ps methods allow filtering by a partial partition specification, 383 | // as needed for dynamic partitions. The values that are not restricted should 384 | // be empty strings. Nulls were considered (instead of "") but caused errors in 385 | // generated Python code. The size of part_vals may be smaller than the 386 | // number of partition columns - the unspecified values are considered the same 387 | // as "". 388 | list get_partitions_ps(1:string db_name 2:string tbl_name 389 | 3:list part_vals, 4:i16 max_parts=-1) 390 | throws(1:MetaException o1, 2:NoSuchObjectException o2) 391 | list get_partitions_ps_with_auth(1:string db_name, 2:string tbl_name, 3:list part_vals, 4:i16 max_parts=-1, 392 | 5: string user_name, 6: list group_names) throws(1:NoSuchObjectException o1, 2:MetaException o2) 393 | 394 | list get_partition_names_ps(1:string db_name, 395 | 2:string tbl_name, 3:list part_vals, 4:i16 max_parts=-1) 396 | throws(1:MetaException o1, 2:NoSuchObjectException o2) 397 | 398 | // get the partitions matching the given partition filter 399 | list get_partitions_by_filter(1:string db_name 2:string tbl_name 400 | 3:string filter, 4:i16 max_parts=-1) 401 | throws(1:MetaException o1, 2:NoSuchObjectException o2) 402 | 403 | // get partitions give a list of partition names 404 | list get_partitions_by_names(1:string db_name 2:string tbl_name 3:list names) 405 | throws(1:MetaException o1, 2:NoSuchObjectException o2) 406 | 407 | // changes the partition to the new partition object. partition is identified from the part values 408 | // in the new_part 409 | // * See notes on DDL_TIME 410 | void alter_partition(1:string db_name, 2:string tbl_name, 3:Partition new_part) 411 | throws (1:InvalidOperationException o1, 2:MetaException o2) 412 | 413 | void alter_partition_with_environment_context(1:string db_name, 414 | 2:string tbl_name, 3:Partition new_part, 415 | 4:EnvironmentContext environment_context) 416 | throws (1:InvalidOperationException o1, 2:MetaException o2) 417 | 418 | // rename the old partition to the new partition object by changing old part values to the part values 419 | // in the new_part. old partition is identified from part_vals. 420 | // partition keys in new_part should be the same as those in old partition. 421 | void rename_partition(1:string db_name, 2:string tbl_name, 3:list part_vals, 4:Partition new_part) 422 | throws (1:InvalidOperationException o1, 2:MetaException o2) 423 | 424 | // gets the value of the configuration key in the metastore server. returns 425 | // defaultValue if the key does not exist. if the configuration key does not 426 | // begin with "hive", "mapred", or "hdfs", a ConfigValSecurityException is 427 | // thrown. 428 | string get_config_value(1:string name, 2:string defaultValue) 429 | throws(1:ConfigValSecurityException o1) 430 | 431 | // converts a partition name into a partition values array 432 | list partition_name_to_vals(1: string part_name) 433 | throws(1: MetaException o1) 434 | // converts a partition name into a partition specification (a mapping from 435 | // the partition cols to the values) 436 | map partition_name_to_spec(1: string part_name) 437 | throws(1: MetaException o1) 438 | 439 | void markPartitionForEvent(1:string db_name, 2:string tbl_name, 3:map part_vals, 440 | 4:PartitionEventType eventType) throws (1: MetaException o1, 2: NoSuchObjectException o2, 441 | 3: UnknownDBException o3, 4: UnknownTableException o4, 5: UnknownPartitionException o5, 442 | 6: InvalidPartitionException o6) 443 | bool isPartitionMarkedForEvent(1:string db_name, 2:string tbl_name, 3:map part_vals, 444 | 4: PartitionEventType eventType) throws (1: MetaException o1, 2:NoSuchObjectException o2, 445 | 3: UnknownDBException o3, 4: UnknownTableException o4, 5: UnknownPartitionException o5, 446 | 6: InvalidPartitionException o6) 447 | 448 | //index 449 | Index add_index(1:Index new_index, 2: Table index_table) 450 | throws(1:InvalidObjectException o1, 2:AlreadyExistsException o2, 3:MetaException o3) 451 | void alter_index(1:string dbname, 2:string base_tbl_name, 3:string idx_name, 4:Index new_idx) 452 | throws (1:InvalidOperationException o1, 2:MetaException o2) 453 | bool drop_index_by_name(1:string db_name, 2:string tbl_name, 3:string index_name, 4:bool deleteData) 454 | throws(1:NoSuchObjectException o1, 2:MetaException o2) 455 | Index get_index_by_name(1:string db_name 2:string tbl_name, 3:string index_name) 456 | throws(1:MetaException o1, 2:NoSuchObjectException o2) 457 | 458 | list get_indexes(1:string db_name, 2:string tbl_name, 3:i16 max_indexes=-1) 459 | throws(1:NoSuchObjectException o1, 2:MetaException o2) 460 | list get_index_names(1:string db_name, 2:string tbl_name, 3:i16 max_indexes=-1) 461 | throws(1:MetaException o2) 462 | 463 | //authorization privileges 464 | 465 | bool create_role(1:Role role) throws(1:MetaException o1) 466 | bool drop_role(1:string role_name) throws(1:MetaException o1) 467 | list get_role_names() throws(1:MetaException o1) 468 | bool grant_role(1:string role_name, 2:string principal_name, 3:PrincipalType principal_type, 469 | 4:string grantor, 5:PrincipalType grantorType, 6:bool grant_option) throws(1:MetaException o1) 470 | bool revoke_role(1:string role_name, 2:string principal_name, 3:PrincipalType principal_type) 471 | throws(1:MetaException o1) 472 | list list_roles(1:string principal_name, 2:PrincipalType principal_type) throws(1:MetaException o1) 473 | 474 | PrincipalPrivilegeSet get_privilege_set(1:HiveObjectRef hiveObject, 2:string user_name, 475 | 3: list group_names) throws(1:MetaException o1) 476 | list list_privileges(1:string principal_name, 2:PrincipalType principal_type, 477 | 3: HiveObjectRef hiveObject) throws(1:MetaException o1) 478 | 479 | bool grant_privileges(1:PrivilegeBag privileges) throws(1:MetaException o1) 480 | bool revoke_privileges(1:PrivilegeBag privileges) throws(1:MetaException o1) 481 | 482 | // this is used by metastore client to send UGI information to metastore server immediately 483 | // after setting up a connection. 484 | list set_ugi(1:string user_name, 2:list group_names) throws (1:MetaException o1) 485 | 486 | //Authentication (delegation token) interfaces 487 | 488 | // get metastore server delegation token for use from the map/reduce tasks to authenticate 489 | // to metastore server 490 | string get_delegation_token(1:string token_owner, 2:string renewer_kerberos_principal_name) 491 | throws (1:MetaException o1) 492 | 493 | // method to renew delegation token obtained from metastore server 494 | i64 renew_delegation_token(1:string token_str_form) throws (1:MetaException o1) 495 | 496 | // method to cancel delegation token obtained from metastore server 497 | void cancel_delegation_token(1:string token_str_form) throws (1:MetaException o1) 498 | } 499 | 500 | // * Note about the DDL_TIME: When creating or altering a table or a partition, 501 | // if the DDL_TIME is not set, the current time will be used. 502 | 503 | // For storing info about archived partitions in parameters 504 | 505 | // Whether the partition is archived 506 | const string IS_ARCHIVED = "is_archived", 507 | // The original location of the partition, before archiving. After archiving, 508 | // this directory will contain the archive. When the partition 509 | // is dropped, this directory will be deleted 510 | const string ORIGINAL_LOCATION = "original_location", 511 | 512 | // these should be needed only for backward compatibility with filestore 513 | const string META_TABLE_COLUMNS = "columns", 514 | const string META_TABLE_COLUMN_TYPES = "columns.types", 515 | const string BUCKET_FIELD_NAME = "bucket_field_name", 516 | const string BUCKET_COUNT = "bucket_count", 517 | const string FIELD_TO_DIMENSION = "field_to_dimension", 518 | const string META_TABLE_NAME = "name", 519 | const string META_TABLE_DB = "db", 520 | const string META_TABLE_LOCATION = "location", 521 | const string META_TABLE_SERDE = "serde", 522 | const string META_TABLE_PARTITION_COLUMNS = "partition_columns", 523 | const string FILE_INPUT_FORMAT = "file.inputformat", 524 | const string FILE_OUTPUT_FORMAT = "file.outputformat", 525 | const string META_TABLE_STORAGE = "storage_handler", 526 | 527 | 528 | 529 | -------------------------------------------------------------------------------- /lib/impala/protocol/beeswax_service.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Autogenerated by Thrift Compiler (0.9.1) 3 | # 4 | # DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 5 | # 6 | 7 | require 'thrift' 8 | require 'beeswax_types' 9 | 10 | module Impala 11 | module Protocol 12 | module Beeswax 13 | module BeeswaxService 14 | class Client 15 | include ::Thrift::Client 16 | 17 | def query(query) 18 | send_query(query) 19 | return recv_query() 20 | end 21 | 22 | def send_query(query) 23 | send_message('query', Query_args, :query => query) 24 | end 25 | 26 | def recv_query() 27 | result = receive_message(Query_result) 28 | return result.success unless result.success.nil? 29 | raise result.error unless result.error.nil? 30 | raise ::Thrift::ApplicationException.new(::Thrift::ApplicationException::MISSING_RESULT, 'query failed: unknown result') 31 | end 32 | 33 | def executeAndWait(query, clientCtx) 34 | send_executeAndWait(query, clientCtx) 35 | return recv_executeAndWait() 36 | end 37 | 38 | def send_executeAndWait(query, clientCtx) 39 | send_message('executeAndWait', ExecuteAndWait_args, :query => query, :clientCtx => clientCtx) 40 | end 41 | 42 | def recv_executeAndWait() 43 | result = receive_message(ExecuteAndWait_result) 44 | return result.success unless result.success.nil? 45 | raise result.error unless result.error.nil? 46 | raise ::Thrift::ApplicationException.new(::Thrift::ApplicationException::MISSING_RESULT, 'executeAndWait failed: unknown result') 47 | end 48 | 49 | def explain(query) 50 | send_explain(query) 51 | return recv_explain() 52 | end 53 | 54 | def send_explain(query) 55 | send_message('explain', Explain_args, :query => query) 56 | end 57 | 58 | def recv_explain() 59 | result = receive_message(Explain_result) 60 | return result.success unless result.success.nil? 61 | raise result.error unless result.error.nil? 62 | raise ::Thrift::ApplicationException.new(::Thrift::ApplicationException::MISSING_RESULT, 'explain failed: unknown result') 63 | end 64 | 65 | def fetch(query_id, start_over, fetch_size) 66 | send_fetch(query_id, start_over, fetch_size) 67 | return recv_fetch() 68 | end 69 | 70 | def send_fetch(query_id, start_over, fetch_size) 71 | send_message('fetch', Fetch_args, :query_id => query_id, :start_over => start_over, :fetch_size => fetch_size) 72 | end 73 | 74 | def recv_fetch() 75 | result = receive_message(Fetch_result) 76 | return result.success unless result.success.nil? 77 | raise result.error unless result.error.nil? 78 | raise result.error2 unless result.error2.nil? 79 | raise ::Thrift::ApplicationException.new(::Thrift::ApplicationException::MISSING_RESULT, 'fetch failed: unknown result') 80 | end 81 | 82 | def get_state(handle) 83 | send_get_state(handle) 84 | return recv_get_state() 85 | end 86 | 87 | def send_get_state(handle) 88 | send_message('get_state', Get_state_args, :handle => handle) 89 | end 90 | 91 | def recv_get_state() 92 | result = receive_message(Get_state_result) 93 | return result.success unless result.success.nil? 94 | raise result.error unless result.error.nil? 95 | raise ::Thrift::ApplicationException.new(::Thrift::ApplicationException::MISSING_RESULT, 'get_state failed: unknown result') 96 | end 97 | 98 | def get_results_metadata(handle) 99 | send_get_results_metadata(handle) 100 | return recv_get_results_metadata() 101 | end 102 | 103 | def send_get_results_metadata(handle) 104 | send_message('get_results_metadata', Get_results_metadata_args, :handle => handle) 105 | end 106 | 107 | def recv_get_results_metadata() 108 | result = receive_message(Get_results_metadata_result) 109 | return result.success unless result.success.nil? 110 | raise result.error unless result.error.nil? 111 | raise ::Thrift::ApplicationException.new(::Thrift::ApplicationException::MISSING_RESULT, 'get_results_metadata failed: unknown result') 112 | end 113 | 114 | def echo(s) 115 | send_echo(s) 116 | return recv_echo() 117 | end 118 | 119 | def send_echo(s) 120 | send_message('echo', Echo_args, :s => s) 121 | end 122 | 123 | def recv_echo() 124 | result = receive_message(Echo_result) 125 | return result.success unless result.success.nil? 126 | raise ::Thrift::ApplicationException.new(::Thrift::ApplicationException::MISSING_RESULT, 'echo failed: unknown result') 127 | end 128 | 129 | def dump_config() 130 | send_dump_config() 131 | return recv_dump_config() 132 | end 133 | 134 | def send_dump_config() 135 | send_message('dump_config', Dump_config_args) 136 | end 137 | 138 | def recv_dump_config() 139 | result = receive_message(Dump_config_result) 140 | return result.success unless result.success.nil? 141 | raise ::Thrift::ApplicationException.new(::Thrift::ApplicationException::MISSING_RESULT, 'dump_config failed: unknown result') 142 | end 143 | 144 | def get_log(context) 145 | send_get_log(context) 146 | return recv_get_log() 147 | end 148 | 149 | def send_get_log(context) 150 | send_message('get_log', Get_log_args, :context => context) 151 | end 152 | 153 | def recv_get_log() 154 | result = receive_message(Get_log_result) 155 | return result.success unless result.success.nil? 156 | raise result.error unless result.error.nil? 157 | raise ::Thrift::ApplicationException.new(::Thrift::ApplicationException::MISSING_RESULT, 'get_log failed: unknown result') 158 | end 159 | 160 | def get_default_configuration(include_hadoop) 161 | send_get_default_configuration(include_hadoop) 162 | return recv_get_default_configuration() 163 | end 164 | 165 | def send_get_default_configuration(include_hadoop) 166 | send_message('get_default_configuration', Get_default_configuration_args, :include_hadoop => include_hadoop) 167 | end 168 | 169 | def recv_get_default_configuration() 170 | result = receive_message(Get_default_configuration_result) 171 | return result.success unless result.success.nil? 172 | raise ::Thrift::ApplicationException.new(::Thrift::ApplicationException::MISSING_RESULT, 'get_default_configuration failed: unknown result') 173 | end 174 | 175 | def close(handle) 176 | send_close(handle) 177 | recv_close() 178 | end 179 | 180 | def send_close(handle) 181 | send_message('close', Close_args, :handle => handle) 182 | end 183 | 184 | def recv_close() 185 | result = receive_message(Close_result) 186 | raise result.error unless result.error.nil? 187 | raise result.error2 unless result.error2.nil? 188 | return 189 | end 190 | 191 | def clean(log_context) 192 | send_clean(log_context) 193 | recv_clean() 194 | end 195 | 196 | def send_clean(log_context) 197 | send_message('clean', Clean_args, :log_context => log_context) 198 | end 199 | 200 | def recv_clean() 201 | result = receive_message(Clean_result) 202 | return 203 | end 204 | 205 | end 206 | 207 | class Processor 208 | include ::Thrift::Processor 209 | 210 | def process_query(seqid, iprot, oprot) 211 | args = read_args(iprot, Query_args) 212 | result = Query_result.new() 213 | begin 214 | result.success = @handler.query(args.query) 215 | rescue ::Impala::Protocol::Beeswax::BeeswaxException => error 216 | result.error = error 217 | end 218 | write_result(result, oprot, 'query', seqid) 219 | end 220 | 221 | def process_executeAndWait(seqid, iprot, oprot) 222 | args = read_args(iprot, ExecuteAndWait_args) 223 | result = ExecuteAndWait_result.new() 224 | begin 225 | result.success = @handler.executeAndWait(args.query, args.clientCtx) 226 | rescue ::Impala::Protocol::Beeswax::BeeswaxException => error 227 | result.error = error 228 | end 229 | write_result(result, oprot, 'executeAndWait', seqid) 230 | end 231 | 232 | def process_explain(seqid, iprot, oprot) 233 | args = read_args(iprot, Explain_args) 234 | result = Explain_result.new() 235 | begin 236 | result.success = @handler.explain(args.query) 237 | rescue ::Impala::Protocol::Beeswax::BeeswaxException => error 238 | result.error = error 239 | end 240 | write_result(result, oprot, 'explain', seqid) 241 | end 242 | 243 | def process_fetch(seqid, iprot, oprot) 244 | args = read_args(iprot, Fetch_args) 245 | result = Fetch_result.new() 246 | begin 247 | result.success = @handler.fetch(args.query_id, args.start_over, args.fetch_size) 248 | rescue ::Impala::Protocol::Beeswax::QueryNotFoundException => error 249 | result.error = error 250 | rescue ::Impala::Protocol::Beeswax::BeeswaxException => error2 251 | result.error2 = error2 252 | end 253 | write_result(result, oprot, 'fetch', seqid) 254 | end 255 | 256 | def process_get_state(seqid, iprot, oprot) 257 | args = read_args(iprot, Get_state_args) 258 | result = Get_state_result.new() 259 | begin 260 | result.success = @handler.get_state(args.handle) 261 | rescue ::Impala::Protocol::Beeswax::QueryNotFoundException => error 262 | result.error = error 263 | end 264 | write_result(result, oprot, 'get_state', seqid) 265 | end 266 | 267 | def process_get_results_metadata(seqid, iprot, oprot) 268 | args = read_args(iprot, Get_results_metadata_args) 269 | result = Get_results_metadata_result.new() 270 | begin 271 | result.success = @handler.get_results_metadata(args.handle) 272 | rescue ::Impala::Protocol::Beeswax::QueryNotFoundException => error 273 | result.error = error 274 | end 275 | write_result(result, oprot, 'get_results_metadata', seqid) 276 | end 277 | 278 | def process_echo(seqid, iprot, oprot) 279 | args = read_args(iprot, Echo_args) 280 | result = Echo_result.new() 281 | result.success = @handler.echo(args.s) 282 | write_result(result, oprot, 'echo', seqid) 283 | end 284 | 285 | def process_dump_config(seqid, iprot, oprot) 286 | args = read_args(iprot, Dump_config_args) 287 | result = Dump_config_result.new() 288 | result.success = @handler.dump_config() 289 | write_result(result, oprot, 'dump_config', seqid) 290 | end 291 | 292 | def process_get_log(seqid, iprot, oprot) 293 | args = read_args(iprot, Get_log_args) 294 | result = Get_log_result.new() 295 | begin 296 | result.success = @handler.get_log(args.context) 297 | rescue ::Impala::Protocol::Beeswax::QueryNotFoundException => error 298 | result.error = error 299 | end 300 | write_result(result, oprot, 'get_log', seqid) 301 | end 302 | 303 | def process_get_default_configuration(seqid, iprot, oprot) 304 | args = read_args(iprot, Get_default_configuration_args) 305 | result = Get_default_configuration_result.new() 306 | result.success = @handler.get_default_configuration(args.include_hadoop) 307 | write_result(result, oprot, 'get_default_configuration', seqid) 308 | end 309 | 310 | def process_close(seqid, iprot, oprot) 311 | args = read_args(iprot, Close_args) 312 | result = Close_result.new() 313 | begin 314 | @handler.close(args.handle) 315 | rescue ::Impala::Protocol::Beeswax::QueryNotFoundException => error 316 | result.error = error 317 | rescue ::Impala::Protocol::Beeswax::BeeswaxException => error2 318 | result.error2 = error2 319 | end 320 | write_result(result, oprot, 'close', seqid) 321 | end 322 | 323 | def process_clean(seqid, iprot, oprot) 324 | args = read_args(iprot, Clean_args) 325 | result = Clean_result.new() 326 | @handler.clean(args.log_context) 327 | write_result(result, oprot, 'clean', seqid) 328 | end 329 | 330 | end 331 | 332 | # HELPER FUNCTIONS AND STRUCTURES 333 | 334 | class Query_args 335 | include ::Thrift::Struct, ::Thrift::Struct_Union 336 | QUERY = 1 337 | 338 | FIELDS = { 339 | QUERY => {:type => ::Thrift::Types::STRUCT, :name => 'query', :class => ::Impala::Protocol::Beeswax::Query} 340 | } 341 | 342 | def struct_fields; FIELDS; end 343 | 344 | def validate 345 | end 346 | 347 | ::Thrift::Struct.generate_accessors self 348 | end 349 | 350 | class Query_result 351 | include ::Thrift::Struct, ::Thrift::Struct_Union 352 | SUCCESS = 0 353 | ERROR = 1 354 | 355 | FIELDS = { 356 | SUCCESS => {:type => ::Thrift::Types::STRUCT, :name => 'success', :class => ::Impala::Protocol::Beeswax::QueryHandle}, 357 | ERROR => {:type => ::Thrift::Types::STRUCT, :name => 'error', :class => ::Impala::Protocol::Beeswax::BeeswaxException} 358 | } 359 | 360 | def struct_fields; FIELDS; end 361 | 362 | def validate 363 | end 364 | 365 | ::Thrift::Struct.generate_accessors self 366 | end 367 | 368 | class ExecuteAndWait_args 369 | include ::Thrift::Struct, ::Thrift::Struct_Union 370 | QUERY = 1 371 | CLIENTCTX = 2 372 | 373 | FIELDS = { 374 | QUERY => {:type => ::Thrift::Types::STRUCT, :name => 'query', :class => ::Impala::Protocol::Beeswax::Query}, 375 | CLIENTCTX => {:type => ::Thrift::Types::STRING, :name => 'clientCtx'} 376 | } 377 | 378 | def struct_fields; FIELDS; end 379 | 380 | def validate 381 | end 382 | 383 | ::Thrift::Struct.generate_accessors self 384 | end 385 | 386 | class ExecuteAndWait_result 387 | include ::Thrift::Struct, ::Thrift::Struct_Union 388 | SUCCESS = 0 389 | ERROR = 1 390 | 391 | FIELDS = { 392 | SUCCESS => {:type => ::Thrift::Types::STRUCT, :name => 'success', :class => ::Impala::Protocol::Beeswax::QueryHandle}, 393 | ERROR => {:type => ::Thrift::Types::STRUCT, :name => 'error', :class => ::Impala::Protocol::Beeswax::BeeswaxException} 394 | } 395 | 396 | def struct_fields; FIELDS; end 397 | 398 | def validate 399 | end 400 | 401 | ::Thrift::Struct.generate_accessors self 402 | end 403 | 404 | class Explain_args 405 | include ::Thrift::Struct, ::Thrift::Struct_Union 406 | QUERY = 1 407 | 408 | FIELDS = { 409 | QUERY => {:type => ::Thrift::Types::STRUCT, :name => 'query', :class => ::Impala::Protocol::Beeswax::Query} 410 | } 411 | 412 | def struct_fields; FIELDS; end 413 | 414 | def validate 415 | end 416 | 417 | ::Thrift::Struct.generate_accessors self 418 | end 419 | 420 | class Explain_result 421 | include ::Thrift::Struct, ::Thrift::Struct_Union 422 | SUCCESS = 0 423 | ERROR = 1 424 | 425 | FIELDS = { 426 | SUCCESS => {:type => ::Thrift::Types::STRUCT, :name => 'success', :class => ::Impala::Protocol::Beeswax::QueryExplanation}, 427 | ERROR => {:type => ::Thrift::Types::STRUCT, :name => 'error', :class => ::Impala::Protocol::Beeswax::BeeswaxException} 428 | } 429 | 430 | def struct_fields; FIELDS; end 431 | 432 | def validate 433 | end 434 | 435 | ::Thrift::Struct.generate_accessors self 436 | end 437 | 438 | class Fetch_args 439 | include ::Thrift::Struct, ::Thrift::Struct_Union 440 | QUERY_ID = 1 441 | START_OVER = 2 442 | FETCH_SIZE = 3 443 | 444 | FIELDS = { 445 | QUERY_ID => {:type => ::Thrift::Types::STRUCT, :name => 'query_id', :class => ::Impala::Protocol::Beeswax::QueryHandle}, 446 | START_OVER => {:type => ::Thrift::Types::BOOL, :name => 'start_over'}, 447 | FETCH_SIZE => {:type => ::Thrift::Types::I32, :name => 'fetch_size', :default => -1} 448 | } 449 | 450 | def struct_fields; FIELDS; end 451 | 452 | def validate 453 | end 454 | 455 | ::Thrift::Struct.generate_accessors self 456 | end 457 | 458 | class Fetch_result 459 | include ::Thrift::Struct, ::Thrift::Struct_Union 460 | SUCCESS = 0 461 | ERROR = 1 462 | ERROR2 = 2 463 | 464 | FIELDS = { 465 | SUCCESS => {:type => ::Thrift::Types::STRUCT, :name => 'success', :class => ::Impala::Protocol::Beeswax::Results}, 466 | ERROR => {:type => ::Thrift::Types::STRUCT, :name => 'error', :class => ::Impala::Protocol::Beeswax::QueryNotFoundException}, 467 | ERROR2 => {:type => ::Thrift::Types::STRUCT, :name => 'error2', :class => ::Impala::Protocol::Beeswax::BeeswaxException} 468 | } 469 | 470 | def struct_fields; FIELDS; end 471 | 472 | def validate 473 | end 474 | 475 | ::Thrift::Struct.generate_accessors self 476 | end 477 | 478 | class Get_state_args 479 | include ::Thrift::Struct, ::Thrift::Struct_Union 480 | HANDLE = 1 481 | 482 | FIELDS = { 483 | HANDLE => {:type => ::Thrift::Types::STRUCT, :name => 'handle', :class => ::Impala::Protocol::Beeswax::QueryHandle} 484 | } 485 | 486 | def struct_fields; FIELDS; end 487 | 488 | def validate 489 | end 490 | 491 | ::Thrift::Struct.generate_accessors self 492 | end 493 | 494 | class Get_state_result 495 | include ::Thrift::Struct, ::Thrift::Struct_Union 496 | SUCCESS = 0 497 | ERROR = 1 498 | 499 | FIELDS = { 500 | SUCCESS => {:type => ::Thrift::Types::I32, :name => 'success', :enum_class => ::Impala::Protocol::Beeswax::QueryState}, 501 | ERROR => {:type => ::Thrift::Types::STRUCT, :name => 'error', :class => ::Impala::Protocol::Beeswax::QueryNotFoundException} 502 | } 503 | 504 | def struct_fields; FIELDS; end 505 | 506 | def validate 507 | unless @success.nil? || ::Impala::Protocol::Beeswax::QueryState::VALID_VALUES.include?(@success) 508 | raise ::Thrift::ProtocolException.new(::Thrift::ProtocolException::UNKNOWN, 'Invalid value of field success!') 509 | end 510 | end 511 | 512 | ::Thrift::Struct.generate_accessors self 513 | end 514 | 515 | class Get_results_metadata_args 516 | include ::Thrift::Struct, ::Thrift::Struct_Union 517 | HANDLE = 1 518 | 519 | FIELDS = { 520 | HANDLE => {:type => ::Thrift::Types::STRUCT, :name => 'handle', :class => ::Impala::Protocol::Beeswax::QueryHandle} 521 | } 522 | 523 | def struct_fields; FIELDS; end 524 | 525 | def validate 526 | end 527 | 528 | ::Thrift::Struct.generate_accessors self 529 | end 530 | 531 | class Get_results_metadata_result 532 | include ::Thrift::Struct, ::Thrift::Struct_Union 533 | SUCCESS = 0 534 | ERROR = 1 535 | 536 | FIELDS = { 537 | SUCCESS => {:type => ::Thrift::Types::STRUCT, :name => 'success', :class => ::Impala::Protocol::Beeswax::ResultsMetadata}, 538 | ERROR => {:type => ::Thrift::Types::STRUCT, :name => 'error', :class => ::Impala::Protocol::Beeswax::QueryNotFoundException} 539 | } 540 | 541 | def struct_fields; FIELDS; end 542 | 543 | def validate 544 | end 545 | 546 | ::Thrift::Struct.generate_accessors self 547 | end 548 | 549 | class Echo_args 550 | include ::Thrift::Struct, ::Thrift::Struct_Union 551 | S = 1 552 | 553 | FIELDS = { 554 | S => {:type => ::Thrift::Types::STRING, :name => 's'} 555 | } 556 | 557 | def struct_fields; FIELDS; end 558 | 559 | def validate 560 | end 561 | 562 | ::Thrift::Struct.generate_accessors self 563 | end 564 | 565 | class Echo_result 566 | include ::Thrift::Struct, ::Thrift::Struct_Union 567 | SUCCESS = 0 568 | 569 | FIELDS = { 570 | SUCCESS => {:type => ::Thrift::Types::STRING, :name => 'success'} 571 | } 572 | 573 | def struct_fields; FIELDS; end 574 | 575 | def validate 576 | end 577 | 578 | ::Thrift::Struct.generate_accessors self 579 | end 580 | 581 | class Dump_config_args 582 | include ::Thrift::Struct, ::Thrift::Struct_Union 583 | 584 | FIELDS = { 585 | 586 | } 587 | 588 | def struct_fields; FIELDS; end 589 | 590 | def validate 591 | end 592 | 593 | ::Thrift::Struct.generate_accessors self 594 | end 595 | 596 | class Dump_config_result 597 | include ::Thrift::Struct, ::Thrift::Struct_Union 598 | SUCCESS = 0 599 | 600 | FIELDS = { 601 | SUCCESS => {:type => ::Thrift::Types::STRING, :name => 'success'} 602 | } 603 | 604 | def struct_fields; FIELDS; end 605 | 606 | def validate 607 | end 608 | 609 | ::Thrift::Struct.generate_accessors self 610 | end 611 | 612 | class Get_log_args 613 | include ::Thrift::Struct, ::Thrift::Struct_Union 614 | CONTEXT = 1 615 | 616 | FIELDS = { 617 | CONTEXT => {:type => ::Thrift::Types::STRING, :name => 'context'} 618 | } 619 | 620 | def struct_fields; FIELDS; end 621 | 622 | def validate 623 | end 624 | 625 | ::Thrift::Struct.generate_accessors self 626 | end 627 | 628 | class Get_log_result 629 | include ::Thrift::Struct, ::Thrift::Struct_Union 630 | SUCCESS = 0 631 | ERROR = 1 632 | 633 | FIELDS = { 634 | SUCCESS => {:type => ::Thrift::Types::STRING, :name => 'success'}, 635 | ERROR => {:type => ::Thrift::Types::STRUCT, :name => 'error', :class => ::Impala::Protocol::Beeswax::QueryNotFoundException} 636 | } 637 | 638 | def struct_fields; FIELDS; end 639 | 640 | def validate 641 | end 642 | 643 | ::Thrift::Struct.generate_accessors self 644 | end 645 | 646 | class Get_default_configuration_args 647 | include ::Thrift::Struct, ::Thrift::Struct_Union 648 | INCLUDE_HADOOP = 1 649 | 650 | FIELDS = { 651 | INCLUDE_HADOOP => {:type => ::Thrift::Types::BOOL, :name => 'include_hadoop'} 652 | } 653 | 654 | def struct_fields; FIELDS; end 655 | 656 | def validate 657 | end 658 | 659 | ::Thrift::Struct.generate_accessors self 660 | end 661 | 662 | class Get_default_configuration_result 663 | include ::Thrift::Struct, ::Thrift::Struct_Union 664 | SUCCESS = 0 665 | 666 | FIELDS = { 667 | SUCCESS => {:type => ::Thrift::Types::LIST, :name => 'success', :element => {:type => ::Thrift::Types::STRUCT, :class => ::Impala::Protocol::Beeswax::ConfigVariable}} 668 | } 669 | 670 | def struct_fields; FIELDS; end 671 | 672 | def validate 673 | end 674 | 675 | ::Thrift::Struct.generate_accessors self 676 | end 677 | 678 | class Close_args 679 | include ::Thrift::Struct, ::Thrift::Struct_Union 680 | HANDLE = 1 681 | 682 | FIELDS = { 683 | HANDLE => {:type => ::Thrift::Types::STRUCT, :name => 'handle', :class => ::Impala::Protocol::Beeswax::QueryHandle} 684 | } 685 | 686 | def struct_fields; FIELDS; end 687 | 688 | def validate 689 | end 690 | 691 | ::Thrift::Struct.generate_accessors self 692 | end 693 | 694 | class Close_result 695 | include ::Thrift::Struct, ::Thrift::Struct_Union 696 | ERROR = 1 697 | ERROR2 = 2 698 | 699 | FIELDS = { 700 | ERROR => {:type => ::Thrift::Types::STRUCT, :name => 'error', :class => ::Impala::Protocol::Beeswax::QueryNotFoundException}, 701 | ERROR2 => {:type => ::Thrift::Types::STRUCT, :name => 'error2', :class => ::Impala::Protocol::Beeswax::BeeswaxException} 702 | } 703 | 704 | def struct_fields; FIELDS; end 705 | 706 | def validate 707 | end 708 | 709 | ::Thrift::Struct.generate_accessors self 710 | end 711 | 712 | class Clean_args 713 | include ::Thrift::Struct, ::Thrift::Struct_Union 714 | LOG_CONTEXT = 1 715 | 716 | FIELDS = { 717 | LOG_CONTEXT => {:type => ::Thrift::Types::STRING, :name => 'log_context'} 718 | } 719 | 720 | def struct_fields; FIELDS; end 721 | 722 | def validate 723 | end 724 | 725 | ::Thrift::Struct.generate_accessors self 726 | end 727 | 728 | class Clean_result 729 | include ::Thrift::Struct, ::Thrift::Struct_Union 730 | 731 | FIELDS = { 732 | 733 | } 734 | 735 | def struct_fields; FIELDS; end 736 | 737 | def validate 738 | end 739 | 740 | ::Thrift::Struct.generate_accessors self 741 | end 742 | 743 | end 744 | 745 | end 746 | end 747 | end 748 | -------------------------------------------------------------------------------- /thrift/cli_service.thrift: -------------------------------------------------------------------------------- 1 | // Licensed to the Apache Software Foundation (ASF) under one 2 | // or more contributor license agreements. See the NOTICE file 3 | // distributed with this work for additional information 4 | // regarding copyright ownership. The ASF licenses this file 5 | // to you under the Apache License, Version 2.0 (the 6 | // "License"); you may not use this file except in compliance 7 | // with the License. You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | 17 | // Coding Conventions for this file: 18 | // 19 | // Structs/Enums/Unions 20 | // * Struct, Enum, and Union names begin with a "T", 21 | // and use a capital letter for each new word, with no underscores. 22 | // * All fields should be declared as either optional or required. 23 | // 24 | // Functions 25 | // * Function names start with a capital letter and have a capital letter for 26 | // each new word, with no underscores. 27 | // * Each function should take exactly one parameter, named TFunctionNameReq, 28 | // and should return either void or TFunctionNameResp. This convention allows 29 | // incremental updates. 30 | // 31 | // Services 32 | // * Service names begin with the letter "T", use a capital letter for each 33 | // new word (with no underscores), and end with the word "Service". 34 | 35 | namespace java org.apache.hive.service.cli.thrift 36 | namespace cpp apache.hive.service.cli.thrift 37 | namespace rb impala.protocol.hive 38 | 39 | // List of protocol versions. A new token should be 40 | // added to the end of this list every time a change is made. 41 | enum TProtocolVersion { 42 | HIVE_CLI_SERVICE_PROTOCOL_V1 43 | } 44 | 45 | enum TTypeId { 46 | BOOLEAN_TYPE, 47 | TINYINT_TYPE, 48 | SMALLINT_TYPE, 49 | INT_TYPE, 50 | BIGINT_TYPE, 51 | FLOAT_TYPE, 52 | DOUBLE_TYPE, 53 | STRING_TYPE, 54 | TIMESTAMP_TYPE, 55 | BINARY_TYPE, 56 | ARRAY_TYPE, 57 | MAP_TYPE, 58 | STRUCT_TYPE, 59 | UNION_TYPE, 60 | USER_DEFINED_TYPE, 61 | DECIMAL_TYPE 62 | } 63 | 64 | const set PRIMITIVE_TYPES = [ 65 | TTypeId.BOOLEAN_TYPE 66 | TTypeId.TINYINT_TYPE 67 | TTypeId.SMALLINT_TYPE 68 | TTypeId.INT_TYPE 69 | TTypeId.BIGINT_TYPE 70 | TTypeId.FLOAT_TYPE 71 | TTypeId.DOUBLE_TYPE 72 | TTypeId.STRING_TYPE 73 | TTypeId.TIMESTAMP_TYPE 74 | TTypeId.BINARY_TYPE, 75 | TTypeId.DECIMAL_TYPE 76 | ] 77 | 78 | const set COMPLEX_TYPES = [ 79 | TTypeId.ARRAY_TYPE 80 | TTypeId.MAP_TYPE 81 | TTypeId.STRUCT_TYPE 82 | TTypeId.UNION_TYPE 83 | TTypeId.USER_DEFINED_TYPE 84 | ] 85 | 86 | const set COLLECTION_TYPES = [ 87 | TTypeId.ARRAY_TYPE 88 | TTypeId.MAP_TYPE 89 | ] 90 | 91 | const map TYPE_NAMES = { 92 | TTypeId.BOOLEAN_TYPE: "BOOLEAN", 93 | TTypeId.TINYINT_TYPE: "TINYINT", 94 | TTypeId.SMALLINT_TYPE: "SMALLINT", 95 | TTypeId.INT_TYPE: "INT", 96 | TTypeId.BIGINT_TYPE: "BIGINT", 97 | TTypeId.FLOAT_TYPE: "FLOAT", 98 | TTypeId.DOUBLE_TYPE: "DOUBLE", 99 | TTypeId.STRING_TYPE: "STRING", 100 | TTypeId.TIMESTAMP_TYPE: "TIMESTAMP", 101 | TTypeId.BINARY_TYPE: "BINARY", 102 | TTypeId.ARRAY_TYPE: "ARRAY", 103 | TTypeId.MAP_TYPE: "MAP", 104 | TTypeId.STRUCT_TYPE: "STRUCT", 105 | TTypeId.UNION_TYPE: "UNIONTYPE" 106 | TTypeId.DECIMAL_TYPE: "DECIMAL" 107 | } 108 | 109 | // Thrift does not support recursively defined types or forward declarations, 110 | // which makes it difficult to represent Hive's nested types. 111 | // To get around these limitations TTypeDesc employs a type list that maps 112 | // integer "pointers" to TTypeEntry objects. The following examples show 113 | // how different types are represented using this scheme: 114 | // 115 | // "INT": 116 | // TTypeDesc { 117 | // types = [ 118 | // TTypeEntry.primitive_entry { 119 | // type = INT_TYPE 120 | // } 121 | // ] 122 | // } 123 | // 124 | // "ARRAY": 125 | // TTypeDesc { 126 | // types = [ 127 | // TTypeEntry.array_entry { 128 | // object_type_ptr = 1 129 | // }, 130 | // TTypeEntry.primitive_entry { 131 | // type = INT_TYPE 132 | // } 133 | // ] 134 | // } 135 | // 136 | // "MAP": 137 | // TTypeDesc { 138 | // types = [ 139 | // TTypeEntry.map_entry { 140 | // key_type_ptr = 1 141 | // value_type_ptr = 2 142 | // }, 143 | // TTypeEntry.primitive_entry { 144 | // type = INT_TYPE 145 | // }, 146 | // TTypeEntry.primitive_entry { 147 | // type = STRING_TYPE 148 | // } 149 | // ] 150 | // } 151 | 152 | typedef i32 TTypeEntryPtr 153 | 154 | // Type entry for a primitive type. 155 | struct TPrimitiveTypeEntry { 156 | // The primitive type token. This must satisfy the condition 157 | // that type is in the PRIMITIVE_TYPES set. 158 | 1: required TTypeId type 159 | } 160 | 161 | // Type entry for an ARRAY type. 162 | struct TArrayTypeEntry { 163 | 1: required TTypeEntryPtr objectTypePtr 164 | } 165 | 166 | // Type entry for a MAP type. 167 | struct TMapTypeEntry { 168 | 1: required TTypeEntryPtr keyTypePtr 169 | 2: required TTypeEntryPtr valueTypePtr 170 | } 171 | 172 | // Type entry for a STRUCT type. 173 | struct TStructTypeEntry { 174 | 1: required map nameToTypePtr 175 | } 176 | 177 | // Type entry for a UNIONTYPE type. 178 | struct TUnionTypeEntry { 179 | 1: required map nameToTypePtr 180 | } 181 | 182 | struct TUserDefinedTypeEntry { 183 | // The fully qualified name of the class implementing this type. 184 | 1: required string typeClassName 185 | } 186 | 187 | // We use a union here since Thrift does not support inheritance. 188 | union TTypeEntry { 189 | 1: TPrimitiveTypeEntry primitiveEntry 190 | 2: TArrayTypeEntry arrayEntry 191 | 3: TMapTypeEntry mapEntry 192 | 4: TStructTypeEntry structEntry 193 | 5: TUnionTypeEntry unionEntry 194 | 6: TUserDefinedTypeEntry userDefinedTypeEntry 195 | } 196 | 197 | // Type descriptor for columns. 198 | struct TTypeDesc { 199 | // The "top" type is always the first element of the list. 200 | // If the top type is an ARRAY, MAP, STRUCT, or UNIONTYPE 201 | // type, then subsequent elements represent nested types. 202 | 1: required list types 203 | } 204 | 205 | // A result set column descriptor. 206 | struct TColumnDesc { 207 | // The name of the column 208 | 1: required string columnName 209 | 210 | // The type descriptor for this column 211 | 2: required TTypeDesc typeDesc 212 | 213 | // The ordinal position of this column in the schema 214 | 3: required i32 position 215 | 216 | 4: optional string comment 217 | } 218 | 219 | // Metadata used to describe the schema (column names, types, comments) 220 | // of result sets. 221 | struct TTableSchema { 222 | 1: required list columns 223 | } 224 | 225 | // A Boolean column value. 226 | struct TBoolValue { 227 | // NULL if value is unset. 228 | 1: optional bool value 229 | } 230 | 231 | // A Byte column value. 232 | struct TByteValue { 233 | // NULL if value is unset. 234 | 1: optional byte value 235 | } 236 | 237 | // A signed, 16 bit column value. 238 | struct TI16Value { 239 | // NULL if value is unset 240 | 1: optional i16 value 241 | } 242 | 243 | // A signed, 32 bit column value 244 | struct TI32Value { 245 | // NULL if value is unset 246 | 1: optional i32 value 247 | } 248 | 249 | // A signed 64 bit column value 250 | struct TI64Value { 251 | // NULL if value is unset 252 | 1: optional i64 value 253 | } 254 | 255 | // A floating point 64 bit column value 256 | struct TDoubleValue { 257 | // NULL if value is unset 258 | 1: optional double value 259 | } 260 | 261 | struct TStringValue { 262 | // NULL if value is unset 263 | 1: optional string value 264 | } 265 | 266 | union TColumn { 267 | 1: list boolColumn 268 | 2: list byteColumn 269 | 3: list i16Column 270 | 4: list i32Column 271 | 5: list i64Column 272 | 6: list doubleColumn 273 | 7: list stringColumn 274 | } 275 | 276 | // A single column value in a result set. 277 | // Note that Hive's type system is richer than Thrift's, 278 | // so in some cases we have to map multiple Hive types 279 | // to the same Thrift type. On the client-side this is 280 | // disambiguated by looking at the Schema of the 281 | // result set. 282 | union TColumnValue { 283 | 1: TBoolValue boolVal // BOOLEAN 284 | 2: TByteValue byteVal // TINYINT 285 | 3: TI16Value i16Val // SMALLINT 286 | 4: TI32Value i32Val // INT 287 | 5: TI64Value i64Val // BIGINT, TIMESTAMP 288 | 6: TDoubleValue doubleVal // FLOAT, DOUBLE 289 | 7: TStringValue stringVal // STRING, LIST, MAP, STRUCT, UNIONTYPE, BINARY, DECIMAL 290 | } 291 | 292 | // Represents a row in a rowset. 293 | struct TRow { 294 | 1: required list colVals 295 | } 296 | 297 | // Represents a rowset 298 | struct TRowSet { 299 | // The starting row offset of this rowset. 300 | 1: required i64 startRowOffset 301 | 2: required list rows 302 | 3: optional list columns 303 | } 304 | 305 | // The return status code contained in each response. 306 | enum TStatusCode { 307 | SUCCESS_STATUS, 308 | SUCCESS_WITH_INFO_STATUS, 309 | STILL_EXECUTING_STATUS, 310 | ERROR_STATUS, 311 | INVALID_HANDLE_STATUS 312 | } 313 | 314 | // The return status of a remote request 315 | struct TStatus { 316 | 1: required TStatusCode statusCode 317 | 318 | // If status is SUCCESS_WITH_INFO, info_msgs may be populated with 319 | // additional diagnostic information. 320 | 2: optional list infoMessages 321 | 322 | // If status is ERROR, then the following fields may be set 323 | 3: optional string sqlState // as defined in the ISO/IEF CLI specification 324 | 4: optional i32 errorCode // internal error code 325 | 5: optional string errorMessage 326 | } 327 | 328 | // The state of an operation (i.e. a query or other 329 | // asynchronous operation that generates a result set) 330 | // on the server. 331 | enum TOperationState { 332 | // The operation has been initialized 333 | INITIALIZED_STATE, 334 | 335 | // The operation is running. In this state the result 336 | // set is not available. 337 | RUNNING_STATE, 338 | 339 | // The operation has completed. When an operation is in 340 | // this state its result set may be fetched. 341 | FINISHED_STATE, 342 | 343 | // The operation was canceled by a client 344 | CANCELED_STATE, 345 | 346 | // The operation was closed by a client 347 | CLOSED_STATE, 348 | 349 | // The operation failed due to an error 350 | ERROR_STATE, 351 | 352 | // The operation is in an unrecognized state 353 | UKNOWN_STATE, 354 | } 355 | 356 | 357 | // A string identifier. This is interpreted literally. 358 | typedef string TIdentifier 359 | 360 | // A search pattern. 361 | // 362 | // Valid search pattern characters: 363 | // '_': Any single character. 364 | // '%': Any sequence of zero or more characters. 365 | // '\': Escape character used to include special characters, 366 | // e.g. '_', '%', '\'. If a '\' precedes a non-special 367 | // character it has no special meaning and is interpreted 368 | // literally. 369 | typedef string TPattern 370 | 371 | 372 | // A search pattern or identifier. Used as input 373 | // parameter for many of the catalog functions. 374 | typedef string TPatternOrIdentifier 375 | 376 | struct THandleIdentifier { 377 | // 16 byte globally unique identifier 378 | // This is the public ID of the handle and 379 | // can be used for reporting. 380 | 1: required binary guid, 381 | 382 | // 16 byte secret generated by the server 383 | // and used to verify that the handle is not 384 | // being hijacked by another user. 385 | 2: required binary secret, 386 | } 387 | 388 | // Client-side handle to persistent 389 | // session information on the server-side. 390 | struct TSessionHandle { 391 | 1: required THandleIdentifier sessionId 392 | } 393 | 394 | // The subtype of an OperationHandle. 395 | enum TOperationType { 396 | EXECUTE_STATEMENT, 397 | GET_TYPE_INFO, 398 | GET_CATALOGS, 399 | GET_SCHEMAS, 400 | GET_TABLES, 401 | GET_TABLE_TYPES, 402 | GET_COLUMNS, 403 | GET_FUNCTIONS, 404 | UNKNOWN, 405 | } 406 | 407 | // Client-side reference to a task running 408 | // asynchronously on the server. 409 | struct TOperationHandle { 410 | 1: required THandleIdentifier operationId 411 | 2: required TOperationType operationType 412 | 413 | // If hasResultSet = TRUE, then this operation 414 | // generates a result set that can be fetched. 415 | // Note that the result set may be empty. 416 | // 417 | // If hasResultSet = FALSE, then this operation 418 | // does not generate a result set, and calling 419 | // GetResultSetMetadata or FetchResults against 420 | // this OperationHandle will generate an error. 421 | 3: required bool hasResultSet 422 | 423 | // For operations that don't generate result sets, 424 | // modifiedRowCount is either: 425 | // 426 | // 1) The number of rows that were modified by 427 | // the DML operation (e.g. number of rows inserted, 428 | // number of rows deleted, etc). 429 | // 430 | // 2) 0 for operations that don't modify or add rows. 431 | // 432 | // 3) < 0 if the operation is capable of modifiying rows, 433 | // but Hive is unable to determine how many rows were 434 | // modified. For example, Hive's LOAD DATA command 435 | // doesn't generate row count information because 436 | // Hive doesn't inspect the data as it is loaded. 437 | // 438 | // modifiedRowCount is unset if the operation generates 439 | // a result set. 440 | 4: optional double modifiedRowCount 441 | } 442 | 443 | 444 | // OpenSession() 445 | // 446 | // Open a session (connection) on the server against 447 | // which operations may be executed. 448 | struct TOpenSessionReq { 449 | // The version of the HiveServer2 protocol that the client is using. 450 | 1: required TProtocolVersion client_protocol = TProtocolVersion.HIVE_CLI_SERVICE_PROTOCOL_V1 451 | 452 | // Username and password for authentication. 453 | // Depending on the authentication scheme being used, 454 | // this information may instead be provided by a lower 455 | // protocol layer, in which case these fields may be 456 | // left unset. 457 | 2: optional string username 458 | 3: optional string password 459 | 460 | // Configuration overlay which is applied when the session is 461 | // first created. 462 | 4: optional map configuration 463 | } 464 | 465 | struct TOpenSessionResp { 466 | 1: required TStatus status 467 | 468 | // The protocol version that the server is using. 469 | 2: required TProtocolVersion serverProtocolVersion = TProtocolVersion.HIVE_CLI_SERVICE_PROTOCOL_V1 470 | 471 | // Session Handle 472 | 3: optional TSessionHandle sessionHandle 473 | 474 | // The configuration settings for this session. 475 | 4: optional map configuration 476 | } 477 | 478 | 479 | // CloseSession() 480 | // 481 | // Closes the specified session and frees any resources 482 | // currently allocated to that session. Any open 483 | // operations in that session will be canceled. 484 | struct TCloseSessionReq { 485 | 1: required TSessionHandle sessionHandle 486 | } 487 | 488 | struct TCloseSessionResp { 489 | 1: required TStatus status 490 | } 491 | 492 | 493 | 494 | enum TGetInfoType { 495 | CLI_MAX_DRIVER_CONNECTIONS = 0, 496 | CLI_MAX_CONCURRENT_ACTIVITIES = 1, 497 | CLI_DATA_SOURCE_NAME = 2, 498 | CLI_FETCH_DIRECTION = 8, 499 | CLI_SERVER_NAME = 13, 500 | CLI_SEARCH_PATTERN_ESCAPE = 14, 501 | CLI_DBMS_NAME = 17, 502 | CLI_DBMS_VER = 18, 503 | CLI_ACCESSIBLE_TABLES = 19, 504 | CLI_ACCESSIBLE_PROCEDURES = 20, 505 | CLI_CURSOR_COMMIT_BEHAVIOR = 23, 506 | CLI_DATA_SOURCE_READ_ONLY = 25, 507 | CLI_DEFAULT_TXN_ISOLATION = 26, 508 | CLI_IDENTIFIER_CASE = 28, 509 | CLI_IDENTIFIER_QUOTE_CHAR = 29, 510 | CLI_MAX_COLUMN_NAME_LEN = 30, 511 | CLI_MAX_CURSOR_NAME_LEN = 31, 512 | CLI_MAX_SCHEMA_NAME_LEN = 32, 513 | CLI_MAX_CATALOG_NAME_LEN = 34, 514 | CLI_MAX_TABLE_NAME_LEN = 35, 515 | CLI_SCROLL_CONCURRENCY = 43, 516 | CLI_TXN_CAPABLE = 46, 517 | CLI_USER_NAME = 47, 518 | CLI_TXN_ISOLATION_OPTION = 72, 519 | CLI_INTEGRITY = 73, 520 | CLI_GETDATA_EXTENSIONS = 81, 521 | CLI_NULL_COLLATION = 85, 522 | CLI_ALTER_TABLE = 86, 523 | CLI_ORDER_BY_COLUMNS_IN_SELECT = 90, 524 | CLI_SPECIAL_CHARACTERS = 94, 525 | CLI_MAX_COLUMNS_IN_GROUP_BY = 97, 526 | CLI_MAX_COLUMNS_IN_INDEX = 98, 527 | CLI_MAX_COLUMNS_IN_ORDER_BY = 99, 528 | CLI_MAX_COLUMNS_IN_SELECT = 100, 529 | CLI_MAX_COLUMNS_IN_TABLE = 101, 530 | CLI_MAX_INDEX_SIZE = 102, 531 | CLI_MAX_ROW_SIZE = 104, 532 | CLI_MAX_STATEMENT_LEN = 105, 533 | CLI_MAX_TABLES_IN_SELECT = 106, 534 | CLI_MAX_USER_NAME_LEN = 107, 535 | CLI_OJ_CAPABILITIES = 115, 536 | 537 | CLI_XOPEN_CLI_YEAR = 10000, 538 | CLI_CURSOR_SENSITIVITY = 10001, 539 | CLI_DESCRIBE_PARAMETER = 10002, 540 | CLI_CATALOG_NAME = 10003, 541 | CLI_COLLATION_SEQ = 10004, 542 | CLI_MAX_IDENTIFIER_LEN = 10005, 543 | } 544 | 545 | union TGetInfoValue { 546 | 1: string stringValue 547 | 2: i16 smallIntValue 548 | 3: i32 integerBitmask 549 | 4: i32 integerFlag 550 | 5: i32 binaryValue 551 | 6: i64 lenValue 552 | } 553 | 554 | // GetInfo() 555 | // 556 | // This function is based on ODBC's CLIGetInfo() function. 557 | // The function returns general information about the data source 558 | // using the same keys as ODBC. 559 | struct TGetInfoReq { 560 | // The sesssion to run this request against 561 | 1: required TSessionHandle sessionHandle 562 | 563 | 2: required TGetInfoType infoType 564 | } 565 | 566 | struct TGetInfoResp { 567 | 1: required TStatus status 568 | 569 | 2: required TGetInfoValue infoValue 570 | } 571 | 572 | 573 | // ExecuteStatement() 574 | // 575 | // Execute a statement. 576 | // The returned OperationHandle can be used to check on the 577 | // status of the statement, and to fetch results once the 578 | // statement has finished executing. 579 | struct TExecuteStatementReq { 580 | // The session to exexcute the statement against 581 | 1: required TSessionHandle sessionHandle 582 | 583 | // The statement to be executed (DML, DDL, SET, etc) 584 | 2: required string statement 585 | 586 | // Configuration properties that are overlayed on top of the 587 | // the existing session configuration before this statement 588 | // is executed. These properties apply to this statement 589 | // only and will not affect the subsequent state of the Session. 590 | 3: optional map confOverlay 591 | } 592 | 593 | struct TExecuteStatementResp { 594 | 1: required TStatus status 595 | 2: optional TOperationHandle operationHandle 596 | } 597 | 598 | 599 | // GetTypeInfo() 600 | // 601 | // Get information about types supported by the HiveServer instance. 602 | // The information is returned as a result set which can be fetched 603 | // using the OperationHandle provided in the response. 604 | // 605 | // Refer to the documentation for ODBC's CLIGetTypeInfo function for 606 | // the format of the result set. 607 | struct TGetTypeInfoReq { 608 | // The session to run this request against. 609 | 1: required TSessionHandle sessionHandle 610 | } 611 | 612 | struct TGetTypeInfoResp { 613 | 1: required TStatus status 614 | 2: optional TOperationHandle operationHandle 615 | } 616 | 617 | 618 | // GetCatalogs() 619 | // 620 | // Returns the list of catalogs (databases) 621 | // Results are ordered by TABLE_CATALOG 622 | // 623 | // Resultset columns : 624 | // col1 625 | // name: TABLE_CAT 626 | // type: STRING 627 | // desc: Catalog name. NULL if not applicable. 628 | // 629 | struct TGetCatalogsReq { 630 | // Session to run this request against 631 | 1: required TSessionHandle sessionHandle 632 | } 633 | 634 | struct TGetCatalogsResp { 635 | 1: required TStatus status 636 | 2: optional TOperationHandle operationHandle 637 | } 638 | 639 | 640 | // GetSchemas() 641 | // 642 | // Retrieves the schema names available in this database. 643 | // The results are ordered by TABLE_CATALOG and TABLE_SCHEM. 644 | // col1 645 | // name: TABLE_SCHEM 646 | // type: STRING 647 | // desc: schema name 648 | // col2 649 | // name: TABLE_CATALOG 650 | // type: STRING 651 | // desc: catalog name 652 | struct TGetSchemasReq { 653 | // Session to run this request against 654 | 1: required TSessionHandle sessionHandle 655 | 656 | // Name of the catalog. Must not contain a search pattern. 657 | 2: optional TIdentifier catalogName 658 | 659 | // schema name or pattern 660 | 3: optional TPatternOrIdentifier schemaName 661 | } 662 | 663 | struct TGetSchemasResp { 664 | 1: required TStatus status 665 | 2: optional TOperationHandle operationHandle 666 | } 667 | 668 | 669 | // GetTables() 670 | // 671 | // Returns a list of tables with catalog, schema, and table 672 | // type information. The information is returned as a result 673 | // set which can be fetched using the OperationHandle 674 | // provided in the response. 675 | // Results are ordered by TABLE_TYPE, TABLE_CAT, TABLE_SCHEM, and TABLE_NAME 676 | // 677 | // Result Set Columns: 678 | // 679 | // col1 680 | // name: TABLE_CAT 681 | // type: STRING 682 | // desc: Catalog name. NULL if not applicable. 683 | // 684 | // col2 685 | // name: TABLE_SCHEM 686 | // type: STRING 687 | // desc: Schema name. 688 | // 689 | // col3 690 | // name: TABLE_NAME 691 | // type: STRING 692 | // desc: Table name. 693 | // 694 | // col4 695 | // name: TABLE_TYPE 696 | // type: STRING 697 | // desc: The table type, e.g. "TABLE", "VIEW", etc. 698 | // 699 | // col5 700 | // name: REMARKS 701 | // type: STRING 702 | // desc: Comments about the table 703 | // 704 | struct TGetTablesReq { 705 | // Session to run this request against 706 | 1: required TSessionHandle sessionHandle 707 | 708 | // Name of the catalog or a search pattern. 709 | 2: optional TPatternOrIdentifier catalogName 710 | 711 | // Name of the schema or a search pattern. 712 | 3: optional TPatternOrIdentifier schemaName 713 | 714 | // Name of the table or a search pattern. 715 | 4: optional TPatternOrIdentifier tableName 716 | 717 | // List of table types to match 718 | // e.g. "TABLE", "VIEW", "SYSTEM TABLE", "GLOBAL TEMPORARY", 719 | // "LOCAL TEMPORARY", "ALIAS", "SYNONYM", etc. 720 | 5: optional list tableTypes 721 | } 722 | 723 | struct TGetTablesResp { 724 | 1: required TStatus status 725 | 2: optional TOperationHandle operationHandle 726 | } 727 | 728 | 729 | // GetTableTypes() 730 | // 731 | // Returns the table types available in this database. 732 | // The results are ordered by table type. 733 | // 734 | // col1 735 | // name: TABLE_TYPE 736 | // type: STRING 737 | // desc: Table type name. 738 | struct TGetTableTypesReq { 739 | // Session to run this request against 740 | 1: required TSessionHandle sessionHandle 741 | } 742 | 743 | struct TGetTableTypesResp { 744 | 1: required TStatus status 745 | 2: optional TOperationHandle operationHandle 746 | } 747 | 748 | 749 | // GetColumns() 750 | // 751 | // Returns a list of columns in the specified tables. 752 | // The information is returned as a result set which can be fetched 753 | // using the OperationHandle provided in the response. 754 | // Results are ordered by TABLE_CAT, TABLE_SCHEM, TABLE_NAME, 755 | // and ORDINAL_POSITION. 756 | // 757 | // Result Set Columns are the same as those for the ODBC CLIColumns 758 | // function. 759 | // 760 | struct TGetColumnsReq { 761 | // Session to run this request against 762 | 1: required TSessionHandle sessionHandle 763 | 764 | // Name of the catalog. Must not contain a search pattern. 765 | 2: optional TIdentifier catalogName 766 | 767 | // Schema name or search pattern 768 | 3: optional TPatternOrIdentifier schemaName 769 | 770 | // Table name or search pattern 771 | 4: optional TPatternOrIdentifier tableName 772 | 773 | // Column name or search pattern 774 | 5: optional TPatternOrIdentifier columnName 775 | } 776 | 777 | struct TGetColumnsResp { 778 | 1: required TStatus status 779 | 2: optional TOperationHandle operationHandle 780 | } 781 | 782 | 783 | // GetFunctions() 784 | // 785 | // Returns a list of functions supported by the data source. The 786 | // behavior of this function matches 787 | // java.sql.DatabaseMetaData.getFunctions() both in terms of 788 | // inputs and outputs. 789 | // 790 | // Result Set Columns: 791 | // 792 | // col1 793 | // name: FUNCTION_CAT 794 | // type: STRING 795 | // desc: Function catalog (may be null) 796 | // 797 | // col2 798 | // name: FUNCTION_SCHEM 799 | // type: STRING 800 | // desc: Function schema (may be null) 801 | // 802 | // col3 803 | // name: FUNCTION_NAME 804 | // type: STRING 805 | // desc: Function name. This is the name used to invoke the function. 806 | // 807 | // col4 808 | // name: REMARKS 809 | // type: STRING 810 | // desc: Explanatory comment on the function. 811 | // 812 | // col5 813 | // name: FUNCTION_TYPE 814 | // type: SMALLINT 815 | // desc: Kind of function. One of: 816 | // * functionResultUnknown - Cannot determine if a return value or a table 817 | // will be returned. 818 | // * functionNoTable - Does not a return a table. 819 | // * functionReturnsTable - Returns a table. 820 | // 821 | // col6 822 | // name: SPECIFIC_NAME 823 | // type: STRING 824 | // desc: The name which uniquely identifies this function within its schema. 825 | // In this case this is the fully qualified class name of the class 826 | // that implements this function. 827 | // 828 | struct TGetFunctionsReq { 829 | // Session to run this request against 830 | 1: required TSessionHandle sessionHandle 831 | 832 | // A catalog name; must match the catalog name as it is stored in the 833 | // database; "" retrieves those without a catalog; null means 834 | // that the catalog name should not be used to narrow the search. 835 | 2: optional TIdentifier catalogName 836 | 837 | // A schema name pattern; must match the schema name as it is stored 838 | // in the database; "" retrieves those without a schema; null means 839 | // that the schema name should not be used to narrow the search. 840 | 3: optional TPatternOrIdentifier schemaName 841 | 842 | // A function name pattern; must match the function name as it is stored 843 | // in the database. 844 | 4: required TPatternOrIdentifier functionName 845 | } 846 | 847 | struct TGetFunctionsResp { 848 | 1: required TStatus status 849 | 2: optional TOperationHandle operationHandle 850 | } 851 | 852 | 853 | // GetOperationStatus() 854 | // 855 | // Get the status of an operation running on the server. 856 | struct TGetOperationStatusReq { 857 | // Session to run this request against 858 | 1: required TOperationHandle operationHandle 859 | } 860 | 861 | struct TGetOperationStatusResp { 862 | 1: required TStatus status 863 | 2: optional TOperationState operationState 864 | } 865 | 866 | 867 | // CancelOperation() 868 | // 869 | // Cancels processing on the specified operation handle and 870 | // frees any resources which were allocated. 871 | struct TCancelOperationReq { 872 | // Operation to cancel 873 | 1: required TOperationHandle operationHandle 874 | } 875 | 876 | struct TCancelOperationResp { 877 | 1: required TStatus status 878 | } 879 | 880 | 881 | // CloseOperation() 882 | // 883 | // Given an operation in the FINISHED, CANCELED, 884 | // or ERROR states, CloseOperation() will free 885 | // all of the resources which were allocated on 886 | // the server to service the operation. 887 | struct TCloseOperationReq { 888 | 1: required TOperationHandle operationHandle 889 | } 890 | 891 | struct TCloseOperationResp { 892 | 1: required TStatus status 893 | } 894 | 895 | 896 | // GetResultSetMetadata() 897 | // 898 | // Retrieves schema information for the specified operation 899 | struct TGetResultSetMetadataReq { 900 | // Operation for which to fetch result set schema information 901 | 1: required TOperationHandle operationHandle 902 | } 903 | 904 | struct TGetResultSetMetadataResp { 905 | 1: required TStatus status 906 | 2: optional TTableSchema schema 907 | } 908 | 909 | 910 | enum TFetchOrientation { 911 | // Get the next rowset. The fetch offset is ignored. 912 | FETCH_NEXT, 913 | 914 | // Get the previous rowset. The fetch offset is ignored. 915 | // NOT SUPPORTED 916 | FETCH_PRIOR, 917 | 918 | // Return the rowset at the given fetch offset relative 919 | // to the curren rowset. 920 | // NOT SUPPORTED 921 | FETCH_RELATIVE, 922 | 923 | // Return the rowset at the specified fetch offset. 924 | // NOT SUPPORTED 925 | FETCH_ABSOLUTE, 926 | 927 | // Get the first rowset in the result set. 928 | FETCH_FIRST, 929 | 930 | // Get the last rowset in the result set. 931 | // NOT SUPPORTED 932 | FETCH_LAST 933 | } 934 | 935 | // FetchResults() 936 | // 937 | // Fetch rows from the server corresponding to 938 | // a particular OperationHandle. 939 | struct TFetchResultsReq { 940 | // Operation from which to fetch results. 941 | 1: required TOperationHandle operationHandle 942 | 943 | // The fetch orientation. For V1 this must be either 944 | // FETCH_NEXT or FETCH_FIRST. Defaults to FETCH_NEXT. 945 | 2: required TFetchOrientation orientation = TFetchOrientation.FETCH_NEXT 946 | 947 | // Max number of rows that should be returned in 948 | // the rowset. 949 | 3: required i64 maxRows 950 | } 951 | 952 | struct TFetchResultsResp { 953 | 1: required TStatus status 954 | 955 | // TRUE if there are more rows left to fetch from the server. 956 | 2: optional bool hasMoreRows 957 | 958 | // The rowset. This is optional so that we have the 959 | // option in the future of adding alternate formats for 960 | // representing result set data, e.g. delimited strings, 961 | // binary encoded, etc. 962 | 3: optional TRowSet results 963 | } 964 | 965 | // GetLog() 966 | // 967 | // Fetch operation log from the server corresponding to 968 | // a particular OperationHandle. 969 | struct TGetLogReq { 970 | // Operation whose log is requested 971 | 1: required TOperationHandle operationHandle 972 | } 973 | 974 | struct TGetLogResp { 975 | 1: required TStatus status 976 | 977 | 2: required string log 978 | } 979 | 980 | service TCLIService { 981 | 982 | TOpenSessionResp OpenSession(1:TOpenSessionReq req); 983 | 984 | TCloseSessionResp CloseSession(1:TCloseSessionReq req); 985 | 986 | TGetInfoResp GetInfo(1:TGetInfoReq req); 987 | 988 | TExecuteStatementResp ExecuteStatement(1:TExecuteStatementReq req); 989 | 990 | TGetTypeInfoResp GetTypeInfo(1:TGetTypeInfoReq req); 991 | 992 | TGetCatalogsResp GetCatalogs(1:TGetCatalogsReq req); 993 | 994 | TGetSchemasResp GetSchemas(1:TGetSchemasReq req); 995 | 996 | TGetTablesResp GetTables(1:TGetTablesReq req); 997 | 998 | TGetTableTypesResp GetTableTypes(1:TGetTableTypesReq req); 999 | 1000 | TGetColumnsResp GetColumns(1:TGetColumnsReq req); 1001 | 1002 | TGetFunctionsResp GetFunctions(1:TGetFunctionsReq req); 1003 | 1004 | TGetOperationStatusResp GetOperationStatus(1:TGetOperationStatusReq req); 1005 | 1006 | TCancelOperationResp CancelOperation(1:TCancelOperationReq req); 1007 | 1008 | TCloseOperationResp CloseOperation(1:TCloseOperationReq req); 1009 | 1010 | TGetResultSetMetadataResp GetResultSetMetadata(1:TGetResultSetMetadataReq req); 1011 | 1012 | TFetchResultsResp FetchResults(1:TFetchResultsReq req); 1013 | 1014 | TGetLogResp GetLog(1:TGetLogReq req); 1015 | } 1016 | --------------------------------------------------------------------------------