@@ -18,6 +18,26 @@ PG_MODULE_MAGIC;
18
18
PG_FUNCTION_INFO_V1 (bzcat );
19
19
PG_FUNCTION_INFO_V1 (bzip2 );
20
20
21
+ /*error handling*/
22
+ typedef struct {
23
+ char buf [40 ];
24
+ } bz2_error_msg ;
25
+
26
+ static bz2_error_msg get_bz2_error_msg (int bz2_code ){
27
+ switch (bz2_code ){
28
+ case BZ_SEQUENCE_ERROR : return (bz2_error_msg ){"internal error" };
29
+ case BZ_PARAM_ERROR : return (bz2_error_msg ){"incorrect parameter" };
30
+ case BZ_MEM_ERROR : return (bz2_error_msg ){"memory allocation failed" };
31
+ case BZ_DATA_ERROR : return (bz2_error_msg ){"integrity error" };
32
+ case BZ_DATA_ERROR_MAGIC : return (bz2_error_msg ){"data is not in bzip2 format" };
33
+ case BZ_IO_ERROR : return (bz2_error_msg ){"i/o error" };
34
+ case BZ_UNEXPECTED_EOF : return (bz2_error_msg ){"compressed data ends unexpectedly" };
35
+ case BZ_OUTBUFF_FULL : return (bz2_error_msg ){"buffer size exceeded" };
36
+ case BZ_CONFIG_ERROR : return (bz2_error_msg ){"bad bzlib library" };
37
+ default : return (bz2_error_msg ){"unknown" };
38
+ }
39
+ }
40
+
21
41
/*
22
42
*custom memory allocators for bzip2
23
43
*/
@@ -60,7 +80,7 @@ Datum bzip2(PG_FUNCTION_ARGS){
60
80
0 ); // according to the man pages (on --repetitive-fast --repetitive-best), the workFactor is unused, so we just leave it at 0 which will take the default.
61
81
62
82
if ( status != BZ_OK ) {
63
- ereport (ERROR , errmsg ("bzip2 compression initialization failed" ));
83
+ ereport (ERROR , errmsg ("bzip2 compression initialization failed: %s" , get_bz2_error_msg ( status ). buf ));
64
84
}
65
85
66
86
StringInfoData si ;
@@ -82,7 +102,7 @@ Datum bzip2(PG_FUNCTION_ARGS){
82
102
83
103
if ( status != BZ_STREAM_END ) {
84
104
BZ2_bzCompressEnd (& stream );
85
- ereport (ERROR , errmsg ("bzip2 compression failed" ));
105
+ ereport (ERROR , errmsg ("bzip2 compression failed: %s" , get_bz2_error_msg ( status ). buf ));
86
106
}
87
107
88
108
BZ2_bzCompressEnd (& stream );
@@ -114,7 +134,7 @@ Datum bzcat(PG_FUNCTION_ARGS){
114
134
status = BZ2_bzDecompressInit (& stream , BZ2_VERBOSITY , 0 );
115
135
116
136
if ( status != BZ_OK ) {
117
- ereport (ERROR , errmsg ("bzip2 decompression initialization failed" ));
137
+ ereport (ERROR , errmsg ("bzip2 decompression initialization failed: %s" , get_bz2_error_msg ( status ). buf ));
118
138
}
119
139
120
140
StringInfoData si ;
@@ -127,11 +147,17 @@ Datum bzcat(PG_FUNCTION_ARGS){
127
147
128
148
stream .avail_out = BZ_MAX_UNUSED ;
129
149
stream .next_out = buffer ;
150
+
151
+ if (status == BZ_OK && stream .avail_in == 0 && stream .avail_out > 0 ){
152
+ status = BZ_UNEXPECTED_EOF ;
153
+ break ;
154
+ };
155
+
130
156
} while (status == BZ_OK );
131
157
132
158
if ( status != BZ_STREAM_END ){
133
159
BZ2_bzDecompressEnd (& stream );
134
- ereport (ERROR , errmsg ("bzip2 decompression failed" ));
160
+ ereport (ERROR , errmsg ("bzip2 decompression failed: %s" , get_bz2_error_msg ( status ). buf ));
135
161
}
136
162
137
163
BZ2_bzDecompressEnd (& stream );
0 commit comments