Changeset: 1f2731776e1b for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=1f2731776e1b
Modified Files:
        java/src/main/java/nl/cwi/monetdb/jdbc/MonetResultSet.java
Branch: default
Log Message:

Implement a faster version of ResultSet.getObject(int columnIndex).
The previous implementation invoked the complex and slow method: getObject(int 
i, Map<String,Class<?>> map)
As this method is used and called a lot (mostly by generic JDBC applications)
it is important to make it as fast as possible.
Simple tests showed it is now 25% faster.


diffs (189 lines):

diff --git a/java/src/main/java/nl/cwi/monetdb/jdbc/MonetResultSet.java 
b/java/src/main/java/nl/cwi/monetdb/jdbc/MonetResultSet.java
--- a/java/src/main/java/nl/cwi/monetdb/jdbc/MonetResultSet.java
+++ b/java/src/main/java/nl/cwi/monetdb/jdbc/MonetResultSet.java
@@ -1670,31 +1670,176 @@ public class MonetResultSet extends Mone
        /**
         * Gets the value of the designated column in the current row of this
         * ResultSet object as an Object in the Java programming language.
-        * 
+        *
         * This method will return the value of the given column as a Java 
object.
         * The type of the Java object will be the default Java object type
         * corresponding to the column's SQL type, following the mapping for
         * built-in types specified in the JDBC specification. If the value is
         * an SQL NULL, the driver returns a Java null.
-        * 
+        *
         * This method may also be used to read database-specific abstract data
         * types. In the JDBC 2.0 API, the behavior of method getObject is 
extended
         * to materialize data of SQL user-defined types. When a column 
contains a
         * structured or distinct value, the behavior of this method is as if it
-        * were a call to: getObject(columnIndex,
-        * this.getStatement().getConnection().getTypeMap()).
+        * were a call to: getObject(columnIndex, 
this.getStatement().getConnection().getTypeMap()).
         *
         * @param columnIndex the first column is 1, the second is 2, ...
-        * @return a java.lang.Object holding the column value
+        * @return a java.lang.Object holding the column value or null
         * @throws SQLException if a database access error occurs
         */
        @Override
        public Object getObject(int columnIndex) throws SQLException {
-               /* statement is null for MonetVirtualResultSet such as the ones 
that hold generated keys */
-               if (this.getStatement() == null) {
-                       return getObject(columnIndex, new HashMap<String, 
Class<?>>());
+               // Many generic JDBC programs use getObject(colnr) to retrieve 
value objects from a resultset
+               // For speed the implementation should be as fast as possible, 
so avoid method calls (by inlining code) where possible
+               final String MonetDBType;
+               final int JdbcType;
+               try {
+                       if (tlp.values[columnIndex - 1] == null) {
+                               lastColumnRead = columnIndex - 1;
+                               return null;
+                       }
+                       MonetDBType = types[columnIndex - 1];
+                       JdbcType = getJavaType(MonetDBType);
+               } catch (IndexOutOfBoundsException e) {
+                       throw new SQLException("No such column " + columnIndex, 
"M1M05");
                }
-               return getObject(columnIndex, 
this.getStatement().getConnection().getTypeMap());
+
+               // for a few JdbcType cases we do not inline its code but 
invoke their getXxx(i) method:
+               switch(JdbcType) {
+                       case Types.DATE:
+                               return getDate(columnIndex);
+                       case Types.TIME:
+                               return getTime(columnIndex);
+                       case Types.TIMESTAMP:
+                               return getTimestamp(columnIndex);
+                       case Types.BINARY:
+                       case Types.VARBINARY:
+                       case Types.LONGVARBINARY: // MonetDB doesn't use type 
LONGVARBINARY, it's here for completeness
+                               return getBytes(columnIndex);
+                       // for other cases continue and use inline code
+               }
+
+               // get the String value once and use it in all below JdbcType 
cases
+               final String val = getString(columnIndex);
+               if (val == null)
+                       return null;
+
+               switch(JdbcType) {
+                       case Types.BIT: // MonetDB doesn't use type BInary 
digiT, it's here for completeness
+                       case Types.TINYINT:
+                       case Types.SMALLINT:
+                               try {
+                                       return Short.valueOf(val);
+                               } catch (NumberFormatException e) {
+                                       return val;
+                               }
+                       case Types.INTEGER:
+                               try {
+                                       return Integer.valueOf(val);
+                               } catch (NumberFormatException e) {
+                                       return val;
+                               }
+                       case Types.BIGINT:
+                               try {
+                                       return Long.valueOf(val);
+                               } catch (NumberFormatException e) {
+                                       return val;
+                               }
+                       case Types.DOUBLE:
+                       case Types.FLOAT:
+                               try {
+                                       return Double.valueOf(val);
+                               } catch (NumberFormatException e) {
+                                       return val;
+                               }
+                       case Types.REAL:
+                               try {
+                                       return Float.valueOf(val);
+                               } catch (NumberFormatException e) {
+                                       return val;
+                               }
+                       case Types.DECIMAL:
+                       case Types.NUMERIC:
+                               try {
+                                       return new BigDecimal(val);
+                               } catch (NumberFormatException e) {
+                                       return val;
+                               }
+                       case Types.BOOLEAN:
+                               return Boolean.valueOf(val);
+                       case Types.VARCHAR:
+                       {
+                               // The MonetDB types: inet, json, url and uuid 
are all mapped to Types.VARCHAR in MonetDriver.typeMap
+                               // For these MonetDB types (except json, see 
comments below) we try to create objects of the corresponding class.
+                               // As in most cases when we get here the 
MonetDBtype will be "varchar". For efficiency we compare
+                               // the MonetDBtype first letter to see if we 
can skip the three .equals(MonetDBType) method calls.
+                               char firstletter = MonetDBType.charAt(0);
+                               if (firstletter == 'i') {
+                                       if ("inet".equals(MonetDBType)) {
+                                               try {
+                                                       
nl.cwi.monetdb.jdbc.types.INET inet_obj = new nl.cwi.monetdb.jdbc.types.INET();
+                                                       
inet_obj.fromString(val);
+                                                       return inet_obj;
+                                               } catch (Exception exc) {
+                                                       // ignore exception and 
just return the val String object
+                                                       return val;
+                                               }
+                                       }
+                               }
+                               else if (firstletter == 'u') {
+                                       if ("url".equals(MonetDBType)) {
+                                               try {
+                                                       
nl.cwi.monetdb.jdbc.types.URL url_obj = new nl.cwi.monetdb.jdbc.types.URL();
+                                                       url_obj.fromString(val);
+                                                       return url_obj;
+                                               } catch (MalformedURLException 
exc) {
+                                                       // ignore exception and 
just return the val String object
+                                                       return val;
+                                               } catch (Exception exc) {
+                                                       // ignore exception and 
just return the val String object
+                                                       return val;
+                                               }
+                                       }
+                                       if ("uuid".equals(MonetDBType)) {
+                                               try {
+                                                       return 
java.util.UUID.fromString(val);
+                                               } catch 
(IllegalArgumentException exc) {
+                                                       // ignore exception and 
just return the val String object
+                                                       return val;
+                                               }
+                                       }
+                               }
+//                             else if (firstletter == 'j') {
+//                                     if ("json".equals(MonetDBType)) {
+                                               // There is no support for JSON 
in standard java class libraries.
+                                               // Possibly we could use 
org.json.simple.JSONObject or other/faster libs
+                                               // javax.json.Json is not 
released yet (see https://json-processing-spec.java.net/)
+                                               // see also 
https://github.com/fabienrenaud/java-json-benchmark
+                                               // Note that it would make our 
JDBC driver dependent of an external jar
+                                               // and we don't want that so 
simply return it as String object
+//                                             return val;
+//                                     }
+//                             }
+                               return val;
+                       }
+                       case Types.CHAR:
+                       case Types.LONGVARCHAR: // MonetDB doesn't use type 
LONGVARCHAR, it's here for completeness
+                               return val;
+                       case Types.CLOB:
+                               return new MonetClob(val);
+                       case Types.BLOB:
+                               return MonetBlob.create(val);
+                       case Types.OTHER:
+                       default:
+                               // When we get here the column type is a 
non-standard JDBC SQL type, possibly a User Defined Type.
+                               // Just call getObject(int, Map) for those rare 
cases.
+
+                               /* note: statement will be null for a 
MonetVirtualResultSet, such as the ones that hold generated keys */
+                               if (this.getStatement() == null) {      // 
prevent NPE
+                                       return val;
+                               }
+                               return getObject(columnIndex, 
this.getStatement().getConnection().getTypeMap());
+               }
        }
 
        private boolean classImplementsSQLData(Class<?> cl) {
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to