|
62 | 62 | #include"access/htup_details.h"
|
63 | 63 | #include"catalog/indexing.h"
|
64 | 64 | #include"catalog/namespace.h"
|
| 65 | +#include"catalog/pg_constraint_fn.h" |
65 | 66 | #include"pglogical_output/hooks.h"
|
66 | 67 | #include"parser/analyze.h"
|
67 | 68 | #include"parser/parse_relation.h"
|
@@ -2143,7 +2144,9 @@ static void
|
2143 | 2144 | MtmLockCluster(void)
|
2144 | 2145 | {
|
2145 | 2146 | timestamp_tdelay=MIN_WAIT_TIMEOUT;
|
2146 |
| -Assert(!MtmClusterLocked); |
| 2147 | +if (MtmClusterLocked) { |
| 2148 | +MtmUnlockCluster(); |
| 2149 | +} |
2147 | 2150 | MtmLock(LW_EXCLUSIVE);
|
2148 | 2151 | if (BIT_CHECK(Mtm->originLockNodeMask,MtmNodeId-1)) {
|
2149 | 2152 | elog(ERROR,"There is already pending exclusive lock");
|
@@ -4876,8 +4879,8 @@ static void MtmProcessUtility(Node *parsetree, const char *queryString,
|
4876 | 4879 | boolskipCommand= false;
|
4877 | 4880 | boolexecuted= false;
|
4878 | 4881 |
|
4879 |
| -MTM_LOG3("%d: Process utility statement tag=%d, context=%d, issubtrans=%d, query=%s", |
4880 |
| -MyProcPid,nodeTag(parsetree),context,IsSubTransaction(),queryString); |
| 4882 | +MTM_LOG2("%d: Process utility statement tag=%d, context=%d, issubtrans=%d, creating_extension=%d, query=%s", |
| 4883 | +MyProcPid,nodeTag(parsetree),context,IsSubTransaction(),creating_extension,queryString); |
4881 | 4884 | switch (nodeTag(parsetree))
|
4882 | 4885 | {
|
4883 | 4886 | caseT_TransactionStmt:
|
@@ -5130,24 +5133,14 @@ static void MtmProcessUtility(Node *parsetree, const char *queryString,
|
5130 | 5133 | break;
|
5131 | 5134 | }
|
5132 | 5135 |
|
5133 |
| -/* XXX: dirty. Clear on new tx */ |
5134 |
| -/* Some "black magic here":( We want to avoid redundant execution of utility statement by ProcessUtilitySlow (which is done with PROCESS_UTILITY_SUBCOMMAND). |
5135 |
| - * But if we allow only PROCESS_UTILITY_TOPLEVEL context, then we will not replicated DDL inside dynamic queries in plpgsql functions (see https://jira.postgrespro.ru/browse/CORE-526). |
5136 |
| - * If we disable only PROCESS_UTILITY_SUBCOMMAND, then we will get problems with "create extension" which is executed also in PROCESS_UTILITY_QUERY context. |
5137 |
| - * So workaround at this moment is to treat extension as special case. |
5138 |
| - * TODO: try to find right solution and rewrite this dummy check. |
5139 |
| - */ |
5140 |
| -if (!skipCommand&& (context==PROCESS_UTILITY_TOPLEVEL|| (context==PROCESS_UTILITY_QUERY&& !creating_extension)||MtmUtilityProcessedInXid!=GetCurrentTransactionId())) |
5141 |
| -MtmUtilityProcessedInXid=InvalidTransactionId; |
5142 |
| - |
5143 |
| -if (!skipCommand&& !MtmTx.isReplicated&& (MtmUtilityProcessedInXid==InvalidTransactionId)) { |
| 5136 | +if (!skipCommand&& !MtmTx.isReplicated&& (context==PROCESS_UTILITY_TOPLEVEL||MtmUtilityProcessedInXid!=GetCurrentTransactionId())) |
| 5137 | +{ |
5144 | 5138 | MtmUtilityProcessedInXid=GetCurrentTransactionId();
|
5145 |
| - |
5146 |
| -if (context==PROCESS_UTILITY_TOPLEVEL) |
| 5139 | +if (context==PROCESS_UTILITY_TOPLEVEL) { |
5147 | 5140 | MtmProcessDDLCommand(queryString, true);
|
5148 |
| -else |
| 5141 | +}else { |
5149 | 5142 | MtmProcessDDLCommand(ActivePortal->sourceText, true);
|
5150 |
| - |
| 5143 | +} |
5151 | 5144 | executed= true;
|
5152 | 5145 | }
|
5153 | 5146 |
|
@@ -5177,6 +5170,26 @@ static void MtmProcessUtility(Node *parsetree, const char *queryString,
|
5177 | 5170 | {
|
5178 | 5171 | MtmFinishDDLCommand();
|
5179 | 5172 | }
|
| 5173 | +if (nodeTag(parsetree)==T_CreateStmt) |
| 5174 | +{ |
| 5175 | +CreateStmt*create= (CreateStmt*)parsetree; |
| 5176 | +Oidrelid=RangeVarGetRelid(create->relation,NoLock, true); |
| 5177 | +if (relid!=InvalidOid) { |
| 5178 | +Oidconstraint_oid; |
| 5179 | +Bitmapset*pk=get_primary_key_attnos(relid, true,&constraint_oid); |
| 5180 | +if (pk==NULL&& !MtmVolksWagenMode) { |
| 5181 | +elog(WARNING, |
| 5182 | +MtmIgnoreTablesWithoutPk |
| 5183 | + ?"Table %s.%s without primary will not be replicated" |
| 5184 | + :"Updates and deletes of table %s.%s without primary will not be replicated", |
| 5185 | +create->relation->schemaname ?create->relation->schemaname :"public", |
| 5186 | +create->relation->relname); |
| 5187 | +} |
| 5188 | +} |
| 5189 | +} |
| 5190 | +if (context==PROCESS_UTILITY_TOPLEVEL) { |
| 5191 | +MtmUtilityProcessedInXid=InvalidTransactionId; |
| 5192 | +} |
5180 | 5193 | }
|
5181 | 5194 |
|
5182 | 5195 | staticvoid
|
|