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"
@@ -3589,67 +3590,109 @@ static bool MtmTwoPhaseCommit(MtmCurrentTrans* x)
3589
3590
3590
3591
// XXX: is it defined somewhere?
3591
3592
#define GUC_KEY_MAXLEN 255
3592
-
3593
3593
#define MTM_GUC_HASHSIZE 20
3594
3594
3595
- typedef struct MtmGucHashEntry
3595
+ typedef struct MtmGucEntry
3596
3596
{
3597
3597
char key [GUC_KEY_MAXLEN ];
3598
+ dlist_node list_node ;
3598
3599
char * value ;
3599
- } MtmGucHashEntry ;
3600
+ } MtmGucEntry ;
3600
3601
3601
3602
static HTAB * MtmGucHash = NULL ;
3602
- static List * MtmGucList = NULL ;
3603
+ static dlist_head MtmGucList = DLIST_STATIC_INIT ( MtmGucList ) ;
3603
3604
3604
- static void MtmGucHashInit (void )
3605
+ static void MtmGucInit (void )
3605
3606
{
3606
3607
HASHCTL hash_ctl ;
3607
3608
3608
3609
MemSet (& hash_ctl , 0 , sizeof (hash_ctl ));
3609
3610
hash_ctl .keysize = GUC_KEY_MAXLEN ;
3610
- hash_ctl .entrysize = sizeof (MtmGucHashEntry );
3611
+ hash_ctl .entrysize = sizeof (MtmGucEntry );
3611
3612
hash_ctl .hcxt = TopMemoryContext ;
3612
3613
MtmGucHash = hash_create ("MtmGucHash" ,
3613
3614
MTM_GUC_HASHSIZE ,
3614
3615
& hash_ctl ,
3615
3616
HASH_ELEM | HASH_CONTEXT );
3616
3617
}
3617
3618
3619
+ static void MtmGucDiscard ()
3620
+ {
3621
+ dlist_iter iter ;
3622
+
3623
+ if (dlist_is_empty (& MtmGucList ))
3624
+ return ;
3625
+
3626
+ dlist_foreach (iter , & MtmGucList )
3627
+ {
3628
+ MtmGucEntry * cur_entry = dlist_container (MtmGucEntry , list_node , iter .cur );
3629
+ pfree (cur_entry -> value );
3630
+ }
3631
+ dlist_init (& MtmGucList );
3632
+
3633
+ hash_destroy (MtmGucHash );
3634
+ MtmGucInit ();
3635
+ }
3636
+
3637
+ static inline void MtmGucUpdate (const char * key , char * value )
3638
+ {
3639
+ MtmGucEntry * hentry ;
3640
+ bool found ;
3641
+
3642
+ hentry = hash_search (MtmGucHash , key , HASH_FIND , & found );
3643
+ if (found )
3644
+ {
3645
+ pfree (hentry -> value );
3646
+ dlist_delete (& hentry -> list_node );
3647
+ }
3648
+
3649
+ hentry = hash_search (MtmGucHash , key , HASH_ENTER , NULL );
3650
+ hentry -> value = value ;
3651
+ dlist_push_tail (& MtmGucList , & hentry -> list_node );
3652
+ }
3653
+
3654
+ static inline void MtmGucRemove (const char * key )
3655
+ {
3656
+ MtmGucEntry * hentry ;
3657
+ bool found ;
3658
+
3659
+ hentry = hash_search (MtmGucHash , key , HASH_FIND , & found );
3660
+ if (found )
3661
+ {
3662
+ pfree (hentry -> value );
3663
+ dlist_delete (& hentry -> list_node );
3664
+ hash_search (MtmGucHash , key , HASH_REMOVE , NULL );
3665
+ }
3666
+ }
3667
+
3618
3668
static void MtmGucSet (VariableSetStmt * stmt , const char * queryStr )
3619
3669
{
3620
3670
MemoryContext oldcontext ;
3621
- MtmGucHashEntry * hentry ;
3622
- bool found ;
3623
3671
3624
3672
if (!MtmGucHash )
3625
- MtmGucHashInit ();
3673
+ MtmGucInit ();
3626
3674
3627
3675
oldcontext = MemoryContextSwitchTo (TopMemoryContext );
3628
3676
3629
3677
switch (stmt -> kind )
3630
3678
{
3631
3679
case VAR_SET_VALUE :
3632
- hentry = (MtmGucHashEntry * ) hash_search (MtmGucHash , stmt -> name ,
3633
- HASH_ENTER , & found );
3634
- if (found )
3635
- pfree (hentry -> value );
3636
- hentry -> value = ExtractSetVariableArgs (stmt );
3680
+ MtmGucUpdate (stmt -> name , ExtractSetVariableArgs (stmt ));
3637
3681
break ;
3638
3682
3639
3683
case VAR_SET_DEFAULT :
3640
- hash_search ( MtmGucHash , stmt -> name , HASH_REMOVE , NULL );
3684
+ MtmGucRemove ( stmt -> name );
3641
3685
break ;
3642
3686
3643
3687
case VAR_RESET :
3644
3688
if (strcmp (stmt -> name , "session_authorization" ) == 0 )
3645
- hash_search ( MtmGucHash , "role" , HASH_REMOVE , NULL );
3646
- hash_search ( MtmGucHash , stmt -> name , HASH_REMOVE , NULL );
3689
+ MtmGucRemove ( "role" );
3690
+ MtmGucRemove ( stmt -> name );
3647
3691
break ;
3648
3692
3649
3693
case VAR_RESET_ALL :
3650
3694
/* XXX: shouldn't we keep auth/role here? */
3651
- hash_destroy (MtmGucHash );
3652
- MtmGucHashInit ();
3695
+ MtmGucDiscard ();
3653
3696
break ;
3654
3697
3655
3698
case VAR_SET_CURRENT :
@@ -3660,46 +3703,36 @@ static void MtmGucSet(VariableSetStmt *stmt, const char *queryStr)
3660
3703
MemoryContextSwitchTo (oldcontext );
3661
3704
}
3662
3705
3663
- static void MtmGucDiscard (DiscardStmt * stmt )
3664
- {
3665
- if (stmt -> target == DISCARD_ALL )
3666
- {
3667
- hash_destroy (MtmGucHash );
3668
- MtmGucHashInit ();
3669
- }
3670
- }
3671
-
3672
3706
static char * MtmGucSerialize (void )
3673
3707
{
3674
- HASH_SEQ_STATUS status ;
3675
- MtmGucHashEntry * hentry ;
3676
3708
StringInfo serialized_gucs ;
3709
+ dlist_iter iter ;
3710
+ int nvars = 0 ;
3677
3711
3678
3712
serialized_gucs = makeStringInfo ();
3679
3713
appendStringInfoString (serialized_gucs , "RESET SESSION AUTHORIZATION; reset all; " );
3680
3714
3681
- if ( MtmGucHash )
3715
+ dlist_foreach ( iter , & MtmGucList )
3682
3716
{
3683
- hash_seq_init (& status , MtmGucHash );
3684
- while ((hentry = (MtmGucHashEntry * ) hash_seq_search (& status )) != NULL )
3685
- {
3686
- appendStringInfoString (serialized_gucs , "SET " );
3687
- appendStringInfoString (serialized_gucs , hentry -> key );
3688
- appendStringInfoString (serialized_gucs , " TO " );
3717
+ MtmGucEntry * cur_entry = dlist_container (MtmGucEntry , list_node , iter .cur );
3689
3718
3690
- /* quite a crutch */
3691
- if (strcmp (hentry -> key , "work_mem" ) == 0 )
3692
- {
3693
- appendStringInfoString (serialized_gucs , "'" );
3694
- appendStringInfoString (serialized_gucs , hentry -> value );
3695
- appendStringInfoString (serialized_gucs , "'" );
3696
- }
3697
- else
3698
- {
3699
- appendStringInfoString (serialized_gucs , hentry -> value );
3700
- }
3701
- appendStringInfoString (serialized_gucs , "; " );
3719
+ appendStringInfoString (serialized_gucs , "SET " );
3720
+ appendStringInfoString (serialized_gucs , cur_entry -> key );
3721
+ appendStringInfoString (serialized_gucs , " TO " );
3722
+
3723
+ /* quite a crutch */
3724
+ if (strcmp (cur_entry -> key , "work_mem" ) == 0 )
3725
+ {
3726
+ appendStringInfoString (serialized_gucs , "'" );
3727
+ appendStringInfoString (serialized_gucs , cur_entry -> value );
3728
+ appendStringInfoString (serialized_gucs , "'" );
3702
3729
}
3730
+ else
3731
+ {
3732
+ appendStringInfoString (serialized_gucs , cur_entry -> value );
3733
+ }
3734
+ appendStringInfoString (serialized_gucs , "; " );
3735
+ nvars ++ ;
3703
3736
}
3704
3737
3705
3738
return serialized_gucs -> data ;
@@ -3847,10 +3880,10 @@ static void MtmProcessUtility(Node *parsetree, const char *queryString,
3847
3880
{
3848
3881
DiscardStmt * stmt = (DiscardStmt * ) parsetree ;
3849
3882
3850
- if (!IsTransactionBlock ())
3883
+ if (!IsTransactionBlock () && stmt -> target == DISCARD_ALL )
3851
3884
{
3852
3885
skipCommand = true;
3853
- MtmGucDiscard (stmt );
3886
+ MtmGucDiscard ();
3854
3887
}
3855
3888
}
3856
3889
break ;
0 commit comments