|
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"
|
@@ -2144,7 +2145,9 @@ static void
|
2144 | 2145 | MtmLockCluster(void)
|
2145 | 2146 | {
|
2146 | 2147 | timestamp_tdelay=MIN_WAIT_TIMEOUT;
|
2147 |
| -Assert(!MtmClusterLocked); |
| 2148 | +if (MtmClusterLocked) { |
| 2149 | +MtmUnlockCluster(); |
| 2150 | +} |
2148 | 2151 | MtmLock(LW_EXCLUSIVE);
|
2149 | 2152 | if (BIT_CHECK(Mtm->originLockNodeMask,MtmNodeId-1)) {
|
2150 | 2153 | elog(ERROR,"There is already pending exclusive lock");
|
@@ -4890,8 +4893,8 @@ static void MtmProcessUtility(Node *parsetree, const char *queryString,
|
4890 | 4893 | boolskipCommand= false;
|
4891 | 4894 | boolexecuted= false;
|
4892 | 4895 |
|
4893 |
| -MTM_LOG3("%d: Process utility statement tag=%d, context=%d, issubtrans=%d, query=%s", |
4894 |
| -MyProcPid,nodeTag(parsetree),context,IsSubTransaction(),queryString); |
| 4896 | +MTM_LOG2("%d: Process utility statement tag=%d, context=%d, issubtrans=%d, creating_extension=%d, query=%s", |
| 4897 | +MyProcPid,nodeTag(parsetree),context,IsSubTransaction(),creating_extension,queryString); |
4895 | 4898 | switch (nodeTag(parsetree))
|
4896 | 4899 | {
|
4897 | 4900 | caseT_TransactionStmt:
|
@@ -5144,24 +5147,14 @@ static void MtmProcessUtility(Node *parsetree, const char *queryString,
|
5144 | 5147 | break;
|
5145 | 5148 | }
|
5146 | 5149 |
|
5147 |
| -/* XXX: dirty. Clear on new tx */ |
5148 |
| -/* Some "black magic here":( We want to avoid redundant execution of utility statement by ProcessUtilitySlow (which is done with PROCESS_UTILITY_SUBCOMMAND). |
5149 |
| - * 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). |
5150 |
| - * If we disable only PROCESS_UTILITY_SUBCOMMAND, then we will get problems with "create extension" which is executed also in PROCESS_UTILITY_QUERY context. |
5151 |
| - * So workaround at this moment is to treat extension as special case. |
5152 |
| - * TODO: try to find right solution and rewrite this dummy check. |
5153 |
| - */ |
5154 |
| -if (!skipCommand&& (context==PROCESS_UTILITY_TOPLEVEL|| (context==PROCESS_UTILITY_QUERY&& !creating_extension)||MtmUtilityProcessedInXid!=GetCurrentTransactionId())) |
5155 |
| -MtmUtilityProcessedInXid=InvalidTransactionId; |
5156 |
| - |
5157 |
| -if (!skipCommand&& !MtmTx.isReplicated&& (MtmUtilityProcessedInXid==InvalidTransactionId)) { |
| 5150 | +if (!skipCommand&& !MtmTx.isReplicated&& (context==PROCESS_UTILITY_TOPLEVEL||MtmUtilityProcessedInXid!=GetCurrentTransactionId())) |
| 5151 | +{ |
5158 | 5152 | MtmUtilityProcessedInXid=GetCurrentTransactionId();
|
5159 |
| - |
5160 |
| -if (context==PROCESS_UTILITY_TOPLEVEL) |
| 5153 | +if (context==PROCESS_UTILITY_TOPLEVEL) { |
5161 | 5154 | MtmProcessDDLCommand(queryString, true);
|
5162 |
| -else |
| 5155 | +}else { |
5163 | 5156 | MtmProcessDDLCommand(ActivePortal->sourceText, true);
|
5164 |
| - |
| 5157 | +} |
5165 | 5158 | executed= true;
|
5166 | 5159 | }
|
5167 | 5160 |
|
@@ -5191,6 +5184,26 @@ static void MtmProcessUtility(Node *parsetree, const char *queryString,
|
5191 | 5184 | {
|
5192 | 5185 | MtmFinishDDLCommand();
|
5193 | 5186 | }
|
| 5187 | +if (nodeTag(parsetree)==T_CreateStmt) |
| 5188 | +{ |
| 5189 | +CreateStmt*create= (CreateStmt*)parsetree; |
| 5190 | +Oidrelid=RangeVarGetRelid(create->relation,NoLock, true); |
| 5191 | +if (relid!=InvalidOid) { |
| 5192 | +Oidconstraint_oid; |
| 5193 | +Bitmapset*pk=get_primary_key_attnos(relid, true,&constraint_oid); |
| 5194 | +if (pk==NULL&& !MtmVolksWagenMode) { |
| 5195 | +elog(WARNING, |
| 5196 | +MtmIgnoreTablesWithoutPk |
| 5197 | + ?"Table %s.%s without primary will not be replicated" |
| 5198 | + :"Updates and deletes of table %s.%s without primary will not be replicated", |
| 5199 | +create->relation->schemaname ?create->relation->schemaname :"public", |
| 5200 | +create->relation->relname); |
| 5201 | +} |
| 5202 | +} |
| 5203 | +} |
| 5204 | +if (context==PROCESS_UTILITY_TOPLEVEL) { |
| 5205 | +MtmUtilityProcessedInXid=InvalidTransactionId; |
| 5206 | +} |
5194 | 5207 | }
|
5195 | 5208 |
|
5196 | 5209 | staticvoid
|
|