Index: src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1Statement.java =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1Statement.java,v retrieving revision 1.28 diff -u -c -r1.28 AbstractJdbc1Statement.java *** src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1Statement.java 22 Jul 2003 05:17:09 -0000 1.28 --- src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1Statement.java 22 Jul 2003 14:07:10 -0000 *************** *** 1059,1065 **** for (int i = 0 ; i < p_input.length() ; ++i) { char c = p_input.charAt(i); ! if (c == '\\' || c == '\'') p_output.append((char)'\\'); p_output.append(c); } --- 1059,1069 ---- for (int i = 0 ; i < p_input.length() ; ++i) { char c = p_input.charAt(i); ! ! // It's not strictly necessary to escape '"' but it makes ! // the "simple" implementation of setArray possible. See ! // AbstractJdbc2Statement.setArray(). ! if (c == '\\' || c == '\'' || c == '"') p_output.append((char)'\\'); p_output.append(c); } Index: src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2Statement.java =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2Statement.java,v retrieving revision 1.15 diff -u -c -r1.15 AbstractJdbc2Statement.java *** src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2Statement.java 30 Jun 2003 16:38:30 -0000 1.15 --- src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2Statement.java 22 Jul 2003 14:07:10 -0000 *************** *** 196,202 **** public void setArray(int i, java.sql.Array x) throws SQLException { ! setString(i, x.toString()); } public void setBlob(int i, Blob x) throws SQLException --- 196,274 ---- public void setArray(int i, java.sql.Array x) throws SQLException { ! int baseType = x.getBaseType(); ! Object array = x.getArray(); ! ! // The approach this takes is to use setObject() to bind each element of ! // the array to the target parameter, then steal the escaped form from ! // m_binds to build the actual array. AbstractJdbc1Statement.escapeString() ! // (used to build string literals) is set up to escape " as well as ' so ! // if we see a string literal, we can translate ' -> " and get a valid array ! // value literal. ! // ! // This is all pretty nasty; the "right way" would be to separate the ! // generation of the DB representation from the actual binding and ! // string-literal-ization steps, for each supported object type. But that ! // requires more code rearrangement than I'd like to do right now. ! ! // This version uses reflection to abstract over Object[] vs. primitive type ! // arrays. java.lang.reflect.Array.get() conveniently wraps primitive types in ! // their corresponding java.lang objects so we can get away with just using ! // setObject(). ! // ! // If reflection then setObject() turns out to be too expensive, there's an ! // alternative but more verbose way -- declare a Binder interface that binds ! // element , then create an appropriate anonymous inner class based on the ! // concrete type of the returned array object that directly calls the appropriate ! // setXXX call (make sure to handle cases where x.getBaseType() doesn't directly ! // correspond to the array type, though .. probably easiest to fall back to ! // setObject in those cases). ! ! int arrayLength = java.lang.reflect.Array.getLength(array); ! ! // We cannot use the shared sbuf as it may be used by setObject. ! StringBuffer sb = new StringBuffer(2 + 8*arrayLength); // take a rough guess at total length ! ! // Bind each element and turn it into an array-quoted form. ! sb.append('{'); ! for (int j = 0; j < arrayLength; ++j) { ! if (j != 0) ! sb.append(','); ! ! // Do the bind: ! setObject(i, java.lang.reflect.Array.get(array, j), baseType); ! ! // Steal the bound value from m_binds[] and escape it. ! sb.append('"'); ! String toEscape = m_binds[i-1].toString(); ! if (toEscape.startsWith("'") && toEscape.endsWith("'")) { ! // String literal. escapeString() escapes both ' and " so ! // we can just swap '' for "" safely. ! sb.append(toEscape.substring(1, toEscape.length()-1)); ! } else { ! // Take the resulting (ready-for-the-parser) value and ! for (int k = 0; k < toEscape.length(); ++k) { ! char c = toEscape.charAt(k); ! if (c == '\\' || c == '"') ! sb.append('\\'); ! sb.append(c); ! } ! } ! sb.append('"'); ! } ! sb.append('}'); ! ! // The type of this field is based on the bound type of the ! // last element (or the bound type of a null of the array's ! // element type, if there are no elements). It would be better ! // to map from baseType -> postgres type directly, but there's ! // no infrastructure to do that currently. ! ! if (arrayLength == 0) ! setNull(i, baseType); // Set m_bindTypes[i-1] correctly. ! ! // Finally, bind the value. ! setString(i, sb.toString(), m_bindTypes[i-1] + "[]"); } public void setBlob(int i, Blob x) throws SQLException Index: src/interfaces/jdbc/org/postgresql/test/jdbc2/Jdbc2TestSuite.java =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/interfaces/jdbc/org/postgresql/test/jdbc2/Jdbc2TestSuite.java,v retrieving revision 1.6 diff -u -c -r1.6 Jdbc2TestSuite.java *** src/interfaces/jdbc/org/postgresql/test/jdbc2/Jdbc2TestSuite.java 29 May 2003 04:39:48 -0000 1.6 --- src/interfaces/jdbc/org/postgresql/test/jdbc2/Jdbc2TestSuite.java 22 Jul 2003 14:07:10 -0000 *************** *** 1,3 **** --- 1,4 ---- + // -*- tab-width: 4; indent-tabs-mode: t -*- package org.postgresql.test.jdbc2; import junit.framework.TestSuite; *************** *** 48,54 **** // BatchExecute suite.addTestSuite(BatchExecuteTest.class); ! // Other misc tests, based on previous problems users have had or specific // features some applications require. --- 49,57 ---- // BatchExecute suite.addTestSuite(BatchExecuteTest.class); ! ! // setArray() and getArray() ! suite.addTest(ArrayTest.suite()); // Other misc tests, based on previous problems users have had or specific // features some applications require.