View Issue Details

IDProjectCategoryView StatusLast Update
0001334SymmetricDSBugpublic2014-02-03 01:53
Reportersnpe Assigned Tochenson  
Prioritynormal 
Status closedResolutionfixed 
Product Version3.5.0 
Target Version3.5.4Fixed in Version3.5.4 
Summary0001334: The issue with jConnect JDBC, SQL Anywhere and decimal value
DescriptionThe issue with jConnect JDBC, SQL Anywhere and decimal value

The evnironment:

- Sybase jConnect JDBC 7.07 ESD 0000005
- SQL Anywhere Personal Server Version 11.0.1.2044

There is, probably, the issue with other JConnect, SQL Anywhere and Sybase ASE versions.
The attached patch works only for SQL Anywhere and jConnect driver.

Test case:

- set SQL Anywhere using jConnect JDBC driver
- create the following table in SQL Anywhere:

create table test(
        id integer not null primary key,
        val numeric(6,2),
        val2 decimal(6,2)
);

- configure symmetric to replicate such table from some database to the SQL Anywhere
- enter a row in another database (I have tested with MySQL, but the issue can be reproduced using some database)

insert into test values (1,2.45, 2.45)

Expected value in SQL Anywhere would be (1,2.45, 2.45), but you will get (1,2.45, 2.0)

If the column is defined as decimal(x,y), the setBigDecimal from jConnect JDBC driver incorrectly truncates decimal values.
The issue doesn't happen if you define a column using numeric(x,y).
I have attached JUnit test case (TestJConnectBigDecimal.java) as well as a patch against symmetricds trunk (bigdecimalissue.diff).
The patch works in the following way:

- when SymmetricDS set a BigDecimal value, the patch checks if the SymmetricDS uses jConnect driver and if value type is BigDecimal.
If so, then it uses jConnect specific SybPreparedStatement.setBigDecimal(int parameterIndex, BigDecimal x, int precision, int scale) method to set this value.
The patch uses Java reflection to test the conditions and set valid BigDecimal value.
Steps To Reproduce- set SQL Anywhere using jConnect JDBC driver
- create the following table in SQL Anywhere:

create table test(
        id integer not null primary key,
        val numeric(6,2),
        val2 decimal(6,2)
);

- configure symmetric to replicate such table from some database to the SQL Anywhere
- enter a row in another database (I have tested with MySQL, but the issue can be reproduced using some database)

insert into test values (1,2.45, 2.45)

Expected value in SQL Anywhere would be (1,2.45, 2.45), but you will get (1,2.45, 2.0)

If the column is defined as decimal(x,y), the setBigDecimal from jConnect JDBC driver incorrectly truncates decimal values.
The issue doesn't happen if you define a column using numeric(x,y).
TagsNo tags attached.

Activities

snpe

2013-07-21 23:54

reporter  

TestJConnectBigDecimal.java (2,725 bytes)   
package rs.snpe.test;

import static org.junit.Assert.assertTrue;

import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;

public class TestJConnectBigDecimal {

	private static final int ID = 1;
	private static Connection con;
	public static BigDecimal testValue = new BigDecimal("5.45");

	@BeforeClass
	public static void setUp() {
		// connection details
		String url = "jdbc:sybase:Tds:localhost:2638/demo";
		String driver =  "com.sybase.jdbc4.jdbc.SybDriver";
		String user = "DBA";
		String pass =  "sql";
		// create a connection
		try {
			Class.forName(driver);
			con = DriverManager.getConnection(url, user, pass);
			con.setAutoCommit(true);
		} catch (Exception e) {
			e.printStackTrace();
			return;
		} 
		// create a table
		Statement stmt = null;
		
		try {
			String ddl = "create table testtable(id integer not null primary key, val decimal(6,2))"; 
			stmt = con.createStatement();
			stmt.execute(ddl);
			
		} catch (SQLException e) {
			e.printStackTrace();
			return;
		} finally {
			if (stmt != null) {
				try {
					stmt.close();
				} catch (SQLException e) {
					// ignore
				}
			}
		}
	}
	
	@AfterClass
	public static void tearDown() {
		// drop  table
		Statement stmt = null;

		try {
			String ddl = "drop table testtable";
			stmt = con.createStatement();
			stmt.execute(ddl);
		} catch (SQLException e) {
			e.printStackTrace();
			return;
		} finally {
			if (stmt != null) {
				try {
					stmt.close();
				} catch (SQLException e) {
					// ignore
				}
			}
			try {
				con.close();
			} catch (SQLException e) {
				// ignore
			}
		}
		
	}
	
	@Test
	public void test() throws SQLException {
		PreparedStatement stmt = null;
		try {
			stmt = con.prepareStatement("insert into testtable values(?,?)");
			stmt.setInt(1, ID);
			stmt.setBigDecimal(2, testValue);
			int ret = stmt.executeUpdate();
			assertTrue(ret == 1);
		} finally {
			if (stmt != null) {
				try {
					stmt.close();
				} catch (SQLException e) {
					// ignore
				}
			}
		}
		ResultSet rs = null;
		
		try {
			stmt = con.prepareStatement("select val from testtable where id=?");
			stmt.setInt(1, ID);
			rs = stmt.executeQuery();
			rs.next();
			BigDecimal ret = rs.getBigDecimal(1);
			assertTrue (testValue.equals(ret));
		} finally {
			if (rs != null) {
				try {
					rs.close();
				} catch (SQLException e) {
					// ignore
				}
			}
			if (stmt != null) {
				try {
					stmt.close();
				} catch (SQLException e) {
					// ignore
				}
			}
		}

	}

}
TestJConnectBigDecimal.java (2,725 bytes)   

snpe

2013-07-21 23:55

reporter  

bigdecimalissue.diff (3,703 bytes)   
Index: symmetric-jdbc/src/main/java/org/jumpmind/db/platform/sqlanywhere/SqlAnywhereJdbcSqlTemplate.java
===================================================================
--- symmetric-jdbc/src/main/java/org/jumpmind/db/platform/sqlanywhere/SqlAnywhereJdbcSqlTemplate.java	(revision 7553)
+++ symmetric-jdbc/src/main/java/org/jumpmind/db/platform/sqlanywhere/SqlAnywhereJdbcSqlTemplate.java	(working copy)
@@ -20,16 +20,29 @@
  */
 package org.jumpmind.db.platform.sqlanywhere;
 
+import java.lang.reflect.Method;
+import java.math.BigDecimal;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.sql.Statement;
+
 import javax.sql.DataSource;
 
+import org.apache.commons.dbcp.DelegatingPreparedStatement;
 import org.jumpmind.db.platform.DatabaseInfo;
 import org.jumpmind.db.sql.ISqlTemplate;
 import org.jumpmind.db.sql.JdbcSqlTemplate;
 import org.jumpmind.db.sql.SqlTemplateSettings;
 import org.jumpmind.db.sql.SymmetricLobHandler;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.jdbc.core.SqlTypeValue;
+import org.springframework.jdbc.support.lob.LobHandler;
 
 public class SqlAnywhereJdbcSqlTemplate extends JdbcSqlTemplate implements ISqlTemplate {
 
+	static final Logger log = LoggerFactory.getLogger(SqlAnywhereJdbcSqlTemplate.class);
+
     public SqlAnywhereJdbcSqlTemplate(DataSource dataSource, SqlTemplateSettings settings,
             SymmetricLobHandler lobHandler, DatabaseInfo databaseInfo) {
         super(dataSource, settings, lobHandler, databaseInfo);
@@ -41,5 +54,69 @@
         return false;
     }
 
+    @Override
+	public void setValues(PreparedStatement ps, Object[] args, int[] argTypes,
+			LobHandler lobHandler) throws SQLException {
+		super.setValues(ps, args, argTypes, lobHandler);
+		if (args == null || args.length <= 0) {
+			return;
+		}
+		Object object = getStmt(ps);
+		if (object == null) {
+			return;
+		}
+		Class clazz = object.getClass();
+		Class[] parameterTypes = new Class[] { int.class,
+				BigDecimal.class, int.class, int.class };
+		Method method = null;
+		try {
+			method = clazz.getMethod("setBigDecimal", parameterTypes);
+		} catch (Exception e) {
+			log.info("Can't find stmt.setBigDecimal(int,BigDecimal,int,int) method: " + e.getMessage() );
+			return;
+		} 
+		
+		for (int i = 0; i < args.length; i++) {
+			Object arg = args[i];
+			if (arg instanceof BigDecimal) {
+				try {
+					BigDecimal value = (BigDecimal) arg;
+					Object[] params = new Object[] { new Integer(i + 1), value,
+							new Integer(value.precision()),
+							new Integer(value.scale()) };
+					method.invoke(object, params);
+				} catch (Exception e) {
+					log.info("Can't execute stmt.setBigDecimal method: "
+							+ e.getMessage());
+				}
+			}
+		}
+	}
+	
+	private PreparedStatement getStmt(PreparedStatement ps) {
+		Statement stmt = ps;
+		while (stmt  instanceof DelegatingPreparedStatement) {
+			stmt = ((DelegatingPreparedStatement) stmt).getDelegate();
+		} 
+		if (stmt instanceof PreparedStatement) {
+			if ("com.sybase.jdbc4.jdbc.SybPreparedStatement".equals(stmt.getClass().getName())) {
+				return (PreparedStatement) stmt;
+			}
+		}
+		return null;
+	}
 
+	@Override
+	public void setValues(PreparedStatement ps, Object[] args)
+			throws SQLException {
+		super.setValues(ps, args);
+		if (args != null && args.length > 0) {
+			int[] argTypes = new int[args.length];
+			for (int i = 0; i < argTypes.length; i++) {
+				argTypes[i] = SqlTypeValue.TYPE_UNKNOWN;
+			}
+			setValues(ps, args, argTypes, getLobHandler().getDefaultHandler());
+		}
+	}
+
 }
bigdecimalissue.diff (3,703 bytes)   

chenson

2013-07-22 00:55

administrator   ~0000294

I think we recently ran into the same issue with numerics and patched it a different way. I do like your approach. I think it probably solves what we tried to patch as well.

Can you test my refactored approach (based on your approach)? It is attached.

chenson

2013-07-22 00:55

administrator  

refactored.patch (6,098 bytes)   
Index: src/main/java/org/jumpmind/db/sql/JdbcSqlTemplate.java
===================================================================
--- src/main/java/org/jumpmind/db/sql/JdbcSqlTemplate.java	(revision 7547)
+++ src/main/java/org/jumpmind/db/sql/JdbcSqlTemplate.java	(working copy)
@@ -875,11 +875,17 @@
                 lobHandler.getLobCreator().setBlobAsBytes(ps, i, arg.toString().getBytes());
             } else if (argType == Types.CLOB && lobHandler != null) {
                 lobHandler.getLobCreator().setClobAsString(ps, i, (String) arg);
+            } else if (argType == Types.DECIMAL) {
+                setDecimalValue(ps, i, arg, argType);
             } else {
                 StatementCreatorUtils.setParameterValue(ps, i, verifyArgType(arg, argType), arg);
             }
         }
     }
+    
+    protected void setDecimalValue(PreparedStatement ps, int i, Object arg, int argType) throws SQLException {
+        StatementCreatorUtils.setParameterValue(ps, i, verifyArgType(arg, argType), arg);
+    }
 
     protected int verifyArgType(Object arg, int argType) {
         if (argType == -101 || argType == Types.OTHER) {
Index: src/main/java/org/jumpmind/db/platform/sqlanywhere/SqlAnywhereDatabasePlatform.java
===================================================================
--- src/main/java/org/jumpmind/db/platform/sqlanywhere/SqlAnywhereDatabasePlatform.java	(revision 7547)
+++ src/main/java/org/jumpmind/db/platform/sqlanywhere/SqlAnywhereDatabasePlatform.java	(working copy)
@@ -27,6 +27,7 @@
 import org.apache.commons.lang.StringUtils;
 import org.jumpmind.db.platform.AbstractJdbcDatabasePlatform;
 import org.jumpmind.db.platform.DatabaseNamesConstants;
+import org.jumpmind.db.sql.JdbcUtils;
 import org.jumpmind.db.sql.SqlTemplateSettings;
 
 /*
@@ -67,7 +68,7 @@
 
     @Override
     protected SqlAnywhereJdbcSqlTemplate createSqlTemplate() {
-        return new SqlAnywhereJdbcSqlTemplate(dataSource, settings, null, getDatabaseInfo());
+        return new SqlAnywhereJdbcSqlTemplate(dataSource, settings, null, getDatabaseInfo(), JdbcUtils.getNativeJdbcExtractory());
     }
 
     public String getName() {
Index: src/main/java/org/jumpmind/db/platform/sqlanywhere/SqlAnywhereJdbcSqlTemplate.java
===================================================================
--- src/main/java/org/jumpmind/db/platform/sqlanywhere/SqlAnywhereJdbcSqlTemplate.java	(revision 7547)
+++ src/main/java/org/jumpmind/db/platform/sqlanywhere/SqlAnywhereJdbcSqlTemplate.java	(working copy)
@@ -20,6 +20,11 @@
  */
 package org.jumpmind.db.platform.sqlanywhere;
 
+import java.lang.reflect.Method;
+import java.math.BigDecimal;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+
 import javax.sql.DataSource;
 
 import org.jumpmind.db.platform.DatabaseInfo;
@@ -27,12 +32,21 @@
 import org.jumpmind.db.sql.JdbcSqlTemplate;
 import org.jumpmind.db.sql.SqlTemplateSettings;
 import org.jumpmind.db.sql.SymmetricLobHandler;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.jdbc.core.SqlTypeValue;
+import org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor;
 
 public class SqlAnywhereJdbcSqlTemplate extends JdbcSqlTemplate implements ISqlTemplate {
 
+	static final Logger log = LoggerFactory.getLogger(SqlAnywhereJdbcSqlTemplate.class);
+
+	private NativeJdbcExtractor nativeJdbcExtractor;
+	
     public SqlAnywhereJdbcSqlTemplate(DataSource dataSource, SqlTemplateSettings settings,
-            SymmetricLobHandler lobHandler, DatabaseInfo databaseInfo) {
+            SymmetricLobHandler lobHandler, DatabaseInfo databaseInfo, NativeJdbcExtractor nativeJdbcExtractor) {
         super(dataSource, settings, lobHandler, databaseInfo);
+        this.nativeJdbcExtractor = nativeJdbcExtractor;
         primaryKeyViolationCodes = new int[] {423,511,515,530,547,2601,2615,2714};
     }
 
@@ -40,6 +54,53 @@
     protected boolean allowsNullForIdentityColumn() {
         return false;
     }
+    
+    protected void setDecimalValue(PreparedStatement ps, int i, Object arg, int argType)
+            throws SQLException {
+        PreparedStatement nativeStatement = getNativeStmt(ps);
+        if (nativeStatement != null
+                && "com.sybase.jdbc4.jdbc.SybPreparedStatement".equals(nativeStatement.getClass()
+                        .getName())) {
+            Class<?> clazz = nativeStatement.getClass();
+            Class<?>[] parameterTypes = new Class[] { int.class, BigDecimal.class, int.class,
+                    int.class };
+            Method method = null;
+            try {
+                method = clazz.getMethod("setBigDecimal", parameterTypes);
+                BigDecimal value = (BigDecimal) arg;
+                Object[] params = new Object[] { new Integer(i + 1), value,
+                        new Integer(value.precision()), new Integer(value.scale()) };
+                method.invoke(nativeStatement, params);
+            } catch (Exception e) {
+                log.info("Can't find stmt.setBigDecimal(int,BigDecimal,int,int) method: "
+                        + e.getMessage());
+                return;
+            }
+        }
+    }
+	
+    private PreparedStatement getNativeStmt(PreparedStatement ps) {
+        PreparedStatement stmt = ps;
+        try {
+            stmt = nativeJdbcExtractor.getNativePreparedStatement(ps);
+        } catch (SQLException ex) {
+            log.debug("Could not find a native preparedstatement using {}", nativeJdbcExtractor
+                    .getClass().getName());
+        }
+        return stmt;
+    }
 
+	@Override
+	public void setValues(PreparedStatement ps, Object[] args)
+			throws SQLException {
+		super.setValues(ps, args);
+		if (args != null && args.length > 0) {
+			int[] argTypes = new int[args.length];
+			for (int i = 0; i < argTypes.length; i++) {
+				argTypes[i] = SqlTypeValue.TYPE_UNKNOWN;
+			}
+			setValues(ps, args, argTypes, getLobHandler().getDefaultHandler());
+		}
+	}
 
 }
refactored.patch (6,098 bytes)   

snpe

2013-07-22 15:52

reporter   ~0000295

You are correct. There is the issue with both decimal and numeric values, but you have already fixed the issue with numeric values.
There are a minor issue in refactored.patch.
Namely, we have already update column count before calling setDecimalValue.
I have attached a new patch (refactored2.patch) that fixed numeric and decimal value.
Only difference related to refactored.patch is the following:

SqlAnywhereJdbcSqlTemplate.java, line 71
- Object[] params = new Object[] { new Integer(i + 1), value,
+ Object[] params = new Object[] { new Integer(i), value,

snpe

2013-07-22 15:52

reporter  

refactored2.patch (6,229 bytes)   
Index: symmetric-jdbc/src/main/java/org/jumpmind/db/sql/JdbcSqlTemplate.java
===================================================================
--- symmetric-jdbc/src/main/java/org/jumpmind/db/sql/JdbcSqlTemplate.java	(revision 7555)
+++ symmetric-jdbc/src/main/java/org/jumpmind/db/sql/JdbcSqlTemplate.java	(working copy)
@@ -875,11 +875,17 @@
                 lobHandler.getLobCreator().setBlobAsBytes(ps, i, arg.toString().getBytes());
             } else if (argType == Types.CLOB && lobHandler != null) {
                 lobHandler.getLobCreator().setClobAsString(ps, i, (String) arg);
+            } else if (argType == Types.DECIMAL) {
+                setDecimalValue(ps, i, arg, argType);
             } else {
                 StatementCreatorUtils.setParameterValue(ps, i, verifyArgType(arg, argType), arg);
             }
         }
     }
+    
+    protected void setDecimalValue(PreparedStatement ps, int i, Object arg, int argType) throws SQLException {
+        StatementCreatorUtils.setParameterValue(ps, i, verifyArgType(arg, argType), arg);
+    }
 
     protected int verifyArgType(Object arg, int argType) {
         if (argType == -101 || argType == Types.OTHER) {
Index: symmetric-jdbc/src/main/java/org/jumpmind/db/platform/sqlanywhere/SqlAnywhereJdbcSqlTemplate.java
===================================================================
--- symmetric-jdbc/src/main/java/org/jumpmind/db/platform/sqlanywhere/SqlAnywhereJdbcSqlTemplate.java	(revision 7555)
+++ symmetric-jdbc/src/main/java/org/jumpmind/db/platform/sqlanywhere/SqlAnywhereJdbcSqlTemplate.java	(working copy)
@@ -20,6 +20,11 @@
  */
 package org.jumpmind.db.platform.sqlanywhere;
 
+import java.lang.reflect.Method;
+import java.math.BigDecimal;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+
 import javax.sql.DataSource;
 
 import org.jumpmind.db.platform.DatabaseInfo;
@@ -27,12 +32,21 @@
 import org.jumpmind.db.sql.JdbcSqlTemplate;
 import org.jumpmind.db.sql.SqlTemplateSettings;
 import org.jumpmind.db.sql.SymmetricLobHandler;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.jdbc.core.SqlTypeValue;
+import org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor;
 
 public class SqlAnywhereJdbcSqlTemplate extends JdbcSqlTemplate implements ISqlTemplate {
 
+	static final Logger log = LoggerFactory.getLogger(SqlAnywhereJdbcSqlTemplate.class);
+
+	private NativeJdbcExtractor nativeJdbcExtractor;
+	
     public SqlAnywhereJdbcSqlTemplate(DataSource dataSource, SqlTemplateSettings settings,
-            SymmetricLobHandler lobHandler, DatabaseInfo databaseInfo) {
+            SymmetricLobHandler lobHandler, DatabaseInfo databaseInfo, NativeJdbcExtractor nativeJdbcExtractor) {
         super(dataSource, settings, lobHandler, databaseInfo);
+        this.nativeJdbcExtractor = nativeJdbcExtractor;
         primaryKeyViolationCodes = new int[] {423,511,515,530,547,2601,2615,2714};
     }
 
@@ -40,6 +54,53 @@
     protected boolean allowsNullForIdentityColumn() {
         return false;
     }
+    
+    protected void setDecimalValue(PreparedStatement ps, int i, Object arg, int argType)
+            throws SQLException {
+        PreparedStatement nativeStatement = getNativeStmt(ps);
+        if (nativeStatement != null
+                && "com.sybase.jdbc4.jdbc.SybPreparedStatement".equals(nativeStatement.getClass()
+                        .getName())) {
+            Class<?> clazz = nativeStatement.getClass();
+            Class<?>[] parameterTypes = new Class[] { int.class, BigDecimal.class, int.class,
+                    int.class };
+            Method method = null;
+            try {
+                method = clazz.getMethod("setBigDecimal", parameterTypes);
+                BigDecimal value = (BigDecimal) arg;
+                Object[] params = new Object[] { new Integer(i), value,
+                        new Integer(value.precision()), new Integer(value.scale()) };
+                method.invoke(nativeStatement, params);
+            } catch (Exception e) {
+                log.info("Can't find stmt.setBigDecimal(int,BigDecimal,int,int) method: "
+                        + e.getMessage());
+                return;
+            }
+        }
+    }
+	
+    private PreparedStatement getNativeStmt(PreparedStatement ps) {
+        PreparedStatement stmt = ps;
+        try {
+            stmt = nativeJdbcExtractor.getNativePreparedStatement(ps);
+        } catch (SQLException ex) {
+            log.debug("Could not find a native preparedstatement using {}", nativeJdbcExtractor
+                    .getClass().getName());
+        }
+        return stmt;
+    }
 
+	@Override
+	public void setValues(PreparedStatement ps, Object[] args)
+			throws SQLException {
+		super.setValues(ps, args);
+		if (args != null && args.length > 0) {
+			int[] argTypes = new int[args.length];
+			for (int i = 0; i < argTypes.length; i++) {
+				argTypes[i] = SqlTypeValue.TYPE_UNKNOWN;
+			}
+			setValues(ps, args, argTypes, getLobHandler().getDefaultHandler());
+		}
+	}
 
 }
Index: symmetric-jdbc/src/main/java/org/jumpmind/db/platform/sqlanywhere/SqlAnywhereDatabasePlatform.java
===================================================================
--- symmetric-jdbc/src/main/java/org/jumpmind/db/platform/sqlanywhere/SqlAnywhereDatabasePlatform.java	(revision 7555)
+++ symmetric-jdbc/src/main/java/org/jumpmind/db/platform/sqlanywhere/SqlAnywhereDatabasePlatform.java	(working copy)
@@ -27,6 +27,7 @@
 import org.apache.commons.lang.StringUtils;
 import org.jumpmind.db.platform.AbstractJdbcDatabasePlatform;
 import org.jumpmind.db.platform.DatabaseNamesConstants;
+import org.jumpmind.db.sql.JdbcUtils;
 import org.jumpmind.db.sql.SqlTemplateSettings;
 
 /*
@@ -67,7 +68,7 @@
 
     @Override
     protected SqlAnywhereJdbcSqlTemplate createSqlTemplate() {
-        return new SqlAnywhereJdbcSqlTemplate(dataSource, settings, null, getDatabaseInfo());
+        return new SqlAnywhereJdbcSqlTemplate(dataSource, settings, null, getDatabaseInfo(), JdbcUtils.getNativeJdbcExtractory());
     }
 
     public String getName() {
refactored2.patch (6,229 bytes)   

abrougher

2013-07-22 17:14

reporter   ~0000296

The fix for dealing with numeric columns was to map them to the double type. I did the same for decimal. Both types are working correctly now.

I've checked in the changes. Let me know if you experience any issues with this solution.

abrougher

2013-07-22 17:15

reporter   ~0000297

Mapped decimal type to double type.

chenson

2013-07-22 21:51

administrator   ~0000300

prepare for release

snpe

2013-07-22 22:46

reporter   ~0000352

Last edited: 2013-07-22 22:51

View 2 revisions

Converting to double solves this issue, but introduce new issues.

1) dbexport issue
- create table as following:

create table test(
    id integer not null primary key,
    val numeric(6,2),
    val2 decimal(6,2)
);

- call dbexport (you have to apply patch from http://www.symmetricds.org/issues/view.php?id=1335)

You will get the following ddl:

CREATE TABLE "test"
(
    "id" INT NOT NULL,
    "val" DOUBLE PRECISION NOT NULL,
    "val2" DOUBLE PRECISION NOT NULL,
    PRIMARY KEY ("id")
);

2) converting a type to double will probably break decimal number precision, but I can't find some reproducible case.

IMO, you can't simple change sql type for column when read a table metadata. It could cause the different issues.

Related Changesets

SymmetricDS: master 21f6132e

2013-07-22 10:59:38

abrougher

Details Diff
0001334: The issue with jConnect JDBC, SQL Anywhere and decimal value Affected Issues
0001334
mod - symmetric-jdbc/src/main/java/org/jumpmind/db/platform/sqlanywhere/SqlAnywhereDdlReader.java Diff File

SymmetricDS: master 714b1575

2013-08-13 13:01:44

abrougher

Details Diff
0001334: The issue with jConnect JDBC, SQL Anywhere and decimal value.

Fixing unit test errors on ASE and mapping issues on ASA.
Affected Issues
0001334
mod - symmetric-jdbc/src/main/java/org/jumpmind/db/platform/ase/AseDatabasePlatform.java Diff File
mod - symmetric-jdbc/src/main/java/org/jumpmind/db/platform/ase/AseJdbcSqlTemplate.java Diff File
mod - symmetric-jdbc/src/main/java/org/jumpmind/db/platform/sqlanywhere/SqlAnywhereDatabasePlatform.java Diff File
mod - symmetric-jdbc/src/main/java/org/jumpmind/db/platform/sqlanywhere/SqlAnywhereDdlReader.java Diff File
mod - symmetric-jdbc/src/main/java/org/jumpmind/db/platform/sqlanywhere/SqlAnywhereJdbcSqlTemplate.java Diff File
mod - symmetric-jdbc/src/main/java/org/jumpmind/db/sql/JdbcSqlTemplate.java Diff File
mod - symmetric-jdbc/src/test/resources/db-test.properties Diff File

SymmetricDS: master 790237e3

2013-08-14 08:27:10

chenson

Details Diff
0001334: The issue with jConnect JDBC, SQL Anywhere and decimal value.

Better error handling. Common super class
Affected Issues
0001334
mod - symmetric-jdbc/src/main/java/org/jumpmind/db/platform/ase/AseJdbcSqlTemplate.java Diff File
mod - symmetric-jdbc/src/main/java/org/jumpmind/db/platform/sqlanywhere/SqlAnywhereJdbcSqlTemplate.java Diff File
add - symmetric-jdbc/src/main/java/org/jumpmind/db/platform/sybase/SybaseJdbcSqlTemplate.java Diff File

SymmetricDS: master b08b0877

2013-08-14 09:01:55

chenson

Details Diff
0001334: The issue with jConnect JDBC, SQL Anywhere and decimal value.

Normalize scale and precision for sybase
Affected Issues
0001334
mod - symmetric-jdbc/src/main/java/org/jumpmind/db/platform/sybase/SybaseJdbcSqlTemplate.java Diff File

SymmetricDS: master 1e908b1f

2013-08-14 09:28:36

chenson

Details Diff
0001334: The issue with jConnect JDBC, SQL Anywhere and decimal value.

Normalize scale and precision for sybase
Affected Issues
0001334
mod - symmetric-jdbc/src/main/java/org/jumpmind/db/platform/sybase/SybaseJdbcSqlTemplate.java Diff File

SymmetricDS: master 4db8a21e

2013-08-14 09:30:35

chenson

Details Diff
0001334: The issue with jConnect JDBC, SQL Anywhere and decimal value.

Normalize scale and precision for sybase
Affected Issues
0001334
mod - symmetric-jdbc/src/main/java/org/jumpmind/db/platform/sybase/SybaseJdbcSqlTemplate.java Diff File

Issue History

Date Modified Username Field Change
2013-07-21 23:54 snpe New Issue
2013-07-21 23:54 snpe File Added: TestJConnectBigDecimal.java
2013-07-21 23:55 snpe File Added: bigdecimalissue.diff
2013-07-22 00:55 chenson Note Added: 0000294
2013-07-22 00:55 chenson File Added: refactored.patch
2013-07-22 01:09 chenson Assigned To => abrougher
2013-07-22 01:09 chenson Status new => assigned
2013-07-22 15:52 snpe Note Added: 0000295
2013-07-22 15:52 snpe File Added: refactored2.patch
2013-07-22 17:14 abrougher Note Added: 0000296
2013-07-22 17:15 abrougher Note Added: 0000297
2013-07-22 17:15 abrougher Status assigned => resolved
2013-07-22 17:15 abrougher Fixed in Version => 3.5.0
2013-07-22 17:15 abrougher Resolution open => fixed
2013-07-22 18:22 chenson Product Version => 3.5.0
2013-07-22 18:22 chenson Target Version => 3.5.0
2013-07-22 21:51 chenson Note Added: 0000300
2013-07-22 21:51 chenson Status resolved => closed
2013-07-22 22:46 snpe Note Added: 0000352
2013-07-22 22:46 snpe Status closed => feedback
2013-07-22 22:46 snpe Resolution fixed => reopened
2013-07-22 22:51 snpe Note Edited: 0000352 View Revisions
2013-07-23 01:10 chenson Fixed in Version 3.5.0 => 3.5.1
2013-07-23 01:10 chenson Target Version 3.5.0 => 3.5.1
2013-07-24 20:59 chenson Status feedback => closed
2013-08-14 13:46 chenson Assigned To abrougher => chenson
2013-08-14 13:46 chenson Status closed => feedback
2013-08-14 13:46 chenson Fixed in Version 3.5.1 => 3.5.4
2013-08-14 13:46 chenson Target Version 3.5.1 => 3.5.4
2013-08-18 23:37 chenson Status feedback => resolved
2013-08-18 23:37 chenson Resolution reopened => fixed
2013-08-19 00:05 chenson Status resolved => closed
2014-02-03 01:53 abrougher Changeset attached => SymmetricDS trunk r7556
2014-02-03 01:53 abrougher Changeset attached => SymmetricDS trunk r7631
2014-02-03 01:53 Changeset attached => SymmetricDS trunk r7635
2014-02-03 01:53 Changeset attached => SymmetricDS trunk r7636
2014-02-03 01:53 Changeset attached => SymmetricDS trunk r7637
2014-02-03 01:53 Changeset attached => SymmetricDS trunk r7638
2015-07-31 01:49 chenson Changeset attached => SymmetricDS master 4db8a21e
2015-07-31 01:49 chenson Changeset attached => SymmetricDS master 1e908b1f
2015-07-31 01:49 chenson Changeset attached => SymmetricDS master b08b0877
2015-07-31 01:49 chenson Changeset attached => SymmetricDS master 790237e3
2015-07-31 01:49 abrougher Changeset attached => SymmetricDS master 714b1575
2015-07-31 01:49 abrougher Changeset attached => SymmetricDS master 21f6132e