Skip to content

Commit f834645

Browse files
author
Vladimir Ershov
committed
fix schema change
1 parent 9531f66 commit f834645

File tree

2 files changed

+113
-21
lines changed

2 files changed

+113
-21
lines changed

sr_plan.c

Lines changed: 109 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
#include "sr_plan.h"
22
#include "commands/event_trigger.h"
3+
#include "commands/extension.h"
4+
#include "catalog/pg_extension.h"
5+
#include "catalog/indexing.h"
6+
#include "access/sysattr.h"
7+
#include "access/xact.h"
8+
#include "utils/lsyscache.h"
39

410
PG_MODULE_MAGIC;
511

@@ -17,6 +23,8 @@ PlanCacheRelCallback(Datum arg, Oid relid);*/
1723
void sr_analyze(ParseState *pstate,
1824
Query *query);
1925

26+
static Oid get_sr_plan_schema(void);
27+
static Oid sr_get_relname_oid(Oid schema_oid, const char *relname);
2028
bool sr_query_walker(Query *node, void *context);
2129
bool sr_query_expr_walker(Node *node, void *context);
2230
void *replace_fake(void *node);
@@ -39,6 +47,65 @@ void sr_analyze(ParseState *pstate, Query *query)
3947
query_text = pstate->p_sourcetext;
4048
}
4149

50+
/*
51+
* Return sr_plan schema's Oid or InvalidOid if that's not possible.
52+
*/
53+
static Oid
54+
get_sr_plan_schema(void)
55+
{
56+
Oid result;
57+
Relation rel;
58+
SysScanDesc scandesc;
59+
HeapTuple tuple;
60+
ScanKeyData entry[1];
61+
Oid ext_schema;
62+
LOCKMODE heap_lock = AccessShareLock;
63+
64+
/* It's impossible to fetch sr_plan's schema now */
65+
if (!IsTransactionState())
66+
return InvalidOid;
67+
68+
ext_schema = get_extension_oid("sr_plan", true);
69+
if (ext_schema == InvalidOid)
70+
return InvalidOid; /* exit if sr_plan does not exist */
71+
72+
ScanKeyInit(&entry[0],
73+
ObjectIdAttributeNumber,
74+
BTEqualStrategyNumber, F_OIDEQ,
75+
ObjectIdGetDatum(ext_schema));
76+
77+
rel = heap_open(ExtensionRelationId, heap_lock);
78+
scandesc = systable_beginscan(rel, ExtensionOidIndexId, true,
79+
NULL, 1, entry);
80+
81+
tuple = systable_getnext(scandesc);
82+
83+
/* We assume that there can be at most one matching tuple */
84+
if (HeapTupleIsValid(tuple))
85+
result = ((Form_pg_extension) GETSTRUCT(tuple))->extnamespace;
86+
else
87+
result = InvalidOid;
88+
89+
systable_endscan(scandesc);
90+
91+
heap_close(rel, heap_lock);
92+
93+
return result;
94+
}
95+
96+
/*
97+
* Return Oid of relation in sr_plan extension schema or
98+
* InvalidOid if that's not possible.
99+
*/
100+
101+
static Oid sr_get_relname_oid(Oid schema_oid, const char *relname)
102+
{
103+
if(schema_oid == InvalidOid) schema_oid = get_sr_plan_schema();
104+
if(schema_oid == InvalidOid) return InvalidOid;
105+
106+
return get_relname_relid(relname, schema_oid);
107+
}
108+
42109
PlannedStmt *sr_planner(Query *parse,
43110
int cursorOptions,
44111
ParamListInfo boundParams)
@@ -47,7 +114,6 @@ PlannedStmt *sr_planner(Query *parse,
47114
Jsonb *out_jsonb;
48115
Jsonb *out_jsonb2;
49116
int query_hash;
50-
RangeVar *sr_plans_table_rv;
51117
Relation sr_plans_heap;
52118
Relation query_index_rel;
53119
HeapTuple tuple;
@@ -58,19 +124,42 @@ PlannedStmt *sr_planner(Query *parse,
58124
Datum search_values[6];
59125
static bool search_nulls[6] = {false, false, false, false, false, false};
60126
bool find_ok = false;
61-
LOCKMODE heap_lock = AccessShareLock;
127+
LOCKMODE heap_lock = RowExclusiveLock; /* AccessShareLock; */
62128
Oid query_index_rel_oid;
63-
Oid sr_plans_oid;
129+
Oid sr_plans_oid;
130+
Oid schema_oid;
131+
char *schema_name;
64132
IndexScanDesc query_index_scan;
65133
ScanKeyData key;
134+
List *func_name_list;
66135

67-
if(sr_plan_write_mode)
68-
heap_lock = RowExclusiveLock;
136+
if(!sr_plan_write_mode)
137+
return standard_planner(parse, cursorOptions, boundParams);
138+
139+
schema_oid = get_sr_plan_schema();
140+
if(!OidIsValid(schema_oid))
141+
{
142+
/* Just call standard_planner() if schema doesn't exist. */
143+
return standard_planner(parse, cursorOptions, boundParams);
144+
}
145+
146+
if(sr_plan_fake_func)
147+
{
148+
HeapTuple ftup;
149+
ftup = SearchSysCache1(PROCOID, ObjectIdGetDatum(sr_plan_fake_func));
150+
if(!HeapTupleIsValid(ftup)) sr_plan_fake_func = 0;
151+
else ReleaseSysCache(ftup);
152+
}
69153

70154
if (!sr_plan_fake_func)
71155
{
72156
Oid args[1] = {ANYELEMENTOID};
73-
sr_plan_fake_func = LookupFuncName(list_make1(makeString("_p")), 1, args, true);
157+
158+
schema_name = get_namespace_name(schema_oid);
159+
func_name_list = list_make2(makeString(schema_name), makeString("_p"));
160+
sr_plan_fake_func = LookupFuncName(func_name_list, 1, args, true);
161+
list_free(func_name_list);
162+
pfree(schema_name);
74163
}
75164

76165

@@ -81,25 +170,21 @@ PlannedStmt *sr_planner(Query *parse,
81170
/* Make list with all _p functions and his position */
82171
sr_query_walker((Query *)parse, NULL);
83172

84-
sr_plans_table_rv = makeRangeVar("public", "sr_plans", -1);
85-
/* First check existance of "sr_plans" table */
86-
sr_plans_oid = RangeVarGetRelid(sr_plans_table_rv, heap_lock, true);
173+
sr_plans_oid = sr_get_relname_oid(schema_oid, SR_PLANS_TABLE_NAME);
174+
87175
if (!OidIsValid(sr_plans_oid))
88176
/* Just call standard_planner() if table doesn't exist. */
89177
return standard_planner(parse, cursorOptions, boundParams);
90178

91179
/* Table "sr_plans" exists */
92-
sr_plans_heap = heap_open(sr_plans_oid, NoLock);
180+
sr_plans_heap = heap_open(sr_plans_oid, heap_lock);
181+
182+
query_index_rel_oid = sr_get_relname_oid(schema_oid, SR_PLANS_TABLE_QUERY_INDEX_NAME);
93183

94-
#if PG_VERSION_NUM >= 90600
95-
query_index_rel_oid = DatumGetObjectId(DirectFunctionCall1(to_regclass, PointerGetDatum(cstring_to_text("sr_plans_query_hash_idx"))));
96-
#else
97-
query_index_rel_oid = DatumGetObjectId(DirectFunctionCall1(to_regclass, CStringGetDatum("sr_plans_query_hash_idx")));
98-
#endif
99184
if (query_index_rel_oid == InvalidOid)
100185
{
101186
heap_close(sr_plans_heap, heap_lock);
102-
elog(WARNING, "Not found sr_plans_query_hash_idx index");
187+
elog(WARNING, "Not found %s index", SR_PLANS_TABLE_QUERY_INDEX_NAME);
103188
return standard_planner(parse, cursorOptions, boundParams);
104189
}
105190

@@ -358,11 +443,11 @@ sr_plan_invalid_table(PG_FUNCTION_ARGS)
358443
FmgrInfo flinfo;
359444
ExprContext econtext;
360445
TupleTableSlot *slot = NULL;
361-
RangeVar *sr_plans_table_rv;
362446
Relation sr_plans_heap;
363447
Datum search_values[6];
364448
static bool search_nulls[6];
365449
static bool search_replaces[6];
450+
Oid sr_plans_oid;
366451
HeapScanDesc heapScan;
367452
Jsonb *jsonb;
368453
JsonbValue relation_key;
@@ -372,9 +457,13 @@ sr_plan_invalid_table(PG_FUNCTION_ARGS)
372457
if (!CALLED_AS_EVENT_TRIGGER(fcinfo)) /* internal error */
373458
elog(ERROR, "not fired by event trigger manager");
374459

375-
sr_plans_table_rv = makeRangeVar("public", "sr_plans", -1);
376-
sr_plans_heap = heap_openrv(sr_plans_table_rv, RowExclusiveLock);
377-
460+
sr_plans_oid = sr_get_relname_oid(InvalidOid, SR_PLANS_TABLE_NAME);
461+
if(sr_plans_oid == InvalidOid)
462+
{
463+
elog(ERROR, "Cannot find %s table", SR_PLANS_TABLE_NAME);
464+
}
465+
sr_plans_heap = heap_open(sr_plans_oid, RowExclusiveLock);
466+
378467
relation_key.type = jbvString;
379468
relation_key.val.string.len = strlen("relationOids");
380469
relation_key.val.string.val = "relationOids";

sr_plan.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,11 @@
3030
#include "utils/syscache.h"
3131
#include "funcapi.h"
3232

33+
#define SR_PLANS_TABLE_NAME "sr_plans"
34+
#define SR_PLANS_TABLE_QUERY_INDEX_NAME "sr_plans_query_hash_idx"
35+
3336
Jsonb *node_tree_to_jsonb(const void *obj, Oid fake_func, bool skip_location_from_node);
3437
void *jsonb_to_node_tree(Jsonb *json, void *(*hookPtr) (void *));
3538
void common_walker(const void *obj, void (*callback) (void *));
3639

37-
#endif
40+
#endif

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy