001: /*
002: Copyright (C) 2002-2004 MySQL AB
003:
004: This program is free software; you can redistribute it and/or modify
005: it under the terms of version 2 of the GNU General Public License as
006: published by the Free Software Foundation.
007:
008: There are special exceptions to the terms and conditions of the GPL
009: as it is applied to this software. View the full text of the
010: exception in file EXCEPTIONS-CONNECTOR-J in the directory of this
011: software distribution.
012:
013: This program is distributed in the hope that it will be useful,
014: but WITHOUT ANY WARRANTY; without even the implied warranty of
015: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
016: GNU General Public License for more details.
017:
018: You should have received a copy of the GNU General Public License
019: along with this program; if not, write to the Free Software
020: Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
021:
022:
023:
024: */
025: package testsuite.regression;
026:
027: import java.sql.ResultSetMetaData;
028: import java.sql.SQLException;
029:
030: import testsuite.BaseTestCase;
031:
032: /**
033: * Tests various number-handling issues that have arrisen in the JDBC driver at
034: * one time or another.
035: *
036: * @author Mark Matthews
037: */
038: public class NumbersRegressionTest extends BaseTestCase {
039: /**
040: * Constructor for NumbersRegressionTest.
041: *
042: * @param name
043: * the test name
044: */
045: public NumbersRegressionTest(String name) {
046: super (name);
047: }
048:
049: /**
050: * Runs all test cases
051: *
052: * @param args
053: * command-line args
054: *
055: * @throws Exception
056: * if any errors occur
057: */
058: public static void main(String[] args) {
059: junit.textui.TestRunner.run(NumbersRegressionTest.class);
060: }
061:
062: /**
063: * Tests that BIGINT retrieval works correctly
064: *
065: * @throws Exception
066: * if any errors occur
067: */
068: public void testBigInt() throws Exception {
069: try {
070: this .stmt
071: .executeUpdate("DROP TABLE IF EXISTS bigIntRegression");
072: this .stmt
073: .executeUpdate("CREATE TABLE bigIntRegression ( val BIGINT NOT NULL)");
074: this .stmt
075: .executeUpdate("INSERT INTO bigIntRegression VALUES (6692730313872877584)");
076: this .rs = this .stmt
077: .executeQuery("SELECT val FROM bigIntRegression");
078:
079: while (this .rs.next()) {
080: // check retrieval
081: long retrieveAsLong = this .rs.getLong(1);
082: assertTrue(retrieveAsLong == 6692730313872877584L);
083: }
084:
085: this .rs.close();
086: this .stmt
087: .executeUpdate("DROP TABLE IF EXISTS bigIntRegression");
088:
089: String bigIntAsString = "6692730313872877584";
090:
091: long parsedBigIntAsLong = Long.parseLong(bigIntAsString);
092:
093: // check JDK parsing
094: assertTrue(bigIntAsString.equals(String
095: .valueOf(parsedBigIntAsLong)));
096: } finally {
097: this .stmt
098: .executeUpdate("DROP TABLE IF EXISTS bigIntRegression");
099: }
100: }
101:
102: /**
103: * Tests correct type assignment for MySQL FLOAT and REAL datatypes.
104: *
105: * @throws Exception
106: * if the test fails.
107: */
108: public void testFloatsAndReals() throws Exception {
109: try {
110: this .stmt
111: .executeUpdate("DROP TABLE IF EXISTS floatsAndReals");
112: this .stmt
113: .executeUpdate("CREATE TABLE IF NOT EXISTS floatsAndReals(floatCol FLOAT, realCol REAL, doubleCol DOUBLE)");
114: this .stmt
115: .executeUpdate("INSERT INTO floatsAndReals VALUES (0, 0, 0)");
116:
117: this .rs = this .stmt
118: .executeQuery("SELECT floatCol, realCol, doubleCol FROM floatsAndReals");
119:
120: ResultSetMetaData rsmd = this .rs.getMetaData();
121:
122: this .rs.next();
123:
124: assertTrue(rsmd.getColumnClassName(1).equals(
125: "java.lang.Float"));
126: assertTrue(this .rs.getObject(1).getClass().getName()
127: .equals("java.lang.Float"));
128:
129: assertTrue(rsmd.getColumnClassName(2).equals(
130: "java.lang.Double"));
131: assertTrue(this .rs.getObject(2).getClass().getName()
132: .equals("java.lang.Double"));
133:
134: assertTrue(rsmd.getColumnClassName(3).equals(
135: "java.lang.Double"));
136: assertTrue(this .rs.getObject(3).getClass().getName()
137: .equals("java.lang.Double"));
138:
139: } finally {
140: this .stmt
141: .executeUpdate("DROP TABLE IF EXISTS floatsAndReals");
142: }
143: }
144:
145: /**
146: * Tests that ResultSetMetaData precision and scale methods work correctly
147: * for all numeric types.
148: *
149: * @throws Exception
150: * if any errors occur
151: */
152: public void testPrecisionAndScale() throws Exception {
153: testPrecisionForType("TINYINT", 8, -1, false);
154: testPrecisionForType("TINYINT", 8, -1, true);
155: testPrecisionForType("SMALLINT", 8, -1, false);
156: testPrecisionForType("SMALLINT", 8, -1, true);
157: testPrecisionForType("MEDIUMINT", 8, -1, false);
158: testPrecisionForType("MEDIUMINT", 8, -1, true);
159: testPrecisionForType("INT", 8, -1, false);
160: testPrecisionForType("INT", 8, -1, true);
161: testPrecisionForType("BIGINT", 8, -1, false);
162: testPrecisionForType("BIGINT", 8, -1, true);
163:
164: testPrecisionForType("FLOAT", 8, 4, false);
165: testPrecisionForType("FLOAT", 8, 4, true);
166: testPrecisionForType("DOUBLE", 8, 4, false);
167: testPrecisionForType("DOUBLE", 8, 4, true);
168:
169: testPrecisionForType("DECIMAL", 8, 4, false);
170: testPrecisionForType("DECIMAL", 8, 4, true);
171:
172: testPrecisionForType("DECIMAL", 9, 0, false);
173: testPrecisionForType("DECIMAL", 9, 0, true);
174: }
175:
176: private void testPrecisionForType(String typeName, int m, int d,
177: boolean unsigned) throws Exception {
178: try {
179: this .stmt
180: .executeUpdate("DROP TABLE IF EXISTS precisionAndScaleRegression");
181:
182: StringBuffer createStatement = new StringBuffer(
183: "CREATE TABLE precisionAndScaleRegression ( val ");
184: createStatement.append(typeName);
185: createStatement.append("(");
186: createStatement.append(m);
187:
188: if (d != -1) {
189: createStatement.append(",");
190: createStatement.append(d);
191: }
192:
193: createStatement.append(")");
194:
195: if (unsigned) {
196: createStatement.append(" UNSIGNED ");
197: }
198:
199: createStatement.append(" NOT NULL)");
200:
201: this .stmt.executeUpdate(createStatement.toString());
202:
203: this .rs = this .stmt
204: .executeQuery("SELECT val FROM precisionAndScaleRegression");
205:
206: ResultSetMetaData rsmd = this .rs.getMetaData();
207: assertTrue("Precision returned incorrectly for type "
208: + typeName + ", " + m
209: + " != rsmd.getPrecision() = "
210: + rsmd.getPrecision(1), rsmd.getPrecision(1) == m);
211:
212: if (d != -1) {
213: assertTrue("Scale returned incorrectly for type "
214: + typeName + ", " + d
215: + " != rsmd.getScale() = " + rsmd.getScale(1),
216: rsmd.getScale(1) == d);
217: }
218: } finally {
219: if (this .rs != null) {
220: try {
221: this .rs.close();
222: } catch (Exception ex) {
223: // ignore
224: }
225: }
226:
227: this .stmt
228: .executeUpdate("DROP TABLE IF EXISTS precisionAndScaleRegression");
229: }
230: }
231:
232: public void testIntShouldReturnLong() throws Exception {
233: try {
234: this .stmt
235: .executeUpdate("DROP TABLE IF EXISTS testIntRetLong");
236: this .stmt
237: .executeUpdate("CREATE TABLE testIntRetLong(field1 INT)");
238: this .stmt
239: .executeUpdate("INSERT INTO testIntRetLong VALUES (1)");
240:
241: this .rs = this .stmt
242: .executeQuery("SELECT * FROM testIntRetLong");
243: this .rs.next();
244:
245: assertTrue(this .rs.getObject(1).getClass().equals(
246: java.lang.Integer.class));
247: } finally {
248: if (this .rs != null) {
249: try {
250: this .rs.close();
251: } catch (SQLException sqlEx) {
252: // ignore
253: }
254:
255: this .rs = null;
256: }
257:
258: this .stmt
259: .executeUpdate("DROP TABLE IF EXISTS testIntRetLong");
260:
261: }
262: }
263:
264: /**
265: * Tests fix for BUG#5729, UNSIGNED BIGINT returned incorrectly
266: *
267: * @throws Exception
268: * if the test fails
269: */
270: public void testBug5729() throws Exception {
271: if (versionMeetsMinimum(4, 1)) {
272: String valueAsString = "1095923280000";
273:
274: try {
275: this .stmt
276: .executeUpdate("DROP TABLE IF EXISTS testBug5729");
277: this .stmt
278: .executeUpdate("CREATE TABLE testBug5729(field1 BIGINT UNSIGNED)");
279: this .stmt
280: .executeUpdate("INSERT INTO testBug5729 VALUES ("
281: + valueAsString + ")");
282:
283: this .rs = this .conn.prepareStatement(
284: "SELECT * FROM testBug5729").executeQuery();
285: this .rs.next();
286:
287: assertTrue(this .rs.getObject(1).toString().equals(
288: valueAsString));
289: } finally {
290: this .stmt
291: .executeUpdate("DROP TABLE IF EXISTS testBug5729");
292: }
293: }
294: }
295:
296: /**
297: * Tests fix for BUG#8484 - ResultSet.getBigDecimal() throws exception when
298: * rounding would need to occur to set scale.
299: *
300: * @throws Exception
301: * if the test fails
302: * @deprecated
303: */
304: public void testBug8484() throws Exception {
305: try {
306: this .stmt.executeUpdate("DROP TABLE IF EXISTS testBug8484");
307: this .stmt
308: .executeUpdate("CREATE TABLE testBug8484 (field1 DECIMAL(16, 8), field2 varchar(32))");
309: this .stmt
310: .executeUpdate("INSERT INTO testBug8484 VALUES (12345678.12345678, '')");
311: this .rs = this .stmt
312: .executeQuery("SELECT field1, field2 FROM testBug8484");
313: this .rs.next();
314: assertEquals("12345678.123", this .rs.getBigDecimal(1, 3)
315: .toString());
316: assertEquals("0.000", this .rs.getBigDecimal(2, 3)
317: .toString());
318:
319: this .pstmt = this .conn
320: .prepareStatement("SELECT field1, field2 FROM testBug8484");
321: this .rs = this .pstmt.executeQuery();
322: this .rs.next();
323: assertEquals("12345678.123", this .rs.getBigDecimal(1, 3)
324: .toString());
325: assertEquals("0.000", this .rs.getBigDecimal(2, 3)
326: .toString());
327: } finally {
328: this .stmt.executeUpdate("DROP TABLE IF EXISTS testBug8484");
329: }
330: }
331: }
|