From a9ac3506d21135373f9ced92c79c0d9d7c7dca13 Mon Sep 17 00:00:00 2001 From: Olivier Bertrand Date: Thu, 2 Jun 2016 23:36:19 +0200 Subject: [PATCH] git90.msg + git91.msg --- storage/connect/.gitattributes | 25 + storage/connect/.gitignore | 264 ++++++++ storage/connect/CMakeLists.txt | 6 +- storage/connect/JdbcApacheInterface.class | Bin 0 -> 15357 bytes storage/connect/JdbcApacheInterface.java | 709 +++++++++++++++++++++ storage/connect/JdbcDSInterface.class | Bin 0 -> 16175 bytes storage/connect/JdbcDSInterface.java | 743 ++++++++++++++++++++++ storage/connect/ha_connect.cc | 30 +- storage/connect/jdbconn.cpp | 23 +- storage/connect/jdbconn.h | 4 +- storage/connect/jsonudf.cpp | 297 +++++++-- storage/connect/myconn.cpp | 8 +- storage/connect/plugutil.c | 4 +- 13 files changed, 2039 insertions(+), 74 deletions(-) create mode 100644 storage/connect/.gitattributes create mode 100644 storage/connect/.gitignore create mode 100644 storage/connect/JdbcApacheInterface.class create mode 100644 storage/connect/JdbcApacheInterface.java create mode 100644 storage/connect/JdbcDSInterface.class create mode 100644 storage/connect/JdbcDSInterface.java diff --git a/storage/connect/.gitattributes b/storage/connect/.gitattributes new file mode 100644 index 00000000000..d21fdf8f212 --- /dev/null +++ b/storage/connect/.gitattributes @@ -0,0 +1,25 @@ +# Set the default behavior, in case people don't have core.autocrlf set. +* text=auto + +# Explicitly declare text files you want to always be normalized and converted +# to native line endings on checkout. +*.c text +*.cc text +*.cpp text +*.h text +*.test text + +# Declare files that will always have LF line endings on checkout. +*.result text eol=lf +mysql-test/connect/std_data/*.txt text eol=lf +mysql-test/connect/std_data/*.dat text eol=lf + +# Denote all files that are truly binary and should not be modified. +*.png binary +*.jpg binary + +*.c diff=cpp +*.h diff=cpp +*.cc diff=cpp +*.ic diff=cpp +*.cpp diff=cpp diff --git a/storage/connect/.gitignore b/storage/connect/.gitignore new file mode 100644 index 00000000000..e2fa07ee143 --- /dev/null +++ b/storage/connect/.gitignore @@ -0,0 +1,264 @@ +# Edited by Olivier Bertrand +*-t +*.a +*.ctest +*.o +*.reject +*.so +*.so.* +*.spec +*~ +*.bak +*.log +*.cmake +*.tgz +*.msg +.*.swp +*.ninja +.ninja_* +.gdb_history + +CMakeFiles/ +connect.dir/ +connect.dir-Copie/ +Debug/ +MinSizeRel/ +Release/ +RelWithDebInfo/ + +# C and C++ + +# Compiled Object files +*.slo +*.lo +*.o +*.ko +*.obj +*.elf +*.exp +*.manifest +*.dep +*.idb +*.res + +# Precompiled Headers +*.gch +*.pch + +# Compiled Static libraries +*.lib +*.a +*.la +*.lai +*.lo + +# Compiled Dynamic libraries +*.so +*.so.* +*.dylib +*.dll + +# Executables +*.exe +*.out +*.app +*.i*86 +*.x86_64 +*.hex + + +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. + +# User-specific files +*.suo +*.user +*.userosscache +*.sln.docstates +*.ncb +*.sln + +*.vcproj +*.vcproj.* +*.vcproj.*.* +*.vcproj.*.*.* +*.vcxproj +*.vcxproj.* +*.vcxproj.*.* +*.vcxproj.*.*.* + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +build/ +bld/ +[Bb]in/ +[Oo]bj/ + +# Roslyn cache directories +*.ide/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +#NUNIT +*.VisualState.xml +TestResult.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +*_i.c +*_p.c +*_i.h +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opensdf +*.sdf +*.cachefile + +# Visual Studio profiler +*.psess +*.vsp +*.vspx + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# JustCode is a .NET coding addin-in +.JustCode + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# NCrunch +_NCrunch_* +.*crunch*.local.xml + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# TODO: Comment the next line if you want to checkin your web deploy settings +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# NuGet Packages +*.nupkg +# The packages folder can be ignored because of Package Restore +**/packages/* +# except build/, which is used as an MSBuild target. +!**/packages/build/ +# If using the old MSBuild-Integrated Package Restore, uncomment this: +#!**/packages/repositories.config + +# Windows Azure Build Output +csx/ +*.build.csdef + +# Windows Store app package directory +AppPackages/ + +# Others +# sql/ +*.Cache +ClientBin/ +[Ss]tyle[Cc]op.* +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.pfx +*.publishsettings +node_modules/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm + +# SQL Server files +*.mdf +*.ldf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings + +# Microsoft Fakes +FakesAssemblies/ diff --git a/storage/connect/CMakeLists.txt b/storage/connect/CMakeLists.txt index ff0060dcc61..254d074612a 100644 --- a/storage/connect/CMakeLists.txt +++ b/storage/connect/CMakeLists.txt @@ -37,7 +37,7 @@ user_connect.h valblk.h value.h xindex.h xobject.h xtable.h) # # Definitions that are shared for all OSes # -add_definitions( -DMARIADB -DFORCE_INIT_OF_VARS ) +add_definitions( -DMARIADB -DFORCE_INIT_OF_VARS -Dconnect_EXPORTS) add_definitions( -DHUGE_SUPPORT -DZIP_SUPPORT -DPIVOT_SUPPORT ) @@ -240,7 +240,7 @@ OPTION(CONNECT_WITH_JDBC "Compile CONNECT storage engine with JDBC support" ON) IF(CONNECT_WITH_JDBC) # TODO: detect Java SDK and the presence of JDBC connectors - # TODO: Find how to compile and install the JdbcInterface.java class + # TODO: Find how to compile and install the java wrapper class # Find required libraries and include directories FIND_PACKAGE(Java) @@ -251,6 +251,8 @@ IF(CONNECT_WITH_JDBC) # SET(JDBC_LIBRARY ${JAVA_JVM_LIBRARY}) SET(CONNECT_SOURCES ${CONNECT_SOURCES} JdbcInterface.java JdbcInterface.class + JdbcDSInterface.java JdbcDSInterface.class + JdbcApacheInterface.java JdbcApacheInterface.class jdbconn.cpp tabjdbc.cpp jdbconn.h tabjdbc.h jdbccat.h) add_definitions(-DJDBC_SUPPORT) ELSE() diff --git a/storage/connect/JdbcApacheInterface.class b/storage/connect/JdbcApacheInterface.class new file mode 100644 index 0000000000000000000000000000000000000000..acd4258e3d3ace51a01fe79b5c0dfeb65d6ac87c GIT binary patch literal 15357 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 bLu1Gu*v`IP9_fOXKEv*wkxh|mjS2q)X94nE literal 0 HcmV?d00001 diff --git a/storage/connect/JdbcApacheInterface.java b/storage/connect/JdbcApacheInterface.java new file mode 100644 index 00000000000..fdbc5bff203 --- /dev/null +++ b/storage/connect/JdbcApacheInterface.java @@ -0,0 +1,709 @@ +import java.math.*; +import java.sql.*; +import java.util.Collections; +import java.util.Hashtable; +import java.util.List; + +import org.apache.commons.dbcp2.BasicDataSource; + +public class JdbcApacheInterface { + boolean DEBUG = false; + String Errmsg = "No error"; + Connection conn = null; + DatabaseMetaData dbmd = null; + Statement stmt = null; + PreparedStatement pstmt = null; + ResultSet rs = null; + ResultSetMetaData rsmd = null; + static Hashtable pool = new Hashtable(); + + // === Constructors/finalize ========================================= + public JdbcApacheInterface() { + this(true); + } // end of default constructor + + public JdbcApacheInterface(boolean b) { + DEBUG = b; + } // end of constructor + + private void SetErrmsg(Exception e) { + if (DEBUG) + System.out.println(e.getMessage()); + + Errmsg = e.toString(); + } // end of SetErrmsg + + private void SetErrmsg(String s) { + if (DEBUG) + System.out.println(s); + + Errmsg = s; + } // end of SetErrmsg + + public String GetErrmsg() { + String err = Errmsg; + + Errmsg = "No error"; + return err; + } // end of GetErrmsg + + public int JdbcConnect(String[] parms, int fsize, boolean scrollable) { + int rc = 0; + String url = parms[1]; + BasicDataSource ds = null; + + if (url == null) { + SetErrmsg("URL cannot be null"); + return -1; + } // endif url + + try { + if ((ds = pool.get(url)) == null) { + ds = new BasicDataSource(); + ds.setDriverClassName(parms[0]); + ds.setUrl(url); + ds.setUsername(parms[2]); + ds.setPassword(parms[3]); + pool.put(url, ds); + } // endif ds + + // Get a connection from the data source + conn = ds.getConnection(); + + // Get the data base meta data object + dbmd = conn.getMetaData(); + + // Get a statement from the connection + if (scrollable) + stmt = conn.createStatement(java.sql.ResultSet.TYPE_SCROLL_INSENSITIVE, java.sql.ResultSet.CONCUR_READ_ONLY); + else + stmt = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY, java.sql.ResultSet.CONCUR_READ_ONLY); + + if (DEBUG) + System.out.println("Statement type = " + stmt.getResultSetType() + + " concurrency = " + stmt.getResultSetConcurrency()); + + if (DEBUG) // Get the fetch size of a statement + System.out.println("Default fetch size = " + stmt.getFetchSize()); + + if (fsize != 0) { + // Set the fetch size + stmt.setFetchSize(fsize); + + if (DEBUG) + System.out.println("New fetch size = " + stmt.getFetchSize()); + + } // endif fsize + + } catch (SQLException se) { + SetErrmsg(se); + rc = -2; + } catch( Exception e ) { + SetErrmsg(e); + rc = -3; + } // end try/catch + + return rc; + } // end of JdbcConnect + + public int CreatePrepStmt(String sql) { + int rc = 0; + + try { + pstmt = conn.prepareStatement(sql); + } catch (SQLException se) { + SetErrmsg(se); + rc = -1; + } catch (Exception e) { + SetErrmsg(e); + rc = -2; + } // end try/catch + + return rc; + } // end of CreatePrepStmt + + public void SetStringParm(int i, String s) { + try { + pstmt.setString(i, s); + } catch (Exception e) { + SetErrmsg(e); + } // end try/catch + + } // end of SetStringParm + + public void SetIntParm(int i, int n) { + try { + pstmt.setInt(i, n); + } catch (Exception e) { + SetErrmsg(e); + } // end try/catch + + } // end of SetIntParm + + public void SetShortParm(int i, short n) { + try { + pstmt.setShort(i, n); + } catch (Exception e) { + SetErrmsg(e); + } // end try/catch + + } // end of SetShortParm + + public void SetBigintParm(int i, long n) { + try { + pstmt.setLong(i, n); + } catch (Exception e) { + SetErrmsg(e); + } // end try/catch + + } // end of SetBigintParm + + public void SetFloatParm(int i, float f) { + try { + pstmt.setFloat(i, f); + } catch (Exception e) { + SetErrmsg(e); + } // end try/catch + + } // end of SetFloatParm + + public void SetDoubleParm(int i, double d) { + try { + pstmt.setDouble(i, d); + } catch (Exception e) { + SetErrmsg(e); + } // end try/catch + + } // end of SetDoubleParm + + public void SetTimestampParm(int i, Timestamp t) { + try { + pstmt.setTimestamp(i, t); + } catch (Exception e) { + SetErrmsg(e); + } // end try/catch + + } // end of SetTimestampParm + + public int ExecutePrep() { + int n = -3; + + if (pstmt != null) try { + n = pstmt.executeUpdate(); + } catch (SQLException se) { + SetErrmsg(se); + n = -1; + } catch (Exception e) { + SetErrmsg(e); + n = -2; + } //end try/catch + + return n; + } // end of ExecutePrep + + public boolean ClosePrepStmt() { + boolean b = false; + + if (pstmt != null) try { + pstmt.close(); + pstmt = null; + } catch (SQLException se) { + SetErrmsg(se); + b = true; + } catch (Exception e) { + SetErrmsg(e); + b = true; + } // end try/catch + + return b; + } // end of ClosePrepStmt + + public int JdbcDisconnect() { + int rc = 0; + + // Cancel pending statement + if (stmt != null) + try { + System.out.println("Cancelling statement"); + stmt.cancel(); + } catch(SQLException se) { + SetErrmsg(se); + rc += 1; + } // nothing more we can do + + // Close the statement and the connection + if (rs != null) + try { + if (DEBUG) + System.out.println("Closing result set"); + + rs.close(); + } catch(SQLException se) { + SetErrmsg(se); + rc = 2; + } // nothing more we can do + + if (stmt != null) + try { + if (DEBUG) + System.out.println("Closing statement"); + + stmt.close(); + } catch(SQLException se) { + SetErrmsg(se); + rc += 4; + } // nothing more we can do + + ClosePrepStmt(); + + if (conn != null) + try { + if (DEBUG) + System.out.println("Closing connection"); + + conn.close(); + } catch (SQLException se) { + SetErrmsg(se); + rc += 8; + } //end try/catch + + if (DEBUG) + System.out.println("All closed"); + + return rc; + } // end of JdbcDisconnect + + public int GetMaxValue(int n) { + int m = 0; + + try { + switch (n) { + case 1: // Max columns in table + m = dbmd.getMaxColumnsInTable(); + break; + case 2: // Max catalog name length + m = dbmd.getMaxCatalogNameLength(); + break; + case 3: // Max schema name length + m = dbmd.getMaxSchemaNameLength(); + break; + case 4: // Max table name length + m = dbmd.getMaxTableNameLength(); + break; + case 5: // Max column name length + m = dbmd.getMaxColumnNameLength(); + break; + } // endswitch n + + } catch(Exception e) { + SetErrmsg(e); + m = -1; + } // end try/catch + + return m; + } // end of GetMaxValue + + public int GetColumns(String[] parms) { + int ncol = 0; + + try { + if (rs != null) rs.close(); + rs = dbmd.getColumns(parms[0], parms[1], parms[2], parms[3]); + + if (rs != null) { + rsmd = rs.getMetaData(); + ncol = rsmd.getColumnCount(); + } // endif rs + + } catch(SQLException se) { + SetErrmsg(se); + } // end try/catch + + return ncol; + } // end of GetColumns + + public int GetTables(String[] parms) { + int ncol = 0; + String[] typ = null; + + if (parms[3] != null) { + typ = new String[1]; + typ[0] = parms[3]; + } // endif parms + + try { + if (rs != null) rs.close(); + rs = dbmd.getTables(parms[0], parms[1], parms[2], typ); + + if (rs != null) { + rsmd = rs.getMetaData(); + ncol = rsmd.getColumnCount(); + } // endif rs + + } catch(SQLException se) { + SetErrmsg(se); + } // end try/catch + + return ncol; + } // end of GetColumns + + public int Execute(String query) { + int n = 0; + + if (DEBUG) + System.out.println("Executing '" + query + "'"); + + try { + boolean b = stmt.execute(query); + + if (b == false) { + n = stmt.getUpdateCount(); + if (rs != null) rs.close(); + } // endif b + + if (DEBUG) + System.out.println("Query '" + query + "' executed: n = " + n); + + } catch (SQLException se) { + SetErrmsg(se); + n = -1; + } catch (Exception e) { + SetErrmsg(e); + n = -2; + } //end try/catch + + return n; + } // end of Execute + + public int GetResult() { + int ncol = 0; + + try { + rs = stmt.getResultSet(); + + if (rs != null) { + rsmd = rs.getMetaData(); + ncol = rsmd.getColumnCount(); + + if (DEBUG) + System.out.println("Result set has " + rsmd.getColumnCount() + " column(s)"); + + } // endif rs + + } catch (SQLException se) { + SetErrmsg(se); + ncol = -1; + } catch (Exception e) { + SetErrmsg(e); + ncol = -2; + } //end try/catch + + return ncol; + } // end of GetResult + + public int ExecuteQuery(String query) { + int ncol = 0; + + if (DEBUG) + System.out.println("Executing query '" + query + "'"); + + try { + rs = stmt.executeQuery(query); + rsmd = rs.getMetaData(); + ncol = rsmd.getColumnCount(); + + if (DEBUG) { + System.out.println("Query '" + query + "' executed successfully"); + System.out.println("Result set has " + rsmd.getColumnCount() + " column(s)"); + } // endif DEBUG + + } catch (SQLException se) { + SetErrmsg(se); + ncol = -1; + } catch (Exception e) { + SetErrmsg(e); + ncol = -2; + } //end try/catch + + return ncol; + } // end of ExecuteQuery + + public int ExecuteUpdate(String query) { + int n = 0; + + if (DEBUG) + System.out.println("Executing update query '" + query + "'"); + + try { + n = stmt.executeUpdate(query); + + if (DEBUG) + System.out.println("Update Query '" + query + "' executed: n = " + n); + + } catch (SQLException se) { + SetErrmsg(se); + n = -1; + } catch (Exception e) { + SetErrmsg(e); + n = -2; + } //end try/catch + + return n; + } // end of ExecuteUpdate + + public int ReadNext() { + if (rs != null) { + try { + return rs.next() ? 1 : 0; + } catch (SQLException se) { + SetErrmsg(se); + return -1; + } //end try/catch + + } else + return 0; + + } // end of ReadNext + + public boolean Fetch(int row) { + if (rs != null) { + try { + return rs.absolute(row); + } catch (SQLException se) { + SetErrmsg(se); + return false; + } //end try/catch + + } else + return false; + + } // end of Fetch + + public String ColumnName(int n) { + if (rsmd == null) { + System.out.println("No result metadata"); + } else try { + return rsmd.getColumnLabel(n); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return null; + } // end of ColumnName + + public int ColumnType(int n, String name) { + if (rsmd == null) { + System.out.println("No result metadata"); + } else try { + if (n == 0) + n = rs.findColumn(name); + + return rsmd.getColumnType(n); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return 666; // Not a type + } // end of ColumnType + + public String ColumnDesc(int n, int[] val) { + if (rsmd == null) { + System.out.println("No result metadata"); + return null; + } else try { + val[0] = rsmd.getColumnType(n); + val[1] = rsmd.getPrecision(n); + val[2] = rsmd.getScale(n); + val[3] = rsmd.isNullable(n); + return rsmd.getColumnLabel(n); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return null; + } // end of ColumnDesc + + public String StringField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getString(n) : rs.getString(name); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return null; + } // end of StringField + + public int IntField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getInt(n) : rs.getInt(name); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return 0; + } // end of IntField + + public long BigintField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + BigDecimal bigDecimal = (n > 0) ? rs.getBigDecimal(n) : rs.getBigDecimal(name); + return bigDecimal != null ? bigDecimal.longValue() : 0; + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return 0; + } // end of BiginttField + + public double DoubleField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getDouble(n) : rs.getDouble(name); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return 0.; + } // end of DoubleField + + public float FloatField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getFloat(n) : rs.getFloat(name); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return 0; + } // end of FloatField + + public boolean BooleanField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getBoolean(n) : rs.getBoolean(name); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return false; + } // end of BooleanField + + public Date DateField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getDate(n) : rs.getDate(name); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return null; + } // end of DateField + + public Time TimeField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getTime(n) : rs.getTime(name); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return null; + } // end of TimeField + + public Timestamp TimestampField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getTimestamp(n) : rs.getTimestamp(name); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return null; + } // end of TimestampField + + public String ObjectField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getObject(n).toString() : rs.getObject(name).toString(); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return null; + } // end of ObjectField + + public int GetDrivers(String[] s, int mxs) { + int n = 0; + List drivers = Collections.list(DriverManager.getDrivers()); + int size = Math.min(mxs, drivers.size()); + + for (int i = 0; i < size; i++) { + Driver driver = (Driver)drivers.get(i); + + // Get name of driver + s[n++] = driver.getClass().getName(); + + // Get version info + s[n++] = driver.getMajorVersion() + "." + driver.getMinorVersion(); + s[n++] = driver.jdbcCompliant() ? "Yes" : "No"; + s[n++] = driver.toString(); + } // endfor i + + return size; + } // end of GetDrivers + + /** + * Adds the specified path to the java library path + * from Fahd Shariff blog + * + * @param pathToAdd the path to add + static public int addLibraryPath(String pathToAdd) { + System.out.println("jpath = " + pathToAdd); + + try { + Field usrPathsField = ClassLoader.class.getDeclaredField("usr_paths"); + usrPathsField.setAccessible(true); + + //get array of paths + String[] paths = (String[])usrPathsField.get(null); + + //check if the path to add is already present + for (String path : paths) { + System.out.println("path = " + path); + + if (path.equals(pathToAdd)) + return -5; + + } // endfor path + + //add the new path + String[] newPaths = Arrays.copyOf(paths, paths.length + 1); + newPaths[paths.length] = pathToAdd; + usrPathsField.set(null, newPaths); + System.setProperty("java.library.path", + System.getProperty("java.library.path") + File.pathSeparator + pathToAdd); + Field fieldSysPath = ClassLoader.class.getDeclaredField("sys_paths"); + fieldSysPath.setAccessible(true); + fieldSysPath.set(null, null); + } catch (Exception e) { + SetErrmsg(e); + return -1; + } // end try/catch + + return 0; + } // end of addLibraryPath + */ + +} // end of class JdbcApacheInterface diff --git a/storage/connect/JdbcDSInterface.class b/storage/connect/JdbcDSInterface.class new file mode 100644 index 0000000000000000000000000000000000000000..d56c04bd81f1253bc788d6c8556fa9a65c326d15 GIT binary patch literal 16175 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 literal 0 HcmV?d00001 diff --git a/storage/connect/JdbcDSInterface.java b/storage/connect/JdbcDSInterface.java new file mode 100644 index 00000000000..09f545bfb74 --- /dev/null +++ b/storage/connect/JdbcDSInterface.java @@ -0,0 +1,743 @@ +import java.math.*; +import java.sql.*; +import java.util.Collections; +import java.util.Hashtable; +import java.util.List; + +import javax.sql.DataSource; + +import org.mariadb.jdbc.MariaDbDataSource; +import org.postgresql.jdbc2.optional.PoolingDataSource; +import com.mysql.cj.jdbc.MysqlDataSource; +import oracle.jdbc.pool.OracleDataSource; + +public class JdbcDSInterface { + boolean DEBUG = false; + String Errmsg = "No error"; + Connection conn = null; + DatabaseMetaData dbmd = null; + Statement stmt = null; + PreparedStatement pstmt = null; + ResultSet rs = null; + ResultSetMetaData rsmd = null; + Hashtable dst = null; + + // === Constructors/finalize ========================================= + public JdbcDSInterface() { + this(true); + } // end of default constructor + + public JdbcDSInterface(boolean b) { + DEBUG = b; + dst = new Hashtable(); + } // end of constructor + + private void SetErrmsg(Exception e) { + if (DEBUG) + System.out.println(e.getMessage()); + + Errmsg = e.toString(); + } // end of SetErrmsg + + private void SetErrmsg(String s) { + if (DEBUG) + System.out.println(s); + + Errmsg = s; + } // end of SetErrmsg + + public String GetErrmsg() { + String err = Errmsg; + + Errmsg = "No error"; + return err; + } // end of GetErrmsg + + public int JdbcConnect(String[] parms, int fsize, boolean scrollable) { + int rc = 0; + String url = parms[1]; + DataSource ds = null; + MysqlDataSource mds = null; + MariaDbDataSource ads = null; + OracleDataSource ods = null; + PoolingDataSource pds = null; + + if (url == null) { + SetErrmsg("URL cannot be null"); + return -1; + } // endif driver + + try { + if ((ds = dst.get(url)) == null) { + if (url.toLowerCase().contains("mysql")) { + mds = new MysqlDataSource(); + mds.setURL(url); + mds.setUser(parms[2]); + mds.setPassword(parms[3]); + ds = mds; + } else if (url.toLowerCase().contains("mariadb")) { + ads = new MariaDbDataSource(); + ads.setUrl(url); + ads.setUser(parms[2]); + ads.setPassword(parms[3]); + ds = ads; + } else if (url.toLowerCase().contains("oracle")) { + ods = new OracleDataSource(); + ods.setURL(url); + ods.setUser(parms[2]); + ods.setPassword(parms[3]); + ds = ods; + } else if (url.toLowerCase().contains("postgresql")) { + pds = new PoolingDataSource(); + pds.setUrl(url); + pds.setUser(parms[2]); + pds.setPassword(parms[3]); + ds = pds; + } else { + SetErrmsg("Unsupported driver"); + return -4; + } // endif driver + + dst.put(url, ds); + } // endif ds + + // Get a connection from the data source + conn = ds.getConnection(); + + // Get the data base meta data object + dbmd = conn.getMetaData(); + + // Get a statement from the connection + if (scrollable) + stmt = conn.createStatement(java.sql.ResultSet.TYPE_SCROLL_INSENSITIVE, java.sql.ResultSet.CONCUR_READ_ONLY); + else + stmt = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY, java.sql.ResultSet.CONCUR_READ_ONLY); + + if (DEBUG) + System.out.println("Statement type = " + stmt.getResultSetType() + + " concurrency = " + stmt.getResultSetConcurrency()); + + if (DEBUG) // Get the fetch size of a statement + System.out.println("Default fetch size = " + stmt.getFetchSize()); + + if (fsize != 0) { + // Set the fetch size + stmt.setFetchSize(fsize); + + if (DEBUG) + System.out.println("New fetch size = " + stmt.getFetchSize()); + + } // endif fsize + + } catch (SQLException se) { + SetErrmsg(se); + rc = -2; + } catch( Exception e ) { + SetErrmsg(e); + rc = -3; + } // end try/catch + + return rc; + } // end of JdbcConnect + + public int CreatePrepStmt(String sql) { + int rc = 0; + + try { + pstmt = conn.prepareStatement(sql); + } catch (SQLException se) { + SetErrmsg(se); + rc = -1; + } catch (Exception e) { + SetErrmsg(e); + rc = -2; + } // end try/catch + + return rc; + } // end of CreatePrepStmt + + public void SetStringParm(int i, String s) { + try { + pstmt.setString(i, s); + } catch (Exception e) { + SetErrmsg(e); + } // end try/catch + + } // end of SetStringParm + + public void SetIntParm(int i, int n) { + try { + pstmt.setInt(i, n); + } catch (Exception e) { + SetErrmsg(e); + } // end try/catch + + } // end of SetIntParm + + public void SetShortParm(int i, short n) { + try { + pstmt.setShort(i, n); + } catch (Exception e) { + SetErrmsg(e); + } // end try/catch + + } // end of SetShortParm + + public void SetBigintParm(int i, long n) { + try { + pstmt.setLong(i, n); + } catch (Exception e) { + SetErrmsg(e); + } // end try/catch + + } // end of SetBigintParm + + public void SetFloatParm(int i, float f) { + try { + pstmt.setFloat(i, f); + } catch (Exception e) { + SetErrmsg(e); + } // end try/catch + + } // end of SetFloatParm + + public void SetDoubleParm(int i, double d) { + try { + pstmt.setDouble(i, d); + } catch (Exception e) { + SetErrmsg(e); + } // end try/catch + + } // end of SetDoubleParm + + public void SetTimestampParm(int i, Timestamp t) { + try { + pstmt.setTimestamp(i, t); + } catch (Exception e) { + SetErrmsg(e); + } // end try/catch + + } // end of SetTimestampParm + + public int ExecutePrep() { + int n = -3; + + if (pstmt != null) try { + n = pstmt.executeUpdate(); + } catch (SQLException se) { + SetErrmsg(se); + n = -1; + } catch (Exception e) { + SetErrmsg(e); + n = -2; + } //end try/catch + + return n; + } // end of ExecutePrep + + public boolean ClosePrepStmt() { + boolean b = false; + + if (pstmt != null) try { + pstmt.close(); + pstmt = null; + } catch (SQLException se) { + SetErrmsg(se); + b = true; + } catch (Exception e) { + SetErrmsg(e); + b = true; + } // end try/catch + + return b; + } // end of ClosePrepStmt + + public int JdbcDisconnect() { + int rc = 0; + + // Cancel pending statement + if (stmt != null) + try { + System.out.println("Cancelling statement"); + stmt.cancel(); + } catch(SQLException se) { + SetErrmsg(se); + rc += 1; + } // nothing more we can do + + // Close the statement and the connection + if (rs != null) + try { + if (DEBUG) + System.out.println("Closing result set"); + + rs.close(); + } catch(SQLException se) { + SetErrmsg(se); + rc = 2; + } // nothing more we can do + + if (stmt != null) + try { + if (DEBUG) + System.out.println("Closing statement"); + + stmt.close(); + } catch(SQLException se) { + SetErrmsg(se); + rc += 4; + } // nothing more we can do + + ClosePrepStmt(); + + if (conn != null) + try { + if (DEBUG) + System.out.println("Closing connection"); + + conn.close(); + } catch (SQLException se) { + SetErrmsg(se); + rc += 8; + } //end try/catch + + if (DEBUG) + System.out.println("All closed"); + + return rc; + } // end of JdbcDisconnect + + public int GetMaxValue(int n) { + int m = 0; + + try { + switch (n) { + case 1: // Max columns in table + m = dbmd.getMaxColumnsInTable(); + break; + case 2: // Max catalog name length + m = dbmd.getMaxCatalogNameLength(); + break; + case 3: // Max schema name length + m = dbmd.getMaxSchemaNameLength(); + break; + case 4: // Max table name length + m = dbmd.getMaxTableNameLength(); + break; + case 5: // Max column name length + m = dbmd.getMaxColumnNameLength(); + break; + } // endswitch n + + } catch(Exception e) { + SetErrmsg(e); + m = -1; + } // end try/catch + + return m; + } // end of GetMaxValue + + public int GetColumns(String[] parms) { + int ncol = 0; + + try { + if (rs != null) rs.close(); + rs = dbmd.getColumns(parms[0], parms[1], parms[2], parms[3]); + + if (rs != null) { + rsmd = rs.getMetaData(); + ncol = rsmd.getColumnCount(); + } // endif rs + + } catch(SQLException se) { + SetErrmsg(se); + } // end try/catch + + return ncol; + } // end of GetColumns + + public int GetTables(String[] parms) { + int ncol = 0; + String[] typ = null; + + if (parms[3] != null) { + typ = new String[1]; + typ[0] = parms[3]; + } // endif parms + + try { + if (rs != null) rs.close(); + rs = dbmd.getTables(parms[0], parms[1], parms[2], typ); + + if (rs != null) { + rsmd = rs.getMetaData(); + ncol = rsmd.getColumnCount(); + } // endif rs + + } catch(SQLException se) { + SetErrmsg(se); + } // end try/catch + + return ncol; + } // end of GetColumns + + public int Execute(String query) { + int n = 0; + + if (DEBUG) + System.out.println("Executing '" + query + "'"); + + try { + boolean b = stmt.execute(query); + + if (b == false) { + n = stmt.getUpdateCount(); + if (rs != null) rs.close(); + } // endif b + + if (DEBUG) + System.out.println("Query '" + query + "' executed: n = " + n); + + } catch (SQLException se) { + SetErrmsg(se); + n = -1; + } catch (Exception e) { + SetErrmsg(e); + n = -2; + } //end try/catch + + return n; + } // end of Execute + + public int GetResult() { + int ncol = 0; + + try { + rs = stmt.getResultSet(); + + if (rs != null) { + rsmd = rs.getMetaData(); + ncol = rsmd.getColumnCount(); + + if (DEBUG) + System.out.println("Result set has " + rsmd.getColumnCount() + " column(s)"); + + } // endif rs + + } catch (SQLException se) { + SetErrmsg(se); + ncol = -1; + } catch (Exception e) { + SetErrmsg(e); + ncol = -2; + } //end try/catch + + return ncol; + } // end of GetResult + + public int ExecuteQuery(String query) { + int ncol = 0; + + if (DEBUG) + System.out.println("Executing query '" + query + "'"); + + try { + rs = stmt.executeQuery(query); + rsmd = rs.getMetaData(); + ncol = rsmd.getColumnCount(); + + if (DEBUG) { + System.out.println("Query '" + query + "' executed successfully"); + System.out.println("Result set has " + rsmd.getColumnCount() + " column(s)"); + } // endif DEBUG + + } catch (SQLException se) { + SetErrmsg(se); + ncol = -1; + } catch (Exception e) { + SetErrmsg(e); + ncol = -2; + } //end try/catch + + return ncol; + } // end of ExecuteQuery + + public int ExecuteUpdate(String query) { + int n = 0; + + if (DEBUG) + System.out.println("Executing update query '" + query + "'"); + + try { + n = stmt.executeUpdate(query); + + if (DEBUG) + System.out.println("Update Query '" + query + "' executed: n = " + n); + + } catch (SQLException se) { + SetErrmsg(se); + n = -1; + } catch (Exception e) { + SetErrmsg(e); + n = -2; + } //end try/catch + + return n; + } // end of ExecuteUpdate + + public int ReadNext() { + if (rs != null) { + try { + return rs.next() ? 1 : 0; + } catch (SQLException se) { + SetErrmsg(se); + return -1; + } //end try/catch + + } else + return 0; + + } // end of ReadNext + + public boolean Fetch(int row) { + if (rs != null) { + try { + return rs.absolute(row); + } catch (SQLException se) { + SetErrmsg(se); + return false; + } //end try/catch + + } else + return false; + + } // end of Fetch + + public String ColumnName(int n) { + if (rsmd == null) { + System.out.println("No result metadata"); + } else try { + return rsmd.getColumnLabel(n); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return null; + } // end of ColumnName + + public int ColumnType(int n, String name) { + if (rsmd == null) { + System.out.println("No result metadata"); + } else try { + if (n == 0) + n = rs.findColumn(name); + + return rsmd.getColumnType(n); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return 666; // Not a type + } // end of ColumnType + + public String ColumnDesc(int n, int[] val) { + if (rsmd == null) { + System.out.println("No result metadata"); + return null; + } else try { + val[0] = rsmd.getColumnType(n); + val[1] = rsmd.getPrecision(n); + val[2] = rsmd.getScale(n); + val[3] = rsmd.isNullable(n); + return rsmd.getColumnLabel(n); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return null; + } // end of ColumnDesc + + public String StringField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getString(n) : rs.getString(name); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return null; + } // end of StringField + + public int IntField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getInt(n) : rs.getInt(name); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return 0; + } // end of IntField + + public long BigintField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + BigDecimal bigDecimal = (n > 0) ? rs.getBigDecimal(n) : rs.getBigDecimal(name); + return bigDecimal != null ? bigDecimal.longValue() : 0; + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return 0; + } // end of BiginttField + + public double DoubleField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getDouble(n) : rs.getDouble(name); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return 0.; + } // end of DoubleField + + public float FloatField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getFloat(n) : rs.getFloat(name); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return 0; + } // end of FloatField + + public boolean BooleanField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getBoolean(n) : rs.getBoolean(name); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return false; + } // end of BooleanField + + public Date DateField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getDate(n) : rs.getDate(name); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return null; + } // end of DateField + + public Time TimeField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getTime(n) : rs.getTime(name); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return null; + } // end of TimeField + + public Timestamp TimestampField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getTimestamp(n) : rs.getTimestamp(name); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return null; + } // end of TimestampField + + public String ObjectField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getObject(n).toString() : rs.getObject(name).toString(); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return null; + } // end of ObjectField + + public int GetDrivers(String[] s, int mxs) { + int n = 0; + List drivers = Collections.list(DriverManager.getDrivers()); + int size = Math.min(mxs, drivers.size()); + + for (int i = 0; i < size; i++) { + Driver driver = (Driver)drivers.get(i); + + // Get name of driver + s[n++] = driver.getClass().getName(); + + // Get version info + s[n++] = driver.getMajorVersion() + "." + driver.getMinorVersion(); + s[n++] = driver.jdbcCompliant() ? "Yes" : "No"; + s[n++] = driver.toString(); + } // endfor i + + return size; + } // end of GetDrivers + + /** + * Adds the specified path to the java library path + * from Fahd Shariff blog + * + * @param pathToAdd the path to add + static public int addLibraryPath(String pathToAdd) { + System.out.println("jpath = " + pathToAdd); + + try { + Field usrPathsField = ClassLoader.class.getDeclaredField("usr_paths"); + usrPathsField.setAccessible(true); + + //get array of paths + String[] paths = (String[])usrPathsField.get(null); + + //check if the path to add is already present + for (String path : paths) { + System.out.println("path = " + path); + + if (path.equals(pathToAdd)) + return -5; + + } // endfor path + + //add the new path + String[] newPaths = Arrays.copyOf(paths, paths.length + 1); + newPaths[paths.length] = pathToAdd; + usrPathsField.set(null, newPaths); + System.setProperty("java.library.path", + System.getProperty("java.library.path") + File.pathSeparator + pathToAdd); + Field fieldSysPath = ClassLoader.class.getDeclaredField("sys_paths"); + fieldSysPath.setAccessible(true); + fieldSysPath.set(null, null); + } catch (Exception e) { + SetErrmsg(e); + return -1; + } // end try/catch + + return 0; + } // end of addLibraryPath + */ + +} // end of class JdbcDSInterface diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc index a6e52bdee9a..45ad4a484e1 100644 --- a/storage/connect/ha_connect.cc +++ b/storage/connect/ha_connect.cc @@ -195,6 +195,7 @@ extern "C" { #if defined(JDBC_SUPPORT) char *JvmPath; char *ClassPath; + char *Wrapper; #endif // JDBC_SUPPORT #if defined(__WIN__) @@ -1141,7 +1142,7 @@ int GetIntegerTableOption(PGLOBAL g, PTOS options, char *opname, int idef) else if (!stricmp(opname, "Compressed")) opval= (options->compressed); - if (opval == (ulonglong)NO_IVAL) { + if ((ulonglong) opval == (ulonglong)NO_IVAL) { char *pv; if ((pv= GetListOption(g, opname, options->oplist))) @@ -1960,7 +1961,7 @@ int ha_connect::MakeRecord(char *buf) if (trace > 1) htrc("Maps: read=%08X write=%08X vcol=%08X defr=%08X defw=%08X\n", *table->read_set->bitmap, *table->write_set->bitmap, - *table->vcol_set->bitmap, + (table->vcol_set) ? *table->vcol_set->bitmap : 0, *table->def_read_set.bitmap, *table->def_write_set.bitmap); // Avoid asserts in field::store() for columns that are not updated @@ -4806,7 +4807,11 @@ int ha_connect::delete_or_rename_table(const char *name, const char *to) DBUG_RETURN(rc); // Get the share info from the .frm file - if (!open_table_def(thd, share)) { + Dummy_error_handler error_handler; + thd->push_internal_handler(&error_handler); + bool got_error= open_table_def(thd, share); + thd->pop_internal_handler(); + if (!got_error) { // Now we can work if ((pos= share->option_struct)) { if (check_privileges(thd, pos, db)) @@ -4819,12 +4824,6 @@ int ha_connect::delete_or_rename_table(const char *name, const char *to) } // endif open_table_def -// This below was done to avoid DBUG_ASSERT in some case that -// we don't know anymore what they were. It was suppressed because -// it did cause assertion in other cases (see MDEV-7935) -// } else // Avoid infamous DBUG_ASSERT -// thd->get_stmt_da()->reset_diagnostics_area(); - free_table_share(share); } else // Temporary file ok= true; @@ -5156,7 +5155,7 @@ static int connect_assisted_discovery(handlerton *, THD* thd, char *nsp= NULL, *cls= NULL; #endif // __WIN__ int port= 0, hdr= 0, mxr= 0, mxe= 0, rc= 0; - int cop __attribute__((unused))= 0; + int cop __attribute__((unused))= 0, lrecl= 0; #if defined(ODBC_SUPPORT) POPARM sop= NULL; char *ucnc= NULL; @@ -5620,7 +5619,7 @@ static int connect_assisted_discovery(handlerton *, THD* thd, len= crp->Length; dec= crp->Prec; flg= crp->Flag; - v= crp->Var; + v= (crp->Kdata->IsUnsigned()) ? 'U' : crp->Var; tm= (crp->Kdata->IsNullable()) ? 0 : NOT_NULL_FLAG; if (!len && typ == TYPE_STRING) @@ -6876,6 +6875,12 @@ static MYSQL_SYSVAR_STR(class_path, ClassPath, "Java class path", // check_class_path, update_class_path, NULL, NULL, NULL); + +static MYSQL_SYSVAR_STR(java_wrapper, Wrapper, + PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_MEMALLOC, + "Java wrapper class", + // check_class_path, update_class_path, + NULL, NULL, "JdbcInterface"); #endif // JDBC_SUPPORT @@ -6899,6 +6904,7 @@ static struct st_mysql_sys_var* connect_system_variables[]= { #if defined(JDBC_SUPPORT) MYSQL_SYSVAR(jvm_path), MYSQL_SYSVAR(class_path), + MYSQL_SYSVAR(java_wrapper), #endif // JDBC_SUPPORT NULL }; @@ -6917,6 +6923,6 @@ maria_declare_plugin(connect) NULL, /* status variables */ connect_system_variables, /* system variables */ "1.04.0006", /* string version */ - MariaDB_PLUGIN_MATURITY_BETA /* maturity */ + MariaDB_PLUGIN_MATURITY_GAMMA /* maturity */ } maria_declare_plugin_end; diff --git a/storage/connect/jdbconn.cpp b/storage/connect/jdbconn.cpp index 23bd64bfb88..7a508cd989b 100644 --- a/storage/connect/jdbconn.cpp +++ b/storage/connect/jdbconn.cpp @@ -53,8 +53,9 @@ extern "C" HINSTANCE s_hModule; // Saved module handle #endif // !__WIN__ int GetConvSize(); -extern char *JvmPath; // The connect_jvm_path global variable value -extern char *ClassPath; // The connect_class_path global variable value +extern char *JvmPath; // The connect_jvm_path global variable value +extern char *ClassPath; // The connect_class_path global variable value +extern char *Wrapper; // The connect_java_wrapper global variable value /***********************************************************************/ /* Static JDBConn objects. */ @@ -645,8 +646,8 @@ JDBConn::JDBConn(PGLOBAL g, TDBJDBC *tdbp) m_Tdb = tdbp; jvm = nullptr; // Pointer to the JVM (Java Virtual Machine) env= nullptr; // Pointer to native interface - jdi = nullptr; // Pointer to the JdbcInterface class - job = nullptr; // The JdbcInterface class object + jdi = nullptr; // Pointer to the java wrapper class + job = nullptr; // The java wrapper class object xqid = xuid = xid = grs = readid = fetchid = typid = errid = nullptr; prepid = xpid = pcid = nullptr; chrfldid = intfldid = dblfldid = fltfldid = datfldid = bigfldid = nullptr; @@ -1028,11 +1029,11 @@ int JDBConn::Open(PJPARM sop) printf("JVM Version %d.%d\n", ((ver>>16)&0x0f), (ver&0x0f)); #endif //_DEBUG - // try to find the JdbcInterface class - jdi = env->FindClass("JdbcInterface"); + // try to find the java wrapper class + jdi = env->FindClass(Wrapper); if (jdi == nullptr) { - strcpy(g->Message, "ERROR: class JdbcInterface not found !"); + sprintf(g->Message, "ERROR: class %s not found!", Wrapper); return RC_FX; } // endif jdi @@ -1078,7 +1079,7 @@ int JDBConn::Open(PJPARM sop) jmethodID ctor = env->GetMethodID(jdi, "", "()V"); if (ctor == nullptr) { - strcpy(g->Message, "ERROR: JdbcInterface constructor not found !"); + sprintf(g->Message, "ERROR: %s constructor not found!", Wrapper); return RC_FX; } else job = env->NewObject(jdi, ctor); @@ -1087,7 +1088,7 @@ int JDBConn::Open(PJPARM sop) // we can then search for the method we want to call, // and invoke it for the object: if (job == nullptr) { - strcpy(g->Message, "JdbcInterface class object not constructed !"); + sprintf(g->Message, "%s class object not constructed!", Wrapper); return RC_FX; } // endif job @@ -1328,6 +1329,7 @@ void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val) case 4: // INTEGER case 5: // SMALLINT case -6: // TINYINT + case -7: // BIT if (!gmID(g, intfldid, "IntField", "(ILjava/lang/String;)I")) val->SetValue((int)env->CallIntMethod(job, intfldid, rank, jn)); else @@ -1393,6 +1395,9 @@ void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val) break; case java.sql.Types.BOOLEAN: System.out.print(jdi.BooleanField(i)); */ + case 0: // NULL + val->SetNull(true); + // passthru default: val->Reset(); } // endswitch Type diff --git a/storage/connect/jdbconn.h b/storage/connect/jdbconn.h index a7744ba6ba1..db8a11716e5 100644 --- a/storage/connect/jdbconn.h +++ b/storage/connect/jdbconn.h @@ -152,8 +152,8 @@ protected: TDBJDBC *m_Tdb; JavaVM *jvm; // Pointer to the JVM (Java Virtual Machine) JNIEnv *env; // Pointer to native interface - jclass jdi; // Pointer to the JdbcInterface class - jobject job; // The JdbcInterface class object + jclass jdi; // Pointer to the java wrapper class + jobject job; // The java wrapper class object jmethodID xqid; // The ExecuteQuery method ID jmethodID xuid; // The ExecuteUpdate method ID jmethodID xid; // The Execute method ID diff --git a/storage/connect/jsonudf.cpp b/storage/connect/jsonudf.cpp index 26965672ba4..0bc964d7351 100644 --- a/storage/connect/jsonudf.cpp +++ b/storage/connect/jsonudf.cpp @@ -1433,7 +1433,7 @@ static my_bool CheckMemory(PGLOBAL g, UDF_INIT *initid, UDF_ARGS *args, uint n, char *p = args->args[0]; // Is this a file name? - if (!strchr("[{ \t\r\n", *p) && (len = GetFileLength(p))) + if (p && !strchr("[{ \t\r\n", *p) && (len = GetFileLength(p))) ml += len * (M + 1); else ml += args->lengths[0] * M; @@ -1805,7 +1805,20 @@ my_bool json_array_add_values_init(UDF_INIT *initid, UDF_ARGS *args, char *messa } else CalcLen(args, false, reslen, memlen); - return JsonInit(initid, args, message, true, reslen, memlen); + if (!JsonInit(initid, args, message, true, reslen, memlen)) { + PGLOBAL g = (PGLOBAL)initid->ptr; + + // This is a constant function + g->N = (initid->const_item) ? 1 : 0; + + // This is to avoid double execution when using prepared statements + if (IsJson(args, 0) > 1) + initid->const_item = 0; + + return false; + } else + return true; + } // end of json_array_add_values_init char *json_array_add_values(UDF_INIT *initid, UDF_ARGS *args, char *result, @@ -1850,7 +1863,7 @@ char *json_array_add_values(UDF_INIT *initid, UDF_ARGS *args, char *result, } // endif str // Keep result of constant function - g->Xchk = (initid->const_item) ? str : NULL; + g->Xchk = (g->N) ? str : NULL; } else str = (char*)g->Xchk; @@ -1873,7 +1886,7 @@ void json_array_add_values_deinit(UDF_INIT* initid) /*********************************************************************************/ my_bool json_array_add_init(UDF_INIT *initid, UDF_ARGS *args, char *message) { - unsigned long reslen, memlen; + unsigned long reslen, memlen; if (args->arg_count < 2) { strcpy(message, "This function must have at least 2 arguments"); @@ -1884,7 +1897,20 @@ my_bool json_array_add_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } else CalcLen(args, false, reslen, memlen, true); - return JsonInit(initid, args, message, true, reslen, memlen); + if (!JsonInit(initid, args, message, true, reslen, memlen)) { + PGLOBAL g = (PGLOBAL)initid->ptr; + + // This is a constant function + g->N = (initid->const_item) ? 1 : 0; + + // This is to avoid double execution when using prepared statements + if (IsJson(args, 0) > 1) + initid->const_item = 0; + + return false; + } else + return true; + } // end of json_array_add_init char *json_array_add(UDF_INIT *initid, UDF_ARGS *args, char *result, @@ -1930,7 +1956,7 @@ char *json_array_add(UDF_INIT *initid, UDF_ARGS *args, char *result, if (!str) str = MakePSZ(g, args, 0); - if (initid->const_item) + if (g->N) // Keep result of constant function g->Xchk = str; @@ -1966,7 +1992,20 @@ my_bool json_array_delete_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } else CalcLen(args, false, reslen, memlen, true); - return JsonInit(initid, args, message, true, reslen, memlen); + if (!JsonInit(initid, args, message, true, reslen, memlen)) { + PGLOBAL g = (PGLOBAL)initid->ptr; + + // This is a constant function + g->N = (initid->const_item) ? 1 : 0; + + // This is to avoid double execution when using prepared statements + if (IsJson(args, 0) > 1) + initid->const_item = 0; + + return false; + } else + return true; + } // end of json_array_delete_init char *json_array_delete(UDF_INIT *initid, UDF_ARGS *args, char *result, @@ -2008,7 +2047,7 @@ char *json_array_delete(UDF_INIT *initid, UDF_ARGS *args, char *result, if (!str) str = MakePSZ(g, args, 0); - if (initid->const_item) + if (g->N) // Keep result of constant function g->Xchk = str; @@ -2184,7 +2223,20 @@ my_bool json_object_add_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } else CalcLen(args, true, reslen, memlen, true); - return JsonInit(initid, args, message, true, reslen, memlen); + if (!JsonInit(initid, args, message, true, reslen, memlen)) { + PGLOBAL g = (PGLOBAL)initid->ptr; + + // This is a constant function + g->N = (initid->const_item) ? 1 : 0; + + // This is to avoid double execution when using prepared statements + if (IsJson(args, 0) > 1) + initid->const_item = 0; + + return false; + } else + return true; + } // end of json_object_add_init char *json_object_add(UDF_INIT *initid, UDF_ARGS *args, char *result, @@ -2227,7 +2279,7 @@ char *json_object_add(UDF_INIT *initid, UDF_ARGS *args, char *result, if (!str) str = MakePSZ(g, args, 0); - if (initid->const_item) + if (g->N) // Keep result of constant function g->Xchk = str; @@ -2266,7 +2318,20 @@ my_bool json_object_delete_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } else CalcLen(args, true, reslen, memlen, true); - return JsonInit(initid, args, message, true, reslen, memlen); + if (!JsonInit(initid, args, message, true, reslen, memlen)) { + PGLOBAL g = (PGLOBAL)initid->ptr; + + // This is a constant function + g->N = (initid->const_item) ? 1 : 0; + + // This is to avoid double execution when using prepared statements + if (IsJson(args, 0) > 1) + initid->const_item = 0; + + return false; + } else + return true; + } // end of json_object_delete_init char *json_object_delete(UDF_INIT *initid, UDF_ARGS *args, char *result, @@ -2307,7 +2372,7 @@ char *json_object_delete(UDF_INIT *initid, UDF_ARGS *args, char *result, if (!str) str = MakePSZ(g, args, 0); - if (initid->const_item) + if (g->N) // Keep result of constant function g->Xchk = str; @@ -2605,7 +2670,20 @@ my_bool json_item_merge_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } else CalcLen(args, false, reslen, memlen, true); - return JsonInit(initid, args, message, true, reslen, memlen); + if (!JsonInit(initid, args, message, true, reslen, memlen)) { + PGLOBAL g = (PGLOBAL)initid->ptr; + + // This is a constant function + g->N = (initid->const_item) ? 1 : 0; + + // This is to avoid double execution when using prepared statements + if (IsJson(args, 0) > 1) + initid->const_item = 0; + + return false; + } else + return true; + } // end of json_item_merge_init char *json_item_merge(UDF_INIT *initid, UDF_ARGS *args, char *result, @@ -2651,7 +2729,7 @@ char *json_item_merge(UDF_INIT *initid, UDF_ARGS *args, char *result, if (!str) str = MakePSZ(g, args, 0); - if (initid->const_item) + if (g->N) // Keep result of constant function g->Xchk = str; @@ -3552,11 +3630,11 @@ char *handle_item(UDF_INIT *initid, UDF_ARGS *args, char *result, PGLOBAL g = (PGLOBAL)initid->ptr; PGLOBAL gb = GetMemPtr(g, args, 0); - if (g->N) { + if (g->Alchecked) { str = (char*)g->Activityp; goto fin; - } else if (initid->const_item) - g->N = 1; + } else if (g->N) + g->Alchecked = 1; if (!strcmp(result, "$set")) w = 0; @@ -3632,7 +3710,7 @@ char *handle_item(UDF_INIT *initid, UDF_ARGS *args, char *result, if (!(str = MakeResult(g, args, jsp, INT_MAX32))) str = MakePSZ(g, args, 0); - if (initid->const_item) + if (g->N) // Keep result of constant function g->Activityp = (PACTIVITY)str; @@ -3677,7 +3755,21 @@ my_bool json_set_item_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } else if (n != 3) memlen += args->lengths[0] * 3; - return JsonInit(initid, args, message, true, reslen, memlen); + if (!JsonInit(initid, args, message, true, reslen, memlen)) { + PGLOBAL g = (PGLOBAL)initid->ptr; + + // This is a constant function + g->N = (initid->const_item) ? 1 : 0; + + // This is to avoid double execution when using prepared statements + if (IsJson(args, 0) > 1) + initid->const_item = 0; + + g->Alchecked = 0; + return false; + } else + return true; + } // end of json_set_item_init char *json_set_item(UDF_INIT *initid, UDF_ARGS *args, char *result, @@ -3742,8 +3834,8 @@ my_bool json_file_init(UDF_INIT *initid, UDF_ARGS *args, char *message) if (args->arg_count < 1 || args->arg_count > 4) { strcpy(message, "This function only accepts 1 to 4 arguments"); return true; - } else if (!args->args[0] || args->arg_type[0] != STRING_RESULT) { - strcpy(message, "First argument must be a constant string (file name)"); + } else if (args->arg_type[0] != STRING_RESULT) { + strcpy(message, "First argument must be a string (file name)"); return true; } // endif's args[0] @@ -3761,7 +3853,12 @@ my_bool json_file_init(UDF_INIT *initid, UDF_ARGS *args, char *message) initid->maybe_null = 1; CalcLen(args, false, reslen, memlen); - fl = GetFileLength(args->args[0]); + + if (args->args[0]) + fl = GetFileLength(args->args[0]); + else + fl = 100; // What can be done here? + reslen += fl; if (initid->const_item) @@ -4020,7 +4117,18 @@ void jbin_array_deinit(UDF_INIT* initid) /*********************************************************************************/ my_bool jbin_array_add_values_init(UDF_INIT *initid, UDF_ARGS *args, char *message) { - return json_array_add_values_init(initid, args, message); + unsigned long reslen, memlen; + + if (args->arg_count < 2) { + strcpy(message, "This function must have at least 2 arguments"); + return true; + } else if (!IsJson(args, 0) && args->arg_type[0] != STRING_RESULT) { + strcpy(message, "First argument must be a json string or item"); + return true; + } else + CalcLen(args, false, reslen, memlen); + + return JsonInit(initid, args, message, true, reslen, memlen); } // end of jbin_array_add_values_init char *jbin_array_add_values(UDF_INIT *initid, UDF_ARGS *args, char *result, @@ -4090,7 +4198,18 @@ void jbin_array_add_values_deinit(UDF_INIT* initid) /*********************************************************************************/ my_bool jbin_array_add_init(UDF_INIT *initid, UDF_ARGS *args, char *message) { - return json_array_add_init(initid, args, message); + unsigned long reslen, memlen; + + if (args->arg_count < 2) { + strcpy(message, "This function must have at least 2 arguments"); + return true; + } else if (!IsJson(args, 0)) { + strcpy(message, "First argument must be a json item"); + return true; + } else + CalcLen(args, false, reslen, memlen, true); + + return JsonInit(initid, args, message, true, reslen, memlen); } // end of jbin_array_add_init char *jbin_array_add(UDF_INIT *initid, UDF_ARGS *args, char *result, @@ -4160,8 +4279,19 @@ void jbin_array_add_deinit(UDF_INIT* initid) /*********************************************************************************/ my_bool jbin_array_delete_init(UDF_INIT *initid, UDF_ARGS *args, char *message) { - return json_array_delete_init(initid, args, message); -} // end of jbin_array_delete_init + unsigned long reslen, memlen; + + if (args->arg_count < 2) { + strcpy(message, "This function must have at least 2 arguments"); + return true; + } else if (!IsJson(args, 0)) { + strcpy(message, "First argument must be a json item"); + return true; + } else + CalcLen(args, false, reslen, memlen, true); + + return JsonInit(initid, args, message, true, reslen, memlen); + } // end of jbin_array_delete_init char *jbin_array_delete(UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned long *res_length, char *is_null, char *error) @@ -4383,8 +4513,19 @@ void jbin_object_key_deinit(UDF_INIT* initid) /*********************************************************************************/ my_bool jbin_object_add_init(UDF_INIT *initid, UDF_ARGS *args, char *message) { - return json_object_add_init(initid, args, message); -} // end of jbin_object_add_init + unsigned long reslen, memlen; + + if (args->arg_count < 2) { + strcpy(message, "This function must have at least 2 arguments"); + return true; + } else if (!IsJson(args, 0)) { + strcpy(message, "First argument must be a json item"); + return true; + } else + CalcLen(args, true, reslen, memlen, true); + + return JsonInit(initid, args, message, true, reslen, memlen); + } // end of jbin_object_add_init char *jbin_object_add(UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned long *res_length, char *is_null, char *error) @@ -4449,8 +4590,22 @@ void jbin_object_add_deinit(UDF_INIT* initid) /*********************************************************************************/ my_bool jbin_object_delete_init(UDF_INIT *initid, UDF_ARGS *args, char *message) { - return json_object_delete_init(initid, args, message); -} // end of jbin_object_delete_init + unsigned long reslen, memlen; + + if (args->arg_count < 2) { + strcpy(message, "This function must have 2 or 3 arguments"); + return true; + } else if (!IsJson(args, 0)) { + strcpy(message, "First argument must be a json item"); + return true; + } else if (args->arg_type[1] != STRING_RESULT) { + strcpy(message, "Second argument must be a key string"); + return true; + } else + CalcLen(args, true, reslen, memlen, true); + + return JsonInit(initid, args, message, true, reslen, memlen); + } // end of jbin_object_delete_init char *jbin_object_delete(UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned long *res_length, char *is_null, char *error) @@ -4659,8 +4814,22 @@ void jbin_get_item_deinit(UDF_INIT* initid) /*********************************************************************************/ my_bool jbin_item_merge_init(UDF_INIT *initid, UDF_ARGS *args, char *message) { - return json_item_merge_init(initid, args, message); -} // end of jbin_item_merge_init + unsigned long reslen, memlen; + + if (args->arg_count < 2) { + strcpy(message, "This function must have at least 2 arguments"); + return true; + } else if (!IsJson(args, 0)) { + strcpy(message, "First argument must be a json item"); + return true; + } else if (!IsJson(args, 1)) { + strcpy(message, "Second argument must be a json item"); + return true; + } else + CalcLen(args, false, reslen, memlen, true); + + return JsonInit(initid, args, message, true, reslen, memlen); + } // end of jbin_item_merge_init char *jbin_item_merge(UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned long *res_length, char *is_null, char *error) @@ -4820,8 +4989,31 @@ fin: /*********************************************************************************/ my_bool jbin_set_item_init(UDF_INIT *initid, UDF_ARGS *args, char *message) { - return json_set_item_init(initid, args, message); -} // end of jbin_set_item_init + unsigned long reslen, memlen; + int n = IsJson(args, 0); + + if (!(args->arg_count % 2)) { + strcpy(message, "This function must have an odd number of arguments"); + return true; + } else if (!n && args->arg_type[0] != STRING_RESULT) { + strcpy(message, "First argument must be a json item"); + return true; + } else + CalcLen(args, false, reslen, memlen); + + if (n == 2 && args->args[0]) { + char fn[_MAX_PATH]; + long fl; + + memcpy(fn, args->args[0], args->lengths[0]); + fn[args->lengths[0]] = 0; + fl = GetFileLength(fn); + memlen += fl * 3; + } else if (n != 3) + memlen += args->lengths[0] * 3; + + return JsonInit(initid, args, message, true, reslen, memlen); + } // end of jbin_set_item_init char *jbin_set_item(UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned long *res_length, char *is_null, char *p) @@ -4992,7 +5184,7 @@ my_bool json_serialize_init(UDF_INIT *initid, UDF_ARGS *args, char *message) if (args->arg_count != 1) { strcpy(message, "This function must have 1 argument"); return true; - } else if (IsJson(args, 0) != 3) { + } else if (args->args[0] && IsJson(args, 0) != 3) { strcpy(message, "Argument must be a Jbin tree"); return true; } else @@ -5002,21 +5194,27 @@ my_bool json_serialize_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // end of json_serialize_init char *json_serialize(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *, char *) + unsigned long *res_length, char *, char *error) { char *str; PGLOBAL g = (PGLOBAL)initid->ptr; if (!g->Xchk) { - PBSON bsp = (PBSON)args->args[0]; + if (IsJson(args, 0) == 3) { + PBSON bsp = (PBSON)args->args[0]; - JsonSubSet(g); + JsonSubSet(g); - if (!(str = Serialize(g, bsp->Jsp, NULL, 0))) - str = strcpy(result, g->Message); + if (!(str = Serialize(g, bsp->Jsp, NULL, 0))) + str = strcpy(result, g->Message); + + // Keep result of constant function + g->Xchk = (initid->const_item) ? str : NULL; + } else { + *error = 1; + str = strcpy(result, "Argument is not a Jbin tree"); + } // endif - // Keep result of constant function - g->Xchk = (initid->const_item) ? str : NULL; } else str = (char*)g->Xchk; @@ -5037,21 +5235,28 @@ my_bool envar_init(UDF_INIT *initid, UDF_ARGS *args, char *message) if (args->arg_count != 1) { strcpy(message, "Unique argument must be an environment variable name"); return true; - } else + } else { + initid->maybe_null = true; return false; + } // endif count } // end of envar_init char *envar(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *, char *) + unsigned long *res_length, char *is_null, char *) { char *str, name[256]; int n = MY_MIN(args->lengths[0], sizeof(name) - 1); memcpy(name, args->args[0], n); name[n] = 0; - str = getenv(name); - *res_length = (str) ? strlen(str) : 0; + + if (!(str = getenv(name))) { + *res_length = 0; + *is_null = 1; + } else + *res_length = strlen(str); + return str; } // end of envar diff --git a/storage/connect/myconn.cpp b/storage/connect/myconn.cpp index e9bd64cf8e6..b844d68e1cd 100644 --- a/storage/connect/myconn.cpp +++ b/storage/connect/myconn.cpp @@ -901,8 +901,12 @@ PQRYRES MYSQLC::GetResult(PGLOBAL g, bool pdb) if (fld->flags & NOT_NULL_FLAG) crp->Nulls = NULL; else { - crp->Nulls = (char*)PlugSubAlloc(g, NULL, m_Rows); - memset(crp->Nulls, ' ', m_Rows); + if (m_Rows) { + crp->Nulls = (char*)PlugSubAlloc(g, NULL, m_Rows); + memset(crp->Nulls, ' ', m_Rows); + } // endif m_Rows + + crp->Kdata->SetNullable(true); } // endelse fld->flags } // endfor fld diff --git a/storage/connect/plugutil.c b/storage/connect/plugutil.c index 38e28a171b2..2551b603349 100644 --- a/storage/connect/plugutil.c +++ b/storage/connect/plugutil.c @@ -516,7 +516,9 @@ void *PlugSubAlloc(PGLOBAL g, void *memp, size_t size) if (trace) htrc("PlugSubAlloc: %s\n", g->Message); - longjmp(g->jumper[g->jump_level], 1); + /* Nothing we can do if longjmp is not initialized. */ + assert(g->jump_level >= 0); + longjmp(g->jumper[g->jump_level], 1); } /* endif size OS32 code */ /*********************************************************************/