Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
4335990
Make EXEC_BACKEND more convenient on Linux and FreeBSD.
michaelpq Feb 8, 2023
976fdea
Stop recommending auto-download of DTD files, and indeed disable it.
tglsfdc Feb 8, 2023
32c8bec
Disable WindowAgg inverse transitions when subplans are present
david-rowley Feb 13, 2023
6b126f2
Fix handling of SCRAM-SHA-256's channel binding with RSA-PSS certific…
michaelpq Feb 15, 2023
1cdbdfc
Print the correct aliases for DML target tables in ruleutils.
tglsfdc Feb 17, 2023
1bf5956
Fix handling of multi-column BRIN indexes
tvondra Feb 18, 2023
19c4d0a
pgbench: Prepare commands in pipelines in advance
alvherre Feb 21, 2023
8f70694
Add missing support for the latest SPI status codes.
deanrasheed Feb 22, 2023
52fd7ad
Fix snapshot handling in logicalmsg_decode
tvondra Feb 22, 2023
9d08e8d
Don't repeatedly register cache callbacks in pgoutput plugin.
tglsfdc Feb 23, 2023
dfec68f
Fix mishandling of OLD/NEW references in subqueries in rule actions.
deanrasheed Feb 25, 2023
fcb2564
Don't force SQL_ASCII/no-locale for installcheck in vcregress.pl
adunstan Feb 26, 2023
fc9ab81
Harden postgres_fdw tests against unexpected cache flushes.
tglsfdc Feb 27, 2023
aa797f5
Avoid fetching one past the end of translate()'s "to" parameter.
tglsfdc Mar 1, 2023
4a37abb
pageinspect: Fix crash with gist_page_items()
michaelpq Mar 2, 2023
c31e116
Fix assert failures in parallel SERIALIZABLE READ ONLY.
macdice Mar 6, 2023
617de97
Fix more bugs caused by adding columns to the end of a view.
tglsfdc Mar 7, 2023
a523db9
Fix corruption due to vacuum_defer_cleanup_age underflowing 64bit xids
anarazel Mar 8, 2023
6541600
Fix race in SERIALIZABLE READ ONLY.
macdice Mar 9, 2023
de3bedc
Fix misbehavior in contrib/pg_trgm with an unsatisfiable regex.
tglsfdc Mar 11, 2023
1b0fd40
amcheck: Fix ordering bug in update_cached_xid_range()
anarazel Mar 11, 2023
f6784db
amcheck: Fix FullTransactionIdFromXidAndCtx() for xids before epoch 0
anarazel Mar 11, 2023
567ccb2
Mark unsafe_tests module as not runnable with installcheck
adunstan Mar 12, 2023
f13a802
Fix inconsistent error handling for GSS encryption in PQconnectPoll()
michaelpq Mar 13, 2023
a1490b5
Fix JSON error reporting for many cases of erroneous string values.
tglsfdc Mar 13, 2023
b8ac646
Remove unnecessary code in dependency_is_compatible_expression().
tglsfdc Mar 14, 2023
99266f7
Fix corner case bug in numeric to_char() some more.
tglsfdc Mar 14, 2023
d657b41
Fix waitpid() emulation on Windows.
macdice Mar 15, 2023
9b52c89
Fix fractional vacuum_cost_delay.
macdice Mar 15, 2023
f32a619
Improve WIN32 port of fstat() to detect more file types
michaelpq Mar 15, 2023
fd03282
Doc: mention CREATE+ATTACH PARTITION with CREATE TABLE...PARTITION OF.
tglsfdc Mar 16, 2023
8a182bb
Small tidyup for commit d41a178b.
macdice Mar 16, 2023
604a6f2
Small tidyup for commit d41a178b, part II.
macdice Mar 17, 2023
fb5d100
tests: Minimize syslog activity by slapd
anarazel Mar 17, 2023
b95732b
tests: Prevent syslog activity by slapd, take 2
anarazel Mar 17, 2023
b00a992
Fix pg_dump for hash partitioning on enum columns.
tglsfdc Mar 17, 2023
9d1db9b
Doc: fix documentation example for bytea hex output format.
tglsfdc Mar 18, 2023
ac91309
Fix memory leak in Memoize cache key evaluation
david-rowley Mar 20, 2023
bb73725
Fix netmask handling in inet_minmax_multi_ops
tvondra Mar 20, 2023
f2b217a
Fix race in parallel hash join batch cleanup, take II.
macdice Mar 21, 2023
a58f565
Ignore dropped columns during apply of update/delete.
Mar 21, 2023
01fbce0
doc: Add description of some missing monitoring functions
michaelpq Mar 22, 2023
8bdea85
Ignore generated columns during apply of update/delete.
Mar 23, 2023
9292a84
amcheck: Fix verify_heapam for tuples where xmin or xmax is 0.
robertmhaas Mar 23, 2023
9d63ac4
Fix oversights in array manipulation.
tglsfdc Mar 26, 2023
19f54ea
Reject attempts to alter composite types used in indexes.
tglsfdc Mar 27, 2023
2b155a0
doc: Fix XML_CATALOG_FILES env var for Apple Silicon machines
danielgustafsson Mar 27, 2023
f98f014
amcheck: In verify_heapam, allows tuples with xmin 0.
robertmhaas Mar 28, 2023
cd83e82
Fix dereference of dangling pointer in GiST index buffering build.
tglsfdc Mar 29, 2023
4544859
Fix List memory issue in transformColumnDefinition
david-rowley Mar 30, 2023
316dc34
Ensure acquire_inherited_sample_rows sets its output parameters.
tglsfdc Mar 31, 2023
c8f8915
Reject system columns as elements of foreign keys.
tglsfdc Mar 31, 2023
5e43f84
doc: Add more details about pg_stat_get_xact_blocks_{fetched,hit}
michaelpq Apr 4, 2023
4663ccf
doc: Update error messages in RLS examples
j-naylor Apr 5, 2023
5d1c6c2
Fix ts_headline() edge cases for empty query and empty search text.
tglsfdc Apr 6, 2023
3196a4f
Stabilize just-added regression test cases.
tglsfdc Apr 6, 2023
b103dcc
For Kerberos testing, disable reverse DNS lookup
sfrost Apr 7, 2023
fd27f65
For Kerberos testing, disable DNS lookups
sfrost Apr 7, 2023
8033771
Doc: adjust examples of EXTRACT() output to match current reality.
tglsfdc Apr 10, 2023
d4a2acf
Doc: add missed entries in BRIN extensibility tables.
tglsfdc Apr 10, 2023
4ebcaf0
Fix detection of unseekable files for fseek() and ftello() with MSVC
michaelpq Apr 12, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion configure
Original file line number Diff line number Diff line change
Expand Up @@ -15802,6 +15802,18 @@ if test "x$ac_cv_func_CRYPTO_lock" = xyes; then :
#define HAVE_CRYPTO_LOCK 1
_ACEOF

fi
done

# Function introduced in OpenSSL 1.1.1.
for ac_func in X509_get_signature_info
do :
ac_fn_c_check_func "$LINENO" "X509_get_signature_info" "ac_cv_func_X509_get_signature_info"
if test "x$ac_cv_func_X509_get_signature_info" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_X509_GET_SIGNATURE_INFO 1
_ACEOF

fi
done

Expand Down Expand Up @@ -16895,7 +16907,7 @@ $as_echo "#define HAVE_STDBOOL_H 1" >>confdefs.h
fi


for ac_header in atomic.h copyfile.h execinfo.h getopt.h ifaddrs.h langinfo.h mbarrier.h poll.h sys/epoll.h sys/event.h sys/ipc.h sys/prctl.h sys/procctl.h sys/pstat.h sys/resource.h sys/select.h sys/sem.h sys/shm.h sys/signalfd.h sys/sockio.h sys/tas.h sys/uio.h sys/un.h termios.h ucred.h wctype.h
for ac_header in atomic.h copyfile.h execinfo.h getopt.h ifaddrs.h langinfo.h mbarrier.h poll.h sys/epoll.h sys/event.h sys/ipc.h sys/personality.h sys/prctl.h sys/procctl.h sys/pstat.h sys/resource.h sys/select.h sys/sem.h sys/shm.h sys/signalfd.h sys/sockio.h sys/tas.h sys/uio.h sys/un.h termios.h ucred.h wctype.h
do :
as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
Expand Down Expand Up @@ -20393,6 +20405,12 @@ esac
;;
esac

case " $LIBOBJS " in
*" win32common.$ac_objext "* ) ;;
*) LIBOBJS="$LIBOBJS win32common.$ac_objext"
;;
esac

case " $LIBOBJS " in
*" win32env.$ac_objext "* ) ;;
*) LIBOBJS="$LIBOBJS win32env.$ac_objext"
Expand Down
4 changes: 4 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -1741,6 +1741,8 @@ if test "$with_ssl" = openssl ; then
# thread-safety. In 1.1.0, it's no longer required, and CRYPTO_lock()
# function was removed.
AC_CHECK_FUNCS([CRYPTO_lock])
# Function introduced in OpenSSL 1.1.1.
AC_CHECK_FUNCS([X509_get_signature_info])
AC_DEFINE([USE_OPENSSL], 1, [Define to 1 to build with OpenSSL support. (--with-ssl=openssl)])
elif test "$with_ssl" != no ; then
AC_MSG_ERROR([--with-ssl must specify openssl])
Expand Down Expand Up @@ -1904,6 +1906,7 @@ AC_CHECK_HEADERS(m4_normalize([
sys/epoll.h
sys/event.h
sys/ipc.h
sys/personality.h
sys/prctl.h
sys/procctl.h
sys/pstat.h
Expand Down Expand Up @@ -2517,6 +2520,7 @@ if test "$PORTNAME" = "win32"; then
AC_LIBOBJ(kill)
AC_LIBOBJ(open)
AC_LIBOBJ(system)
AC_LIBOBJ(win32common)
AC_LIBOBJ(win32env)
AC_LIBOBJ(win32error)
AC_LIBOBJ(win32security)
Expand Down
44 changes: 37 additions & 7 deletions contrib/amcheck/verify_heapam.c
Original file line number Diff line number Diff line change
Expand Up @@ -775,6 +775,8 @@ check_tuple_visibility(HeapCheckContext *ctx)
switch (get_xid_status(xmin, ctx, &xmin_status))
{
case XID_INVALID:
/* Could be the result of a speculative insertion that aborted. */
return false;
case XID_BOUNDS_OK:
break;
case XID_IN_FUTURE:
Expand Down Expand Up @@ -1110,6 +1112,9 @@ check_tuple_visibility(HeapCheckContext *ctx)
xmax = HeapTupleHeaderGetRawXmax(tuphdr);
switch (get_xid_status(xmax, ctx, &xmax_status))
{
case XID_INVALID:
ctx->tuple_could_be_pruned = false;
return true;
case XID_IN_FUTURE:
report_corruption(ctx,
psprintf("xmax %u equals or exceeds next valid transaction ID %u:%u",
Expand All @@ -1132,7 +1137,6 @@ check_tuple_visibility(HeapCheckContext *ctx)
XidFromFullTransactionId(ctx->oldest_fxid)));
return false; /* corrupt */
case XID_BOUNDS_OK:
case XID_INVALID:
break;
}

Expand Down Expand Up @@ -1577,14 +1581,40 @@ check_tuple(HeapCheckContext *ctx)
static FullTransactionId
FullTransactionIdFromXidAndCtx(TransactionId xid, const HeapCheckContext *ctx)
{
uint32 epoch;
uint64 nextfxid_i;
int32 diff;
FullTransactionId fxid;

Assert(TransactionIdIsNormal(ctx->next_xid));
Assert(FullTransactionIdIsNormal(ctx->next_fxid));
Assert(XidFromFullTransactionId(ctx->next_fxid) == ctx->next_xid);

if (!TransactionIdIsNormal(xid))
return FullTransactionIdFromEpochAndXid(0, xid);
epoch = EpochFromFullTransactionId(ctx->next_fxid);
if (xid > ctx->next_xid)
epoch--;
return FullTransactionIdFromEpochAndXid(epoch, xid);

nextfxid_i = U64FromFullTransactionId(ctx->next_fxid);

/* compute the 32bit modulo difference */
diff = (int32) (ctx->next_xid - xid);

/*
* In cases of corruption we might see a 32bit xid that is before epoch
* 0. We can't represent that as a 64bit xid, due to 64bit xids being
* unsigned integers, without the modulo arithmetic of 32bit xid. There's
* no really nice way to deal with that, but it works ok enough to use
* FirstNormalFullTransactionId in that case, as a freshly initdb'd
* cluster already has a newer horizon.
*/
if (diff > 0 && (nextfxid_i - FirstNormalTransactionId) < (int64) diff)
{
Assert(EpochFromFullTransactionId(ctx->next_fxid) == 0);
fxid = FirstNormalFullTransactionId;
}
else
fxid = FullTransactionIdFromU64(nextfxid_i - diff);

Assert(FullTransactionIdIsNormal(fxid));
return fxid;
}

/*
Expand All @@ -1600,8 +1630,8 @@ update_cached_xid_range(HeapCheckContext *ctx)
LWLockRelease(XidGenLock);

/* And compute alternate versions of the same */
ctx->oldest_fxid = FullTransactionIdFromXidAndCtx(ctx->oldest_xid, ctx);
ctx->next_xid = XidFromFullTransactionId(ctx->next_fxid);
ctx->oldest_fxid = FullTransactionIdFromXidAndCtx(ctx->oldest_xid, ctx);
}

/*
Expand Down
8 changes: 5 additions & 3 deletions contrib/pageinspect/expected/brin.out
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,14 @@ SELECT * FROM brin_page_items(get_raw_page('test1_a_idx', 2), 'test1_a_idx')
1 | 0 | 1 | f | f | f | {1 .. 1}
(1 row)

-- Failure for non-BRIN index.
-- Mask DETAIL messages as these are not portable across architectures.
\set VERBOSITY terse
-- Failures for non-BRIN index.
CREATE INDEX test1_a_btree ON test1 (a);
SELECT brin_page_items(get_raw_page('test1_a_btree', 0), 'test1_a_btree');
ERROR: "test1_a_btree" is not a BRIN index
-- Mask DETAIL messages as these are not portable across architectures.
\set VERBOSITY terse
SELECT brin_page_items(get_raw_page('test1_a_btree', 0), 'test1_a_idx');
ERROR: input page is not a valid BRIN page
-- Invalid special area size
SELECT brin_page_type(get_raw_page('test1', 0));
ERROR: input page is not a valid BRIN page
Expand Down
10 changes: 6 additions & 4 deletions contrib/pageinspect/expected/gist.out
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,16 @@ SELECT itemoffset, ctid, itemlen FROM gist_page_items_bytea(get_raw_page('test_g
2 | (2,65535) | 40
(2 rows)

-- Failure with non-GiST index.
-- Suppress the DETAIL message, to allow the tests to work across various
-- page sizes and architectures.
\set VERBOSITY terse
-- Failures with non-GiST index.
CREATE INDEX test_gist_btree on test_gist(t);
SELECT gist_page_items(get_raw_page('test_gist_btree', 0), 'test_gist_btree');
ERROR: "test_gist_btree" is not a GiST index
SELECT gist_page_items(get_raw_page('test_gist_btree', 0), 'test_gist_idx');
ERROR: input page is not a valid GiST page
-- Failure with various modes.
-- Suppress the DETAIL message, to allow the tests to work across various
-- page sizes and architectures.
\set VERBOSITY terse
-- invalid page size
SELECT gist_page_items_bytea('aaa'::bytea);
ERROR: invalid page size
Expand Down
82 changes: 40 additions & 42 deletions contrib/pageinspect/gistfuncs.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,29 +34,20 @@ PG_FUNCTION_INFO_V1(gist_page_items_bytea);
#define ItemPointerGetDatum(X) PointerGetDatum(X)


Datum
gist_page_opaque_info(PG_FUNCTION_ARGS)
static Page verify_gist_page(bytea *raw_page);

/*
* Verify that the given bytea contains a GIST page or die in the attempt.
* A pointer to the page is returned.
*/
static Page
verify_gist_page(bytea *raw_page)
{
bytea *raw_page = PG_GETARG_BYTEA_P(0);
TupleDesc tupdesc;
Page page;
Page page = get_page_from_raw(raw_page);
GISTPageOpaque opaq;
HeapTuple resultTuple;
Datum values[4];
bool nulls[4];
Datum flags[16];
int nflags = 0;
uint16 flagbits;

if (!superuser())
ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("must be superuser to use raw page functions")));

page = get_page_from_raw(raw_page);

if (PageIsNew(page))
PG_RETURN_NULL();
return page;

/* verify the special space has the expected size */
if (PageGetSpecialSize(page) != MAXALIGN(sizeof(GISTPageOpaqueData)))
Expand All @@ -76,12 +67,38 @@ gist_page_opaque_info(PG_FUNCTION_ARGS)
GIST_PAGE_ID,
opaq->gist_page_id)));

return page;
}

Datum
gist_page_opaque_info(PG_FUNCTION_ARGS)
{
bytea *raw_page = PG_GETARG_BYTEA_P(0);
TupleDesc tupdesc;
Page page;
HeapTuple resultTuple;
Datum values[4];
bool nulls[4];
Datum flags[16];
int nflags = 0;
uint16 flagbits;

if (!superuser())
ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("must be superuser to use raw page functions")));

page = verify_gist_page(raw_page);

if (PageIsNew(page))
PG_RETURN_NULL();

/* Build a tuple descriptor for our result type */
if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
elog(ERROR, "return type must be a row type");

/* Convert the flags bitmask to an array of human-readable names */
flagbits = opaq->flags;
flagbits = GistPageGetOpaque(page)->flags;
if (flagbits & F_LEAF)
flags[nflags++] = CStringGetTextDatum("leaf");
if (flagbits & F_DELETED)
Expand All @@ -103,7 +120,7 @@ gist_page_opaque_info(PG_FUNCTION_ARGS)

values[0] = LSNGetDatum(PageGetLSN(page));
values[1] = LSNGetDatum(GistPageGetNSN(page));
values[2] = Int64GetDatum(opaq->rightlink);
values[2] = Int64GetDatum(GistPageGetOpaque(page)->rightlink);
values[3] = PointerGetDatum(construct_array(flags, nflags,
TEXTOID,
-1, false, TYPALIGN_INT));
Expand All @@ -124,7 +141,6 @@ gist_page_items_bytea(PG_FUNCTION_ARGS)
Tuplestorestate *tupstore;
MemoryContext oldcontext;
Page page;
GISTPageOpaque opaq;
OffsetNumber offset;
OffsetNumber maxoff = InvalidOffsetNumber;

Expand Down Expand Up @@ -157,29 +173,11 @@ gist_page_items_bytea(PG_FUNCTION_ARGS)

MemoryContextSwitchTo(oldcontext);

page = get_page_from_raw(raw_page);
page = verify_gist_page(raw_page);

if (PageIsNew(page))
PG_RETURN_NULL();

/* verify the special space has the expected size */
if (PageGetSpecialSize(page) != MAXALIGN(sizeof(GISTPageOpaqueData)))
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("input page is not a valid %s page", "GiST"),
errdetail("Expected special size %d, got %d.",
(int) MAXALIGN(sizeof(GISTPageOpaqueData)),
(int) PageGetSpecialSize(page))));

opaq = (GISTPageOpaque) PageGetSpecialPointer(page);
if (opaq->gist_page_id != GIST_PAGE_ID)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("input page is not a valid %s page", "GiST"),
errdetail("Expected %08x, got %08x.",
GIST_PAGE_ID,
opaq->gist_page_id)));

/* Avoid bogus PageGetMaxOffsetNumber() call with deleted pages */
if (GistPageIsDeleted(page))
elog(NOTICE, "page is deleted");
Expand Down Expand Up @@ -276,7 +274,7 @@ gist_page_items(PG_FUNCTION_ARGS)
errmsg("\"%s\" is not a %s index",
RelationGetRelationName(indexRel), "GiST")));

page = get_page_from_raw(raw_page);
page = verify_gist_page(raw_page);

if (PageIsNew(page))
{
Expand Down
8 changes: 5 additions & 3 deletions contrib/pageinspect/sql/brin.sql
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,14 @@ SELECT * FROM brin_revmap_data(get_raw_page('test1_a_idx', 1)) LIMIT 5;
SELECT * FROM brin_page_items(get_raw_page('test1_a_idx', 2), 'test1_a_idx')
ORDER BY blknum, attnum LIMIT 5;

-- Failure for non-BRIN index.
-- Mask DETAIL messages as these are not portable across architectures.
\set VERBOSITY terse

-- Failures for non-BRIN index.
CREATE INDEX test1_a_btree ON test1 (a);
SELECT brin_page_items(get_raw_page('test1_a_btree', 0), 'test1_a_btree');
SELECT brin_page_items(get_raw_page('test1_a_btree', 0), 'test1_a_idx');

-- Mask DETAIL messages as these are not portable across architectures.
\set VERBOSITY terse
-- Invalid special area size
SELECT brin_page_type(get_raw_page('test1', 0));
SELECT * FROM brin_metapage_info(get_raw_page('test1', 0));
Expand Down
10 changes: 6 additions & 4 deletions contrib/pageinspect/sql/gist.sql
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,16 @@ SELECT * FROM gist_page_items(get_raw_page('test_gist_idx', 1), 'test_gist_idx')
-- platform-dependent (endianess), so omit the actual key data from the output.
SELECT itemoffset, ctid, itemlen FROM gist_page_items_bytea(get_raw_page('test_gist_idx', 0));

-- Failure with non-GiST index.
-- Suppress the DETAIL message, to allow the tests to work across various
-- page sizes and architectures.
\set VERBOSITY terse

-- Failures with non-GiST index.
CREATE INDEX test_gist_btree on test_gist(t);
SELECT gist_page_items(get_raw_page('test_gist_btree', 0), 'test_gist_btree');
SELECT gist_page_items(get_raw_page('test_gist_btree', 0), 'test_gist_idx');

-- Failure with various modes.
-- Suppress the DETAIL message, to allow the tests to work across various
-- page sizes and architectures.
\set VERBOSITY terse
-- invalid page size
SELECT gist_page_items_bytea('aaa'::bytea);
SELECT gist_page_items('aaa'::bytea, 'test_gist_idx'::regclass);
Expand Down
14 changes: 7 additions & 7 deletions contrib/pax_storage/src/test/regress/expected/alter_table.out
Original file line number Diff line number Diff line change
Expand Up @@ -2628,20 +2628,20 @@ View definition:
FROM at_view_1 v1;

explain (verbose, costs off) select * from at_view_2;
QUERY PLAN
----------------------------------------------------------------------
QUERY PLAN
-------------------------------------------------------------------
Gather Motion 3:1 (slice1; segments: 3)
Output: bt.id, bt.stuff, (to_json(ROW(bt.id, bt.stuff, NULL)))
Output: bt.id, bt.stuff, (to_json(ROW(bt.id, bt.stuff, 4)))
-> Seq Scan on public.at_base_table bt
Output: bt.id, bt.stuff, to_json(ROW(bt.id, bt.stuff, NULL))
Output: bt.id, bt.stuff, to_json(ROW(bt.id, bt.stuff, 4))
Optimizer: Postgres query optimizer
Settings: constraint_exclusion=partition
(6 rows)

select * from at_view_2;
id | stuff | j
----+--------+----------------------------------------
23 | skidoo | {"id":23,"stuff":"skidoo","more":null}
id | stuff | j
----+--------+-------------------------------------
23 | skidoo | {"id":23,"stuff":"skidoo","more":4}
(1 row)

drop view at_view_2;
Expand Down
Loading
Loading