Skip to content

Commit

Permalink
Fix for RM 42047, Issue EnterpriseDB#39
Browse files Browse the repository at this point in the history
Problem Statement:
The HDFS_FDW was inferring the authentication type
from the options of the CREATE USER MAPPING command
If it found that the username is empty, it concluded NOSASL
otherwise it concluded LDAP.
In case of NOSASL since the username was empty while
connecting to the hive server the FDW was specifying an
arbitrary username. While this technique worked for the rest
of the cases, it failed in case of ANALYZE.
ANALYZE needed an OS user that had write access to the
folder /tmp/hadoop-yarn

Solution:
Add another option in CREATE SERVER command, called the
auth_type. This option, which can be omitted, can have the
following values: NOSASL & LDAP
When specified a non empty username must be specified while
creating the user mapping.
When omitted the FDW tries to infer the auth_type from the options
of the user mapping, like it used to do.
Hence the FDW is backwards compatible and existing test cases
do not need any modification.

If auth_type is specified and a valid username is specified
that has write access to the folder /tmp/hadoop-yarn, then
ANALYZE works fine.

For Example:

postgres=# CREATE EXTENSION hdfs_fdw;
CREATE EXTENSION
postgres=# CREATE SERVER hdfs_svr FOREIGN DATA WRAPPER hdfs_fdw OPTIONS (host '127.0.0.1',port '10000',client_type 'hiveserver2', auth_type 'NOSASL');
CREATE SERVER
postgres=# CREATE USER MAPPING FOR abbasbutt server hdfs_svr OPTIONS (username 'abbasbutt', password '');
CREATE USER MAPPING
postgres=# CREATE FOREIGN TABLE fnt( a int, name varchar(255)) SERVER hdfs_svr OPTIONS (dbname 'testdb', table_name 'names_tab');
CREATE FOREIGN TABLE
postgres=# SELECT * FROM fnt;
 a | name
---+-------
 1 | abcd
 2 | pqrs
 3 | wxyz
 4 | a_b_c
 5 | p_q_r
   |
 1 | abcd
 2 | pqrs
 3 | wxyz
 4 | a_b_c
 5 | p_q_r
   |
(12 rows)

postgres=# ANALYZE fnt;
ANALYZE
  • Loading branch information
gabbasb committed Aug 22, 2017
1 parent 297ac13 commit 6a6dc6d
Show file tree
Hide file tree
Showing 6 changed files with 91 additions and 13 deletions.
1 change: 1 addition & 0 deletions hdfs_connection.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ hdfs_get_connection(ForeignServer *server, UserMapping *user, hdfs_opt *opt)
opt->password,
opt->connect_timeout,
opt->receive_timeout,
opt->auth_type,
&err_buf);
if (conn < 0)
ereport(ERROR,
Expand Down
1 change: 1 addition & 0 deletions hdfs_fdw.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ typedef struct hdfs_opt
char *dbname; /* HDFS database name */
char *table_name; /* HDFS table name */
CLIENT_TYPE client_type;
AUTH_TYPE auth_type;
bool use_remote_estimate;
int connect_timeout;
int receive_timeout;
Expand Down
19 changes: 19 additions & 0 deletions hdfs_option.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ static struct HDFSFdwOption valid_options[] =
{ "dbname", ForeignTableRelationId },
{ "table_name", ForeignTableRelationId },
{ "client_type", ForeignServerRelationId },
{ "auth_type", ForeignServerRelationId },
{ "use_remote_estimate", ForeignServerRelationId },
{ "query_timeout", ForeignServerRelationId },
{ "connect_timeout", ForeignServerRelationId },
Expand Down Expand Up @@ -183,6 +184,8 @@ hdfs_get_options(Oid foreigntableid)
/* Set default clinet type to HiverServer2 */
opt->client_type = HIVESERVER2;

opt->auth_type = AUTH_TYPE_UNSPECIFIED;

/* Loop through the options, and get the server/port */
foreach(lc, options)
{
Expand Down Expand Up @@ -221,6 +224,22 @@ hdfs_get_options(Oid foreigntableid)
errhint("Valid client_type is hiveserver2, this option will be deprecated soon")));
}

if (strcmp(def->defname, "auth_type") == 0)
{
if (strcasecmp(defGetString(def), "NOSASL") == 0)
opt->auth_type = AUTH_TYPE_NOSASL;
else
{
if (strcasecmp(defGetString(def), "LDAP") == 0)
opt->auth_type = AUTH_TYPE_LDAP;
else
ereport(ERROR,
(errcode(ERRCODE_FDW_INVALID_OPTION_NAME),
errmsg("invalid option \"%s\"", defGetString(def)),
errhint("Valid auth_type are NOSASL & LDAP")));
}
}

if (strcmp(def->defname, "use_remote_estimate") == 0)
opt->use_remote_estimate = defGetBoolean(def);

Expand Down
69 changes: 59 additions & 10 deletions libhive/jdbc/HiveJdbcClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@
public class HiveJdbcClient
{
private static String m_driverName = "org.apache.hive.jdbc.HiveDriver";

private static final int m_authTypeUnspecified = 0;
private static final int m_authTypeNoSasl = 1;
private static final int m_authTypeLDAP = 2;

private int m_queryTimeout = 0;
private boolean m_isDebug = false;
private int m_nestingLimit = 100;
Expand Down Expand Up @@ -72,11 +77,11 @@ public int FindFreeSlot()
return (-1);
}

/* singature will be (Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;IILMsgBuf;)I */
/* singature will be (Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;IIILMsgBuf;)I */
public int DBOpenConnection(String host, int port, String databaseName,
String userName, String password,
int connectTimeout, int receiveTimeout,
MsgBuf errBuf)
int authType, MsgBuf errBuf)
{
int index;
String hst;
Expand Down Expand Up @@ -165,14 +170,58 @@ public int DBOpenConnection(String host, int port, String databaseName,

try
{
if (userName == null || userName.equals(""))
switch (authType)
{
conURL += ";auth=noSasl";
m_hdfsConnection[index] = DriverManager.getConnection(conURL, "userName", "password");
}
else
{
m_hdfsConnection[index] = DriverManager.getConnection(conURL, userName, password);
case m_authTypeUnspecified:
if (userName == null || userName.equals(""))
{
conURL += ";auth=noSasl";
m_hdfsConnection[index] = DriverManager.getConnection(conURL, "userName", "password");
}
else
{
m_hdfsConnection[index] = DriverManager.getConnection(conURL, userName, password);
}
break;

case m_authTypeNoSasl:
conURL += ";auth=noSasl";
if (userName == null || userName.equals(""))
{
errBuf.catVal("ERROR : A valid user name is required");
m_isFree[index] = true;
return (-3);
}
else
{
m_hdfsConnection[index] = DriverManager.getConnection(conURL, userName, password);
}
break;

case m_authTypeLDAP:
if (userName == null || userName.equals(""))
{
errBuf.catVal("ERROR : A valid user name is required");
m_isFree[index] = true;
return (-4);
}
else
{
m_hdfsConnection[index] = DriverManager.getConnection(conURL, userName, password);
}
break;

default:
if (userName == null || userName.equals(""))
{
conURL += ";auth=noSasl";
m_hdfsConnection[index] = DriverManager.getConnection(conURL, "userName", "password");
}
else
{
m_hdfsConnection[index] = DriverManager.getConnection(conURL, userName, password);
}
break;
}
}
catch (SQLException ex)
Expand All @@ -183,7 +232,7 @@ public int DBOpenConnection(String host, int port, String databaseName,
errBuf.catVal(DriverManager.getLoginTimeout());
errBuf.catVal(" seconds");
m_isFree[index] = true;
return (-3);
return (-5);
}

m_host[index].resetVal();
Expand Down
5 changes: 3 additions & 2 deletions libhive/jdbc/hiveclient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ int Initialize()
}

g_DBOpenConnection = g_jni->GetMethodID(g_clsJdbcClient, "DBOpenConnection",
"(Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;IILMsgBuf;)I");
"(Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;IIILMsgBuf;)I");
if (g_DBOpenConnection == NULL)
{
g_jvm->DestroyJavaVM();
Expand Down Expand Up @@ -255,7 +255,7 @@ int Destroy()
int DBOpenConnection(char *host, int port, char *databaseName,
char *username, char *password,
int connectTimeout, int receiveTimeout,
char **errBuf)
AUTH_TYPE auth_type, char **errBuf)
{
int rc;
jstring rv;
Expand All @@ -276,6 +276,7 @@ int DBOpenConnection(char *host, int port, char *databaseName,
g_jni->NewStringUTF(password),
connectTimeout,
receiveTimeout,
auth_type,
g_objMsgBuf);

rv = (jstring)g_jni->CallObjectMethod(g_objMsgBuf, g_getVal);
Expand Down
9 changes: 8 additions & 1 deletion libhive/jdbc/hiveclient.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,13 @@ typedef enum HIVE_SERVER_TYPE {
HIVE_SERVER2 = 1
} HIVE_SERVER_TYPE;

typedef enum AUTH_TYPE
{
AUTH_TYPE_UNSPECIFIED = 0,
AUTH_TYPE_NOSASL,
AUTH_TYPE_LDAP
} AUTH_TYPE;

/******************************************************************************
* Global Hive Client Functions (usable as C callback functions)
*****************************************************************************/
Expand Down Expand Up @@ -85,7 +92,7 @@ int Destroy(void);
int DBOpenConnection(char *host, int port, char *databaseName,
char *username, char *password,
int connectTimeout, int receiveTimeout,
char **errBuf);
AUTH_TYPE auth_type, char **errBuf);

/**
* @brief Disconnect from a Hive database.
Expand Down

0 comments on commit 6a6dc6d

Please sign in to comment.