Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 506c578

Browse files
committed
Merge commit '0fe30cb22e5b082a54f9debcbf6c70c321c6458a' into PGPROEE9_6_ALPHA
Conflicts: contrib/sr_plan/sr_plan.c
2 parents 47c5b39 + 0fe30cb commit 506c578

File tree

5 files changed

+121
-25
lines changed

5 files changed

+121
-25
lines changed

contrib/sr_plan/expected/sr_plan.out

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
CREATE EXTENSION sr_plan;
2+
set client_min_messages = LOG;
23
CREATE TABLE test_table(test_attr1 int, test_attr2 int);
34
SET sr_plan.write_mode = true;
45
SELECT * FROM test_table WHERE test_attr1 = _p(10);
@@ -34,19 +35,19 @@ SELECT * FROM test_table WHERE test_attr1 = 15;
3435

3536
UPDATE sr_plans SET enable = true;
3637
SELECT * FROM test_table WHERE test_attr1 = _p(10);
37-
WARNING: Ok we find saved plan.
38+
LOG: Ok we find saved plan.
3839
test_attr1 | test_attr2
3940
------------+------------
4041
(0 rows)
4142

4243
SELECT * FROM test_table WHERE test_attr1 = _p(15);
43-
WARNING: Ok we find saved plan.
44+
LOG: Ok we find saved plan.
4445
test_attr1 | test_attr2
4546
------------+------------
4647
(0 rows)
4748

4849
SELECT * FROM test_table WHERE test_attr1 = 10;
49-
WARNING: Ok we find saved plan.
50+
LOG: Ok we find saved plan.
5051
test_attr1 | test_attr2
5152
------------+------------
5253
(0 rows)

contrib/sr_plan/sql/sr_plan.sql

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
CREATE EXTENSION sr_plan;
2+
set client_min_messages = LOG;
23

34
CREATE TABLE test_table(test_attr1 int, test_attr2 int);
45
SET sr_plan.write_mode = true;
@@ -24,4 +25,4 @@ CREATE TABLE test_table(test_attr1 int, test_attr2 int);
2425
SELECT * FROM test_table WHERE test_attr1 = _p(10);
2526
SELECT * FROM test_table WHERE test_attr1 = 10;
2627
SELECT * FROM test_table WHERE test_attr1 = 10;
27-
SELECT * FROM test_table WHERE test_attr1 = 15;
28+
SELECT * FROM test_table WHERE test_attr1 = 15;

contrib/sr_plan/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();

contrib/sr_plan/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(LOG, "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";

contrib/sr_plan/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)