Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1kJ48Z-0003Ia-LN for pljava-dev@arkaria.postgresql.org; Fri, 18 Sep 2020 00:20:27 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1kJ48X-0001up-QM for pljava-dev@arkaria.postgresql.org; Fri, 18 Sep 2020 00:20:25 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1kJ48X-0001ui-9N for pljava-dev@lists.postgresql.org; Fri, 18 Sep 2020 00:20:25 +0000 Received: from anastigmatix.net ([68.171.219.55]) by magus.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1kJ48P-00015M-OX for pljava-dev@lists.postgresql.org; Fri, 18 Sep 2020 00:20:24 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=anastigmatix.net; s=default; h=Content-Transfer-Encoding:Content-Type: In-Reply-To:MIME-Version:Date:Message-ID:From:References:To:Subject:Sender: Reply-To:Cc:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help: List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=SEGO6v4qBfU+VxGK/LJ1ok0rXtPXA22Li1MnCg6ODNI=; b=WdYnzhpJ2Zb9yApFT6hvbsTTbZ 9abKzPK6KTNKT3k3xZjR2qTV4VdVvtv4q7JgNsLru1wL0RDFkz0HDeZLWtnNYweahD6T/zxO/ll/d kgpbP5Uvbl4ZmRjQ70GREqxdF6mBCIUmCgylwuWCTar3cEkjHnIvOjjYqajxhP/QcMGRBsNOqMvhI lUQsmQlr43WwB6n46iOE6lEv6W5zGJEze3QVvc5Q745uppAySGlIA7ijkkQ3uKoB2DuOub8wPa5EB NPYkhYwVw3qtd1a6II8SrHHK9EWPxLGuXRY8nikNvf4nJAH27S78ZvdGM1WK4XwDUadLEWr1TmAF4 GA9jRQ3w==; Received: from [184.19.31.139] (port=32876) by bay.acenet.us with esmtpsa (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.93) (envelope-from ) id 1kJ48L-008kUZ-Jb; Thu, 17 Sep 2020 20:20:14 -0400 Subject: Re: [Pljava-dev] Arrays support for object views To: Kris Jurka , Krzysztof Nienartowicz , "pljava-dev@lists.postgresql.org" References: <707ef6b40809230929p66557facy414f760052fab9ab@mail.gmail.com> <707ef6b40809260702n77f7737fh703b5123457df9bd@mail.gmail.com> From: Chapman Flack X-Enigmail-Draft-Status: N1110 Message-ID: <5F63FD3C.3080206@anastigmatix.net> Date: Thu, 17 Sep 2020 20:20:12 -0400 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.7.0 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-OutGoing-Spam-Status: No, score=-94.2 X-AntiAbuse: This header was added to track abuse, please include it with any abuse report X-AntiAbuse: Primary Hostname - bay.acenet.us X-AntiAbuse: Original Domain - lists.postgresql.org X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12] X-AntiAbuse: Sender Address Domain - anastigmatix.net X-Get-Message-Sender-Via: bay.acenet.us: authenticated_id: chap@anastigmatix.net X-Authenticated-Sender: bay.acenet.us: chap@anastigmatix.net X-Source: X-Source-Args: X-Source-Dir: X-From-Rewrite: unmodified, already matched List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk On 10/08/08 20:04, books at ejurka.com (Kris Jurka) wrote: > On Fri, 26 Sep 2008, Krzysztof Nienartowicz wrote: > >> By using simply: >> receiver.updateObject(5, new Double[]{1.0,2.0,3.0}); >> I finally don't get any errors but the values are not related to the array >> set and always stay the same. Seems they are not initialized properly even. > > When I test the same here, I get a crash. Pljava is trying to read the > Double[] as if it was a double[] and that's blowing up. If I change the This email thread from 2008 got reanimated as issue 300 [1]. Here is how the support currently stands: Among the examples in current releases, there is TypeRoundTripper, which is handy for testing questions like this. For example: # select * from (select '{1.9,2.8,3.7}'::float8[]) as p, roundtrip(p) as (class text, roundtripped float8[]); float8 | class | roundtripped ---------------+---------------------+--------------- {1.9,2.8,3.7} | [Ljava.lang.Double; | {1.9,2.8,3.7} (1 row) showing that when PostgreSQL passes a float8[] to PL/Java, Java receives an array of Double, and when PL/Java passes that to the result receiver, the right results are received. So that has improved since 2008. The story seems to be the same for: float4 | class | roundtripped ---------------+--------------------+--------------- {1.9,2.8,3.7} | [Ljava.lang.Float; | {1.9,2.8,3.7} int8 | class | roundtripped ---------+-------------------+-------------- {1,2,3} | [Ljava.lang.Long; | {1,2,3} int4 | class | roundtripped ---------+----------------------+-------------- {1,2,3} | [Ljava.lang.Integer; | {1,2,3} int2 | class | roundtripped ---------+--------------------+-------------- {1,2,3} | [Ljava.lang.Short; | {1,2,3} bool | class | roundtripped -------+----------------------+-------------- {t,f} | [Ljava.lang.Boolean; | {t,f} PostgreSQL "char"[] is mapped to Byte[] but the roundtrip does not go well: # select * from (select '{Q,R,S}'::"char"[]) as p, roundtrip(p) as (class text, roundtripped "char"[]); char | class | roundtripped ---------+-------------------+-------------- {Q,R,S} | [Ljava.lang.Byte; | {�,0,�} Other arbitrary types do what you expect: text | class | roundtripped -----------+---------------------+-------------- {foo,bar} | [Ljava.lang.String; | {foo,bar} time | class | roundtripped ---------------------+------------------+--------------------- {01:23:00,23:45:00} | [Ljava.sql.Time; | {01:23:00,23:45:00} For the types corresponding to Java primitives, you must pass updateObject the boxed array type, for example, Double[] rather than double[]. Passing the primitive array type simply produces: java.sql.SQLException: Cannot derive a value of class [Ljava.lang.Integer; from an object of class [I and the equivalent for all of the primitive types. An explanation might be that PostgreSQL arrays can contain nulls, and you wouldn't be able to supply those from a true Java primitive array. That doesn't mean it would not be convenient if you had no nulls. Disappointingly, you don't get to include nulls even when you use the boxed array form: # select * from (select '{1,null,3}'::float8[]) as p, roundtrip(p) as (class text, roundtripped float8[]); ERROR: java.lang.NullPointerException That's true for all the types corresponding to Java primitives. If you omit the 'roundtripped' column from the result descriptor, the function succeeds, confirming that PL/Java will /receive/ an array containing nulls with no difficulty; the problem is in /returning/ one. There is no such problem with the non-Java-primitive types: time | class | roundtripped --------------------------+------------------+-------------------------- {01:23:00,NULL,23:45:00} | [Ljava.sql.Time; | {01:23:00,NULL,23:45:00} Current PL/Java versions do not implement java.sql.Array, so using getObject/updateObject this way is the way to go. PL/Java will receive all the elements of a PostgreSQL multidimensional array, but only as a one-dimensional array, and will return them in that form: # select * from (select '{{1,2,3},{4,5,6},{7,8,9}}'::int2[]) as p, roundtrip(p) as (class text, roundtripped int2[]); int2 | class | roundtripped ---------------------------+--------------------+--------------------- {{1,2,3},{4,5,6},{7,8,9}} | [Ljava.lang.Short; | {1,2,3,4,5,6,7,8,9} That's true even if you explicitly declare the result type multidimensional: # select * from (select '{{1,2,3},{4,5,6},{7,8,9}}'::int2[]) as p, roundtrip(p) as (class text, roundtripped int2[][]); int2 | class | roundtripped ---------------------------+--------------------+--------------------- {{1,2,3},{4,5,6},{7,8,9}} | [Ljava.lang.Short; | {1,2,3,4,5,6,7,8,9} In the currently-released (1.5.x) and the nearing-release (1.6.x) branches, the type-mapping machinery is very little changed since 2008; like Kris, I have tried to touch it as little as possible. A good deal of refactoring in 1.6.x is happening to make it more thinkable to touch the type workings, but actually revamping the types is planned to happen later. When that happens, I would like to have a PostgreSQL-specific class that exposes all the features of PostgreSQL arrays: multidimensionality, arbitrary starting index, the works. For 1.5.x and 1.6.x, I will consider the null-not-accepted problem and the "char"[] value corruption to be bugs, and look at whether they will be easy to fix. I think multidimensionality is more than I want to bite off at the moment; I'd consider a pull request if someone else wants to work on it, but as I am already designing a future rework of the type system, putting too much effort into the current one at this point might be difficult to justify. Regards, -Chap [1] https://github.com/tada/pljava/issues/300