|
3 | 3 | * show.c: show backup information. |
4 | 4 | * |
5 | 5 | * Portions Copyright (c) 2009-2011, NIPPON TELEGRAPH AND TELEPHONE CORPORATION |
6 | | - * Portions Copyright (c) 2015-2019, Postgres Professional |
| 6 | + * Portions Copyright (c) 2015-2022, Postgres Professional |
7 | 7 | * |
8 | 8 | *------------------------------------------------------------------------- |
9 | 9 | */ |
|
12 | 12 |
|
13 | 13 | #include<time.h> |
14 | 14 | #include<dirent.h> |
| 15 | +#include<locale.h> |
15 | 16 | #include<sys/stat.h> |
16 | 17 |
|
17 | 18 | #include"utils/json.h" |
@@ -71,6 +72,43 @@ static PQExpBufferData show_buf; |
71 | 72 | staticboolfirst_instance= true; |
72 | 73 | staticint32json_level=0; |
73 | 74 |
|
| 75 | +staticconstchar*lc_env_locale; |
| 76 | +typedefenum { |
| 77 | +LOCALE_C,// Used for formatting output to unify the dot-based floating point representation |
| 78 | +LOCALE_ENV// Default environment locale |
| 79 | +}output_numeric_locale; |
| 80 | + |
| 81 | +#ifdefHAVE_USELOCALE |
| 82 | +staticlocale_tenv_locale,c_locale; |
| 83 | +#endif |
| 84 | +voidmemorize_environment_locale() { |
| 85 | +lc_env_locale= (constchar*)getenv("LC_NUMERIC"); |
| 86 | +lc_env_locale=lc_env_locale!=NULL ?lc_env_locale :"C"; |
| 87 | +#ifdefHAVE_USELOCALE |
| 88 | +env_locale=newlocale(LC_NUMERIC_MASK,lc_env_locale, (locale_t)0); |
| 89 | +c_locale=newlocale(LC_NUMERIC_MASK,"C", (locale_t)0); |
| 90 | +#else |
| 91 | +#ifdefHAVE__CONFIGTHREADLOCALE |
| 92 | +_configthreadlocale(_ENABLE_PER_THREAD_LOCALE); |
| 93 | +#endif |
| 94 | +#endif |
| 95 | +} |
| 96 | + |
| 97 | +voidfree_environment_locale() { |
| 98 | +#ifdefHAVE_USELOCALE |
| 99 | +freelocale(env_locale); |
| 100 | +freelocale(c_locale); |
| 101 | +#endif |
| 102 | +} |
| 103 | + |
| 104 | +staticvoidset_output_numeric_locale(output_numeric_localeloc) { |
| 105 | +#ifdefHAVE_USELOCALE |
| 106 | +uselocale(loc==LOCALE_C ?c_locale :env_locale); |
| 107 | +#else |
| 108 | +setlocale(LC_NUMERIC,loc==LOCALE_C ?"C" :lc_env_locale); |
| 109 | +#endif |
| 110 | +} |
| 111 | + |
74 | 112 | /* |
75 | 113 | * Entry point of pg_probackup SHOW subcommand. |
76 | 114 | */ |
@@ -513,6 +551,9 @@ show_instance_plain(const char *instance_name, parray *backup_list, bool show_na |
513 | 551 | ShowBackendRow*rows; |
514 | 552 | TimeLineIDparent_tli=0; |
515 | 553 |
|
| 554 | +// Since we've been printing a table, set LC_NUMERIC to its default environment value |
| 555 | +set_output_numeric_locale(LOCALE_ENV); |
| 556 | + |
516 | 557 | for (i=0;i<SHOW_FIELDS_COUNT;i++) |
517 | 558 | widths[i]=strlen(names[i]); |
518 | 559 |
|
@@ -726,6 +767,8 @@ show_instance_plain(const char *instance_name, parray *backup_list, bool show_na |
726 | 767 | } |
727 | 768 |
|
728 | 769 | pfree(rows); |
| 770 | +// Restore the C locale |
| 771 | +set_output_numeric_locale(LOCALE_C); |
729 | 772 | } |
730 | 773 |
|
731 | 774 | /* |
@@ -806,6 +849,9 @@ show_archive_plain(const char *instance_name, uint32 xlog_seg_size, |
806 | 849 | uint32widths_sum=0; |
807 | 850 | ShowArchiveRow*rows; |
808 | 851 |
|
| 852 | +// Since we've been printing a table, set LC_NUMERIC to its default environment value |
| 853 | +set_output_numeric_locale(LOCALE_ENV); |
| 854 | + |
809 | 855 | for (i=0;i<SHOW_ARCHIVE_FIELDS_COUNT;i++) |
810 | 856 | widths[i]=strlen(names[i]); |
811 | 857 |
|
@@ -973,6 +1019,8 @@ show_archive_plain(const char *instance_name, uint32 xlog_seg_size, |
973 | 1019 | } |
974 | 1020 |
|
975 | 1021 | pfree(rows); |
| 1022 | +// Restore the C locale |
| 1023 | +set_output_numeric_locale(LOCALE_C); |
976 | 1024 | //TODO: free timelines |
977 | 1025 | } |
978 | 1026 |
|
@@ -1045,8 +1093,9 @@ show_archive_json(const char *instance_name, uint32 xlog_seg_size, |
1045 | 1093 | appendPQExpBuffer(buf,"%lu",tlinfo->size); |
1046 | 1094 |
|
1047 | 1095 | json_add_key(buf,"zratio",json_level); |
| 1096 | + |
1048 | 1097 | if (tlinfo->size!=0) |
1049 | | -zratio= ((float)xlog_seg_size*tlinfo->n_xlog_files) /tlinfo->size; |
| 1098 | +zratio= ((float)xlog_seg_size*tlinfo->n_xlog_files) /tlinfo->size; |
1050 | 1099 | appendPQExpBuffer(buf,"%.2f",zratio); |
1051 | 1100 |
|
1052 | 1101 | if (tlinfo->closest_backup!=NULL) |
|