|  | 
| 23 | 23 | PG_MODULE_MAGIC; | 
| 24 | 24 | 
 | 
| 25 | 25 | PG_FUNCTION_INFO_V1(do_nothing); | 
|  | 26 | +PG_FUNCTION_INFO_V1(show_plan); | 
| 26 | 27 | 
 | 
| 27 | 28 | void _PG_init(void); | 
| 28 | 29 | void _PG_fini(void); | 
| @@ -397,7 +398,9 @@ lookup_plan_by_query_hash(Snapshot snapshot, Relation sr_index_rel, | 
| 397 | 398 | 			char *out = TextDatumGetCString(DatumGetTextP((search_values[3]))); | 
| 398 | 399 | 			pl_stmt = stringToNode(out); | 
| 399 | 400 | 
 | 
| 400 |  | -			execute_for_plantree(pl_stmt, restore_params, context); | 
|  | 401 | +			if (context) | 
|  | 402 | +				execute_for_plantree(pl_stmt, restore_params, context); | 
|  | 403 | + | 
| 401 | 404 | 			break; | 
| 402 | 405 | 		} | 
| 403 | 406 | 	} | 
| @@ -864,6 +867,59 @@ do_nothing(PG_FUNCTION_ARGS) | 
| 864 | 867 | 	PG_RETURN_DATUM(PG_GETARG_DATUM(0)); | 
| 865 | 868 | } | 
| 866 | 869 | 
 | 
|  | 870 | +Datum | 
|  | 871 | +show_plan(PG_FUNCTION_ARGS) | 
|  | 872 | +{ | 
|  | 873 | +	PlannedStmt	   *pl_stmt = NULL; | 
|  | 874 | +	LOCKMODE		heap_lock =  AccessShareLock; | 
|  | 875 | +	Relation		sr_plans_heap, | 
|  | 876 | +					sr_index_rel; | 
|  | 877 | +	Snapshot		snapshot; | 
|  | 878 | +	ScanKeyData		key; | 
|  | 879 | + | 
|  | 880 | +	ExplainFormat	format = EXPLAIN_FORMAT_TEXT; | 
|  | 881 | +	ExplainState	state; | 
|  | 882 | +	uint32	index, | 
|  | 883 | +			query_hash = PG_GETARG_INT32(0); | 
|  | 884 | + | 
|  | 885 | +	if (!PG_ARGISNULL(1)) | 
|  | 886 | +		index = PG_GETARG_INT32(0); | 
|  | 887 | +	else | 
|  | 888 | +		index = 1; | 
|  | 889 | + | 
|  | 890 | +	if (!PG_ARGISNULL(2)) | 
|  | 891 | +	{ | 
|  | 892 | +		char	*ftext = PG_GETARG_CSTRING(2); | 
|  | 893 | + | 
|  | 894 | +		if (strcmp(ftext, "text") == 0) | 
|  | 895 | +			format = EXPLAIN_FORMAT_TEXT; | 
|  | 896 | +		else if (strcmp(ftext, "xml") == 0) | 
|  | 897 | +			format = EXPLAIN_FORMAT_XML; | 
|  | 898 | +		else if (strcmp(ftext, "json") == 0) | 
|  | 899 | +			format = EXPLAIN_FORMAT_JSON; | 
|  | 900 | +		else if (strcmp(ftext, "yaml") == 0) | 
|  | 901 | +			format = EXPLAIN_FORMAT_YAML; | 
|  | 902 | +		else | 
|  | 903 | +			elog(ERROR, "unknown format of EXPLAIN"); | 
|  | 904 | +	} | 
|  | 905 | +	state.format = format; | 
|  | 906 | + | 
|  | 907 | +	/* Try to find already planned statement */ | 
|  | 908 | +	sr_plans_heap = heap_open(cachedInfo.sr_plans_oid, heap_lock); | 
|  | 909 | +	sr_index_rel = index_open(cachedInfo.sr_index_oid, heap_lock); | 
|  | 910 | + | 
|  | 911 | +	snapshot = RegisterSnapshot(GetLatestSnapshot()); | 
|  | 912 | +	ScanKeyInit(&key, 1, BTEqualStrategyNumber, F_INT4EQ, query_hash); | 
|  | 913 | +	pl_stmt = lookup_plan_by_query_hash(snapshot, sr_index_rel, sr_plans_heap, | 
|  | 914 | +										&key, NULL); | 
|  | 915 | +	if (pl_stmt == NULL) | 
|  | 916 | +		elog(ERROR, "no saved plan on this query hash"); | 
|  | 917 | + | 
|  | 918 | +	UnregisterSnapshot(snapshot); | 
|  | 919 | +	index_close(sr_index_rel, heap_lock); | 
|  | 920 | +	heap_close(sr_plans_heap, heap_lock); | 
|  | 921 | +} | 
|  | 922 | + | 
| 867 | 923 | /* | 
| 868 | 924 |  * Basic plan tree walker. | 
| 869 | 925 |  * | 
|  | 
0 commit comments