Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit eab1d1f

Browse files
committed
Merge branch 'master' into anyelement
2 parents 04a08d5 + 50ab76d commit eab1d1f

File tree

18 files changed

+562
-316
lines changed

18 files changed

+562
-316
lines changed

contrib/hstore_plpython/expected/hstore_plpython.out

+4-12
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,10 @@ CREATE FUNCTION test1arr(val hstore[]) RETURNS int
4343
LANGUAGE plpythonu
4444
TRANSFORM FOR TYPE hstore
4545
AS $$
46-
plpy.info(repr(val))
46+
assert(val == [{'aa': 'bb', 'cc': None}, {'dd': 'ee'}])
4747
return len(val)
4848
$$;
4949
SELECT test1arr(array['aa=>bb, cc=>NULL'::hstore, 'dd=>ee']);
50-
INFO: [{'aa': 'bb', 'cc': None}, {'dd': 'ee'}]
51-
CONTEXT: PL/Python function "test1arr"
5250
test1arr
5351
----------
5452
2
@@ -88,18 +86,14 @@ LANGUAGE plpythonu
8886
TRANSFORM FOR TYPE hstore
8987
AS $$
9088
rv = plpy.execute("SELECT 'aa=>bb, cc=>NULL'::hstore AS col1")
91-
plpy.info(repr(rv[0]["col1"]))
89+
assert(rv[0]["col1"] == {'aa': 'bb', 'cc': None})
9290

9391
val = {'a': 1, 'b': 'boo', 'c': None}
9492
plan = plpy.prepare("SELECT $1::text AS col1", ["hstore"])
9593
rv = plpy.execute(plan, [val])
96-
plpy.info(repr(rv[0]["col1"]))
94+
assert(rv[0]["col1"] == '"a"=>"1", "b"=>"boo", "c"=>NULL')
9795
$$;
9896
SELECT test3();
99-
INFO: {'aa': 'bb', 'cc': None}
100-
CONTEXT: PL/Python function "test3"
101-
INFO: '"a"=>"1", "b"=>"boo", "c"=>NULL'
102-
CONTEXT: PL/Python function "test3"
10397
test3
10498
-------
10599

@@ -118,16 +112,14 @@ CREATE FUNCTION test4() RETURNS trigger
118112
LANGUAGE plpythonu
119113
TRANSFORM FOR TYPE hstore
120114
AS $$
121-
plpy.info("Trigger row: {'a': %r, 'b': %r}" % (TD["new"]["a"], TD["new"]["b"]))
115+
assert(TD["new"] == {'a': 1, 'b': {'aa': 'bb', 'cc': None}})
122116
if TD["new"]["a"] == 1:
123117
TD["new"]["b"] = {'a': 1, 'b': 'boo', 'c': None}
124118

125119
return "MODIFY"
126120
$$;
127121
CREATE TRIGGER test4 BEFORE UPDATE ON test1 FOR EACH ROW EXECUTE PROCEDURE test4();
128122
UPDATE test1 SET a = a;
129-
INFO: Trigger row: {'a': 1, 'b': {'aa': 'bb', 'cc': None}}
130-
CONTEXT: PL/Python function "test4"
131123
SELECT * FROM test1;
132124
a | b
133125
---+---------------------------------

contrib/hstore_plpython/sql/hstore_plpython.sql

+4-4
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ CREATE FUNCTION test1arr(val hstore[]) RETURNS int
3737
LANGUAGE plpythonu
3838
TRANSFORM FOR TYPE hstore
3939
AS $$
40-
plpy.info(repr(val))
40+
assert(val == [{'aa': 'bb', 'cc': None}, {'dd': 'ee'}])
4141
return len(val)
4242
$$;
4343

@@ -74,12 +74,12 @@ LANGUAGE plpythonu
7474
TRANSFORM FOR TYPE hstore
7575
AS $$
7676
rv = plpy.execute("SELECT 'aa=>bb, cc=>NULL'::hstore AS col1")
77-
plpy.info(repr(rv[0]["col1"]))
77+
assert(rv[0]["col1"] == {'aa': 'bb', 'cc': None})
7878

7979
val = {'a': 1, 'b': 'boo', 'c': None}
8080
plan = plpy.prepare("SELECT $1::text AS col1", ["hstore"])
8181
rv = plpy.execute(plan, [val])
82-
plpy.info(repr(rv[0]["col1"]))
82+
assert(rv[0]["col1"] == '"a"=>"1", "b"=>"boo", "c"=>NULL')
8383
$$;
8484

8585
SELECT test3();
@@ -94,7 +94,7 @@ CREATE FUNCTION test4() RETURNS trigger
9494
LANGUAGE plpythonu
9595
TRANSFORM FOR TYPE hstore
9696
AS $$
97-
plpy.info("Trigger row: {'a': %r, 'b': %r}" % (TD["new"]["a"], TD["new"]["b"]))
97+
assert(TD["new"] == {'a': 1, 'b': {'aa': 'bb', 'cc': None}})
9898
if TD["new"]["a"] == 1:
9999
TD["new"]["b"] = {'a': 1, 'b': 'boo', 'c': None}
100100

doc/src/sgml/func.sgml

+44-7
Original file line numberDiff line numberDiff line change
@@ -10323,6 +10323,15 @@ table2-mapping
1032310323
</tgroup>
1032410324
</table>
1032510325

10326+
<note>
10327+
<para>
10328+
The <literal>||</> operator concatenates the elements at the top level of
10329+
each of its operands. It does not operate recursively. For example, if
10330+
both operands are objects with a common key field name, the value of the
10331+
field in the result will just be the value from the right hand operand.
10332+
</para>
10333+
</note>
10334+
1032610335
<para>
1032710336
<xref linkend="functions-json-creation-table"> shows the functions that are
1032810337
available for creating <type>json</type> and <type>jsonb</type> values.
@@ -10830,17 +10839,24 @@ table2-mapping
1083010839
<entry><literal>[{"f1":1},2,null,3]</literal></entry>
1083110840
</row>
1083210841
<row>
10833-
<entry><para><literal>jsonb_replace(target jsonb, path text[], replacement jsonb)</literal>
10842+
<entry><para><literal>jsonb_set(target jsonb, path text[], new_value jsonb<optional>, <parameter>create_missing</parameter> <type>boolean</type></optional>)</literal>
1083410843
</para></entry>
1083510844
<entry><para><type>jsonb</type></para></entry>
1083610845
<entry>
1083710846
Returns <replaceable>target</replaceable>
10838-
with the section designated by <replaceable>path</replaceable>
10839-
replaced by <replaceable>replacement</replaceable>.
10840-
</entry>
10841-
<entry><literal>jsonb_replace('[{"f1":1,"f2":null},2,null,3]', '{0,f1}','[2,3,4]')</literal></entry>
10842-
<entry><literal>[{"f1":[2,3,4],"f2":null},2,null,3]</literal>
10843-
</entry>
10847+
with the section designated by <replaceable>path</replaceable>
10848+
replaced by <replaceable>new_value</replaceable>, or with
10849+
<replaceable>new_value</replaceable> added if
10850+
<replaceable>create_missing</replaceable> is true ( default is
10851+
<literal>true</>) and the item
10852+
designated by <replaceable>path</replaceable> does not exist.
10853+
</entry>
10854+
<entry><para><literal>jsonb_set('[{"f1":1,"f2":null},2,null,3]', '{0,f1}','[2,3,4]', false)</literal>
10855+
</para><para><literal>jsonb_set('[{"f1":1,"f2":null},2]', '{0,f3}','[2,3,4]')</literal>
10856+
</para></entry>
10857+
<entry><para><literal>[{"f1":[2,3,4],"f2":null},2,null,3]</literal>
10858+
</para><para><literal>[{"f1": 1, "f2": null, "f3": [2, 3, 4]}, 2]</literal>
10859+
</para></entry>
1084410860
</row>
1084510861
<row>
1084610862
<entry><para><literal>jsonb_pretty(from_json jsonb)</literal>
@@ -10891,6 +10907,27 @@ table2-mapping
1089110907
</para>
1089210908
</note>
1089310909

10910+
<note>
10911+
<para>
10912+
All the items of the <literal>path</> parameter of <literal>jsonb_set</>
10913+
must be present in the <literal>target</>, unless
10914+
<literal>create_missing</> is true, in which case all but the last item
10915+
must be present. If these conditions are not met the <literal>target</>
10916+
is returned unchanged.
10917+
</para>
10918+
<para>
10919+
If the last path item is an object key, it will be created if it
10920+
is absent and given the new value. If the last path item is an array
10921+
index, if it is positive the item to set is found by counting from
10922+
the left, and if negative by counting from the right - <literal>-1</>
10923+
designates the rightmost element, and so on.
10924+
If the item is out of the range -array_length .. array_length -1,
10925+
and create_missing is true, the new value is added at the beginning
10926+
of the array if the item is negative, and at the end of the array if
10927+
it is positive.
10928+
</para>
10929+
</note>
10930+
1089410931
<note>
1089510932
<para>
1089610933
The <literal>json_typeof</> function's <literal>null</> return value

src/backend/catalog/system_views.sql

+8
Original file line numberDiff line numberDiff line change
@@ -922,3 +922,11 @@ RETURNS interval
922922
LANGUAGE INTERNAL
923923
STRICT IMMUTABLE
924924
AS 'make_interval';
925+
926+
CREATE OR REPLACE FUNCTION
927+
jsonb_set(jsonb_in jsonb, path text[] , replacement jsonb,
928+
create_if_missing boolean DEFAULT true)
929+
RETURNS jsonb
930+
LANGUAGE INTERNAL
931+
STRICT IMMUTABLE
932+
AS 'jsonb_set';

src/backend/storage/file/fd.c

+3-12
Original file line numberDiff line numberDiff line change
@@ -2648,18 +2648,15 @@ pre_sync_fname(const char *fname, bool isdir, int elevel)
26482648
{
26492649
if (errno == EACCES || (isdir && errno == EISDIR))
26502650
return;
2651-
2652-
#ifdef ETXTBSY
2653-
if (errno == ETXTBSY)
2654-
return;
2655-
#endif
2656-
26572651
ereport(elevel,
26582652
(errcode_for_file_access(),
26592653
errmsg("could not open file \"%s\": %m", fname)));
26602654
return;
26612655
}
26622656

2657+
/*
2658+
* We ignore errors from pg_flush_data() because this is only a hint.
2659+
*/
26632660
(void) pg_flush_data(fd, 0, 0);
26642661

26652662
(void) CloseTransientFile(fd);
@@ -2703,12 +2700,6 @@ fsync_fname_ext(const char *fname, bool isdir, int elevel)
27032700
{
27042701
if (errno == EACCES || (isdir && errno == EISDIR))
27052702
return;
2706-
2707-
#ifdef ETXTBSY
2708-
if (errno == ETXTBSY)
2709-
return;
2710-
#endif
2711-
27122703
ereport(elevel,
27132704
(errcode_for_file_access(),
27142705
errmsg("could not open file \"%s\": %m", fname)));

0 commit comments

Comments
 (0)