summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOlivier Bertrand <bertrandop@gmail.com>2018-03-14 11:31:28 +0100
committerOlivier Bertrand <bertrandop@gmail.com>2018-03-14 11:31:28 +0100
commita0f47c39b7a706ad8fc4770af87ac7187aaf3ffd (patch)
treed7a3af1f3c25404973490ace4b5118ee4b87d937
parentc195e05132466fb017730d6b19c46681b33a6909 (diff)
parent46defc4373832dfad3b2676df8b90fd4f15eeb24 (diff)
downloadmariadb-git-a0f47c39b7a706ad8fc4770af87ac7187aaf3ffd.tar.gz
Merge branch 'ob-10.1' into 10.1
-rw-r--r--storage/connect/Client.java27
-rw-r--r--storage/connect/JavaWrappers.jarbin44053 -> 19192 bytes
-rw-r--r--storage/connect/JdbcInterface.java54
-rw-r--r--storage/connect/PostgresqlInterface.java5
-rw-r--r--storage/connect/global.h6
-rw-r--r--storage/connect/ha_connect.cc21
-rw-r--r--storage/connect/jdbconn.cpp339
-rw-r--r--storage/connect/jdbconn.h11
-rw-r--r--storage/connect/mysql-test/connect/r/jdbc_postgresql.result35
-rw-r--r--storage/connect/mysql-test/connect/std_data/JavaWrappers.jarbin0 -> 19192 bytes
-rw-r--r--storage/connect/mysql-test/connect/t/jdbc_postgresql.test33
-rw-r--r--storage/connect/mysql-test/connect/t/jdbconn.inc7
-rw-r--r--storage/connect/plgdbsem.h3
-rw-r--r--storage/connect/tabjdbc.cpp11
-rw-r--r--storage/connect/tabjdbc.h2
15 files changed, 383 insertions, 171 deletions
diff --git a/storage/connect/Client.java b/storage/connect/Client.java
index aaf1b7bf2f8..afa54fa4256 100644
--- a/storage/connect/Client.java
+++ b/storage/connect/Client.java
@@ -1,9 +1,13 @@
+
package wrappers;
import java.io.BufferedReader;
import java.io.Console;
import java.io.IOException;
import java.io.InputStreamReader;
+import java.sql.Date;
+import java.sql.Time;
+import java.sql.Timestamp;
public class Client {
static boolean DEBUG = true;
@@ -58,6 +62,9 @@ public class Client {
String query;
System.out.println("Successfully connected to " + parms[1]);
+ s = jdi.GetQuoteString();
+ System.out.println("Qstr = '" + s + "'");
+
while ((query = getLine("Query: ", false)) != null) {
n = jdi.Execute(query);
System.out.println("Returned n = " + n);
@@ -79,7 +86,11 @@ public class Client {
private static void PrintResult(int ncol) {
// Get result set meta data
int i;
+ Date date = new Date(0);
+ Time time = new Time(0);
+ Timestamp tsp = new Timestamp(0);
String columnName;
+ Object job;
// Get the column names; column indices start from 1
for (i = 1; i <= ncol; i++) {
@@ -112,6 +123,7 @@ public class Client {
case java.sql.Types.VARCHAR:
case java.sql.Types.LONGVARCHAR:
case java.sql.Types.CHAR:
+ case 1111:
System.out.print(jdi.StringField(i, null));
break;
case java.sql.Types.INTEGER:
@@ -120,14 +132,17 @@ public class Client {
case java.sql.Types.BIGINT:
System.out.print(jdi.BigintField(i, null));
break;
- case java.sql.Types.TIMESTAMP:
- System.out.print(jdi.TimestampField(i, null));
- break;
case java.sql.Types.TIME:
- System.out.print(jdi.TimeField(i, null));
+ time.setTime((long)jdi.TimeField(i, null) * 1000);
+ System.out.print(time);
break;
case java.sql.Types.DATE:
- System.out.print(jdi.DateField(i, null));
+ date.setTime((long)jdi.DateField(i, null) * 1000);
+ System.out.print(date);
+ break;
+ case java.sql.Types.TIMESTAMP:
+ tsp.setTime((long)jdi.TimestampField(i, null) * 1000);
+ System.out.print(tsp);
break;
case java.sql.Types.SMALLINT:
System.out.print(jdi.IntField(i, null));
@@ -141,6 +156,8 @@ public class Client {
case java.sql.Types.BOOLEAN:
System.out.print(jdi.BooleanField(i, null));
default:
+ job = jdi.ObjectField(i, null);
+ System.out.print(job.toString());
break;
} // endswitch Type
diff --git a/storage/connect/JavaWrappers.jar b/storage/connect/JavaWrappers.jar
index ef407f6a9c2..33b29e7685b 100644
--- a/storage/connect/JavaWrappers.jar
+++ b/storage/connect/JavaWrappers.jar
Binary files differ
diff --git a/storage/connect/JdbcInterface.java b/storage/connect/JdbcInterface.java
index a1b1360e6ea..72ee4ab0d39 100644
--- a/storage/connect/JdbcInterface.java
+++ b/storage/connect/JdbcInterface.java
@@ -1,10 +1,22 @@
package wrappers;
-import java.math.*;
-import java.sql.*;
+import java.math.BigDecimal;
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.Date;
+import java.sql.Driver;
+import java.sql.DriverManager;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.sql.Time;
+import java.sql.Timestamp;
import java.util.Collections;
import java.util.Hashtable;
import java.util.List;
+import java.util.UUID;
import javax.sql.DataSource;
@@ -223,6 +235,24 @@ public class JdbcInterface {
} // end of SetTimestampParm
+ public void SetUuidParm(int i, String s) {
+ try {
+ UUID uuid;
+
+ if (s == null)
+ uuid = null;
+ else if (s.isEmpty())
+ uuid = UUID.randomUUID();
+ else
+ uuid = UUID.fromString(s);
+
+ pstmt.setObject(i, uuid);
+ } catch (Exception e) {
+ SetErrmsg(e);
+ } // end try/catch
+
+ } // end of SetUuidParm
+
public int SetNullParm(int i, int typ) {
int rc = 0;
@@ -481,6 +511,8 @@ public class JdbcInterface {
System.out.println("Executing query '" + query + "'");
try {
+ if (rs != null)
+ rs.close();
rs = stmt.executeQuery(query);
rsmd = rs.getMetaData();
ncol = rsmd.getColumnCount();
@@ -708,7 +740,7 @@ public class JdbcInterface {
return 0;
} // end of TimestampField
- public Object ObjectField(int n, String name) {
+ public Object ObjectField(int n, String name) {
if (rs == null) {
System.out.println("No result set");
} else try {
@@ -720,6 +752,22 @@ public class JdbcInterface {
return null;
} // end of ObjectField
+ public String UuidField(int n, String name) {
+ Object job;
+
+ if (rs == null) {
+ System.out.println("No result set");
+ } else
+ try {
+ job = (n > 0) ? rs.getObject(n) : rs.getObject(name);
+ return job.toString();
+ } catch (SQLException se) {
+ SetErrmsg(se);
+ } // end try/catch
+
+ return null;
+ } // end of UuidField
+
public int GetDrivers(String[] s, int mxs) {
int n = 0;
List<Driver> drivers = Collections.list(DriverManager.getDrivers());
diff --git a/storage/connect/PostgresqlInterface.java b/storage/connect/PostgresqlInterface.java
index adce0616a1b..9f611eeb23b 100644
--- a/storage/connect/PostgresqlInterface.java
+++ b/storage/connect/PostgresqlInterface.java
@@ -1,9 +1,10 @@
package wrappers;
-import java.sql.*;
+import java.sql.SQLException;
import java.util.Hashtable;
import javax.sql.DataSource;
+
import org.postgresql.jdbc2.optional.PoolingDataSource;
public class PostgresqlInterface extends JdbcInterface {
@@ -19,7 +20,7 @@ public class PostgresqlInterface extends JdbcInterface {
} // end of constructor
- @Override
+ @Override
public int JdbcConnect(String[] parms, int fsize, boolean scrollable) {
int rc = 0;
String url = parms[1];
diff --git a/storage/connect/global.h b/storage/connect/global.h
index d8d03f606ba..472d09408c3 100644
--- a/storage/connect/global.h
+++ b/storage/connect/global.h
@@ -220,7 +220,6 @@ DllExport BOOL PlugIsAbsolutePath(LPCSTR path);
DllExport bool AllocSarea(PGLOBAL, uint);
DllExport void FreeSarea(PGLOBAL);
DllExport BOOL PlugSubSet(PGLOBAL, void *, uint);
- void *PlugSubAlloc(PGLOBAL, void *, size_t); // Does throw
DllExport char *PlugDup(PGLOBAL g, const char *str);
DllExport void *MakePtr(void *, OFFSET);
DllExport void htrc(char const *fmt, ...);
@@ -231,4 +230,9 @@ DllExport uint GetTraceValue(void);
} // extern "C"
#endif
+/***********************************************************************/
+/* Non exported routine declarations. */
+/***********************************************************************/
+void *PlugSubAlloc(PGLOBAL, void *, size_t); // Does throw
+
/*-------------------------- End of Global.H --------------------------*/
diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc
index 2efed93ee2a..c878bf2a7de 100644
--- a/storage/connect/ha_connect.cc
+++ b/storage/connect/ha_connect.cc
@@ -174,9 +174,9 @@
#define JSONMAX 10 // JSON Default max grp size
extern "C" {
- char version[]= "Version 1.06.0006 February 02, 2018";
+ char version[]= "Version 1.06.0007 March 11, 2018";
#if defined(__WIN__)
- char compver[]= "Version 1.06.0006 " __DATE__ " " __TIME__;
+ char compver[]= "Version 1.06.0007 " __DATE__ " " __TIME__;
char slash= '\\';
#else // !__WIN__
char slash= '/';
@@ -288,11 +288,16 @@ static MYSQL_THDVAR_SET(
0, // def (NO)
&xtrace_typelib); // typelib
- // Getting exact info values
+// Getting exact info values
static MYSQL_THDVAR_BOOL(exact_info, PLUGIN_VAR_RQCMDARG,
"Getting exact info values",
NULL, NULL, 0);
+// Enabling cond_push
+static MYSQL_THDVAR_BOOL(cond_push, PLUGIN_VAR_RQCMDARG,
+ "Enabling cond_push",
+ NULL, NULL, 1); // YES by default
+
/**
Temporary file usage:
no: Not using temporary file
@@ -427,6 +432,7 @@ handlerton *connect_hton= NULL;
uint GetTraceValue(void)
{return (uint)(connect_hton ? THDVAR(current_thd, xtrace) : 0);}
bool ExactInfo(void) {return THDVAR(current_thd, exact_info);}
+bool CondPushEnabled(void) {return THDVAR(current_thd, cond_push);}
USETEMP UseTemp(void) {return (USETEMP)THDVAR(current_thd, use_tempfile);}
int GetConvSize(void) {return THDVAR(current_thd, conv_size);}
TYPCONV GetTypeConv(void) {return (TYPCONV)THDVAR(current_thd, type_conv);}
@@ -3196,7 +3202,7 @@ const COND *ha_connect::cond_push(const COND *cond)
{
DBUG_ENTER("ha_connect::cond_push");
- if (tdbp) {
+ if (tdbp && CondPushEnabled()) {
PGLOBAL& g= xp->g;
AMT tty= tdbp->GetAmType();
bool x= (tty == TYPE_AM_MYX || tty == TYPE_AM_XDBC);
@@ -7243,7 +7249,8 @@ static struct st_mysql_sys_var* connect_system_variables[]= {
#if defined(JAVA_SUPPORT) || defined(CMGO_SUPPORT)
MYSQL_SYSVAR(enable_mongo),
#endif // JAVA_SUPPORT || CMGO_SUPPORT
-NULL
+ MYSQL_SYSVAR(cond_push),
+ NULL
};
maria_declare_plugin(connect)
@@ -7256,10 +7263,10 @@ maria_declare_plugin(connect)
PLUGIN_LICENSE_GPL,
connect_init_func, /* Plugin Init */
connect_done_func, /* Plugin Deinit */
- 0x0106, /* version number (1.05) */
+ 0x0107, /* version number (1.05) */
NULL, /* status variables */
connect_system_variables, /* system variables */
- "1.06.0006", /* string version */
+ "1.06.0007", /* string version */
MariaDB_PLUGIN_MATURITY_STABLE /* maturity */
}
maria_declare_plugin_end;
diff --git a/storage/connect/jdbconn.cpp b/storage/connect/jdbconn.cpp
index ff84c75b67f..33414ca74c2 100644
--- a/storage/connect/jdbconn.cpp
+++ b/storage/connect/jdbconn.cpp
@@ -1,7 +1,7 @@
/************ Jdbconn C++ Functions Source Code File (.CPP) ************/
-/* Name: JDBCONN.CPP Version 1.1 */
+/* Name: JDBCONN.CPP Version 1.2 */
/* */
-/* (C) Copyright to the author Olivier BERTRAND 2016-2017 */
+/* (C) Copyright to the author Olivier BERTRAND 2016-2018 */
/* */
/* This file contains the JDBC connection classes functions. */
/***********************************************************************/
@@ -116,10 +116,26 @@ int TranslateJDBCType(int stp, char *tn, int prec, int& len, char& v)
return TYPE_ERROR;
else
len = MY_MIN(abs(len), GetConvSize());
+
// Pass through
case 12: // VARCHAR
+ if (tn && !stricmp(tn, "TEXT"))
+ // Postgresql returns 12 for TEXT
+ if (GetTypeConv() == TPC_NO)
+ return TYPE_ERROR;
+
+ // Postgresql can return this
+ if (len == 0x7FFFFFFF)
+ len = GetConvSize();
+
+ // Pass through
case -9: // NVARCHAR (unicode)
+ // Postgresql can return this when size is unknown
+ if (len == 0x7FFFFFFF)
+ len = GetConvSize();
+
v = 'V';
+ // Pass through
case 1: // CHAR
case -15: // NCHAR (unicode)
case -8: // ROWID
@@ -171,6 +187,14 @@ int TranslateJDBCType(int stp, char *tn, int prec, int& len, char& v)
case -5: // BIGINT
type = TYPE_BIGINT;
break;
+ case 1111: // UNKNOWN or UUID
+ if (!tn || !stricmp(tn, "UUID")) {
+ type = TYPE_STRING;
+ len = 36;
+ break;
+ } // endif tn
+
+ // Pass through
case 0: // NULL
case -2: // BINARY
case -4: // LONGVARBINARY
@@ -192,6 +216,104 @@ int TranslateJDBCType(int stp, char *tn, int prec, int& len, char& v)
return type;
} // end of TranslateJDBCType
+ /***********************************************************************/
+ /* A helper class to split an optionally qualified table name into */
+ /* components. */
+ /* These formats are understood: */
+ /* "CatalogName.SchemaName.TableName" */
+ /* "SchemaName.TableName" */
+ /* "TableName" */
+ /***********************************************************************/
+class SQLQualifiedName {
+ static const uint max_parts = 3; // Catalog.Schema.Table
+ MYSQL_LEX_STRING m_part[max_parts];
+ char m_buf[512];
+
+ void lex_string_set(MYSQL_LEX_STRING *S, char *str, size_t length)
+ {
+ S->str = str;
+ S->length = length;
+ } // end of lex_string_set
+
+ void lex_string_shorten_down(MYSQL_LEX_STRING *S, size_t offs)
+ {
+ DBUG_ASSERT(offs <= S->length);
+ S->str += offs;
+ S->length -= offs;
+ } // end of lex_string_shorten_down
+
+ /*********************************************************************/
+ /* Find the rightmost '.' delimiter and return the length */
+ /* of the qualifier, including the rightmost '.' delimier. */
+ /* For example, for the string {"a.b.c",5} it will return 4, */
+ /* which is the length of the qualifier "a.b." */
+ /*********************************************************************/
+ size_t lex_string_find_qualifier(MYSQL_LEX_STRING *S)
+ {
+ size_t i;
+ for (i = S->length; i > 0; i--)
+ {
+ if (S->str[i - 1] == '.')
+ {
+ S->str[i - 1] = '\0';
+ return i;
+ }
+ }
+ return 0;
+ } // end of lex_string_find_qualifier
+
+public:
+ /*********************************************************************/
+ /* Initialize to the given optionally qualified name. */
+ /* NULL pointer in "name" is supported. */
+ /* name qualifier has precedence over schema. */
+ /*********************************************************************/
+ SQLQualifiedName(JCATPARM *cap)
+ {
+ const char *name = (const char *)cap->Tab;
+ char *db = (char *)cap->DB;
+ size_t len, i;
+
+ // Initialize the parts
+ for (i = 0; i < max_parts; i++)
+ lex_string_set(&m_part[i], NULL, 0);
+
+ if (name) {
+ // Initialize the first (rightmost) part
+ lex_string_set(&m_part[0], m_buf,
+ strmake(m_buf, name, sizeof(m_buf) - 1) - m_buf);
+
+ // Initialize the other parts, if exist.
+ for (i = 1; i < max_parts; i++) {
+ if (!(len = lex_string_find_qualifier(&m_part[i - 1])))
+ break;
+
+ lex_string_set(&m_part[i], m_part[i - 1].str, len - 1);
+ lex_string_shorten_down(&m_part[i - 1], len);
+ } // endfor i
+
+ } // endif name
+
+ // If it was not specified, set schema as the passed db name
+ if (db && !m_part[1].length)
+ lex_string_set(&m_part[1], db, strlen(db));
+
+ } // end of SQLQualifiedName
+
+ char *ptr(uint i)
+ {
+ DBUG_ASSERT(i < max_parts);
+ return (char *)(m_part[i].length ? m_part[i].str : NULL);
+ } // end of ptr
+
+ size_t length(uint i)
+ {
+ DBUG_ASSERT(i < max_parts);
+ return m_part[i].length;
+ } // end of length
+
+}; // end of class SQLQualifiedName
+
/***********************************************************************/
/* Allocate the structure used to refer to the result set. */
/***********************************************************************/
@@ -519,7 +641,7 @@ JDBConn::JDBConn(PGLOBAL g, PCSZ wrapper) : JAVAConn(g, wrapper)
xqid = xuid = xid = grs = readid = fetchid = typid = errid = nullptr;
prepid = xpid = pcid = nullptr;
chrfldid = intfldid = dblfldid = fltfldid = bigfldid = nullptr;
- objfldid = datfldid = timfldid = tspfldid = nullptr;
+ objfldid = datfldid = timfldid = tspfldid = uidfldid = nullptr;
DiscFunc = "JdbcDisconnect";
m_Ncol = 0;
m_Aff = 0;
@@ -535,12 +657,84 @@ JDBConn::JDBConn(PGLOBAL g, PCSZ wrapper) : JAVAConn(g, wrapper)
m_IDQuoteChar[1] = 0;
} // end of JDBConn
-//JDBConn::~JDBConn()
-// {
-//if (Connected())
-// EndCom();
+/***********************************************************************/
+/* Search for UUID columns. */
+/***********************************************************************/
+bool JDBConn::SetUUID(PGLOBAL g, PTDBJDBC tjp)
+{
+ int ncol, ctyp;
+ bool brc = true;
+ PCSZ fnc = "GetColumns";
+ PCOL colp;
+ JCATPARM *cap;
+ //jint jtyp;
+ jboolean rc = false;
+ jobjectArray parms;
+ jmethodID catid = nullptr;
+
+ if (gmID(g, catid, fnc, "([Ljava/lang/String;)I"))
+ return true;
+ else if (gmID(g, intfldid, "IntField", "(ILjava/lang/String;)I"))
+ return true;
+ else if (gmID(g, readid, "ReadNext", "()I"))
+ return true;
+
+ cap = AllocCatInfo(g, JCAT_COL, tjp->Schema, tjp->TableName, NULL);
+ SQLQualifiedName name(cap);
+
+ // Build the java string array
+ parms = env->NewObjectArray(4, env->FindClass("java/lang/String"), NULL);
+ env->SetObjectArrayElement(parms, 0, env->NewStringUTF(name.ptr(2)));
+ env->SetObjectArrayElement(parms, 1, env->NewStringUTF(name.ptr(1)));
+ env->SetObjectArrayElement(parms, 2, env->NewStringUTF(name.ptr(0)));
+
+ for (colp = tjp->GetColumns(); colp; colp = colp->GetNext()) {
+ env->SetObjectArrayElement(parms, 3, env->NewStringUTF(colp->GetName()));
+ ncol = env->CallIntMethod(job, catid, parms);
+
+ if (Check(ncol)) {
+ sprintf(g->Message, "%s: %s", fnc, Msg);
+ goto err;
+ } // endif Check
+
+ rc = env->CallBooleanMethod(job, readid);
+
+ if (Check(rc)) {
+ sprintf(g->Message, "ReadNext: %s", Msg);
+ goto err;
+ } else if (rc == 0) {
+ sprintf(g->Message, "table %s does not exist", tjp->TableName);
+ goto err;
+ } // endif rc
+
+ // Returns 666 is case of error
+ //jtyp = env->CallIntMethod(job, typid, 5, nullptr);
+
+ //if (Check((jtyp == 666) ? -1 : 1)) {
+ // sprintf(g->Message, "Getting jtyp: %s", Msg);
+ // goto err;
+ //} // endif ctyp
+
+ ctyp = (int)env->CallIntMethod(job, intfldid, 5, nullptr);
+
+ if (Check(ctyp)) {
+ sprintf(g->Message, "Getting ctyp: %s", Msg);
+ goto err;
+ } // endif ctyp
+
+ if (ctyp == 1111)
+ ((PJDBCCOL)colp)->uuid = true;
+
+ } // endfor colp
+
+ // All is Ok
+ brc = false;
-// } // end of ~JDBConn
+ err:
+ // Not used anymore
+ env->DeleteLocalRef(parms);
+ return brc;
+} // end of SetUUID
/***********************************************************************/
/* Utility routine. */
@@ -770,6 +964,7 @@ int JDBConn::Rewind(PCSZ sql)
/***********************************************************************/
void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val)
{
+ const char *field;
PGLOBAL& g = m_G;
jint ctyp;
jstring cn, jn = nullptr;
@@ -793,6 +988,11 @@ void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val)
if (!gmID(g, objfldid, "ObjectField", "(ILjava/lang/String;)Ljava/lang/Object;")) {
jb = env->CallObjectMethod(job, objfldid, (jint)rank, jn);
+ if (Check(0)) {
+ sprintf(g->Message, "Getting jp: %s", Msg);
+ throw (int)TYPE_AM_JDBC;
+ } // endif Check
+
if (jb == nullptr) {
val->Reset();
val->SetNull(true);
@@ -818,7 +1018,7 @@ void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val)
cn = nullptr;
if (cn) {
- const char *field = env->GetStringUTFChars(cn, (jboolean)false);
+ field = env->GetStringUTFChars(cn, (jboolean)false);
val->SetValue_psz((PSZ)field);
} else
val->Reset();
@@ -885,6 +1085,19 @@ void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val)
break;
case java.sql.Types.BOOLEAN:
System.out.print(jdi.BooleanField(i)); */
+ case 1111: // UUID
+ if (!gmID(g, uidfldid, "UuidField", "(ILjava/lang/String;)Ljava/lang/String;"))
+ cn = (jstring)env->CallObjectMethod(job, uidfldid, (jint)rank, jn);
+ else
+ cn = nullptr;
+
+ if (cn) {
+ const char *field = env->GetStringUTFChars(cn, (jboolean)false);
+ val->SetValue_psz((PSZ)field);
+ } else
+ val->Reset();
+
+ break;
case 0: // NULL
val->SetNull(true);
// passthru
@@ -1055,7 +1268,14 @@ bool JDBConn::SetParam(JDBCCOL *colp)
if (gmID(g, setid, "SetNullParm", "(II)I"))
return true;
- jrc = env->CallIntMethod(job, setid, i, (jint)GetJDBCType(val->GetType()));
+ jrc = env->CallIntMethod(job, setid, i,
+ (colp->uuid ? 1111 : (jint)GetJDBCType(val->GetType())));
+ } else if (colp->uuid) {
+ if (gmID(g, setid, "SetUuidParm", "(ILjava/lang/String;)V"))
+ return true;
+
+ jst = env->NewStringUTF(val->GetCharValue());
+ env->CallVoidMethod(job, setid, i, jst);
} else switch (val->GetType()) {
case TYPE_STRING:
if (gmID(g, setid, "SetStringParm", "(ILjava/lang/String;)V"))
@@ -1275,105 +1495,6 @@ bool JDBConn::SetParam(JDBCCOL *colp)
} // end of GetMetaData
/***********************************************************************/
- /* A helper class to split an optionally qualified table name into */
- /* components. */
- /* These formats are understood: */
- /* "CatalogName.SchemaName.TableName" */
- /* "SchemaName.TableName" */
- /* "TableName" */
- /***********************************************************************/
- class SQLQualifiedName
- {
- static const uint max_parts= 3; // Catalog.Schema.Table
- MYSQL_LEX_STRING m_part[max_parts];
- char m_buf[512];
-
- void lex_string_set(MYSQL_LEX_STRING *S, char *str, size_t length)
- {
- S->str= str;
- S->length= length;
- } // end of lex_string_set
-
- void lex_string_shorten_down(MYSQL_LEX_STRING *S, size_t offs)
- {
- DBUG_ASSERT(offs <= S->length);
- S->str+= offs;
- S->length-= offs;
- } // end of lex_string_shorten_down
-
- /*********************************************************************/
- /* Find the rightmost '.' delimiter and return the length */
- /* of the qualifier, including the rightmost '.' delimier. */
- /* For example, for the string {"a.b.c",5} it will return 4, */
- /* which is the length of the qualifier "a.b." */
- /*********************************************************************/
- size_t lex_string_find_qualifier(MYSQL_LEX_STRING *S)
- {
- size_t i;
- for (i= S->length; i > 0; i--)
- {
- if (S->str[i - 1] == '.')
- {
- S->str[i - 1]= '\0';
- return i;
- }
- }
- return 0;
- } // end of lex_string_find_qualifier
-
- public:
- /*********************************************************************/
- /* Initialize to the given optionally qualified name. */
- /* NULL pointer in "name" is supported. */
- /* name qualifier has precedence over schema. */
- /*********************************************************************/
- SQLQualifiedName(JCATPARM *cap)
- {
- const char *name = (const char *)cap->Tab;
- char *db = (char *)cap->DB;
- size_t len, i;
-
- // Initialize the parts
- for (i = 0; i < max_parts; i++)
- lex_string_set(&m_part[i], NULL, 0);
-
- if (name) {
- // Initialize the first (rightmost) part
- lex_string_set(&m_part[0], m_buf,
- strmake(m_buf, name, sizeof(m_buf) - 1) - m_buf);
-
- // Initialize the other parts, if exist.
- for (i= 1; i < max_parts; i++) {
- if (!(len= lex_string_find_qualifier(&m_part[i - 1])))
- break;
-
- lex_string_set(&m_part[i], m_part[i - 1].str, len - 1);
- lex_string_shorten_down(&m_part[i - 1], len);
- } // endfor i
-
- } // endif name
-
- // If it was not specified, set schema as the passed db name
- if (db && !m_part[1].length)
- lex_string_set(&m_part[1], db, strlen(db));
-
- } // end of SQLQualifiedName
-
- char *ptr(uint i)
- {
- DBUG_ASSERT(i < max_parts);
- return (char *)(m_part[i].length ? m_part[i].str : NULL);
- } // end of ptr
-
- size_t length(uint i)
- {
- DBUG_ASSERT(i < max_parts);
- return m_part[i].length;
- } // end of length
-
- }; // end of class SQLQualifiedName
-
- /***********************************************************************/
/* Allocate recset and call SQLTables, SQLColumns or SQLPrimaryKeys. */
/***********************************************************************/
int JDBConn::GetCatInfo(JCATPARM *cap)
diff --git a/storage/connect/jdbconn.h b/storage/connect/jdbconn.h
index 56f318d238b..0c36cccadcf 100644
--- a/storage/connect/jdbconn.h
+++ b/storage/connect/jdbconn.h
@@ -29,6 +29,7 @@ public:
// Attributes
public:
char *GetQuoteChar(void) { return m_IDQuoteChar; }
+ bool SetUUID(PGLOBAL g, PTDBJDBC tjp);
virtual int GetMaxValue(int infotype);
public:
@@ -58,13 +59,6 @@ public:
protected:
// Members
-#if 0
- JavaVM *jvm; // Pointer to the JVM (Java Virtual Machine)
- JNIEnv *env; // Pointer to native interface
- jclass jdi; // Pointer to the java wrapper class
- jobject job; // The java wrapper class object
- jmethodID errid; // The GetErrmsg method ID
-#endif // 0
jmethodID xqid; // The ExecuteQuery method ID
jmethodID xuid; // The ExecuteUpdate method ID
jmethodID xid; // The Execute method ID
@@ -84,8 +78,7 @@ protected:
jmethodID timfldid; // The TimeField method ID
jmethodID tspfldid; // The TimestampField method ID
jmethodID bigfldid; // The BigintField method ID
-// PCSZ Msg;
-// PCSZ m_Wrap;
+ jmethodID uidfldid; // The UuidField method ID
char m_IDQuoteChar[2];
PCSZ m_Pwd;
int m_Ncol;
diff --git a/storage/connect/mysql-test/connect/r/jdbc_postgresql.result b/storage/connect/mysql-test/connect/r/jdbc_postgresql.result
index 6d77d79d5d3..7969672dd66 100644
--- a/storage/connect/mysql-test/connect/r/jdbc_postgresql.result
+++ b/storage/connect/mysql-test/connect/r/jdbc_postgresql.result
@@ -1,9 +1,11 @@
+SET GLOBAL connect_class_path='C:/MariaDB-10.2/MariaDB/storage/connect/mysql-test/connect/std_data/JavaWrappers.jar;C:/Jconnectors/postgresql-42.2.1.jar';
CREATE TABLE t2 (
command varchar(128) not null,
number int(5) not null flag=1,
message varchar(255) flag=2)
-ENGINE=CONNECT TABLE_TYPE=JDBC CONNECTION='jdbc:postgresql://localhost/mtr'
-OPTION_LIST='User=mtr,Password=mtr,Schema=public,Execsrc=1';
+ENGINE=CONNECT TABLE_TYPE=JDBC
+CONNECTION='jdbc:postgresql://localhost/test?user=postgres&password=tinono'
+OPTION_LIST='Execsrc=1';
SELECT * FROM t2 WHERE command='drop table employee';
command number message
drop table employee 0 Execute: org.postgresql.util.PSQLException: ERREUR: la table « employee » n'existe pas
@@ -14,17 +16,18 @@ SELECT * FROM t2 WHERE command = "insert into employee values(4567,'Johnson', 'E
command number message
insert into employee values(4567,'Johnson', 'Engineer', 12560.50) 1 Affected rows
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC CATFUNC=tables
-CONNECTION='jdbc:postgresql://localhost/mtr'
-OPTION_LIST='User=mtr,Password=mtr,Schema=public,Tabtype=TABLE,Maxres=10';
+CONNECTION='jdbc:postgresql://localhost/test?user=postgres&password=tinono'
+OPTION_LIST='Tabtype=TABLE,Maxres=10';
SELECT * FROM t1;
Table_Cat Table_Schema Table_Name Table_Type Remark
- public employee TABLE NULL
- public t1 TABLE NULL
- public t2 TABLE NULL
+NULL public employee TABLE NULL
+NULL public t1 TABLE NULL
+NULL public t2 TABLE NULL
+NULL public tchar TABLE NULL
+NULL public testuuid TABLE NULL
DROP TABLE t1;
-CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC CATFUNC=columns
-CONNECTION='jdbc:postgresql://localhost/mtr' tabname=employee
-OPTION_LIST='User=mtr,Password=mtr,Maxres=10';
+CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC tabname=employee CATFUNC=columns
+CONNECTION='jdbc:postgresql://localhost/test?user=postgres&password=tinono';
SELECT * FROM t1;
Table_Cat Table_Schema Table_Name Column_Name Data_Type Type_Name Column_Size Buffer_Length Decimal_Digits Radix Nullable Remarks
NULL public employee id 4 int4 10 0 0 10 0 NULL
@@ -34,13 +37,14 @@ NULL public employee salary 2 numeric 8 0 2 10 1 NULL
DROP TABLE t1;
CREATE SERVER 'postgresql' FOREIGN DATA WRAPPER 'postgresql' OPTIONS (
HOST 'localhost',
-DATABASE 'mtr',
-USER 'mtr',
-PASSWORD 'mtr',
+DATABASE 'test',
+USER 'postgres',
+PASSWORD 'tinono',
PORT 0,
SOCKET '',
OWNER 'root');
-CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC CONNECTION='postgresql/public.employee';
+CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC
+CONNECTION='postgresql/public.employee';
SELECT * FROM t1;
id name title salary
4567 Johnson Engineer 12560.50
@@ -60,6 +64,3 @@ SELECT * FROM t2 WHERE command='drop table employee';
command number message
drop table employee 0 Affected rows
DROP TABLE t2;
-SET GLOBAL connect_jvm_path=NULL;
-SET GLOBAL connect_class_path=NULL;
-SET GLOBAL time_zone = SYSTEM;
diff --git a/storage/connect/mysql-test/connect/std_data/JavaWrappers.jar b/storage/connect/mysql-test/connect/std_data/JavaWrappers.jar
new file mode 100644
index 00000000000..33b29e7685b
--- /dev/null
+++ b/storage/connect/mysql-test/connect/std_data/JavaWrappers.jar
Binary files differ
diff --git a/storage/connect/mysql-test/connect/t/jdbc_postgresql.test b/storage/connect/mysql-test/connect/t/jdbc_postgresql.test
index 1041ef468d7..8036f71020d 100644
--- a/storage/connect/mysql-test/connect/t/jdbc_postgresql.test
+++ b/storage/connect/mysql-test/connect/t/jdbc_postgresql.test
@@ -3,25 +3,32 @@
#
# This test is run against Postgresql driver
#
+eval SET GLOBAL connect_class_path='$MTR_SUITE_DIR/std_data/JavaWrappers.jar;C:/Jconnectors/postgresql-42.2.1.jar';
CREATE TABLE t2 (
command varchar(128) not null,
number int(5) not null flag=1,
message varchar(255) flag=2)
-ENGINE=CONNECT TABLE_TYPE=JDBC CONNECTION='jdbc:postgresql://localhost/mtr'
-OPTION_LIST='User=mtr,Password=mtr,Schema=public,Execsrc=1';
+ENGINE=CONNECT TABLE_TYPE=JDBC
+CONNECTION='jdbc:postgresql://localhost/test?user=postgres&password=tinono'
+OPTION_LIST='Execsrc=1';
+#CONNECTION='jdbc:postgresql://localhost/mtr'
+#OPTION_LIST='User=mtr,Password=mtr,Schema=public,Execsrc=1';
SELECT * FROM t2 WHERE command='drop table employee';
SELECT * FROM t2 WHERE command = 'create table employee (id int not null, name varchar(32), title char(16), salary decimal(8,2))';
SELECT * FROM t2 WHERE command = "insert into employee values(4567,'Johnson', 'Engineer', 12560.50)";
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC CATFUNC=tables
-CONNECTION='jdbc:postgresql://localhost/mtr'
-OPTION_LIST='User=mtr,Password=mtr,Schema=public,Tabtype=TABLE,Maxres=10';
+CONNECTION='jdbc:postgresql://localhost/test?user=postgres&password=tinono'
+OPTION_LIST='Tabtype=TABLE,Maxres=10';
+#CONNECTION='jdbc:postgresql://localhost/mtr'
+#OPTION_LIST='User=mtr,Password=mtr,Schema=public,Tabtype=TABLE,Maxres=10';
SELECT * FROM t1;
DROP TABLE t1;
-CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC CATFUNC=columns
-CONNECTION='jdbc:postgresql://localhost/mtr' tabname=employee
-OPTION_LIST='User=mtr,Password=mtr,Maxres=10';
+CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC tabname=employee CATFUNC=columns
+CONNECTION='jdbc:postgresql://localhost/test?user=postgres&password=tinono';
+#CONNECTION='jdbc:postgresql://localhost/mtr' tabname=employee;
+#OPTION_LIST='User=mtr,Password=mtr,Maxres=10';
SELECT * FROM t1;
DROP TABLE t1;
@@ -30,14 +37,18 @@ DROP TABLE t1;
#
CREATE SERVER 'postgresql' FOREIGN DATA WRAPPER 'postgresql' OPTIONS (
HOST 'localhost',
-DATABASE 'mtr',
-USER 'mtr',
-PASSWORD 'mtr',
+DATABASE 'test',
+USER 'postgres',
+PASSWORD 'tinono',
PORT 0,
SOCKET '',
OWNER 'root');
+#DATABASE 'mtr',
+#USER 'mtr',
+#PASSWORD 'mtr',
-CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC CONNECTION='postgresql/public.employee';
+CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC
+CONNECTION='postgresql/public.employee';
SELECT * FROM t1;
INSERT INTO t1 VALUES(3126,'Smith', 'Clerk', 5230.00);
UPDATE t1 SET salary = salary + 100.00;
diff --git a/storage/connect/mysql-test/connect/t/jdbconn.inc b/storage/connect/mysql-test/connect/t/jdbconn.inc
index 05122f51924..81ec80c13d6 100644
--- a/storage/connect/mysql-test/connect/t/jdbconn.inc
+++ b/storage/connect/mysql-test/connect/t/jdbconn.inc
@@ -22,10 +22,11 @@ DROP TABLE t1;
# 1 - The current directory.
# 2 - The paths of the connect_class_path global variable.
# 3 - The paths of the CLASSPATH environment variable.
-# In this test we use an executable jar file that contains all what is needed.
-eval SET GLOBAL connect_class_path='$MTR_SUITE_DIR/std_data/JdbcMariaDB.jar';
+# In this test we use an executable jar file that contains all the eisting wrappers.
+#eval SET GLOBAL connect_class_path='$MTR_SUITE_DIR/std_data/JdbcMariaDB.jar';
+eval SET GLOBAL connect_class_path='$MTR_SUITE_DIR/std_data/JavaWrappers.jar';
-# Paths to the JDK classes and to the MySQL and MariaDB drivers can be defined in the CLASSPATH environment variable
+# Paths to the JDK classes and to the JDBC drivers should be defined in the CLASSPATH environment variable
#CREATE FUNCTION envar RETURNS STRING SONAME 'ha_connect.dll';
#SELECT envar('CLASSPATH');
diff --git a/storage/connect/plgdbsem.h b/storage/connect/plgdbsem.h
index 6a0a8be8ff8..5446e0d2a07 100644
--- a/storage/connect/plgdbsem.h
+++ b/storage/connect/plgdbsem.h
@@ -362,7 +362,8 @@ enum COLUSE {U_P = 0x01, /* the projection list. */
U_IS_NULL = 0x80, /* The column has a null value */
U_SPECIAL = 0x100, /* The column is special */
U_UNSIGNED = 0x200, /* The column type is unsigned */
- U_ZEROFILL = 0x400}; /* The column is zero filled */
+ U_ZEROFILL = 0x400, /* The column is zero filled */
+ U_UUID = 0x800}; /* The column is a UUID */
/***********************************************************************/
/* DB description class and block pointer definitions. */
diff --git a/storage/connect/tabjdbc.cpp b/storage/connect/tabjdbc.cpp
index c0fda584381..adbfb2168ae 100644
--- a/storage/connect/tabjdbc.cpp
+++ b/storage/connect/tabjdbc.cpp
@@ -605,6 +605,10 @@ bool TDBJDBC::OpenDB(PGLOBAL g)
else if (Quoted)
Quote = Jcp->GetQuoteChar();
+ if (Mode != MODE_READ && Mode != MODE_READX)
+ if (Jcp->SetUUID(g, this))
+ PushWarning(g, this, 1);
+
Use = USE_OPEN; // Do it now in case we are recursively called
/*********************************************************************/
@@ -970,6 +974,7 @@ void TDBJDBC::CloseDB(PGLOBAL g)
JDBCCOL::JDBCCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PCSZ am)
: EXTCOL(cdp, tdbp, cprec, i, am)
{
+ uuid = false;
} // end of JDBCCOL constructor
/***********************************************************************/
@@ -977,6 +982,7 @@ JDBCCOL::JDBCCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PCSZ am)
/***********************************************************************/
JDBCCOL::JDBCCOL(void) : EXTCOL()
{
+ uuid = false;
} // end of JDBCCOL constructor
/***********************************************************************/
@@ -985,12 +991,11 @@ JDBCCOL::JDBCCOL(void) : EXTCOL()
/***********************************************************************/
JDBCCOL::JDBCCOL(JDBCCOL *col1, PTDB tdbp) : EXTCOL(col1, tdbp)
{
+ uuid = col1->uuid;
} // end of JDBCCOL copy constructor
/***********************************************************************/
-/* ReadColumn: when SQLFetch is used there is nothing to do as the */
-/* column buffer was bind to the record set. This is also the case */
-/* when calculating MaxSize (Bufp is NULL even when Rows is not). */
+/* ReadColumn: retrieve the column value via the JDBC driver. */
/***********************************************************************/
void JDBCCOL::ReadColumn(PGLOBAL g)
{
diff --git a/storage/connect/tabjdbc.h b/storage/connect/tabjdbc.h
index d422ed26ef2..078129a14e3 100644
--- a/storage/connect/tabjdbc.h
+++ b/storage/connect/tabjdbc.h
@@ -101,6 +101,7 @@ protected:
/***********************************************************************/
class JDBCCOL : public EXTCOL {
friend class TDBJDBC;
+ friend class JDBConn;
public:
// Constructors
JDBCCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PCSZ am = "JDBC");
@@ -119,6 +120,7 @@ protected:
JDBCCOL(void);
// Members
+ bool uuid; // For PostgreSQL
}; // end of class JDBCCOL
/***********************************************************************/