Skip to content

Commit ddc0cc7

Browse files
author
Vladimir Ershov
committed
Merge branch 'master' into PGPRO9_6
2 parents 8205886 + 0d17974 commit ddc0cc7

File tree

4 files changed

+115
-24
lines changed

4 files changed

+115
-24
lines changed

expected/sr_plan.out

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,19 +34,16 @@ SELECT * FROM test_table WHERE test_attr1 = 15;
3434

3535
UPDATE sr_plans SET enable = true;
3636
SELECT * FROM test_table WHERE test_attr1 = _p(10);
37-
WARNING: Ok we find saved plan.
3837
test_attr1 | test_attr2
3938
------------+------------
4039
(0 rows)
4140

4241
SELECT * FROM test_table WHERE test_attr1 = _p(15);
43-
WARNING: Ok we find saved plan.
4442
test_attr1 | test_attr2
4543
------------+------------
4644
(0 rows)
4745

4846
SELECT * FROM test_table WHERE test_attr1 = 10;
49-
WARNING: Ok we find saved plan.
5047
test_attr1 | test_attr2
5148
------------+------------
5249
(0 rows)

sr_plan--1.0.sql

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ CREATE TABLE sr_plans (
1414

1515
CREATE INDEX sr_plans_query_hash_idx ON sr_plans (query_hash);
1616
--CREATE INDEX sr_plans_plan_hash_idx ON sr_plans (plan_hashs);
17-
--create function _p(anyelement) returns anyelement as $$ select $1; $$ language sql VOLATILE;
1817

1918
CREATE FUNCTION _p(anyelement)
2019
RETURNS anyelement
@@ -32,4 +31,4 @@ CREATE FUNCTION sr_plan_invalid_table() RETURNS event_trigger
3231

3332
CREATE EVENT TRIGGER sr_plan_invalid_table ON sql_drop
3433
-- WHEN TAG IN ('DROP TABLE')
35-
EXECUTE PROCEDURE sr_plan_invalid_table();
34+
EXECUTE PROCEDURE sr_plan_invalid_table();

sr_plan.c

Lines changed: 110 additions & 18 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 = 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)
136+
if(sr_plan_write_mode)
68137
heap_lock = RowExclusiveLock;
69138

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+
}
153+
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,21 +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-
query_index_rel_oid = DatumGetObjectId(DirectFunctionCall1(to_regclass, PointerGetDatum(cstring_to_text("sr_plans_query_hash_idx"))));
95184
if (query_index_rel_oid == InvalidOid)
96185
{
97186
heap_close(sr_plans_heap, heap_lock);
98-
elog(WARNING, "Not found sr_plans_query_hash_idx index");
187+
elog(WARNING, "Not found %s index", SR_PLANS_TABLE_QUERY_INDEX_NAME);
99188
return standard_planner(parse, cursorOptions, boundParams);
100189
}
101190

@@ -121,8 +210,7 @@ PlannedStmt *sr_planner(Query *parse,
121210
HeapTuple local_tuple;
122211
local_tuple = index_getnext(query_index_scan, ForwardScanDirection);
123212

124-
if (local_tuple == NULL)
125-
break;
213+
if (local_tuple == NULL) break;
126214

127215
heap_deform_tuple(local_tuple, sr_plans_heap->rd_att,
128216
search_values, search_nulls);
@@ -138,7 +226,7 @@ PlannedStmt *sr_planner(Query *parse,
138226

139227
if (find_ok)
140228
{
141-
elog(WARNING, "Ok we find saved plan.");
229+
/* elog(WARNING, "Ok we find saved plan."); */
142230
out_jsonb2 = (Jsonb *)DatumGetPointer(PG_DETOAST_DATUM(search_values[3]));
143231
if (query_params != NULL)
144232
pl_stmt = jsonb_to_node_tree(out_jsonb2, &replace_fake);
@@ -354,11 +442,11 @@ sr_plan_invalid_table(PG_FUNCTION_ARGS)
354442
FmgrInfo flinfo;
355443
ExprContext econtext;
356444
TupleTableSlot *slot = NULL;
357-
RangeVar *sr_plans_table_rv;
358445
Relation sr_plans_heap;
359446
Datum search_values[6];
360447
static bool search_nulls[6];
361448
static bool search_replaces[6];
449+
Oid sr_plans_oid;
362450
HeapScanDesc heapScan;
363451
Jsonb *jsonb;
364452
JsonbValue relation_key;
@@ -368,9 +456,13 @@ sr_plan_invalid_table(PG_FUNCTION_ARGS)
368456
if (!CALLED_AS_EVENT_TRIGGER(fcinfo)) /* internal error */
369457
elog(ERROR, "not fired by event trigger manager");
370458

371-
sr_plans_table_rv = makeRangeVar("public", "sr_plans", -1);
372-
sr_plans_heap = heap_openrv(sr_plans_table_rv, RowExclusiveLock);
373-
459+
sr_plans_oid = sr_get_relname_oid(InvalidOid, SR_PLANS_TABLE_NAME);
460+
if(sr_plans_oid == InvalidOid)
461+
{
462+
elog(ERROR, "Cannot find %s table", SR_PLANS_TABLE_NAME);
463+
}
464+
sr_plans_heap = heap_open(sr_plans_oid, RowExclusiveLock);
465+
374466
relation_key.type = jbvString;
375467
relation_key.val.string.len = strlen("relationOids");
376468
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