Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit b093bb1

Browse files
committed
Keep order off assignments in GUC context handlers
1 parent 93becb4 commit b093bb1

File tree

1 file changed

+84
-51
lines changed

1 file changed

+84
-51
lines changed

multimaster.c

Lines changed: 84 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363
#include "parser/analyze.h"
6464
#include "parser/parse_relation.h"
6565
#include "tcop/pquery.h"
66+
#include "lib/ilist.h"
6667

6768
#include "multimaster.h"
6869
#include "ddd.h"
@@ -3588,67 +3589,109 @@ static bool MtmTwoPhaseCommit(MtmCurrentTrans* x)
35883589

35893590
// XXX: is it defined somewhere?
35903591
#define GUC_KEY_MAXLEN 255
3591-
35923592
#define MTM_GUC_HASHSIZE 20
35933593

3594-
typedef struct MtmGucHashEntry
3594+
typedef struct MtmGucEntry
35953595
{
35963596
char key[GUC_KEY_MAXLEN];
3597+
dlist_node list_node;
35973598
char *value;
3598-
} MtmGucHashEntry;
3599+
} MtmGucEntry;
35993600

36003601
static HTAB *MtmGucHash = NULL;
3601-
static List *MtmGucList = NULL;
3602+
static dlist_head MtmGucList = DLIST_STATIC_INIT(MtmGucList);
36023603

3603-
static void MtmGucHashInit(void)
3604+
static void MtmGucInit(void)
36043605
{
36053606
HASHCTL hash_ctl;
36063607

36073608
MemSet(&hash_ctl, 0, sizeof(hash_ctl));
36083609
hash_ctl.keysize = GUC_KEY_MAXLEN;
3609-
hash_ctl.entrysize = sizeof(MtmGucHashEntry);
3610+
hash_ctl.entrysize = sizeof(MtmGucEntry);
36103611
hash_ctl.hcxt = TopMemoryContext;
36113612
MtmGucHash = hash_create("MtmGucHash",
36123613
MTM_GUC_HASHSIZE,
36133614
&hash_ctl,
36143615
HASH_ELEM | HASH_CONTEXT);
36153616
}
36163617

3618+
static void MtmGucDiscard()
3619+
{
3620+
dlist_iter iter;
3621+
3622+
if (dlist_is_empty(&MtmGucList))
3623+
return;
3624+
3625+
dlist_foreach(iter, &MtmGucList)
3626+
{
3627+
MtmGucEntry *cur_entry = dlist_container(MtmGucEntry, list_node, iter.cur);
3628+
pfree(cur_entry->value);
3629+
}
3630+
dlist_init(&MtmGucList);
3631+
3632+
hash_destroy(MtmGucHash);
3633+
MtmGucInit();
3634+
}
3635+
3636+
static inline void MtmGucUpdate(const char *key, char *value)
3637+
{
3638+
MtmGucEntry *hentry;
3639+
bool found;
3640+
3641+
hentry = hash_search(MtmGucHash, key, HASH_FIND, &found);
3642+
if (found)
3643+
{
3644+
pfree(hentry->value);
3645+
dlist_delete(&hentry->list_node);
3646+
}
3647+
3648+
hentry = hash_search(MtmGucHash, key, HASH_ENTER, NULL);
3649+
hentry->value = value;
3650+
dlist_push_tail(&MtmGucList, &hentry->list_node);
3651+
}
3652+
3653+
static inline void MtmGucRemove(const char *key)
3654+
{
3655+
MtmGucEntry *hentry;
3656+
bool found;
3657+
3658+
hentry = hash_search(MtmGucHash, key, HASH_FIND, &found);
3659+
if (found)
3660+
{
3661+
pfree(hentry->value);
3662+
dlist_delete(&hentry->list_node);
3663+
hash_search(MtmGucHash, key, HASH_REMOVE, NULL);
3664+
}
3665+
}
3666+
36173667
static void MtmGucSet(VariableSetStmt *stmt, const char *queryStr)
36183668
{
36193669
MemoryContext oldcontext;
3620-
MtmGucHashEntry *hentry;
3621-
bool found;
36223670

36233671
if (!MtmGucHash)
3624-
MtmGucHashInit();
3672+
MtmGucInit();
36253673

36263674
oldcontext = MemoryContextSwitchTo(TopMemoryContext);
36273675

36283676
switch (stmt->kind)
36293677
{
36303678
case VAR_SET_VALUE:
3631-
hentry = (MtmGucHashEntry *) hash_search(MtmGucHash, stmt->name,
3632-
HASH_ENTER, &found);
3633-
if (found)
3634-
pfree(hentry->value);
3635-
hentry->value = ExtractSetVariableArgs(stmt);
3679+
MtmGucUpdate(stmt->name, ExtractSetVariableArgs(stmt));
36363680
break;
36373681

36383682
case VAR_SET_DEFAULT:
3639-
hash_search(MtmGucHash, stmt->name, HASH_REMOVE, NULL);
3683+
MtmGucRemove(stmt->name);
36403684
break;
36413685

36423686
case VAR_RESET:
36433687
if (strcmp(stmt->name, "session_authorization") == 0)
3644-
hash_search(MtmGucHash, "role", HASH_REMOVE, NULL);
3645-
hash_search(MtmGucHash, stmt->name, HASH_REMOVE, NULL);
3688+
MtmGucRemove("role");
3689+
MtmGucRemove(stmt->name);
36463690
break;
36473691

36483692
case VAR_RESET_ALL:
36493693
/* XXX: shouldn't we keep auth/role here? */
3650-
hash_destroy(MtmGucHash);
3651-
MtmGucHashInit();
3694+
MtmGucDiscard();
36523695
break;
36533696

36543697
case VAR_SET_CURRENT:
@@ -3659,46 +3702,36 @@ static void MtmGucSet(VariableSetStmt *stmt, const char *queryStr)
36593702
MemoryContextSwitchTo(oldcontext);
36603703
}
36613704

3662-
static void MtmGucDiscard(DiscardStmt *stmt)
3663-
{
3664-
if (stmt->target == DISCARD_ALL)
3665-
{
3666-
hash_destroy(MtmGucHash);
3667-
MtmGucHashInit();
3668-
}
3669-
}
3670-
36713705
static char * MtmGucSerialize(void)
36723706
{
3673-
HASH_SEQ_STATUS status;
3674-
MtmGucHashEntry *hentry;
36753707
StringInfo serialized_gucs;
3708+
dlist_iter iter;
3709+
int nvars = 0;
36763710

36773711
serialized_gucs = makeStringInfo();
36783712
appendStringInfoString(serialized_gucs, "RESET SESSION AUTHORIZATION; reset all; ");
36793713

3680-
if (MtmGucHash)
3714+
dlist_foreach(iter, &MtmGucList)
36813715
{
3682-
hash_seq_init(&status, MtmGucHash);
3683-
while ((hentry = (MtmGucHashEntry *) hash_seq_search(&status)) != NULL)
3684-
{
3685-
appendStringInfoString(serialized_gucs, "SET ");
3686-
appendStringInfoString(serialized_gucs, hentry->key);
3687-
appendStringInfoString(serialized_gucs, " TO ");
3716+
MtmGucEntry *cur_entry = dlist_container(MtmGucEntry, list_node, iter.cur);
36883717

3689-
/* quite a crutch */
3690-
if (strcmp(hentry->key, "work_mem") == 0)
3691-
{
3692-
appendStringInfoString(serialized_gucs, "'");
3693-
appendStringInfoString(serialized_gucs, hentry->value);
3694-
appendStringInfoString(serialized_gucs, "'");
3695-
}
3696-
else
3697-
{
3698-
appendStringInfoString(serialized_gucs, hentry->value);
3699-
}
3700-
appendStringInfoString(serialized_gucs, "; ");
3718+
appendStringInfoString(serialized_gucs, "SET ");
3719+
appendStringInfoString(serialized_gucs, cur_entry->key);
3720+
appendStringInfoString(serialized_gucs, " TO ");
3721+
3722+
/* quite a crutch */
3723+
if (strcmp(cur_entry->key, "work_mem") == 0)
3724+
{
3725+
appendStringInfoString(serialized_gucs, "'");
3726+
appendStringInfoString(serialized_gucs, cur_entry->value);
3727+
appendStringInfoString(serialized_gucs, "'");
37013728
}
3729+
else
3730+
{
3731+
appendStringInfoString(serialized_gucs, cur_entry->value);
3732+
}
3733+
appendStringInfoString(serialized_gucs, "; ");
3734+
nvars++;
37023735
}
37033736

37043737
return serialized_gucs->data;
@@ -3846,10 +3879,10 @@ static void MtmProcessUtility(Node *parsetree, const char *queryString,
38463879
{
38473880
DiscardStmt *stmt = (DiscardStmt *) parsetree;
38483881

3849-
if (!IsTransactionBlock())
3882+
if (!IsTransactionBlock() && stmt->target == DISCARD_ALL)
38503883
{
38513884
skipCommand = true;
3852-
MtmGucDiscard(stmt);
3885+
MtmGucDiscard();
38533886
}
38543887
}
38553888
break;

0 commit comments

Comments
 (0)