Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit6e40f6a

Browse files
committed
Add RELOID and TYPEOID portbility.
1 parent1349c4e commit6e40f6a

File tree

10 files changed

+329
-6
lines changed

10 files changed

+329
-6
lines changed

‎contrib/pg_execplan/init.sql

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@
44
-- query - query string which will be parsed and planned.
55
-- filename - path to the file on a disk.
66
CREATEOR REPLACE FUNCTION @extschema@.pg_store_query_plan(
7-
queryTEXT,
8-
filenameTEXT)
7+
filenameTEXT,
8+
queryTEXT
9+
)
910
RETURNS VOIDAS'pg_execplan'
1011
LANGUAGE C;
1112

‎contrib/pg_execplan/pg_execplan.c

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,9 @@ pg_store_query_plan(PG_FUNCTION_ARGS)
8383
fwrite(&string_len,sizeof(size_t),1,fout);
8484
fwrite(query_string,sizeof(char),string_len,fout);
8585

86+
set_portable_output(true);
8687
plan_string=nodeToString(queryDesc->plannedstmt);
88+
set_portable_output(false);
8789
string_len=strlen(plan_string);
8890
fwrite(&string_len,sizeof(size_t),1,fout);
8991
fwrite(plan_string,sizeof(char),string_len,fout);
@@ -135,7 +137,19 @@ pg_exec_query_plan(PG_FUNCTION_ARGS)
135137
inteflags=0;
136138

137139
LoadPlanFromFile(filename,&query_string,&plan_string);
138-
pstmt= (PlannedStmt*)stringToNode(plan_string);
140+
141+
PG_TRY();
142+
{
143+
set_portable_input(true);
144+
pstmt= (PlannedStmt*)stringToNode(plan_string);
145+
set_portable_input(false);
146+
}
147+
PG_CATCH();
148+
{
149+
elog(INFO,"!!!BAD PLAN: %s",plan_string);
150+
PG_RE_THROW();
151+
}
152+
PG_END_TRY();
139153

140154
psrc=CreateCachedPlan(NULL,query_string,query_string);
141155
CompleteCachedPlan(psrc,NIL,NULL,NULL,0,NULL,NULL,
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
-- Make dummy I/O routines using the existing internal support for int4, text
2+
CREATEFUNCTIONint42_in(cstring)
3+
RETURNS int42
4+
AS'int4in'
5+
LANGUAGE internal STRICT IMMUTABLE;
6+
CREATEFUNCTIONint42_out(int42)
7+
RETURNS cstring
8+
AS'int4out'
9+
LANGUAGE internal STRICT IMMUTABLE;
10+
11+
CREATETYPEint42 (
12+
internallength=4,
13+
input= int42_in,
14+
output= int42_out,
15+
alignment= int4,
16+
default=42,
17+
passedbyvalue
18+
);
19+
20+
CREATETABLEt1 (id int42);

‎contrib/pg_execplan/tests/rpl.sh

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
#!/bin/bash
2+
3+
# Script for the plan passing between separate instances
4+
U=`whoami`
5+
6+
# Paths
7+
PGINSTALL=`pwd`/tmp_install/
8+
LD_LIBRARY_PATH=$PGINSTALL/lib
9+
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH
10+
export PATH=$PGINSTALL/bin:$PATH
11+
12+
pkill -9 postgres||true
13+
sleep 1
14+
rm -rf$PGINSTALL||true
15+
rm -rf PGDATA_Master||true
16+
rm -rf PGDATA_Slave||true
17+
rm -rf master.log||true
18+
rm -rf slave.log||true
19+
20+
# Building project
21+
make> /dev/null
22+
make -C contrib> /dev/null
23+
make install> /dev/null
24+
make -C contrib install> /dev/null
25+
26+
mkdir PGDATA_Master
27+
mkdir PGDATA_Slave
28+
initdb -D PGDATA_Master
29+
initdb -D PGDATA_Slave
30+
echo"shared_preload_libraries = 'postgres_fdw, pg_execplan'">> PGDATA_Master/postgresql.conf
31+
echo"shared_preload_libraries = 'postgres_fdw, pg_execplan'">> PGDATA_Slave/postgresql.conf
32+
33+
pg_ctl -w -D PGDATA_Master -o"-p 5432" -l master.log start
34+
pg_ctl -w -D PGDATA_Slave -o"-p 5433" -l slave.log start
35+
createdb$U -p 5432
36+
createdb$U -p 5433
37+
38+
psql -p 5432 -c"CREATE EXTENSION postgres_fdw;"
39+
psql -p 5433 -c"CREATE EXTENSION postgres_fdw;"
40+
psql -p 5432 -c"CREATE EXTENSION pg_execplan;"
41+
psql -p 5433 -c"CREATE EXTENSION pg_execplan;"
42+
43+
# shift oids
44+
psql -p 5433 -c"CREATE TABLE t0 (id int);"
45+
psql -p 5433 -c"DROP TABLE t0;"
46+
47+
#create database objects for check of oid switching
48+
psql -p 5432 -f contrib/pg_execplan/tests/create_objects.sql
49+
psql -p 5433 -f contrib/pg_execplan/tests/create_objects.sql
50+
51+
# TEST ON RELOID and TYPEOID objects.
52+
psql -p 5432 -c"SELECT pg_store_query_plan('../test.txt', 'SELECT * FROM t1;');"
53+
psql -p 5433 -c"SELECT pg_exec_query_plan('../test.txt');"
54+

‎src/backend/nodes/outfuncs.c

Lines changed: 76 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,80 @@
3030
#include"nodes/plannodes.h"
3131
#include"nodes/relation.h"
3232
#include"utils/datum.h"
33+
#include"utils/lsyscache.h"
3334
#include"utils/rel.h"
35+
#include"utils/syscache.h"
3436

37+
#defineOID_TYPES_NUM(2)
38+
staticconstOidoid_types[OID_TYPES_NUM]= {RELOID,TYPEOID};
39+
40+
staticboolportable_output= false;
41+
void
42+
set_portable_output(boolvalue)
43+
{
44+
portable_output=value;
45+
}
46+
47+
staticvoid
48+
write_oid_field(StringInfostr,Oidoid)
49+
{
50+
inti;
51+
52+
if (!portable_output)
53+
{
54+
appendStringInfo(str," %u",oid);
55+
return;
56+
}
57+
58+
appendStringInfo(str," (");
59+
60+
if (!OidIsValid(oid))
61+
{
62+
/* Special case for invalid oid fields. For example, checkAsUser. */
63+
elog(INFO,"oid %d is INVALID OID!",oid);
64+
appendStringInfo(str,"%u %u)",0,oid);
65+
return;
66+
}
67+
68+
for (i=0;i<OID_TYPES_NUM;i++)
69+
if (SearchSysCacheExists1(oid_types[i],oid))
70+
break;
71+
72+
if (i==OID_TYPES_NUM)
73+
{
74+
elog(INFO,"Unexpected oid type %d!",oid);
75+
appendStringInfo(str,"%u %u)",0,oid);
76+
return;
77+
}
78+
79+
switch (oid_types[i])
80+
{
81+
caseRELOID:
82+
elog(INFO,"(RELOID %d): (%s, %s)",oid,
83+
get_namespace_name((get_rel_namespace((oid)))),
84+
get_rel_name((oid))
85+
);
86+
appendStringInfo(str,"%u %s %s",RELOID,
87+
get_namespace_name((get_rel_namespace((oid)))),
88+
get_rel_name((oid)));
89+
break;
90+
91+
caseTYPEOID:
92+
elog(INFO,"(TYPEOID %d): %s %s",oid,
93+
get_namespace_name(get_typ_namespace(oid)),
94+
get_typ_name(oid));
95+
appendStringInfo(str,"%u %s %s",TYPEOID,
96+
get_namespace_name(get_typ_namespace(oid)),
97+
get_typ_name(oid));
98+
99+
break;
100+
101+
default:
102+
elog(ERROR,"oid %d type is %d (NOT DEFINED)!",oid,oid_types[i]);
103+
break;
104+
}
105+
appendStringInfo(str,")");
106+
}
35107

36108
/*
37109
* Macros to simplify output of different kinds of fields. Use these
@@ -54,7 +126,10 @@
54126

55127
/* Write an OID field (don't hard-wire assumption that OID is same as uint) */
56128
#defineWRITE_OID_FIELD(fldname) \
57-
appendStringInfo(str, " :" CppAsString(fldname) " %u", node->fldname)
129+
do { \
130+
appendStringInfo(str, " :%s", CppAsString(fldname)); \
131+
write_oid_field(str, node->fldname); \
132+
} while (0)
58133

59134
/* Write a long-integer field */
60135
#defineWRITE_LONG_FIELD(fldname) \

‎src/backend/nodes/readfuncs.c

Lines changed: 91 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,19 @@
3434
#include"nodes/plannodes.h"
3535
#include"nodes/readfuncs.h"
3636

37+
/* Portable-related dependencies */
38+
#include"utils/lsyscache.h"
39+
#include"catalog/namespace.h"
40+
#include"utils/syscache.h"
41+
42+
staticOidread_oid_field(char**token,int*length);
43+
44+
staticboolportable_input= false;
45+
void
46+
set_portable_input(boolvalue)
47+
{
48+
portable_input=value;
49+
}
3750

3851
/*
3952
* Macros to simplify reading of different kinds of fields. Use these
@@ -79,8 +92,7 @@
7992
/* Read an OID field (don't hard-wire assumption that OID is same as uint) */
8093
#defineREAD_OID_FIELD(fldname) \
8194
token = pg_strtok(&length);/* skip :fldname */ \
82-
token=pg_strtok(&length);/* get field value */ \
83-
local_node->fldname=atooid(token)
95+
local_node->fldname=read_oid_field(&token,&length);
8496

8597
/* Read a char field (ie, one ascii character) */
8698
#defineREAD_CHAR_FIELD(fldname) \
@@ -2719,3 +2731,80 @@ readBoolCols(int numCols)
27192731

27202732
returnbool_vals;
27212733
}
2734+
2735+
#defineatooid(x) ((Oid) strtoul((x), NULL, 10))
2736+
2737+
staticOid
2738+
read_oid_field(char**token,int*length)
2739+
{
2740+
Oidoid_type,
2741+
oid;
2742+
2743+
if (!portable_input)
2744+
{
2745+
*token=pg_strtok(length);
2746+
returnatooid(*token);
2747+
}
2748+
2749+
*token=pg_strtok(length);
2750+
Assert((*token)[0]='(');
2751+
*token=pg_strtok(length);
2752+
oid_type=atooid(*token);
2753+
2754+
if (!OidIsValid(oid_type))
2755+
{
2756+
Oidoid;
2757+
*token=pg_strtok(length);
2758+
oid=atooid(*token);
2759+
*token=pg_strtok(length);
2760+
Assert((*token)[0]=')');
2761+
returnoid;
2762+
}
2763+
2764+
switch (oid_type)
2765+
{
2766+
caseRELOID:
2767+
{
2768+
char*relname,
2769+
*nspname;
2770+
Oidrel_nsp_oid;
2771+
2772+
*token=pg_strtok(length);/* Switch to namespace name */
2773+
nspname=nullable_string(*token,*length);
2774+
rel_nsp_oid=LookupNamespaceNoError(nspname);
2775+
*token=pg_strtok(length);/* Switch to relname */
2776+
relname=nullable_string(*token,*length);
2777+
oid=get_relname_relid(relname,rel_nsp_oid);
2778+
elog(INFO,"reloid=%d",oid);
2779+
break;
2780+
}
2781+
caseTYPEOID:
2782+
{
2783+
char*nspname;/* namespace name */
2784+
char*typname;/* data type name */
2785+
2786+
*token=pg_strtok(length);/* get nspname */
2787+
nspname=nullable_string(*token,*length);
2788+
*token=pg_strtok(length);/* get typname */
2789+
typname=nullable_string(*token,*length);
2790+
if (typname)
2791+
{
2792+
oid=get_typname_typid(typname,LookupNamespaceNoError((nspname)));
2793+
if (!OidIsValid((oid)))
2794+
elog(WARNING,"could not find OID for type %s.%s",
2795+
nspname,typname);
2796+
}
2797+
else
2798+
oid=InvalidOid;
2799+
elog(INFO,"typeoid=%d",oid);
2800+
}
2801+
break;
2802+
2803+
default:
2804+
Assert(0);
2805+
break;
2806+
}
2807+
*token=pg_strtok(length);
2808+
Assert((*token)[0]=')');
2809+
returnoid;
2810+
}

‎src/backend/utils/cache/lsyscache.c

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3061,3 +3061,67 @@ get_range_subtype(Oid rangeOid)
30613061
else
30623062
returnInvalidOid;
30633063
}
3064+
3065+
/*
3066+
* get_typ_name
3067+
*
3068+
*Given the type OID, find the type name
3069+
*It returns palloc'd copy of the name or NULL if the cache lookup fails...
3070+
*/
3071+
char*
3072+
get_typ_name(Oidtypid)
3073+
{
3074+
HeapTupletp;
3075+
3076+
tp=SearchSysCache1(TYPEOID,ObjectIdGetDatum(typid));
3077+
if (HeapTupleIsValid(tp))
3078+
{
3079+
Form_pg_typetyptup= (Form_pg_type)GETSTRUCT(tp);
3080+
char*result;
3081+
3082+
result=pstrdup(NameStr(typtup->typname));
3083+
ReleaseSysCache(tp);
3084+
returnresult;
3085+
}
3086+
else
3087+
returnNULL;
3088+
}
3089+
3090+
/*
3091+
* get_typ_namespace
3092+
*
3093+
*Given the type OID, find the namespace
3094+
*It returns InvalidOid if the cache lookup fails...
3095+
*/
3096+
Oid
3097+
get_typ_namespace(Oidtypid)
3098+
{
3099+
HeapTupletp;
3100+
3101+
tp=SearchSysCache1(TYPEOID,ObjectIdGetDatum(typid));
3102+
if (HeapTupleIsValid(tp))
3103+
{
3104+
Form_pg_typetyptup= (Form_pg_type)GETSTRUCT(tp);
3105+
Oidresult;
3106+
3107+
result=typtup->typnamespace;
3108+
ReleaseSysCache(tp);
3109+
returnresult;
3110+
}
3111+
else
3112+
returnInvalidOid;
3113+
}
3114+
3115+
/*
3116+
* get_typname_typid
3117+
* Given a type name and namespace OID, look up the type OID.
3118+
*
3119+
* Returns InvalidOid if there is no such type
3120+
*/
3121+
Oid
3122+
get_typname_typid(constchar*typname,Oidtypnamespace)
3123+
{
3124+
returnGetSysCacheOid2(TYPENAMENSP,
3125+
CStringGetDatum(typname),
3126+
ObjectIdGetDatum(typnamespace));
3127+
}

‎src/include/nodes/nodes.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -575,6 +575,8 @@ extern void outBitmapset(struct StringInfoData *str,
575575
conststructBitmapset*bms);
576576
externvoidoutDatum(structStringInfoData*str,uintptr_tvalue,
577577
inttyplen,booltypbyval);
578+
579+
externvoidset_portable_output(boolvalue);
578580
externchar*nodeToString(constvoid*obj);
579581
externchar*bmsToString(conststructBitmapset*bms);
580582

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp