1 /*-------------------------------------------------------------------------
2 *
3 * columnar.c
4 *
5 * This file contains...
6 *
7 * Copyright (c) 2016, Citus Data, Inc.
8 *
9 * $Id$
10 *
11 *-------------------------------------------------------------------------
12 */
13
14 #include "postgres.h"
15
16 #include <sys/stat.h>
17 #include <unistd.h>
18
19 #include "miscadmin.h"
20 #include "utils/guc.h"
21 #include "utils/rel.h"
22
23 #include "citus_version.h"
24 #include "columnar/columnar.h"
25
26 /* Default values for option parameters */
27 #define DEFAULT_STRIPE_ROW_COUNT 150000
28 #define DEFAULT_CHUNK_ROW_COUNT 10000
29
30 #if HAVE_LIBZSTD
31 #define DEFAULT_COMPRESSION_TYPE COMPRESSION_ZSTD
32 #elif HAVE_LIBLZ4
33 #define DEFAULT_COMPRESSION_TYPE COMPRESSION_LZ4
34 #else
35 #define DEFAULT_COMPRESSION_TYPE COMPRESSION_PG_LZ
36 #endif
37
38 int columnar_compression = DEFAULT_COMPRESSION_TYPE;
39 int columnar_stripe_row_limit = DEFAULT_STRIPE_ROW_COUNT;
40 int columnar_chunk_group_row_limit = DEFAULT_CHUNK_ROW_COUNT;
41 int columnar_compression_level = 3;
42
43 static const struct config_enum_entry columnar_compression_options[] =
44 {
45 { "none", COMPRESSION_NONE, false },
46 { "pglz", COMPRESSION_PG_LZ, false },
47 #if HAVE_LIBLZ4
48 { "lz4", COMPRESSION_LZ4, false },
49 #endif
50 #if HAVE_LIBZSTD
51 { "zstd", COMPRESSION_ZSTD, false },
52 #endif
53 { NULL, 0, false }
54 };
55
56 void
columnar_init_gucs()57 columnar_init_gucs()
58 {
59 DefineCustomEnumVariable("columnar.compression",
60 "Compression type for columnar.",
61 NULL,
62 &columnar_compression,
63 DEFAULT_COMPRESSION_TYPE,
64 columnar_compression_options,
65 PGC_USERSET,
66 0,
67 NULL,
68 NULL,
69 NULL);
70
71 DefineCustomIntVariable("columnar.compression_level",
72 "Compression level to be used with zstd.",
73 NULL,
74 &columnar_compression_level,
75 3,
76 COMPRESSION_LEVEL_MIN,
77 COMPRESSION_LEVEL_MAX,
78 PGC_USERSET,
79 0,
80 NULL,
81 NULL,
82 NULL);
83
84 DefineCustomIntVariable("columnar.stripe_row_limit",
85 "Maximum number of tuples per stripe.",
86 NULL,
87 &columnar_stripe_row_limit,
88 DEFAULT_STRIPE_ROW_COUNT,
89 STRIPE_ROW_COUNT_MINIMUM,
90 STRIPE_ROW_COUNT_MAXIMUM,
91 PGC_USERSET,
92 0,
93 NULL,
94 NULL,
95 NULL);
96
97 DefineCustomIntVariable("columnar.chunk_group_row_limit",
98 "Maximum number of rows per chunk.",
99 NULL,
100 &columnar_chunk_group_row_limit,
101 DEFAULT_CHUNK_ROW_COUNT,
102 CHUNK_ROW_COUNT_MINIMUM,
103 CHUNK_ROW_COUNT_MAXIMUM,
104 PGC_USERSET,
105 0,
106 NULL,
107 NULL,
108 NULL);
109 }
110
111
112 /*
113 * ParseCompressionType converts a string to a compression type.
114 * For compression algorithms that are invalid or not compiled, it
115 * returns COMPRESSION_TYPE_INVALID.
116 */
117 CompressionType
ParseCompressionType(const char * compressionTypeString)118 ParseCompressionType(const char *compressionTypeString)
119 {
120 Assert(compressionTypeString != NULL);
121
122 for (int compressionIndex = 0;
123 columnar_compression_options[compressionIndex].name != NULL;
124 compressionIndex++)
125 {
126 const char *compressionName = columnar_compression_options[compressionIndex].name;
127 if (strncmp(compressionTypeString, compressionName, NAMEDATALEN) == 0)
128 {
129 return columnar_compression_options[compressionIndex].val;
130 }
131 }
132
133 return COMPRESSION_TYPE_INVALID;
134 }
135
136
137 /*
138 * CompressionTypeStr returns string representation of a compression type.
139 * For compression algorithms that are invalid or not compiled, it
140 * returns NULL.
141 */
142 const char *
CompressionTypeStr(CompressionType requestedType)143 CompressionTypeStr(CompressionType requestedType)
144 {
145 for (int compressionIndex = 0;
146 columnar_compression_options[compressionIndex].name != NULL;
147 compressionIndex++)
148 {
149 CompressionType compressionType =
150 columnar_compression_options[compressionIndex].val;
151 if (compressionType == requestedType)
152 {
153 return columnar_compression_options[compressionIndex].name;
154 }
155 }
156
157 return NULL;
158 }
159