|
| 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 | +staticplanner_hook_typeprev_planner_hook=NULL; |
| 18 | + |
| 19 | +staticPlannedStmt*HOOK_Planner_injection(Query*parse,intcursorOptions, |
| 20 | +ParamListInfoboundParams); |
| 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 | +staticPlannedStmt*HOOK_Planner_injection(Query*parse,intcursorOptions, |
| 34 | +ParamListInfoboundParams) |
| 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 | +returnstmt; |
| 58 | +} |
| 59 | + |
| 60 | +#include"executor/executor.h" |
| 61 | +#include"utils/plancache.h" |
| 62 | +#include"utils/snapmgr.h" |
| 63 | + |
| 64 | +staticvoid |
| 65 | +ScanQueryForLocks(PlannedStmt*pstmt,boolacquire) |
| 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 | +caseRTE_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 | +staticvoid |
| 97 | +AcquirePlannerLocks(PlannedStmt*pstmt,boolacquire) |
| 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 | +charqueryString[5]="NONE"; |
| 114 | +ParamListInfoparamLI=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 | + |