1
1
#include "sr_plan.h"
2
2
#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"
3
9
4
10
PG_MODULE_MAGIC ;
5
11
@@ -17,6 +23,8 @@ PlanCacheRelCallback(Datum arg, Oid relid);*/
17
23
void sr_analyze (ParseState * pstate ,
18
24
Query * query );
19
25
26
+ static Oid get_sr_plan_schema (void );
27
+ static Oid sr_get_relname_oid (Oid schema_oid , const char * relname );
20
28
bool sr_query_walker (Query * node , void * context );
21
29
bool sr_query_expr_walker (Node * node , void * context );
22
30
void * replace_fake (void * node );
@@ -39,6 +47,65 @@ void sr_analyze(ParseState *pstate, Query *query)
39
47
query_text = pstate -> p_sourcetext ;
40
48
}
41
49
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
+
42
109
PlannedStmt * sr_planner (Query * parse ,
43
110
int cursorOptions ,
44
111
ParamListInfo boundParams )
@@ -47,7 +114,6 @@ PlannedStmt *sr_planner(Query *parse,
47
114
Jsonb * out_jsonb ;
48
115
Jsonb * out_jsonb2 ;
49
116
int query_hash ;
50
- RangeVar * sr_plans_table_rv ;
51
117
Relation sr_plans_heap ;
52
118
Relation query_index_rel ;
53
119
HeapTuple tuple ;
@@ -58,19 +124,42 @@ PlannedStmt *sr_planner(Query *parse,
58
124
Datum search_values [6 ];
59
125
static bool search_nulls [6 ] = {false, false, false, false, false, false};
60
126
bool find_ok = false;
61
- LOCKMODE heap_lock = AccessShareLock ;
127
+ LOCKMODE heap_lock = AccessShareLock ;
62
128
Oid query_index_rel_oid ;
63
- Oid sr_plans_oid ;
129
+ Oid sr_plans_oid ;
130
+ Oid schema_oid ;
131
+ char * schema_name ;
64
132
IndexScanDesc query_index_scan ;
65
133
ScanKeyData key ;
134
+ List * func_name_list ;
66
135
67
- if (sr_plan_write_mode )
136
+ if (sr_plan_write_mode )
68
137
heap_lock = RowExclusiveLock ;
69
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
+ }
153
+
70
154
if (!sr_plan_fake_func )
71
155
{
72
156
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 );
74
163
}
75
164
76
165
@@ -81,21 +170,21 @@ PlannedStmt *sr_planner(Query *parse,
81
170
/* Make list with all _p functions and his position */
82
171
sr_query_walker ((Query * )parse , NULL );
83
172
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
+
87
175
if (!OidIsValid (sr_plans_oid ))
88
176
/* Just call standard_planner() if table doesn't exist. */
89
177
return standard_planner (parse , cursorOptions , boundParams );
90
178
91
179
/* 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 );
93
183
94
- query_index_rel_oid = DatumGetObjectId (DirectFunctionCall1 (to_regclass , PointerGetDatum (cstring_to_text ("sr_plans_query_hash_idx" ))));
95
184
if (query_index_rel_oid == InvalidOid )
96
185
{
97
186
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 );
99
188
return standard_planner (parse , cursorOptions , boundParams );
100
189
}
101
190
@@ -121,8 +210,7 @@ PlannedStmt *sr_planner(Query *parse,
121
210
HeapTuple local_tuple ;
122
211
local_tuple = index_getnext (query_index_scan , ForwardScanDirection );
123
212
124
- if (local_tuple == NULL )
125
- break ;
213
+ if (local_tuple == NULL ) break ;
126
214
127
215
heap_deform_tuple (local_tuple , sr_plans_heap -> rd_att ,
128
216
search_values , search_nulls );
@@ -138,7 +226,7 @@ PlannedStmt *sr_planner(Query *parse,
138
226
139
227
if (find_ok )
140
228
{
141
- elog (WARNING , "Ok we find saved plan." );
229
+ /* elog(WARNING, "Ok we find saved plan."); */
142
230
out_jsonb2 = (Jsonb * )DatumGetPointer (PG_DETOAST_DATUM (search_values [3 ]));
143
231
if (query_params != NULL )
144
232
pl_stmt = jsonb_to_node_tree (out_jsonb2 , & replace_fake );
@@ -354,11 +442,11 @@ sr_plan_invalid_table(PG_FUNCTION_ARGS)
354
442
FmgrInfo flinfo ;
355
443
ExprContext econtext ;
356
444
TupleTableSlot * slot = NULL ;
357
- RangeVar * sr_plans_table_rv ;
358
445
Relation sr_plans_heap ;
359
446
Datum search_values [6 ];
360
447
static bool search_nulls [6 ];
361
448
static bool search_replaces [6 ];
449
+ Oid sr_plans_oid ;
362
450
HeapScanDesc heapScan ;
363
451
Jsonb * jsonb ;
364
452
JsonbValue relation_key ;
@@ -368,9 +456,13 @@ sr_plan_invalid_table(PG_FUNCTION_ARGS)
368
456
if (!CALLED_AS_EVENT_TRIGGER (fcinfo )) /* internal error */
369
457
elog (ERROR , "not fired by event trigger manager" );
370
458
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
+
374
466
relation_key .type = jbvString ;
375
467
relation_key .val .string .len = strlen ("relationOids" );
376
468
relation_key .val .string .val = "relationOids" ;
0 commit comments