63
63
#include "parser/analyze.h"
64
64
#include "parser/parse_relation.h"
65
65
#include "tcop/pquery.h"
66
+ #include "lib/ilist.h"
66
67
67
68
#include "multimaster.h"
68
69
#include "ddd.h"
@@ -3588,67 +3589,109 @@ static bool MtmTwoPhaseCommit(MtmCurrentTrans* x)
3588
3589
3589
3590
// XXX: is it defined somewhere?
3590
3591
#define GUC_KEY_MAXLEN 255
3591
-
3592
3592
#define MTM_GUC_HASHSIZE 20
3593
3593
3594
- typedef struct MtmGucHashEntry
3594
+ typedef struct MtmGucEntry
3595
3595
{
3596
3596
char key [GUC_KEY_MAXLEN ];
3597
+ dlist_node list_node ;
3597
3598
char * value ;
3598
- } MtmGucHashEntry ;
3599
+ } MtmGucEntry ;
3599
3600
3600
3601
static HTAB * MtmGucHash = NULL ;
3601
- static List * MtmGucList = NULL ;
3602
+ static dlist_head MtmGucList = DLIST_STATIC_INIT ( MtmGucList ) ;
3602
3603
3603
- static void MtmGucHashInit (void )
3604
+ static void MtmGucInit (void )
3604
3605
{
3605
3606
HASHCTL hash_ctl ;
3606
3607
3607
3608
MemSet (& hash_ctl , 0 , sizeof (hash_ctl ));
3608
3609
hash_ctl .keysize = GUC_KEY_MAXLEN ;
3609
- hash_ctl .entrysize = sizeof (MtmGucHashEntry );
3610
+ hash_ctl .entrysize = sizeof (MtmGucEntry );
3610
3611
hash_ctl .hcxt = TopMemoryContext ;
3611
3612
MtmGucHash = hash_create ("MtmGucHash" ,
3612
3613
MTM_GUC_HASHSIZE ,
3613
3614
& hash_ctl ,
3614
3615
HASH_ELEM | HASH_CONTEXT );
3615
3616
}
3616
3617
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
+
3617
3667
static void MtmGucSet (VariableSetStmt * stmt , const char * queryStr )
3618
3668
{
3619
3669
MemoryContext oldcontext ;
3620
- MtmGucHashEntry * hentry ;
3621
- bool found ;
3622
3670
3623
3671
if (!MtmGucHash )
3624
- MtmGucHashInit ();
3672
+ MtmGucInit ();
3625
3673
3626
3674
oldcontext = MemoryContextSwitchTo (TopMemoryContext );
3627
3675
3628
3676
switch (stmt -> kind )
3629
3677
{
3630
3678
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 ));
3636
3680
break ;
3637
3681
3638
3682
case VAR_SET_DEFAULT :
3639
- hash_search ( MtmGucHash , stmt -> name , HASH_REMOVE , NULL );
3683
+ MtmGucRemove ( stmt -> name );
3640
3684
break ;
3641
3685
3642
3686
case VAR_RESET :
3643
3687
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 );
3646
3690
break ;
3647
3691
3648
3692
case VAR_RESET_ALL :
3649
3693
/* XXX: shouldn't we keep auth/role here? */
3650
- hash_destroy (MtmGucHash );
3651
- MtmGucHashInit ();
3694
+ MtmGucDiscard ();
3652
3695
break ;
3653
3696
3654
3697
case VAR_SET_CURRENT :
@@ -3659,46 +3702,36 @@ static void MtmGucSet(VariableSetStmt *stmt, const char *queryStr)
3659
3702
MemoryContextSwitchTo (oldcontext );
3660
3703
}
3661
3704
3662
- static void MtmGucDiscard (DiscardStmt * stmt )
3663
- {
3664
- if (stmt -> target == DISCARD_ALL )
3665
- {
3666
- hash_destroy (MtmGucHash );
3667
- MtmGucHashInit ();
3668
- }
3669
- }
3670
-
3671
3705
static char * MtmGucSerialize (void )
3672
3706
{
3673
- HASH_SEQ_STATUS status ;
3674
- MtmGucHashEntry * hentry ;
3675
3707
StringInfo serialized_gucs ;
3708
+ dlist_iter iter ;
3709
+ int nvars = 0 ;
3676
3710
3677
3711
serialized_gucs = makeStringInfo ();
3678
3712
appendStringInfoString (serialized_gucs , "RESET SESSION AUTHORIZATION; reset all; " );
3679
3713
3680
- if ( MtmGucHash )
3714
+ dlist_foreach ( iter , & MtmGucList )
3681
3715
{
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 );
3688
3717
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 , "'" );
3701
3728
}
3729
+ else
3730
+ {
3731
+ appendStringInfoString (serialized_gucs , cur_entry -> value );
3732
+ }
3733
+ appendStringInfoString (serialized_gucs , "; " );
3734
+ nvars ++ ;
3702
3735
}
3703
3736
3704
3737
return serialized_gucs -> data ;
@@ -3846,10 +3879,10 @@ static void MtmProcessUtility(Node *parsetree, const char *queryString,
3846
3879
{
3847
3880
DiscardStmt * stmt = (DiscardStmt * ) parsetree ;
3848
3881
3849
- if (!IsTransactionBlock ())
3882
+ if (!IsTransactionBlock () && stmt -> target == DISCARD_ALL )
3850
3883
{
3851
3884
skipCommand = true;
3852
- MtmGucDiscard (stmt );
3885
+ MtmGucDiscard ();
3853
3886
}
3854
3887
}
3855
3888
break ;
0 commit comments