-
Notifications
You must be signed in to change notification settings - Fork 851
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: primitive arrays #887
Conversation
This is a minimal PR for purposes of discussion to support primitive arrays as part of issue #871 feat: minimal PR to support primitive arrays Improve StringBuilder init sizes. feat: support primitive arrays Add unit tests. Provide binary representation. Add javadoc. feat: support primitive arrays Use Oid rather than type name. More unit tests. feat: support primitive arrays Address checkstyle issues. feat: support primitive arrays Address checkstyle issues. Fix an issue with creating array string. Add support for boolean[]. Optimize mapping from String values to boolean. feat: support primitive arrays Address checkstyle issues. feat: support primitive arrays Use java 6 syntax. feat: support primitive arrays checkstyle in existing test feat: support primitive arrays checkstyle in existing test test: migrate tests to JUnit 4 fixes #738 fixes #205 test: assume minimum server version 8.3 testing autosave with ALTER Prior to 8.3, PostgreSQL didn't invalidate cached plans following DDL changes. This is mentioned in the 8.3 release notes as Automatically re-plan cached queries when table definitions change or statistics are updated https://www.postgresql.org/docs/8.3/static/release-8-3.html For details, see PostgreSQL commit b9527e9840 and friends. https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=b9527e984092e838790b543b014c0c2720ea4f11 test: assume minimum server version 8.3 when testing with uuid The UUID datatype was added to PostgreSQL in version 8.3. https://www.postgresql.org/docs/8.3/static/release-8-3.html refactor: remove unused import test: fix StringTypeParameterTest to skip preferQueryMode=simple Simple query mode does not send data type over the wire, so errors like "column \"m\" is of type mood but expression is of type character varying" never happen chore: install PostgreSQL 9.1 to Trusty builds via apt, and use Precise for Java 6 Travis deprecates Precise. See https://blog.travis-ci.com/2017-07-11-trusty-as-default-linux-is-coming sudo: required for dist: precise will still be supported for a while, however no updates to that image is planned Java 6 is not included into Trusty image, and installers no longer work (see http://www.webupd8.org/2017/06/why-oracle-java-7-and-6-installers-no.html) since Oracle removed the installer files from public access. refactor: remove useless checks in the tests remove useless checks for protocol version in the tests. style: update checkstyle + turn on some rules (#847) 1. Update checkstyle to 7.8.2 2. Add checkstyle module "RedundantModifier" 3. Uncomment checkstyle modules "ArrayTypeStyle", "ModifierOrder" test: make StringTypeParameterTest 8.3+ since 8.2 misses enum types (#882) PostgreSQL 8.2 tests at Travis should be green now, so removing allow_failures configuration test: assume integer datetimes for timestamp tests (#873) Float timestamp equality comparisons like comparisons with any float are problematic if they don't take into account their imprecise nature. Some timestamp tests produce false negative failures for servers compiled with float timestamps. Use JUnit assumptions to skip these tests if the server doesn't have integer datetimes. This addresses #12 in part in that it omits (most of) the failing tests, though it leaves these timestamp behaviors untested under float timestamps, which was the default prior to PostgreSQL 8.4. fix: named statements were used when fetchSize was non-zero and prepareThreshold=0 (#870) Non-zero fetchSize triggers use of named portals (for subsequent fetch requests), however named portals does not require to use named statements. As per PostgreSQL documentation, named portals are automatically closed as transaction completes, so named portals should play well with transaction-based poolers. fixes #869 test: skip ConcurrentStatementFetch for PostgreSQL < 8.4 (#884) PostgreSQL 8.2 is known to close named portals unexpectedly, so we just ignore the test. The following scenario might be affected: old backend version + setFetchSize + interleaved ResultSet processing This is a follow-up for #870 and #869 for PostgreSQL < 8.4 honour PGPORT, PGHOST, PGDBNAME in connection properties (#862) * honour PGPORT, PGHOST, PGDBNAME in connection properties feat: support primitive arrays use string array representation when simple query mode selected feat: support primitive arrays Checkstyle feat: support primitive arrays More unit test coverage feat: support primitive arrays Checkstyle test: migrate tests to Junit4 (#883) Migrate XATestSuite, Jdbc2TestSuite, Jdbc4TestSuite, ExtensionsTestSuite test suites see #205 feat: support primitive arrays Performance optimizations. Some renaming. feat: support primitive arrays Performance optimizations in TypeInfoCache. Checkstyle issue. feat: support primitive arrays Initialize maps in TypeInfoCache to appropriate size. feat: support primitive arrays Checkstyle feat: primitive arrays revert changes not directly related to supporting primitive arrays
Codecov Report
@@ Coverage Diff @@
## master #887 +/- ##
============================================
+ Coverage 66.35% 66.83% +0.48%
- Complexity 3607 3637 +30
============================================
Files 168 169 +1
Lines 15355 15593 +238
Branches 2483 2529 +46
============================================
+ Hits 10189 10422 +233
+ Misses 3985 3976 -9
- Partials 1181 1195 +14 |
private static final Map<Class, PrimitiveArraySupport> ARRAY_CLASS_TOSTRING = new HashMap<Class, PrimitiveArraySupport>(9); | ||
|
||
static { | ||
ARRAY_CLASS_TOSTRING.put(long[].class, LONG_ARRAY_TOSTRING); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As binary serialization is also supported, I think the TOSTRING
part can be removed from all the identifiers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
Object array = readBinaryArray(1, 0); | ||
|
||
if (PrimitiveArraySupport.isSupportedPrimitiveArray(array)) { | ||
fieldString = PrimitiveArraySupport.arrayToString(connection.getTypeInfo().getArrayDelimiter(oid), array); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
might be like this:
arraySupport = PrimitiveArraySupport.getArraySupport(array)
if (arraySupport != null) {
fieldString = arraySupport.toArrayString(array)
}
The static PrimitiveArraySupport.arrayToString()
method can be removed then.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
The static utility arrayToString method was used more before binary support was added. I did not realize it had dropped to only 1 use when binary representation became preferred.
@@ -295,27 +313,34 @@ public void testUUIDArray() throws SQLException { | |||
@Test | |||
public void testSetObjectFromJavaArray() throws SQLException { | |||
String[] strArray = new String[]{"a", "b", "c"}; | |||
Object[] objCopy = new Object[strArray.length]; | |||
System.arraycopy(strArray, 0, objCopy, 0, strArray.length); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can be replaced with Arrays.copyOf(strArray, strArray.length, Object[].class)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
Out of curiosity, why do you prefer the Arrays wrapper? These are functionally equivalent things, skipping some of the reflection stuff that Arrays has to do (or in this specific case because it is Object[]
, just a class identity comparison).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's shorter, so more readable.
/** | ||
* Defines public PostgreSQL extensions to create {@link Array} objects. | ||
*/ | ||
public interface PGArraySupport { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How much this level of indirection is useful? How many methods can be here potentially? I would suggest declaring the method directly in PGConnection.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@vlsi seemed to want at least 1 more method.
It was not clear to me if it was just one more or several more.
I do not know at what number you would want to group together with a specific interface. I would think at 3 or so, but I do not really care either way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a little bit closer to Connection if comparing with other extensions, as there is java.sql.Connection.createArrayOf()
already.
code review comments
It still appears that the code coverage report is not including the new unit test class i added. How is it identifying what tests to run? |
@bokken add your test class to the corresponding test suite |
code review comments
documentation
@davecramer, @vlsi, @panchenko, is there anything else needed, or can this get merged in? Thanks. |
@vlsi and @davecramer any update on when this could get merged in? |
Thanks @davecramer |
@vlsi, any update/eta on when this could get merged in? |
@davecramer, @vlsi, any update/eta on when this could get merged in? |
@bokken Sorry, I'll commit to reviewing this on Wed. Thanks for your patience |
docs/documentation/head/arrays.md
Outdated
`int[]` | `int4[]` | ||
`long[]` | `int8[]` | ||
`float[]` | `float4[]` | ||
`double[]` | `float[]8` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
float[]8
typo
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
@davecramer, @vlsi, any update/eta on when this could get merged in? |
@bokken there are some subtle semantic changes here. Specifically setObject(1, String[], Types.Array) used to fail, now it doesn't was this intentional? |
@davecramer, yes that was intentional and is called out in the documentation: The listed array types can go through setObject |
* @throws SQLException If for some reason the array cannot be created. | ||
* @see java.sql.Connection#createArrayOf(String, Object[]) | ||
*/ | ||
Array createArrayOf(String typeName, Object elements) throws SQLException; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can Object elements
be null?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No it cannot.
Similar to how createArrayOf(String typeName, Object[] elements) cannot take null elements either.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bokken , here's Java 8 documentation:
SQLException - if a database error occurs, the JDBC type is not appropriate for the typeName and the conversion is not supported, the typeName is null or this method is called on a closed connection
It does forbid null
for typeName
, however I do not see how it forbids null
for elements
The added PGConnection.createArrayOf(String, Object)
is a public API, and I think nullability documentation is a must.
PS. Sorry for the long-standing discussion, however we'd better be picky when adding new APIs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was speaking to the PGConnection
implementation of createArrayOf
, which also throws a NullPointerException
if given null
elements
.
As this was not documented there, I did not document here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps both methods should return null
if elements
is null
?
I was simply expecting/providing symmetry with the existing implementation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NullPointerException if given null elements
might be an existing bug.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It appears that it is possible to create a PGArray representing a null
array. Perhaps that is the solution?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So it is possible to create a null array in postgres so seems reasonable to allow it
select null::int[];
int4
------
@bokken can you fix the conflict and I'll commit this. Thanks |
# Conflicts: # pgjdbc/src/test/java/org/postgresql/test/jdbc2/Jdbc2TestSuite.java
@davecramer, @vlsi, I have fixed the conflict. Let me know if you would like me to add the |
|
||
/** | ||
* Creates an {@link Array} wrapping <i>elements</i>. This is similar to | ||
* java.sql.Connection#createArrayOf(String, Object[]), but also provides |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
{@link ...createArrayOf...}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
* java.sql.Connection#createArrayOf(String, Object[]), but also provides | ||
* support for primitive arrays. | ||
* | ||
* @param typeName |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add nullability description
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
* | ||
* @param typeName | ||
* The SQL name of the type to map the <i>elements</i> to. | ||
* @param elements |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add nullability description
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
Which I think is effectively what current code does, right? It is simply
wrapped in an Array object.
For comparison, this seems to match ojdbc’s behavior.
…On Sat, Dec 16, 2017 at 4:27 AM Dave Cramer ***@***.***> wrote:
***@***.**** commented on this pull request.
------------------------------
In pgjdbc/src/main/java/org/postgresql/PGConnection.java
<#887 (comment)>:
> @@ -21,6 +22,22 @@
* returned by the PostgreSQL driver implement PGConnection.
*/
public interface PGConnection {
+
+ /**
+ * Creates an ***@***.*** Array} wrapping <i>elements</i>. This is similar to
+ * java.sql.Connection#
createArrayOf(String, Object[]), but also provides
+ * support for primitive arrays.
+ *
+ * @param typeName
+ * The SQL name of the type to map the <i>elements</i> to.
+ * @param elements
+ * The array of objects to map.
+ * @return An ***@***.*** Array} wrapping <i>elements</i>.
+ * @throws SQLException If for some reason the array cannot be created.
+ * @see java.sql.Connection#createArrayOf(String, Object[])
+ */
+ Array createArrayOf(String typeName, Object elements) throws SQLException;
So it is possible to create a null array in postgres so seems reasonable
to allow it
select null::int[];
int4
------
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#887 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AC26bUiehoA_MmNpgDx0xr--J9atfHecks5tA5sPgaJpZM4Ol20_>
.
|
@davecramer the conflict has been resolved. |
Add support for primitive arrays.
This is a replacement for PR 872.