Skip to content

Commit 6ac5290

Browse files
committed
Simple plans are launched
1 parent 540335e commit 6ac5290

File tree

5 files changed

+186
-21
lines changed

5 files changed

+186
-21
lines changed

LICENSE

Lines changed: 7 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,11 @@
1-
BSD 2-Clause License
1+
ExecPlan is released under the PostgreSQL License, a liberal Open Source license, similar to the BSD or MIT licenses.
22

3-
Copyright (c) 2018, Andrey Lepikhov
4-
All rights reserved.
3+
Copyright (c) 2018-2019, Postgres Professional
4+
Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group
5+
Portions Copyright (c) 1994, The Regents of the University of California
56

6-
Redistribution and use in source and binary forms, with or without
7-
modification, are permitted provided that the following conditions are met:
7+
Permission to use, copy, modify, and distribute this software and its documentation for any purpose, without fee, and without a written agreement is hereby granted, provided that the above copyright notice and this paragraph and the following two paragraphs appear in all copies.
88

9-
* Redistributions of source code must retain the above copyright notice, this
10-
list of conditions and the following disclaimer.
9+
IN NO EVENT SHALL POSTGRES PROFESSIONAL BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF POSTGRES PROFESSIONAL HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1110

12-
* Redistributions in binary form must reproduce the above copyright notice,
13-
this list of conditions and the following disclaimer in the documentation
14-
and/or other materials provided with the distribution.
15-
16-
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17-
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18-
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19-
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
20-
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21-
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22-
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23-
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24-
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25-
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
11+
POSTGRES PROFESSIONAL SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND POSTGRES PROFESSIONAL HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.

Makefile

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# contrib/execplan/Makefile
2+
3+
MODULE_big = execplan
4+
EXTENSION = execplan
5+
EXTVERSION = 0.1
6+
PGFILEDESC = "ExecPlan"
7+
MODULES = execplan
8+
OBJS = exec_plan.o $(WIN32RES)
9+
10+
PG_CPPFLAGS = -I$(libpq_srcdir)
11+
SHLIB_LINK_INTERNAL = $(libpq)
12+
13+
DATA_built = $(EXTENSION)--$(EXTVERSION).sql
14+
15+
ifdef USE_PGXS
16+
PG_CONFIG = pg_config
17+
PGXS := $(shell $(PG_CONFIG) --pgxs)
18+
include $(PGXS)
19+
else
20+
SHLIB_PREREQS = submake-libpq
21+
subdir = contrib/pargres
22+
top_builddir = ../..
23+
include $(top_builddir)/src/Makefile.global
24+
include $(top_srcdir)/contrib/contrib-global.mk
25+
endif
26+
27+
$(EXTENSION)--$(EXTVERSION).sql: init.sql
28+
cat $^ > $@

exec_plan.c

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
2+
#include "postgres.h"
3+
4+
#include "commands/extension.h"
5+
#include "executor/execdesc.h"
6+
#include "fmgr.h"
7+
#include "optimizer/planner.h"
8+
#include "storage/lmgr.h"
9+
#include "utils/builtins.h"
10+
11+
PG_MODULE_MAGIC;
12+
13+
PG_FUNCTION_INFO_V1(pg_execute_plan);
14+
15+
void _PG_init(void);
16+
17+
static planner_hook_type prev_planner_hook = NULL;
18+
19+
static PlannedStmt *HOOK_Planner_injection(Query *parse, int cursorOptions,
20+
ParamListInfo boundParams);
21+
22+
/*
23+
* Module load/unload callback
24+
*/
25+
void
26+
_PG_init(void)
27+
{
28+
/* Planner hook */
29+
prev_planner_hook = planner_hook;
30+
planner_hook = HOOK_Planner_injection;
31+
}
32+
33+
static PlannedStmt *HOOK_Planner_injection(Query *parse, int cursorOptions,
34+
ParamListInfo boundParams)
35+
{
36+
PlannedStmt *stmt;
37+
char *serialized_plan;
38+
39+
if (prev_planner_hook)
40+
stmt = prev_planner_hook(parse, cursorOptions, boundParams);
41+
else
42+
stmt = standard_planner(parse, cursorOptions, boundParams);
43+
44+
/* Extension is not initialized. */
45+
if (OidIsValid(get_extension_oid("execplan", true)))
46+
{
47+
FILE *f = fopen("/home/andrey/plans.txt", "at");
48+
if (stmt->paramExecTypes == NIL)
49+
{
50+
elog(LOG, "commandType: %d\n", stmt->commandType);
51+
}
52+
//Assert(stmt->paramExecTypes != NIL);
53+
serialized_plan = nodeToString(stmt);
54+
// fprintf(f, "\n%s\n", serialized_plan);
55+
fclose(f);
56+
}
57+
return stmt;
58+
}
59+
60+
#include "executor/executor.h"
61+
#include "utils/plancache.h"
62+
#include "utils/snapmgr.h"
63+
64+
static void
65+
ScanQueryForLocks(PlannedStmt *pstmt, bool acquire)
66+
{
67+
ListCell *lc;
68+
69+
/* Shouldn't get called on utility commands */
70+
Assert(pstmt->commandType != CMD_UTILITY);
71+
72+
/*
73+
* First, process RTEs of the current query level.
74+
*/
75+
foreach(lc, pstmt->rtable)
76+
{
77+
RangeTblEntry *rte = (RangeTblEntry *) lfirst(lc);
78+
79+
switch (rte->rtekind)
80+
{
81+
case RTE_RELATION:
82+
/* Acquire or release the appropriate type of lock */
83+
if (acquire)
84+
LockRelationOid(rte->relid, rte->rellockmode);
85+
else
86+
UnlockRelationOid(rte->relid, rte->rellockmode);
87+
break;
88+
89+
default:
90+
/* ignore other types of RTEs */
91+
break;
92+
}
93+
}
94+
95+
}
96+
static void
97+
AcquirePlannerLocks(PlannedStmt *pstmt, bool acquire)
98+
{
99+
if (pstmt->commandType == CMD_UTILITY)
100+
{
101+
/* Ignore utility statements, unless they contain a Query */
102+
}
103+
104+
ScanQueryForLocks(pstmt, acquire);
105+
}
106+
107+
Datum
108+
pg_execute_plan(PG_FUNCTION_ARGS)
109+
{
110+
char *data = TextDatumGetCString(PG_GETARG_DATUM(0));
111+
PlannedStmt *pstmt;
112+
QueryDesc *queryDesc;
113+
char queryString[5] = "NONE";
114+
ParamListInfo paramLI = NULL;
115+
116+
elog(INFO, "MESSAGE: %s", data);
117+
118+
/* Execute query plan. Based on execParallel.c ParallelQueryMain() */
119+
pstmt = (PlannedStmt *) stringToNode(data);
120+
// pstmt->paramExecTypes = NIL;
121+
queryDesc = CreateQueryDesc(pstmt, queryString, GetActiveSnapshot(),
122+
InvalidSnapshot, None_Receiver, paramLI, NULL,
123+
0);
124+
AcquirePlannerLocks(pstmt, true);
125+
126+
ExecutorStart(queryDesc, 0);
127+
128+
ExecutorRun(queryDesc, ForwardScanDirection, 0, true);
129+
130+
/* Shut down the executor */
131+
ExecutorFinish(queryDesc);
132+
ExecutorEnd(queryDesc);
133+
FreeQueryDesc(queryDesc);
134+
135+
PG_RETURN_BOOL(true);
136+
}
137+

execplan.control

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Pargres extension
2+
comment = 'Execute raw query plan'
3+
default_version = '0.1'
4+
module_pathname = '$libdir/execplan'
5+
relocatable = false

init.sql

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
\echo Use "CREATE EXTENSION execplan" to load this file. \quit
2+
3+
--
4+
-- Function ExecutePlan execute 'raw' query plan and ignore it's results.
5+
--
6+
CREATE OR REPLACE FUNCTION @extschema@.pg_execute_plan(plan TEXT)
7+
RETURNS BOOL
8+
AS 'MODULE_PATHNAME', 'pg_execute_plan'
9+
LANGUAGE C STRICT;

0 commit comments

Comments
 (0)