Skip to content

Commit 6a6dc6d

Browse files
committed
Fix for RM 42047, Issue EnterpriseDB#39
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
1 parent 297ac13 commit 6a6dc6d

File tree

6 files changed

+91
-13
lines changed

6 files changed

+91
-13
lines changed

Diff for: hdfs_connection.c

+1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ hdfs_get_connection(ForeignServer *server, UserMapping *user, hdfs_opt *opt)
3737
opt->password,
3838
opt->connect_timeout,
3939
opt->receive_timeout,
40+
opt->auth_type,
4041
&err_buf);
4142
if (conn < 0)
4243
ereport(ERROR,

Diff for: hdfs_fdw.h

+1
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ typedef struct hdfs_opt
7171
char *dbname; /* HDFS database name */
7272
char *table_name; /* HDFS table name */
7373
CLIENT_TYPE client_type;
74+
AUTH_TYPE auth_type;
7475
bool use_remote_estimate;
7576
int connect_timeout;
7677
int receive_timeout;

Diff for: hdfs_option.c

+19
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ static struct HDFSFdwOption valid_options[] =
7070
{ "dbname", ForeignTableRelationId },
7171
{ "table_name", ForeignTableRelationId },
7272
{ "client_type", ForeignServerRelationId },
73+
{ "auth_type", ForeignServerRelationId },
7374
{ "use_remote_estimate", ForeignServerRelationId },
7475
{ "query_timeout", ForeignServerRelationId },
7576
{ "connect_timeout", ForeignServerRelationId },
@@ -183,6 +184,8 @@ hdfs_get_options(Oid foreigntableid)
183184
/* Set default clinet type to HiverServer2 */
184185
opt->client_type = HIVESERVER2;
185186

187+
opt->auth_type = AUTH_TYPE_UNSPECIFIED;
188+
186189
/* Loop through the options, and get the server/port */
187190
foreach(lc, options)
188191
{
@@ -221,6 +224,22 @@ hdfs_get_options(Oid foreigntableid)
221224
errhint("Valid client_type is hiveserver2, this option will be deprecated soon")));
222225
}
223226

227+
if (strcmp(def->defname, "auth_type") == 0)
228+
{
229+
if (strcasecmp(defGetString(def), "NOSASL") == 0)
230+
opt->auth_type = AUTH_TYPE_NOSASL;
231+
else
232+
{
233+
if (strcasecmp(defGetString(def), "LDAP") == 0)
234+
opt->auth_type = AUTH_TYPE_LDAP;
235+
else
236+
ereport(ERROR,
237+
(errcode(ERRCODE_FDW_INVALID_OPTION_NAME),
238+
errmsg("invalid option \"%s\"", defGetString(def)),
239+
errhint("Valid auth_type are NOSASL & LDAP")));
240+
}
241+
}
242+
224243
if (strcmp(def->defname, "use_remote_estimate") == 0)
225244
opt->use_remote_estimate = defGetBoolean(def);
226245

Diff for: libhive/jdbc/HiveJdbcClient.java

+59-10
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,11 @@
3434
public class HiveJdbcClient
3535
{
3636
private static String m_driverName = "org.apache.hive.jdbc.HiveDriver";
37+
38+
private static final int m_authTypeUnspecified = 0;
39+
private static final int m_authTypeNoSasl = 1;
40+
private static final int m_authTypeLDAP = 2;
41+
3742
private int m_queryTimeout = 0;
3843
private boolean m_isDebug = false;
3944
private int m_nestingLimit = 100;
@@ -72,11 +77,11 @@ public int FindFreeSlot()
7277
return (-1);
7378
}
7479

75-
/* singature will be (Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;IILMsgBuf;)I */
80+
/* singature will be (Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;IIILMsgBuf;)I */
7681
public int DBOpenConnection(String host, int port, String databaseName,
7782
String userName, String password,
7883
int connectTimeout, int receiveTimeout,
79-
MsgBuf errBuf)
84+
int authType, MsgBuf errBuf)
8085
{
8186
int index;
8287
String hst;
@@ -165,14 +170,58 @@ public int DBOpenConnection(String host, int port, String databaseName,
165170

166171
try
167172
{
168-
if (userName == null || userName.equals(""))
173+
switch (authType)
169174
{
170-
conURL += ";auth=noSasl";
171-
m_hdfsConnection[index] = DriverManager.getConnection(conURL, "userName", "password");
172-
}
173-
else
174-
{
175-
m_hdfsConnection[index] = DriverManager.getConnection(conURL, userName, password);
175+
case m_authTypeUnspecified:
176+
if (userName == null || userName.equals(""))
177+
{
178+
conURL += ";auth=noSasl";
179+
m_hdfsConnection[index] = DriverManager.getConnection(conURL, "userName", "password");
180+
}
181+
else
182+
{
183+
m_hdfsConnection[index] = DriverManager.getConnection(conURL, userName, password);
184+
}
185+
break;
186+
187+
case m_authTypeNoSasl:
188+
conURL += ";auth=noSasl";
189+
if (userName == null || userName.equals(""))
190+
{
191+
errBuf.catVal("ERROR : A valid user name is required");
192+
m_isFree[index] = true;
193+
return (-3);
194+
}
195+
else
196+
{
197+
m_hdfsConnection[index] = DriverManager.getConnection(conURL, userName, password);
198+
}
199+
break;
200+
201+
case m_authTypeLDAP:
202+
if (userName == null || userName.equals(""))
203+
{
204+
errBuf.catVal("ERROR : A valid user name is required");
205+
m_isFree[index] = true;
206+
return (-4);
207+
}
208+
else
209+
{
210+
m_hdfsConnection[index] = DriverManager.getConnection(conURL, userName, password);
211+
}
212+
break;
213+
214+
default:
215+
if (userName == null || userName.equals(""))
216+
{
217+
conURL += ";auth=noSasl";
218+
m_hdfsConnection[index] = DriverManager.getConnection(conURL, "userName", "password");
219+
}
220+
else
221+
{
222+
m_hdfsConnection[index] = DriverManager.getConnection(conURL, userName, password);
223+
}
224+
break;
176225
}
177226
}
178227
catch (SQLException ex)
@@ -183,7 +232,7 @@ public int DBOpenConnection(String host, int port, String databaseName,
183232
errBuf.catVal(DriverManager.getLoginTimeout());
184233
errBuf.catVal(" seconds");
185234
m_isFree[index] = true;
186-
return (-3);
235+
return (-5);
187236
}
188237

189238
m_host[index].resetVal();

Diff for: libhive/jdbc/hiveclient.cpp

+3-2
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ int Initialize()
169169
}
170170

171171
g_DBOpenConnection = g_jni->GetMethodID(g_clsJdbcClient, "DBOpenConnection",
172-
"(Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;IILMsgBuf;)I");
172+
"(Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;IIILMsgBuf;)I");
173173
if (g_DBOpenConnection == NULL)
174174
{
175175
g_jvm->DestroyJavaVM();
@@ -255,7 +255,7 @@ int Destroy()
255255
int DBOpenConnection(char *host, int port, char *databaseName,
256256
char *username, char *password,
257257
int connectTimeout, int receiveTimeout,
258-
char **errBuf)
258+
AUTH_TYPE auth_type, char **errBuf)
259259
{
260260
int rc;
261261
jstring rv;
@@ -276,6 +276,7 @@ int DBOpenConnection(char *host, int port, char *databaseName,
276276
g_jni->NewStringUTF(password),
277277
connectTimeout,
278278
receiveTimeout,
279+
auth_type,
279280
g_objMsgBuf);
280281

281282
rv = (jstring)g_jni->CallObjectMethod(g_objMsgBuf, g_getVal);

Diff for: libhive/jdbc/hiveclient.h

+8-1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,13 @@ typedef enum HIVE_SERVER_TYPE {
3838
HIVE_SERVER2 = 1
3939
} HIVE_SERVER_TYPE;
4040

41+
typedef enum AUTH_TYPE
42+
{
43+
AUTH_TYPE_UNSPECIFIED = 0,
44+
AUTH_TYPE_NOSASL,
45+
AUTH_TYPE_LDAP
46+
} AUTH_TYPE;
47+
4148
/******************************************************************************
4249
* Global Hive Client Functions (usable as C callback functions)
4350
*****************************************************************************/
@@ -85,7 +92,7 @@ int Destroy(void);
8592
int DBOpenConnection(char *host, int port, char *databaseName,
8693
char *username, char *password,
8794
int connectTimeout, int receiveTimeout,
88-
char **errBuf);
95+
AUTH_TYPE auth_type, char **errBuf);
8996

9097
/**
9198
* @brief Disconnect from a Hive database.

0 commit comments

Comments
 (0)