Skip to content

Commit 1cd24be

Browse files
committed
Add 6 more OID typeds at portable plan
1 parent f3cc978 commit 1cd24be

File tree

9 files changed

+356
-11
lines changed

9 files changed

+356
-11
lines changed

contrib/pg_execplan/tests/regress

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#!/bin/bash
22

33
# This script performs regress tests at a master and mirrored it into the slave.
4-
U=`whoami`
4+
U=regression
55
export LC_ALL=C
66
export LANGUAGE="en_US:en"
77

@@ -12,6 +12,7 @@ LD_LIBRARY_PATH=$PGINSTALL/lib
1212
remoteSrvName=fdwremote
1313
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH
1414
export PATH=$PGINSTALL/bin:$PATH
15+
export PGDATABASE=regression
1516

1617
pkill -9 postgres || true
1718
sleep 1
@@ -41,7 +42,7 @@ createdb -p 5433 $U
4142
createdb -p 5432 $U
4243

4344
psql -p 5432 -c "CREATE EXTENSION postgres_fdw;"
44-
psql -p 5432 -c "CREATE SERVER $remoteSrvName FOREIGN DATA WRAPPER postgres_fdw OPTIONS (port '5433', use_remote_estimate 'on');"
45+
psql -p 5432 -c "CREATE SERVER $remoteSrvName FOREIGN DATA WRAPPER postgres_fdw OPTIONS (port '5433', dbname 'regression', use_remote_estimate 'on');"
4546
psql -p 5432 -c "CREATE USER MAPPING FOR PUBLIC SERVER $remoteSrvName;"
4647

4748
# Prepare plan execution
@@ -59,4 +60,4 @@ rm -rf $PGINSTALL/lib/regress.so
5960
cp `pwd`/src/test/regress/regress.so $PGINSTALL/lib
6061
cp `pwd`/src/test/regress/regress.so $PGINSTALL/lib/postgresql/
6162
cd src/test/regress
62-
./pg_regress --schedule=$SCRIPTS/serial_schedule --load-extension=postgres_fdw --load-extension=pg_execplan --load-extension=pg_repeater --dbname=andrey --use-existing
63+
./pg_regress --schedule=$SCRIPTS/serial_schedule --load-extension=postgres_fdw --load-extension=pg_execplan --load-extension=pg_repeater --dbname=regression --use-existing

contrib/pg_execplan/tests/rpl.sh

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,3 +78,17 @@ psql -p 5433 -c "SELECT oid, oprname, oprnamespace FROM pg_operator WHERE oprnam
7878
# Test
7979
psql -p 5432 -c "SELECT pg_store_query_plan('../test.txt', 'SELECT id ### 1 FROM tests.ttest1;');"
8080
psql -p 5433 -c "SELECT pg_exec_stored_plan('../test.txt');"
81+
82+
#ENUMOID -----------------------------------------------------------------------
83+
psql -p 5432 -c "CREATE TYPE mood AS ENUM ('sad', 'ok', 'happy');"
84+
psql -p 5432 -c "CREATE TABLE person ( name text, current_mood mood);"
85+
psql -p 5433 -c "CREATE TYPE mood AS ENUM ('sad', 'ok', 'happy');"
86+
psql -p 5433 -c "CREATE TABLE person ( name text, current_mood mood);"
87+
88+
psql -p 5432 -c "SELECT pg_store_query_plan('../test.txt', 'INSERT INTO person VALUES (''Moe'', ''happy'');');"
89+
psql -p 5432 -c "SELECT pg_exec_stored_plan('../test.txt');"
90+
psql -p 5433 -c "SELECT pg_exec_stored_plan('../test.txt');"
91+
92+
psql -p 5432 -c "SELECT * FROM person WHERE current_mood = 'happy';"
93+
psql -p 5433 -c "SELECT * FROM person WHERE current_mood = 'happy';"
94+

contrib/pg_repeater/pg_repeater.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
#include "postgres.h"
1515

16+
#include "access/parallel.h"
1617
#include "access/xact.h"
1718
#include "commands/extension.h"
1819
#include "executor/executor.h"
@@ -184,6 +185,7 @@ HOOK_ExecStart_injection(QueryDesc *queryDesc, int eflags)
184185
*/
185186
if (ExtensionIsActive() &&
186187
queryDesc->plannedstmt->canSetTag &&
188+
!IsParallelWorker() &&
187189
((parsetree == NULL) || (nodeTag(parsetree) != T_CreatedbStmt)) &&
188190
!(eflags & EXEC_FLAG_EXPLAIN_ONLY))
189191
{

src/backend/commands/opclasscmds.c

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1589,6 +1589,58 @@ RemoveOpFamilyById(Oid opfamilyOid)
15891589
heap_close(rel, RowExclusiveLock);
15901590
}
15911591

1592+
Oid
1593+
get_family_oid(const char *opfname, const char *nspname, const char *ammth)
1594+
{
1595+
Oid nspoid,
1596+
amoid,
1597+
opfoid = InvalidOid;
1598+
HeapTuple htup = NULL;
1599+
1600+
nspoid = LookupNamespaceNoError(nspname);
1601+
amoid = get_am_oid(ammth, false);
1602+
1603+
if (OidIsValid(nspoid) && OidIsValid(amoid))
1604+
htup = SearchSysCache3(OPFAMILYAMNAMENSP,
1605+
ObjectIdGetDatum(amoid),
1606+
PointerGetDatum(opfname),
1607+
ObjectIdGetDatum(nspoid));
1608+
1609+
if (HeapTupleIsValid(htup))
1610+
{
1611+
opfoid = HeapTupleGetOid(htup);
1612+
ReleaseSysCache(htup);
1613+
}
1614+
1615+
return opfoid;
1616+
}
1617+
1618+
char *
1619+
get_opfamily_name(Oid opfamilyOid, char **nspname, char **opfmethod)
1620+
{
1621+
HeapTuple tup;
1622+
char *opfname;
1623+
Oid nspoid,
1624+
mthoid;
1625+
1626+
Assert(nspname != NULL);
1627+
1628+
1629+
tup = SearchSysCache1(OPFAMILYOID, ObjectIdGetDatum(opfamilyOid));
1630+
if (!HeapTupleIsValid(tup)) /* should not happen */
1631+
elog(ERROR, "cache lookup failed for opfamily %u", opfamilyOid);
1632+
1633+
opfname = pstrdup(NameStr(((Form_pg_opfamily) GETSTRUCT(tup))->opfname));
1634+
nspoid = ((Form_pg_opfamily) GETSTRUCT(tup))->opfnamespace;
1635+
*nspname = get_namespace_name(nspoid);
1636+
1637+
mthoid = ((Form_pg_opfamily) GETSTRUCT(tup))->opfmethod;
1638+
*opfmethod = get_am_name(mthoid);
1639+
1640+
ReleaseSysCache(tup);
1641+
return opfname;
1642+
}
1643+
15921644
void
15931645
RemoveOpClassById(Oid opclassOid)
15941646
{

src/backend/nodes/outfuncs.c

Lines changed: 107 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,12 @@
2525

2626
#include <ctype.h>
2727

28+
#include "catalog/pg_type.h"
29+
#include "commands/dbcommands.h"
30+
#include "commands/defrem.h"
2831
#include "commands/user.h"
2932
#include "lib/stringinfo.h"
33+
#include "miscadmin.h"
3034
#include "nodes/extensible.h"
3135
#include "nodes/plannodes.h"
3236
#include "nodes/relation.h"
@@ -36,10 +40,13 @@
3640
#include "utils/syscache.h"
3741

3842
#define NSP_NAME(nspoid) (get_namespace_name(nspoid))
39-
#define OID_TYPES_NUM (6)
40-
static const Oid oid_types[OID_TYPES_NUM] = {RELOID, TYPEOID, PROCOID, COLLOID,
41-
OPEROID, AUTHOID};
43+
#define OID_TYPES_NUM (12)
4244

45+
static const Oid oid_types[OID_TYPES_NUM] = {RELOID, TYPEOID, PROCOID, COLLOID,
46+
OPEROID, AUTHOID, LANGOID, AMOID,
47+
NAMESPACEOID, DATABASEOID, RULEOID,
48+
OPFAMILYOID};
49+
static void _printDatum(StringInfo str, Datum value, Oid typid);
4350
static bool portable_output = false;
4451
void
4552
set_portable_output(bool value)
@@ -50,7 +57,9 @@ set_portable_output(bool value)
5057
static void
5158
write_oid_field(StringInfo str, Oid oid)
5259
{
53-
int i;
60+
int i;
61+
char *rulename;
62+
Oid ev_class = InvalidOid;
5463

5564
if (!portable_output)
5665
{
@@ -63,18 +72,23 @@ write_oid_field(StringInfo str, Oid oid)
6372
if (!OidIsValid(oid))
6473
{
6574
/* Special case for invalid oid fields. For example, checkAsUser. */
66-
appendStringInfo(str, "%u %u)", 0, oid);
75+
appendStringInfo(str, "0 %u)", oid);
6776
return;
6877
}
6978

7079
for (i = 0; i < OID_TYPES_NUM; i++)
71-
if (SearchSysCacheExists1(oid_types[i], oid))
80+
if (oid_types[i] != RULEOID)
81+
{
82+
if (SearchSysCacheExists1(oid_types[i], oid))
83+
break;
84+
}
85+
else if ((rulename = get_rule_name(oid, &ev_class)) != NULL)
7286
break;
7387

7488
if (i == OID_TYPES_NUM)
7589
{
76-
elog(INFO, "Unexpected oid type %d!", oid);
77-
appendStringInfo(str, "%u %u)", 0, oid);
90+
elog(LOG, "Unexpected oid type %d!", oid);
91+
appendStringInfo(str, "0 %u)", oid);
7892
return;
7993
}
8094

@@ -147,6 +161,42 @@ write_oid_field(StringInfo str, Oid oid)
147161
appendStringInfo(str, "%u %s", AUTHOID, get_rolename(oid));
148162
break;
149163

164+
case LANGOID:
165+
appendStringInfo(str, "%u %s", LANGOID, get_language_name(oid, false));
166+
break;
167+
168+
case AMOID:
169+
appendStringInfo(str, "%u %s", AMOID, get_am_name(oid));
170+
break;
171+
172+
case NAMESPACEOID:
173+
appendStringInfo(str, "%u %s", NAMESPACEOID, get_namespace_name_or_temp(oid));
174+
break;
175+
176+
case DATABASEOID:
177+
appendStringInfo(str, "%u %s", DATABASEOID, get_database_name(oid));
178+
break;
179+
180+
case RULEOID:
181+
Assert(rulename != NULL);
182+
appendStringInfo(str, "%u %s %s %s", RULEOID, rulename,
183+
NSP_NAME(get_rel_namespace(ev_class)),
184+
get_rel_name(ev_class));
185+
break;
186+
187+
case OPFAMILYOID:
188+
{
189+
char *opfname = NULL,
190+
*nspname = NULL,
191+
*amname = NULL;
192+
193+
opfname = get_opfamily_name(oid, &nspname, &amname);
194+
Assert(opfname && nspname && amname);
195+
196+
appendStringInfo(str, "%u %s %s %s", OPFAMILYOID, opfname, nspname, amname);
197+
}
198+
break;
199+
150200
default:
151201
Assert(0);
152202
break;
@@ -1125,6 +1175,8 @@ _outConst(StringInfo str, const Const *node)
11251175
appendStringInfoString(str, " :constvalue ");
11261176
if (node->constisnull)
11271177
appendStringInfoString(str, "<>");
1178+
else if (portable_output)
1179+
_printDatum(str, node->constvalue, node->consttype);
11281180
else
11291181
outDatum(str, node->constvalue, node->constlen, node->constbyval);
11301182
}
@@ -4125,3 +4177,50 @@ bmsToString(const Bitmapset *bms)
41254177
outBitmapset(&str, bms);
41264178
return str.data;
41274179
}
4180+
4181+
/*
4182+
* Output value in text format
4183+
*/
4184+
static void
4185+
_printDatum(StringInfo str, Datum value, Oid typid)
4186+
{
4187+
Oid typOutput;
4188+
bool typIsVarlena;
4189+
FmgrInfo finfo;
4190+
Datum tmpval;
4191+
char *textvalue;
4192+
int saveDateStyle;
4193+
4194+
/* Get output function for the type */
4195+
getTypeOutputInfo(typid, &typOutput, &typIsVarlena);
4196+
fmgr_info(typOutput, &finfo);
4197+
4198+
/* Detoast value if needed */
4199+
if (typIsVarlena)
4200+
tmpval = PointerGetDatum(PG_DETOAST_DATUM(value));
4201+
else
4202+
tmpval = value;
4203+
4204+
/*
4205+
* It was found that if configuration setting for date style is
4206+
* "postgres,ymd" the output dates have format DD-MM-YYYY and they can not
4207+
* be parsed correctly by receiving party. So force ISO format YYYY-MM-DD
4208+
* in internal cluster communications, these values are always parsed
4209+
* correctly.
4210+
*/
4211+
saveDateStyle = DateStyle;
4212+
DateStyle = USE_ISO_DATES;
4213+
4214+
if (typid == OIDOID)
4215+
{
4216+
/* Const type is "OID". Need to parse. */
4217+
Oid oid = DatumGetObjectId(value);
4218+
write_oid_field(str, oid);
4219+
}
4220+
else
4221+
{
4222+
textvalue = DatumGetCString(FunctionCall1(&finfo, tmpval));
4223+
outToken(str, textvalue);
4224+
}
4225+
DateStyle = saveDateStyle;
4226+
}

0 commit comments

Comments
 (0)